glge-compiled.js 671 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835108361083710838108391084010841108421084310844108451084610847108481084910850108511085210853108541085510856108571085810859108601086110862108631086410865108661086710868108691087010871108721087310874108751087610877108781087910880108811088210883108841088510886108871088810889108901089110892108931089410895108961089710898108991090010901109021090310904109051090610907109081090910910109111091210913109141091510916109171091810919109201092110922109231092410925109261092710928109291093010931109321093310934109351093610937109381093910940109411094210943109441094510946109471094810949109501095110952109531095410955109561095710958109591096010961109621096310964109651096610967109681096910970109711097210973109741097510976109771097810979109801098110982109831098410985109861098710988109891099010991109921099310994109951099610997109981099911000110011100211003110041100511006110071100811009110101101111012110131101411015110161101711018110191102011021110221102311024110251102611027110281102911030110311103211033110341103511036110371103811039110401104111042110431104411045110461104711048110491105011051110521105311054110551105611057110581105911060110611106211063110641106511066110671106811069110701107111072110731107411075110761107711078110791108011081110821108311084110851108611087110881108911090110911109211093110941109511096110971109811099111001110111102111031110411105111061110711108111091111011111111121111311114111151111611117111181111911120111211112211123111241112511126111271112811129111301113111132111331113411135111361113711138111391114011141111421114311144111451114611147111481114911150111511115211153111541115511156111571115811159111601116111162111631116411165111661116711168111691117011171111721117311174111751117611177111781117911180111811118211183111841118511186111871118811189111901119111192111931119411195111961119711198111991120011201112021120311204112051120611207112081120911210112111121211213112141121511216112171121811219112201122111222112231122411225112261122711228112291123011231112321123311234112351123611237112381123911240112411124211243112441124511246112471124811249112501125111252112531125411255112561125711258112591126011261112621126311264112651126611267112681126911270112711127211273112741127511276112771127811279112801128111282112831128411285112861128711288112891129011291112921129311294112951129611297112981129911300113011130211303113041130511306113071130811309113101131111312113131131411315113161131711318113191132011321113221132311324113251132611327113281132911330113311133211333113341133511336113371133811339113401134111342113431134411345113461134711348113491135011351113521135311354113551135611357113581135911360113611136211363113641136511366113671136811369113701137111372113731137411375113761137711378113791138011381113821138311384113851138611387113881138911390113911139211393113941139511396113971139811399114001140111402114031140411405114061140711408114091141011411114121141311414114151141611417114181141911420114211142211423114241142511426114271142811429114301143111432114331143411435114361143711438114391144011441114421144311444114451144611447114481144911450114511145211453114541145511456114571145811459114601146111462114631146411465114661146711468114691147011471114721147311474114751147611477114781147911480114811148211483114841148511486114871148811489114901149111492114931149411495114961149711498114991150011501115021150311504115051150611507115081150911510115111151211513115141151511516115171151811519115201152111522115231152411525115261152711528115291153011531115321153311534115351153611537115381153911540115411154211543115441154511546115471154811549115501155111552115531155411555115561155711558115591156011561115621156311564115651156611567115681156911570115711157211573115741157511576115771157811579115801158111582115831158411585115861158711588115891159011591115921159311594115951159611597115981159911600116011160211603116041160511606116071160811609116101161111612116131161411615116161161711618116191162011621116221162311624116251162611627116281162911630116311163211633116341163511636116371163811639116401164111642116431164411645116461164711648116491165011651116521165311654116551165611657116581165911660116611166211663116641166511666116671166811669116701167111672116731167411675116761167711678116791168011681116821168311684116851168611687116881168911690116911169211693116941169511696116971169811699117001170111702117031170411705117061170711708117091171011711117121171311714117151171611717117181171911720117211172211723117241172511726117271172811729117301173111732117331173411735117361173711738117391174011741117421174311744117451174611747117481174911750117511175211753117541175511756117571175811759117601176111762117631176411765117661176711768117691177011771117721177311774117751177611777117781177911780117811178211783117841178511786117871178811789117901179111792117931179411795117961179711798117991180011801118021180311804118051180611807118081180911810118111181211813118141181511816118171181811819118201182111822118231182411825118261182711828118291183011831118321183311834118351183611837118381183911840118411184211843118441184511846118471184811849118501185111852118531185411855118561185711858118591186011861118621186311864118651186611867118681186911870118711187211873118741187511876118771187811879118801188111882118831188411885118861188711888118891189011891118921189311894118951189611897118981189911900119011190211903119041190511906119071190811909119101191111912119131191411915119161191711918119191192011921119221192311924119251192611927119281192911930119311193211933119341193511936119371193811939119401194111942119431194411945119461194711948119491195011951119521195311954119551195611957119581195911960119611196211963119641196511966119671196811969119701197111972119731197411975119761197711978119791198011981119821198311984119851198611987119881198911990119911199211993119941199511996119971199811999120001200112002120031200412005120061200712008120091201012011120121201312014120151201612017120181201912020120211202212023120241202512026120271202812029120301203112032120331203412035120361203712038120391204012041120421204312044120451204612047120481204912050120511205212053120541205512056120571205812059120601206112062120631206412065120661206712068120691207012071120721207312074120751207612077120781207912080120811208212083120841208512086120871208812089120901209112092120931209412095120961209712098120991210012101121021210312104121051210612107121081210912110121111211212113121141211512116121171211812119121201212112122121231212412125121261212712128121291213012131121321213312134121351213612137121381213912140121411214212143121441214512146121471214812149121501215112152121531215412155121561215712158121591216012161121621216312164121651216612167121681216912170121711217212173121741217512176121771217812179121801218112182121831218412185121861218712188121891219012191121921219312194121951219612197121981219912200122011220212203122041220512206122071220812209122101221112212122131221412215122161221712218122191222012221122221222312224122251222612227122281222912230122311223212233122341223512236122371223812239122401224112242122431224412245122461224712248122491225012251122521225312254122551225612257122581225912260122611226212263122641226512266122671226812269122701227112272122731227412275122761227712278122791228012281122821228312284122851228612287122881228912290122911229212293122941229512296122971229812299123001230112302123031230412305123061230712308123091231012311123121231312314123151231612317123181231912320123211232212323123241232512326123271232812329123301233112332123331233412335123361233712338123391234012341123421234312344123451234612347123481234912350123511235212353123541235512356123571235812359123601236112362123631236412365123661236712368123691237012371123721237312374123751237612377123781237912380123811238212383123841238512386123871238812389123901239112392123931239412395123961239712398123991240012401124021240312404124051240612407124081240912410124111241212413124141241512416124171241812419124201242112422124231242412425124261242712428124291243012431124321243312434124351243612437124381243912440124411244212443124441244512446124471244812449124501245112452124531245412455124561245712458124591246012461124621246312464124651246612467124681246912470124711247212473124741247512476124771247812479124801248112482124831248412485124861248712488124891249012491124921249312494124951249612497124981249912500125011250212503125041250512506125071250812509125101251112512125131251412515125161251712518125191252012521125221252312524125251252612527125281252912530125311253212533125341253512536125371253812539125401254112542125431254412545125461254712548125491255012551125521255312554125551255612557125581255912560125611256212563125641256512566125671256812569125701257112572125731257412575125761257712578125791258012581125821258312584125851258612587125881258912590125911259212593125941259512596125971259812599126001260112602126031260412605126061260712608126091261012611126121261312614126151261612617126181261912620126211262212623126241262512626126271262812629126301263112632126331263412635126361263712638126391264012641126421264312644126451264612647126481264912650126511265212653126541265512656126571265812659126601266112662126631266412665126661266712668126691267012671126721267312674126751267612677126781267912680126811268212683126841268512686126871268812689126901269112692126931269412695126961269712698126991270012701127021270312704127051270612707127081270912710127111271212713127141271512716127171271812719127201272112722127231272412725127261272712728127291273012731127321273312734127351273612737127381273912740127411274212743127441274512746127471274812749127501275112752127531275412755127561275712758127591276012761127621276312764127651276612767127681276912770127711277212773127741277512776127771277812779127801278112782127831278412785127861278712788127891279012791127921279312794127951279612797127981279912800128011280212803128041280512806128071280812809128101281112812128131281412815128161281712818128191282012821128221282312824128251282612827128281282912830128311283212833128341283512836128371283812839128401284112842128431284412845128461284712848128491285012851128521285312854128551285612857128581285912860128611286212863128641286512866128671286812869128701287112872128731287412875128761287712878128791288012881128821288312884128851288612887128881288912890128911289212893128941289512896128971289812899129001290112902129031290412905129061290712908129091291012911129121291312914129151291612917129181291912920129211292212923129241292512926129271292812929129301293112932129331293412935129361293712938129391294012941129421294312944129451294612947129481294912950129511295212953129541295512956129571295812959129601296112962129631296412965129661296712968129691297012971129721297312974129751297612977129781297912980129811298212983129841298512986129871298812989129901299112992129931299412995129961299712998129991300013001130021300313004130051300613007130081300913010130111301213013130141301513016130171301813019130201302113022130231302413025130261302713028130291303013031130321303313034130351303613037130381303913040130411304213043130441304513046130471304813049130501305113052130531305413055130561305713058130591306013061130621306313064130651306613067130681306913070130711307213073130741307513076130771307813079130801308113082130831308413085130861308713088130891309013091130921309313094130951309613097130981309913100131011310213103131041310513106131071310813109131101311113112131131311413115131161311713118131191312013121131221312313124131251312613127131281312913130131311313213133131341313513136131371313813139131401314113142131431314413145131461314713148131491315013151131521315313154131551315613157131581315913160131611316213163131641316513166131671316813169131701317113172131731317413175131761317713178131791318013181131821318313184131851318613187131881318913190131911319213193131941319513196131971319813199132001320113202132031320413205132061320713208132091321013211132121321313214132151321613217132181321913220132211322213223132241322513226132271322813229132301323113232132331323413235132361323713238132391324013241132421324313244132451324613247132481324913250132511325213253132541325513256132571325813259132601326113262132631326413265132661326713268132691327013271132721327313274132751327613277132781327913280132811328213283132841328513286132871328813289132901329113292132931329413295132961329713298132991330013301133021330313304133051330613307133081330913310133111331213313133141331513316133171331813319133201332113322133231332413325133261332713328133291333013331133321333313334133351333613337133381333913340133411334213343133441334513346133471334813349133501335113352133531335413355133561335713358133591336013361133621336313364133651336613367133681336913370133711337213373133741337513376133771337813379133801338113382133831338413385133861338713388133891339013391133921339313394133951339613397133981339913400134011340213403134041340513406134071340813409134101341113412134131341413415134161341713418134191342013421134221342313424134251342613427134281342913430134311343213433134341343513436134371343813439134401344113442134431344413445134461344713448134491345013451134521345313454134551345613457134581345913460134611346213463134641346513466134671346813469134701347113472134731347413475134761347713478134791348013481134821348313484134851348613487134881348913490134911349213493134941349513496134971349813499135001350113502135031350413505135061350713508135091351013511135121351313514135151351613517135181351913520135211352213523135241352513526135271352813529135301353113532135331353413535135361353713538135391354013541135421354313544135451354613547135481354913550135511355213553135541355513556135571355813559135601356113562135631356413565135661356713568135691357013571135721357313574135751357613577135781357913580135811358213583135841358513586135871358813589135901359113592135931359413595135961359713598135991360013601136021360313604136051360613607136081360913610136111361213613136141361513616136171361813619136201362113622136231362413625136261362713628136291363013631136321363313634136351363613637136381363913640136411364213643136441364513646136471364813649136501365113652136531365413655136561365713658136591366013661136621366313664136651366613667136681366913670136711367213673136741367513676136771367813679136801368113682136831368413685136861368713688136891369013691136921369313694136951369613697136981369913700137011370213703137041370513706137071370813709137101371113712137131371413715137161371713718137191372013721137221372313724137251372613727137281372913730137311373213733137341373513736137371373813739137401374113742137431374413745137461374713748137491375013751137521375313754137551375613757137581375913760137611376213763137641376513766137671376813769137701377113772137731377413775137761377713778137791378013781137821378313784137851378613787137881378913790137911379213793137941379513796137971379813799138001380113802138031380413805138061380713808138091381013811138121381313814138151381613817138181381913820138211382213823138241382513826138271382813829138301383113832138331383413835138361383713838138391384013841138421384313844138451384613847138481384913850138511385213853138541385513856138571385813859138601386113862138631386413865138661386713868138691387013871138721387313874138751387613877138781387913880138811388213883138841388513886138871388813889138901389113892138931389413895138961389713898138991390013901139021390313904139051390613907139081390913910139111391213913139141391513916139171391813919139201392113922139231392413925139261392713928139291393013931139321393313934139351393613937139381393913940139411394213943139441394513946139471394813949139501395113952139531395413955139561395713958139591396013961139621396313964139651396613967139681396913970139711397213973139741397513976139771397813979139801398113982139831398413985139861398713988139891399013991139921399313994139951399613997139981399914000140011400214003140041400514006140071400814009140101401114012140131401414015140161401714018140191402014021140221402314024140251402614027140281402914030140311403214033140341403514036140371403814039140401404114042140431404414045140461404714048140491405014051140521405314054140551405614057140581405914060140611406214063140641406514066140671406814069140701407114072140731407414075140761407714078140791408014081140821408314084140851408614087140881408914090140911409214093140941409514096140971409814099141001410114102141031410414105141061410714108141091411014111141121411314114141151411614117141181411914120141211412214123141241412514126141271412814129141301413114132141331413414135141361413714138141391414014141141421414314144141451414614147141481414914150141511415214153141541415514156141571415814159141601416114162141631416414165141661416714168141691417014171141721417314174141751417614177141781417914180141811418214183141841418514186141871418814189141901419114192141931419414195141961419714198141991420014201142021420314204142051420614207142081420914210142111421214213142141421514216142171421814219142201422114222142231422414225142261422714228142291423014231142321423314234142351423614237142381423914240142411424214243142441424514246142471424814249142501425114252142531425414255142561425714258142591426014261142621426314264142651426614267142681426914270142711427214273142741427514276142771427814279142801428114282142831428414285142861428714288142891429014291142921429314294142951429614297142981429914300143011430214303143041430514306143071430814309143101431114312143131431414315143161431714318143191432014321143221432314324143251432614327143281432914330143311433214333143341433514336143371433814339143401434114342143431434414345143461434714348143491435014351143521435314354143551435614357143581435914360143611436214363143641436514366143671436814369143701437114372143731437414375143761437714378143791438014381143821438314384143851438614387143881438914390143911439214393143941439514396143971439814399144001440114402144031440414405144061440714408144091441014411144121441314414144151441614417144181441914420144211442214423144241442514426144271442814429144301443114432144331443414435144361443714438144391444014441144421444314444144451444614447144481444914450144511445214453144541445514456144571445814459144601446114462144631446414465144661446714468144691447014471144721447314474144751447614477144781447914480144811448214483144841448514486144871448814489144901449114492144931449414495144961449714498144991450014501145021450314504145051450614507145081450914510145111451214513145141451514516145171451814519145201452114522145231452414525145261452714528145291453014531145321453314534145351453614537145381453914540145411454214543145441454514546145471454814549145501455114552145531455414555145561455714558145591456014561145621456314564145651456614567145681456914570145711457214573145741457514576145771457814579145801458114582145831458414585145861458714588145891459014591145921459314594145951459614597145981459914600146011460214603146041460514606146071460814609146101461114612146131461414615146161461714618146191462014621146221462314624146251462614627146281462914630146311463214633146341463514636146371463814639146401464114642146431464414645146461464714648146491465014651146521465314654146551465614657146581465914660146611466214663146641466514666146671466814669146701467114672146731467414675146761467714678146791468014681146821468314684146851468614687146881468914690146911469214693146941469514696146971469814699147001470114702147031470414705147061470714708147091471014711147121471314714147151471614717147181471914720147211472214723147241472514726147271472814729147301473114732147331473414735147361473714738147391474014741147421474314744147451474614747147481474914750147511475214753147541475514756147571475814759147601476114762147631476414765147661476714768147691477014771147721477314774147751477614777147781477914780147811478214783147841478514786147871478814789147901479114792147931479414795147961479714798147991480014801148021480314804148051480614807148081480914810148111481214813148141481514816148171481814819148201482114822148231482414825148261482714828148291483014831148321483314834148351483614837148381483914840148411484214843148441484514846148471484814849148501485114852148531485414855148561485714858148591486014861148621486314864148651486614867148681486914870148711487214873148741487514876148771487814879148801488114882148831488414885148861488714888148891489014891148921489314894148951489614897148981489914900149011490214903149041490514906149071490814909149101491114912149131491414915149161491714918149191492014921149221492314924149251492614927149281492914930149311493214933149341493514936149371493814939149401494114942149431494414945149461494714948149491495014951149521495314954149551495614957149581495914960149611496214963149641496514966149671496814969149701497114972149731497414975149761497714978149791498014981149821498314984149851498614987149881498914990149911499214993149941499514996149971499814999150001500115002150031500415005150061500715008150091501015011150121501315014150151501615017150181501915020150211502215023150241502515026150271502815029150301503115032150331503415035150361503715038150391504015041150421504315044150451504615047150481504915050150511505215053150541505515056150571505815059150601506115062150631506415065150661506715068150691507015071150721507315074150751507615077150781507915080150811508215083150841508515086150871508815089150901509115092150931509415095150961509715098150991510015101151021510315104151051510615107151081510915110151111511215113151141511515116151171511815119151201512115122151231512415125151261512715128151291513015131151321513315134151351513615137151381513915140151411514215143151441514515146151471514815149151501515115152151531515415155151561515715158151591516015161151621516315164151651516615167151681516915170151711517215173151741517515176151771517815179151801518115182151831518415185151861518715188151891519015191151921519315194151951519615197151981519915200152011520215203152041520515206152071520815209152101521115212152131521415215152161521715218152191522015221152221522315224152251522615227152281522915230152311523215233152341523515236152371523815239152401524115242152431524415245152461524715248152491525015251152521525315254152551525615257152581525915260152611526215263152641526515266152671526815269152701527115272152731527415275152761527715278152791528015281152821528315284152851528615287152881528915290152911529215293152941529515296152971529815299153001530115302153031530415305153061530715308153091531015311153121531315314153151531615317153181531915320153211532215323153241532515326153271532815329153301533115332153331533415335153361533715338153391534015341153421534315344153451534615347153481534915350153511535215353153541535515356153571535815359153601536115362153631536415365153661536715368153691537015371153721537315374153751537615377153781537915380153811538215383153841538515386153871538815389153901539115392153931539415395153961539715398153991540015401154021540315404154051540615407154081540915410154111541215413154141541515416154171541815419154201542115422154231542415425154261542715428154291543015431154321543315434154351543615437154381543915440154411544215443154441544515446154471544815449154501545115452154531545415455154561545715458154591546015461154621546315464154651546615467154681546915470154711547215473154741547515476154771547815479154801548115482154831548415485154861548715488154891549015491154921549315494154951549615497154981549915500155011550215503155041550515506155071550815509155101551115512155131551415515155161551715518155191552015521155221552315524155251552615527155281552915530155311553215533155341553515536155371553815539155401554115542155431554415545155461554715548155491555015551155521555315554155551555615557155581555915560155611556215563155641556515566155671556815569155701557115572155731557415575155761557715578155791558015581155821558315584155851558615587155881558915590155911559215593155941559515596155971559815599156001560115602156031560415605156061560715608156091561015611156121561315614156151561615617156181561915620156211562215623156241562515626156271562815629156301563115632156331563415635156361563715638156391564015641156421564315644156451564615647156481564915650156511565215653156541565515656156571565815659156601566115662156631566415665156661566715668156691567015671156721567315674156751567615677156781567915680156811568215683156841568515686156871568815689156901569115692156931569415695156961569715698156991570015701157021570315704157051570615707157081570915710157111571215713157141571515716157171571815719157201572115722157231572415725157261572715728157291573015731157321573315734157351573615737157381573915740157411574215743157441574515746157471574815749157501575115752157531575415755157561575715758157591576015761157621576315764157651576615767157681576915770157711577215773157741577515776157771577815779157801578115782157831578415785157861578715788157891579015791157921579315794157951579615797157981579915800158011580215803158041580515806158071580815809158101581115812158131581415815158161581715818158191582015821158221582315824158251582615827158281582915830158311583215833158341583515836158371583815839158401584115842158431584415845158461584715848158491585015851158521585315854158551585615857158581585915860158611586215863158641586515866158671586815869158701587115872158731587415875158761587715878158791588015881158821588315884158851588615887158881588915890158911589215893158941589515896158971589815899159001590115902159031590415905159061590715908159091591015911159121591315914159151591615917159181591915920159211592215923159241592515926159271592815929159301593115932159331593415935159361593715938159391594015941159421594315944159451594615947159481594915950159511595215953159541595515956159571595815959159601596115962159631596415965159661596715968159691597015971159721597315974159751597615977159781597915980159811598215983159841598515986159871598815989159901599115992159931599415995159961599715998159991600016001160021600316004160051600616007160081600916010160111601216013160141601516016160171601816019160201602116022160231602416025160261602716028160291603016031160321603316034160351603616037160381603916040160411604216043160441604516046160471604816049160501605116052160531605416055160561605716058160591606016061160621606316064160651606616067160681606916070160711607216073160741607516076160771607816079160801608116082160831608416085160861608716088160891609016091160921609316094160951609616097160981609916100161011610216103161041610516106161071610816109161101611116112161131611416115161161611716118161191612016121161221612316124161251612616127161281612916130161311613216133161341613516136161371613816139161401614116142161431614416145161461614716148161491615016151161521615316154161551615616157161581615916160161611616216163161641616516166161671616816169161701617116172161731617416175161761617716178161791618016181161821618316184161851618616187161881618916190161911619216193161941619516196161971619816199162001620116202162031620416205162061620716208162091621016211162121621316214162151621616217162181621916220162211622216223162241622516226162271622816229162301623116232162331623416235162361623716238162391624016241162421624316244162451624616247162481624916250162511625216253162541625516256162571625816259162601626116262162631626416265162661626716268162691627016271162721627316274162751627616277162781627916280162811628216283162841628516286162871628816289162901629116292162931629416295162961629716298162991630016301163021630316304163051630616307163081630916310163111631216313163141631516316163171631816319163201632116322163231632416325163261632716328163291633016331163321633316334163351633616337163381633916340163411634216343163441634516346163471634816349163501635116352163531635416355163561635716358163591636016361163621636316364163651636616367163681636916370163711637216373163741637516376163771637816379163801638116382163831638416385163861638716388163891639016391163921639316394163951639616397163981639916400164011640216403164041640516406164071640816409164101641116412164131641416415164161641716418164191642016421164221642316424164251642616427164281642916430164311643216433164341643516436164371643816439164401644116442164431644416445164461644716448164491645016451164521645316454164551645616457164581645916460164611646216463164641646516466164671646816469164701647116472164731647416475164761647716478164791648016481164821648316484164851648616487164881648916490164911649216493164941649516496164971649816499165001650116502165031650416505165061650716508165091651016511165121651316514165151651616517165181651916520165211652216523165241652516526165271652816529165301653116532165331653416535165361653716538165391654016541165421654316544165451654616547165481654916550165511655216553165541655516556165571655816559165601656116562165631656416565165661656716568165691657016571165721657316574165751657616577165781657916580165811658216583165841658516586165871658816589165901659116592165931659416595165961659716598165991660016601166021660316604166051660616607166081660916610166111661216613166141661516616166171661816619166201662116622166231662416625166261662716628166291663016631166321663316634166351663616637166381663916640166411664216643166441664516646166471664816649166501665116652166531665416655166561665716658166591666016661166621666316664166651666616667166681666916670166711667216673166741667516676166771667816679166801668116682166831668416685166861668716688166891669016691166921669316694166951669616697166981669916700167011670216703167041670516706167071670816709167101671116712167131671416715167161671716718167191672016721167221672316724167251672616727167281672916730167311673216733167341673516736167371673816739167401674116742167431674416745167461674716748167491675016751167521675316754167551675616757167581675916760167611676216763167641676516766167671676816769167701677116772167731677416775167761677716778167791678016781167821678316784167851678616787167881678916790167911679216793167941679516796167971679816799168001680116802168031680416805168061680716808168091681016811168121681316814168151681616817168181681916820168211682216823168241682516826168271682816829168301683116832168331683416835168361683716838168391684016841168421684316844168451684616847168481684916850168511685216853168541685516856168571685816859168601686116862168631686416865168661686716868168691687016871168721687316874168751687616877168781687916880168811688216883168841688516886168871688816889168901689116892168931689416895168961689716898168991690016901169021690316904169051690616907169081690916910169111691216913169141691516916169171691816919169201692116922169231692416925169261692716928169291693016931169321693316934169351693616937169381693916940169411694216943169441694516946169471694816949169501695116952169531695416955169561695716958169591696016961169621696316964169651696616967169681696916970169711697216973169741697516976169771697816979169801698116982169831698416985169861698716988169891699016991169921699316994169951699616997169981699917000170011700217003170041700517006170071700817009170101701117012170131701417015170161701717018170191702017021170221702317024170251702617027170281702917030170311703217033170341703517036170371703817039170401704117042170431704417045170461704717048170491705017051170521705317054170551705617057170581705917060170611706217063170641706517066170671706817069170701707117072170731707417075170761707717078170791708017081170821708317084170851708617087170881708917090170911709217093170941709517096170971709817099171001710117102171031710417105171061710717108171091711017111171121711317114171151711617117171181711917120171211712217123171241712517126171271712817129171301713117132171331713417135171361713717138171391714017141171421714317144171451714617147171481714917150171511715217153171541715517156171571715817159171601716117162171631716417165171661716717168171691717017171171721717317174171751717617177171781717917180171811718217183171841718517186171871718817189171901719117192171931719417195171961719717198171991720017201172021720317204172051720617207172081720917210172111721217213172141721517216172171721817219172201722117222172231722417225172261722717228172291723017231172321723317234172351723617237172381723917240172411724217243172441724517246172471724817249172501725117252172531725417255172561725717258172591726017261172621726317264172651726617267172681726917270172711727217273172741727517276172771727817279172801728117282172831728417285172861728717288172891729017291172921729317294172951729617297172981729917300173011730217303173041730517306173071730817309173101731117312173131731417315173161731717318173191732017321173221732317324173251732617327173281732917330173311733217333173341733517336173371733817339173401734117342173431734417345173461734717348173491735017351173521735317354173551735617357173581735917360173611736217363173641736517366173671736817369173701737117372173731737417375173761737717378173791738017381173821738317384173851738617387173881738917390173911739217393173941739517396173971739817399174001740117402174031740417405174061740717408174091741017411174121741317414174151741617417174181741917420174211742217423174241742517426174271742817429174301743117432174331743417435174361743717438174391744017441174421744317444174451744617447174481744917450174511745217453174541745517456174571745817459174601746117462174631746417465174661746717468174691747017471174721747317474174751747617477174781747917480174811748217483174841748517486174871748817489174901749117492174931749417495174961749717498174991750017501175021750317504175051750617507175081750917510175111751217513175141751517516175171751817519175201752117522175231752417525175261752717528175291753017531175321753317534175351753617537175381753917540175411754217543175441754517546175471754817549175501755117552175531755417555175561755717558175591756017561175621756317564175651756617567175681756917570175711757217573175741757517576175771757817579175801758117582175831758417585175861758717588175891759017591175921759317594175951759617597175981759917600176011760217603176041760517606176071760817609176101761117612176131761417615176161761717618176191762017621176221762317624176251762617627176281762917630176311763217633176341763517636176371763817639176401764117642176431764417645176461764717648176491765017651176521765317654176551765617657176581765917660176611766217663176641766517666176671766817669176701767117672176731767417675176761767717678176791768017681176821768317684176851768617687176881768917690176911769217693176941769517696176971769817699177001770117702177031770417705177061770717708177091771017711177121771317714177151771617717177181771917720177211772217723177241772517726177271772817729177301773117732177331773417735177361773717738177391774017741177421774317744177451774617747177481774917750177511775217753177541775517756177571775817759177601776117762177631776417765177661776717768177691777017771177721777317774177751777617777177781777917780177811778217783177841778517786177871778817789177901779117792177931779417795177961779717798177991780017801178021780317804178051780617807178081780917810178111781217813178141781517816178171781817819178201782117822178231782417825178261782717828178291783017831178321783317834178351783617837178381783917840178411784217843178441784517846178471784817849178501785117852178531785417855178561785717858178591786017861178621786317864178651786617867178681786917870178711787217873178741787517876178771787817879178801788117882178831788417885178861788717888178891789017891178921789317894178951789617897178981789917900179011790217903179041790517906179071790817909179101791117912179131791417915179161791717918179191792017921179221792317924179251792617927179281792917930179311793217933179341793517936179371793817939179401794117942179431794417945179461794717948179491795017951179521795317954179551795617957179581795917960179611796217963179641796517966179671796817969179701797117972179731797417975179761797717978179791798017981179821798317984179851798617987179881798917990179911799217993179941799517996179971799817999180001800118002180031800418005180061800718008180091801018011180121801318014180151801618017180181801918020180211802218023180241802518026180271802818029180301803118032180331803418035180361803718038180391804018041180421804318044180451804618047180481804918050180511805218053180541805518056180571805818059180601806118062180631806418065180661806718068180691807018071180721807318074180751807618077180781807918080180811808218083180841808518086180871808818089180901809118092180931809418095180961809718098180991810018101181021810318104181051810618107181081810918110181111811218113181141811518116181171811818119181201812118122181231812418125181261812718128181291813018131181321813318134181351813618137181381813918140181411814218143181441814518146181471814818149181501815118152181531815418155181561815718158181591816018161181621816318164181651816618167181681816918170181711817218173181741817518176181771817818179181801818118182181831818418185181861818718188181891819018191181921819318194181951819618197181981819918200182011820218203182041820518206182071820818209182101821118212182131821418215182161821718218182191822018221182221822318224182251822618227182281822918230182311823218233182341823518236182371823818239182401824118242182431824418245182461824718248182491825018251182521825318254182551825618257182581825918260182611826218263182641826518266182671826818269182701827118272182731827418275182761827718278182791828018281182821828318284182851828618287182881828918290182911829218293182941829518296182971829818299183001830118302183031830418305183061830718308183091831018311183121831318314183151831618317183181831918320183211832218323183241832518326183271832818329183301833118332183331833418335183361833718338183391834018341183421834318344183451834618347183481834918350183511835218353183541835518356183571835818359183601836118362183631836418365183661836718368183691837018371183721837318374183751837618377183781837918380183811838218383183841838518386183871838818389183901839118392183931839418395183961839718398183991840018401184021840318404184051840618407184081840918410184111841218413184141841518416184171841818419184201842118422184231842418425184261842718428184291843018431184321843318434184351843618437184381843918440184411844218443184441844518446184471844818449184501845118452184531845418455184561845718458184591846018461184621846318464184651846618467184681846918470184711847218473184741847518476184771847818479184801848118482184831848418485184861848718488184891849018491184921849318494184951849618497184981849918500185011850218503185041850518506185071850818509185101851118512185131851418515185161851718518185191852018521185221852318524185251852618527185281852918530185311853218533185341853518536185371853818539185401854118542185431854418545185461854718548185491855018551185521855318554185551855618557185581855918560185611856218563185641856518566185671856818569185701857118572185731857418575185761857718578185791858018581185821858318584185851858618587185881858918590185911859218593185941859518596185971859818599186001860118602186031860418605186061860718608186091861018611186121861318614186151861618617186181861918620186211862218623186241862518626186271862818629186301863118632186331863418635186361863718638186391864018641186421864318644186451864618647186481864918650186511865218653186541865518656186571865818659186601866118662186631866418665186661866718668186691867018671186721867318674186751867618677186781867918680186811868218683186841868518686186871868818689186901869118692186931869418695186961869718698186991870018701187021870318704187051870618707187081870918710187111871218713187141871518716187171871818719187201872118722187231872418725187261872718728187291873018731187321873318734187351873618737187381873918740187411874218743187441874518746187471874818749187501875118752187531875418755187561875718758187591876018761187621876318764187651876618767187681876918770187711877218773187741877518776187771877818779187801878118782187831878418785187861878718788187891879018791187921879318794187951879618797187981879918800188011880218803188041880518806188071880818809188101881118812188131881418815188161881718818188191882018821188221882318824188251882618827188281882918830188311883218833188341883518836188371883818839188401884118842188431884418845188461884718848188491885018851188521885318854188551885618857188581885918860188611886218863188641886518866188671886818869188701887118872188731887418875188761887718878188791888018881188821888318884188851888618887188881888918890188911889218893188941889518896188971889818899189001890118902189031890418905189061890718908189091891018911189121891318914189151891618917189181891918920189211892218923189241892518926189271892818929189301893118932189331893418935189361893718938189391894018941189421894318944189451894618947189481894918950189511895218953189541895518956189571895818959189601896118962189631896418965189661896718968189691897018971189721897318974189751897618977189781897918980189811898218983189841898518986189871898818989189901899118992189931899418995189961899718998189991900019001190021900319004190051900619007190081900919010190111901219013190141901519016190171901819019190201902119022190231902419025190261902719028190291903019031190321903319034190351903619037190381903919040190411904219043190441904519046190471904819049190501905119052190531905419055190561905719058190591906019061190621906319064190651906619067190681906919070190711907219073190741907519076190771907819079190801908119082190831908419085190861908719088190891909019091190921909319094190951909619097190981909919100191011910219103191041910519106191071910819109191101911119112191131911419115191161911719118191191912019121191221912319124191251912619127191281912919130191311913219133191341913519136191371913819139191401914119142191431914419145191461914719148191491915019151191521915319154191551915619157191581915919160191611916219163191641916519166191671916819169191701917119172191731917419175191761917719178191791918019181191821918319184191851918619187191881918919190191911919219193191941919519196191971919819199192001920119202192031920419205192061920719208192091921019211192121921319214192151921619217192181921919220192211922219223192241922519226192271922819229192301923119232192331923419235192361923719238192391924019241192421924319244192451924619247192481924919250192511925219253192541925519256192571925819259192601926119262192631926419265192661926719268192691927019271192721927319274192751927619277192781927919280192811928219283192841928519286192871928819289192901929119292192931929419295192961929719298192991930019301193021930319304193051930619307193081930919310193111931219313193141931519316193171931819319193201932119322193231932419325193261932719328193291933019331193321933319334193351933619337193381933919340193411934219343193441934519346193471934819349193501935119352193531935419355193561935719358193591936019361193621936319364193651936619367193681936919370193711937219373193741937519376193771937819379193801938119382193831938419385193861938719388193891939019391193921939319394193951939619397193981939919400194011940219403194041940519406194071940819409194101941119412194131941419415194161941719418194191942019421194221942319424194251942619427194281942919430194311943219433194341943519436194371943819439194401944119442194431944419445194461944719448194491945019451194521945319454194551945619457194581945919460194611946219463194641946519466194671946819469194701947119472194731947419475194761947719478194791948019481194821948319484194851948619487194881948919490194911949219493194941949519496194971949819499195001950119502195031950419505195061950719508195091951019511195121951319514195151951619517195181951919520195211952219523195241952519526195271952819529195301953119532195331953419535195361953719538195391954019541195421954319544195451954619547195481954919550195511955219553195541955519556195571955819559195601956119562195631956419565195661956719568195691957019571195721957319574195751957619577195781957919580195811958219583195841958519586195871958819589195901959119592195931959419595195961959719598195991960019601196021960319604196051960619607196081960919610196111961219613196141961519616196171961819619196201962119622196231962419625196261962719628196291963019631196321963319634196351963619637196381963919640196411964219643196441964519646196471964819649196501965119652196531965419655196561965719658196591966019661196621966319664196651966619667196681966919670196711967219673196741967519676196771967819679196801968119682196831968419685196861968719688196891969019691196921969319694196951969619697196981969919700197011970219703197041970519706197071970819709197101971119712197131971419715197161971719718197191972019721197221972319724197251972619727197281972919730197311973219733197341973519736197371973819739197401974119742197431974419745197461974719748197491975019751197521975319754197551975619757197581975919760197611976219763197641976519766197671976819769197701977119772197731977419775197761977719778197791978019781197821978319784197851978619787197881978919790197911979219793197941979519796197971979819799198001980119802198031980419805198061980719808198091981019811198121981319814198151981619817198181981919820198211982219823198241982519826198271982819829198301983119832198331983419835198361983719838198391984019841198421984319844198451984619847198481984919850198511985219853198541985519856198571985819859198601986119862198631986419865198661986719868198691987019871198721987319874198751987619877198781987919880198811988219883198841988519886198871988819889198901989119892198931989419895198961989719898198991990019901199021990319904199051990619907199081990919910199111991219913199141991519916199171991819919199201992119922199231992419925199261992719928199291993019931199321993319934199351993619937199381993919940199411994219943199441994519946199471994819949199501995119952199531995419955199561995719958199591996019961199621996319964199651996619967199681996919970199711997219973199741997519976199771997819979199801998119982199831998419985199861998719988199891999019991199921999319994199951999619997199981999920000200012000220003200042000520006200072000820009200102001120012200132001420015200162001720018200192002020021200222002320024200252002620027200282002920030200312003220033200342003520036200372003820039200402004120042200432004420045200462004720048200492005020051200522005320054200552005620057200582005920060200612006220063200642006520066200672006820069200702007120072200732007420075200762007720078200792008020081200822008320084200852008620087200882008920090200912009220093200942009520096200972009820099201002010120102201032010420105201062010720108201092011020111201122011320114201152011620117201182011920120201212012220123201242012520126201272012820129201302013120132201332013420135201362013720138201392014020141201422014320144201452014620147201482014920150201512015220153201542015520156201572015820159201602016120162201632016420165201662016720168201692017020171201722017320174201752017620177201782017920180201812018220183201842018520186201872018820189201902019120192201932019420195201962019720198201992020020201202022020320204202052020620207202082020920210202112021220213202142021520216202172021820219202202022120222202232022420225202262022720228202292023020231202322023320234202352023620237202382023920240202412024220243202442024520246202472024820249202502025120252202532025420255202562025720258202592026020261202622026320264202652026620267202682026920270202712027220273202742027520276202772027820279202802028120282202832028420285202862028720288202892029020291202922029320294202952029620297202982029920300203012030220303203042030520306203072030820309203102031120312203132031420315203162031720318203192032020321203222032320324203252032620327203282032920330203312033220333203342033520336203372033820339203402034120342203432034420345203462034720348203492035020351203522035320354203552035620357203582035920360203612036220363203642036520366203672036820369203702037120372203732037420375203762037720378203792038020381203822038320384203852038620387203882038920390203912039220393203942039520396203972039820399204002040120402204032040420405204062040720408204092041020411204122041320414204152041620417204182041920420204212042220423204242042520426204272042820429204302043120432204332043420435204362043720438204392044020441204422044320444204452044620447204482044920450204512045220453204542045520456204572045820459204602046120462204632046420465204662046720468204692047020471204722047320474204752047620477204782047920480204812048220483204842048520486204872048820489204902049120492204932049420495204962049720498204992050020501205022050320504205052050620507205082050920510205112051220513205142051520516205172051820519205202052120522205232052420525205262052720528205292053020531205322053320534205352053620537205382053920540205412054220543205442054520546205472054820549205502055120552205532055420555205562055720558205592056020561205622056320564205652056620567205682056920570205712057220573205742057520576205772057820579205802058120582205832058420585205862058720588205892059020591205922059320594205952059620597205982059920600206012060220603206042060520606206072060820609206102061120612206132061420615206162061720618206192062020621206222062320624206252062620627206282062920630206312063220633206342063520636206372063820639206402064120642206432064420645206462064720648206492065020651206522065320654206552065620657206582065920660206612066220663206642066520666206672066820669206702067120672206732067420675206762067720678206792068020681206822068320684206852068620687206882068920690206912069220693206942069520696206972069820699207002070120702207032070420705207062070720708207092071020711207122071320714207152071620717207182071920720207212072220723207242072520726207272072820729207302073120732207332073420735207362073720738207392074020741207422074320744207452074620747207482074920750207512075220753207542075520756207572075820759207602076120762207632076420765207662076720768207692077020771207722077320774207752077620777207782077920780207812078220783207842078520786207872078820789207902079120792207932079420795207962079720798207992080020801208022080320804208052080620807208082080920810208112081220813208142081520816208172081820819208202082120822208232082420825208262082720828208292083020831208322083320834208352083620837208382083920840208412084220843208442084520846208472084820849208502085120852208532085420855208562085720858208592086020861208622086320864208652086620867208682086920870208712087220873208742087520876208772087820879208802088120882208832088420885208862088720888208892089020891208922089320894208952089620897208982089920900209012090220903209042090520906209072090820909209102091120912209132091420915209162091720918209192092020921209222092320924209252092620927209282092920930209312093220933209342093520936209372093820939209402094120942209432094420945209462094720948209492095020951209522095320954209552095620957209582095920960209612096220963209642096520966209672096820969209702097120972209732097420975209762097720978209792098020981209822098320984209852098620987209882098920990209912099220993209942099520996209972099820999210002100121002210032100421005210062100721008210092101021011210122101321014210152101621017210182101921020210212102221023210242102521026210272102821029210302103121032210332103421035210362103721038210392104021041210422104321044210452104621047210482104921050210512105221053210542105521056210572105821059210602106121062210632106421065210662106721068210692107021071210722107321074210752107621077210782107921080210812108221083210842108521086210872108821089210902109121092210932109421095210962109721098210992110021101211022110321104211052110621107211082110921110211112111221113211142111521116211172111821119211202112121122211232112421125211262112721128211292113021131211322113321134211352113621137211382113921140211412114221143211442114521146211472114821149211502115121152211532115421155211562115721158211592116021161211622116321164211652116621167211682116921170211712117221173211742117521176211772117821179211802118121182211832118421185211862118721188211892119021191211922119321194211952119621197211982119921200212012120221203212042120521206212072120821209212102121121212212132121421215212162121721218212192122021221212222122321224212252122621227212282122921230212312123221233212342123521236212372123821239212402124121242212432124421245212462124721248212492125021251212522125321254212552125621257212582125921260212612126221263212642126521266212672126821269212702127121272212732127421275212762127721278212792128021281212822128321284212852128621287212882128921290212912129221293212942129521296212972129821299213002130121302213032130421305213062130721308213092131021311213122131321314213152131621317213182131921320213212132221323213242132521326213272132821329213302133121332213332133421335213362133721338213392134021341213422134321344213452134621347213482134921350213512135221353213542135521356213572135821359213602136121362213632136421365213662136721368213692137021371213722137321374213752137621377213782137921380213812138221383213842138521386213872138821389213902139121392213932139421395213962139721398213992140021401214022140321404214052140621407214082140921410214112141221413214142141521416214172141821419214202142121422214232142421425214262142721428214292143021431214322143321434214352143621437214382143921440214412144221443214442144521446214472144821449214502145121452214532145421455214562145721458214592146021461214622146321464214652146621467214682146921470214712147221473214742147521476214772147821479214802148121482214832148421485214862148721488214892149021491214922149321494214952149621497214982149921500215012150221503215042150521506215072150821509215102151121512215132151421515215162151721518215192152021521215222152321524215252152621527215282152921530215312153221533215342153521536215372153821539215402154121542215432154421545215462154721548215492155021551215522155321554215552155621557215582155921560215612156221563215642156521566215672156821569215702157121572215732157421575215762157721578215792158021581215822158321584215852158621587215882158921590215912159221593215942159521596215972159821599216002160121602216032160421605216062160721608216092161021611216122161321614216152161621617216182161921620216212162221623216242162521626216272162821629216302163121632216332163421635216362163721638216392164021641216422164321644216452164621647216482164921650216512165221653216542165521656216572165821659216602166121662216632166421665216662166721668216692167021671216722167321674216752167621677216782167921680216812168221683216842168521686216872168821689216902169121692216932169421695216962169721698216992170021701217022170321704217052170621707217082170921710217112171221713217142171521716217172171821719217202172121722
  1. /*
  2. GLGE WebGL Graphics Engine
  3. Copyright (c) 2010, Paul Brunt
  4. All rights reserved.
  5. Redistribution and use in source and binary forms, with or without
  6. modification, are permitted provided that the following conditions are met:
  7. * Redistributions of source code must retain the above copyright
  8. notice, this list of conditions and the following disclaimer.
  9. * Redistributions in binary form must reproduce the above copyright
  10. notice, this list of conditions and the following disclaimer in the
  11. documentation and/or other materials provided with the distribution.
  12. * Neither the name of GLGE nor the
  13. names of its contributors may be used to endorse or promote products
  14. derived from this software without specific prior written permission.
  15. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  16. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  17. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  18. DISCLAIMED. IN NO EVENT SHALL PAUL BRUNT BE LIABLE FOR ANY
  19. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  20. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  21. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  22. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  23. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  24. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  25. */
  26. /**
  27. * @fileOverview
  28. * @name GLGE_math.js
  29. */
  30. if(typeof(GLGE) == "undefined"){
  31. /**
  32. * @namespace Holds the functionality of the library
  33. */
  34. GLGE = {};
  35. }
  36. (function(GLGE){
  37. var matrixCache=[];
  38. //matrix reuse prevent so much GC
  39. GLGE.reuseMatrix4=function(mat4){
  40. //if(mat4 && mat4.length==16 && matrixCache<10000) matrixCache.push(mat4);
  41. }
  42. GLGE.matrix4=function(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16){
  43. if(matrixCache.length==0){
  44. var mat=[a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16];
  45. }else{
  46. var mat=matrixCache.shift();
  47. mat[0]=a1;
  48. mat[1]=a2;
  49. mat[2]=a3;
  50. mat[3]=a4;
  51. mat[4]=a5;
  52. mat[5]=a6;
  53. mat[6]=a7;
  54. mat[7]=a8;
  55. mat[8]=a9;
  56. mat[9]=a10;
  57. mat[10]=a11;
  58. mat[11]=a12;
  59. mat[12]=a13;
  60. mat[13]=a14;
  61. mat[14]=a15;
  62. mat[15]=a16;
  63. }
  64. return mat;
  65. }
  66. GLGE.Vec=function(array) {
  67. return array.slice(0);
  68. }
  69. /**
  70. * The Vec3 Class creates a vector
  71. * @param {Array} array An array of 3 floats
  72. */
  73. GLGE.Vec3=function(x,y,z){
  74. return [x,y,z];
  75. }
  76. /**
  77. * The Vec4 Class creates a vector
  78. * @param {Array} array An array of 4 floats
  79. */
  80. GLGE.Vec4=function(x,y,z,w){
  81. return [x,y,z,w];
  82. }
  83. /**
  84. * Gets the nth element (1 indexed) from the array
  85. * @param {Array} v A vector with 4 elements
  86. * @param {number} i The index from one
  87. */
  88. GLGE.get1basedVec4=function(v,i){
  89. return v[i-1];
  90. };
  91. /**
  92. * Gets the nth element (1 indexed) from the array
  93. * @param {Array} v A vector with 3 elements
  94. * @param {number} i The index from one
  95. */
  96. GLGE.get1basedVec3=function(v,i){
  97. return v[i-1];
  98. };
  99. /**
  100. * Gets the nth element (1 indexed) from the array
  101. * @param {Array} v A vector with 4 elements
  102. * @param {number} i The index from one
  103. */
  104. GLGE.getVec4=function(v,i){
  105. return v[i];
  106. };
  107. /**
  108. * Gets the nth element (1 indexed) from the array
  109. * @param {Array} v A vector with 3 elements
  110. * @param {number} i The index from one
  111. */
  112. GLGE.getVec3=function(v,i){
  113. return v[i];
  114. };
  115. /**
  116. * Adds a GLGE.Vec4 to this Vec4
  117. * @param {Array} a The first value to add
  118. * * @param {Array} b The second value to add
  119. */
  120. GLGE.addVec4=function(a,b) {
  121. return [a[0]+b[0],a[1]+b[1],a[2]+b[2],a[3]+b[3]];
  122. }
  123. /**
  124. * Adds a GLGE.Vec3 to this GLGE.Vec3
  125. * @param {Array} a The first value to add
  126. * @param {Array} b The second value to add
  127. */
  128. GLGE.addVec3=function(a,b) {
  129. return [a[0]+b[0],a[1]+b[1],a[2]+b[2]];
  130. }
  131. /**
  132. * Adds a GLGE.Vec4 to this Vec4
  133. * @param {Array} a The first value
  134. * * @param {Array} b The second value to subtract from the first
  135. */
  136. GLGE.subVec4=function(a,b) {
  137. return [a[0]-b[0],a[1]-b[1],a[2]-b[2],a[3]-b[3]];
  138. }
  139. /**
  140. * Adds a GLGE.Vec3 to this GLGE.Vec3
  141. * @param {Array} a The first value
  142. * @param {Array} b The second value to subtract from the first
  143. */
  144. GLGE.subVec3=function(a,b) {
  145. return [a[0]-b[0],a[1]-b[1],a[2]-b[2]];
  146. }
  147. /**
  148. * Gets the dot product between this and the input vector
  149. * @param {Array} a the first value to dot
  150. * @param {Array} b the second value to dot
  151. */
  152. GLGE.dotVec3=function(a,b) {
  153. return a[0]*b[0]+a[1]*b[1]+a[2]*b[2];
  154. }
  155. /**
  156. * Gets the dot product between this and the input vector
  157. * @param {Array} a the first value to dot
  158. * @param {Array} b the second value to dot
  159. */
  160. GLGE.dotVec4=function(a,b) {
  161. return a[0]*b[0]+a[1]*b[1]+a[2]*b[2]+a[3]*b[3];
  162. }
  163. /**
  164. * Gets the dot product between this and the input vector
  165. * @param {Array} a the vector to scale
  166. * @param {Number} b the scalar
  167. */
  168. GLGE.scaleVec4=function(a,b) {
  169. return [a[0]*b,a[1]*b,a[2]*b,a[3]*b];
  170. }
  171. /**
  172. * Gets the dot product between this and the input vector
  173. * @param {Array} a the vector to scale
  174. * @param {Number} b the scalar
  175. */
  176. GLGE.scaleVec3=function(a,b) {
  177. return [a[0]*b,a[1]*b,a[2]*b];
  178. }
  179. /**
  180. * Gets the cross product between this and the input vector
  181. * @param {Array} a the first value to dot
  182. * @param {Array} b the second value to dot
  183. */
  184. GLGE.crossVec3=function(a,b) {
  185. return [a[1]*b[2]-a[2]*b[1],
  186. a[2]*b[0]-a[0]*b[2],
  187. a[0]*b[1]-a[1]*b[0]];
  188. }
  189. /**
  190. * Returns a unitized version of the input vector3
  191. * @param {Array} a the vector3 to be unitized
  192. */
  193. GLGE.toUnitVec3=function(a) {
  194. var sq=a[0]*a[0]+a[1]*a[1]+a[2]*a[2];
  195. var f=1.0;
  196. if (sq>0) {
  197. f=Math.pow(sq,0.5);
  198. }
  199. return [a[0]/f,a[1]/f,a[2]/f];
  200. };
  201. /**
  202. * Returns a unitized version of the input vector4
  203. * @param {Array} a the vector4 to be unitized
  204. */
  205. GLGE.toUnitVec4=function(a) {
  206. var sq=a[0]*a[0]+a[1]*a[1]+a[2]*a[2]+a[3]*a[3];
  207. var f=1.0;
  208. if (sq>0) {
  209. f=Math.pow(sq,0.5);
  210. }
  211. return [a[0]/f,a[1]/f,a[2]/f,a[3]/f];
  212. };
  213. /**
  214. * Returns the length of a vector3
  215. * @param {Array} a the vector to be measured
  216. */
  217. GLGE.lengthVec3=function(a) {
  218. return Math.pow(a[0]*a[0]+a[1]*a[1]+a[2]*a[2],0.5);
  219. };
  220. /**
  221. * Returns the distance between 2 vector3s
  222. * @param {Array} a the first vector
  223. * @param {Array} b the second vector
  224. */
  225. GLGE.distanceVec3=function(a,b){
  226. return GLGE.lengthVec3(GLGE.subVec3(a,b));
  227. };
  228. /**
  229. * Returns the length of a vector3
  230. * @param {Array} a the vector to be measured
  231. */
  232. GLGE.lengthVec4=function(a,b) {
  233. return Math.pow(a[0]*a[0]+a[1]*a[1]+a[2]*a[2]+a[3]*a[3],0.5);
  234. };
  235. /**
  236. * Returns the distance between 2 vector4s
  237. * @param {Array} a the first vector
  238. * @param {Array} b the second vector
  239. */
  240. GLGE.distanceVec4=function(a,b){
  241. return GLGE.lengthVec4(GLGE.subVec4(a,b));
  242. };
  243. /**
  244. * Returns the angle between 2 vector3s in radians
  245. * @param {Array} a the first vector
  246. * @param {Array} b the second vector
  247. */
  248. GLGE.angleVec3=function(a,b){
  249. a=GLGE.toUnitVec3(a);
  250. b=GLGE.toUnitVec3(b);
  251. d=GLGE.dotVec3(a,b);
  252. if (d<-1)
  253. d=-1;
  254. if (d>1)
  255. d=1;
  256. return Math.acos(d);
  257. };
  258. /**
  259. * Returns the angle between 2 vector4s in radians
  260. * @param {Array} a the first vector
  261. * @param {Array} b the second vector
  262. */
  263. GLGE.angleVec4=function(a,b){
  264. a=GLGE.toUnitVec4(a);
  265. b=GLGE.toUnitVec4(b);
  266. d=GLGE.dotVec4(a,b);
  267. if (d<-1)
  268. d=-1;
  269. if (d>1)
  270. d=1;
  271. return Math.acos(d);
  272. };
  273. GLGE_math_use_webgl_float=false;
  274. /**
  275. * The Mat class creates a matrix from an array
  276. * @param {Array} array An array of 9 or 16 floats
  277. */
  278. GLGE.Mat3=GLGE_math_use_webgl_float?function(array) {
  279. if (array.length==9) {
  280. return new Float32Array(array);
  281. }else if (array.length==16) {
  282. return new Float32Array([array[0],array[1],array[2],array[4],array[5],array[6],array[8],array[9],array[10]]);
  283. }else {
  284. throw "invalid matrix length";
  285. }
  286. }:function(array) {
  287. var retval;
  288. if (array.length==9) {
  289. retval=array.slice(0);
  290. }else if (array.length==16) {
  291. retval=[array[0],array[1],array[2],array[4],array[5],array[6],array[8],array[9],array[10]];
  292. }else {
  293. throw "invalid matrix length";
  294. }
  295. retval.get=function(i){return this[i];};
  296. return retval;
  297. };
  298. GLGE.Mat=GLGE_math_use_webgl_float?function(array) {
  299. return new Float32Array(array);
  300. }:function(array){
  301. var retval=array.slice(0);
  302. retval.get=function(i){return this[i];};
  303. return retval;
  304. };
  305. GLGE.Mat4=function(array) {
  306. var retval;
  307. if (array.length==9) {
  308. retval=[array[0],array[1],array[2],0,array[3],array[4],array[5],0,array[6],array[7],array[8],0,0,0,0,1];
  309. }else if (array.length==16) {
  310. if(array.slice) retval=array.slice(0);
  311. else retval=array.subarray(0);
  312. }else {
  313. throw "invalid matrix length";
  314. }
  315. retval.get=function(i){return this[i];};
  316. return retval;
  317. };
  318. /**
  319. * Finds the determinate of the matrix
  320. * @returns {number} the determinate
  321. */
  322. GLGE.determinantMat4=function(m) {
  323. return m[12] * m[9] * m[6] * m[3] - m[8] * m[13] * m[6] * m[3] - m[12] * m[5] * m[10] * m[3] + m[4] * m[13] * m[10] * m[3] + m[8] * m[5] * m[14] * m[3] - m[4] * m[9] * m[14] * m[3] - m[12] * m[9] * m[2] * m[7] + m[8] * m[13] * m[2] * m[7] + m[12] * m[1] * m[10] * m[7] - m[0] * m[13] * m[10] * m[7] - m[8] * m[1] * m[14] * m[7] + m[0] * m[9] * m[14] * m[7] + m[12] * m[5] * m[2] * m[11] - m[4] * m[13] * m[2] * m[11] - m[12] * m[1] * m[6] * m[11] + m[0] * m[13] * m[6] * m[11] + m[4] * m[1] * m[14] * m[11] - m[0] * m[5] * m[14] * m[11] - m[8] * m[5] * m[2] * m[15] + m[4] * m[9] * m[2] * m[15] + m[8] * m[1] * m[6] * m[15] - m[0] * m[9] * m[6] * m[15] - m[4] * m[1] * m[10] * m[15] + m[0] * m[5] * m[10] * m[15];
  324. };
  325. /**
  326. * Finds the inverse of the matrix
  327. * @returns {GLGE.Mat} the inverse
  328. */
  329. GLGE.inverseMat4=function(mat){
  330. // Cache the matrix values (makes for huge speed increases!)
  331. var a00 = mat[0], a01 = mat[1], a02 = mat[2], a03 = mat[3];
  332. var a10 = mat[4], a11 = mat[5], a12 = mat[6], a13 = mat[7];
  333. var a20 = mat[8], a21 = mat[9], a22 = mat[10], a23 = mat[11];
  334. var a30 = mat[12], a31 = mat[13], a32 = mat[14], a33 = mat[15];
  335. var d = a30*a21*a12*a03 - a20*a31*a12*a03 - a30*a11*a22*a03 + a10*a31*a22*a03 +
  336. a20*a11*a32*a03 - a10*a21*a32*a03 - a30*a21*a02*a13 + a20*a31*a02*a13 +
  337. a30*a01*a22*a13 - a00*a31*a22*a13 - a20*a01*a32*a13 + a00*a21*a32*a13 +
  338. a30*a11*a02*a23 - a10*a31*a02*a23 - a30*a01*a12*a23 + a00*a31*a12*a23 +
  339. a10*a01*a32*a23 - a00*a11*a32*a23 - a20*a11*a02*a33 + a10*a21*a02*a33 +
  340. a20*a01*a12*a33 - a00*a21*a12*a33 - a10*a01*a22*a33 + a00*a11*a22*a33;
  341. return GLGE.matrix4((a21*a32*a13 - a31*a22*a13 + a31*a12*a23 - a11*a32*a23 - a21*a12*a33 + a11*a22*a33)/d,
  342. (a31*a22*a03 - a21*a32*a03 - a31*a02*a23 + a01*a32*a23 + a21*a02*a33 - a01*a22*a33)/d,
  343. (a11*a32*a03 - a31*a12*a03 + a31*a02*a13 - a01*a32*a13 - a11*a02*a33 + a01*a12*a33)/d,
  344. (a21*a12*a03 - a11*a22*a03 - a21*a02*a13 + a01*a22*a13 + a11*a02*a23 - a01*a12*a23)/d,
  345. (a30*a22*a13 - a20*a32*a13 - a30*a12*a23 + a10*a32*a23 + a20*a12*a33 - a10*a22*a33)/d,
  346. (a20*a32*a03 - a30*a22*a03 + a30*a02*a23 - a00*a32*a23 - a20*a02*a33 + a00*a22*a33)/d,
  347. (a30*a12*a03 - a10*a32*a03 - a30*a02*a13 + a00*a32*a13 + a10*a02*a33 - a00*a12*a33)/d,
  348. (a10*a22*a03 - a20*a12*a03 + a20*a02*a13 - a00*a22*a13 - a10*a02*a23 + a00*a12*a23)/d,
  349. (a20*a31*a13 - a30*a21*a13 + a30*a11*a23 - a10*a31*a23 - a20*a11*a33 + a10*a21*a33)/d,
  350. (a30*a21*a03 - a20*a31*a03 - a30*a01*a23 + a00*a31*a23 + a20*a01*a33 - a00*a21*a33)/d,
  351. (a10*a31*a03 - a30*a11*a03 + a30*a01*a13 - a00*a31*a13 - a10*a01*a33 + a00*a11*a33)/d,
  352. (a20*a11*a03 - a10*a21*a03 - a20*a01*a13 + a00*a21*a13 + a10*a01*a23 - a00*a11*a23)/d,
  353. (a30*a21*a12 - a20*a31*a12 - a30*a11*a22 + a10*a31*a22 + a20*a11*a32 - a10*a21*a32)/d,
  354. (a20*a31*a02 - a30*a21*a02 + a30*a01*a22 - a00*a31*a22 - a20*a01*a32 + a00*a21*a32)/d,
  355. (a30*a11*a02 - a10*a31*a02 - a30*a01*a12 + a00*a31*a12 + a10*a01*a32 - a00*a11*a32)/d,
  356. (a10*a21*a02 - a20*a11*a02 + a20*a01*a12 - a00*a21*a12 - a10*a01*a22 + a00*a11*a22)/d)
  357. };
  358. /**
  359. * multiplies two mat4's
  360. * @returns {GLGE.Mat} the matrix multiplication of the matrices
  361. */
  362. GLGE.mulMat4Vec3=function(mat1,vec2){
  363. return GLGE.Vec3(mat1[0]*vec2[0]+mat1[1]*vec2[1]+mat1[2]*vec2[2]+mat1[3],
  364. mat1[4]*vec2[0]+mat1[5]*vec2[1]+mat1[6]*vec2[2]+mat1[7],
  365. mat1[8]*vec2[0]+mat1[9]*vec2[1]+mat1[10]*vec2[2]+mat1[11]);
  366. };
  367. /**
  368. * multiplies two mat4's
  369. * @returns {GLGE.Mat} the matrix multiplication of the matrices
  370. */
  371. GLGE.mulMat4Vec4=function(mat1,vec2){
  372. return GLGE.Vec4(mat1[0]*vec2[0]+mat1[1]*vec2[1]+mat1[2]*vec2[2]+mat1[3]*vec2[3],
  373. mat1[4]*vec2[0]+mat1[5]*vec2[1]+mat1[6]*vec2[2]+mat1[7]*vec2[3],
  374. mat1[8]*vec2[0]+mat1[9]*vec2[1]+mat1[10]*vec2[2]+mat1[11]*vec2[3],
  375. mat1[12]*vec2[0]+mat1[13]*vec2[1]+mat1[14]*vec2[2]+mat1[15]*vec2[3]);
  376. };
  377. /**
  378. * multiplies a Mat4 by a scalar value
  379. * @returns {GLGE.Mat} the matrix multiplication of the matrices
  380. */
  381. GLGE.scaleMat4=function(m,value) {
  382. return GLGE.matrix4([m[0]*value,m[1]*value,m[2]*value,m[3]*value,
  383. m[4]*value,m[5]*value,m[6]*value,m[7]*value,
  384. m[8]*value,m[9]*value,m[10]*value,m[11]*value,
  385. m[12]*value,m[13]*value,m[14]*value,m[15]*value]);
  386. };
  387. /**
  388. * multiplies a Mat4 by a scalar value in place without allocation
  389. * @returns {GLGE.Mat} the input matrix, modified
  390. */
  391. GLGE.scaleInPlaceMat4=function(m,value) {
  392. m.set(0,m[0]*value);
  393. m.set(1,m[1]*value);
  394. m.set(2,m[2]*value);
  395. m.set(3,m[3]*value);
  396. m.set(4,m[4]*value);
  397. m.set(5,m[5]*value);
  398. m.set(6,m[6]*value);
  399. m.set(7,m[7]*value);
  400. m.set(8,m[8]*value);
  401. m.set(9,m[9]*value);
  402. m.set(10,m[10]*value);
  403. m.set(11,m[11]*value);
  404. m.set(12,m[12]*value);
  405. m.set(13,m[13]*value);
  406. m.set(14,m[14]*value);
  407. m.set(15,m[15]*value);
  408. return m;
  409. };
  410. /**
  411. * adds a Mat4 to another Mat4 in place without allocation
  412. * @returns {GLGE.Mat} the first input matrix, modified to be added
  413. */
  414. GLGE.addInPlaceMat4=function(m,value) {
  415. m.set(0,m[0]+value[0]);
  416. m.set(1,m[1]+value[1]);
  417. m.set(2,m[2]+value[2]);
  418. m.set(3,m[3]+value[3]);
  419. m.set(4,m[4]+value[4]);
  420. m.set(5,m[5]+value[5]);
  421. m.set(6,m[6]+value[6]);
  422. m.set(7,m[7]+value[7]);
  423. m.set(8,m[8]+value[8]);
  424. m.set(9,m[9]+value[9]);
  425. m.set(10,m[10]+value[10]);
  426. m.set(11,m[11]+value[11]);
  427. m.set(12,m[12]+value[12]);
  428. m.set(13,m[13]+value[13]);
  429. m.set(14,m[14]+value[14]);
  430. m.set(15,m[15]+value[15]);
  431. return m;
  432. };
  433. /**
  434. * adds two Mat4 together
  435. * @returns {GLGE.Mat} a new, added Mat4
  436. */
  437. GLGE.addMat4=function(m,value) {
  438. return GLGE.Mat([m[0]+value[0],
  439. m[1]+value[1],
  440. m[2]+value[2],
  441. m[3]+value[3],
  442. m[4]+value[4],
  443. m[5]+value[5],
  444. m[6]+value[6],
  445. m[7]+value[7],
  446. m[8]+value[8],
  447. m[9]+value[9],
  448. m[10]+value[10],
  449. m[11]+value[11],
  450. m[12]+value[12],
  451. m[13]+value[13],
  452. m[14]+value[14],
  453. m[15]+value[15]]);
  454. return m;
  455. };
  456. /**
  457. * subs a Mat4 from another Mat4 in place without allocation
  458. * @returns {GLGE.Mat} the first input matrix, modified to have the second subtacted
  459. */
  460. GLGE.subInPlaceMat4=function(m,value) {
  461. m.set(0,m[0]-value[0]);
  462. m.set(1,m[1]-value[1]);
  463. m.set(2,m[2]-value[2]);
  464. m.set(3,m[3]-value[3]);
  465. m.set(4,m[4]-value[4]);
  466. m.set(5,m[5]-value[5]);
  467. m.set(6,m[6]-value[6]);
  468. m.set(7,m[7]-value[7]);
  469. m.set(8,m[8]-value[8]);
  470. m.set(9,m[9]-value[9]);
  471. m.set(10,m[10]-value[10]);
  472. m.set(11,m[11]-value[11]);
  473. m.set(12,m[12]-value[12]);
  474. m.set(13,m[13]-value[13]);
  475. m.set(14,m[14]-value[14]);
  476. m.set(15,m[15]-value[15]);
  477. return m;
  478. };
  479. /**
  480. * subtracts the second matrix from the first
  481. * @returns {GLGE.Mat} a new, subed Mat4
  482. */
  483. GLGE.subMat4=function(m,value) {
  484. return GLGE.Mat([m[0]-value[0],
  485. m[1]-value[1],
  486. m[2]-value[2],
  487. m[3]-value[3],
  488. m[4]-value[4],
  489. m[5]-value[5],
  490. m[6]-value[6],
  491. m[7]-value[7],
  492. m[8]-value[8],
  493. m[9]-value[9],
  494. m[10]-value[10],
  495. m[11]-value[11],
  496. m[12]-value[12],
  497. m[13]-value[13],
  498. m[14]-value[14],
  499. m[15]-value[15]]);
  500. return m;
  501. };
  502. /**
  503. * Finds the matrix multiplication with another GLGE.Mat or GLGE.vec or an Array of length 3-4
  504. * @param {object} value An GLGE.Mat, GLGE.vec or Array
  505. * @returns {GLGE.Mat|GLGE.Vec}
  506. */
  507. GLGE.mulMat4=function(mat2,mat1){
  508. var a00 = mat1[0], a01 = mat1[1], a02 = mat1[2], a03 = mat1[3];
  509. var a10 = mat1[4], a11 = mat1[5], a12 = mat1[6], a13 = mat1[7];
  510. var a20 = mat1[8], a21 = mat1[9], a22 = mat1[10], a23 = mat1[11];
  511. var a30 = mat1[12], a31 = mat1[13], a32 = mat1[14], a33 = mat1[15];
  512. var b00 = mat2[0], b01 = mat2[1], b02 = mat2[2], b03 = mat2[3];
  513. var b10 = mat2[4], b11 = mat2[5], b12 = mat2[6], b13 = mat2[7];
  514. var b20 = mat2[8], b21 = mat2[9], b22 = mat2[10], b23 = mat2[11];
  515. var b30 = mat2[12], b31 = mat2[13], b32 = mat2[14], b33 = mat2[15];
  516. return GLGE.matrix4(b00 * a00 + b01 * a10 + b02 * a20 + b03 * a30,
  517. b00 * a01 + b01 * a11 + b02 * a21 + b03 * a31,
  518. b00 * a02 + b01 * a12 + b02 * a22 + b03 * a32,
  519. b00 * a03 + b01 * a13 + b02 * a23 + b03 * a33,
  520. b10 * a00 + b11 * a10 + b12 * a20 + b13 * a30,
  521. b10 * a01 + b11 * a11 + b12 * a21 + b13 * a31,
  522. b10 * a02 + b11 * a12 + b12 * a22 + b13 * a32,
  523. b10 * a03 + b11 * a13 + b12 * a23 + b13 * a33,
  524. b20 * a00 + b21 * a10 + b22 * a20 + b23 * a30,
  525. b20 * a01 + b21 * a11 + b22 * a21 + b23 * a31,
  526. b20 * a02 + b21 * a12 + b22 * a22 + b23 * a32,
  527. b20 * a03 + b21 * a13 + b22 * a23 + b23 * a33,
  528. b30 * a00 + b31 * a10 + b32 * a20 + b33 * a30,
  529. b30 * a01 + b31 * a11 + b32 * a21 + b33 * a31,
  530. b30 * a02 + b31 * a12 + b32 * a22 + b33 * a32,
  531. b30 * a03 + b31 * a13 + b32 * a23 + b33 * a33);
  532. };
  533. GLGE.transposeInPlaceMat4=function(m) {
  534. var v=m[1];
  535. m.set(1,m[4]);
  536. m.set(4,v);
  537. v=m[8];
  538. m.set(8,m[2]);
  539. m.set(2,v);
  540. v=m[3];
  541. m.set(3,m[12]);
  542. m.set(12,v);
  543. v=m[9];
  544. m.set(9,m[6]);
  545. m.set(6,v);
  546. v=m[13];
  547. m.set(13,m[7]);
  548. m.set(7,v);
  549. v=m[14];
  550. m.set(14,m[11]);
  551. m.set(11,v);
  552. };
  553. /**
  554. * Builds the transpose of the matrix
  555. * @returns {GLGE.Mat} the transposed matrix
  556. */
  557. GLGE.transposeMat4=function(m) {
  558. return GLGE.matrix4(m[0],m[4],m[8],m[12],
  559. m[1],m[5],m[9],m[13],
  560. m[2],m[6],m[10],m[14],
  561. m[3],m[7],m[11],m[15]);
  562. };
  563. /**
  564. * copys a js array into a webglarray
  565. * @param {array} mat the source array
  566. * @param {webglarray} glarray the destination array
  567. */
  568. GLGE.mat4gl=function(mat,glarray){
  569. glarray[0]=mat[0];
  570. glarray[1]=mat[1];
  571. glarray[2]=mat[2];
  572. glarray[3]=mat[3];
  573. glarray[4]=mat[4];
  574. glarray[5]=mat[5];
  575. glarray[6]=mat[6];
  576. glarray[7]=mat[7];
  577. glarray[8]=mat[8];
  578. glarray[9]=mat[9];
  579. glarray[10]=mat[10];
  580. glarray[11]=mat[11];
  581. glarray[12]=mat[12];
  582. glarray[13]=mat[13];
  583. glarray[14]=mat[14];
  584. glarray[15]=mat[15];
  585. };
  586. /**
  587. * Sets the value at the specified index
  588. * @param {number} i the first index 1 offset
  589. * @param {number} j the second index 1 offset
  590. * @param {number} value the value to set
  591. */
  592. GLGE.set1basedMat4=function(m,i,j,value){
  593. m[(i-1)*4+(j-1)]=value;
  594. if(m.glData!==undefined){
  595. delete m.glData;
  596. }
  597. };
  598. /**
  599. * Sets the value at the specified index
  600. * @param {number} i the first index from zero
  601. * @param {number} j the second index from zero
  602. * @param {number} value the value to set
  603. */
  604. GLGE.setMat4=function(m,i,j,value){
  605. m[i*4+j]=value;
  606. if(m.glData!==undefined){
  607. delete m.glData;
  608. }
  609. };
  610. /**
  611. * Gets the value at the specified index
  612. * @param {number} i the first index from one
  613. * @param {number} j the second index from one
  614. * @returns {number} the value at the given index
  615. */
  616. GLGE.get1basedMat4=function(m,i,j){
  617. return m.get((i-1)*4+(j-1));
  618. };
  619. /**
  620. * Gets the value at the specified index
  621. * @param {number} i the first index from zero
  622. * @param {number} j the second index from zero
  623. * @returns {number} the value at the given index
  624. */
  625. GLGE.getMat4=function(m,i,j){
  626. return m[i*4+j];
  627. };
  628. /**
  629. * gets the a webgl float array for this Matrix, once generated it will cache it so it doesn't need to recreate everytime
  630. * @returns {Float32Array} the webgl array for this Matrix
  631. * @private
  632. */
  633. GLGE.glDataMat4=function(m) {
  634. m.glArray=new Float32Array(m);
  635. return m.glArray;
  636. };
  637. /**
  638. * Creates an identity matrix
  639. * @returns {GLGE.Mat} the identity matrix
  640. */
  641. GLGE.identMatrix=function(){
  642. return GLGE.matrix4(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1);
  643. };
  644. /**
  645. * Creates a translation matrix
  646. * @returns {Array} value an array GLGE.Vec or 3 paramters
  647. * @returns {GLGE.Mat} the translation matrix
  648. */
  649. GLGE.translateMatrix=function(value){
  650. var x;
  651. var y;
  652. var z;
  653. if(arguments.length==3){
  654. x=arguments[0];
  655. y=arguments[1];
  656. z=arguments[2];
  657. }
  658. else if(value.data){
  659. x=value.data[0];
  660. y=value.data[1];
  661. z=value.data[2];
  662. }
  663. else if(value instanceof Array){
  664. x=value[0];
  665. y=value[1];
  666. z=value[2];
  667. }
  668. return GLGE.matrix4(
  669. 1,0,0,x,
  670. 0,1,0,y,
  671. 0,0,1,z,
  672. 0,0,0,1
  673. );
  674. };
  675. /**
  676. * Creates a scale matrix
  677. * @returns {Array} value an array GLGE.Vec or 3 paramters
  678. * @returns {GLGE.Mat} the scale matrix
  679. */
  680. GLGE.scaleMatrix=function(value){
  681. var x;
  682. var y;
  683. var z;
  684. if(arguments.length==3){
  685. x=arguments[0];
  686. y=arguments[1];
  687. z=arguments[2];
  688. }
  689. else if(value.data){
  690. x=value.data[0];
  691. y=value.data[1];
  692. z=value.data[2];
  693. }
  694. else if(value instanceof Array){
  695. x=value[0];
  696. y=value[1];
  697. z=value[2];
  698. }
  699. return GLGE.matrix4(
  700. x,0,0,0,
  701. 0,y,0,0,
  702. 0,0,z,0,
  703. 0,0,0,1
  704. );
  705. }
  706. /**
  707. * @constant
  708. * @description Enum for XYZ rotation order
  709. */
  710. GLGE.ROT_XYZ=1;
  711. /**
  712. * @constant
  713. * @description Enum for XZY rotation order
  714. */
  715. GLGE.ROT_XZY=2;
  716. /**
  717. * @constant
  718. * @description Enum for YXZ rotation order
  719. */
  720. GLGE.ROT_YXZ=3;
  721. /**
  722. * @constant
  723. * @description Enum for YZX rotation order
  724. */
  725. GLGE.ROT_YZX=4;
  726. /**
  727. * @constant
  728. * @description Enum for ZXY rotation order
  729. */
  730. GLGE.ROT_ZXY=5;
  731. /**
  732. * @constant
  733. * @description Enum for ZYX rotation order
  734. */
  735. GLGE.ROT_ZYX=6;
  736. /**
  737. * Creates a rotation matrix
  738. * @returns {Array} value an array GLGE.Vec or 3 paramters
  739. * @returns {GLGE.Mat} the rotation matrix
  740. */
  741. GLGE.rotateMatrix=function(value,type) {
  742. var x;
  743. var y;
  744. var z;
  745. if(arguments.length>2){
  746. x=arguments[0];
  747. y=arguments[1];
  748. z=arguments[2];
  749. type=arguments[3];
  750. }
  751. else if(value.data){
  752. x=value.data[0];
  753. y=value.data[1];
  754. z=value.data[2];
  755. }
  756. else if(value instanceof Array){
  757. x=value[0];
  758. y=value[1];
  759. z=value[2];
  760. }
  761. if(!type) type=GLGE.ROT_XYZ;
  762. var cosx=Math.cos(x);
  763. var sinx=Math.sin(x);
  764. var cosy=Math.cos(y);
  765. var siny=Math.sin(y);
  766. var cosz=Math.cos(z);
  767. var sinz=Math.sin(z);
  768. var rotx=GLGE.matrix4(1,0,0,0,0,cosx,-sinx,0,0,sinx,cosx,0,0,0,0,1);
  769. var roty=GLGE.matrix4(cosy,0,siny,0,0,1,0,0,-siny,0,cosy,0,0,0,0,1);
  770. var rotz=GLGE.matrix4(cosz,-sinz,0,0,sinz,cosz,0,0,0,0,1,0,0,0,0,1);
  771. switch(type){
  772. case GLGE.ROT_XYZ:
  773. return GLGE.mulMat4(rotx,GLGE.mulMat4(roty,rotz));
  774. break;
  775. case GLGE.ROT_XZY:
  776. return GLGE.mulMat4(rotx,GLGE.mulMat4(rotz,roty));
  777. break;
  778. case GLGE.ROT_YXZ:
  779. return GLGE.mulMat4(roty,GLGE.mulMat4(rotx,rotz));
  780. break;
  781. case GLGE.ROT_YZX:
  782. return GLGE.mulMat4(roty,GLGE.mulMat4(rotz,rotx));
  783. break;
  784. case GLGE.ROT_ZXY:
  785. return GLGE.mulMat4(rotz,GLGE.mulMat4(rotx,roty));
  786. break;
  787. case GLGE.ROT_ZYX:
  788. return GLGE.mulMat4(rotz,GLGE.mulMat4(roty,rotx));
  789. break;
  790. }
  791. }
  792. GLGE.angleAxis=function(angle, axis) {
  793. var xmx,ymy,zmz,xmy,ymz,zmx,xms,yms,zms;
  794. axis=[axis[0],axis[1],axis[2],0];
  795. var x = axis[0];
  796. var y = axis[1];
  797. var z = axis[2];
  798. var cos = Math.cos(angle);
  799. var cosi = 1.0 - cos;
  800. var sin = Math.sin(angle);
  801. xms = x * sin;yms = y * sin;zms = z * sin;
  802. xmx = x * x;ymy = y * y;zmz = z * z;
  803. xmy = x * y;ymz = y * z;zmx = z * x;
  804. var matrix = GLGE.matrix4((cosi * xmx) + cos,(cosi * xmy) - zms,(cosi * zmx) + yms,0,
  805. (cosi * xmy) + zms,(cosi * ymy) + cos,(cosi * ymz) - xms,0,
  806. (cosi * zmx) - yms,(cosi * ymz) + xms,(cosi * zmz) + cos,0,
  807. 0,0,0,1);
  808. return GLGE.Mat(matrix);
  809. };
  810. // JHD
  811. GLGE.quatFromAxisAngle = function(axis, angle) {
  812. var quaternion = [];
  813. var halfAngle = angle * 0.5;
  814. var sinus = Math.sin(halfAngle);
  815. var cosinus = Math.cos(halfAngle);
  816. quaternion[0] = axis[0] * sinus;
  817. quaternion[1] = axis[1] * sinus;
  818. quaternion[2] = axis[2] * sinus;
  819. quaternion[3] = cosinus;
  820. return quaternion;
  821. };
  822. GLGE.mulQuat = function(quaternion1, quaternion2) {
  823. var quaternion = [];
  824. var x = quaternion1[0];
  825. var y = quaternion1[1];
  826. var z = quaternion1[2];
  827. var w = quaternion1[3];
  828. var x2 = quaternion2[0];
  829. var y2 = quaternion2[1];
  830. var z2 = quaternion2[2];
  831. var w2 = quaternion2[3];
  832. var a = (y * z2) - (z * y2);
  833. var b = (z * x2) - (x * z2);
  834. var c = (x * y2) - (y * x2);
  835. var d = ((x * x2) + (y * y2)) + (z * z2);
  836. quaternion[0] = ((x * w2) + (x2 * w)) + a;
  837. quaternion[1] = ((y * w2) + (y2 * w)) + b;
  838. quaternion[2] = ((z * w2) + (z2 * w)) + c;
  839. quaternion[3] = (w * w2) - d;
  840. return quaternion;
  841. };
  842. GLGE.mat4FromQuat = function(quaternion) {
  843. // TODO: Optimize with storing the array-wise indexed values
  844. // in direct acessible variables?
  845. var x2 = quaternion[0] * quaternion[0];
  846. var y2 = quaternion[1] * quaternion[1];
  847. var z2 = quaternion[2] * quaternion[2];
  848. var xy = quaternion[0] * quaternion[1];
  849. var zw = quaternion[2] * quaternion[3];
  850. var zx = quaternion[2] * quaternion[0];
  851. var yw = quaternion[1] * quaternion[3];
  852. var yz = quaternion[1] * quaternion[2];
  853. var xw = quaternion[0] * quaternion[3];
  854. var result = [];
  855. result[0] = 1 - (2 * (y2 + z2));
  856. result[1] = 2 * (xy + zw);
  857. result[2] = 2 * (zx - yw);
  858. result[3] = 0;
  859. result[4] = 2 * (xy - zw);
  860. result[5] = 1 - (2 * (z2 + x2));
  861. result[6] = 2 * (yz + xw);
  862. result[7] = 0;
  863. result[8] = 2 * (zx + yw);
  864. result[9] = 2 * (yz - xw);
  865. result[10] = 1 - (2 * (y2 + x2));
  866. result[11] = 0;
  867. result[12] = 0;
  868. result[13] = 0;
  869. result[14] = 0;
  870. result[15] = 1;
  871. return result;
  872. };
  873. // JHD - end
  874. GLGE.quatRotation=function(qx,qy,qz,qw){
  875. return GLGE.matrix4(
  876. 1 - 2*qy*qy - 2*qz*qz,2*qx*qy - 2*qz*qw,2*qx*qz + 2*qy*qw,0,
  877. 2*qx*qy + 2*qz*qw,1 - 2*qx*qx - 2*qz*qz,2*qy*qz - 2*qx*qw,0,
  878. 2*qx*qz - 2*qy*qw,2*qy*qz + 2*qx*qw,1 - 2*qx*qx - 2*qy*qy,0,
  879. 0,0,0,1
  880. );
  881. };
  882. GLGE.makeOrtho=function(left,right,bottom,top,near,far){
  883. var x = -(right+left)/(right-left);
  884. var y = -(top+bottom)/(top-bottom);
  885. var z = -(far+near)/(far-near);
  886. return GLGE.matrix4(2/(right-left), 0, 0, x,
  887. 0, 2/(top-bottom), 0, y,
  888. 0, 0, -2/(far-near), z,
  889. 0, 0, 0, 1);
  890. };
  891. GLGE.makeFrustum=function(left,right,bottom,top,near,far){
  892. var x = 2*near/(right-left);
  893. var y = 2*near/(top-bottom);
  894. var a = (right+left)/(right-left);
  895. var b = (top+bottom)/(top-bottom);
  896. var c = -(far+near)/(far-near);
  897. var d = -2*far*near/(far-near);
  898. return GLGE.matrix4(x, 0, a, 0,
  899. 0, y, b, 0,
  900. 0, 0, c, d,
  901. 0, 0, -1, 0);
  902. };
  903. GLGE.makePerspective=function(fovy, aspect, near, far){
  904. var ymax = near * Math.tan(fovy * 0.00872664625972);
  905. var ymin = -ymax;
  906. var xmin = ymin * aspect;
  907. var xmax = ymax * aspect;
  908. return GLGE.makeFrustum(xmin, xmax, ymin, ymax, near, far);
  909. };
  910. GLGE.makePerspectiveX=function(fovx, aspect, near, far){
  911. var xmax = near * Math.tan(fovx * 0.00872664625972);
  912. var xmin = -xmax;
  913. var ymin = xmin / aspect;
  914. var ymax = xmax / aspect;
  915. return GLGE.makeFrustum(xmin, xmax, ymin, ymax, near, far);
  916. };
  917. GLGE.matrix2Scale=function(m){
  918. var m1=m[0];
  919. var m2=m[1];
  920. var m3=m[2];
  921. var m4=m[4];
  922. var m5=m[5];
  923. var m6=m[6];
  924. var m7=m[8];
  925. var m8=m[9];
  926. var m9=m[10];
  927. var scaleX=Math.sqrt(m1*m1+m2*m2+m3*m3);
  928. var scaleY=Math.sqrt(m4*m4+m5*m5+m6*m6);
  929. var scaleZ=Math.sqrt(m7*m7+m8*m8+m9*m9);
  930. return [scaleX,scaleY,scaleZ]
  931. }
  932. GLGE.rotationMatrix2Quat=function(m){
  933. var tr = m[0] + m[5] + m[10]+1.0;
  934. var S,x,y,z,w;
  935. if (tr > 0) {
  936. S = 0.5/Math.sqrt(tr);
  937. w = 0.25 / S;
  938. x = (m[9] - m[6]) * S;
  939. y = (m[2] - m[8]) * S;
  940. z = (m[4] - m[1]) * S;
  941. } else if ((m[0] > m[5])&&(m[0] > m[10])) {
  942. S = Math.sqrt(1.0 + m[0] - m[5] - m[10]) * 2;
  943. w = (m[9] - m[6]) / S;
  944. x = 0.25 / S;
  945. y = (m[1] + m[4]) / S;
  946. z = (m[2] + m[8]) / S;
  947. } else if (m[5] > m[10]) {
  948. S = Math.sqrt(1.0 + m[5] - m[0] - m[10]) * 2;
  949. w = (m[2] - m[8]) / S;
  950. x = (m[1] + m[4]) / S;
  951. y = 0.25 / S;
  952. z = (m[6] + m[9]) / S;
  953. } else {
  954. S = Math.sqrt(1.0 + m[10] - m[0] - m[5]) * 2;
  955. w = (m[4] - m[1]) / S;
  956. x = (m[2] + m[8]) / S;
  957. y = (m[6] + m[9]) / S;
  958. z = 0.25 / S;
  959. }
  960. var N=Math.sqrt(x*x+y*y+z*z+w*w)
  961. return [x/N,y/N,z/N,w/N];
  962. }
  963. //returns plane as array [X,Y,Z,D]
  964. GLGE.rayToPlane=function(origin,dir){
  965. var dirnorm=GLGE.toUnitVec3(dir);
  966. return [dirnorm[0],dirnorm[1],dirnorm[2],GLGE.dotVec3(origin,dirnorm)];
  967. }
  968. GLGE.rayIntersectPlane=function(origin,dir,plane){
  969. var planeN=[plane[0],plane[1],plane[2]];
  970. var planeD=plane[3];
  971. var vdir=GLGE.dotVec3(planeN,dir);
  972. if(vdir<=0){
  973. //ray in wrong direction
  974. return false;
  975. }
  976. var vo=-(GLGE.dotVec3(planeN,origin)+planeD);
  977. var t=vo/vdir;
  978. if(t<=0){
  979. return false;
  980. }
  981. return GLGE.addVec3(origin,GLGE.scaleVec3(dir,t));
  982. }
  983. //assumes perspective projection
  984. GLGE.screenToDirection=function(x,y,width,height,proj){
  985. xcoord = -( ( ( 2 * x ) / width ) - 1 ) / proj[0];
  986. ycoord =( ( ( 2 * y ) / height ) - 1 ) / proj[5];
  987. zcoord = 1;
  988. return GLGE.toUnitVec3([xcoord,ycoord,zcoord]);
  989. }
  990. GLGE.BoundingVolume=function(minX,maxX,minY,maxY,minZ,maxZ){
  991. this.limits=[minX,maxX,minY,maxY,minZ,maxZ];
  992. this.calcProps();
  993. }
  994. GLGE.BoundingVolume.prototype.getCornerPoints=function(){
  995. return this.points;
  996. }
  997. //returns the radius of a bounding sphere
  998. GLGE.BoundingVolume.prototype.getSphereRadius=function(){
  999. return this.radius;
  1000. }
  1001. //returns the center of a bounding volume
  1002. GLGE.BoundingVolume.prototype.getCenter=function(){
  1003. return this.center;
  1004. }
  1005. GLGE.BoundingVolume.prototype.isNull=function(){
  1006. return this.limits[0]==0&&this.limits[1]==0&&this.limits[2]==0&&this.limits[3]==0&&this.limits[4]==0&&this.limits[5]==0;
  1007. }
  1008. //adds an additional bounding volume to resize the current and returns the result
  1009. GLGE.BoundingVolume.prototype.addBoundingVolume=function(vol){
  1010. if (this.isNull()) {
  1011. this.limits[0]=vol.limits[0];
  1012. this.limits[1]=vol.limits[1];
  1013. this.limits[2]=vol.limits[2];
  1014. this.limits[3]=vol.limits[3];
  1015. this.limits[4]=vol.limits[4];
  1016. this.limits[5]=vol.limits[5];
  1017. }
  1018. else if (!vol.isNull()) {
  1019. this.limits[0]=Math.min(vol.limits[0],this.limits[0]);
  1020. this.limits[2]=Math.min(vol.limits[2],this.limits[2]);
  1021. this.limits[4]=Math.min(vol.limits[4],this.limits[4]);
  1022. this.limits[1]=Math.max(vol.limits[1],this.limits[1]);
  1023. this.limits[3]=Math.max(vol.limits[3],this.limits[3]);
  1024. this.limits[5]=Math.max(vol.limits[5],this.limits[5]);
  1025. }
  1026. this.calcProps();
  1027. }
  1028. //scales a volume based on a transform matrix
  1029. GLGE.BoundingVolume.prototype.applyMatrix=function(matrix){
  1030. var coord0=GLGE.mulMat4Vec4(matrix,[this.limits[0],this.limits[2],this.limits[4],1]);
  1031. var coord1=GLGE.mulMat4Vec4(matrix,[this.limits[1],this.limits[2],this.limits[4],1]);
  1032. var coord2=GLGE.mulMat4Vec4(matrix,[this.limits[0],this.limits[3],this.limits[4],1]);
  1033. var coord3=GLGE.mulMat4Vec4(matrix,[this.limits[1],this.limits[3],this.limits[4],1]);
  1034. var coord4=GLGE.mulMat4Vec4(matrix,[this.limits[0],this.limits[2],this.limits[5],1]);
  1035. var coord5=GLGE.mulMat4Vec4(matrix,[this.limits[1],this.limits[2],this.limits[5],1]);
  1036. var coord6=GLGE.mulMat4Vec4(matrix,[this.limits[0],this.limits[3],this.limits[5],1]);
  1037. var coord7=GLGE.mulMat4Vec4(matrix,[this.limits[1],this.limits[3],this.limits[5],1]);
  1038. this.limits[0]=Math.min(coord0[0],coord1[0],coord2[0],coord3[0],coord4[0],coord5[0],coord6[0],coord7[0]);
  1039. this.limits[1]=Math.max(coord0[0],coord1[0],coord2[0],coord3[0],coord4[0],coord5[0],coord6[0],coord7[0]);
  1040. this.limits[2]=Math.min(coord0[1],coord1[1],coord2[1],coord3[1],coord4[1],coord5[1],coord6[1],coord7[1]);
  1041. this.limits[3]=Math.max(coord0[1],coord1[1],coord2[1],coord3[1],coord4[1],coord5[1],coord6[1],coord7[1]);
  1042. this.limits[4]=Math.min(coord0[2],coord1[2],coord2[2],coord3[2],coord4[2],coord5[2],coord6[2],coord7[2]);
  1043. this.limits[5]=Math.max(coord0[2],coord1[2],coord2[2],coord3[2],coord4[2],coord5[2],coord6[2],coord7[2]);
  1044. this.calcProps();
  1045. }
  1046. GLGE.BoundingVolume.prototype.calcProps=function(){
  1047. var minX=this.limits[0];
  1048. var maxX=this.limits[1];
  1049. var minY=this.limits[2];
  1050. var maxY=this.limits[3];
  1051. var minZ=this.limits[4];
  1052. var maxZ=this.limits[5];
  1053. this.points=[
  1054. [minX,minY,minZ],
  1055. [maxX,minY,minZ],
  1056. [minX,maxY,minZ],
  1057. [maxX,maxY,minZ],
  1058. [minX,minY,maxZ],
  1059. [maxX,minY,maxZ],
  1060. [minX,maxY,maxZ],
  1061. [maxX,maxY,maxZ]
  1062. ];
  1063. this.center=[(this.limits[1]-this.limits[0])/2+this.limits[0],(this.limits[3]-this.limits[2])/2+this.limits[2],(this.limits[5]-this.limits[4])/2+this.limits[4]];
  1064. var dx=this.limits[0]-this.center[0];
  1065. var dy=this.limits[2]-this.center[1];
  1066. var dz=this.limits[4]-this.center[2];
  1067. this.radius=Math.sqrt(dx*dx+dy*dy+dz*dz);
  1068. }
  1069. GLGE.BoundingVolume.prototype.clone=function(){
  1070. return new GLGE.BoundingVolume(this.limits[0],this.limits[1],this.limits[2],this.limits[3],this.limits[4],this.limits[5]);
  1071. }
  1072. GLGE.BoundingVolume.prototype.toString=function(){
  1073. return this.limits.toString();
  1074. }
  1075. //creates the bounding planes for the cameraViewProjectionMatrix
  1076. GLGE.cameraViewProjectionToPlanes=function(cvp){
  1077. var cvpinv=GLGE.inverseMat4(cvp);
  1078. var mulMat4Vec4=GLGE.mulMat4Vec4;
  1079. var subVec3=GLGE.subVec3;
  1080. var crossVec3=GLGE.crossVec3;
  1081. var toUnitVec3=GLGE.toUnitVec3;
  1082. var dotVec3=GLGE.dotVec3
  1083. var nbl=mulMat4Vec4(cvpinv,[-1,-1,-1,1]);
  1084. var nbr=mulMat4Vec4(cvpinv,[1,-1,-1,1]);
  1085. var fbl=mulMat4Vec4(cvpinv,[-1,-1,1,1]);
  1086. var ntr=mulMat4Vec4(cvpinv,[1,1,-1,1]);
  1087. var ftr=mulMat4Vec4(cvpinv,[1,1,1,1]);
  1088. var ftl=mulMat4Vec4(cvpinv,[-1,1,1,1]);
  1089. nbl=[nbl[0]/nbl[3],nbl[1]/nbl[3],nbl[2]/nbl[3]];
  1090. nbr=[nbr[0]/nbr[3],nbr[1]/nbr[3],nbr[2]/nbr[3]];
  1091. fbl=[fbl[0]/fbl[3],fbl[1]/fbl[3],fbl[2]/fbl[3]];
  1092. ntr=[ntr[0]/ntr[3],ntr[1]/ntr[3],ntr[2]/ntr[3]];
  1093. ftr=[ftr[0]/ftr[3],ftr[1]/ftr[3],ftr[2]/ftr[3]];
  1094. ftl=[ftl[0]/ftl[3],ftl[1]/ftl[3],ftl[2]/ftl[3]];
  1095. var nearnorm=toUnitVec3(crossVec3(subVec3(ntr,nbr),subVec3(nbl,nbr)));
  1096. var farnorm=toUnitVec3(crossVec3(subVec3(ftl,fbl),subVec3(ftr,fbl)));
  1097. var leftnorm=toUnitVec3(crossVec3(subVec3(nbl,fbl),subVec3(ftl,fbl)));
  1098. var rightnorm=toUnitVec3(crossVec3(subVec3(ftr,ntr),subVec3(ntr,nbr)));
  1099. var topnorm=toUnitVec3(crossVec3(subVec3(ftl,ntr),subVec3(ntr,ftr)));
  1100. var bottomnorm=toUnitVec3(crossVec3(subVec3(nbl,nbr),subVec3(fbl,nbl)));
  1101. nearnorm.push(dotVec3(nearnorm,nbl));
  1102. farnorm.push(dotVec3(farnorm,fbl));
  1103. leftnorm.push(dotVec3(leftnorm,nbl));
  1104. rightnorm.push(dotVec3(rightnorm,nbr));
  1105. topnorm.push(dotVec3(topnorm,ftr));
  1106. bottomnorm.push(dotVec3(bottomnorm,nbl));
  1107. //might be worth calulating the frustum sphere for optimization at this point!
  1108. return [nearnorm,farnorm,leftnorm,rightnorm,topnorm,bottomnorm];
  1109. }
  1110. //Checks if sphere is within frustum planes
  1111. //sphere passed as [center.x,center.y,center.z,radius]
  1112. GLGE.sphereInFrustumPlanes=function(sphere,planes){
  1113. var sphere0=sphere[0];var sphere1=sphere[1];
  1114. var sphere2=sphere[2];var sphere3=sphere[3];
  1115. var plane0=planes[0];var plane1=planes[1];
  1116. var plane2=planes[2];var plane3=planes[3];
  1117. var plane4=planes[4];var plane5=planes[5];
  1118. if(sphere0*plane0[0] + sphere1*plane0[1] + sphere2*plane0[2] - plane0[3] - sphere3 > 0
  1119. || sphere0*plane1[0] + sphere1*plane1[1] + sphere2*plane1[2] - plane1[3] - sphere3 > 0
  1120. || sphere0*plane2[0] + sphere1*plane2[1] + sphere2*plane2[2] - plane2[3] - sphere3 > 0
  1121. || sphere0*plane3[0] + sphere1*plane3[1] + sphere2*plane3[2] - plane3[3] - sphere3 > 0
  1122. || sphere0*plane4[0] + sphere1*plane4[1] + sphere2*plane4[2] - plane4[3] - sphere3 > 0
  1123. || sphere0*plane5[0] + sphere1*plane5[1] + sphere2*plane5[2] - plane5[3] - sphere3 > 0){
  1124. return false;
  1125. }else{
  1126. return true;
  1127. }
  1128. }
  1129. //checks if cube points are within the frustum planes
  1130. GLGE.pointsInFrustumPlanes=function(points,planes){
  1131. var plane0=planes[0];var plane1=planes[1];
  1132. var plane2=planes[2];var plane3=planes[3];
  1133. var plane4=planes[4];var plane5=planes[5];
  1134. var x, y, z;
  1135. for(var i=0; i<points.length;i++){
  1136. x=points[i][0];
  1137. y=points[i][1];
  1138. z=points[i][2];
  1139. if(x*plane0[0] + y*plane0[1] + z*plane0[2] - plane0[3] > 0
  1140. && x*plane1[0] + y*plane1[1] + z*plane1[2] - plane1[3] > 0
  1141. && x*plane2[0] + y*plane2[1] + z*plane2[2] - plane3[3] > 0
  1142. && x*plane3[0] + y*plane3[1] + z*plane3[2] - plane4[3] > 0
  1143. && x*plane4[0] + y*plane4[1] + z*plane4[2] - plane4[3] > 0
  1144. && x*plane5[0] + y*plane5[1] + z*plane5[2] - plane5[3] > 0){
  1145. return false;
  1146. }
  1147. }
  1148. return true;
  1149. }
  1150. //get projection matrix for a directional light
  1151. GLGE.getDirLightProjection=function(cvp,light,projectedDistance,distance){
  1152. var pointTransform=GLGE.mulMat4(light,GLGE.inverseMat4(cvp));
  1153. var min=[0,0,0];
  1154. var max=[0,0,0];
  1155. for(var x=0;x<2;x++){
  1156. for(var y=0;y<2;y++){
  1157. for(var z=0;z<2;z++){
  1158. var vec=GLGE.mulMat4Vec4(pointTransform,[x*2-1,y*2-1,z*projectedDistance,1]);
  1159. vec[0]=vec[0]/vec[3];vec[1]=vec[1]/vec[3];vec[2]=vec[2]/vec[3];
  1160. min[0]=min[0] > vec[0] ? vec[0] : min[0];
  1161. min[1]=min[1] > vec[1] ? vec[1] : min[1];
  1162. max[0]=max[0] < vec[0] ? vec[0] : max[0];
  1163. max[1]=max[1] < vec[1] ? vec[1] : max[1];
  1164. max[2]=max[2] < vec[2] ? vec[2] : max[2];
  1165. }
  1166. }
  1167. }
  1168. var mat=GLGE.makeOrtho(min[0],max[0],min[1],max[1],0.01,+distance);
  1169. //mat[0]*=8;
  1170. //mat[5]*=8;
  1171. //var mat=GLGE.makeFrustum(min[0],max[0],min[1],max[1],500,0.01);
  1172. //var mat=GLGE.makeOrtho(-30,30,-30,30,0.01,500);
  1173. //alert(mat);
  1174. return mat
  1175. };
  1176. function GLGE_mathUnitTest() {
  1177. var a=GLGE.Vec([1,2,3,4]);
  1178. var b=GLGE.Vec4(GLGE.getVec4(a,3),
  1179. GLGE.get1basedVec4(a,3),
  1180. GLGE.getVec4(a,1),
  1181. GLGE.getVec4(a,0));
  1182. var c=GLGE.identMatrix();
  1183. var d=GLGE.mulMat4Vec4(c,b);
  1184. if (GLGE.getVec4(d,0)!=4||
  1185. GLGE.getVec4(d,1)!=3||
  1186. GLGE.getVec4(d,2)!=2||
  1187. GLGE.getVec4(d,3)!=1) {
  1188. throw "Unit Test 1 failed MatVecMul "+d;
  1189. }
  1190. var m=GLGE.Mat4([3,4,5,0,.5,.75,0,0,.75,.5,0,0,.25,.25,1,1]);
  1191. var m1=GLGE.Mat4([2,1,8,2,1,4,3,2,1,.5,6.5,2,8,3,1,.25]);
  1192. var mm1=GLGE.mulMat4(m,m1);
  1193. var am1=GLGE.Mat4([15,21.5,68.5,24,
  1194. 1.75,3.5,6.25,2.5,
  1195. 2,2.75,7.5,2.5,
  1196. 9.75,4.75,10.25,3.25]);
  1197. for (var i=0;i<4;++i) {
  1198. for (var j=0;j<4;++j) {
  1199. var diff=GLGE.getMat4(mm1,i,j)-GLGE.getMat4(am1,i,j);
  1200. if (diff<.000001&&diff>-.000001) {
  1201. }else {
  1202. throw "Unit Test 1 failed Multiplication "+GLGE.getMat4(mm1,i,j)+" != "+GLGE.getMat4(am1,i,j);
  1203. }
  1204. }
  1205. }
  1206. var inv = GLGE.inverseMat4(m);
  1207. var k = GLGE.mulMat4(m,inv);
  1208. var l = GLGE.mulMat4(inv,m);
  1209. for (var i=0;i<4;++i) {
  1210. for (var j=0;j<4;++j) {
  1211. var diff=GLGE.getMat4(k,i,j)-GLGE.getMat4(c,i,j);
  1212. if (diff<.0001&&diff>-.0001) {
  1213. }else {
  1214. throw "Unit Test 1 failed Inverse "+GLGE.getMat4(k,i,j)+" != "+GLGE.getMat4(c,i,j);
  1215. }
  1216. }
  1217. }
  1218. }
  1219. GLGE_mathUnitTest() ;
  1220. })(GLGE);
  1221. /*
  1222. GLGE WebGL Graphics Engine
  1223. Copyright (c) 2010, Paul Brunt
  1224. All rights reserved.
  1225. Redistribution and use in source and binary forms, with or without
  1226. modification, are permitted provided that the following conditions are met:
  1227. * Redistributions of source code must retain the above copyright
  1228. notice, this list of conditions and the following disclaimer.
  1229. * Redistributions in binary form must reproduce the above copyright
  1230. notice, this list of conditions and the following disclaimer in the
  1231. documentation and/or other materials provided with the distribution.
  1232. * Neither the name of GLGE nor the
  1233. names of its contributors may be used to endorse or promote products
  1234. derived from this software without specific prior written permission.
  1235. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  1236. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  1237. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  1238. DISCLAIMED. IN NO EVENT SHALL PAUL BRUNT BE LIABLE FOR ANY
  1239. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  1240. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  1241. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  1242. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  1243. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  1244. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  1245. */
  1246. /**
  1247. * @fileOverview
  1248. * @name glge.js
  1249. * @author me@paulbrunt.co.uk
  1250. */
  1251. if(typeof(GLGE) == "undefined"){
  1252. /**
  1253. * @namespace Holds the functionality of the library
  1254. */
  1255. GLGE = {};
  1256. }
  1257. (function(GLGE){
  1258. //speed ups parsing a float that is already a float is expensive!
  1259. var parseFloat2=function(val){
  1260. if(typeof val!="number") return parseFloat(val);
  1261. else return val;
  1262. }
  1263. /**
  1264. * Function to augment one object with another
  1265. * @param {object} obj1 Source Object
  1266. * @param {object} obj2 Destination Object
  1267. */
  1268. GLGE.augment=function(obj1,obj2){
  1269. obj2.prototype.baseclass = obj1;
  1270. for(var proto in obj1.prototype){
  1271. if(!obj2.prototype[proto]) // do not overwrite functions of the derived objects
  1272. obj2.prototype[proto]=obj1.prototype[proto];
  1273. else // Attach those to the baseclass instead. Use 'call(this)' to call baseclass methods
  1274. obj2.prototype.baseclass[proto]=obj1.prototype[proto];
  1275. }
  1276. }
  1277. /**
  1278. * Moves all GLGE function to global
  1279. **/
  1280. GLGE.makeGlobal=function(){
  1281. for(var key in GLGE){
  1282. window[key]=GLGE[key];
  1283. }
  1284. }
  1285. GLGE.New=function(createclass){
  1286. if(GLGE[createclass].prototype.className!=""){
  1287. return new GLGE[createclass]();
  1288. }else{
  1289. return false;
  1290. }
  1291. }
  1292. GLGE.now = function(){
  1293. return parseInt(new Date().getTime());
  1294. };
  1295. /**
  1296. * @constant
  1297. * @description Enumeration for TRUE
  1298. */
  1299. GLGE.TRUE=1;
  1300. /**
  1301. * @constant
  1302. * @description Enumeration for FALSE
  1303. */
  1304. GLGE.FALSE=0;
  1305. /**
  1306. * @constant
  1307. * @description Enumeration for global refrance frame
  1308. */
  1309. GLGE.GLOBAL=0;
  1310. /**
  1311. * @constant
  1312. * @description Enumeration for local refrance frame
  1313. */
  1314. GLGE.LOCAL=1;
  1315. /**
  1316. * @constant
  1317. * @description Enumeration for tri rendering
  1318. */
  1319. GLGE.DRAW_TRIS=1;
  1320. /**
  1321. * @constant
  1322. * @description Enumeration for line rendering
  1323. */
  1324. GLGE.DRAW_LINES=2;
  1325. /**
  1326. * @constant
  1327. * @description Enumeration for line loop rendering
  1328. */
  1329. GLGE.DRAW_LINELOOPS=3;
  1330. /**
  1331. * @constant
  1332. * @description Enumeration for line loop rendering
  1333. */
  1334. GLGE.DRAW_LINESTRIPS=4;
  1335. /**
  1336. * @constant
  1337. * @description Enumeration for point rendering
  1338. */
  1339. GLGE.DRAW_POINTS=5;
  1340. /**
  1341. * @constant
  1342. * @description Enumeration for point rendering
  1343. */
  1344. GLGE.DRAW_TRIANGLESTRIP=6;
  1345. /**
  1346. * @constant
  1347. * @description Enumeration for rendering using default shader
  1348. */
  1349. GLGE.RENDER_DEFAULT=0;
  1350. /**
  1351. * @constant
  1352. * @description Enumeration for rendering using shadow shader
  1353. */
  1354. GLGE.RENDER_SHADOW=1;
  1355. /**
  1356. * @constant
  1357. * @description Enumeration for rendering using pick shader
  1358. */
  1359. GLGE.RENDER_PICK=2;
  1360. /**
  1361. * @constant
  1362. * @description Enumeration for rendering using normal shader
  1363. */
  1364. GLGE.RENDER_NORMAL=3;
  1365. /**
  1366. * @constant
  1367. * @description Enumeration for emit rendering
  1368. */
  1369. GLGE.RENDER_EMIT=4;
  1370. /**
  1371. * @constant
  1372. * @description Enumeration for depth rendering
  1373. */
  1374. GLGE.RENDER_DEPTH=5;
  1375. /**
  1376. * @constant
  1377. * @description Enumeration for no rendering
  1378. */
  1379. GLGE.RENDER_NULL=6;
  1380. /**
  1381. * @constant
  1382. * @description Enumeration for box bound text picking
  1383. */
  1384. GLGE.TEXT_BOXPICK=1;
  1385. /**
  1386. * @constant
  1387. * @description Enumeration for text bound text picking
  1388. */
  1389. GLGE.TEXT_TEXTPICK=2;
  1390. /**
  1391. * @constant
  1392. * @description Enumeration for euler rotaions mode
  1393. */
  1394. GLGE.P_EULER=1;
  1395. /**
  1396. * @constant
  1397. * @description Enumeration for quaternions mode
  1398. */
  1399. GLGE.P_QUAT=2;
  1400. /**
  1401. * @constant
  1402. * @description Enumeration for matrix rotation mode
  1403. */
  1404. GLGE.P_MATRIX=3;
  1405. /**
  1406. * @constant
  1407. * @description Enumeration for no value
  1408. */
  1409. GLGE.NONE=0;
  1410. /**
  1411. * @constant
  1412. * @description Enumeration for X-Axis
  1413. */
  1414. GLGE.XAXIS=1;
  1415. /**
  1416. * @constant
  1417. * @description Enumeration for Y-Axis
  1418. */
  1419. GLGE.YAXIS=2;
  1420. /**
  1421. * @constant
  1422. * @description Enumeration for Z-Axis
  1423. */
  1424. GLGE.ZAXIS=3;
  1425. /**
  1426. * @constant
  1427. * @description Enumeration for +X-Axis
  1428. */
  1429. GLGE.POS_XAXIS=1;
  1430. /**
  1431. * @constant
  1432. * @description Enumeration for -X-Axis
  1433. */
  1434. GLGE.NEG_XAXIS=2;
  1435. /**
  1436. * @constant
  1437. * @description Enumeration for +Y-Axis
  1438. */
  1439. GLGE.POS_YAXIS=3;
  1440. /**
  1441. * @constant
  1442. * @description Enumeration for -Y-Axis
  1443. */
  1444. GLGE.NEG_YAXIS=4;
  1445. /**
  1446. * @constant
  1447. * @description Enumeration for +Z-Axis
  1448. */
  1449. GLGE.POS_ZAXIS=5;
  1450. /**
  1451. * @constant
  1452. * @description Enumeration for -Z-Axis
  1453. */
  1454. GLGE.NEG_ZAXIS=6;
  1455. GLGE.ZERO="ZERO";
  1456. GLGE.ONE="ONE";
  1457. GLGE.SRC_COLOR="SRC_COLOR";
  1458. GLGE.ONE_MINUS_SRC_COLOR="ONE_MINUS_SRC_COLOR";
  1459. GLGE.SRC_ALPHA="SRC_ALPHA";
  1460. GLGE.ONE_MINUS_SRC_ALPHA="ONE_MINUS_SRC_ALPHA";
  1461. GLGE.DST_ALPHA="DST_ALPHA";
  1462. GLGE.ONE_MINUS_DST_ALPHA="ONE_MINUS_DST_ALPHA";
  1463. /**
  1464. * @constant
  1465. * @description Linear blending function
  1466. */
  1467. GLGE.LINEAR_BLEND=function(value){
  1468. return value;
  1469. }
  1470. /**
  1471. * @constant
  1472. * @description Quadratic blending function
  1473. */
  1474. GLGE.QUAD_BLEND=function(value){
  1475. return value*value;
  1476. }
  1477. /**
  1478. * @constant
  1479. * @description Special blending function
  1480. */
  1481. GLGE.SPECIAL_BLEND=function(value){
  1482. value=value*(2-value);
  1483. return value*value;
  1484. }
  1485. GLGE.error=function(error){
  1486. if (console&&console.log)
  1487. console.log("GLGE error: "+error);
  1488. //do not use a modal dialog to indicate this users can override GLGE.error if they desire
  1489. };
  1490. GLGE.warning=function(warning){
  1491. if (console&&console.log)
  1492. console.log("GLGE warning: "+warning);
  1493. //do not use a modal dialog to indicate this users can override GLGE.warning if they desire
  1494. };
  1495. /**
  1496. * @namespace Holds the global asset store
  1497. */
  1498. GLGE.Assets={};
  1499. GLGE.Assets.assets={};
  1500. //don't need to register assets unless we are using network or webworkers
  1501. GLGE.REGISTER_ASSETS=true;
  1502. GLGE.Assets.createUUID=function(){
  1503. var data=["0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"];
  1504. var data2=["8","9","A","B"];
  1505. uuid="";
  1506. for(var i=0;i<38;i++){
  1507. switch(i){
  1508. case 8:uuid=uuid+"-";break;
  1509. case 13:uuid=uuid+"-";break;
  1510. case 18:uuid=uuid+"-";break;
  1511. case 14:uuid=uuid+"4";break;
  1512. case 19:uuid=uuid+data2[Math.round(Math.random()*3)];break;
  1513. default:uuid=uuid+data[Math.round(Math.random()*15)];break;
  1514. }
  1515. }
  1516. return uuid;
  1517. }
  1518. /**
  1519. * @function registers a new asset
  1520. */
  1521. GLGE.Assets.registerAsset=function(obj,uid){
  1522. if(typeof uid=="object"){
  1523. if(obj._) obj._(uid);
  1524. uid=uid.uid;
  1525. }
  1526. if(!uid){
  1527. uid=GLGE.Assets.createUUID();
  1528. };
  1529. obj.uid=uid;
  1530. if(GLGE.REGISTER_ASSETS){
  1531. GLGE.Assets.assets[uid]=obj;
  1532. }
  1533. }
  1534. /**
  1535. * @function removes an asset
  1536. */
  1537. GLGE.Assets.unregisterAsset=function(uid){
  1538. delete GLGE.Assets.assets[uid];
  1539. }
  1540. /**
  1541. * @function finds an asset by uid
  1542. */
  1543. GLGE.Assets.get=function(uid){
  1544. var value=GLGE.Assets.assets[uid];
  1545. if(value){
  1546. return value;
  1547. }else{
  1548. return false;
  1549. }
  1550. }
  1551. /**
  1552. * @function hashing function
  1553. * @private
  1554. */
  1555. GLGE.DJBHash=function(str){
  1556. var hash = 5381;
  1557. for(var i = 0; i < str.length; i++){
  1558. hash = ((hash << 5) + hash) + str.charCodeAt(i);
  1559. }
  1560. return hash;
  1561. }
  1562. /**
  1563. * @function check if shader is already created if not then create it
  1564. * @private
  1565. */
  1566. GLGE.getGLShader=function(gl,type,str){
  1567. var hash=GLGE.DJBHash(str);
  1568. if(!gl.shaderCache) gl.shaderCache={};
  1569. if(!gl.shaderCache[hash]){
  1570. var shader=gl.createShader(type);
  1571. gl.shaderSource(shader, str);
  1572. gl.compileShader(shader);
  1573. if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
  1574. try {
  1575. GLGE.error(gl.getShaderInfoLog(shader));
  1576. return;
  1577. } catch (e) {
  1578. /* Firefox hack: Assume no error if there was no shader log. */
  1579. }
  1580. }
  1581. gl.shaderCache[hash]=shader;
  1582. }
  1583. return gl.shaderCache[hash];
  1584. }
  1585. var progIdx=0;
  1586. /**
  1587. * @function tries to re use programs
  1588. * @private
  1589. */
  1590. GLGE.getGLProgram=function(gl,vShader,fShader){
  1591. if(!gl.programCache) gl.programCache=[];
  1592. var programCache=gl.programCache;
  1593. for(var i=0; i<programCache.length;i++){
  1594. if(programCache[i].fShader==fShader && programCache[i].vShader==vShader){
  1595. return programCache[i].program;
  1596. }
  1597. }
  1598. var program=gl.createProgram();
  1599. program.progIdx=progIdx++;
  1600. gl.attachShader(program, vShader);
  1601. gl.attachShader(program, fShader);
  1602. gl.linkProgram(program);
  1603. if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
  1604. GLGE.error("Couldn't link shader: " + gl.getProgramInfoLog(program));
  1605. }
  1606. programCache.push({vShader:vShader,fShader:fShader,program:program});
  1607. if(!program.uniformDetails){
  1608. program.uniformDetails={};
  1609. var uniforms = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS);
  1610. for (var i=0;i<uniforms;++i) {
  1611. var info=gl.getActiveUniform(program, i);
  1612. program.uniformDetails[info.name]={loc:GLGE.getUniformLocation(gl,program,info.name),info:info};
  1613. }
  1614. }
  1615. return program;
  1616. }
  1617. /**
  1618. * function to cache the uniform locations
  1619. * @param {glcontext} the gl context of the program
  1620. * @param {program} the shader program
  1621. * @param {string} the uniform name
  1622. * @private
  1623. */
  1624. GLGE.getUniformLocation=function(gl,program, uniform){
  1625. /*if(program.uniformDetails[uniform]){
  1626. return program.uniformDetails[uniform].loc;
  1627. }else{
  1628. return gl.getUniformLocation(program, uniform);
  1629. }*/
  1630. if(!program.uniformCache) program.uniformCache={};
  1631. if(!program.uniformChecked) program.uniformChecked={};
  1632. if(!program.uniformChecked[uniform]){
  1633. program.uniformCache[uniform]=gl.getUniformLocation(program, uniform);
  1634. program.uniformChecked[uniform]=true;
  1635. }
  1636. return program.uniformCache[uniform];
  1637. };
  1638. /**
  1639. * functions to set uniforms with location check.
  1640. */
  1641. GLGE.setUniform=function(gl,type,location,value){
  1642. if(typeof value=="string") value=+value;
  1643. if(location!=null)
  1644. gl["uniform"+type](location,value);
  1645. };
  1646. GLGE.setUniform3=function(gl,type,location,value1,value2,value3){
  1647. if(typeof value1=="string") value1=+value1;
  1648. if(typeof value2=="string") value2=+value2;
  1649. if(typeof value3=="string") value3=+value3;
  1650. if(location!=null)
  1651. gl["uniform"+type](location,value1,value2,value3);
  1652. };
  1653. GLGE.setUniform2=function(gl,type,location,value1,value2){
  1654. if(typeof value1=="string") value1=+value1;
  1655. if(typeof value2=="string") value2=+value2;
  1656. if(location!=null)
  1657. gl["uniform"+type](location,value1,value2);
  1658. };
  1659. GLGE.setUniform4=function(gl,type,location,value1,value2,value3,value4){
  1660. if(location!=null)
  1661. gl["uniform"+type](location,value1,value2,value3,value4);
  1662. };
  1663. GLGE.setUniformMatrix=function(gl,type,location,transpose,value){
  1664. if(location!=null)
  1665. gl["uniform"+type](location,transpose,value);
  1666. };
  1667. /**
  1668. * function to cache the attribute locations
  1669. * @param {glcontext} the gl context of the program
  1670. * @param {program} the shader program
  1671. * @param {string} the attribe name
  1672. * @private
  1673. */
  1674. GLGE.getAttribLocation=function(gl,program, attrib){
  1675. if(!program.attribCache) program.attribCache={};
  1676. if(program.attribCache[attrib]==undefined){
  1677. program.attribCache[attrib]=gl.getAttribLocation(program, attrib);
  1678. }
  1679. return program.attribCache[attrib];
  1680. }
  1681. /**
  1682. * function to parse a colour input into RGB eg #ff00ff, red, rgb(100,100,100)
  1683. * @param {string} color the color to parse
  1684. */
  1685. GLGE.colorParse=function(color){
  1686. var red,green,blue,alpha;
  1687. //defines the color names
  1688. var color_names = {
  1689. aliceblue: 'f0f8ff', antiquewhite: 'faebd7', aqua: '00ffff',
  1690. aquamarine: '7fffd4', azure: 'f0ffff', beige: 'f5f5dc',
  1691. bisque: 'ffe4c4', black: '000000', blanchedalmond: 'ffebcd',
  1692. blue: '0000ff', blueviolet: '8a2be2', brown: 'a52a2a',
  1693. burlywood: 'deb887', cadetblue: '5f9ea0', chartreuse: '7fff00',
  1694. chocolate: 'd2691e', coral: 'ff7f50', cornflowerblue: '6495ed',
  1695. cornsilk: 'fff8dc', crimson: 'dc143c', cyan: '00ffff',
  1696. darkblue: '00008b', darkcyan: '008b8b', darkgoldenrod: 'b8860b',
  1697. darkgray: 'a9a9a9', darkgreen: '006400', darkkhaki: 'bdb76b',
  1698. darkmagenta: '8b008b', darkolivegreen: '556b2f', darkorange: 'ff8c00',
  1699. darkorchid: '9932cc', darkred: '8b0000', darksalmon: 'e9967a',
  1700. darkseagreen: '8fbc8f', darkslateblue: '483d8b', darkslategray: '2f4f4f',
  1701. darkturquoise: '00ced1', darkviolet: '9400d3', deeppink: 'ff1493',
  1702. deepskyblue: '00bfff', dimgray: '696969', dodgerblue: '1e90ff',
  1703. feldspar: 'd19275', firebrick: 'b22222', floralwhite: 'fffaf0',
  1704. forestgreen: '228b22', fuchsia: 'ff00ff', gainsboro: 'dcdcdc',
  1705. ghostwhite: 'f8f8ff', gold: 'ffd700', goldenrod: 'daa520',
  1706. gray: '808080', green: '008000', greenyellow: 'adff2f',
  1707. honeydew: 'f0fff0', hotpink: 'ff69b4', indianred : 'cd5c5c',
  1708. indigo : '4b0082', ivory: 'fffff0', khaki: 'f0e68c',
  1709. lavender: 'e6e6fa', lavenderblush: 'fff0f5', lawngreen: '7cfc00',
  1710. lemonchiffon: 'fffacd', lightblue: 'add8e6', lightcoral: 'f08080',
  1711. lightcyan: 'e0ffff', lightgoldenrodyellow: 'fafad2', lightgrey: 'd3d3d3',
  1712. lightgreen: '90ee90', lightpink: 'ffb6c1', lightsalmon: 'ffa07a',
  1713. lightseagreen: '20b2aa', lightskyblue: '87cefa', lightslateblue: '8470ff',
  1714. lightslategray: '778899', lightsteelblue: 'b0c4de', lightyellow: 'ffffe0',
  1715. lime: '00ff00', limegreen: '32cd32', linen: 'faf0e6',
  1716. magenta: 'ff00ff', maroon: '800000', mediumaquamarine: '66cdaa',
  1717. mediumblue: '0000cd', mediumorchid: 'ba55d3', mediumpurple: '9370d8',
  1718. mediumseagreen: '3cb371', mediumslateblue: '7b68ee', mediumspringgreen: '00fa9a',
  1719. mediumturquoise: '48d1cc', mediumvioletred: 'c71585', midnightblue: '191970',
  1720. mintcream: 'f5fffa', mistyrose: 'ffe4e1', moccasin: 'ffe4b5',
  1721. navajowhite: 'ffdead', navy: '000080', oldlace: 'fdf5e6',
  1722. olive: '808000', olivedrab: '6b8e23', orange: 'ffa500',
  1723. orangered: 'ff4500', orchid: 'da70d6', palegoldenrod: 'eee8aa',
  1724. palegreen: '98fb98', paleturquoise: 'afeeee', palevioletred: 'd87093',
  1725. papayawhip: 'ffefd5', peachpuff: 'ffdab9', peru: 'cd853f',
  1726. pink: 'ffc0cb', plum: 'dda0dd', powderblue: 'b0e0e6',
  1727. purple: '800080', red: 'ff0000', rosybrown: 'bc8f8f',
  1728. royalblue: '4169e1', saddlebrown: '8b4513', salmon: 'fa8072',
  1729. sandybrown: 'f4a460', seagreen: '2e8b57', seashell: 'fff5ee',
  1730. sienna: 'a0522d', silver: 'c0c0c0', skyblue: '87ceeb',
  1731. slateblue: '6a5acd', slategray: '708090', snow: 'fffafa',
  1732. springgreen: '00ff7f', steelblue: '4682b4', tan: 'd2b48c',
  1733. teal: '008080', thistle: 'd8bfd8', tomato: 'ff6347',
  1734. turquoise: '40e0d0', violet: 'ee82ee', violetred: 'd02090',
  1735. wheat: 'f5deb3', white: 'ffffff', whitesmoke: 'f5f5f5',
  1736. yellow: 'ffff00', yellowgreen: '9acd32'
  1737. };
  1738. if(color_names[color]) color="#"+color_names[color];
  1739. if(color.substr && color.substr(0,1)=="#"){
  1740. color=color.substr(1);
  1741. if(color.length==8){
  1742. red=parseInt("0x"+color.substr(0,2))/255;
  1743. green=parseInt("0x"+color.substr(2,2))/255;
  1744. blue=parseInt("0x"+color.substr(4,2))/255;
  1745. alpha=parseInt("0x"+color.substr(6,2))/255;
  1746. }else if(color.length==4){
  1747. red=parseInt("0x"+color.substr(0,1))/15;
  1748. green=parseInt("0x"+color.substr(1,1))/15;
  1749. blue=parseInt("0x"+color.substr(2,1))/15;
  1750. alpha=parseInt("0x"+color.substr(3,1))/15;
  1751. }else if(color.length==6){
  1752. red=parseInt("0x"+color.substr(0,2))/255;
  1753. green=parseInt("0x"+color.substr(2,2))/255;
  1754. blue=parseInt("0x"+color.substr(4,2))/255;
  1755. alpha=1;
  1756. }else if(color.length==3){
  1757. red=parseInt("0x"+color.substr(0,1))/15;
  1758. green=parseInt("0x"+color.substr(1,1))/15;
  1759. blue=parseInt("0x"+color.substr(2,1))/15;
  1760. alpha=1;
  1761. }
  1762. }else if(color.substr && color.substr(0,4)=="rgb("){
  1763. var colors=color.substr(4).split(",");
  1764. red=parseInt(colors[0])/255;
  1765. green=parseInt(colors[1])/255;
  1766. blue=parseInt(colors[2])/255;
  1767. alpha=1;
  1768. }else if(color.substr && color.substr(0,5)=="rgba("){
  1769. var colors=color.substr(4).split(",");
  1770. red=parseInt(colors[0])/255;
  1771. green=parseInt(colors[1])/255;
  1772. blue=parseInt(colors[2])/255;
  1773. alpha=parseInt(colors[3])/255;
  1774. } else if ( color.constructor == Array ) {
  1775. if ( color.length == 3 ) {
  1776. red = parseInt(color[0])/255;
  1777. green = parseInt(color[1])/255;
  1778. blue = parseInt(color[2])/255;
  1779. alpha = 1;
  1780. } else if ( color.length == 4 ) {
  1781. red = parseInt(color[0])/255;
  1782. green = parseInt(color[1])/255;
  1783. blue = parseInt(color[2])/255;
  1784. alpha = parseInt(color[3])/255;
  1785. }
  1786. }else{
  1787. red=0;
  1788. green=0;
  1789. blue=0;
  1790. alpha=0;
  1791. }
  1792. return {r:red,g:green,b:blue,a:alpha};
  1793. }
  1794. })(GLGE);
  1795. /*
  1796. GLGE WebGL Graphics Engine
  1797. Copyright (c) 2010, Paul Brunt
  1798. All rights reserved.
  1799. Redistribution and use in source and binary forms, with or without
  1800. modification, are permitted provided that the following conditions are met:
  1801. * Redistributions of source code must retain the above copyright
  1802. notice, this list of conditions and the following disclaimer.
  1803. * Redistributions in binary form must reproduce the above copyright
  1804. notice, this list of conditions and the following disclaimer in the
  1805. documentation and/or other materials provided with the distribution.
  1806. * Neither the name of GLGE nor the
  1807. names of its contributors may be used to endorse or promote products
  1808. derived from this software without specific prior written permission.
  1809. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  1810. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  1811. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  1812. DISCLAIMED. IN NO EVENT SHALL PAUL BRUNT BE LIABLE FOR ANY
  1813. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  1814. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  1815. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  1816. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  1817. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  1818. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  1819. */
  1820. /**
  1821. * @fileOverview
  1822. * @name glge_event.js
  1823. * @author me@paulbrunt.co.uk
  1824. */
  1825. (function(GLGE){
  1826. /**
  1827. * @class A events class
  1828. **/
  1829. GLGE.Events=function(){
  1830. }
  1831. /**
  1832. * Fires an event
  1833. * @param {string} event The name of the event to fire
  1834. * @param {object} data the events data
  1835. **/
  1836. GLGE.Events.prototype.fireEvent=function(event,data){
  1837. if(this.events && this.events[event]){
  1838. var events=this.events[event];
  1839. for(var i=0;i<events.length;i++){
  1840. if(events[i] && events[i].call) events[i].call(this,data);
  1841. }
  1842. }
  1843. }
  1844. /**
  1845. * Adds an event listener
  1846. * @param {string} event The name of the event to listen for
  1847. * @param {function} fn the event callback
  1848. **/
  1849. GLGE.Events.prototype.addEventListener=function(event,fn){
  1850. if(!this.events) this.events={};
  1851. if(!this.events[event]) this.events[event]=[];
  1852. this.events[event].push(fn);
  1853. }
  1854. /**
  1855. * Removes an event listener
  1856. * @param {function} fn the event callback to remove
  1857. **/
  1858. GLGE.Events.prototype.removeEventListener=function(event,fn){
  1859. if(!this.events[event]) return;
  1860. var idx=this.events[event].indexOf(fn);
  1861. if(idx!=-1) this.events[event].splice(idx,1);
  1862. }
  1863. })(GLGE);/*
  1864. GLGE WebGL Graphics Engine
  1865. Copyright (c) 2010, Paul Brunt
  1866. All rights reserved.
  1867. Redistribution and use in source and binary forms, with or without
  1868. modification, are permitted provided that the following conditions are met:
  1869. * Redistributions of source code must retain the above copyright
  1870. notice, this list of conditions and the following disclaimer.
  1871. * Redistributions in binary form must reproduce the above copyright
  1872. notice, this list of conditions and the following disclaimer in the
  1873. documentation and/or other materials provided with the distribution.
  1874. * Neither the name of GLGE nor the
  1875. names of its contributors may be used to endorse or promote products
  1876. derived from this software without specific prior written permission.
  1877. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  1878. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  1879. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  1880. DISCLAIMED. IN NO EVENT SHALL PAUL BRUNT BE LIABLE FOR ANY
  1881. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  1882. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  1883. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  1884. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  1885. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  1886. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  1887. */
  1888. /**
  1889. * @fileOverview
  1890. * @name glge_quicknote.js
  1891. * @author me@paulbrunt.co.uk
  1892. */
  1893. (function(GLGE){
  1894. /**
  1895. * @class class to implelemnt quick notation
  1896. */
  1897. GLGE.QuickNotation=function(){
  1898. }
  1899. /**
  1900. * Call to set properties and add children to an object
  1901. * @example myObject._({LocX:10,LocY:20},child1,child2,.....);
  1902. */
  1903. GLGE.QuickNotation.prototype._=function(){
  1904. var argument;
  1905. for(var i=0; i<arguments.length;i++){
  1906. argument=arguments[i];
  1907. if(typeof argument=="object"){
  1908. if(argument.className && this["add"+argument.className]){
  1909. this["add"+argument.className](argument);
  1910. }else{
  1911. for(var key in argument){
  1912. if(this["set"+key]){
  1913. this["set"+key](argument[key]);
  1914. }
  1915. }
  1916. }
  1917. }
  1918. }
  1919. return this;
  1920. }
  1921. })(GLGE);/*
  1922. GLGE WebGL Graphics Engine
  1923. Copyright (c) 2010, Paul Brunt
  1924. All rights reserved.
  1925. Redistribution and use in source and binary forms, with or without
  1926. modification, are permitted provided that the following conditions are met:
  1927. * Redistributions of source code must retain the above copyright
  1928. notice, this list of conditions and the following disclaimer.
  1929. * Redistributions in binary form must reproduce the above copyright
  1930. notice, this list of conditions and the following disclaimer in the
  1931. documentation and/or other materials provided with the distribution.
  1932. * Neither the name of GLGE nor the
  1933. names of its contributors may be used to endorse or promote products
  1934. derived from this software without specific prior written permission.
  1935. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  1936. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  1937. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  1938. DISCLAIMED. IN NO EVENT SHALL PAUL BRUNT BE LIABLE FOR ANY
  1939. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  1940. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  1941. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  1942. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  1943. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  1944. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  1945. */
  1946. /**
  1947. * @fileOverview
  1948. * @name glge_animatable.js
  1949. * @author me@paulbrunt.co.uk
  1950. */
  1951. (function(GLGE){
  1952. /**
  1953. * @class Animation class to agument animatiable objects
  1954. * @augments GLGE.Events
  1955. */
  1956. GLGE.Animatable=function(){
  1957. }
  1958. /**
  1959. * @name GLGE.Animatable#animFinished
  1960. * @event
  1961. * @param {object} data
  1962. */
  1963. GLGE.augment(GLGE.Events,GLGE.Animatable);
  1964. GLGE.Animatable.prototype.animationStart=null;
  1965. GLGE.Animatable.prototype.animation=null;
  1966. GLGE.Animatable.prototype.blendStart=0;
  1967. GLGE.Animatable.prototype.blendTime=0;
  1968. GLGE.Animatable.prototype.lastFrame=null;
  1969. GLGE.Animatable.prototype.frameRate=30;
  1970. GLGE.Animatable.prototype.loop=GLGE.TRUE;
  1971. GLGE.Animatable.prototype.paused=GLGE.FALSE;
  1972. GLGE.Animatable.prototype.pausedTime=null;
  1973. GLGE.Animatable.prototype.blendFunction=GLGE.LINEAR_BLEND;
  1974. /**
  1975. * Creates and sets an animation to blend to the properties. Useful for blending to a specific location for example:
  1976. * blendto({LocX:10,LocY:5,LocZ:10},2000);
  1977. * @param {object} properties The properties to blend
  1978. * @param {number} duration the duration of the blend
  1979. * @param {function} blendFunction[optional] the function used for blending defaults to GLGE.LINEAR_BLEND
  1980. */
  1981. GLGE.Animatable.prototype.blendTo=function(properties,duration,blendFunction){
  1982. if(!blendFunction) blendFunction=GLGE.LINEAR_BLEND;
  1983. var animation=new GLGE.AnimationVector();
  1984. var curve;
  1985. var point;
  1986. for(var prop in properties){
  1987. curve=new GLGE.AnimationCurve();
  1988. curve.setChannel(prop);
  1989. point=new GLGE.LinearPoint();
  1990. point.setX(1);
  1991. point.setY(properties[prop]);
  1992. curve.addPoint(point);
  1993. animation.addAnimationCurve(curve);
  1994. }
  1995. this.setBlendFunction(blendFunction);
  1996. this.setAnimation(animation,duration);
  1997. return this;
  1998. }
  1999. /**
  2000. * Sets the animation blending function
  2001. * @param {function} value The blending function
  2002. */
  2003. GLGE.Animatable.prototype.setBlendFunction=function(value){
  2004. this.blendFunction=value;
  2005. return this;
  2006. }
  2007. /**
  2008. * Gets the animation blending function
  2009. * @returns {function} the blending function
  2010. */
  2011. GLGE.Animatable.prototype.getBlendFunction=function(){
  2012. return this.blendFunction;
  2013. }
  2014. /**
  2015. * Sets the name of this object used for skinning
  2016. * @param {String} value The name to set
  2017. */
  2018. GLGE.Animatable.prototype.setName=function(value){
  2019. this.name=value;
  2020. return this;
  2021. }
  2022. /**
  2023. * Gets the name of this object used for skinning
  2024. * @returns {String} the name
  2025. */
  2026. GLGE.Animatable.prototype.getName=function(){
  2027. return this.name;
  2028. }
  2029. /**
  2030. * gets the frame at the specified time
  2031. * @param {number} now the current time
  2032. */
  2033. GLGE.Animatable.prototype.getFrameNumber=function(now){
  2034. if(!this.startFrame) this.startFrame=this.animation.startFrame;
  2035. if(!this.animFrames) this.animFrames=this.animation.frames;
  2036. var frame;
  2037. if(!now) now=GLGE.now();
  2038. if(this.animFrames>1){
  2039. if(this.loop){
  2040. frame=((parseFloat(now)-parseFloat(this.animationStart))/1000*this.frameRate)%(this.animFrames-1)+1+this.startFrame;
  2041. }else{
  2042. frame=((parseFloat(now)-parseFloat(this.animationStart))/1000*this.frameRate)+1+this.startFrame;
  2043. if(frame>=(this.animFrames+this.startFrame)){
  2044. frame=this.animFrames;
  2045. }
  2046. }
  2047. }else{
  2048. frame=1;
  2049. }
  2050. return parseInt(frame);
  2051. }
  2052. /**
  2053. * Sets the start frame for the animation overriding the animation default
  2054. * @param {number} startFrame the start frame
  2055. */
  2056. GLGE.Animatable.prototype.setStartFrame=function(startFrame,blendTime,loop){
  2057. this.loop=loop;
  2058. var starttime=GLGE.now();
  2059. if(!blendTime) blendTime=0;
  2060. if(blendTime>0){
  2061. if(this.animation){
  2062. this.blendInitValues=this.getInitialValues(this.animation,starttime);
  2063. this.blendTime=blendTime;
  2064. }
  2065. }
  2066. this.animationStart=starttime;
  2067. this.pauseTime=starttime;
  2068. this.lastFrame=null;
  2069. this.animFinished=false;
  2070. this.startFrame=startFrame;
  2071. if(this.children){
  2072. for(var i=0;i<this.children.length;i++){
  2073. if(this.children[i].setStartFrame){
  2074. this.children[i].setStartFrame(startFrame,blendTime,loop);
  2075. }
  2076. }
  2077. }
  2078. return this;
  2079. }
  2080. /**
  2081. * Sets the number of frames to play overriding the animation default
  2082. * @param {number} frames the number of frames
  2083. * @private
  2084. */
  2085. GLGE.Animatable.prototype.setFrames=function(frames){
  2086. this.animFrames=frames;
  2087. if(this.children){
  2088. for(var i=0;i<this.children.length;i++){
  2089. if(this.children[i].setFrames){
  2090. this.children[i].setFrames(frames);
  2091. }
  2092. }
  2093. }
  2094. return this;
  2095. }
  2096. /**
  2097. * gets the initial values for the animation vector for blending
  2098. * @param {GLGE.AnimationVector} animation The animation
  2099. * @private
  2100. */
  2101. GLGE.Animatable.prototype.getInitialValues=function(animation,time){
  2102. var initValues={};
  2103. if(this.animation){
  2104. this.lastFrame=null;
  2105. this.animate(time,true);
  2106. }
  2107. for(var property in animation.curves){
  2108. if(this["get"+property]){
  2109. initValues[property]=this["get"+property]();
  2110. }
  2111. }
  2112. return initValues;
  2113. }
  2114. /**
  2115. * update animated properties on this object
  2116. */
  2117. GLGE.Animatable.prototype.animate=function(now,nocache){
  2118. if(!this.paused && this.animation){
  2119. if(!now) now=GLGE.now();
  2120. var frame=this.getFrameNumber(now);
  2121. if(!this.animation.animationCache) this.animation.animationCache={};
  2122. if(frame!=this.lastFrame || this.blendTime!=0){
  2123. this.lastFrame=frame;
  2124. if(this.blendTime==0){
  2125. if(!this.animation.animationCache[frame] || nocache){
  2126. this.animation.animationCache[frame]=[];
  2127. if(this.animation.curves["LocX"] && this.animation.curves["LocY"] && this.animation.curves["LocZ"]
  2128. && this.animation.curves["ScaleX"] && this.animation.curves["ScaleY"] && this.animation.curves["ScaleZ"]
  2129. && this.animation.curves["QuatX"] && this.animation.curves["QuatY"] && this.animation.curves["QuatZ"] && this.animation.curves["QuatW"]){
  2130. //just set matrix
  2131. for(var property in this.animation.curves){
  2132. if(this["set"+property]){
  2133. var value=this.animation.curves[property].getValue(parseFloat(frame));
  2134. switch(property){
  2135. case "QuatX":
  2136. case "QuatY":
  2137. case "QuatZ":
  2138. case "QuatW":
  2139. case "LocX":
  2140. case "LocY":
  2141. case "LocZ":
  2142. case "ScaleX":
  2143. case "ScaleY":
  2144. case "ScaleZ":
  2145. break;
  2146. default:
  2147. this.animation.animationCache[frame].push({property:property,value:value});
  2148. break;
  2149. }
  2150. this["set"+property](value);
  2151. }
  2152. }
  2153. this.animation.animationCache[frame].push({property:"StaticMatrix",value:this.getLocalMatrix()});
  2154. }else{
  2155. for(property in this.animation.curves){
  2156. if(this["set"+property]){
  2157. var value=this.animation.curves[property].getValue(parseFloat(frame));
  2158. switch(property){
  2159. case "QuatX":
  2160. case "QuatY":
  2161. case "QuatZ":
  2162. case "QuatW":
  2163. case "RotX":
  2164. case "RotY":
  2165. case "RotZ":
  2166. var rot=true;
  2167. break;
  2168. default:
  2169. this.animation.animationCache[frame].push({property:property,value:value});
  2170. break;
  2171. }
  2172. this["set"+property](value);
  2173. }
  2174. }
  2175. if(rot){
  2176. value=this.getRotMatrix();
  2177. this.animation.animationCache[frame].push({property:"RotMatrix",value:value});
  2178. }
  2179. }
  2180. }else{
  2181. var cache=this.animation.animationCache[frame];
  2182. for(var i=0;i<cache.length;i++){
  2183. if(this["set"+cache[i].property]) this["set"+cache[i].property](cache[i].value);
  2184. }
  2185. }
  2186. }else{
  2187. var time=now-this.animationStart;
  2188. if(time<this.blendTime){
  2189. var blendfactor=time/this.blendTime;
  2190. blendfactor=this.blendFunction(blendfactor);
  2191. for(property in this.animation.curves){
  2192. if(this["set"+property]){
  2193. var value=this.animation.curves[property].getValue(parseFloat(frame));
  2194. value=value*blendfactor+this.blendInitValues[property]*(1-blendfactor);
  2195. this["set"+property](value);
  2196. }
  2197. }
  2198. }else{
  2199. this.blendTime=0;
  2200. }
  2201. }
  2202. }
  2203. }
  2204. if(this.children){
  2205. for(var i=0; i<this.children.length;i++){
  2206. if(this.children[i].animate){
  2207. this.children[i].animate(now,nocache);
  2208. }
  2209. }
  2210. }
  2211. if(!this.paused && this.animation && !this.animFinished && this.blendTime==0 && this.animFrames==frame && !nocache){
  2212. this.animFinished=true;
  2213. this.fireEvent("animFinished",{});
  2214. }
  2215. }
  2216. /**
  2217. * Sets the animation vector of this object
  2218. * @param {GLGE.AnimationVector} animationVector the animation to apply to this object
  2219. * @param {number} blendDuration [Optional] the time in milliseconds to blend into this animation
  2220. * @param {number} starttime [Optional] the starting time of the animation
  2221. */
  2222. GLGE.Animatable.prototype.setAnimation=function(animationVector,blendDuration,starttime){
  2223. if(starttime==null) starttime=GLGE.now();
  2224. if(!blendDuration) blendDuration=0;
  2225. if(blendDuration>0){
  2226. this.blendInitValues=this.getInitialValues(animationVector,starttime);
  2227. this.blendTime=blendDuration;
  2228. }
  2229. this.animFrames=null;
  2230. this.startFrame=null;
  2231. this.animationStart=starttime;
  2232. this.pauseTime=starttime;
  2233. this.lastFrame=null;
  2234. this.animation=animationVector;
  2235. this.animFinished=false;
  2236. return this;
  2237. }
  2238. /**
  2239. * Gets the animation vector of this object
  2240. * @returns {AnimationVector}
  2241. */
  2242. GLGE.Animatable.prototype.getAnimation=function(){
  2243. return this.animation;
  2244. }
  2245. /**
  2246. * Sets the frame rate of the animation
  2247. * @param {number} value the frame rate to set
  2248. */
  2249. GLGE.Animatable.prototype.setFrameRate=function(value){
  2250. this.frameRate=value;
  2251. if (this.children) {
  2252. for (var i = 0; i < this.children.length; i++) {
  2253. if (this.children[i].setFrameRate) {
  2254. this.children[i].setFrameRate(value);
  2255. }
  2256. }
  2257. }
  2258. return this;
  2259. }
  2260. /**
  2261. * Gets the frame rate of the animation
  2262. * @return {number} the current frame rate
  2263. */
  2264. GLGE.Animatable.prototype.getFrameRate=function(){
  2265. return this.frameRate;
  2266. }
  2267. /**
  2268. * Sets the loop flag to GLGE.TRUE or GLGE.FALSE
  2269. * @param {boolean} value
  2270. */
  2271. GLGE.Animatable.prototype.setLoop=function(value){
  2272. this.loop=value;
  2273. return this;
  2274. }
  2275. /**
  2276. * Gets the loop flag
  2277. * @return {boolean}
  2278. */
  2279. GLGE.Animatable.prototype.getLoop=function(){
  2280. return this.loop;
  2281. }
  2282. /**
  2283. * @function is looping? @see GLGE.Animatable#getLoop
  2284. */
  2285. GLGE.Animatable.prototype.isLooping=GLGE.Animatable.prototype.getLoop;
  2286. /**
  2287. * Sets the paused flag to GLGE.TRUE or GLGE.FALSE
  2288. * @param {boolean} value
  2289. */
  2290. GLGE.Animatable.prototype.setPaused=function(value){
  2291. if(value && !this.paused) this.pauseTime=GLGE.now();
  2292. else if(!value && this.paused) this.animationStart=this.animationStart+(GLGE.now()-this.pauseTime);
  2293. this.paused=value;
  2294. return this;
  2295. }
  2296. /**
  2297. * Gets the paused flag
  2298. * @return {boolean}
  2299. */
  2300. GLGE.Animatable.prototype.getPaused=function(){
  2301. return this.paused;
  2302. }
  2303. /**
  2304. * Toggles the paused flag
  2305. * @return {boolean} returns the resulting flag state
  2306. */
  2307. GLGE.Animatable.prototype.togglePaused=function(){
  2308. this.setPaused(!this.getPaused());
  2309. return this.paused;
  2310. }
  2311. })(GLGE);
  2312. /*
  2313. GLGE WebGL Graphics Engine
  2314. Copyright (c) 2010, Paul Brunt
  2315. All rights reserved.
  2316. Redistribution and use in source and binary forms, with or without
  2317. modification, are permitted provided that the following conditions are met:
  2318. * Redistributions of source code must retain the above copyright
  2319. notice, this list of conditions and the following disclaimer.
  2320. * Redistributions in binary form must reproduce the above copyright
  2321. notice, this list of conditions and the following disclaimer in the
  2322. documentation and/or other materials provided with the distribution.
  2323. * Neither the name of GLGE nor the
  2324. names of its contributors may be used to endorse or promote products
  2325. derived from this software without specific prior written permission.
  2326. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  2327. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  2328. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  2329. DISCLAIMED. IN NO EVENT SHALL PAUL BRUNT BE LIABLE FOR ANY
  2330. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  2331. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  2332. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  2333. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  2334. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  2335. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  2336. */
  2337. /**
  2338. * @fileOverview
  2339. * @name glge_document.js
  2340. * @author me@paulbrunt.co.uk
  2341. */
  2342. (function(GLGE){
  2343. /**
  2344. * @class Document class to load scene, object, mesh etc from an external XML file
  2345. * @param {string} url URL of the resource to load
  2346. */
  2347. GLGE.Document=function(){
  2348. this.listeners=[];
  2349. this.documents=[];
  2350. }
  2351. GLGE.Document.prototype.listeners=null;
  2352. GLGE.Document.prototype.documents=null;
  2353. GLGE.Document.prototype.rootURL=null;
  2354. GLGE.Document.prototype.loadCount=0;
  2355. GLGE.Document.prototype.version=0;
  2356. GLGE.Document.prototype.preloader=null;
  2357. /**
  2358. * This is just a fix for a bug in webkit
  2359. * @param {string} id the id name to get
  2360. * @returns {object} node with teh specified id
  2361. * @private
  2362. */
  2363. GLGE.Document.prototype.getElementById=function(id){
  2364. var tags=this.getElementsByTagName("*");
  2365. for(var i=0; i<tags.length;i++){
  2366. if(tags[i].getAttribute("id")==id){
  2367. return tags[i];
  2368. break;
  2369. }
  2370. }
  2371. return null;
  2372. }
  2373. /**
  2374. * Gets the absolute path given an import path and the path it's relative to
  2375. * @param {string} path the path to get the absolute path for
  2376. * @param {string} relativeto the path the supplied path is relativeto
  2377. * @returns {string} absolute path
  2378. * @private
  2379. */
  2380. GLGE.Document.prototype.getAbsolutePath=function(path,relativeto){
  2381. if(path.substr(0,7)=="http://" || path.substr(0,7)=="file://" || path.substr(0,8)=="https://"){
  2382. return path;
  2383. }
  2384. else
  2385. {
  2386. if(!relativeto){
  2387. relativeto=window.location.protocol+"//"+window.location.host+window.location.pathname;
  2388. }
  2389. //find the path compoents
  2390. var bits=relativeto.split("/");
  2391. var domain=bits[2];
  2392. var proto=bits[0];
  2393. var initpath=[];
  2394. for(var i=3;i<bits.length-1;i++){
  2395. initpath.push(bits[i]);
  2396. }
  2397. //relative to domain
  2398. if(path.substr(0,1)=="/"){
  2399. initpath=[];
  2400. }
  2401. var locpath=path.split("/");
  2402. for(var i=0;i<locpath.length;i++){
  2403. if(locpath[i]=="..") initpath.pop();
  2404. else if(locpath[i]!="") initpath.push(locpath[i]);
  2405. }
  2406. return proto+"//"+domain+"/"+initpath.join("/");
  2407. }
  2408. }
  2409. /**
  2410. * Loads the root document
  2411. * @param {string} url URL of the resource to load
  2412. * @param {object} preload Decides if a preloader is used. true: default preloader, object: specialized preloader
  2413. */
  2414. GLGE.Document.prototype.load=function(url, preload){
  2415. if(preload)
  2416. this.usePreloader(preload);
  2417. this.documents=[];
  2418. this.rootURL=url;
  2419. this.loadDocument(url,null);
  2420. }
  2421. /**
  2422. * Loads an additional documents into the collection
  2423. * @param {string} url URL of the resource to load
  2424. * @param {string} relativeto the path the URL is relative to, null for default
  2425. */
  2426. GLGE.Document.prototype.loadDocument=function(url,relativeto){
  2427. this.loadCount++;
  2428. url=this.getAbsolutePath(url,relativeto);
  2429. if(this.preloader)
  2430. {
  2431. this.preloader.loadXMLFile(url);
  2432. }
  2433. else
  2434. {
  2435. var req = new XMLHttpRequest();
  2436. if(req) {
  2437. req.docurl=url;
  2438. req.docObj=this;
  2439. req.overrideMimeType("text/xml");
  2440. req.onreadystatechange = function() {
  2441. if(this.readyState == 4)
  2442. {
  2443. if(this.status == 200 || this.status==0){
  2444. this.responseXML.getElementById=this.docObj.getElementById;
  2445. this.docObj.loaded(this.docurl,this.responseXML);
  2446. }else{
  2447. GLGE.error("Error loading Document: "+this.docurl+" status "+this.status);
  2448. }
  2449. }
  2450. };
  2451. req.open("GET", url, true);
  2452. req.send("");
  2453. }
  2454. }
  2455. }
  2456. /**
  2457. * Trigered when a document has finished loading
  2458. * @param {string} url the absolute url of the document that has loaded
  2459. * @param {XMLDoc} responceXML the xml document that has finished loading
  2460. * @private
  2461. */
  2462. GLGE.Document.prototype.loaded=function(url,responceXML){
  2463. this.loadCount--;
  2464. this.documents[url]={'xml':responceXML, 'url':url};
  2465. var root=responceXML.getElementsByTagName("glge");
  2466. if(root[0] && root[0].hasAttribute("version")) this.version=parseFloat(root[0].getAttribute("version"));
  2467. var imports=responceXML.getElementsByTagName("import");
  2468. for(var i=0; i<imports.length;i++){
  2469. if(!this.documents[this.getAbsolutePath(imports[i].getAttribute("url"),url)]){
  2470. this.documents[this.getAbsolutePath(imports[i].getAttribute("url"),url)]={};
  2471. this.loadDocument(imports[i].getAttribute("url"),url);
  2472. }
  2473. }
  2474. if(this.loadCount==0){
  2475. this.finishedLoading();
  2476. }
  2477. }
  2478. /**
  2479. * Called when all documents have finished loading
  2480. * @private
  2481. */
  2482. GLGE.Document.prototype.finishedLoading=function(){
  2483. for(var i=0; i<this.listeners.length;i++){
  2484. this.listeners[i](this.listeners.rootURL);
  2485. }
  2486. this["onLoad"]();
  2487. }
  2488. /**
  2489. * Called when all documents have finished loading
  2490. * @event
  2491. */
  2492. GLGE.Document.prototype["onLoad"]=function(){};
  2493. /**
  2494. * Use a preloader
  2495. * @param {object} [object] This object contains optional parameters. Example1: {XMLQuota: 0.30, XMLBytes: 852605}, Example2: {XMLQuota: 0.13, numXMLFiles: 1}, Example3: true
  2496. */
  2497. GLGE.Document.prototype.usePreloader = function(args){
  2498. this.preloader = new GLGE.DocumentPreloader(this, args);
  2499. var that = this;
  2500. this.addLoadListener(function(url){that.preloadImages.call(that);});
  2501. }
  2502. /**
  2503. * Start preloading images. This function should be called when the document (xml) is loaded.
  2504. * @private
  2505. */
  2506. GLGE.Document.prototype.preloadImages = function(){
  2507. var imageArrays = []; // 2 dimensional
  2508. var docUrls = [];
  2509. // create an array of all images
  2510. for(var doc in this.documents){
  2511. if(this.documents[doc].xml){
  2512. imageArrays.push(this.documents[doc].xml.getElementsByTagName("texture"));
  2513. docUrls.push(this.documents[doc].url);
  2514. }
  2515. }
  2516. // add images to the preloader
  2517. for(var a in imageArrays){
  2518. for(var i=0; i<imageArrays[a].length; i++){
  2519. var src = imageArrays[a][i].getAttribute("src");
  2520. if(src)
  2521. this.preloader.addImage(this.getAbsolutePath(src, docUrls[a]));
  2522. }
  2523. }
  2524. this.preloader.loadImages();
  2525. }
  2526. /**
  2527. * Converts and attribute name into a class name
  2528. * @param {string} name attribute name to convert
  2529. * @private
  2530. */
  2531. GLGE.Document.prototype.classString=function(name){
  2532. if(!name) return false;
  2533. var names=name.split("_");
  2534. var converted="";
  2535. for(var i=0;i<names.length;i++){
  2536. converted=converted+names[i][0].toUpperCase()+names[i].substr(1);
  2537. }
  2538. return converted;
  2539. }
  2540. /**
  2541. * Sets the properties of an object based on the attributes of the corresponding dom element
  2542. * @param {object} Obj the DOM element to apply the attributes of
  2543. * @private
  2544. */
  2545. GLGE.Document.prototype.setProperties=function(Obj){
  2546. var set_method;
  2547. var attribute_name;
  2548. var value;
  2549. for(var i=0; i<Obj.attributes.length; i++){
  2550. value=false;
  2551. set_method="set"+this.classString(Obj.attributes[i].nodeName);
  2552. if(Obj.attributes[i].value[0]=="#"){
  2553. value=this.getElement(Obj.attributes[i].value.substr(1),true);
  2554. }
  2555. if(!value){
  2556. //if this is a GLGE contsant then set the constant value otherwise just literal
  2557. if(typeof(GLGE[Obj.attributes[i].value]) != "undefined"){
  2558. value=GLGE[Obj.attributes[i].value];
  2559. }
  2560. else
  2561. {
  2562. value=Obj.attributes[i].value;
  2563. }
  2564. }
  2565. if(Obj.object[set_method]) Obj.object[set_method](value);
  2566. //if a uid is set in the xml doc then make sure it's registered correctly in the assets
  2567. if(Obj.attributes[i].nodeName=="uid"){
  2568. GLGE.Assets.unregisterAsset(Obj.object.uid);
  2569. Obj.object.uid=Obj.attributes[i].value;
  2570. GLGE.Assets.registerAsset(Obj.object,Obj.attributes[i].value);
  2571. }
  2572. }
  2573. }
  2574. /**
  2575. * Adds child objects
  2576. * @param {object} Obj the DOM element to apply the children of
  2577. * @private
  2578. */
  2579. GLGE.Document.prototype.addChildren=function(Obj){
  2580. //loop though and add the children
  2581. var add_method;
  2582. var child=Obj.firstChild;
  2583. while(child){
  2584. add_method="add"+this.classString(child.tagName);
  2585. if(Obj.object[add_method]) Obj.object[add_method](this.getElement(child));
  2586. child=child.nextSibling;
  2587. }
  2588. }
  2589. /**
  2590. * Gets an object from the XML document based on the dom element
  2591. * @param {string|domelement} ele the id of the element to get or the dom node
  2592. */
  2593. GLGE.Document.prototype.getElement=function(ele,noerrors){
  2594. var docele,doc;
  2595. if(typeof(ele)=="string"){
  2596. for(var doc in this.documents){
  2597. if(this.documents[doc].xml){
  2598. docele=this.documents[doc].xml.getElementById(ele);
  2599. if(docele){
  2600. ele=docele;
  2601. break;
  2602. }
  2603. }
  2604. }
  2605. }
  2606. if(typeof(ele)=="string"){
  2607. //if element is still a string at this point there there is an issue
  2608. if(!noerrors) GLGE.error("Element "+ele+" not found in document");
  2609. return false;
  2610. }
  2611. else
  2612. {
  2613. if(this["get"+this.classString(ele.tagName)]){
  2614. return this["get"+this.classString(ele.tagName)](ele);
  2615. }
  2616. else
  2617. {
  2618. return this.getDefault(ele);
  2619. }
  2620. }
  2621. }
  2622. /**
  2623. * Parses the a data array
  2624. * @param {domelement} ele the element to create the objects from
  2625. * @private
  2626. */
  2627. GLGE.Document.prototype.getData=function(ele){
  2628. if(!ele.object){
  2629. ele.object=this.parseArray(ele);
  2630. if(ele.hasAttribute("type")){
  2631. var type=ele.getAttribute("type");
  2632. switch(type){
  2633. case "matrix":
  2634. for(var i=0;i<ele.object.length;i++){
  2635. ele.object[i]=GLGE.Mat4(ele.object[i].split(" "));
  2636. }
  2637. break;
  2638. case "links":
  2639. for(var i=0;i<ele.object.length;i++){
  2640. ele.object[i]=this.getElement(ele.object[i].substr(1));
  2641. }
  2642. break;
  2643. }
  2644. }
  2645. }
  2646. return ele.object;
  2647. }
  2648. /**
  2649. * Parses the dom element and creates any objects that are required
  2650. * @param {domelement} ele the element to create the objects from
  2651. * @private
  2652. */
  2653. GLGE.Document.prototype.getDefault=function(ele){
  2654. if(!ele.object){
  2655. if(GLGE[this.classString(ele.tagName)]){
  2656. ele.object=new GLGE[this.classString(ele.tagName)]();
  2657. this.setProperties(ele);
  2658. this.addChildren(ele);
  2659. }
  2660. else
  2661. {
  2662. GLGE.error("XML Parse Error: GLGE Object not found");
  2663. }
  2664. }
  2665. return ele.object;
  2666. }
  2667. /**
  2668. * Parses the dom element and creates a texture
  2669. * @param {domelement} ele the element to create the objects from
  2670. * @private
  2671. */
  2672. GLGE.Document.prototype.getTexture=function(ele){
  2673. if(!ele.object){
  2674. var rel=this.getAbsolutePath(this.rootURL,null);
  2675. ele.object=new GLGE[this.classString(ele.tagName)];
  2676. ele.object.setSrc(this.getAbsolutePath(ele.getAttribute("src"),rel));
  2677. ele.removeAttribute("src");
  2678. this.setProperties(ele);
  2679. }
  2680. return ele.object;
  2681. }
  2682. GLGE.Document.prototype.getTextureVideo=GLGE.Document.prototype.getTexture;
  2683. /**
  2684. * Parses a document node into an array
  2685. * @param {node} the node to parse
  2686. * @private
  2687. */
  2688. GLGE.Document.prototype.parseArray=function(node){
  2689. var child=node.firstChild;
  2690. var prev="";
  2691. var output=[];
  2692. var currentArray;
  2693. var i;
  2694. while(child){
  2695. currentArray=(prev+child.nodeValue).split(",");
  2696. child=child.nextSibling;
  2697. if(currentArray[0]=="") currentArray.unshift();
  2698. if(child) prev=currentArray.pop();
  2699. for(var i=0;i<currentArray.length;i++) output.push(currentArray[i]);
  2700. }
  2701. return output;
  2702. }
  2703. /**
  2704. * Parses the mesh dom to create the mesh object
  2705. * @param {domelement} ele the element to create the mesh from
  2706. * @private
  2707. */
  2708. GLGE.Document.prototype.getMesh=function(ele){
  2709. if(this.version>0) return this.getDefault(ele); //as of GLGE XML 1.0 the mesh is nothing special!
  2710. if(!ele.object){
  2711. ele.object=new GLGE.Mesh();
  2712. this.setProperties(ele);
  2713. var child=ele.firstChild;
  2714. while(child){
  2715. switch(child.tagName){
  2716. case "positions":
  2717. ele.object.setPositions(this.parseArray(child));
  2718. break;
  2719. case "normals":
  2720. ele.object.setNormals(this.parseArray(child));
  2721. break;
  2722. case "uv1":
  2723. ele.object.setUV(this.parseArray(child));
  2724. break;
  2725. case "uv2":
  2726. ele.object.setUV2(this.parseArray(child));
  2727. break;
  2728. case "faces":
  2729. ele.object.setFaces(this.parseArray(child));
  2730. break;
  2731. case "color":
  2732. ele.object.setVertexColors(this.parseArray(child));
  2733. break;
  2734. case "joint_names":
  2735. var names=this.parseArray(child);
  2736. var jointObjects=[];
  2737. for(var i=0;i<names.length;i++){
  2738. if(names[i].substr(0,1)=="#"){
  2739. jointObjects.push(this.getElement(names[i].substr(1)));
  2740. }else{
  2741. jointObjects.push(names[i]);
  2742. }
  2743. }
  2744. ele.object.setJoints(jointObjects);
  2745. break;
  2746. case "bind_matrix":
  2747. var mats=this.parseArray(child);
  2748. var invBind=[];
  2749. for(var i=0;i<mats.length;i++){
  2750. invBind.push(GLGE.Mat4(mats[i].split(" ")));
  2751. }
  2752. ele.object.setInvBindMatrix(invBind);
  2753. break;
  2754. case "joints":
  2755. ele.object.setVertexJoints(this.parseArray(child),child.getAttribute("count"));
  2756. break;
  2757. case "weights":
  2758. ele.object.setVertexWeights(this.parseArray(child),child.getAttribute("count"));
  2759. break;
  2760. }
  2761. child=child.nextSibling;
  2762. }
  2763. }
  2764. return ele.object;
  2765. }
  2766. /**
  2767. * Adds a listener to be called when all documents have finished loading
  2768. * @param {function} listener the function to call when all loading in complete
  2769. */
  2770. GLGE.Document.prototype.addLoadListener=function(listener){
  2771. this.listeners.push(listener);
  2772. }
  2773. /**
  2774. * Removes a load listener
  2775. * @param {function} listener Listener to remove
  2776. */
  2777. GLGE.Document.prototype.removeLoadListener=function(listener){
  2778. for(var i=0; i<this.listeners.length; i++){
  2779. if(this.listeners[i]===listener) this.listeners.splice(i,1);
  2780. }
  2781. }
  2782. /**
  2783. * loads xml from a script tag
  2784. * @param {string} id the id of the element to load
  2785. */
  2786. GLGE.Document.prototype.parseScript=function(id){
  2787. this.rootURL=window.location.toString();
  2788. var xmlScript = document.getElementById(id);
  2789. if (!xmlScript) {
  2790. return null;
  2791. }
  2792. var str = "";
  2793. var k = xmlScript.firstChild;
  2794. while (k) {
  2795. if (k.nodeType == 3) {
  2796. str += k.textContent;
  2797. }
  2798. k = k.nextSibling;
  2799. }
  2800. var parser=new DOMParser();
  2801. var xmlDoc=parser.parseFromString(str,"text/xml");
  2802. xmlDoc.getElementById=this.getElementById;
  2803. this.documents["#"+id]={xml:xmlDoc};
  2804. var imports=xmlDoc.getElementsByTagName("import");
  2805. for(var i=0; i<imports.length;i++){
  2806. if(!this.documents[this.getAbsolutePath(imports[i].getAttribute("url"),url)]){
  2807. this.documents[this.getAbsolutePath(imports[i].getAttribute("url"),url)]={};
  2808. this.loadDocument(imports[i].getAttribute("url"));
  2809. }
  2810. }
  2811. if(this.loadCount==0){
  2812. this.finishedLoading();
  2813. }
  2814. }
  2815. })(GLGE);
  2816. /*
  2817. GLGE WebGL Graphics Engine
  2818. Copyright (c) 2010, Paul Brunt
  2819. All rights reserved.
  2820. Redistribution and use in source and binary forms, with or without
  2821. modification, are permitted provided that the following conditions are met:
  2822. * Redistributions of source code must retain the above copyright
  2823. notice, this list of conditions and the following disclaimer.
  2824. * Redistributions in binary form must reproduce the above copyright
  2825. notice, this list of conditions and the following disclaimer in the
  2826. documentation and/or other materials provided with the distribution.
  2827. * Neither the name of GLGE nor the
  2828. names of its contributors may be used to endorse or promote products
  2829. derived from this software without specific prior written permission.
  2830. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  2831. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  2832. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  2833. DISCLAIMED. IN NO EVENT SHALL PAUL BRUNT BE LIABLE FOR ANY
  2834. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  2835. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  2836. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  2837. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  2838. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  2839. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  2840. */
  2841. /**
  2842. * @fileOverview
  2843. * @name glge_placeable.js
  2844. * @author me@paulbrunt.co.uk
  2845. */
  2846. (function(GLGE){
  2847. GLGE.ZUP=[0,0,1];
  2848. GLGE.YUP=[0,1,0];
  2849. GLGE.XUP=[1,0,0];
  2850. /**
  2851. * @class Abstract class to agument objects that requires position, rotation and scale.
  2852. */
  2853. GLGE.Placeable=function(){
  2854. }
  2855. GLGE.Placeable.prototype.locX=0;
  2856. GLGE.Placeable.prototype.locY=0;
  2857. GLGE.Placeable.prototype.locZ=0;
  2858. GLGE.Placeable.prototype.dLocX=0;
  2859. GLGE.Placeable.prototype.dLocY=0;
  2860. GLGE.Placeable.prototype.dLocZ=0;
  2861. GLGE.Placeable.prototype.quatX=0;
  2862. GLGE.Placeable.prototype.quatY=0;
  2863. GLGE.Placeable.prototype.quatZ=0;
  2864. GLGE.Placeable.prototype.quatW=0;
  2865. GLGE.Placeable.prototype.rotX=0;
  2866. GLGE.Placeable.prototype.rotY=0;
  2867. GLGE.Placeable.prototype.rotZ=0;
  2868. GLGE.Placeable.prototype.dRotX=0;
  2869. GLGE.Placeable.prototype.dRotY=0;
  2870. GLGE.Placeable.prototype.dRotZ=0;
  2871. GLGE.Placeable.prototype.scaleX=1;
  2872. GLGE.Placeable.prototype.scaleY=1;
  2873. GLGE.Placeable.prototype.scaleZ=1;
  2874. GLGE.Placeable.prototype.dScaleX=0;
  2875. GLGE.Placeable.prototype.dScaleY=0;
  2876. GLGE.Placeable.prototype.dScaleZ=0;
  2877. GLGE.Placeable.prototype.matrix=null;
  2878. GLGE.Placeable.prototype.rotOrder=GLGE.ROT_XYZ;
  2879. GLGE.Placeable.prototype.lookAt=null;
  2880. GLGE.Placeable.prototype.mode=GLGE.P_EULER;
  2881. GLGE.Placeable.prototype.upAxis=GLGE.ZUP;
  2882. /**
  2883. * @name GLGE.Placeable#appened
  2884. * @event fires when all the object is appened as a child to another
  2885. * @param {object} event
  2886. */
  2887. /**
  2888. * @name GLGE.Placeable#removed
  2889. * @event fires when all the object is removed as a child to another
  2890. * @param {object} event
  2891. */
  2892. /**
  2893. * @name GLGE.Placeable#matrixUpdate
  2894. * @event fires when this object has its transform changed supplies the target object as event.obj
  2895. * @param {object} event
  2896. */
  2897. /**
  2898. * @name GLGE.Placeable#childMatrixUpdate
  2899. * @event fires when any child objects have there transform changed supplies the target object as event.obj
  2900. * @param {object} event
  2901. */
  2902. /**
  2903. * Gets the root node object
  2904. * @returns {object}
  2905. */
  2906. GLGE.Placeable.prototype.getRoot=function(){
  2907. if(this.type==GLGE.G_ROOT){
  2908. return this;
  2909. }else if(this.parent){
  2910. var value=this.parent.getRoot();
  2911. if(!value) return this;
  2912. else return value;
  2913. }else{
  2914. return this;
  2915. }
  2916. }
  2917. /**
  2918. * Gets the id string of this text
  2919. * @returns {string}
  2920. */
  2921. GLGE.Placeable.prototype.getRef=function(){
  2922. if(this.id){
  2923. return this.id;
  2924. }else if(this.parent){
  2925. return this.parent.getRef();
  2926. }else{
  2927. return null;
  2928. }
  2929. }
  2930. /**
  2931. * Sets the id string
  2932. * @param {string} id The id string
  2933. */
  2934. GLGE.Placeable.prototype.setId=function(id){
  2935. this.id=id;
  2936. return this;
  2937. }
  2938. /**
  2939. * Gets the id string of this text
  2940. * @returns {string}
  2941. */
  2942. GLGE.Placeable.prototype.getId=function(){
  2943. return this.id
  2944. }
  2945. /**
  2946. * gets the object or poisition being looking at
  2947. * @param {array|object} value the location/object
  2948. */
  2949. GLGE.Placeable.prototype.getLookat=function(){
  2950. return this.lookAt;
  2951. }
  2952. /**
  2953. * sets the look at for this object, will be updated every frame
  2954. * @param {array|object} value the location/objec to look at
  2955. */
  2956. GLGE.Placeable.prototype.setLookat=function(value){
  2957. this.lookAt=value;
  2958. return this;
  2959. }
  2960. /**
  2961. * gets the up axis of the object
  2962. */
  2963. GLGE.Placeable.prototype.getUpAxis=function(){
  2964. return this.upAxis;
  2965. }
  2966. /**
  2967. * sets the upAxis for this object
  2968. * @param {array} value the up axis for the object
  2969. */
  2970. GLGE.Placeable.prototype.setUpAxis=function(value){
  2971. this.upAxis=value;
  2972. return this;
  2973. }
  2974. /**
  2975. * Points the object in the direction of the coords or placeable value
  2976. * @param {array|object} value the location/objec to look at
  2977. */
  2978. GLGE.Placeable.prototype.Lookat=function(value){
  2979. var objpos;
  2980. var pos=this.getPosition();
  2981. if(value.getPosition){
  2982. objpos=value.getPosition();
  2983. }else{
  2984. objpos={x:value[0],y:value[1],z:value[2]};
  2985. }
  2986. var coord=[pos.x-objpos.x,pos.y-objpos.y,pos.z-objpos.z];
  2987. var zvec=GLGE.toUnitVec3(coord);
  2988. var xvec=GLGE.toUnitVec3(GLGE.crossVec3(this.upAxis,zvec));
  2989. if(xvec[0]==0 && xvec[1]==0 && xvec[2]==0) xvec[1]=1;
  2990. var yvec=GLGE.toUnitVec3(GLGE.crossVec3(zvec,xvec));
  2991. this.setRotMatrix(GLGE.Mat4([xvec[0], yvec[0], zvec[0], 0,
  2992. xvec[1], yvec[1], zvec[1], 0,
  2993. xvec[2], yvec[2], zvec[2], 0,
  2994. 0, 0, 0, 1]));
  2995. }
  2996. /**
  2997. * Sets the transform mode
  2998. * @param {mode} value the transform mode
  2999. */
  3000. GLGE.Placeable.prototype.setTransformMode=function(value){
  3001. this.mode=value;
  3002. this.matrix=null;
  3003. return this;
  3004. }
  3005. /**
  3006. * Gets the euler rotation order
  3007. * @returns {number} the objects rotation matrix
  3008. */
  3009. GLGE.Placeable.prototype.getRotOrder=function(){
  3010. return this.rotOrder;
  3011. }
  3012. /**
  3013. * Sets the euler rotation order
  3014. * @param {number} value the order to rotate GLGE.ROT_XYZ,GLGE.ROT_XZY,etc..
  3015. */
  3016. GLGE.Placeable.prototype.setRotOrder=function(value){
  3017. this.rotOrder=value;
  3018. this.matrix=null;
  3019. this.rotmatrix=null;
  3020. return this;
  3021. }
  3022. /**
  3023. * Gets the rotaion matrix
  3024. * @returns {matrix} the objects rotation matrix
  3025. */
  3026. GLGE.Placeable.prototype.getRotMatrix=function(){
  3027. if(!this.rotmatrix){
  3028. var rotation=this.getRotation();
  3029. if(this.mode==GLGE.P_EULER) this.rotmatrix=GLGE.rotateMatrix(rotation.x,rotation.y,rotation.z,this.rotOrder);
  3030. if(this.mode==GLGE.P_QUAT) this.rotmatrix=GLGE.quatRotation(rotation.x,rotation.y,rotation.z,rotation.w);
  3031. }
  3032. return this.rotmatrix;
  3033. }
  3034. /**
  3035. * Sets the rotation matrix
  3036. * @param {matrix} the objects rotation matrix
  3037. */
  3038. GLGE.Placeable.prototype.setRotMatrix=function(matrix){
  3039. this.mode=GLGE.P_MATRIX;
  3040. this.rotmatrix=matrix;
  3041. this.updateMatrix();
  3042. return this;
  3043. }
  3044. /**
  3045. * Sets the x location of the object
  3046. * @param {number} value The value to assign to the x position
  3047. */
  3048. GLGE.Placeable.prototype.setLocX=function(value){this.locX=value; this.translateMatrix=null;this.staticMatrix=null;this.updateMatrix();return this;}
  3049. /**
  3050. * Sets the y location of the object
  3051. * @param {number} value The value to assign to the y position
  3052. */
  3053. GLGE.Placeable.prototype.setLocY=function(value){this.locY=value; this.translateMatrix=null;this.staticMatrix=null;this.updateMatrix();return this;}
  3054. /**
  3055. * Sets the z location of the object
  3056. * @param {number} value The value to assign to the z position
  3057. */
  3058. GLGE.Placeable.prototype.setLocZ=function(value){this.locZ=value; this.translateMatrix=null;this.staticMatrix=null;this.updateMatrix();return this;}
  3059. /**
  3060. * Sets the location of the object
  3061. * @param {number} x The value to assign to the x position
  3062. * @param {number} y The value to assign to the y position
  3063. * @param {number} z The value to assign to the z position
  3064. */
  3065. GLGE.Placeable.prototype.setLoc=function(x,y,z){this.locX=x;this.locY=y;this.locZ=z; this.translateMatrix=null;this.staticMatrix=null;this.updateMatrix();return this;}
  3066. /**
  3067. * Sets the x location displacement of the object, usefull for animation
  3068. * @param {number} value The value to assign to the x displacement
  3069. */
  3070. GLGE.Placeable.prototype.setDLocX=function(value){this.dLocX=value;this.translateMatrix=null;this.staticMatrix=null;this.updateMatrix();return this;}
  3071. /**
  3072. * Sets the y location displacement of the object, usefull for animation
  3073. * @param {number} value The value to assign to the y displacement
  3074. */
  3075. GLGE.Placeable.prototype.setDLocY=function(value){this.dLocY=value; this.translateMatrix=null;this.staticMatrix=null;this.updateMatrix();return this;}
  3076. /**
  3077. * Sets the z location displacement of the object, usefull for animation
  3078. * @param {number} value The value to assign to the z displacement
  3079. */
  3080. GLGE.Placeable.prototype.setDLocZ=function(value){this.dLocZ=value;this.translateMatrix=null;this.staticMatrix=null;this.updateMatrix();return this;}
  3081. /**
  3082. * Sets the location displacement of the object, useful for animation
  3083. * @param {number} x The value to assign to the x position
  3084. * @param {number} y The value to assign to the y position
  3085. * @param {number} z The value to assign to the z position
  3086. */
  3087. GLGE.Placeable.prototype.setDLoc=function(x,y,z){this.dLocX=x;this.dLocY=y;this.dLocZ=z; this.translateMatrix=null;this.staticMatrix=null;this.updateMatrix();return this;}
  3088. /**
  3089. * Sets the x quat value
  3090. * @param {number} value the x quat value
  3091. */
  3092. GLGE.Placeable.prototype.setQuatX=function(value){this.mode=GLGE.P_QUAT;this.quatX=parseFloat(value);this.staticMatrix=null;this.rotmatrix=null;this.updateMatrix();return this;}
  3093. /**
  3094. * Sets the y quat value
  3095. * @param {number} value the y quat value
  3096. */
  3097. GLGE.Placeable.prototype.setQuatY=function(value){this.mode=GLGE.P_QUAT;this.quatY=parseFloat(value);this.staticMatrix=null;this.rotmatrix=null;this.updateMatrix();return this;}
  3098. /**
  3099. * Sets the z quat value
  3100. * @param {number} value the z quat value
  3101. */
  3102. GLGE.Placeable.prototype.setQuatZ=function(value){this.mode=GLGE.P_QUAT;this.quatZ=parseFloat(value);this.staticMatrix=null;this.rotmatrix=null;this.updateMatrix();return this;}
  3103. /**
  3104. * Sets the w quat value
  3105. * @param {number} value the w quat value
  3106. */
  3107. GLGE.Placeable.prototype.setQuatW=function(value){this.mode=GLGE.P_QUAT;this.quatW=parseFloat(value);this.staticMatrix=null;this.rotmatrix=null;this.updateMatrix();return this;}
  3108. /**
  3109. * Sets the quaternions
  3110. * @param {number} x The value to assign to the x
  3111. * @param {number} y The value to assign to the y
  3112. * @param {number} z The value to assign to the z
  3113. * @param {number} w The value to assign to the w
  3114. */
  3115. GLGE.Placeable.prototype.setQuat=function(x,y,z,w){this.mode=GLGE.P_QUAT;this.quatX=x;this.quatY=y;this.quatZ=z;this.quatW=w;this.staticMatrix=null;this.rotmatrix=null;this.updateMatrix();return this;}
  3116. /**
  3117. * Sets the x rotation of the object
  3118. * @param {number} value The value to assign to the x rotation
  3119. */
  3120. GLGE.Placeable.prototype.setRotX=function(value){this.mode=GLGE.P_EULER;this.rotX=value;this.staticMatrix=null;this.rotmatrix=null;this.updateMatrix();return this;}
  3121. /**
  3122. * Sets the y rotation of the object
  3123. * @param {number} value The value to assign to the y rotation
  3124. */
  3125. GLGE.Placeable.prototype.setRotY=function(value){this.mode=GLGE.P_EULER;this.rotY=value;this.staticMatrix=null;this.rotmatrix=null;this.updateMatrix();return this;}
  3126. /**
  3127. * Sets the z rotation of the object
  3128. * @param {number} value The value to assign to the z rotation
  3129. */
  3130. GLGE.Placeable.prototype.setRotZ=function(value){this.mode=GLGE.P_EULER;this.rotZ=value;this.staticMatrix=null;this.rotmatrix=null;this.updateMatrix();return this;}
  3131. /**
  3132. * Sets the z rotation mode of the object
  3133. * @param {number or string} mode The value to assign to the rotation mode
  3134. */
  3135. GLGE.Placeable.prototype.setRotMode=function(mode){if(mode=="euler"||mode==GLGE.P_EULER){this.mode=GLGE.P_EULER;}else{this.mode=GLGE.P_QUAT;}this.updateMatrix();}
  3136. /**
  3137. * Sets the rotation of the object
  3138. * @param {number} x The value to assign to the x rotation
  3139. * @param {number} y The value to assign to the y rotation
  3140. * @param {number} z The value to assign to the z rotation
  3141. */
  3142. GLGE.Placeable.prototype.setRot=function(x,y,z){this.mode=GLGE.P_EULER;this.rotX=x;this.rotY=y;this.rotZ=z;this.staticMatrix=null;this.rotmatrix=null;this.updateMatrix();return this;}
  3143. /**
  3144. * Sets the x rotation displacement of the object, usefull for animation
  3145. * @param {number} value The value to assign to the x displacement
  3146. */
  3147. GLGE.Placeable.prototype.setDRotX=function(value){this.mode=GLGE.P_EULER;this.dRotX=value;this.staticMatrix=null;this.rotmatrix=null;this.updateMatrix();return this;}
  3148. /**
  3149. * Sets the y rotation displacement of the object, usefull for animation
  3150. * @param {number} value The value to assign to the y displacement
  3151. */
  3152. GLGE.Placeable.prototype.setDRotY=function(value){this.mode=GLGE.P_EULER;this.dRotY=value;this.staticMatrix=null;this.rotmatrix=null;this.updateMatrix();return this;}
  3153. /**
  3154. * Sets the z rotation displacement of the object, usefull for animation
  3155. * @param {number} value The value to assign to the z displacement
  3156. */
  3157. GLGE.Placeable.prototype.setDRotZ=function(value){this.mode=GLGE.P_EULER;this.dRotZ=value;this.staticMatrix=null;this.rotmatrix=null;this.updateMatrix();return this;}
  3158. /**
  3159. * Sets the rotation displacement of the object, useful for animation
  3160. * @param {number} x The value to assign to the x rotation
  3161. * @param {number} y The value to assign to the y rotation
  3162. * @param {number} z The value to assign to the z rotation
  3163. */
  3164. GLGE.Placeable.prototype.setDRot=function(x,y,z){this.mode=GLGE.P_EULER;this.dRotX=x;this.dRotY=y;this.dRotZ=z;this.staticMatrix=null;this.rotmatrix=null;this.updateMatrix();return this;}
  3165. /**
  3166. * Sets the x scale of the object
  3167. * @param {number} value The value to assign to the x scale
  3168. */
  3169. GLGE.Placeable.prototype.setScaleX=function(value){if(this.ScaleX==value) return this;this.scaleX=value;this.staticMatrix=null;this.scaleMatrix=null;this.updateMatrix();return this;}
  3170. /**
  3171. * Sets the y scale of the object
  3172. * @param {number} value The value to assign to the y scale
  3173. */
  3174. GLGE.Placeable.prototype.setScaleY=function(value){if(this.ScaleY==value) return this;this.scaleY=value;this.staticMatrix=null;this.scaleMatrix=null;this.updateMatrix();return this;}
  3175. /**
  3176. * Sets the z scale of the object
  3177. * @param {number} value The value to assign to the z scale
  3178. */
  3179. GLGE.Placeable.prototype.setScaleZ=function(value){if(this.ScaleZ==value) return this;this.scaleZ=value;this.staticMatrix=null;this.scaleMatrix=null;this.updateMatrix();return this;}
  3180. /**
  3181. * Sets the scale of the object
  3182. * @param {number} x The value to assign to the x scale
  3183. * @param {number} y The value to assign to the y scale
  3184. * @param {number} z The value to assign to the z scale
  3185. */
  3186. GLGE.Placeable.prototype.setScale=function(x,y,z){if(!y){y=x;z=x}; this.scaleX=x;this.scaleY=y;this.scaleZ=z;this.staticMatrix=null;this.scaleMatrix=null;this.updateMatrix();return this;}
  3187. /**
  3188. * Sets the x scale displacement of the object, usefull for animation
  3189. * @param {number} value The value to assign to the x displacement
  3190. */
  3191. GLGE.Placeable.prototype.setDScaleX=function(value){if(this.dScaleX==value) return this;this.dScaleX=value;this.staticMatrix=null;this.scaleMatrix=null;this.updateMatrix();return this;}
  3192. /**
  3193. * Sets the y scale displacement of the object, usefull for animation
  3194. * @param {number} value The value to assign to the y displacement
  3195. */
  3196. GLGE.Placeable.prototype.setDScaleY=function(value){if(this.dScaleY==value) return this;this.dScaleY=value;this.staticMatrix=null;this.scaleMatrix=null;this.updateMatrix();return this;}
  3197. /**
  3198. * Sets the z scale displacement of the object, usefull for animation
  3199. * @param {number} value The value to assign to the z displacement
  3200. */
  3201. GLGE.Placeable.prototype.setDScaleZ=function(value){if(this.dScaleZ==value) return this;this.dScaleZ=value;this.staticMatrix=null;this.scaleMatrix=null;this.updateMatrix();return this;}
  3202. /**
  3203. * Sets the scale displacement of the object, useful for animation
  3204. * @param {number} x The value to assign to the x scale
  3205. * @param {number} y The value to assign to the y scale
  3206. * @param {number} z The value to assign to the z scale
  3207. */
  3208. GLGE.Placeable.prototype.setDScale=function(x,y,z){this.dScaleX=x;this.dScaleY=y;this.dScaleZ=z;this.staticMatrix==null;this.scaleMatrix=null;this.updateMatrix();return this;}
  3209. /**
  3210. * Gets the x location of the object
  3211. * @returns {number}
  3212. */
  3213. GLGE.Placeable.prototype.getLocX=function(){return this.locX;}
  3214. /**
  3215. * Gets the y location of the object
  3216. * @returns {number}
  3217. */
  3218. GLGE.Placeable.prototype.getLocY=function(){return this.locY;}
  3219. /**
  3220. * Gets the z location of the object
  3221. * @returns {number}
  3222. */
  3223. GLGE.Placeable.prototype.getLocZ=function(){return this.locZ;}
  3224. /**
  3225. * Gets the x location displacement of the object
  3226. * @returns {number}
  3227. */
  3228. GLGE.Placeable.prototype.getDLocX=function(){return this.dLocX;}
  3229. /**
  3230. * Gets the y location displacement of the object
  3231. * @returns {number}
  3232. */
  3233. GLGE.Placeable.prototype.getDLocY=function(){return this.dLocY;}
  3234. /**
  3235. * Gets the z location displacement of the object
  3236. * @returns {number}
  3237. */
  3238. GLGE.Placeable.prototype.getDLocZ=function(){return this.dLocZ;}
  3239. /**
  3240. * Gets the x quat of the rotation
  3241. * @returns {number}
  3242. */
  3243. GLGE.Placeable.prototype.getQuatX=function(){return this.quatX;}
  3244. /**
  3245. * Gets the y quat of the rotation
  3246. * @returns {number}
  3247. */
  3248. GLGE.Placeable.prototype.getQuatY=function(){return this.quatY;}
  3249. /**
  3250. * Gets the z quat of the rotation
  3251. * @returns {number}
  3252. */
  3253. GLGE.Placeable.prototype.getQuatZ=function(){return this.quatZ;}
  3254. /**
  3255. * Gets the w quat of the rotation
  3256. * @returns {number}
  3257. */
  3258. GLGE.Placeable.prototype.getQuatW=function(){return this.quatW;}
  3259. /**
  3260. * Gets the x rotation of the object
  3261. * @returns {number}
  3262. */
  3263. GLGE.Placeable.prototype.getRotX=function(){return this.rotX;}
  3264. /**
  3265. * Gets the y rotation of the object
  3266. * @returns {number}
  3267. */
  3268. GLGE.Placeable.prototype.getRotY=function(){return this.rotY;}
  3269. /**
  3270. * Gets the z rotation of the object
  3271. * @returns {number}
  3272. */
  3273. GLGE.Placeable.prototype.getRotZ=function(){return this.rotZ;}
  3274. /**
  3275. * Gets the x rotaional displacement of the object
  3276. * @returns {number}
  3277. */
  3278. GLGE.Placeable.prototype.getDRotX=function(){return this.dRotX;}
  3279. /**
  3280. * Gets the y rotaional displacement of the object
  3281. * @returns {number}
  3282. */
  3283. GLGE.Placeable.prototype.getDRotY=function(){return this.dRotY;}
  3284. /**
  3285. * Gets the z rotaional displacement of the object
  3286. * @returns {number}
  3287. */
  3288. GLGE.Placeable.prototype.getDRotZ=function(){return this.dRotZ;}
  3289. /**
  3290. * Gets the x scale of the object
  3291. * @returns {number}
  3292. */
  3293. GLGE.Placeable.prototype.getScaleX=function(){return this.scaleX;}
  3294. /**
  3295. * Gets the y scale of the object
  3296. * @returns {number}
  3297. */
  3298. GLGE.Placeable.prototype.getScaleY=function(){return this.scaleY;}
  3299. /**
  3300. * Gets the z scale of the object
  3301. * @returns {number}
  3302. */
  3303. GLGE.Placeable.prototype.getScaleZ=function(){return this.scaleZ;}
  3304. /**
  3305. * Gets the x scale displacement of the object
  3306. * @returns {number}
  3307. */
  3308. GLGE.Placeable.prototype.getDScaleX=function(){return this.dScaleX;}
  3309. /**
  3310. * Gets the y scale displacement of the object
  3311. * @returns {number}
  3312. */
  3313. GLGE.Placeable.prototype.getDScaleY=function(){return this.dScaleY;}
  3314. /**
  3315. * Gets the z scale displacement of the object
  3316. * @returns {number}
  3317. */
  3318. GLGE.Placeable.prototype.getDScaleZ=function(){return this.dScaleZ;}
  3319. /**
  3320. * Gets the position of the object
  3321. * @returns {array}
  3322. */
  3323. GLGE.Placeable.prototype.getPosition=function(){
  3324. var position={};
  3325. position.x=parseFloat(this.locX)+parseFloat(this.dLocX);
  3326. position.y=parseFloat(this.locY)+parseFloat(this.dLocY);
  3327. position.z=parseFloat(this.locZ)+parseFloat(this.dLocZ);
  3328. return position;
  3329. }
  3330. /**
  3331. * Gets the rotation of the object
  3332. * @returns {object}
  3333. */
  3334. GLGE.Placeable.prototype.getRotation=function(){
  3335. var rotation={};
  3336. if(this.mode==GLGE.P_EULER){
  3337. rotation.x=parseFloat(this.rotX)+parseFloat(this.dRotX);
  3338. rotation.y=parseFloat(this.rotY)+parseFloat(this.dRotY);
  3339. rotation.z=parseFloat(this.rotZ)+parseFloat(this.dRotZ);
  3340. }
  3341. if(this.mode==GLGE.P_QUAT){
  3342. rotation.x=parseFloat(this.quatX);
  3343. rotation.y=parseFloat(this.quatY);
  3344. rotation.z=parseFloat(this.quatZ);
  3345. rotation.w=parseFloat(this.quatW);
  3346. }
  3347. return rotation;
  3348. }
  3349. /**
  3350. * Gets the scale of the object
  3351. * @returns {object}
  3352. */
  3353. GLGE.Placeable.prototype.getScale=function(){
  3354. var scale={};
  3355. scale.x=parseFloat(this.scaleX)+parseFloat(this.dScaleX);
  3356. scale.y=parseFloat(this.scaleY)+parseFloat(this.dScaleY);
  3357. scale.z=parseFloat(this.scaleZ)+parseFloat(this.dScaleZ);
  3358. return scale;
  3359. }
  3360. /**
  3361. * Gets the scale matrix
  3362. * @returns {object}
  3363. */
  3364. GLGE.Placeable.prototype.getScaleMatrix=function(){
  3365. if(!this.scaleMatrix){
  3366. this.scaleMatrix=GLGE.scaleMatrix(parseFloat(this.scaleX)+parseFloat(this.dScaleX),parseFloat(this.scaleY)+parseFloat(this.dScaleY),parseFloat(this.scaleZ)+parseFloat(this.dScaleZ));
  3367. }
  3368. return this.scaleMatrix;
  3369. }
  3370. /**
  3371. * Gets the translate matrix
  3372. * @returns {object}
  3373. */
  3374. GLGE.Placeable.prototype.getTranslateMatrix=function(){
  3375. if(!this.tmatrix) this.tmatrix=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1];
  3376. if(!this.translateMatrix){
  3377. this.tmatrix[3]=+this.locX+this.dLocX;
  3378. this.tmatrix[7]=+this.locY+this.dLocY;
  3379. this.tmatrix[11]=+this.locZ+this.dLocZ;
  3380. this.translateMatrix=this.tmatrix;
  3381. }
  3382. return this.translateMatrix;
  3383. }
  3384. /**
  3385. * Gets the local transform matrix
  3386. * @returns {object}
  3387. */
  3388. GLGE.Placeable.prototype.getLocalMatrix=function(){
  3389. this.getModelMatrix();
  3390. return this.localMatrix;
  3391. }
  3392. /**
  3393. * Sets a static transfrom matrix, overrides any rotations and translation that may be set
  3394. * @returns {object}
  3395. */
  3396. GLGE.Placeable.prototype.setStaticMatrix=function(matrix){
  3397. this.staticMatrix=matrix;
  3398. this.updateMatrix();
  3399. return this;
  3400. }
  3401. /**
  3402. * Clears the static matrix if one is set
  3403. * @returns {object}
  3404. */
  3405. GLGE.Placeable.prototype.clearStaticMatrix=function(){
  3406. this.staticMatrix=null;
  3407. this.updateMatrix();
  3408. return this;
  3409. }
  3410. /**
  3411. * Updates the model matrix
  3412. * @private
  3413. */
  3414. GLGE.Placeable.prototype.updateMatrix=function(){
  3415. this.matrix=null;
  3416. if(this.children){
  3417. for(var i=0;i<this.children.length;i++){
  3418. this.children[i].updateMatrix();
  3419. }
  3420. }
  3421. var o=obj=this;
  3422. obj.fireEvent("matrixUpdate",{obj:o});
  3423. if(obj=obj.parent) obj.fireEvent("childMatrixUpdate",{obj:o});
  3424. }
  3425. /**
  3426. * Gets the model matrix to transform the model within the world
  3427. */
  3428. GLGE.Placeable.prototype.getModelMatrix=function(){
  3429. if(!this.matrix){
  3430. GLGE.reuseMatrix4(this.invmatrix);
  3431. GLGE.reuseMatrix4(this.transmatrix);
  3432. GLGE.reuseMatrix4(this.transinvmatrix);
  3433. this.invmatrix=null;
  3434. this.transmatrix=null;
  3435. this.transinvmatrix=null;
  3436. if(this.staticMatrix){
  3437. var matrix=this.staticMatrix;
  3438. this.localMatrix=this.staticMatrix;
  3439. if(this.parent) matrix=GLGE.mulMat4(this.parent.getModelMatrix(),matrix);
  3440. this.matrix=matrix;
  3441. }else{
  3442. var translate=this.getTranslateMatrix();
  3443. var scale=this.getScaleMatrix();
  3444. var M1=GLGE.mulMat4(this.getRotMatrix(),scale);
  3445. var matrix=GLGE.mulMat4(translate,M1);
  3446. //GLGE.reuseMatrix4(M1);
  3447. this.localMatrix=matrix;
  3448. if(this.parent) matrix=GLGE.mulMat4(this.parent.getModelMatrix(),matrix);
  3449. this.matrix=matrix;
  3450. }
  3451. }
  3452. return this.matrix;
  3453. }
  3454. /**
  3455. * Gets the model inverse matrix to transform the model within the world
  3456. */
  3457. GLGE.Placeable.prototype.getInverseModelMatrix=function(){
  3458. if(!this.matrix){
  3459. this.getModelMatrix();
  3460. }
  3461. if(!this.invmatrix){
  3462. this.invmatrix=GLGE.transposeMat4(this.matrix);
  3463. }
  3464. return this.invmatrix;
  3465. }
  3466. /**
  3467. * Gets the model transposed matrix to transform the model within the world
  3468. */
  3469. GLGE.Placeable.prototype.getTransposeModelMatrix=function(){
  3470. if(!this.matrix){
  3471. this.getModelMatrix();
  3472. }
  3473. if(!this.transmatrix){
  3474. this.transmatrix=GLGE.transposeMat4(this.matrix);
  3475. }
  3476. return this.transmatrix;
  3477. }
  3478. /**
  3479. * Gets the model inverse transposed matrix to transform the model within the world
  3480. */
  3481. GLGE.Placeable.prototype.getTransposeInverseModelMatrix=function(){
  3482. if(!this.matrix){
  3483. this.getModelMatrix();
  3484. }
  3485. if(!this.transinvmatrix){
  3486. this.invtransmatrix=GLGE.transposeMat4(this.getInverseModelMatrix());
  3487. }
  3488. return this.transinvmatrix;
  3489. }
  3490. /**
  3491. * Moves the object
  3492. * @returns {array} amount array [x,y,z] to move
  3493. * @returns {number} reference move with respecct to GLGE.GLOBAL or GLGE.LOCAL
  3494. */
  3495. GLGE.Placeable.prototype.move=function(amount,reference){
  3496. if(!reference) reference=GLGE.GLOBAL;
  3497. switch(reference){
  3498. case GLGE.GLOBAL:
  3499. this.setLocX(+this.locX+amount[0]);
  3500. this.setLocY(+this.locY+amount[1]);
  3501. this.setLocZ(+this.locZ+amount[2]);
  3502. break;
  3503. case GLGE.LOCAL:
  3504. var matrix=this.getModelMatrix();
  3505. var xAxis=GLGE.toUnitVec3([matrix[0],matrix[1],matrix[2]]);
  3506. var yAxis=GLGE.toUnitVec3([matrix[4],matrix[5],matrix[6]]);
  3507. var zAxis=GLGE.toUnitVec3([matrix[8],matrix[9],matrix[10]]);
  3508. var x=xAxis[0]*amount[0]+xAxis[1]*amount[1]+xAxis[2]*amount[2];
  3509. var y=yAxis[0]*amount[0]+yAxis[1]*amount[1]+yAxis[2]*amount[2];
  3510. var z=zAxis[0]*amount[0]+zAxis[1]*amount[1]+zAxis[2]*amount[2];
  3511. this.setLocX(+this.locX+x);
  3512. this.setLocY(+this.locY+y);
  3513. this.setLocZ(+this.locZ+z);
  3514. break;
  3515. }
  3516. return this;
  3517. }
  3518. })(GLGE);/*
  3519. GLGE WebGL Graphics Engine
  3520. Copyright (c) 2010, Paul Brunt
  3521. All rights reserved.
  3522. Redistribution and use in source and binary forms, with or without
  3523. modification, are permitted provided that the following conditions are met:
  3524. * Redistributions of source code must retain the above copyright
  3525. notice, this list of conditions and the following disclaimer.
  3526. * Redistributions in binary form must reproduce the above copyright
  3527. notice, this list of conditions and the following disclaimer in the
  3528. documentation and/or other materials provided with the distribution.
  3529. * Neither the name of GLGE nor the
  3530. names of its contributors may be used to endorse or promote products
  3531. derived from this software without specific prior written permission.
  3532. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  3533. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  3534. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  3535. DISCLAIMED. IN NO EVENT SHALL PAUL BRUNT BE LIABLE FOR ANY
  3536. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  3537. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  3538. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  3539. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  3540. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  3541. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  3542. */
  3543. /**
  3544. * @fileOverview
  3545. * @name glge_jsonloader.js
  3546. * @author me@paulbrunt.co.uk
  3547. */
  3548. (function(GLGE){
  3549. /**
  3550. * @class A class to load json fragments from remote location or string
  3551. **/
  3552. GLGE.JSONLoader=function(){
  3553. }
  3554. GLGE.JSONLoader.prototype.downloadPriority=0;
  3555. /**
  3556. * Loads a json fragment from a url
  3557. * @param {string} url The URL to load
  3558. **/
  3559. GLGE.JSONLoader.prototype.setJSONSrc=function(url){
  3560. var GLGEObj=this;
  3561. GLGE.Message.messageLoader(url,function(text){
  3562. GLGEObj.setJSONString(text);
  3563. },this.downloadPriority);
  3564. }
  3565. /**
  3566. * Loads a json fragment from a string
  3567. * @param {string} string The URL to load
  3568. **/
  3569. GLGE.JSONLoader.prototype.setJSONString=function(string){
  3570. var message = JSON.parse(string);
  3571. //check to make sure this is the correct class type
  3572. if(message.type==this.className){
  3573. message.uid=this.uid;
  3574. //we don't want to create a new one we want to update this one
  3575. message.command="update";
  3576. GLGE.Message.parseMessage(message);
  3577. }
  3578. }
  3579. /**
  3580. * Sets the download priority
  3581. * @param {number} value The download priority
  3582. **/
  3583. GLGE.JSONLoader.prototype.setDownloadPriority=function(value){
  3584. this.downloadPriority=value;
  3585. }
  3586. /**
  3587. * Gets the download priority
  3588. * @returns {number} The download priority
  3589. **/
  3590. GLGE.JSONLoader.prototype.getDownloadPriority=function(){
  3591. return this.downloadPriority;
  3592. }
  3593. })(GLGE);/*
  3594. GLGE WebGL Graphics Engine
  3595. Copyright (c) 2010, Paul Brunt
  3596. All rights reserved.
  3597. Redistribution and use in source and binary forms, with or without
  3598. modification, are permitted provided that the following conditions are met:
  3599. * Redistributions of source code must retain the above copyright
  3600. notice, this list of conditions and the following disclaimer.
  3601. * Redistributions in binary form must reproduce the above copyright
  3602. notice, this list of conditions and the following disclaimer in the
  3603. documentation and/or other materials provided with the distribution.
  3604. * Neither the name of GLGE nor the
  3605. names of its contributors may be used to endorse or promote products
  3606. derived from this software without specific prior written permission.
  3607. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  3608. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  3609. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  3610. DISCLAIMED. IN NO EVENT SHALL PAUL BRUNT BE LIABLE FOR ANY
  3611. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  3612. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  3613. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  3614. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  3615. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  3616. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  3617. */
  3618. /**
  3619. * @fileOverview
  3620. * @name glge_group.js
  3621. * @author me@paulbrunt.co.uk
  3622. */
  3623. (function(GLGE){
  3624. /**
  3625. * @name GLGE.Group#downloadComplete
  3626. * @event fires when all the assets for this class have finished loading
  3627. * @param {object} data
  3628. */
  3629. /**
  3630. * @name GLGE.Group#childAdded
  3631. * @event fires when and object is added as a child
  3632. * @param {object} event
  3633. */
  3634. /**
  3635. * @name GLGE.Group#childRemoved
  3636. * @event fires when and object is removed
  3637. * @param {object} event
  3638. */
  3639. /**
  3640. * @constant
  3641. * @description Enumeration for node group type
  3642. */
  3643. GLGE.G_NODE=1;
  3644. /**
  3645. * @constant
  3646. * @description Enumeration for root group type
  3647. */
  3648. GLGE.G_ROOT=2;
  3649. /**
  3650. * @class Group class to allow object transform hierarchies
  3651. * @augments GLGE.Animatable
  3652. * @augments GLGE.Placeable
  3653. * @augments GLGE.QuickNotation
  3654. * @augments GLGE.JSONLoader
  3655. */
  3656. GLGE.Group=function(uid){
  3657. this.children=[];
  3658. var that=this;
  3659. this.downloadComplete=function(){
  3660. if(that.isComplete()) that.fireEvent("downloadComplete");
  3661. }
  3662. GLGE.Assets.registerAsset(this,uid);
  3663. }
  3664. GLGE.augment(GLGE.Placeable,GLGE.Group);
  3665. GLGE.augment(GLGE.Animatable,GLGE.Group);
  3666. GLGE.augment(GLGE.QuickNotation,GLGE.Group);
  3667. GLGE.augment(GLGE.JSONLoader,GLGE.Group);
  3668. GLGE.Group.prototype.children=null;
  3669. GLGE.Group.prototype.className="Group";
  3670. GLGE.Group.prototype.type=GLGE.G_NODE;
  3671. GLGE.Group.prototype.visible=true;
  3672. /**
  3673. * Sets the groups visibility
  3674. * @param {boolean} visable flag to indicate the objects visibility
  3675. */
  3676. GLGE.Group.prototype.setVisible=function(visible){
  3677. this.visible=visible;
  3678. return this;
  3679. }
  3680. /**
  3681. * Gets the groups visibility
  3682. * @returns flag to indicate the objects visibility
  3683. */
  3684. GLGE.Group.prototype.getVisible=function(){
  3685. return this.visible;
  3686. }
  3687. /**
  3688. * Checks if resources have finished downloading
  3689. * @returns {boolean}
  3690. */
  3691. GLGE.Group.prototype.isComplete=function(){
  3692. for(var i=0;i<this.children.length;i++){
  3693. if(this.children[i].isComplete && !this.children[i].isComplete()){
  3694. return false;
  3695. }
  3696. }
  3697. return true;
  3698. }
  3699. /**
  3700. * Sets the action for this Group
  3701. * @param {GLGE.Action} action the action to apply
  3702. */
  3703. GLGE.Group.prototype.setAction=function(action,blendTime,loop){
  3704. action.start(blendTime,loop,this.getNames());
  3705. return this;
  3706. }
  3707. /**
  3708. * Gets the name of the object and names of any sub objects
  3709. * @returns an object of name
  3710. */
  3711. GLGE.Group.prototype.getNames=function(names){
  3712. if(!names) names={};
  3713. var thisname=this.getName();
  3714. if(thisname!="") names[thisname]=this;
  3715. for(var i=0;i<this.children.length;i++){
  3716. if(this.children[i].getNames){
  3717. this.children[i].getNames(names);
  3718. }
  3719. }
  3720. return names;
  3721. }
  3722. /**
  3723. * Gets the bounding volume for this group
  3724. * @returns {GLGE.BoundingVolume}
  3725. */
  3726. GLGE.Group.prototype.getBoundingVolume=function(local){
  3727. this.boundingVolume=null;
  3728. for(var i=0; i<this.children.length;i++){
  3729. if(this.children[i].getBoundingVolume){
  3730. if(!this.boundingVolume) {
  3731. this.boundingVolume=this.children[i].getBoundingVolume(true).clone();
  3732. }else{
  3733. this.boundingVolume.addBoundingVolume(this.children[i].getBoundingVolume(true));
  3734. }
  3735. }
  3736. }
  3737. if(!this.boundingVolume) this.boundingVolume=new GLGE.BoundingVolume(0,0,0,0,0,0);
  3738. if(local){
  3739. this.boundingVolume.applyMatrix(this.getLocalMatrix());
  3740. }else{
  3741. this.boundingVolume.applyMatrix(this.getModelMatrix());
  3742. }
  3743. return this.boundingVolume;
  3744. }
  3745. /**
  3746. * Gets a list of all objects in this group
  3747. * @param {array} pointer to an array [optional]
  3748. * @returns {GLGE.Object[]} an array of GLGE.Objects
  3749. */
  3750. GLGE.Group.prototype.getObjects=function(objects){
  3751. if(this.lookAt) this.Lookat(this.lookAt);
  3752. if(this.animation) this.animate();
  3753. if(!objects) objects=[];
  3754. for(var i=0; i<this.children.length;i++){
  3755. if(this.children[i].className=="Object" || this.children[i].className=="Text" || this.children[i].toRender){
  3756. if(this.children[i].visible || this.children[i].visible==undefined){
  3757. if(this.children[i].renderFirst) objects.unshift(this.children[i]);
  3758. else objects.push(this.children[i]);
  3759. }
  3760. }else if(this.children[i].getObjects){
  3761. if(this.children[i].visible || this.children[i].visible==undefined){
  3762. this.children[i].getObjects(objects);
  3763. }
  3764. }
  3765. }
  3766. return objects;
  3767. }
  3768. /**
  3769. * Gets a list of all lights in this group
  3770. * @param {array} pointer to an array [optional]
  3771. * @returns {GLGE.Lights[]} an array of GLGE.Lights
  3772. */
  3773. GLGE.Group.prototype.getLights=function(lights){
  3774. if(!lights) lights=[];
  3775. for(var i=0; i<this.children.length;i++){
  3776. if(this.children[i].className=="Light"){
  3777. lights.push(this.children[i]);
  3778. }else if(this.children[i].getLights){
  3779. this.children[i].getLights(lights);
  3780. }
  3781. }
  3782. return lights;
  3783. }
  3784. /**
  3785. * Forces an update of all shaders and programs in this group
  3786. */
  3787. GLGE.Group.prototype.updateAllPrograms=function(){
  3788. var objects=this.getObjects();
  3789. for(var i=0;i<objects.length;i++){
  3790. if(objects[i].updateProgram) objects[i].updateProgram();
  3791. }
  3792. }
  3793. /**
  3794. * Adds a new object to this group
  3795. * @param {object} object the object to add to this group
  3796. */
  3797. GLGE.Group.prototype.addChild=function(object){
  3798. if(object.parent) object.parent.removeChild(object);
  3799. if(this.noCastShadows!=null && object.noCastShadows==null && object.setCastShadows) object.setCastShadows(!this.noCastShadows);
  3800. GLGE.reuseMatrix4(object.matrix);
  3801. object.matrix=null; //clear any cache
  3802. object.parent=this;
  3803. this.children.push(object);
  3804. //if the child added contains lights or is a light then we'll need to update shader programs
  3805. if((object.getLights && object.getLights().length>0) || object.className=="Light"){
  3806. var root=object;
  3807. while(root.parent) root=root.parent;
  3808. root.updateAllPrograms();
  3809. }
  3810. if(object.addEventListener){
  3811. object.addEventListener("shaderupdate",function(){
  3812. var root=this;
  3813. while(root.parent) root=root.parent;
  3814. root.updateAllPrograms();
  3815. });
  3816. object.addEventListener("downloadComplete",this.downloadComplete);
  3817. }
  3818. this.fireEvent("childAdded",{obj:object});
  3819. if(object.fireEvent) object.fireEvent("appened",{obj:this});
  3820. this.fireEvent("childAdded",{obj:object});
  3821. //fire child added event for all parents as well
  3822. var o=this;
  3823. while(o=o.parent) o.fireEvent("childAdded",{obj:object,target:this});
  3824. return this;
  3825. }
  3826. GLGE.Group.prototype.addObject=GLGE.Group.prototype.addChild;
  3827. GLGE.Group.prototype.addObjectInstance=GLGE.Group.prototype.addChild;
  3828. GLGE.Group.prototype.addGroup=GLGE.Group.prototype.addChild;
  3829. GLGE.Group.prototype.addLight=GLGE.Group.prototype.addChild;
  3830. GLGE.Group.prototype.addText=GLGE.Group.prototype.addChild;
  3831. GLGE.Group.prototype.addSkeleton=GLGE.Group.prototype.addChild;
  3832. GLGE.Group.prototype.addCamera=GLGE.Group.prototype.addChild;
  3833. GLGE.Group.prototype.addWavefront=GLGE.Group.prototype.addChild;
  3834. /**
  3835. * Removes an object or sub group from this group
  3836. * @param {object} object the item to remove
  3837. */
  3838. GLGE.Group.prototype.removeChild=function(object){
  3839. for(var i=0;i<this.children.length;i++){
  3840. if(this.children[i]==object){
  3841. if(this.children[i].removeEventListener){
  3842. this.children[i].removeEventListener("downloadComplete",this.downloadComplete);
  3843. }
  3844. this.children.splice(i, 1);
  3845. if(this.scene && this.scene["remove"+object.className]){
  3846. this.scene["remove"+object.className](object);
  3847. }
  3848. if(object.fireEvent) object.fireEvent("removed",{obj:this});
  3849. this.fireEvent("childRemoved",{obj:object});
  3850. //fire child removed event for all parents as well
  3851. var o=this;
  3852. while(o=o.parent) o.fireEvent("childRemoved",{obj:object,target:this});
  3853. break;
  3854. }
  3855. }
  3856. }
  3857. /**
  3858. * Gets an array of all children in this group
  3859. */
  3860. GLGE.Group.prototype.getChildren=function(){
  3861. return this.children;
  3862. }
  3863. /**
  3864. * Initiallize all the GL stuff needed to render to screen
  3865. * @private
  3866. */
  3867. GLGE.Group.prototype.GLInit=function(gl){
  3868. this.gl=gl;
  3869. for(var i=0;i<this.children.length;i++){
  3870. if(this.children[i].GLInit){
  3871. this.children[i].GLInit(gl);
  3872. }
  3873. }
  3874. }
  3875. /**
  3876. * Gets the pickable flag for the object
  3877. */
  3878. GLGE.Group.prototype.getPickable=function(){
  3879. return this.pickable;
  3880. }
  3881. /**
  3882. * Sets the pickable flag for the object
  3883. * @param {boolean} value the picking flag
  3884. */
  3885. GLGE.Group.prototype.setPickable=function(pickable){
  3886. for(var i=0;i<this.children.length;i++){
  3887. if(this.children[i].setPickable){
  3888. this.children[i].setPickable(pickable);
  3889. }
  3890. }
  3891. this.pickable=pickable;
  3892. return this;
  3893. }
  3894. })(GLGE);/*
  3895. GLGE WebGL Graphics Engine
  3896. Copyright (c) 2010, Paul Brunt
  3897. All rights reserved.
  3898. Redistribution and use in source and binary forms, with or without
  3899. modification, are permitted provided that the following conditions are met:
  3900. * Redistributions of source code must retain the above copyright
  3901. notice, this list of conditions and the following disclaimer.
  3902. * Redistributions in binary form must reproduce the above copyright
  3903. notice, this list of conditions and the following disclaimer in the
  3904. documentation and/or other materials provided with the distribution.
  3905. * Neither the name of GLGE nor the
  3906. names of its contributors may be used to endorse or promote products
  3907. derived from this software without specific prior written permission.
  3908. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  3909. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  3910. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  3911. DISCLAIMED. IN NO EVENT SHALL PAUL BRUNT BE LIABLE FOR ANY
  3912. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  3913. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  3914. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  3915. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  3916. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  3917. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  3918. */
  3919. /**
  3920. * @fileOverview
  3921. * @name glge_messages.js
  3922. * @author me@paulbrunt.co.uk
  3923. */
  3924. (function(GLGE){
  3925. /**
  3926. * @namespace GLGE Messaging System
  3927. */
  3928. GLGE.Message={};
  3929. /**
  3930. * @function parses messages and updates the scene graph
  3931. */
  3932. GLGE.Message.parseMessage=function(msg){
  3933. switch(msg.command){
  3934. case "create":
  3935. var obj=new GLGE[msg.type](msg.uid);
  3936. this.setAttributes(obj,msg.attributes);
  3937. if(msg.children) GLGE.Message.addChildren(obj,msg.children);
  3938. return obj;
  3939. break;
  3940. case "update":
  3941. var obj=GLGE.Assets.get(msg.uid);
  3942. this.setAttributes(obj,msg.attributes);
  3943. if(msg.add) GLGE.Message.addChildren(obj,msg.add);
  3944. if(msg.remove) GLGE.Message.removeChildren(obj,msg.remove);
  3945. return obj;
  3946. break;
  3947. }
  3948. return null;
  3949. }
  3950. /**
  3951. * @function parses the attributes from a message
  3952. * @private
  3953. */
  3954. GLGE.Message.setAttributes=function(obj,attribs){
  3955. if(attribs){
  3956. for(var attrib in attribs){
  3957. if(obj["set"+attrib]){
  3958. //check to see if the attribute has to be parsed as a message
  3959. if(attribs[attrib].command){
  3960. attribs[attrib]=GLGE.Message.parseMessage(attribs[attrib]);
  3961. }
  3962. obj["set"+attrib](attribs[attrib]);
  3963. }
  3964. }
  3965. }
  3966. return this;
  3967. }
  3968. /**
  3969. * @function parses the children to add
  3970. * @private
  3971. */
  3972. GLGE.Message.addChildren=function(obj,children){
  3973. if(!(children instanceof Array)) children=[children];
  3974. for(var i=0;i<children.length;i++){
  3975. if(children[i].command){
  3976. var asset=GLGE.Message.parseMessage(children[i]);
  3977. }else{
  3978. var asset=GLGE.Assets.get(children[i]);
  3979. }
  3980. obj["add"+asset.className](asset);
  3981. }
  3982. }
  3983. /**
  3984. * @function parses the children to remove
  3985. * @private
  3986. */
  3987. GLGE.Message.removeChildren=function(obj,children){
  3988. if(!(children instanceof Array)) children=[children];
  3989. for(var i=0;i<children.length;i++){
  3990. var asset=GLGE.Assets.get(children[i]);
  3991. obj["add"+asset.className](asset);
  3992. }
  3993. }
  3994. GLGE.Message.toLoad=[];
  3995. GLGE.Message.messageLoader=function(url,callback,priority){
  3996. GLGE.Message.toLoad.push([url,callback,priority]);
  3997. if(GLGE.Message.toLoad.length==1) GLGE.Message.loadMessages();
  3998. }
  3999. GLGE.Message.loadMessages=function(){
  4000. //TODO: use priority
  4001. var nextDoc=GLGE.Message.toLoad.pop();
  4002. var req=new XMLHttpRequest();
  4003. req.onreadystatechange = function() {
  4004. if(this.readyState == 4){
  4005. if(this.status == 200 || this.status==0){
  4006. nextDoc[1](this.responseText);
  4007. }else{
  4008. GLGE.error("Error loading Document: "+nextDoc[0]+" status "+this.status);
  4009. }
  4010. }
  4011. }
  4012. req.open("GET", nextDoc[0], true);
  4013. req.send("");
  4014. if(GLGE.Message.toLoad.length>0) GLGE.Message.loadMessages();
  4015. }
  4016. })(GLGE);/*
  4017. GLGE WebGL Graphics Engine
  4018. Copyright (c) 2010, Paul Brunt
  4019. All rights reserved.
  4020. Redistribution and use in source and binary forms, with or without
  4021. modification, are permitted provided that the following conditions are met:
  4022. * Redistributions of source code must retain the above copyright
  4023. notice, this list of conditions and the following disclaimer.
  4024. * Redistributions in binary form must reproduce the above copyright
  4025. notice, this list of conditions and the following disclaimer in the
  4026. documentation and/or other materials provided with the distribution.
  4027. * Neither the name of GLGE nor the
  4028. names of its contributors may be used to endorse or promote products
  4029. derived from this software without specific prior written permission.
  4030. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  4031. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  4032. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  4033. DISCLAIMED. IN NO EVENT SHALL PAUL BRUNT BE LIABLE FOR ANY
  4034. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  4035. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  4036. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  4037. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  4038. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  4039. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  4040. */
  4041. /**
  4042. * @fileOverview
  4043. * @name glge_action.js
  4044. * @author me@paulbrunt.co.uk
  4045. */
  4046. (function(GLGE){
  4047. /**
  4048. * @class Class to describe and action on a skeleton
  4049. * @param {string} uid a unique reference string for this object
  4050. * @augments GLGE.QuickNotation
  4051. * @augments GLGE.JSONLoader
  4052. */
  4053. GLGE.Action=function(uid){
  4054. this.channels=[];
  4055. GLGE.Assets.registerAsset(this,uid);
  4056. };
  4057. GLGE.augment(GLGE.QuickNotation,GLGE.Action);
  4058. GLGE.augment(GLGE.JSONLoader,GLGE.Action);
  4059. /**
  4060. * @name Action#animFinished
  4061. * @event
  4062. * @param {object} data
  4063. */
  4064. GLGE.augment(GLGE.Events,GLGE.Action);
  4065. /**
  4066. * Starts playing the action
  4067. */
  4068. GLGE.Action.prototype.start=function(blendTime,loop,names){
  4069. if(!loop) loop=false;
  4070. if(!blendTime) blendTime=0;
  4071. var channels=this.channels;
  4072. var start=GLGE.now();
  4073. this.animFinished=false;
  4074. for(var i=0;i<channels.length;i++){
  4075. var animation=channels[i].getAnimation();
  4076. var action=this;
  4077. var channel=channels[i];
  4078. var target=channel.getTarget();
  4079. if(typeof target=="string"){
  4080. if(names && names[target]){
  4081. target=names[target];
  4082. }
  4083. }
  4084. var closure={};
  4085. closure.finishEvent=function(data){
  4086. target.removeEventListener("animFinished",closure.finishEvent);
  4087. if(!action.animFinished && target.animation==animation){
  4088. action.fireEvent("animFinished",{});
  4089. action.animFinished=true;
  4090. }
  4091. }
  4092. target.addEventListener("animFinished",closure.finishEvent);
  4093. target.setAnimation(animation,blendTime,start);
  4094. target.setLoop(loop);
  4095. }
  4096. };
  4097. /**
  4098. * Sets the start frame for all animations
  4099. * @param {number} startFrame the starting frame for the animation
  4100. */
  4101. GLGE.Action.prototype.setStartFrame=function(startFrame){
  4102. for(var i=0;i<this.channels.length;i++){
  4103. this.channels[i].getAnimation().setStartFrame(startFrame);
  4104. }
  4105. return this;
  4106. };
  4107. /**
  4108. * Sets the number of frames to play
  4109. * @param {number} frame the number of frames to play
  4110. */
  4111. GLGE.Action.prototype.setFrames=function(frames){
  4112. for(var i=0;i<this.channels.length;i++){
  4113. this.channels[i].getAnimation().setFrames(frames);
  4114. }
  4115. return this;
  4116. };
  4117. /**
  4118. * Adds and action channel to this action
  4119. * @param {GLGE.ActionChannel} channel the channel to be added
  4120. */
  4121. GLGE.Action.prototype.addActionChannel=function(channel){
  4122. this.channels.push(channel);
  4123. return this;
  4124. };
  4125. /**
  4126. * Removes and action channel to this action
  4127. * @param {GLGE.ActionChannel} channel the channel to be removed
  4128. */
  4129. GLGE.Action.prototype.removeActionChannel=function(channel){
  4130. for(var i=0;i<this.channels.length;i++){
  4131. if(this.channels[i]==channels){
  4132. this.channels.splice(i,1);
  4133. break;
  4134. }
  4135. }
  4136. };
  4137. })(GLGE);
  4138. /*
  4139. GLGE WebGL Graphics Engine
  4140. Copyright (c) 2010, Paul Brunt
  4141. All rights reserved.
  4142. Redistribution and use in source and binary forms, with or without
  4143. modification, are permitted provided that the following conditions are met:
  4144. * Redistributions of source code must retain the above copyright
  4145. notice, this list of conditions and the following disclaimer.
  4146. * Redistributions in binary form must reproduce the above copyright
  4147. notice, this list of conditions and the following disclaimer in the
  4148. documentation and/or other materials provided with the distribution.
  4149. * Neither the name of GLGE nor the
  4150. names of its contributors may be used to endorse or promote products
  4151. derived from this software without specific prior written permission.
  4152. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  4153. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  4154. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  4155. DISCLAIMED. IN NO EVENT SHALL PAUL BRUNT BE LIABLE FOR ANY
  4156. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  4157. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  4158. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  4159. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  4160. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  4161. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  4162. */
  4163. /**
  4164. * @fileOverview
  4165. * @name glge_actionchannel.js
  4166. * @author me@paulbrunt.co.uk
  4167. */
  4168. (function(GLGE){
  4169. /**
  4170. * @class Class defining a channel of animation for an action
  4171. * @param {string} uid a unique reference string for this object
  4172. * @augments GLGE.QuickNotation
  4173. * @augments GLGE.JSONLoader
  4174. */
  4175. GLGE.ActionChannel=function(uid){
  4176. GLGE.Assets.registerAsset(this,uid);
  4177. }
  4178. GLGE.augment(GLGE.QuickNotation,GLGE.ActionChannel);
  4179. GLGE.augment(GLGE.JSONLoader,GLGE.ActionChannel);
  4180. /**
  4181. * Sets the name/object of the bone channel
  4182. * @param {string} name the name of the bone channel
  4183. */
  4184. GLGE.ActionChannel.prototype.setTarget=function(object){
  4185. this.target=object;
  4186. };
  4187. /**
  4188. * Sets the animation for this channel
  4189. * @param {GLGE.AnimationVector} animation the animation vector for this channel
  4190. */
  4191. GLGE.ActionChannel.prototype.setAnimation=function(animation){
  4192. this.animation=animation;
  4193. };
  4194. /**
  4195. * Gets the name/object of the bone channel
  4196. * @returns {string} the name of the bone channel
  4197. */
  4198. GLGE.ActionChannel.prototype.getTarget=function(){
  4199. return this.target;
  4200. };
  4201. /**
  4202. * Gets the animation vector for this channel
  4203. * @returns {GLGE.AnimationVector} the animation vector for this channel
  4204. */
  4205. GLGE.ActionChannel.prototype.getAnimation=function(){
  4206. return this.animation;
  4207. };
  4208. })(GLGE);
  4209. /*
  4210. GLGE WebGL Graphics Engine
  4211. Copyright (c) 2010, Paul Brunt
  4212. All rights reserved.
  4213. Redistribution and use in source and binary forms, with or without
  4214. modification, are permitted provided that the following conditions are met:
  4215. * Redistributions of source code must retain the above copyright
  4216. notice, this list of conditions and the following disclaimer.
  4217. * Redistributions in binary form must reproduce the above copyright
  4218. notice, this list of conditions and the following disclaimer in the
  4219. documentation and/or other materials provided with the distribution.
  4220. * Neither the name of GLGE nor the
  4221. names of its contributors may be used to endorse or promote products
  4222. derived from this software without specific prior written permission.
  4223. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  4224. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  4225. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  4226. DISCLAIMED. IN NO EVENT SHALL PAUL BRUNT BE LIABLE FOR ANY
  4227. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  4228. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  4229. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  4230. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  4231. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  4232. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  4233. */
  4234. /**
  4235. * @fileOverview
  4236. * @name glge_animationcurve.js
  4237. * @author me@paulbrunt.co.uk
  4238. */
  4239. (function(GLGE){
  4240. /**
  4241. * @class A curve which interpolates between control points
  4242. * @augments GLGE.QuickNotation
  4243. * @augments GLGE.JSONLoader
  4244. */
  4245. GLGE.AnimationCurve=function(uid){
  4246. this.keyFrames=[];
  4247. this.solutions={};
  4248. this.caches={};
  4249. GLGE.Assets.registerAsset(this,uid);
  4250. };
  4251. GLGE.augment(GLGE.QuickNotation,GLGE.AnimationCurve);
  4252. GLGE.augment(GLGE.JSONLoader,GLGE.AnimationCurve);
  4253. GLGE.AnimationCurve.prototype.className="AnimationCurve";
  4254. GLGE.AnimationCurve.prototype.keyFrames=null;
  4255. /**
  4256. * Adds a point to the curve
  4257. * @param {object} point The point to add
  4258. * @returns {Number} Index of the newly added point
  4259. */
  4260. GLGE.AnimationCurve.prototype.addPoint=function(point){
  4261. this.keyFrames.push(point);
  4262. return this.keyFrames.length-1;
  4263. };
  4264. GLGE.AnimationCurve.prototype.addStepPoint=GLGE.AnimationCurve.prototype.addPoint;
  4265. GLGE.AnimationCurve.prototype.addLinearPoint=GLGE.AnimationCurve.prototype.addPoint;
  4266. GLGE.AnimationCurve.prototype.addBezTriple=GLGE.AnimationCurve.prototype.addPoint;
  4267. /**
  4268. * Get the value of the curve at any point
  4269. * @param {Number} frame The frame(x-coord) to return the value for
  4270. * @returns {Number} The value of the curve at the given point
  4271. */
  4272. GLGE.AnimationCurve.prototype.coord=function(x,y){
  4273. return {x:x,y:y}
  4274. }
  4275. /**
  4276. * Sets the animation channel this curve animates
  4277. * @param {string} channel The property to animate
  4278. */
  4279. GLGE.AnimationCurve.prototype.setChannel=function(channel){
  4280. this.channel=channel
  4281. }
  4282. GLGE.AnimationCurve.prototype.getValue=function(frame){
  4283. if(this.keyFrames.length==0) return 0;
  4284. if(this.caches[frame]) return this.caches[frame];
  4285. var startKey;
  4286. var endKey;
  4287. var preStartKey;
  4288. var preEndKey;
  4289. if(frame<this.keyFrames[0].x) return this.keyFrames[0].y;
  4290. for(var i=0; i<this.keyFrames.length;i++){
  4291. if(this.keyFrames[i].x==frame){
  4292. return this.keyFrames[i].y;
  4293. }
  4294. if(this.keyFrames[i].x<=frame && (startKey==undefined || this.keyFrames[i].x>this.keyFrames[startKey].x)){
  4295. preStartKey=startKey;
  4296. startKey=i;
  4297. }else if(this.keyFrames[i].x<=frame && (preStartKey==undefined || this.keyFrames[i].x>this.keyFrames[preStartKey].x)){
  4298. preStartKey=i;
  4299. }
  4300. if(this.keyFrames[i].x>frame && (endKey==undefined || this.keyFrames[i].x<=this.keyFrames[endKey].x)){
  4301. preEndKey=endKey;
  4302. endKey=i;
  4303. }else if(this.keyFrames[i].x>frame && (preEndKey==undefined || this.keyFrames[i].x<=this.keyFrames[preEndKey].x)){
  4304. preEndKey=i;
  4305. }
  4306. }
  4307. if(startKey==undefined){
  4308. startKey=endKey;
  4309. endKey=preEndKey;
  4310. }
  4311. if(endKey==undefined){
  4312. endKey=startKey;
  4313. startKey=preStartKey;
  4314. }
  4315. if(this.keyFrames[startKey] instanceof GLGE.BezTriple && this.keyFrames[endKey] instanceof GLGE.BezTriple){
  4316. var C1=this.coord(this.keyFrames[startKey].x,this.keyFrames[startKey].y);
  4317. var C2=this.coord(this.keyFrames[startKey].x3,this.keyFrames[startKey].y3);
  4318. var C3=this.coord(this.keyFrames[endKey].x1,this.keyFrames[endKey].y1);
  4319. var C4=this.coord(this.keyFrames[endKey].x,this.keyFrames[endKey].y);
  4320. return this.atX(frame,C1,C2,C3,C4).y;
  4321. }
  4322. if(this.keyFrames[startKey] instanceof GLGE.LinearPoint && this.keyFrames[endKey] instanceof GLGE.BezTriple){
  4323. var C1=this.coord(this.keyFrames[startKey].x,this.keyFrames[startKey].y);
  4324. var C2=this.coord(this.keyFrames[endKey].x1,this.keyFrames[endKey].y1);
  4325. var C3=this.coord(this.keyFrames[endKey].x1,this.keyFrames[endKey].y1);
  4326. var C4=this.coord(this.keyFrames[endKey].x,this.keyFrames[endKey].y);
  4327. return this.atX(frame,C1,C2,C3,C4).y;
  4328. }
  4329. if(this.keyFrames[startKey] instanceof GLGE.BezTriple && this.keyFrames[endKey] instanceof GLGE.LinearPoint){
  4330. var C1=this.coord(this.keyFrames[startKey].x,this.keyFrames[startKey].y);
  4331. var C2=this.coord(this.keyFrames[startKey].x3,this.keyFrames[startKey].y3);
  4332. var C3=this.coord(this.keyFrames[startKey].x3,this.keyFrames[startKey].y3);
  4333. var C4=this.coord(this.keyFrames[endKey].x,this.keyFrames[endKey].y);
  4334. return this.atX(frame,C1,C2,C3,C4).y;
  4335. }
  4336. if(this.keyFrames[startKey] instanceof GLGE.LinearPoint && this.keyFrames[endKey] instanceof GLGE.LinearPoint){
  4337. var value=(frame-this.keyFrames[startKey].x)*(this.keyFrames[endKey].y-this.keyFrames[startKey].y)/(this.keyFrames[endKey].x-this.keyFrames[startKey].x)+this.keyFrames[startKey].y;
  4338. return value;
  4339. }
  4340. if(this.keyFrames[startKey] instanceof GLGE.StepPoint){
  4341. return this.keyFrames[startKey].y
  4342. }
  4343. if(!this.keyFrames.preStartKey) this.keyFrames.preStartKey=this.keyFrames[0].y;
  4344. this.caches[frame]=this.keyFrames.preStartKey;
  4345. return this.caches[frame];
  4346. };
  4347. /**
  4348. * Function used to calculate bezier curve
  4349. * @private
  4350. */
  4351. GLGE.AnimationCurve.prototype.B1=function(t) { return t*t*t };
  4352. /**
  4353. * Function used to calculate bezier curve
  4354. * @private
  4355. */
  4356. GLGE.AnimationCurve.prototype.B2=function(t) { return 3*t*t*(1-t) };
  4357. /**
  4358. * Function used to calculate bezier curve
  4359. * @private
  4360. */
  4361. GLGE.AnimationCurve.prototype.B3=function(t) { return 3*t*(1-t)*(1-t) };
  4362. /**
  4363. * Function used to calculate bezier curve
  4364. * @private
  4365. */
  4366. GLGE.AnimationCurve.prototype.B4=function(t) { return (1-t)*(1-t)*(1-t) };
  4367. /**
  4368. * Gets the value of a bezier curve at a given point
  4369. * @private
  4370. */
  4371. GLGE.AnimationCurve.prototype.getBezier=function(t,C1,C2,C3,C4) {
  4372. var pos = {};
  4373. pos.x = C1.x*this.B1(t) + C2.x*this.B2(t) + C3.x*this.B3(t) + C4.x*this.B4(t);
  4374. pos.y = C1.y*this.B1(t) + C2.y*this.B2(t) + C3.y*this.B3(t) + C4.y*this.B4(t);
  4375. return pos;
  4376. };
  4377. /**
  4378. * Solves cubic equation to get the parametic value of the curve at a specified point
  4379. * @private
  4380. */
  4381. GLGE.AnimationCurve.prototype.Quad3Solve=function(a,b,c,d){
  4382. ref=a+"-"+b+"-"+"-"+c+"-"+d;
  4383. if(this.solutions[ref]){
  4384. return this.solutions[ref];
  4385. }
  4386. else
  4387. {
  4388. b /= a;c /= a;d /= a;
  4389. var q, r, d1, s, t, t1, r13;
  4390. q = (3.0*c - (b*b))/9.0;
  4391. r = -(27.0*d) + b*(9.0*c - 2.0*(b*b));
  4392. r /= 54.0;
  4393. t1 = (b/3.0);
  4394. discrim = q*q*q + r*r;
  4395. result=[];
  4396. if (discrim > 0) {
  4397. // one real, two complex
  4398. s = r + Math.sqrt(discrim);
  4399. s = ((s < 0) ? -Math.pow(-s, (1.0/3.0)) : Math.pow(s, (1.0/3.0)));
  4400. t = r - Math.sqrt(discrim);
  4401. t = ((t < 0) ? -Math.pow(-t, (1.0/3.0)) : Math.pow(t, (1.0/3.0)));
  4402. result[0] = -t1 + s + t;
  4403. t1 = t1 + (s + t)/2.0;
  4404. result[1] = result[2] = -t1;
  4405. t1 = Math.sqrt(3.0)*(-t + s)/2;
  4406. }
  4407. else if (discrim == 0){
  4408. // All roots real
  4409. r13 = ((r < 0) ? -Math.pow(-r,(1.0/3.0)) : Math.pow(r,(1.0/3.0)));
  4410. result[1] = -t1 + 2.0*r13;
  4411. result[1] = result[2] = -(r13 + t1);
  4412. }
  4413. else
  4414. {
  4415. q = -q;
  4416. d1 = q*q*q;
  4417. d1 = Math.acos(r/Math.sqrt(1));
  4418. r13 = 2.0*Math.sqrt(q);
  4419. result[0] = -t1 + r13*Math.cos(d1/3.0);
  4420. result[1] = -t1 + r13*Math.cos((d1 + 2.0*Math.PI)/3.0);
  4421. result[2] = -t1 + r13*Math.cos((d1 + 4.0*Math.PI)/3.0);
  4422. }
  4423. var toreturn=false;
  4424. //determine which is the correct result
  4425. if(result[0]>=0 && result[0]<=1) toreturn=result[0];
  4426. if(!toreturn && result[1]>=0 && result[1]<=1) toreturn=result[1];
  4427. if(!toreturn && result[2]>=0 && result[2]<=1) toreturn=result[2];
  4428. //cache result for next time
  4429. this.solutions[ref]=toreturn;
  4430. return toreturn;
  4431. }
  4432. };
  4433. /**
  4434. * Get the value of the a single bezier curve
  4435. * @param {Number} x xcoord of point to get
  4436. * @param {Number} C1 First bezier control point
  4437. * @param {Number} C2 Second bezier control point
  4438. * @param {Number} C3 Third bezier control point
  4439. * @param {Number} C4 Forth bezier control point
  4440. * @returns {Number} The value of the curve at the given x
  4441. */
  4442. GLGE.AnimationCurve.prototype.atX=function(x,C1,C2,C3,C4){
  4443. a=C1.x-C2.x*3+C3.x*3-C4.x;
  4444. b=C2.x*3-C3.x*6+C4.x*3;
  4445. c=C3.x*3-C4.x*3;
  4446. d=C4.x-x;
  4447. return this.getBezier(this.Quad3Solve(a,b,c,d),C1,C2,C3,C4);
  4448. };
  4449. })(GLGE);
  4450. /*
  4451. GLGE WebGL Graphics Engine
  4452. Copyright (c) 2010, Paul Brunt
  4453. All rights reserved.
  4454. Redistribution and use in source and binary forms, with or without
  4455. modification, are permitted provided that the following conditions are met:
  4456. * Redistributions of source code must retain the above copyright
  4457. notice, this list of conditions and the following disclaimer.
  4458. * Redistributions in binary form must reproduce the above copyright
  4459. notice, this list of conditions and the following disclaimer in the
  4460. documentation and/or other materials provided with the distribution.
  4461. * Neither the name of GLGE nor the
  4462. names of its contributors may be used to endorse or promote products
  4463. derived from this software without specific prior written permission.
  4464. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  4465. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  4466. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  4467. DISCLAIMED. IN NO EVENT SHALL PAUL BRUNT BE LIABLE FOR ANY
  4468. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  4469. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  4470. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  4471. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  4472. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  4473. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  4474. */
  4475. /**
  4476. * @fileOverview
  4477. * @name glge_animationvector.js
  4478. * @author me@paulbrunt.co.uk
  4479. */
  4480. (function(GLGE){
  4481. /**
  4482. * @class The AnimationVectors class allows you to specify the 2D Animation curves that define specific channels of animation within the engine.
  4483. * @augments GLGE.QuickNotation
  4484. * @augments GLGE.JSONLoader
  4485. */
  4486. GLGE.AnimationVector=function(uid){
  4487. this.curves={};
  4488. GLGE.Assets.registerAsset(this,uid);
  4489. }
  4490. GLGE.augment(GLGE.QuickNotation,GLGE.AnimationVector);
  4491. GLGE.augment(GLGE.JSONLoader,GLGE.AnimationVector);
  4492. GLGE.AnimationVector.prototype.curves={};
  4493. GLGE.AnimationVector.prototype.frames=250;
  4494. GLGE.AnimationVector.prototype.startFrame=0;
  4495. /**
  4496. * Adds an Animation Curve to a channel
  4497. * @param {String} channel The name of the curve to be added
  4498. * @param {GLGE.AnimationCurve} curve The animation curve to add
  4499. */
  4500. GLGE.AnimationVector.prototype.addAnimationCurve=function(curve){
  4501. this.curves[curve.channel]=curve;
  4502. return this;
  4503. }
  4504. /**
  4505. * Removes an Animation Curve form a channel
  4506. * @param {String} channel The name of the curve to be removed
  4507. */
  4508. GLGE.AnimationVector.prototype.removeAnimationCurve=function(name){
  4509. delete(this.curves[name]);
  4510. }
  4511. /**
  4512. * Sets the number of frames in the animation
  4513. * @param {number} value The number of frames in the animation
  4514. */
  4515. GLGE.AnimationVector.prototype.setFrames=function(value){
  4516. this.frames=value;
  4517. return this;
  4518. }
  4519. /**
  4520. * Sets the number of frames in the animation
  4521. * @returns {number} The number of frames in the animation
  4522. */
  4523. GLGE.AnimationVector.prototype.getFrames=function(){
  4524. return this.frames;
  4525. }
  4526. /**
  4527. * Sets the start frame
  4528. * @param {number} value The starting frame for the animation
  4529. */
  4530. GLGE.AnimationVector.prototype.setStartFrame=function(value){
  4531. this.startFrame=value;
  4532. return this;
  4533. }
  4534. /**
  4535. * Gets the start fames
  4536. * @returns {number} The starting frame for the animation
  4537. */
  4538. GLGE.AnimationVector.prototype.getStartFrame=function(){
  4539. return this.startFrame;
  4540. }
  4541. })(GLGE);
  4542. /*
  4543. GLGE WebGL Graphics Engine
  4544. Copyright (c) 2010, Paul Brunt
  4545. All rights reserved.
  4546. Redistribution and use in source and binary forms, with or without
  4547. modification, are permitted provided that the following conditions are met:
  4548. * Redistributions of source code must retain the above copyright
  4549. notice, this list of conditions and the following disclaimer.
  4550. * Redistributions in binary form must reproduce the above copyright
  4551. notice, this list of conditions and the following disclaimer in the
  4552. documentation and/or other materials provided with the distribution.
  4553. * Neither the name of GLGE nor the
  4554. names of its contributors may be used to endorse or promote products
  4555. derived from this software without specific prior written permission.
  4556. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  4557. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  4558. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  4559. DISCLAIMED. IN NO EVENT SHALL PAUL BRUNT BE LIABLE FOR ANY
  4560. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  4561. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  4562. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  4563. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  4564. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  4565. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  4566. */
  4567. /**
  4568. * @fileOverview
  4569. * @name glge_animationpoints.js
  4570. * @author me@paulbrunt.co.uk
  4571. */
  4572. (function(GLGE){
  4573. /**
  4574. * @class A bezier class to add points to the Animation Curve
  4575. * @param {string} uid a unique string to identify this object
  4576. * @augments GLGE.QuickNotation
  4577. * @augments GLGE.JSONLoader
  4578. */
  4579. GLGE.BezTriple=function(uid){
  4580. GLGE.Assets.registerAsset(this,uid);
  4581. };
  4582. GLGE.augment(GLGE.QuickNotation,GLGE.BezTriple);
  4583. GLGE.augment(GLGE.JSONLoader,GLGE.BezTriple);
  4584. GLGE.BezTriple.prototype.className="BezTriple";
  4585. /**
  4586. * set the x1-coord
  4587. * @param {number} x x1-coord control point
  4588. */
  4589. GLGE.BezTriple.prototype.setX1=function(x){
  4590. this.x1=parseFloat(x);
  4591. return this;
  4592. };
  4593. /**
  4594. * set the y1-coord
  4595. * @param {number} y y1-coord control point
  4596. */
  4597. GLGE.BezTriple.prototype.setY1=function(y){
  4598. this.y1=parseFloat(y);
  4599. return this;
  4600. };
  4601. /**
  4602. * set the x2-coord
  4603. * @param {number} x x2-coord control point
  4604. */
  4605. GLGE.BezTriple.prototype.setX2=function(x){
  4606. this.x=parseFloat(x);
  4607. return this;
  4608. };
  4609. /**
  4610. * set the y2-coord
  4611. * @param {number} y y2-coord control point
  4612. */
  4613. GLGE.BezTriple.prototype.setY2=function(y){
  4614. this.y=parseFloat(y);
  4615. return this;
  4616. };
  4617. /**
  4618. * set the x3-coord
  4619. * @param {number} x x3-coord control point
  4620. */
  4621. GLGE.BezTriple.prototype.setX3=function(x){
  4622. this.x3=parseFloat(x);
  4623. return this;
  4624. };
  4625. /**
  4626. * set the y3-coord
  4627. * @param {number} y y3-coord control point
  4628. */
  4629. GLGE.BezTriple.prototype.setY3=function(y){
  4630. this.y3=parseFloat(y);
  4631. return this;
  4632. };
  4633. /**
  4634. * @class A LinearPoint class to add points to the Animation Curve
  4635. * @param {string} uid unique string for this class
  4636. * @augments GLGE.QuickNotation
  4637. * @augments GLGE.JSONLoader
  4638. */
  4639. GLGE.LinearPoint=function(uid){
  4640. //GLGE.Assets.registerAsset(this,uid);
  4641. };
  4642. GLGE.augment(GLGE.QuickNotation,GLGE.LinearPoint);
  4643. GLGE.augment(GLGE.JSONLoader,GLGE.LinearPoint);
  4644. GLGE.LinearPoint.prototype.className="LinearPoint";
  4645. GLGE.LinearPoint.prototype.x=0;
  4646. GLGE.LinearPoint.prototype.y=0;
  4647. /**
  4648. * set the x-coord
  4649. * @param {number} x x-coord control point
  4650. */
  4651. GLGE.LinearPoint.prototype.setX=function(x){
  4652. this.x=parseFloat(x);
  4653. return this;
  4654. };
  4655. /**
  4656. * set the y-coord
  4657. * @param {number} y y-coord control point
  4658. */
  4659. GLGE.LinearPoint.prototype.setY=function(y){
  4660. this.y=parseFloat(y);
  4661. return this;
  4662. };
  4663. /**
  4664. * @class A StepPoint class to add points to the Animation Curve
  4665. * @param {number} x x-coord control point
  4666. * @param {object} value value of control point
  4667. */
  4668. GLGE.StepPoint=function(x,value){
  4669. this.x=parseFloat(x);
  4670. this.y=value;
  4671. };
  4672. })(GLGE);
  4673. /*
  4674. GLGE WebGL Graphics Engine
  4675. Copyright (c) 2010, Paul Brunt
  4676. All rights reserved.
  4677. Redistribution and use in source and binary forms, with or without
  4678. modification, are permitted provided that the following conditions are met:
  4679. * Redistributions of source code must retain the above copyright
  4680. notice, this list of conditions and the following disclaimer.
  4681. * Redistributions in binary form must reproduce the above copyright
  4682. notice, this list of conditions and the following disclaimer in the
  4683. documentation and/or other materials provided with the distribution.
  4684. * Neither the name of GLGE nor the
  4685. names of its contributors may be used to endorse or promote products
  4686. derived from this software without specific prior written permission.
  4687. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  4688. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  4689. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  4690. DISCLAIMED. IN NO EVENT SHALL PAUL BRUNT BE LIABLE FOR ANY
  4691. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  4692. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  4693. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  4694. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  4695. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  4696. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  4697. */
  4698. /**
  4699. * @fileOverview
  4700. * @name glge_mesh.js
  4701. * @author me@paulbrunt.co.uk
  4702. */
  4703. (function(GLGE){
  4704. var meshIndx = 0;
  4705. /**
  4706. * @class Creates a new mesh
  4707. * @see GLGE.Object
  4708. * @augments GLGE.QuickNotation
  4709. * @augments GLGE.JSONLoader
  4710. * @augments GLGE.Events
  4711. */
  4712. GLGE.Mesh=function(uid,windingOrder){
  4713. this.GLbuffers=[];
  4714. this.buffers=[];
  4715. this.framePositions=[];
  4716. this.frameNormals=[];
  4717. this.frameTangents=[];
  4718. this.UV=[];
  4719. this.boneWeights=[];
  4720. this.setBuffers=[];
  4721. this.faces={};
  4722. this.name = "mesh"+ (++meshIndx);
  4723. if (windingOrder!==undefined)
  4724. this.windingOrder=windingOrder;
  4725. else
  4726. this.windingOrder=GLGE.Mesh.WINDING_ORDER_UNKNOWN;
  4727. GLGE.Assets.registerAsset(this,uid);
  4728. };
  4729. GLGE.Mesh.WINDING_ORDER_UNKNOWN=2;
  4730. GLGE.Mesh.WINDING_ORDER_CLOCKWISE=1;
  4731. GLGE.Mesh.WINDING_ORDER_COUNTER=0;
  4732. GLGE.augment(GLGE.QuickNotation,GLGE.Mesh);
  4733. GLGE.augment(GLGE.JSONLoader,GLGE.Mesh);
  4734. GLGE.augment(GLGE.Events,GLGE.Mesh);
  4735. GLGE.Mesh.prototype.gl=null;
  4736. GLGE.Mesh.prototype.className="Mesh";
  4737. GLGE.Mesh.prototype.GLbuffers=null;
  4738. GLGE.Mesh.prototype.buffers=null;
  4739. GLGE.Mesh.prototype.setBuffers=null;
  4740. GLGE.Mesh.prototype.GLfaces=null;
  4741. GLGE.Mesh.prototype.faces=null;
  4742. GLGE.Mesh.prototype.UV=null;
  4743. GLGE.Mesh.prototype.joints=null;
  4744. GLGE.Mesh.prototype.invBind=null;
  4745. GLGE.Mesh.prototype.loaded=false;
  4746. /**
  4747. * @name GLGE.Mesh#shaderupdate
  4748. * @event fired when the shader needs updating
  4749. * @param {object} data
  4750. */
  4751. /**
  4752. * Gets the bounding volume for the mesh
  4753. * @returns {GLGE.BoundingVolume}
  4754. */
  4755. GLGE.Mesh.prototype.getBoundingVolume=function(){
  4756. if(!this.positions) return new GLGE.BoundingVolume(0,0,0,0,0,0);
  4757. if(!this.boundingVolume){
  4758. var minX,maxX,minY,maxY,minZ,maxZ;
  4759. var positions=this.positions;
  4760. for(var i=0;i<positions.length;i=i+3){
  4761. if(i==0){
  4762. minX=maxX=positions[i];
  4763. minY=maxY=positions[i+1];
  4764. minZ=maxZ=positions[i+2];
  4765. }else{
  4766. minX=Math.min(minX,positions[i]);
  4767. maxX=Math.max(maxX,positions[i]);
  4768. minY=Math.min(minY,positions[i+1]);
  4769. maxY=Math.max(maxY,positions[i+1]);
  4770. minZ=Math.min(minZ,positions[i+2]);
  4771. maxZ=Math.max(maxZ,positions[i+2]);
  4772. }
  4773. }
  4774. this.boundingVolume=new GLGE.BoundingVolume(minX,maxX,minY,maxY,minZ,maxZ);
  4775. }
  4776. return this.boundingVolume;
  4777. }
  4778. /**
  4779. * Sets the joints
  4780. * @param {string[]} jsArray set joint objects
  4781. */
  4782. GLGE.Mesh.prototype.setJoints=function(jsArray){
  4783. this.joints=jsArray;
  4784. this.fireEvent("shaderupdate",{});
  4785. return this;
  4786. }
  4787. /**
  4788. * Sets the inverse bind matrix for each joint
  4789. * @param {GLGE.Matrix[]} jsArray set joint names
  4790. */
  4791. GLGE.Mesh.prototype.setInvBindMatrix=function(jsArray){
  4792. this.invBind=jsArray;
  4793. this.fireEvent("shaderupdate",{});
  4794. return this;
  4795. }
  4796. /**
  4797. * Sets the joint channels for each vertex
  4798. * @param {Number[]} jsArray The 1 dimentional array of bones
  4799. * @param {Number} num the number of chanels in this mesh
  4800. */
  4801. GLGE.Mesh.prototype.setVertexJoints=function(jsArray,num){
  4802. if(!num){
  4803. num=jsArray.length*3/this.positions.length;
  4804. }
  4805. if(num<5){
  4806. this.setBuffer("joints1",jsArray,num);
  4807. }else{
  4808. var jsArray1=[];
  4809. var jsArray2=[];
  4810. for(var i=0;i<jsArray.length;i++){
  4811. if(i%num<4){
  4812. jsArray1.push(jsArray[i]);
  4813. }else{
  4814. jsArray2.push(jsArray[i]);
  4815. }
  4816. }
  4817. this.setBuffer("joints1",jsArray1,4);
  4818. this.setBuffer("joints2",jsArray2,num-4);
  4819. }
  4820. this.fireEvent("shaderupdate",{});
  4821. return this;
  4822. }
  4823. /**
  4824. * Sets the joint weights on each vertex
  4825. * @param {Number[]} jsArray The 1 dimentional array of weights
  4826. * @param {Number} num the number of chanels in this mesh
  4827. */
  4828. GLGE.Mesh.prototype.setVertexWeights=function(jsArray,num){
  4829. if(!num){
  4830. num=jsArray.length*3/this.positions.length;
  4831. }
  4832. //normalize the weights!
  4833. for(var i=0;i<jsArray.length;i=i+parseInt(num)){
  4834. var total=0;
  4835. for(var n=0;n<num;n++){
  4836. total+=parseFloat(jsArray[i+n]);
  4837. }
  4838. if(total==0) total=1;
  4839. for(var n=0;n<num;n++){
  4840. jsArray[i+n]=jsArray[i+n]/total;
  4841. }
  4842. }
  4843. if(num<4){
  4844. this.setBuffer("weights1",jsArray,num);
  4845. }else{
  4846. var jsArray1=[];
  4847. var jsArray2=[];
  4848. for(var i=0;i<jsArray.length;i++){
  4849. if(i%num<4){
  4850. jsArray1.push(jsArray[i]);
  4851. }else{
  4852. jsArray2.push(jsArray[i]);
  4853. }
  4854. }
  4855. this.setBuffer("weights1",jsArray1,4);
  4856. this.setBuffer("weights2",jsArray2,num-4);
  4857. }
  4858. this.fireEvent("shaderupdate",{});
  4859. return this;
  4860. }
  4861. /**
  4862. * clears any buffers currently set
  4863. * @param {Number[]} jsArray the UV coords in a 1 dimentional array
  4864. */
  4865. GLGE.Mesh.prototype.clearBuffers=function(){
  4866. //if(this.GLfaces) this.gl.deleteBuffer(this.GLfaces);
  4867. this.GLFaces=null;
  4868. delete(this.GLFaces);
  4869. for(var i in this.buffers){
  4870. //if(this.buffers[i].GL) this.gl.deleteBuffer(this.buffers[i].GL);
  4871. this.buffers[i]=null;
  4872. delete(this.buffers[i]);
  4873. }
  4874. this.buffers=[];
  4875. this.loaded=false;
  4876. }
  4877. /**
  4878. * Set the UV coord for the first UV layer
  4879. * @param {Number[]} jsArray the UV coords in a 1 dimentional array
  4880. */
  4881. GLGE.Mesh.prototype.setUV=function(jsArray){
  4882. this.uv1set=jsArray;
  4883. var idx=0;
  4884. for(var i=0; i<jsArray.length;i=i+2){
  4885. this.UV[idx]=jsArray[i];
  4886. this.UV[idx+1]=jsArray[i+1];
  4887. if(!this.UV[idx+2]) this.UV[idx+2]=jsArray[i];//<-- hack in case the collada file only specified UV1 but accesses UV2 and expects the UV1 coordinates to be properly reflected there
  4888. if(!this.UV[idx+3]) this.UV[idx+3]=jsArray[i+1];
  4889. idx=idx+4;
  4890. }
  4891. this.setBuffer("UV",this.UV,4);
  4892. return this;
  4893. }
  4894. /**
  4895. * Set the UV coord for the second UV layer
  4896. * @param {Number[]} jsArray the UV coords in a 1 dimentional array
  4897. */
  4898. GLGE.Mesh.prototype.setUV2=function(jsArray){
  4899. this.uv2set=jsArray;
  4900. var idx=0;
  4901. for(var i=0; i<jsArray.length;i=i+2){
  4902. if(!this.UV[idx]) this.UV[idx]=jsArray[i];
  4903. if(!this.UV[idx+1]) this.UV[idx+1]=jsArray[i+1];
  4904. this.UV[idx+2]=jsArray[i];
  4905. this.UV[idx+3]=jsArray[i+1];
  4906. idx=idx+4;
  4907. }
  4908. this.setBuffer("UV",this.UV,4);
  4909. return this;
  4910. }
  4911. /**
  4912. * Sets the positions of the verticies
  4913. * @param {Number[]} jsArray The 1 dimentional array of positions
  4914. * @param {number} frame optional mesh frame number
  4915. */
  4916. GLGE.Mesh.prototype.setPositions=function(jsArray,frame){
  4917. if(!frame) frame=0;
  4918. this.loaded=true;
  4919. if(frame==0) this.positions=jsArray;
  4920. this.framePositions[frame]=jsArray;
  4921. this.setBuffer("position"+frame,jsArray,3,true);
  4922. this.boundingVolume=null;
  4923. this.fireEvent("updatebound");
  4924. return this;
  4925. }
  4926. /**
  4927. * Sets the colors of the verticies
  4928. * @param {Number[]} jsArray The vertex colors
  4929. */
  4930. GLGE.Mesh.prototype.setVertexColors=function(jsArray){
  4931. this.colors=jsArray;
  4932. this.setBuffer("color",jsArray,4);
  4933. return this;
  4934. }
  4935. /**
  4936. * Sets the normals of the verticies
  4937. * @param {Number[]} jsArray The 1 dimentional array of normals
  4938. * @param {number} frame optional mesh frame number
  4939. */
  4940. GLGE.Mesh.prototype.setNormals=function(jsArray,frame){
  4941. if(!frame) frame=0;
  4942. if(frame==0) this.normals=jsArray;
  4943. this.frameNormals[frame]=jsArray;
  4944. this.setBuffer("normal"+frame,jsArray,3,true);
  4945. return this;
  4946. }
  4947. /**
  4948. * Sets the tangents of the verticies
  4949. * @param {Number[]} jsArray The 1 dimentional array of tangents
  4950. * @param {number} frame optional mesh frame number
  4951. */
  4952. GLGE.Mesh.prototype.setTangents=function(jsArray,frame){
  4953. if(!frame) frame=0;
  4954. if(frame==0) this.tangents=jsArray;
  4955. this.frameTangents[frame]=jsArray;
  4956. this.setBuffer("tangent"+frame,jsArray,3,true);
  4957. return this;
  4958. }
  4959. /**
  4960. * Sets a buffer for the
  4961. * @param {String} boneName The name of the bone
  4962. * @param {Number[]} jsArray The 1 dimentional array of weights
  4963. * @private
  4964. */
  4965. GLGE.Mesh.prototype.setBuffer=function(bufferName,jsArray,size,exclude){
  4966. //make sure all jsarray items are floats
  4967. if(typeof jsArray[0] !="number") for(var i=0;i<jsArray.length;i++) jsArray[i]=parseFloat(jsArray[i]);
  4968. var buffer;
  4969. for(var i=0;i<this.buffers.length;i++){
  4970. if(this.buffers[i].name==bufferName) buffer=i;
  4971. }
  4972. if(!buffer){
  4973. this.buffers.push({name:bufferName,data:jsArray,size:size,GL:false,exclude:exclude});
  4974. }
  4975. else
  4976. {
  4977. this.buffers[buffer]={name:bufferName,data:jsArray,size:size,GL:false,exclude:exclude};
  4978. }
  4979. return this;
  4980. }
  4981. /**
  4982. * gets a vert tangent
  4983. * @private
  4984. */
  4985. GLGE.Mesh.prototype.tangentFromUV=function(p1,p2,p3,uv1,uv2,uv3,n){
  4986. var toUnitVec3=GLGE.toUnitVec3;
  4987. var subVec3=GLGE.subVec3;
  4988. var scaleVec3=GLGE.scaleVec3;
  4989. var dotVec3=GLGE.dotVec3;
  4990. var crossVec3=GLGE.crossVec3;
  4991. uv21=[uv2[0]-uv1[0],uv2[1]-uv1[1]];
  4992. uv31=[uv3[0]-uv1[0],uv3[1]-uv1[1]];
  4993. p21=GLGE.subVec3(p2,p1);
  4994. p31=GLGE.subVec3(p3,p1);
  4995. var s=(uv21[0]*uv31[1]-uv31[0]*uv21[1]);
  4996. if(s!=0){
  4997. s=1/s;
  4998. var t=subVec3(scaleVec3(p21,uv31[1]*s),scaleVec3(p31,uv21[1]*s));
  4999. var b=subVec3(scaleVec3(p31,uv21[0]*s),scaleVec3(p21,uv31[0]*s));
  5000. }else{
  5001. t=[0,0,0];
  5002. b=[0,0,0];
  5003. }
  5004. if(GLGE.dotVec3(GLGE.crossVec3(p21,p31),n)>0){
  5005. t=scaleVec3(t,-1);
  5006. b=scaleVec3(b,-1);
  5007. }
  5008. return [t,b];
  5009. }
  5010. /**
  5011. * Sets the faces for this mesh
  5012. * @param {Number[]} jsArray The 1 dimentional array of normals
  5013. */
  5014. GLGE.Mesh.prototype.setFaces=function(jsArray){
  5015. this.faces={data:jsArray,GL:false};
  5016. //if at this point calculate normals if we haven't got them yet
  5017. if(!this.normals) this.calcNormals();
  5018. if(!this.tangents && this.UV.length>0) this.calcTangents();
  5019. return this;
  5020. }
  5021. /**
  5022. * Calculates the tangents for this mesh - this is messy FIX ME!
  5023. * @private
  5024. */
  5025. GLGE.Mesh.prototype.calcTangents=function(){
  5026. for(var j=0;j<this.framePositions.length;j++){
  5027. var position=this.framePositions[j];
  5028. var normal=this.frameNormals[j];
  5029. var uv=this.UV;
  5030. var tangentArray=[];
  5031. var data={};
  5032. var ref;
  5033. for(var i=0;i<position.length;i++){
  5034. tangentArray[i]=0;
  5035. }
  5036. for(var i=0;i<this.faces.data.length;i=i+3){
  5037. var p1=[position[(parseInt(this.faces.data[i]))*3],position[(parseInt(this.faces.data[i]))*3+1],position[(parseInt(this.faces.data[i]))*3+2]];
  5038. var p2=[position[(parseInt(this.faces.data[i+1]))*3],position[(parseInt(this.faces.data[i+1]))*3+1],position[(parseInt(this.faces.data[i+1]))*3+2]];
  5039. var p3=[position[(parseInt(this.faces.data[i+2]))*3],position[(parseInt(this.faces.data[i+2]))*3+1],position[(parseInt(this.faces.data[i+2]))*3+2]];
  5040. var n1=[normal[(parseInt(this.faces.data[i]))*3],normal[(parseInt(this.faces.data[i]))*3+1],normal[(parseInt(this.faces.data[i]))*3+2]];
  5041. var n2=[normal[(parseInt(this.faces.data[i+1]))*3],normal[(parseInt(this.faces.data[i+1]))*3+1],normal[(parseInt(this.faces.data[i+1]))*3+2]];
  5042. var n3=[normal[(parseInt(this.faces.data[i+2]))*3],normal[(parseInt(this.faces.data[i+2]))*3+1],normal[(parseInt(this.faces.data[i+2]))*3+2]];
  5043. var uv1=[uv[(parseInt(this.faces.data[i]))*4],uv[(parseInt(this.faces.data[i]))*4+1]];
  5044. var uv2=[uv[(parseInt(this.faces.data[i+1]))*4],uv[(parseInt(this.faces.data[i+1]))*4+1]];
  5045. var uv3=[uv[(parseInt(this.faces.data[i+2]))*4],uv[(parseInt(this.faces.data[i+2]))*4+1]];
  5046. var tb=this.tangentFromUV(p2,p1,p3,uv2,uv1,uv3,n2);
  5047. if(!data[[p1[0],p1[1],p1[2],uv1[0],uv1[1],n1[0],n1[1],n1[2]].join(",")]){
  5048. data[[p1[0],p1[1],p1[2],uv1[0],uv1[1],n1[0],n1[1],n1[2]].join(",")]=tb;
  5049. }else{
  5050. data[[p1[0],p1[1],p1[2],uv1[0],uv1[1],n1[0],n1[1],n1[2]].join(",")][0][0]+=tb[0][0];
  5051. data[[p1[0],p1[1],p1[2],uv1[0],uv1[1],n1[0],n1[1],n1[2]].join(",")][0][1]+=tb[0][1];
  5052. data[[p1[0],p1[1],p1[2],uv1[0],uv1[1],n1[0],n1[1],n1[2]].join(",")][0][2]+=tb[0][2];
  5053. data[[p1[0],p1[1],p1[2],uv1[0],uv1[1],n1[0],n1[1],n1[2]].join(",")][1][0]+=tb[1][0];
  5054. data[[p1[0],p1[1],p1[2],uv1[0],uv1[1],n1[0],n1[1],n1[2]].join(",")][1][1]+=tb[1][1];
  5055. data[[p1[0],p1[1],p1[2],uv1[0],uv1[1],n1[0],n1[1],n1[2]].join(",")][1][2]+=tb[1][2];
  5056. }
  5057. if(!data[[p2[0],p2[1],p2[2],uv2[0],uv2[1],n2[0],n2[1],n2[2]].join(",")]){
  5058. data[[p2[0],p2[1],p2[2],uv2[0],uv2[1],n2[0],n2[1],n2[2]].join(",")]=tb;
  5059. }else{
  5060. data[[p2[0],p2[1],p2[2],uv2[0],uv2[1],n2[0],n2[1],n2[2]].join(",")][0][0]+=tb[0][0];
  5061. data[[p2[0],p2[1],p2[2],uv2[0],uv2[1],n2[0],n2[1],n2[2]].join(",")][0][1]+=tb[0][1];
  5062. data[[p2[0],p2[1],p2[2],uv2[0],uv2[1],n2[0],n2[1],n2[2]].join(",")][0][2]+=tb[0][2];
  5063. data[[p2[0],p2[1],p2[2],uv2[0],uv2[1],n2[0],n2[1],n2[2]].join(",")][1][0]+=tb[1][0];
  5064. data[[p2[0],p2[1],p2[2],uv2[0],uv2[1],n2[0],n2[1],n2[2]].join(",")][1][1]+=tb[1][1];
  5065. data[[p2[0],p2[1],p2[2],uv2[0],uv2[1],n2[0],n2[1],n2[2]].join(",")][1][2]+=tb[1][2];
  5066. }
  5067. if(!data[[p3[0],p3[1],p3[2],uv3[0],uv3[1],n3[0],n3[1],n3[2]].join(",")]){
  5068. data[[p3[0],p3[1],p3[2],uv3[0],uv3[1],n3[0],n3[1],n3[2]].join(",")]=tb;
  5069. }else{
  5070. data[[p3[0],p3[1],p3[2],uv3[0],uv3[1],n3[0],n3[1],n3[2]].join(",")][0][0]+=tb[0][0];
  5071. data[[p3[0],p3[1],p3[2],uv3[0],uv3[1],n3[0],n3[1],n3[2]].join(",")][0][1]+=tb[0][1];
  5072. data[[p3[0],p3[1],p3[2],uv3[0],uv3[1],n3[0],n3[1],n3[2]].join(",")][0][2]+=tb[0][2];
  5073. data[[p3[0],p3[1],p3[2],uv3[0],uv3[1],n3[0],n3[1],n3[2]].join(",")][1][0]+=tb[1][0];
  5074. data[[p3[0],p3[1],p3[2],uv3[0],uv3[1],n3[0],n3[1],n3[2]].join(",")][1][1]+=tb[1][1];
  5075. data[[p3[0],p3[1],p3[2],uv3[0],uv3[1],n3[0],n3[1],n3[2]].join(",")][1][2]+=tb[1][2];
  5076. }
  5077. }
  5078. for(var i=0;i<position.length/3;i++){
  5079. var p1=[position[i*3],position[i*3+1],position[i*3+2]];
  5080. var n1=[normal[i*3],normal[i*3+1],normal[i*3+2]];
  5081. var uv1=[uv[i*4],uv[i*4+1]];
  5082. try{
  5083. var t=GLGE.toUnitVec3(data[[p1[0],p1[1],p1[2],uv1[0],uv1[1],n1[0],n1[1],n1[2]].join(",")][0]);
  5084. var b=GLGE.toUnitVec3(data[[p1[0],p1[1],p1[2],uv1[0],uv1[1],n1[0],n1[1],n1[2]].join(",")][1]);
  5085. }catch(e){
  5086. //if we fail probably a exporter bug carry on anyway
  5087. }
  5088. if(t){
  5089. tangentArray[i*3]=t[0];
  5090. tangentArray[i*3+1]=t[1];
  5091. tangentArray[i*3+2]=t[2];
  5092. }
  5093. }
  5094. this.setTangents(tangentArray,j);
  5095. }
  5096. }
  5097. /**
  5098. * Sets the faces for this mesh
  5099. * @param {Number[]} jsArray The 1 dimentional array of normals
  5100. * @private
  5101. */
  5102. GLGE.Mesh.prototype.GLSetFaceBuffer=function(gl){
  5103. if(!this.GLfaces) this.GLfaces = gl.createBuffer();
  5104. gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.GLfaces);
  5105. gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(this.faces.data), gl.STATIC_DRAW);
  5106. this.GLfaces.itemSize = 1;
  5107. this.GLfaces.numItems = this.faces.data.length;
  5108. }
  5109. /**
  5110. * Sets up a GL Buffer
  5111. * @param {WebGLContext} gl The context being drawn on
  5112. * @param {String} bufferName The name of the buffer to create
  5113. * @param {Number[]} jsArray The data to add to the buffer
  5114. * @param {Number} size Size of a single element within the array
  5115. * @private
  5116. */
  5117. GLGE.Mesh.prototype.GLSetBuffer=function(gl,bufferName,jsArray,size){
  5118. if(!this.GLbuffers[bufferName]) this.GLbuffers[bufferName] = gl.createBuffer();
  5119. gl.bindBuffer(gl.ARRAY_BUFFER, this.GLbuffers[bufferName]);
  5120. if(!jsArray.byteLength) jsArray=new Float32Array(jsArray);
  5121. gl.bufferData(gl.ARRAY_BUFFER, jsArray, gl.STATIC_DRAW);
  5122. this.GLbuffers[bufferName].itemSize = size;
  5123. this.GLbuffers[bufferName].numItems = jsArray.length/size;
  5124. };
  5125. /**
  5126. * Calculates the normals for this mesh
  5127. * @private
  5128. */
  5129. GLGE.Mesh.prototype.calcNormals=function(){
  5130. for(var n=0;n<this.framePositions.length;n++){
  5131. var normals=[];
  5132. var positions=this.framePositions[n];
  5133. var faces=this.faces.data;
  5134. if(!faces){
  5135. faces=[];
  5136. for(var i=0;i<positions.length/3;i++) faces[i]=i;
  5137. }
  5138. for(var i=0;i<faces.length;i=i+3){
  5139. var v1=[positions[faces[i]*3],positions[faces[i]*3+1],positions[faces[i]*3+2]];
  5140. var v2=[positions[faces[i+1]*3],positions[faces[i+1]*3+1],positions[faces[i+1]*3+2]];
  5141. var v3=[positions[faces[i+2]*3],positions[faces[i+2]*3+1],positions[faces[i+2]*3+2]];
  5142. var vec1=GLGE.subVec3(v2,v1);
  5143. var vec2=GLGE.subVec3(v3,v1);
  5144. var norm=GLGE.toUnitVec3(GLGE.crossVec3(vec1,vec2));
  5145. if(normals[faces[i]]==undefined) normals[faces[i]]=[];
  5146. normals[faces[i]].push(norm);
  5147. if(normals[faces[i+1]]==undefined) normals[faces[i+1]]=[];
  5148. normals[faces[i+1]].push(norm);
  5149. if(normals[faces[i+2]]==undefined) normals[faces[i+2]]=[];
  5150. normals[faces[i+2]].push(norm);
  5151. }
  5152. var norms=[];
  5153. for(i=0;i<normals.length;i++){
  5154. var x=0,y=0,z=0;
  5155. if(normals[i]!=undefined){
  5156. for(var j=0;j<normals[i].length;j++){
  5157. x+=normals[i][j][0];
  5158. y+=normals[i][j][1];
  5159. z+=normals[i][j][2];
  5160. }
  5161. x/=normals[i].length;
  5162. y/=normals[i].length;
  5163. z/=normals[i].length;
  5164. norms[i*3]=x;
  5165. norms[i*3+1]=y;
  5166. norms[i*3+2]=z;
  5167. }
  5168. }
  5169. this.setNormals(norms,n);
  5170. }
  5171. }
  5172. /**
  5173. * Calculates a ambient occlution effect and sets the vertex color with AO level
  5174. */
  5175. GLGE.Mesh.prototype.calcFauxAO=function(){
  5176. this.optimize();
  5177. //calculate ambient color based on vertex angles
  5178. var verts=this.positions;
  5179. var faces=this.faces.data;
  5180. var normals=this.normals;
  5181. var idx=[];
  5182. var len=verts.length/3
  5183. for(var i=0;i<len;i++){
  5184. idx.push([]);
  5185. }
  5186. for(var i=0;i<faces.length;i=i+3){
  5187. idx[faces[i]].push(faces[i+1]);
  5188. idx[faces[i]].push(faces[i+2]);
  5189. idx[faces[i+1]].push(faces[i]);
  5190. idx[faces[i+1]].push(faces[i+2]);
  5191. idx[faces[i+2]].push(faces[i]);
  5192. idx[faces[i+2]].push(faces[i+1]);
  5193. }
  5194. var ao=[];
  5195. for(var i=0;i<len;i++){
  5196. var AOfactor=0;
  5197. var normal=[normals[i*3],normals[i*3+1],normals[i*3+2]];
  5198. for(var j=0;j<idx[i].length;j++){
  5199. var f=idx[i][j];
  5200. var v=[verts[f*3]-verts[i*3],verts[f*3+1]-verts[i*3+1],verts[f*3+2]-verts[i*3+2]];
  5201. v=GLGE.toUnitVec3(v);
  5202. AOfactor+=v[0]*normal[0]+v[1]*normal[1]+v[2]*normal[2];
  5203. }
  5204. AOfactor/=idx[i].length;
  5205. AOfactor=1.0-(AOfactor+1)*0.5;
  5206. ao.push(AOfactor);
  5207. ao.push(AOfactor);
  5208. ao.push(AOfactor);
  5209. ao.push(1);
  5210. }
  5211. this.setVertexColors(ao);
  5212. }
  5213. /**
  5214. * optimize geometry
  5215. * @private
  5216. */
  5217. GLGE.Mesh.prototype.optimize=function(){
  5218. var verts=this.positions;
  5219. var normals=this.normals;
  5220. var faces=this.faces.data;
  5221. var tangents=this.tangents;
  5222. var uv1=this.uv1set;
  5223. var uv2=this.uv2set;
  5224. //expand out the faces
  5225. var vertsTemp=[];
  5226. var normalsTemp=[];
  5227. var uv1Temp=[];
  5228. var uv2Temp=[];
  5229. var tangentsTemp=[];
  5230. if(faces){
  5231. for(var i=0;i<faces.length;i++){
  5232. vertsTemp.push(verts[faces[i]*3]);
  5233. vertsTemp.push(verts[faces[i]*3+1]);
  5234. vertsTemp.push(verts[faces[i]*3+2]);
  5235. normalsTemp.push(normals[faces[i]*3]);
  5236. normalsTemp.push(normals[faces[i]*3+1]);
  5237. normalsTemp.push(normals[faces[i]*3+2]);
  5238. if(tangents && tangents.length>0){
  5239. tangentsTemp.push(tangents[faces[i]*3]);
  5240. tangentsTemp.push(tangents[faces[i]*3+1]);
  5241. tangentsTemp.push(tangents[faces[i]*3+2]);
  5242. }
  5243. if(uv1){
  5244. uv1Temp.push(uv1[faces[i]*2]);
  5245. uv1Temp.push(uv1[faces[i]*2+1]);
  5246. }
  5247. if(uv2){
  5248. uv2Temp.push(uv2[faces[i]*2]);
  5249. uv2Temp.push(uv2[faces[i]*2+1]);
  5250. }
  5251. }
  5252. }else{
  5253. vertsTemp=verts;
  5254. normalsTemp=normals;
  5255. tangentsTemp=tangents;
  5256. uv1Temp=uv1;
  5257. uv2Temp=uv2;
  5258. }
  5259. var newVerts=[];
  5260. var newNormals=[];
  5261. var newFaces=[];
  5262. var newUV1s=[];
  5263. var newUV2s=[];
  5264. var newTangents=[];
  5265. var stack=[];
  5266. for(var i=0;i<vertsTemp.length;i=i+3){
  5267. if(uv1 && uv2){
  5268. var idx=[vertsTemp[i],vertsTemp[i+1],vertsTemp[i+2],normalsTemp[i],normalsTemp[i+1],normalsTemp[i+2],uv1Temp[i/3*2],uv1Temp[i/3*2+1]].join(" ");
  5269. }else if(uv1){
  5270. var idx=[vertsTemp[i],vertsTemp[i+1],vertsTemp[i+2],normalsTemp[i],normalsTemp[i+1],normalsTemp[i+2],uv1Temp[i/3*2],uv1Temp[i/3*2+1]].join(" ");
  5271. }else{
  5272. var idx=[vertsTemp[i],vertsTemp[i+1],vertsTemp[i+2],normalsTemp[i],normalsTemp[i+1],normalsTemp[i+2]].join(" ");
  5273. }
  5274. var vertIdx=stack.indexOf(idx);
  5275. if(vertIdx<0){
  5276. stack.push(idx);
  5277. vertIdx=stack.length-1;
  5278. newVerts.push(vertsTemp[i]);
  5279. newVerts.push(vertsTemp[i+1]);
  5280. newVerts.push(vertsTemp[i+2]);
  5281. newNormals.push(normalsTemp[i]);
  5282. newNormals.push(normalsTemp[i+1]);
  5283. newNormals.push(normalsTemp[i+2]);
  5284. if(tangents && tangents.length>0){
  5285. newTangents.push(tangentsTemp[i]);
  5286. newTangents.push(tangentsTemp[i+1]);
  5287. newTangents.push(tangentsTemp[i+2]);
  5288. }
  5289. if(uv1){
  5290. newUV1s.push(uv1Temp[i/3*2]);
  5291. newUV1s.push(uv1Temp[i/3*2+1]);
  5292. }
  5293. if(uv2){
  5294. newUV2s.push(uv2Temp[i/3*2]);
  5295. newUV2s.push(uv2Temp[i/3*2+1]);
  5296. }
  5297. }
  5298. newFaces.push(vertIdx);
  5299. }
  5300. this.setPositions(newVerts).setNormals(newNormals).setFaces(newFaces).setUV(newUV1s).setUV2(newUV2s).setTangents(newTangents);
  5301. }
  5302. /**
  5303. * Sets the Attributes for this mesh
  5304. * @param {WebGLContext} gl The context being drawn on
  5305. * @private
  5306. */
  5307. GLGE.Mesh.prototype.GLAttributes=function(gl,shaderProgram,frame1, frame2){
  5308. this.gl=gl;
  5309. if(!frame1) frame1=0;
  5310. //if at this point we have no normals set then calculate them
  5311. if(!this.normals) this.calcNormals();
  5312. //disable all the attribute initially arrays - do I really need this?
  5313. for(var i=0; i<8; i++) gl.disableVertexAttribArray(i);
  5314. //check if the faces have been updated
  5315. if(!this.faces.GL && this.faces.data && this.faces.data.length>0){
  5316. this.GLSetFaceBuffer(gl);
  5317. this.faces.GL=true;
  5318. }
  5319. //loop though the buffers
  5320. for(i=0; i<this.buffers.length;i++){
  5321. if(!this.buffers[i].GL){
  5322. this.GLSetBuffer(gl,this.buffers[i].name,this.buffers[i].data,this.buffers[i].size);
  5323. this.buffers[i].GL=true;
  5324. }
  5325. attribslot=GLGE.getAttribLocation(gl,shaderProgram, this.buffers[i].name);
  5326. if(attribslot>-1){
  5327. gl.bindBuffer(gl.ARRAY_BUFFER, this.GLbuffers[this.buffers[i].name]);
  5328. gl.enableVertexAttribArray(attribslot);
  5329. gl.vertexAttribPointer(attribslot, this.GLbuffers[this.buffers[i].name].itemSize, gl.FLOAT, false, 0, 0);
  5330. }
  5331. }
  5332. //do the position normal and if we have tangent then tangent
  5333. var positionSlot=GLGE.getAttribLocation(gl,shaderProgram, "position");
  5334. if(positionSlot>-1){
  5335. gl.bindBuffer(gl.ARRAY_BUFFER, this.GLbuffers["position"+frame1]);
  5336. gl.enableVertexAttribArray(positionSlot);
  5337. gl.vertexAttribPointer(positionSlot, this.GLbuffers["position"+frame1].itemSize, gl.FLOAT, false, 0, 0);
  5338. }
  5339. var normalSlot=GLGE.getAttribLocation(gl,shaderProgram, "normal");
  5340. if(normalSlot>-1){
  5341. gl.bindBuffer(gl.ARRAY_BUFFER, this.GLbuffers["normal"+frame1]);
  5342. gl.enableVertexAttribArray(normalSlot);
  5343. gl.vertexAttribPointer(normalSlot, this.GLbuffers["normal"+frame1].itemSize, gl.FLOAT, false, 0, 0);
  5344. }
  5345. var tangentSlot=GLGE.getAttribLocation(gl,shaderProgram, "tangent");
  5346. if(tangentSlot>-1){
  5347. gl.bindBuffer(gl.ARRAY_BUFFER, this.GLbuffers["tangent"+frame1]);
  5348. gl.enableVertexAttribArray(tangentSlot);
  5349. gl.vertexAttribPointer(tangentSlot, this.GLbuffers["tangent"+frame1].itemSize, gl.FLOAT, false, 0, 0);
  5350. }
  5351. if(frame2!=undefined){
  5352. var positionSlot2=GLGE.getAttribLocation(gl,shaderProgram, "position2");
  5353. if(positionSlot2>-1){
  5354. gl.bindBuffer(gl.ARRAY_BUFFER, this.GLbuffers["position"+frame2]);
  5355. gl.enableVertexAttribArray(positionSlot2);
  5356. gl.vertexAttribPointer(positionSlot2, this.GLbuffers["position"+frame2].itemSize, gl.FLOAT, false, 0, 0);
  5357. }
  5358. var normalSlot2=GLGE.getAttribLocation(gl,shaderProgram, "normal2");
  5359. if(normalSlot2>-1){
  5360. gl.bindBuffer(gl.ARRAY_BUFFER, this.GLbuffers["normal"+frame2]);
  5361. gl.enableVertexAttribArray(normalSlot2);
  5362. gl.vertexAttribPointer(normalSlot2, this.GLbuffers["normal"+frame2].itemSize, gl.FLOAT, false, 0, 0);
  5363. }
  5364. var tangentSlot2=GLGE.getAttribLocation(gl,shaderProgram, "tangent2");
  5365. if(tangentSlot2>-1){
  5366. gl.bindBuffer(gl.ARRAY_BUFFER, this.GLbuffers["tangent"+frame2]);
  5367. gl.enableVertexAttribArray(tangentSlot2);
  5368. gl.vertexAttribPointer(tangentSlot2, this.GLbuffers["tangent"+frame2].itemSize, gl.FLOAT, false, 0, 0);
  5369. }
  5370. }
  5371. }
  5372. })(GLGE);/*
  5373. GLGE WebGL Graphics Engine
  5374. Copyright (c) 2011, Paul Brunt
  5375. All rights reserved.
  5376. Redistribution and use in source and binary forms, with or without
  5377. modification, are permitted provided that the following conditions are met:
  5378. * Redistributions of source code must retain the above copyright
  5379. notice, this list of conditions and the following disclaimer.
  5380. * Redistributions in binary form must reproduce the above copyright
  5381. notice, this list of conditions and the following disclaimer in the
  5382. documentation and/or other materials provided with the distribution.
  5383. * Neither the name of GLGE nor the
  5384. names of its contributors may be used to endorse or promote products
  5385. derived from this software without specific prior written permission.
  5386. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  5387. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  5388. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  5389. DISCLAIMED. IN NO EVENT SHALL PAUL BRUNT BE LIABLE FOR ANY
  5390. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  5391. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  5392. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  5393. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  5394. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  5395. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  5396. */
  5397. /**
  5398. * @fileOverview
  5399. * @name glge_sphere.js
  5400. * @author me@paulbrunt.co.uk
  5401. */
  5402. (function(GLGE){
  5403. /**
  5404. * @class Used to generate a basic sphere mesh
  5405. * @augments GLGE.Mesh
  5406. */
  5407. GLGE.Sphere=function(uid){
  5408. this.vertical=10;
  5409. this.horizontal=10;
  5410. this.radius=1;
  5411. this.dirtySphere=false;
  5412. GLGE.Mesh.apply(this,arguments);
  5413. this.generateMeshData();
  5414. }
  5415. GLGE.augment(GLGE.Mesh,GLGE.Sphere);
  5416. /**
  5417. * @private
  5418. */
  5419. GLGE.Sphere.prototype.generateMeshData=function(){
  5420. var vertical=this.vertical;
  5421. var horizontal=this.horizontal;
  5422. var radius=this.radius;
  5423. var t1,y,r1,i,j,x,y,t2;
  5424. var verts=[];
  5425. var normals=[];
  5426. var faces=[];
  5427. for(i=0;i<=vertical;i++){
  5428. t1=i/vertical*Math.PI;
  5429. y=Math.cos(t1)*radius;
  5430. r1=Math.sin(t1)*radius;
  5431. for(j=0;j<horizontal;j++){
  5432. t2=j/horizontal*2*Math.PI;
  5433. x=Math.sin(t2)*r1;
  5434. z=Math.cos(t2)*r1;
  5435. verts.push(x,y,z);
  5436. var n=GLGE.toUnitVec3([x,y,z]);
  5437. normals.push(n[0],n[1],n[2]);
  5438. }
  5439. if(i>0){
  5440. for(j=0;j<horizontal;j++){
  5441. var v1=i*horizontal+j;
  5442. var v2=(i-1)*horizontal+j;
  5443. var v3=i*horizontal+(j+1)%horizontal;
  5444. var v4=(i-1)*horizontal+(j+1)%horizontal;
  5445. faces.push(v1,v3,v4,v1,v4,v2)
  5446. }
  5447. }
  5448. }
  5449. this.setPositions(verts);
  5450. this.setNormals(normals);
  5451. this.setFaces(faces);
  5452. this.dirtySphere=false;
  5453. }
  5454. /**
  5455. * Sets the sphere radius
  5456. * @param {number} radius the sphere radius
  5457. */
  5458. GLGE.Sphere.prototype.setRadius=function(radius){
  5459. this.radius=radius;
  5460. this.dirtySphere=true;
  5461. return this;
  5462. }
  5463. /**
  5464. * Gets the sphere radius
  5465. * @returns the radius
  5466. */
  5467. GLGE.Sphere.prototype.getRadius=function(){
  5468. return this.radius;
  5469. }
  5470. /**
  5471. * Sets the sphere vertical divisions
  5472. * @param {number} radius the sphere radius
  5473. */
  5474. GLGE.Sphere.prototype.setVertical=function(vertical){
  5475. this.vertical=vertical;
  5476. this.dirtySphere=true;
  5477. return this;
  5478. }
  5479. /**
  5480. * Gets the sphere vertical divisions
  5481. * @returns the radius
  5482. */
  5483. GLGE.Sphere.prototype.getRadius=function(){
  5484. return this.vertical;
  5485. }
  5486. /**
  5487. * Sets the sphere horizontal divisions
  5488. * @param {number} radius the sphere radius
  5489. */
  5490. GLGE.Sphere.prototype.setHorizontal=function(horizontal){
  5491. this.horizontal=horizontal;
  5492. this.dirtySphere=true;
  5493. return this;
  5494. }
  5495. /**
  5496. * Gets the sphere horizontal divisions
  5497. * @returns the radius
  5498. */
  5499. GLGE.Sphere.prototype.getRadius=function(){
  5500. return this.horizontal;
  5501. }
  5502. /**
  5503. * @private
  5504. */
  5505. GLGE.Sphere.prototype.GLAttributes=function(){
  5506. if(this.dirtySphere) this.generateMeshData();
  5507. GLGE.Mesh.prototype.GLAttributes.apply(this,arguments);
  5508. };
  5509. })(GLGE);/*
  5510. GLGE WebGL Graphics Engine
  5511. Copyright (c) 2010, Paul Brunt
  5512. All rights reserved.
  5513. Redistribution and use in source and binary forms, with or without
  5514. modification, are permitted provided that the following conditions are met:
  5515. * Redistributions of source code must retain the above copyright
  5516. notice, this list of conditions and the following disclaimer.
  5517. * Redistributions in binary form must reproduce the above copyright
  5518. notice, this list of conditions and the following disclaimer in the
  5519. documentation and/or other materials provided with the distribution.
  5520. * Neither the name of GLGE nor the
  5521. names of its contributors may be used to endorse or promote products
  5522. derived from this software without specific prior written permission.
  5523. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  5524. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  5525. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  5526. DISCLAIMED. IN NO EVENT SHALL PAUL BRUNT BE LIABLE FOR ANY
  5527. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  5528. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  5529. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  5530. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  5531. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  5532. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  5533. */
  5534. /**
  5535. * @fileOverview
  5536. * @name glge_material.js
  5537. * @author me@paulbrunt.co.uk
  5538. */
  5539. (function(GLGE){
  5540. var materialIdx=0;
  5541. /**
  5542. * @class The Material class creates materials to be applied to objects in the graphics engine
  5543. * @see GLGE.Object
  5544. * @augments GLGE.Animatable
  5545. * @augments GLGE.QuickNotation
  5546. * @augments GLGE.JSONLoader
  5547. * @augments GLGE.Events
  5548. */
  5549. GLGE.Material=function(uid){
  5550. this.layers=[];
  5551. this.layerlisteners=[];
  5552. this.textures=[];
  5553. this.lights=[];
  5554. this.color={r:1,g:1,b:1,a:1};
  5555. this.specColor={r:1,g:1,b:1};
  5556. this.reflect=0.8;
  5557. this.shine=10;
  5558. this.specular=1;
  5559. this.emit={r:0,g:0,b:0};
  5560. this.alpha=1;
  5561. this.materialIdx=materialIdx++;
  5562. GLGE.Assets.registerAsset(this,uid);
  5563. };
  5564. GLGE.augment(GLGE.Animatable,GLGE.Material);
  5565. GLGE.augment(GLGE.QuickNotation,GLGE.Material);
  5566. GLGE.augment(GLGE.JSONLoader,GLGE.Material);
  5567. GLGE.augment(GLGE.Events,GLGE.Material);
  5568. /**
  5569. * @name GLGE.Material#shaderupdate
  5570. * @event fires when the shader for this material needs updating
  5571. * @param {object} data
  5572. */
  5573. /**
  5574. * @name GLGE.Material#downloadComplete
  5575. * @event fires when all the assets for this material have finished loading
  5576. * @param {object} data
  5577. */
  5578. /**
  5579. * @constant
  5580. * @description Flag for material colour
  5581. */
  5582. GLGE.M_COLOR=1;
  5583. /**
  5584. * @constant
  5585. * @description Flag for material normal
  5586. */
  5587. GLGE.M_NOR=2;
  5588. /**
  5589. * @constant
  5590. * @description Flag for material alpha
  5591. */
  5592. GLGE.M_ALPHA=4;
  5593. /**
  5594. * @constant
  5595. * @description Flag for material specular color
  5596. */
  5597. GLGE.M_SPECCOLOR=8;
  5598. /**
  5599. * @constant
  5600. * @description Flag for material specular cvalue
  5601. */
  5602. GLGE.M_SPECULAR=16;
  5603. /**
  5604. * @constant
  5605. * @description Flag for material shineiness
  5606. */
  5607. GLGE.M_SHINE=32;
  5608. /**
  5609. * @constant
  5610. * @description Flag for material reflectivity
  5611. */
  5612. GLGE.M_REFLECT=64;
  5613. /**
  5614. * @constant
  5615. * @description Flag for material emision
  5616. */
  5617. GLGE.M_EMIT=128;
  5618. /**
  5619. * @constant
  5620. * @description Flag for material alpha
  5621. */
  5622. GLGE.M_ALPHA=256;
  5623. /**
  5624. * @constant
  5625. * @description Flag for masking with textures red value
  5626. */
  5627. GLGE.M_MSKR=512;
  5628. /**
  5629. * @constant
  5630. * @description Flag for masking with textures green value
  5631. */
  5632. GLGE.M_MSKG=1024;
  5633. /**
  5634. * @constant
  5635. * @description Flag for masking with textures blue value
  5636. */
  5637. GLGE.M_MSKB=2048;
  5638. /**
  5639. * @constant
  5640. * @description Flag for masking with textures alpha value
  5641. */
  5642. GLGE.M_MSKA=4096;
  5643. /**
  5644. * @constant
  5645. * @description Flag for mapping of the height in parallax mapping
  5646. */
  5647. GLGE.M_HEIGHT=8192;
  5648. /**
  5649. * @constant
  5650. * @description Flag for ambient mapping
  5651. */
  5652. GLGE.M_AMBIENT=16384;
  5653. /**
  5654. * @constant
  5655. * @description Flag for Steep parallax mapng
  5656. */
  5657. GLGE.M_STEEP=32768;
  5658. /**
  5659. * @constant
  5660. * @description Enumeration for first UV layer
  5661. */
  5662. GLGE.UV1=0;
  5663. /**
  5664. * @constant
  5665. * @description Enumeration for second UV layer
  5666. */
  5667. GLGE.UV2=1;
  5668. /**
  5669. * @constant
  5670. * @description Enumeration for normal texture coords
  5671. */
  5672. GLGE.MAP_NORM=3;
  5673. /**
  5674. * @constant
  5675. * @description Enumeration for object texture coords
  5676. */
  5677. GLGE.MAP_OBJ=4;
  5678. /**
  5679. * @constant
  5680. * @description Enumeration for reflection coords
  5681. */
  5682. GLGE.MAP_REF=5;
  5683. /**
  5684. * @constant
  5685. * @description Enumeration for environment coords
  5686. */
  5687. GLGE.MAP_ENV=6;
  5688. /**
  5689. * @constant
  5690. * @description Enumeration for view coords
  5691. */
  5692. GLGE.MAP_VIEW=7;
  5693. /**
  5694. * @constant
  5695. * @description Enumeration for point coords
  5696. */
  5697. GLGE.MAP_POINT=8;
  5698. /**
  5699. * @constant
  5700. * @description Enumeration for mix blending mode
  5701. */
  5702. GLGE.BL_MIX=0;
  5703. /**
  5704. * @constant
  5705. * @description Enumeration for mix blending mode
  5706. */
  5707. GLGE.BL_MUL=1;
  5708. /**
  5709. * @constant
  5710. * @description Enumeration for no use of vertex color
  5711. */
  5712. GLGE.VC_NONE=0;
  5713. /**
  5714. * @constant
  5715. * @description Enumeration for base vertex color mode
  5716. */
  5717. GLGE.VC_BASE=1;
  5718. /**
  5719. * @constant
  5720. * @description Enumeration for muliply vertex color mode
  5721. */
  5722. GLGE.VC_MUL=2;
  5723. /**
  5724. * @constant
  5725. * @description Enumeration for vertex color sets ambient lighting
  5726. */
  5727. GLGE.VC_AMB=3;
  5728. /**
  5729. * @constant
  5730. * @description Enumeration for vertex color multiplied by ambient lighting
  5731. */
  5732. GLGE.VC_AMBMUL=4;
  5733. GLGE.Material.prototype.layers=null;
  5734. GLGE.Material.prototype.className="Material";
  5735. GLGE.Material.prototype.textures=null;
  5736. GLGE.Material.prototype.color=null;
  5737. GLGE.Material.prototype.specColor=null;
  5738. GLGE.Material.prototype.specular=null;
  5739. GLGE.Material.prototype.emit={r:0,g:0,b:0};
  5740. GLGE.Material.prototype.shine=null;
  5741. GLGE.Material.prototype.reflect=null;
  5742. GLGE.Material.prototype.lights=null;
  5743. GLGE.Material.prototype.alpha=null;
  5744. GLGE.Material.prototype.ambient={r:0,g:0,b:0};
  5745. GLGE.Material.prototype.shadow=true;
  5746. GLGE.Material.prototype.shadeless=false;
  5747. GLGE.Material.prototype.downloadComplete=false;
  5748. GLGE.Material.prototype.vertexColorMode=GLGE.VC_BASE;
  5749. /**
  5750. * Sets the vertex color mode. Default is to override the base color VC_MUL will multiply the vertex color with the resulting color
  5751. * @param {boolean} value The vertex color mode
  5752. */
  5753. GLGE.Material.prototype.setVertexColorMode=function(value){
  5754. this.vertexColorMode=value;
  5755. this.fireEvent("shaderupdate",{});
  5756. return this;
  5757. };
  5758. /**
  5759. * Gets the vertex color mode
  5760. * @returns {boolean} The vertex color mode
  5761. */
  5762. GLGE.Material.prototype.getVertexColorMode=function(value){
  5763. return this.vertexColorMode;
  5764. };
  5765. /**
  5766. * Sets the fall back material the material will be used if this one fails to produce a program
  5767. * @param {boolean} value The fallback material
  5768. */
  5769. GLGE.Material.prototype.setFallback=function(value){
  5770. this.fallback=value;
  5771. return this;
  5772. };
  5773. /**
  5774. * Gets the fallback material, if program fails then the fallback will be used
  5775. * @returns {boolean} The fallback material
  5776. */
  5777. GLGE.Material.prototype.getFallback=function(value){
  5778. return this.fallback;
  5779. };
  5780. /**
  5781. * Sets the flag indicateing if the material is shadeless
  5782. * @param {boolean} value The shadeless flag
  5783. */
  5784. GLGE.Material.prototype.setShadeless=function(value){
  5785. this.shadeless=value;
  5786. return this;
  5787. };
  5788. /**
  5789. * Gets the shadeless flag
  5790. * @returns {boolean} The shadeless flag
  5791. */
  5792. GLGE.Material.prototype.getShadeless=function(value){
  5793. return this.shadeless;
  5794. };
  5795. /**
  5796. * Sets the flag indicateing the material should or shouldn't recieve shadows
  5797. * @param {boolean} value The recieving shadow flag
  5798. */
  5799. GLGE.Material.prototype.setShadow=function(value){
  5800. this.shadow=value;
  5801. return this;
  5802. };
  5803. /**
  5804. * gets the show flag
  5805. * @returns {boolean} The shadow flag
  5806. */
  5807. GLGE.Material.prototype.getShadow=function(value){
  5808. return this.shadow;
  5809. };
  5810. /**
  5811. * Sets the base colour of the material
  5812. * @param {string} color The colour of the material
  5813. */
  5814. GLGE.Material.prototype.setColor=function(color){
  5815. if(!color.r){
  5816. color=GLGE.colorParse(color);
  5817. }
  5818. this.color={r:color.r,g:color.g,b:color.b};
  5819. //this.fireEvent("shaderupdate",{});
  5820. return this;
  5821. };
  5822. /**
  5823. * Sets the red base colour of the material
  5824. * @param {Number} r The new red level 0-1
  5825. */
  5826. GLGE.Material.prototype.setColorR=function(value){
  5827. this.color={r:value,g:this.color.g,b:this.color.b,a:this.color.a};
  5828. return this;
  5829. };
  5830. /**
  5831. * Sets the green base colour of the material
  5832. * @param {Number} g The new green level 0-1
  5833. */
  5834. GLGE.Material.prototype.setColorG=function(value){
  5835. this.color={r:this.color.r,g:value,b:this.color.b,a:this.color.a};
  5836. return this;
  5837. };
  5838. /**
  5839. * Sets the blue base colour of the material
  5840. * @param {Number} b The new blue level 0-1
  5841. */
  5842. GLGE.Material.prototype.setColorB=function(value){
  5843. this.color={r:this.color.r,g:this.color.g,b:value,a:this.color.a};
  5844. return this;
  5845. };
  5846. /**
  5847. * Gets the red base colour of the material
  5848. * @returns The red level 0-1
  5849. */
  5850. GLGE.Material.prototype.getColorR=function(value){
  5851. return this.color.r;
  5852. };
  5853. /**
  5854. * Gets the green base colour of the material
  5855. * @returns The green level 0-1
  5856. */
  5857. GLGE.Material.prototype.getColorG=function(value){
  5858. return this.color.g;
  5859. };
  5860. /**
  5861. * Gets the blue base colour of the material
  5862. * @returns The blue level 0-1
  5863. */
  5864. GLGE.Material.prototype.getColorB=function(value){
  5865. return this.color.b;
  5866. };
  5867. /**
  5868. * Gets the current base color of the material
  5869. * @return {[r,g,b]} The current base color
  5870. */
  5871. GLGE.Material.prototype.getColor=function(){
  5872. return this.color;
  5873. };
  5874. /**
  5875. * Sets the base specular colour of the material
  5876. * @param {string} color The new specular colour
  5877. */
  5878. GLGE.Material.prototype.setSpecularColor=function(color){
  5879. if(!color.r){
  5880. color=GLGE.colorParse(color);
  5881. }
  5882. this.specColor={r:parseFloat(color.r),g:parseFloat(color.g),b:parseFloat(color.b)};
  5883. this.fireEvent("shaderupdate",{});
  5884. return this;
  5885. };
  5886. /**
  5887. * Gets the ambient lighting of the material
  5888. * @return {[r,g,b]} The current ambient lighting
  5889. */
  5890. GLGE.Material.prototype.getAmbient=function(){
  5891. return this.ambient;
  5892. };
  5893. /**
  5894. * Sets the ambient lighting of the material
  5895. * @param {string} color The new specular colour
  5896. */
  5897. GLGE.Material.prototype.setAmbient=function(color){
  5898. if(!color.r){
  5899. color=GLGE.colorParse(color);
  5900. }
  5901. this.ambient={r:parseFloat(color.r),g:parseFloat(color.g),b:parseFloat(color.b)};
  5902. this.fireEvent("shaderupdate",{});
  5903. return this;
  5904. };
  5905. /**
  5906. * Gets the current base specular color of the material
  5907. * @return {[r,g,b]} The current base specular color
  5908. */
  5909. GLGE.Material.prototype.getSpecularColor=function(){
  5910. return this.specColor;
  5911. };
  5912. /**
  5913. * Sets the alpha of the material
  5914. * @param {Number} value how much alpha
  5915. */
  5916. GLGE.Material.prototype.setAlpha=function(value){
  5917. this.alpha=value;
  5918. return this;
  5919. };
  5920. /**
  5921. * Gets the alpha of the material
  5922. * @return {Number} The current alpha of the material
  5923. */
  5924. GLGE.Material.prototype.getAlpha=function(){
  5925. return this.alpha;
  5926. };
  5927. /**
  5928. * Sets the specular of the material
  5929. * @param {Number} value how much specular
  5930. */
  5931. GLGE.Material.prototype.setSpecular=function(value){
  5932. this.specular=value;
  5933. this.fireEvent("shaderupdate",{});
  5934. return this;
  5935. };
  5936. /**
  5937. * Gets the specular of the material
  5938. * @return {Number} The current specular of the material
  5939. */
  5940. GLGE.Material.prototype.getSpecular=function(){
  5941. return this.specular;
  5942. };
  5943. /**
  5944. * Sets the shininess of the material
  5945. * @param {Number} value how much shine
  5946. */
  5947. GLGE.Material.prototype.setShininess=function(value){
  5948. if (value<=0) value=0.001;
  5949. this.shine=value;
  5950. this.fireEvent("shaderupdate",{});
  5951. return this;
  5952. };
  5953. /**
  5954. * Gets the shininess of the material
  5955. * @return {Number} The current shininess of the material
  5956. */
  5957. GLGE.Material.prototype.getShininess=function(){
  5958. return this.shine;
  5959. };
  5960. /**
  5961. * Sets how much the material should emit
  5962. * @param {Number} color what color to emit
  5963. */
  5964. GLGE.Material.prototype.setEmit=function(color){
  5965. if(color>0) color={r:color,g:color,b:color};
  5966. if(!color.r){
  5967. color=GLGE.colorParse(color);
  5968. }
  5969. this.emit={r:parseFloat(color.r),g:parseFloat(color.g),b:parseFloat(color.b)};
  5970. this.fireEvent("shaderupdate",{});
  5971. return this;
  5972. };
  5973. /**
  5974. * Sets how much the Red material should emit
  5975. * @param {Number} value what Red to emit
  5976. */
  5977. GLGE.Material.prototype.setEmitR=function(value){
  5978. this.emit.r=parseFloat(value);
  5979. return this;
  5980. };
  5981. /**
  5982. * Sets how much the green material should emit
  5983. * @param {Number} value what green to emit
  5984. */
  5985. GLGE.Material.prototype.setEmitG=function(value){
  5986. this.emit.g=parseFloat(value);
  5987. return this;
  5988. };
  5989. /**
  5990. * Sets how much the blue material should emit
  5991. * @param {Number} value what blue to emit
  5992. */
  5993. GLGE.Material.prototype.setEmitB=function(value){
  5994. this.emit.b=parseFloat(value);
  5995. return this;
  5996. };
  5997. /**
  5998. * Sets how much the Red material should emit
  5999. * @returns Red to emit
  6000. */
  6001. GLGE.Material.prototype.getEmitR=function(value){
  6002. return this.emit.r;
  6003. };
  6004. /**
  6005. * Sets how much the green material should emit
  6006. * @returns green to emit
  6007. */
  6008. GLGE.Material.prototype.getEmitG=function(value){
  6009. return this.emit.g;
  6010. };
  6011. /**
  6012. * Sets how much the blue material should emit
  6013. * @returns blue to emit
  6014. */
  6015. GLGE.Material.prototype.getEmitB=function(value){
  6016. return this.emit.b;
  6017. };
  6018. /**
  6019. * Gets the amount this material emits
  6020. * @return {Number} The emit value for the material
  6021. */
  6022. GLGE.Material.prototype.getEmit=function(){
  6023. return this.emit;
  6024. };
  6025. /**
  6026. * Sets reflectivity of the material
  6027. * @param {Number} value how much to reflect (0-1)
  6028. */
  6029. GLGE.Material.prototype.setReflectivity=function(value){
  6030. this.reflect=value;
  6031. this.fireEvent("shaderupdate",{});
  6032. return this;
  6033. };
  6034. /**
  6035. * Gets the materials reflectivity
  6036. * @return {Number} The reflectivity of the material
  6037. */
  6038. GLGE.Material.prototype.getReflectivity=function(){
  6039. return this.reflect;
  6040. };
  6041. /**
  6042. * Sets the material to output with 0 alpha or 1 alpha
  6043. * @param {boolean} value binary alpha flag
  6044. */
  6045. GLGE.Material.prototype.setBinaryAlpha=function(value){
  6046. this.binaryAlpha=value;
  6047. this.fireEvent("shaderupdate",{});
  6048. return this;
  6049. };
  6050. /**
  6051. * Gets the binary alpha flag
  6052. * @return {boolean} The binary alpha flag
  6053. */
  6054. GLGE.Material.prototype.getBinaryAlpha=function(){
  6055. return this.binaryAlpha;
  6056. };
  6057. /**
  6058. * Add a new layer to the material
  6059. * @param {MaterialLayer} layer The material layer to add to the material
  6060. */
  6061. GLGE.Material.prototype.addMaterialLayer=function(layer){
  6062. if(typeof layer=="string") layer=GLGE.Assets.get(layer);
  6063. this.layers.push(layer);
  6064. var material=this;
  6065. var listener=function(event){
  6066. material.fireEvent("shaderupdate",{});
  6067. };
  6068. this.layerlisteners.push(listener);
  6069. layer.addEventListener("shaderupdate",listener);
  6070. this.fireEvent("shaderupdate",{});
  6071. return this;
  6072. };
  6073. /**
  6074. * Removes a layer from the material
  6075. * @param {MaterialLayer} layer The material layer to remove
  6076. */
  6077. GLGE.Material.prototype.removeMaterialLayer=function(layer){
  6078. var idx=this.layers.indexOf(layer);
  6079. if(idx>=0){
  6080. this.layers.splice(idx,1);
  6081. layer.removeEventListener("shaderupdate",this.layerlisteners[idx]);
  6082. this.layerlisteners.splice(idx,1);
  6083. this.fireEvent("shaderupdate",{});
  6084. }
  6085. return this;
  6086. };
  6087. /**
  6088. * Gets all the materials layers
  6089. * @returns {GLGE.MaterialLayer[]} all of the layers contained within this material
  6090. */
  6091. GLGE.Material.prototype.getLayers=function(){
  6092. return this.layers;
  6093. };
  6094. /**
  6095. * Generate the code required to calculate the texture coords for each layer
  6096. * @private
  6097. */
  6098. GLGE.Material.prototype.getLayerCoords=function(shaderInjection){
  6099. var shader=[];
  6100. shader.push("vec4 texturePos;\n");
  6101. for(var i=0; i<this.layers.length;i++){
  6102. shader.push("textureCoords"+i+"=vec3(0.0,0.0,0.0);\n");
  6103. if(this.layers[i].mapinput==GLGE.UV1 || this.layers[i].mapinput==GLGE.UV2){
  6104. shader.push("texturePos=vec4(vec2(UVCoord["+(this.layers[i].mapinput*2)+"],(1.0-UVCoord["+(this.layers[i].mapinput*2+1)+"])),1.0,1.0);\n");
  6105. }
  6106. if(this.layers[i].mapinput==GLGE.MAP_NORM){
  6107. shader.push("texturePos=vec4(normalize(n.xyz),1.0);\n");
  6108. }
  6109. if(this.layers[i].mapinput==GLGE.MAP_OBJ){
  6110. shader.push("texturePos=vec4(normalize(OBJCoord.xyz),1.0);\n");
  6111. }
  6112. if(this.layers[i].mapinput==GLGE.MAP_REF){
  6113. //will need to do in fragment to take the normal maps into account!
  6114. shader.push("texturePos=vec4(reflect(normalize(eyevec.xyz),normalize(n.xyz)),1.0);\n");
  6115. }
  6116. if(this.layers[i].mapinput==GLGE.MAP_ENV){
  6117. //will need to do in fragment to take the normal maps into account!
  6118. shader.push("texturePos=envMat * vec4(reflect(normalize(eyevec.xyz),normalize(n.xyz)),1.0);\n");
  6119. }
  6120. shader.push("textureCoords"+i+"=(layer"+i+"Matrix * texturePos).xyz;\n");
  6121. if(shaderInjection && ~shaderInjection.indexOf("GLGE_Texcoord")){
  6122. shader.push("textureCoords"+i+"=GLGE_Texcoord("+i+",textureCoords"+i+");\n");
  6123. }
  6124. }
  6125. return shader.join("");
  6126. }
  6127. /**
  6128. * Generate the fragment shader program for this material
  6129. * @private
  6130. */
  6131. GLGE.Material.prototype.getVertexVarying=function(){
  6132. var shader=[];
  6133. for(var i=0; i<this.layers.length;i++){
  6134. shader.push("uniform mat4 layer"+i+"Matrix;\n");
  6135. shader.push("varying vec3 textureCoords"+i+";\n");
  6136. }
  6137. return shader.join("");
  6138. }
  6139. GLGE.Material.prototype.registerPasses=function(gl,object){
  6140. for(var i=0; i<this.textures.length;i++){
  6141. if(this.textures[i].registerPasses) this.textures[i].registerPasses(gl,object);
  6142. }
  6143. }
  6144. /**
  6145. * Generate the fragment shader program for this material
  6146. * @private
  6147. */
  6148. GLGE.Material.prototype.getFragmentShader=function(lights,colors,shaderInjection){
  6149. var shader="#ifdef GL_ES\nprecision mediump float;\n#endif\n#define GLGE_FRAGMENT\n";
  6150. if(shaderInjection) shader+=shaderInjection;
  6151. var tangent=false;
  6152. for(var i=0; i<lights.length;i++){
  6153. if(lights[i].type==GLGE.L_POINT || lights[i].type==GLGE.L_SPOT || lights[i].type==GLGE.L_DIR){
  6154. shader=shader+"varying vec3 lightvec"+i+";\n";
  6155. shader=shader+"varying float lightdist"+i+";\n";
  6156. }
  6157. }
  6158. shader=shader+"varying vec3 n;\n";
  6159. shader=shader+"varying vec3 t;\n";
  6160. shader=shader+"varying vec4 UVCoord;\n";
  6161. shader=shader+"varying vec3 eyevec;\n";
  6162. shader=shader+"varying vec3 OBJCoord;\n";
  6163. if(colors) shader=shader+"varying vec4 vcolor;\n";
  6164. shader=shader+"uniform sampler2D sky;\n";
  6165. //texture uniforms
  6166. for(var i=0; i<this.textures.length;i++){
  6167. if(this.textures[i].className=="Texture") shader=shader+"uniform sampler2D TEXTURE"+i+";\n";
  6168. if(this.textures[i].className=="TextureCanvas") shader=shader+"uniform sampler2D TEXTURE"+i+";\n";
  6169. if(this.textures[i].className=="TextureVideo") shader=shader+"uniform sampler2D TEXTURE"+i+";\n";
  6170. if(this.textures[i].className=="TextureCube") shader=shader+"uniform samplerCube TEXTURE"+i+";\n";
  6171. }
  6172. var cnt=1;
  6173. var shadowlights=[];
  6174. var num;
  6175. for(var i=0; i<lights.length;i++){
  6176. if(lights[i].type==GLGE.L_OFF) continue;
  6177. shader=shader+"uniform vec3 lightcolor"+i+";\n";
  6178. shader=shader+"uniform vec3 lightAttenuation"+i+";\n";
  6179. shader=shader+"uniform float spotCosCutOff"+i+";\n";
  6180. shader=shader+"uniform float spotExp"+i+";\n";
  6181. shader=shader+"uniform vec3 lightdir"+i+";\n";
  6182. shader=shader+"uniform mat4 lightmat"+i+";\n";
  6183. shader=shader+"uniform float shadowbias"+i+";\n";
  6184. shader=shader+"uniform int shadowsamples"+i+";\n";
  6185. shader=shader+"uniform float shadowsoftness"+i+";\n";
  6186. shader=shader+"uniform bool castshadows"+i+";\n";
  6187. shader=shader+"uniform vec2 shadowoffset"+i+";\n";
  6188. if(lights[i].getCastShadows() && this.shadow){
  6189. shader=shader+"varying vec4 spotcoord"+i+";\n";
  6190. num=this.textures.length+(cnt++);
  6191. shader=shader+"uniform sampler2D TEXTURE"+num+";\n";
  6192. shadowlights[i]=num;
  6193. }
  6194. }
  6195. for(i=0; i<this.layers.length;i++){
  6196. shader=shader+"varying vec3 textureCoords"+i+";\n";
  6197. shader=shader+"uniform float layeralpha"+i+";\n";
  6198. if(this.layers[i].mapinput==GLGE.MAP_VIEW){
  6199. shader=shader+"uniform mat4 layer"+i+"Matrix;\n";
  6200. }
  6201. if((this.layers[i].mapto & GLGE.M_HEIGHT) == GLGE.M_HEIGHT || (this.layers[i].mapto & GLGE.M_STEEP) == GLGE.M_STEEP){
  6202. shader=shader+"uniform float layerheight"+i+";\n";
  6203. }
  6204. }
  6205. shader=shader+"uniform vec4 baseColor;\n";
  6206. shader=shader+"uniform vec3 specColor;\n";
  6207. shader=shader+"uniform float shine;\n";
  6208. shader=shader+"uniform float specular;\n";
  6209. shader=shader+"uniform float reflective;\n";
  6210. shader=shader+"uniform vec3 emit;\n";
  6211. shader=shader+"uniform float alpha;\n";
  6212. shader=shader+"uniform vec3 amb;\n";
  6213. shader=shader+"uniform float fognear;\n";
  6214. shader=shader+"uniform float fogfar;\n";
  6215. shader=shader+"uniform int fogtype;\n";
  6216. shader=shader+"uniform vec3 fogcolor;\n";
  6217. shader=shader+"uniform float far;\n";
  6218. shader=shader+"uniform mat4 worldInverseTranspose;\n";
  6219. shader=shader+"uniform mat4 projection;\n";
  6220. shader=shader+"uniform bool emitpass;\n";
  6221. shader=shader+"uniform bool shadeless;\n";
  6222. shader=shader+"void main(void)\n";
  6223. shader=shader+"{\n";
  6224. shader=shader+"float att;\n";
  6225. shader=shader+"int texture;\n";
  6226. shader=shader+"float mask=1.0;\n";
  6227. shader=shader+"float spec=specular;\n";
  6228. shader=shader+"vec3 specC=specColor;\n";
  6229. shader=shader+"vec4 view;\n";
  6230. shader=shader+"vec3 textureCoords=vec3(0.0,0.0,0.0);\n";
  6231. shader=shader+"float ref=reflective;\n";
  6232. shader=shader+"float sh=shine;\n";
  6233. shader=shader+"vec3 em=emit;\n";
  6234. shader=shader+"float al=alpha;\n";
  6235. shader=shader+"vec3 amblight=vec3(1.0,1.0,1.0);\n";
  6236. shader=shader+"vec4 normalmap= vec4(n,0.0);\n"
  6237. if(colors && this.vertexColorMode==GLGE.VC_BASE){
  6238. shader=shader+"vec4 color= vcolor;";
  6239. shader=shader+"al = vcolor.a;";
  6240. }else{
  6241. shader=shader+"vec4 color = baseColor;"; //set the initial color
  6242. }
  6243. shader=shader+"float pheight=0.0;\n"
  6244. shader=shader+"vec3 textureHeight=vec3(0.0,0.0,0.0);\n";
  6245. shader=shader+"vec3 normal = normalize(n);\n";
  6246. shader=shader+"vec3 b = vec3(0.0,0.0,0.0);\n";
  6247. var diffuseLayer=0;
  6248. var anyAlpha=false;
  6249. for(i=0; i<this.layers.length;i++){
  6250. shader=shader+"textureCoords=textureCoords"+i+"+textureHeight;\n";
  6251. shader=shader+"mask=layeralpha"+i+"*mask;\n";
  6252. if(this.layers[i].mapinput==GLGE.MAP_VIEW){
  6253. shader=shader+"view=projection * vec4(-eyevec,1.0);\n";
  6254. shader=shader+"textureCoords=view.xyz/view.w*0.5+0.5;\n";
  6255. shader=shader+"textureCoords=(layer"+i+"Matrix*vec4(textureCoords,1.0)).xyz+textureHeight;\n";
  6256. }
  6257. if(this.layers[i].mapinput==GLGE.MAP_POINT){
  6258. shader=shader+"textureCoords=vec3(gl_PointCoord,1.0);\n";
  6259. }
  6260. if(this.layers[i].getTexture().className=="Texture" || this.layers[i].getTexture().className=="TextureCanvas" || this.layers[i].getTexture().className=="TextureVideo" ){
  6261. var txcoord="xy";
  6262. var sampletype="2D";
  6263. }else{
  6264. var txcoord="xyz";
  6265. var sampletype="Cube";
  6266. }
  6267. if((this.layers[i].mapto & GLGE.M_COLOR) == GLGE.M_COLOR){
  6268. diffuseLayer=i;
  6269. if(this.layers[i].blendMode==GLGE.BL_MUL){
  6270. shader=shader+"color = color*(1.0-mask) + color*texture"+sampletype+"(TEXTURE"+this.layers[i].texture.idx+", textureCoords."+txcoord+")*mask;\n";
  6271. }
  6272. else
  6273. {
  6274. shader=shader+"color = color*(1.0-mask) + texture"+sampletype+"(TEXTURE"+this.layers[i].texture.idx+", textureCoords."+txcoord+")*mask;\n";
  6275. }
  6276. }
  6277. if((this.layers[i].mapto & GLGE.M_HEIGHT) == GLGE.M_HEIGHT){
  6278. //do paralax stuff
  6279. shader=shader+"pheight = texture2D(TEXTURE"+this.layers[i].texture.idx+", textureCoords."+txcoord+").x;\n";
  6280. shader=shader+"textureHeight =vec3((layerheight"+i+"* (pheight-0.5) * normalize(eyevec).xy*vec2(1.0,-1.0)),0.0);\n";
  6281. }
  6282. if((this.layers[i].mapto & GLGE.M_STEEP) == GLGE.M_STEEP){
  6283. shader=shader+"b=normalize(cross(t.xyz,n));\n";
  6284. shader=shader+"vec3 neye=normalize(eyevec.xyz);"
  6285. shader=shader+"neye = vec3(dot(neye,t),dot(neye,b),dot(neye,n));";
  6286. shader=shader+"neye = normalize(neye);";
  6287. shader=shader+"float stepheight"+i+"=layerheight"+i+";";
  6288. shader=shader+"float steepstep"+i+"=(1.0/8.0)*stepheight"+i+"/neye.z;";
  6289. shader=shader+"float steepdisplace"+i+"=0.0;";
  6290. shader=shader+"for(int steepcount"+i+"=0;steepcount"+i+"<8;steepcount"+i+"++){";
  6291. shader=shader+"pheight = texture2D(TEXTURE"+this.layers[i].texture.idx+", textureCoords."+txcoord+"+vec2(neye.x,neye.y)*steepdisplace"+i+").x;\n";
  6292. shader=shader+"if(pheight*stepheight"+i+">neye.z*steepdisplace"+i+"){";
  6293. shader=shader+"textureHeight=vec3(vec2(neye.x,neye.y)*steepdisplace"+i+",0.0);";
  6294. shader=shader+"}else{";
  6295. shader=shader+"steepdisplace"+i+"-=steepstep"+i+";";
  6296. shader=shader+"steepstep"+i+"*=0.5;";
  6297. shader=shader+"}";
  6298. shader=shader+"steepdisplace"+i+"+=steepstep"+i+";";
  6299. shader=shader+"}";
  6300. }
  6301. if((this.layers[i].mapto & GLGE.M_SPECCOLOR) == GLGE.M_SPECCOLOR){
  6302. shader=shader+"specC = specC*(1.0-mask) + texture"+sampletype+"(TEXTURE"+this.layers[i].texture.idx+", textureCoords."+txcoord+").rgb*mask;\n";
  6303. }
  6304. if((this.layers[i].mapto & GLGE.M_MSKR) == GLGE.M_MSKR){
  6305. shader=shader+"mask = texture"+sampletype+"(TEXTURE"+this.layers[i].texture.idx+", textureCoords."+txcoord+").r;\n";
  6306. }
  6307. if((this.layers[i].mapto & GLGE.M_MSKG) == GLGE.M_MSKG){
  6308. shader=shader+"mask = texture"+sampletype+"(TEXTURE"+this.layers[i].texture.idx+", textureCoords."+txcoord+").g;\n";
  6309. }
  6310. if((this.layers[i].mapto & GLGE.M_MSKB) == GLGE.M_MSKB){
  6311. shader=shader+"mask = texture"+sampletype+"(TEXTURE"+this.layers[i].texture.idx+", textureCoords."+txcoord+").b;\n";
  6312. }
  6313. if((this.layers[i].mapto & GLGE.M_MSKA) == GLGE.M_MSKA){
  6314. shader=shader+"mask = texture"+sampletype+"(TEXTURE"+this.layers[i].texture.idx+", textureCoords."+txcoord+").a;\n";
  6315. }
  6316. if((this.layers[i].mapto & GLGE.M_SPECULAR) == GLGE.M_SPECULAR){
  6317. shader=shader+"spec = spec*(1.0-mask) + texture"+sampletype+"(TEXTURE"+this.layers[i].texture.idx+", textureCoords."+txcoord+").r*mask;\n";
  6318. }
  6319. if((this.layers[i].mapto & GLGE.M_REFLECT) == GLGE.M_REFLECT){
  6320. shader=shader+"ref = ref*(1.0-mask) + texture"+sampletype+"(TEXTURE"+this.layers[i].texture.idx+", textureCoords."+txcoord+").g*mask;\n";
  6321. }
  6322. if((this.layers[i].mapto & GLGE.M_SHINE) == GLGE.M_SHINE){
  6323. shader=shader+"sh = sh*(1.0-mask) + texture"+sampletype+"(TEXTURE"+this.layers[i].texture.idx+", textureCoords."+txcoord+").b*mask*255.0;\n";
  6324. }
  6325. if((this.layers[i].mapto & GLGE.M_EMIT) == GLGE.M_EMIT){
  6326. shader=shader+"em = em*(1.0-mask) + texture"+sampletype+"(TEXTURE"+this.layers[i].texture.idx+", textureCoords."+txcoord+").rgb*mask;\n";
  6327. }
  6328. if((this.layers[i].mapto & GLGE.M_NOR) == GLGE.M_NOR){
  6329. shader=shader+"normalmap = normalmap*(1.0-mask) + texture"+sampletype+"(TEXTURE"+this.layers[i].texture.idx+", textureCoords."+txcoord+")*mask;\n";
  6330. shader=shader+"normal = normalmap.rgb;\n";
  6331. shader=shader+"normal = 2.0*(vec3(normal.r, -normal.g, normal.b) - vec3(0.5, -0.5, 0.5));";
  6332. shader=shader+"b=normalize(cross(t.xyz,n));\n";
  6333. shader=shader+"normal = normal.x*t + normal.y*b + normal.z*n;";
  6334. shader=shader+"normal = normalize(normal);";
  6335. }
  6336. if((this.layers[i].mapto & GLGE.M_ALPHA) == GLGE.M_ALPHA){
  6337. anyAlpha=true;
  6338. shader=shader+"al = al*(1.0-mask) + texture"+sampletype+"(TEXTURE"+this.layers[i].texture.idx+", textureCoords."+txcoord+").a*mask;\n";
  6339. }
  6340. if((this.layers[i].mapto & GLGE.M_AMBIENT) == GLGE.M_AMBIENT){
  6341. shader=shader+"amblight = amblight*(1.0-mask) + texture"+sampletype+"(TEXTURE"+this.layers[i].texture.idx+", textureCoords."+txcoord+").rgb*mask;\n";
  6342. }
  6343. }
  6344. shader=shader+"amblight *= amb;\n";
  6345. if (!anyAlpha && this.layers.length) {
  6346. if(this.layers[diffuseLayer].getTexture().className=="Texture" || this.layers[diffuseLayer].getTexture().className=="TextureCanvas" || this.layers[diffuseLayer].getTexture().className=="TextureVideo" ) {
  6347. var txcoord="xy";
  6348. var sampletype="2D";
  6349. }else{
  6350. var txcoord="xyz";
  6351. var sampletype="Cube";
  6352. }
  6353. shader=shader+"al = al*(1.0-mask) + texture"+sampletype+"(TEXTURE"+this.layers[diffuseLayer].texture.idx+", textureCoords."+txcoord+").a*al*mask;\n";
  6354. }
  6355. if(colors && this.vertexColorMode==GLGE.VC_MUL){
  6356. shader=shader+"color *= vcolor;";
  6357. }
  6358. if(this.binaryAlpha) {
  6359. shader=shader+"if(al<0.5) discard;\n";
  6360. shader=shader+"al=1.0;\n";
  6361. }else{
  6362. shader=shader+"if(al==0.0) discard;\n";
  6363. }
  6364. shader=shader+"vec3 lightvalue=amblight;\n";
  6365. if(colors && this.vertexColorMode==GLGE.VC_AMB){
  6366. shader=shader+"lightvalue = vcolor.rgb;";
  6367. }
  6368. if(colors && this.vertexColorMode==GLGE.VC_AMBMUL){
  6369. shader=shader+"lightvalue *= vcolor.rgb;";
  6370. }
  6371. shader=shader+"float dotN,spotEffect;";
  6372. shader=shader+"vec3 lightvec=vec3(0.0,0.0,0.0);";
  6373. shader=shader+"vec3 viewvec=vec3(0.0,0.0,0.0);";
  6374. shader=shader+"vec3 specvalue=vec3(0.0,0.0,0.0);";
  6375. shader=shader+"vec2 scoord=vec2(0.0,0.0);";
  6376. shader=shader+"float sDepth=0.0;";
  6377. shader=shader+"float spotmul=0.0;";
  6378. shader=shader+"float rnd=0.0;";
  6379. shader=shader+"float spotsampleX=0.0;";
  6380. shader=shader+"float spotsampleY=0.0;";
  6381. shader=shader+"float totalweight=0.0;";
  6382. shader=shader+"int cnt=0;";
  6383. shader=shader+"float specularSmoothStepValue=.125;\n";
  6384. shader=shader+"vec2 spotoffset=vec2(0.0,0.0);";
  6385. shader=shader+"float dp=0.0;";
  6386. shader=shader+"vec4 dist;float depth,m1,m2,prob,variance;\n";
  6387. shader=shader+"if (normal.z<0.0) {normal.z=0.0;}\n";
  6388. shader=shader+"float fogfact=1.0;";
  6389. shader=shader+"if(fogtype=="+GLGE.FOG_QUADRATIC+" || fogtype=="+GLGE.FOG_SKYQUADRATIC+") fogfact=clamp(pow(max((fogfar - length(eyevec)) / (fogfar - fognear),0.0),2.0),0.0,1.0);\n";
  6390. shader=shader+"if(fogtype=="+GLGE.FOG_LINEAR+" || fogtype=="+GLGE.FOG_SKYLINEAR+") fogfact=clamp((fogfar - length(eyevec)) / (fogfar - fognear),0.0,1.0);\n";
  6391. shader=shader+"if (emitpass) {gl_FragColor=vec4(em,1.0);} else if (shadeless) {\n";
  6392. shader=shader+"gl_FragColor=vec4(color.rgb,al);\n";
  6393. shader=shader+"} else {\n";
  6394. for(var i=0; i<lights.length;i++){
  6395. if(lights[i].type==GLGE.L_OFF) continue;
  6396. shader=shader+"lightvec=lightvec"+i+";\n";
  6397. shader=shader+"viewvec=eyevec;\n";
  6398. if(lights[i].type==GLGE.L_POINT){
  6399. shader=shader+"dotN=max(dot(normal,normalize(-lightvec)),0.0);\n";
  6400. shader=shader+"att = 1.0 / (lightAttenuation"+i+"[0] + lightAttenuation"+i+"[1] * lightdist"+i+" + lightAttenuation"+i+"[2] * lightdist"+i+" * lightdist"+i+");\n";
  6401. shader=shader+"if(dotN>0.0){\n";
  6402. if(lights[i].diffuse){
  6403. shader=shader+"lightvalue += att * dotN * lightcolor"+i+";\n";
  6404. }
  6405. shader=shader+"}\n";
  6406. if(lights[i].specular){
  6407. shader=shader+"specvalue += smoothstep(-specularSmoothStepValue,specularSmoothStepValue,dotN)*att * specC * lightcolor"+i+" * spec * pow(max(dot(reflect(normalize(lightvec), normal),normalize(viewvec)),0.0), 0.3*sh);\n";
  6408. }
  6409. }
  6410. shader=shader+"spotEffect = 0.0;\n";
  6411. if(lights[i].type==GLGE.L_SPOT){
  6412. shader=shader+"spotEffect = dot(normalize(lightdir"+i+"), normalize(-lightvec"+i+"));";
  6413. shader=shader+"if (spotEffect > spotCosCutOff"+i+""+(!this.spotCutOff ? " || spotEffect>0.0" : "")+") {\n";
  6414. shader=shader+"spotEffect = pow(spotEffect, spotExp"+i+");";
  6415. //spot shadow stuff
  6416. if(lights[i].getCastShadows() && this.shadow){
  6417. shader=shader+"scoord=(((spotcoord"+i+".xy)/spotcoord"+i+".w)+1.0)/2.0;\n";
  6418. shader=shader+"if(scoord.x>0.0 && scoord.x<1.0 && scoord.y>0.0 && scoord.y<1.0){\n";
  6419. shader=shader+"dist=texture2D(TEXTURE"+(shadowlights[i])+", scoord);\n";
  6420. if(lights[i].spotSoftness==0){
  6421. shader=shader+"depth = dot(dist, vec4(0.000000059604644775390625,0.0000152587890625,0.00390625,1.0))*"+lights[i].distance+".0;\n";
  6422. shader=shader+"if(depth<length(lightvec"+i+")) spotmul=1.0; else spotmul=0.0;\n";
  6423. }else{
  6424. shader=shader+"m1 = pow(dot(dist, vec4(0.00390625,1.0,0.0,0.0)),2.0);\n";
  6425. shader=shader+"m2 = dot(dist, vec4(0.0,0.0,0.00390625,1.0));\n";
  6426. shader=shader+"variance = min(max(m1-m2*m2, 0.0) + 0.000002, 1.0);;\n";
  6427. shader=shader+"depth=length(lightvec"+i+")/"+lights[i].distance+".0-m2;\n";
  6428. shader=shader+"prob=variance /( variance + depth*depth );\n";
  6429. shader=shader+"prob=smoothstep("+lights[i].spotSoftnessDistance.toFixed(2)+",1.0,prob);\n";
  6430. shader=shader+"if (depth<=0.0) prob=1.0;\n";
  6431. shader=shader+"spotmul=1.0-prob;\n";
  6432. }
  6433. shader=shader+"spotEffect=spotEffect*(1.0-spotmul);\n";
  6434. shader=shader+"}\n";
  6435. }
  6436. shader=shader+"dotN=max(dot(normal,normalize(-lightvec)),0.0);\n";
  6437. if(lights[i].negativeShadow){
  6438. shader=shader+"if(dotN>0.0){\n";
  6439. if(lights[i].diffuse){
  6440. shader=shader+"lightvalue -= (1.0-spotEffect) / (lightAttenuation"+i+"[0] + lightAttenuation"+i+"[1] * lightdist"+i+" + lightAttenuation"+i+"[2] * lightdist"+i+" * lightdist"+i+");\n";
  6441. }
  6442. shader=shader+"}\n";
  6443. }else{
  6444. shader=shader+"att = spotEffect / (lightAttenuation"+i+"[0] + lightdist"+i+"*(lightAttenuation"+i+"[1] + lightAttenuation"+i+"[2] * lightdist"+i+"));\n";
  6445. shader=shader+"if(dotN>0.0){\n";
  6446. if(lights[i].diffuse){
  6447. shader=shader+"lightvalue += att * dotN * lightcolor"+i+";\n";
  6448. }
  6449. shader=shader+"}\n";
  6450. if(lights[i].specular){
  6451. shader=shader+"specvalue += smoothstep(-specularSmoothStepValue,specularSmoothStepValue,dotN) * att * specC * lightcolor"+i+" * spec * pow(max(dot(reflect(normalize(lightvec), normal),normalize(viewvec)),0.0), 0.3 * sh);\n";
  6452. }
  6453. }
  6454. shader=shader+"}\n";
  6455. }
  6456. if(lights[i].type==GLGE.L_DIR){
  6457. shader=shader+"dotN=max(dot(normal,-normalize(lightvec)),0.0);\n";
  6458. if(lights[i].getCastShadows() && this.shadow){
  6459. shader=shader+"float shadowfact"+i+" = 0.0;\n";
  6460. shader=shader+"float level"+i+" = 1.0;\n";
  6461. shader=shader+"scoord=((spotcoord"+i+".xy)+1.0)/2.0;\n";
  6462. var levels=lights[i].getCascadeLevels();
  6463. for(var l=1;l<levels;l++){
  6464. shader=shader+"if(scoord.x<0.0 || scoord.x>1.0 || scoord.y<0.0 || scoord.y>1.0) {scoord=((spotcoord"+i+".xy-shadowoffset"+i+")*"+Math.pow(0.5,l).toFixed(5)+"+shadowoffset"+i+"+1.0)/2.0;level"+i+"="+(l+1).toFixed(2)+";};\n";
  6465. }
  6466. shader=shader+"scoord.y=scoord.y/"+levels.toFixed(2)+"+1.0-"+((1/levels).toFixed(5))+"*level"+i+";\n";
  6467. if(lights[i].samples==0){
  6468. shader=shader+"dist=texture2D(TEXTURE"+shadowlights[i]+", scoord);\n";
  6469. shader=shader+"depth = dot(dist, vec4(0.000000059604644775390625,0.0000152587890625,0.00390625,1.0))*"+((+lights[i].distance).toFixed(2))+";\n";
  6470. shader=shader+"sDepth = ((spotcoord"+i+".z)/spotcoord"+i+".w+1.0)/2.0;\n";
  6471. shader=shader+"if(scoord.x>0.0 && scoord.x<1.0 && scoord.y>0.0 && scoord.y<1.0 && sDepth-shadowbias"+i+"-depth>0.0) {\n";
  6472. shader=shader+"shadowfact"+i+"=pow(clamp(2.0*length(eyevec)/"+((+lights[i].distance).toFixed(2))+",0.0,1.0),1.2);\n";
  6473. shader=shader+"}else{shadowfact"+i+"=1.0;}\n";
  6474. }else{
  6475. shader=shader+"rnd=(fract(sin(dot(scoord,vec2(12.9898,78.233))) * 43758.5453)-0.5)*0.5;\n"; //generate random number
  6476. for(var x=-lights[i].samples;x<=lights[i].samples;x++){
  6477. for(var y=-lights[i].samples;y<=lights[i].samples;y++){
  6478. shader=shader+"dist=texture2D(TEXTURE"+shadowlights[i]+", scoord+vec2("+(x/lights[i].bufferWidth).toFixed(4)+","+(y/lights[i].bufferHeight).toFixed(4)+")*shadowsoftness"+i+"*100.0/level"+i+"+vec2("+(1.0/lights[i].bufferWidth).toFixed(4)+","+(1.0/lights[i].bufferHeight).toFixed(4)+")*rnd);\n";
  6479. shader=shader+"depth = dot(dist, vec4(0.000000059604644775390625,0.0000152587890625,0.00390625,1.0))*"+((+lights[i].distance).toFixed(2))+";\n";
  6480. shader=shader+"sDepth = ((spotcoord"+i+".z)/spotcoord"+i+".w+1.0)/2.0;\n";
  6481. shader=shader+"if(scoord.x>0.0 && scoord.x<1.0 && scoord.y>0.0 && scoord.y<1.0 && sDepth-shadowbias"+i+"-depth>0.0) {\n";
  6482. shader=shader+"shadowfact"+i+"+=pow(clamp(2.0*length(eyevec)/"+((+lights[i].distance).toFixed(2))+",0.0,1.0),2.0);\n";
  6483. shader=shader+"}else{shadowfact"+i+"+=1.0;}\n";
  6484. }
  6485. }
  6486. shader=shader+"shadowfact"+i+"/="+((lights[i].samples*2+1)*(lights[i].samples*2+1)).toFixed(1)+";\n";
  6487. }
  6488. }else{
  6489. shader=shader+"float shadowfact"+i+" = 1.0;\n";
  6490. }
  6491. if(lights[i].diffuse){
  6492. if(lights[i].negativeShadow){
  6493. shader=shader+"lightvalue -= lightcolor"+i+"-(dotN * lightcolor"+i+" * shadowfact"+i+");\n";
  6494. }else{
  6495. shader=shader+"lightvalue += dotN * lightcolor"+i+" * shadowfact"+i+";\n";
  6496. }
  6497. }
  6498. if(lights[i].specular){
  6499. shader=shader+"specvalue += smoothstep(-specularSmoothStepValue,specularSmoothStepValue,dotN) * specC * lightcolor"+i+" * spec * pow(max(dot(reflect(normalize(lightvec), normal),normalize(viewvec)),0.0), 0.3 * sh);\n";
  6500. }
  6501. }
  6502. }
  6503. shader=shader+"lightvalue = (lightvalue)*ref;\n";
  6504. shader=shader+"vec3 fc=fogcolor.rgb;\n";
  6505. shader=shader+"if(fogtype=="+GLGE.FOG_SKYLINEAR+" || fogtype=="+GLGE.FOG_SKYQUADRATIC+"){";
  6506. shader=shader+"vec4 view=projection * vec4(-eyevec,1.0);\n";
  6507. shader=shader+"vec2 fogCoords=view.xy/view.w*0.5+0.5;\n";
  6508. shader=shader+"fc=texture2D(sky,fogCoords.xy).rgb;\n";
  6509. //shader=shader+"fogfact=1.0-(1.0-fogfact)*min(length(fc)/1.73,1.0);\n";
  6510. shader=shader+"}\n";
  6511. shader=shader+"vec4 finalColor =vec4(specvalue.rgb+color.rgb*lightvalue.rgb+em.rgb,al)*fogfact+vec4(fc,al)*(1.0-fogfact);\n";
  6512. if(shaderInjection && ~shaderInjection.indexOf("GLGE_FragColor")){
  6513. shader=shader+"finalColor=GLGE_FragColor(finalColor);\n";
  6514. }
  6515. shader=shader+"gl_FragColor = finalColor;";
  6516. if(GLGE.DEBUGNORMALS) shader=shader+"gl_FragColor = vec4(normal.rgb,1.0);";
  6517. if(GLGE.DEBUGCOORD0) shader=shader+"gl_FragColor = vec4(textureCoords0.rg,0.0,1.0);";
  6518. shader=shader+"}\n"; //end emit pass test
  6519. shader=shader+"}\n";
  6520. return shader;
  6521. };
  6522. /**
  6523. * Set the uniforms needed to render this material
  6524. * @private
  6525. */
  6526. GLGE.Material.prototype.textureUniforms=function(gl,shaderProgram,lights,object){
  6527. if(this.animation) this.animate();
  6528. var pc=shaderProgram.caches;
  6529. if(!pc.baseColor || pc.baseColor.r!=this.color.r || pc.baseColor.g!=this.color.g || pc.baseColor.b!=this.color.b || pc.baseColor.a!=this.color.a){
  6530. if(!this.ccache || this.ccache.r!=this.color.r || this.ccache.g!=this.color.g || this.ccache.b!=this.color.b || this.ccache.a!=this.color.a){
  6531. this.ccache=this.color;
  6532. this.glColor=new Float32Array([this.color.r,this.color.g,this.color.b,this.color.a]);
  6533. }
  6534. gl.uniform4fv(GLGE.getUniformLocation(gl,shaderProgram, "baseColor"), this.glColor);
  6535. pc.baseColor=this.color;
  6536. }
  6537. if(pc.specColor!=this.specColor){
  6538. if(this.sccache!=this.specColor){
  6539. this.sccache=this.specColor;
  6540. this.glspecColor=new Float32Array([this.specColor.r,this.specColor.g,this.specColor.b]);
  6541. }
  6542. gl.uniform3fv(GLGE.getUniformLocation(gl,shaderProgram, "specColor"), this.glspecColor);
  6543. pc.specColor=this.specColor;
  6544. }
  6545. if(pc.emit!=this.emit){
  6546. gl.uniform3f(GLGE.getUniformLocation(gl,shaderProgram, "emit"), this.emit.r,this.emit.g,this.emit.b);
  6547. pc.emit=this.emit;
  6548. }
  6549. if(pc.specular!=this.specular){
  6550. GLGE.setUniform(gl,"1f",GLGE.getUniformLocation(gl,shaderProgram, "specular"), this.specular);
  6551. pc.specular=this.specular;
  6552. }
  6553. if(pc.shine!=this.shine){
  6554. GLGE.setUniform(gl,"1f",GLGE.getUniformLocation(gl,shaderProgram, "shine"), this.shine);
  6555. pc.shine=this.shine;
  6556. }
  6557. if(pc.reflect!=this.reflect){
  6558. GLGE.setUniform(gl,"1f",GLGE.getUniformLocation(gl,shaderProgram, "reflective"), this.reflect);
  6559. pc.reflect=this.reflect;
  6560. }
  6561. if(pc.alpha!=this.alpha){
  6562. GLGE.setUniform(gl,"1f",GLGE.getUniformLocation(gl,shaderProgram, "alpha"), this.alpha);
  6563. pc.alpha=this.alpha;
  6564. }
  6565. if(pc.shadeless==undefined || pc.shadeless!=this.shadeless){
  6566. GLGE.setUniform(gl,"1i",GLGE.getUniformLocation(gl,shaderProgram, "shadeless"), this.shadeless);
  6567. pc.shadeless=this.shadeless;
  6568. }
  6569. if(gl.scene.skyTexture){
  6570. gl.activeTexture(gl["TEXTURE0"]);
  6571. gl.bindTexture(gl.TEXTURE_2D, gl.scene.skyTexture);
  6572. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
  6573. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
  6574. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
  6575. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
  6576. GLGE.setUniform(gl,"1i",GLGE.getUniformLocation(gl,shaderProgram, "sky"), 0);
  6577. }
  6578. /*
  6579. if(this.ambient && pc.ambient!=this.ambient){
  6580. gl.uniform3fv(GLGE.getUniformLocation(gl,shaderProgram, "amb"), new Float32Array([this.ambient.r,this.ambient.g,this.ambient.b]));
  6581. pc.ambient=this.ambient;
  6582. }
  6583. */
  6584. var cnt=1;
  6585. var num=0;
  6586. if(!pc["lightcolor"]){
  6587. pc["lightcolor"]=[];
  6588. pc["lightAttenuation"]=[];
  6589. pc["spotCosCutOff"]=[];
  6590. pc["spotExponent"]=[];
  6591. pc["shadowbias"]=[];
  6592. pc["castshadows"]=[];
  6593. pc["shadowsamples"]=[];
  6594. pc["shadowsoftness"]=[];
  6595. }
  6596. for(var i=0; i<lights.length;i++){
  6597. if(lights[i].type==GLGE.L_OFF) continue;
  6598. if(pc["lightcolor"][i]!=lights[i].color){
  6599. GLGE.setUniform3(gl,"3f",GLGE.getUniformLocation(gl,shaderProgram, "lightcolor"+i), lights[i].color.r,lights[i].color.g,lights[i].color.b);
  6600. pc["lightcolor"][i]=lights[i].color;
  6601. }
  6602. if(pc["lightAttenuation"][i]!=lights[i].constantAttenuation){
  6603. GLGE.setUniform3(gl,"3f",GLGE.getUniformLocation(gl,shaderProgram, "lightAttenuation"+i), lights[i].constantAttenuation,lights[i].linearAttenuation,lights[i].quadraticAttenuation);
  6604. pc["lightAttenuation"][i]=lights[i].constantAttenuation;
  6605. }
  6606. if(pc["spotCosCutOff"][i]!=lights[i].spotCosCutOff){
  6607. GLGE.setUniform(gl,"1f",GLGE.getUniformLocation(gl,shaderProgram, "spotCosCutOff"+i), lights[i].spotCosCutOff);
  6608. pc["spotCosCutOff"][i]=lights[i].spotCosCutOff;
  6609. }
  6610. if(pc["spotExponent"][i]!=lights[i].spotExponent){
  6611. GLGE.setUniform(gl,"1f",GLGE.getUniformLocation(gl,shaderProgram, "spotExp"+i), lights[i].spotExponent);
  6612. pc["spotExponent"][i]=lights[i].spotExponent;
  6613. }
  6614. if(pc["shadowbias"][i]!=lights[i].shadowBias){
  6615. GLGE.setUniform(gl,"1f",GLGE.getUniformLocation(gl,shaderProgram, "shadowbias"+i), lights[i].shadowBias);
  6616. pc["shadowbias"][i]=lights[i].shadowBias;
  6617. }
  6618. if(pc["shadowsoftness"][i]!=lights[i].softness){
  6619. GLGE.setUniform(gl,"1f",GLGE.getUniformLocation(gl,shaderProgram, "shadowsoftness"+i), lights[i].softness);
  6620. pc["shadowsoftness"][i]=lights[i].softness;
  6621. }
  6622. //shadow code
  6623. if(lights[i].getCastShadows() && this.shadow) {
  6624. num=this.textures.length+(cnt++);
  6625. gl.activeTexture(gl["TEXTURE"+num]);
  6626. gl.bindTexture(gl.TEXTURE_2D, lights[i].texture);
  6627. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
  6628. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
  6629. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
  6630. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
  6631. GLGE.setUniform(gl,"1i",GLGE.getUniformLocation(gl,shaderProgram, "TEXTURE"+num), num);
  6632. }
  6633. }
  6634. if(!shaderProgram.glarrays.layermat) shaderProgram.glarrays.layermat=[];
  6635. var scale,offset;
  6636. for(i=0; i<this.layers.length;i++){
  6637. if(this.layers[i].animation) this.layers[i].animate();
  6638. scale=this.layers[i].getScale();
  6639. offset=this.layers[i].getOffset();
  6640. if(!shaderProgram.glarrays.layermat[i]) shaderProgram.glarrays.layermat[i]=new Float32Array(this.layers[i].getMatrix());
  6641. else GLGE.mat4gl(this.layers[i].getMatrix(),shaderProgram.glarrays.layermat[i]);
  6642. try{GLGE.setUniformMatrix(gl,"Matrix4fv",GLGE.getUniformLocation(gl,shaderProgram, "layer"+i+"Matrix"), true, shaderProgram.glarrays.layermat[i]);}catch(e){}
  6643. GLGE.setUniform(gl,"1f",GLGE.getUniformLocation(gl,shaderProgram, "layeralpha"+i), this.layers[i].getAlpha());
  6644. GLGE.setUniform(gl,"1f",GLGE.getUniformLocation(gl,shaderProgram, "layerheight"+i), this.layers[i].getHeight());
  6645. }
  6646. for(var i=0; i<this.textures.length;i++){
  6647. gl.activeTexture(gl["TEXTURE"+(i+1)]);
  6648. if(this.textures[i].doTexture(gl,object)){
  6649. }
  6650. GLGE.setUniform(gl,"1i",GLGE.getUniformLocation(gl,shaderProgram, "TEXTURE"+i), i+1);
  6651. }
  6652. };
  6653. /**
  6654. * Adds a new texture to this material
  6655. * @returns {boolean} true if all resources have loaded false otherwise
  6656. */
  6657. GLGE.Material.prototype.isComplete=function(){
  6658. for(var i=0;i<this.textures.length;i++){
  6659. if(!this.textures[i].isComplete) continue;
  6660. if(!this.textures[i].isComplete()) return false;
  6661. }
  6662. return true;
  6663. }
  6664. /**
  6665. * Adds a new texture to this material
  6666. * @param {String} image URL of the image to be used by the texture
  6667. * @return {Number} index of the new texture
  6668. */
  6669. GLGE.Material.prototype.addTexture=function(texture){
  6670. if(typeof texture=="string") texture=GLGE.Assets.get(texture);
  6671. var material=this;
  6672. texture.addEventListener("downloadComplete",function(){
  6673. if(material.isComplete()) material.fireEvent("downloadComplete");
  6674. });
  6675. this.textures.push(texture);
  6676. texture.idx=this.textures.length-1;
  6677. this.fireEvent("shaderupdate",{});
  6678. return this;
  6679. };
  6680. GLGE.Material.prototype.addTextureCube=GLGE.Material.prototype.addTexture;
  6681. GLGE.Material.prototype.addTextureCamera=GLGE.Material.prototype.addTexture;
  6682. GLGE.Material.prototype.addTextureCanvas=GLGE.Material.prototype.addTexture;
  6683. GLGE.Material.prototype.addTextureVideo=GLGE.Material.prototype.addTexture;
  6684. GLGE.DEFAULT_MATERIAL=new GLGE.Material();
  6685. })(GLGE);/*
  6686. GLGE WebGL Graphics Engine
  6687. Copyright (c) 2010, Paul Brunt
  6688. All rights reserved.
  6689. Redistribution and use in source and binary forms, with or without
  6690. modification, are permitted provided that the following conditions are met:
  6691. * Redistributions of source code must retain the above copyright
  6692. notice, this list of conditions and the following disclaimer.
  6693. * Redistributions in binary form must reproduce the above copyright
  6694. notice, this list of conditions and the following disclaimer in the
  6695. documentation and/or other materials provided with the distribution.
  6696. * Neither the name of GLGE nor the
  6697. names of its contributors may be used to endorse or promote products
  6698. derived from this software without specific prior written permission.
  6699. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  6700. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  6701. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  6702. DISCLAIMED. IN NO EVENT SHALL PAUL BRUNT BE LIABLE FOR ANY
  6703. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  6704. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  6705. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  6706. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  6707. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  6708. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  6709. */
  6710. /**
  6711. * @fileOverview
  6712. * @name glge_materiallayer.js
  6713. * @author me@paulbrunt.co.uk
  6714. */
  6715. (function(GLGE){
  6716. /**
  6717. * @class The material layer describes how to apply this layer to the material
  6718. * @see GLGE.Material
  6719. * @augments GLGE.Animatable
  6720. * @augments GLGE.QuickNotation
  6721. * @augments GLGE.JSONLoader
  6722. * @augments GLGE.Events
  6723. */
  6724. GLGE.MaterialLayer=function(uid){
  6725. this.blendMode=GLGE.BL_MIX;
  6726. GLGE.Assets.registerAsset(this,uid);
  6727. };
  6728. GLGE.augment(GLGE.Animatable,GLGE.MaterialLayer);
  6729. GLGE.augment(GLGE.QuickNotation,GLGE.MaterialLayer);
  6730. GLGE.augment(GLGE.JSONLoader,GLGE.MaterialLayer);
  6731. GLGE.augment(GLGE.Events,GLGE.MaterialLayer);
  6732. /**
  6733. * @name GLGE.MaterialLayer#shaderupdated
  6734. * @event Fires when a change will result in a change to the GLSL shader
  6735. * @param {object} data
  6736. */
  6737. GLGE.MaterialLayer.prototype.className="MaterialLayer";
  6738. GLGE.MaterialLayer.prototype.texture=null;
  6739. GLGE.MaterialLayer.prototype.blendMode=null;
  6740. GLGE.MaterialLayer.prototype.mapto=GLGE.M_COLOR;
  6741. GLGE.MaterialLayer.prototype.mapinput=GLGE.UV1;
  6742. GLGE.MaterialLayer.prototype.scaleX=1;
  6743. GLGE.MaterialLayer.prototype.offsetX=0;
  6744. GLGE.MaterialLayer.prototype.rotX=0;
  6745. GLGE.MaterialLayer.prototype.scaleY=1;
  6746. GLGE.MaterialLayer.prototype.offsetY=0;
  6747. GLGE.MaterialLayer.prototype.rotY=0;
  6748. GLGE.MaterialLayer.prototype.scaleZ=1;
  6749. GLGE.MaterialLayer.prototype.offsetZ=0;
  6750. GLGE.MaterialLayer.prototype.rotZ=0;
  6751. GLGE.MaterialLayer.prototype.dScaleX=0;
  6752. GLGE.MaterialLayer.prototype.dOffsetX=0;
  6753. GLGE.MaterialLayer.prototype.dRotX=0;
  6754. GLGE.MaterialLayer.prototype.dScaleY=0;
  6755. GLGE.MaterialLayer.prototype.dOffsetY=0;
  6756. GLGE.MaterialLayer.prototype.dRotY=0;
  6757. GLGE.MaterialLayer.prototype.dScaleZ=0;
  6758. GLGE.MaterialLayer.prototype.dOffsetZ=0;
  6759. GLGE.MaterialLayer.prototype.dRotZ=0;
  6760. GLGE.MaterialLayer.prototype.alpha=1;
  6761. GLGE.MaterialLayer.prototype.height=0.05;
  6762. GLGE.MaterialLayer.prototype.matrix=null;
  6763. /**
  6764. * Gets the textures used by the layer
  6765. * @return {GLGE.Texture} The current shininess of the material
  6766. */
  6767. GLGE.MaterialLayer.prototype.getMatrix=function(){
  6768. if(!this.matrix){
  6769. var offset=this.getOffset();
  6770. var scale=this.getScale();
  6771. var rotation=this.getRotation();
  6772. this.matrix=GLGE.mulMat4(GLGE.mulMat4(GLGE.translateMatrix(offset.x,offset.y,offset.z),GLGE.scaleMatrix(scale.x,scale.y,scale.z)),GLGE.rotateMatrix(rotation.x,rotation.y,rotation.z));
  6773. }
  6774. return this.matrix;
  6775. };
  6776. /**
  6777. * Sets the height for this layer, currently only used for parallax mapping
  6778. * @param {number} the height of this layer
  6779. */
  6780. GLGE.MaterialLayer.prototype.setHeight=function(value){
  6781. this.height=value;
  6782. return this;
  6783. };
  6784. /**
  6785. * Gets the height for this layer, currently only used for parallax mapping
  6786. * @return {number} the height of this layer
  6787. */
  6788. GLGE.MaterialLayer.prototype.getHeight=function(){
  6789. return this.height;
  6790. };
  6791. /**
  6792. * Sets the textures alpha blending value
  6793. * @param {number} the alpha for this layer
  6794. */
  6795. GLGE.MaterialLayer.prototype.setAlpha=function(value){
  6796. this.alpha=value;
  6797. return this;
  6798. };
  6799. /**
  6800. * Gets the textures alpha blending value
  6801. * @return {number} the alpha for this layer
  6802. */
  6803. GLGE.MaterialLayer.prototype.getAlpha=function(){
  6804. return this.alpha;
  6805. };
  6806. /**
  6807. * Sets the textures used by the layer
  6808. * @param {GLGE.Texture} value the teture to associate with this layer
  6809. */
  6810. GLGE.MaterialLayer.prototype.setTexture=function(value){
  6811. if(typeof value=="string") value=GLGE.Assets.get(value);
  6812. this.texture=value;
  6813. this.fireEvent("shaderupdate",{});
  6814. return this;
  6815. };
  6816. /**
  6817. * Gets the textures used by the layer
  6818. * @return {GLGE.Texture} The current shininess of the material
  6819. */
  6820. GLGE.MaterialLayer.prototype.getTexture=function(){
  6821. return this.texture;
  6822. };
  6823. /**
  6824. * Sets the flag for how this layer maps to the material
  6825. * @param {Number} value the flags to set for this layer
  6826. */
  6827. GLGE.MaterialLayer.prototype.setMapto=function(value){
  6828. this.mapto=value;
  6829. this.fireEvent("shaderupdate",{});
  6830. return this;
  6831. };
  6832. /**
  6833. * Gets the flag representing the way the layer maps to the material
  6834. * @return {Number} The flags currently set for this layer
  6835. */
  6836. GLGE.MaterialLayer.prototype.getMapto=function(){
  6837. return this.mapto;
  6838. };
  6839. /**
  6840. * Sets the texture coordinate system
  6841. * @param {Number} value the mapping to use
  6842. */
  6843. GLGE.MaterialLayer.prototype.setMapinput=function(value){
  6844. this.mapinput=value;
  6845. this.fireEvent("shaderupdate",{});
  6846. return this;
  6847. };
  6848. /**
  6849. * Gets the texture coordinate system
  6850. * @return {Number} The current mapping
  6851. */
  6852. GLGE.MaterialLayer.prototype.getMapinput=function(){
  6853. return this.mapinput;
  6854. };
  6855. /**
  6856. * Gets the layers texture offset
  6857. * @return {object} the current offset
  6858. */
  6859. GLGE.MaterialLayer.prototype.getOffset=function(){
  6860. var offset={};
  6861. offset.x=parseFloat(this.getOffsetX())+parseFloat(this.getDOffsetX());
  6862. offset.y=parseFloat(this.getOffsetY())+parseFloat(this.getDOffsetY());
  6863. offset.z=parseFloat(this.getOffsetZ())+parseFloat(this.getDOffsetZ());
  6864. return offset;
  6865. };
  6866. /**
  6867. * Gets the layers texture rotation
  6868. * @return {object} the current rotation
  6869. */
  6870. GLGE.MaterialLayer.prototype.getRotation=function(){
  6871. var rotation={};
  6872. rotation.x=parseFloat(this.getRotX())+parseFloat(this.getDRotX());
  6873. rotation.y=parseFloat(this.getRotY())+parseFloat(this.getDRotY());
  6874. rotation.z=parseFloat(this.getRotZ())+parseFloat(this.getDRotZ());
  6875. return rotation;
  6876. };
  6877. /**
  6878. * Gets the layers texture scale
  6879. * @return {object} the current scale
  6880. */
  6881. GLGE.MaterialLayer.prototype.getScale=function(){
  6882. var scale={};
  6883. scale.x=parseFloat(this.getScaleX())+parseFloat(this.getDScaleX());
  6884. scale.y=parseFloat(this.getScaleY())+parseFloat(this.getDScaleY());
  6885. scale.z=parseFloat(this.getScaleZ())+parseFloat(this.getDScaleZ());
  6886. return scale;
  6887. };
  6888. /**
  6889. * Sets the layers texture X offset
  6890. * @param {Number} value the amount to offset the texture
  6891. */
  6892. GLGE.MaterialLayer.prototype.setOffsetX=function(value){
  6893. this.matrix=null;
  6894. this.offsetX=value;
  6895. return this;
  6896. };
  6897. /**
  6898. * Gets the layers texture X offset
  6899. * @return {Number} the current offset
  6900. */
  6901. GLGE.MaterialLayer.prototype.getOffsetX=function(){
  6902. return this.offsetX;
  6903. };
  6904. /**
  6905. * Sets the layers texture Y offset
  6906. * @param {Number} value the amount to offset the texture
  6907. */
  6908. GLGE.MaterialLayer.prototype.setOffsetY=function(value){
  6909. this.matrix=null;
  6910. this.offsetY=value;
  6911. return this;
  6912. };
  6913. /**
  6914. * Gets the layers texture Y offset
  6915. * @return {Number} the current offset
  6916. */
  6917. GLGE.MaterialLayer.prototype.getOffsetY=function(){
  6918. return this.offsetY;
  6919. };
  6920. /**
  6921. * Sets the layers texture Z offset
  6922. * @param {Number} value the amount to offset the texture
  6923. */
  6924. GLGE.MaterialLayer.prototype.setOffsetZ=function(value){
  6925. this.matrix=null;
  6926. this.offsetZ=value;
  6927. return this;
  6928. };
  6929. /**
  6930. * Gets the layers texture Z offset
  6931. * @return {Number} the current offset
  6932. */
  6933. GLGE.MaterialLayer.prototype.getOffsetZ=function(){
  6934. return this.offsetZ;
  6935. };
  6936. /**
  6937. * Sets the layers texture X displacment offset, useful for animation
  6938. * @param {Number} value the amount to offset the texture
  6939. */
  6940. GLGE.MaterialLayer.prototype.setDOffsetX=function(value){
  6941. this.matrix=null;
  6942. this.dOffsetX=value;
  6943. return this;
  6944. };
  6945. /**
  6946. * Gets the layers texture X displacment offset, useful for animation
  6947. * @return {Number} the current offset
  6948. */
  6949. GLGE.MaterialLayer.prototype.getDOffsetX=function(){
  6950. return this.dOffsetX;
  6951. };
  6952. /**
  6953. * Sets the layers texture Y displacment offset, useful for animation
  6954. * @param {Number} value the amount to offset the texture
  6955. */
  6956. GLGE.MaterialLayer.prototype.setDOffsetY=function(value){
  6957. this.matrix=null;
  6958. this.dOffsetY=value;
  6959. return this;
  6960. };
  6961. /**
  6962. * Gets the layers texture Y displacment offset, useful for animation
  6963. * @return {Number} the current offset
  6964. */
  6965. GLGE.MaterialLayer.prototype.getDOffsetY=function(){
  6966. return this.dOffsetY;
  6967. };
  6968. /**
  6969. * Sets the layers texture Z displacment offset, useful for animation
  6970. * @param {Number} value the amount to offset the texture
  6971. */
  6972. GLGE.MaterialLayer.prototype.setDOffsetZ=function(value){
  6973. this.matrix=null;
  6974. this.dOffsetZ=value;
  6975. return this;
  6976. };
  6977. /**
  6978. * Gets the layers texture X displacment offset, useful for animation
  6979. * @return {Number} the current offset
  6980. */
  6981. GLGE.MaterialLayer.prototype.getDOffsetZ=function(){
  6982. return this.dOffsetZ;
  6983. };
  6984. /**
  6985. * Sets the layers texture X scale
  6986. * @param {Number} value the amount to scale the texture
  6987. */
  6988. GLGE.MaterialLayer.prototype.setScaleX=function(value){
  6989. this.matrix=null;
  6990. this.scaleX=value;
  6991. return this;
  6992. };
  6993. /**
  6994. * Gets the layers texture X scale
  6995. * @return {Number} the current scale
  6996. */
  6997. GLGE.MaterialLayer.prototype.getScaleX=function(){
  6998. return this.scaleX;
  6999. };
  7000. /**
  7001. * Sets the layers texture Y scale
  7002. * @param {Number} value the amount to scale the texture
  7003. */
  7004. GLGE.MaterialLayer.prototype.setScaleY=function(value){
  7005. this.matrix=null;
  7006. this.scaleY=value;
  7007. return this;
  7008. };
  7009. /**
  7010. * Gets the layers texture Y scale
  7011. * @return {Number} the current scale
  7012. */
  7013. GLGE.MaterialLayer.prototype.getScaleY=function(){
  7014. return this.scaleY;
  7015. };
  7016. /**
  7017. * Sets the layers texture Z scale
  7018. * @param {Number} value the amount to scale the texture
  7019. */
  7020. GLGE.MaterialLayer.prototype.setScaleZ=function(value){
  7021. this.matrix=null;
  7022. this.scaleZ=value;
  7023. return this;
  7024. };
  7025. /**
  7026. * Gets the layers texture Z offset
  7027. * @return {Number} the current offset
  7028. */
  7029. GLGE.MaterialLayer.prototype.getScaleZ=function(){
  7030. return this.scaleZ;
  7031. };
  7032. /**
  7033. * Sets the layers texture X displacment scale, useful for animation
  7034. * @param {Number} value the amount to scale the texture
  7035. */
  7036. GLGE.MaterialLayer.prototype.setDScaleX=function(value){
  7037. this.matrix=null;
  7038. this.dScaleX=value;
  7039. return this;
  7040. };
  7041. /**
  7042. * Gets the layers texture X displacment scale, useful for animation
  7043. * @return {Number} the current scale
  7044. */
  7045. GLGE.MaterialLayer.prototype.getDScaleX=function(){
  7046. return this.dScaleX;
  7047. };
  7048. /**
  7049. * Sets the layers texture Y displacment scale, useful for animation
  7050. * @param {Number} value the amount to scale the texture
  7051. */
  7052. GLGE.MaterialLayer.prototype.setDScaleY=function(value){
  7053. this.matrix=null;
  7054. this.dScaleY=value;
  7055. return this;
  7056. };
  7057. /**
  7058. * Gets the layers texture Y displacment scale, useful for animation
  7059. * @return {Number} the current scale
  7060. */
  7061. GLGE.MaterialLayer.prototype.getDScaleY=function(){
  7062. return this.dScaleY;
  7063. };
  7064. /**
  7065. * Sets the layers texture Z displacment scale, useful for animation
  7066. * @param {Number} value the amount to scale the texture
  7067. */
  7068. GLGE.MaterialLayer.prototype.setDScaleZ=function(value){
  7069. this.matrix=null;
  7070. this.dScaleZ=value;
  7071. return this;
  7072. };
  7073. /**
  7074. * Gets the layers texture X displacment scale, useful for animation
  7075. * @return {Number} the current scale
  7076. */
  7077. GLGE.MaterialLayer.prototype.getDScaleZ=function(){
  7078. return this.dScaleZ;
  7079. };
  7080. /**
  7081. * Sets the layers texture X Rotation
  7082. * @param {Number} value the amount to roate the texture
  7083. */
  7084. GLGE.MaterialLayer.prototype.setRotX=function(value){
  7085. this.matrix=null;
  7086. this.rotX=value;
  7087. return this;
  7088. };
  7089. /**
  7090. * Gets the layers texture X rotate
  7091. * @return {Number} the current rotate
  7092. */
  7093. GLGE.MaterialLayer.prototype.getRotX=function(){
  7094. return this.rotX;
  7095. };
  7096. /**
  7097. * Sets the layers texture Y rotate
  7098. * @param {Number} value the amount to rotate the texture
  7099. */
  7100. GLGE.MaterialLayer.prototype.setRotY=function(value){
  7101. this.matrix=null;
  7102. this.rotY=value;
  7103. return this;
  7104. };
  7105. /**
  7106. * Gets the layers texture Y rotate
  7107. * @return {Number} the current rotate
  7108. */
  7109. GLGE.MaterialLayer.prototype.getRotY=function(){
  7110. return this.rotY;
  7111. };
  7112. /**
  7113. * Sets the layers texture Z rotate
  7114. * @param {Number} value the amount to rotate the texture
  7115. */
  7116. GLGE.MaterialLayer.prototype.setRotZ=function(value){
  7117. this.matrix=null;
  7118. this.rotZ=value;
  7119. return this;
  7120. };
  7121. /**
  7122. * Gets the layers texture Z rotate
  7123. * @return {Number} the current rotate
  7124. */
  7125. GLGE.MaterialLayer.prototype.getRotZ=function(){
  7126. return this.rotZ;
  7127. };
  7128. /**
  7129. * Sets the layers texture X displacment rotation, useful for animation
  7130. * @param {Number} value the amount to rotation the texture
  7131. */
  7132. GLGE.MaterialLayer.prototype.setDRotX=function(value){
  7133. this.matrix=null;
  7134. this.dRotX=value;
  7135. return this;
  7136. };
  7137. /**
  7138. * Gets the layers texture X displacment rotation, useful for animation
  7139. * @return {Number} the current rotation
  7140. */
  7141. GLGE.MaterialLayer.prototype.getDRotX=function(){
  7142. return this.dRotX;
  7143. };
  7144. /**
  7145. * Sets the layers texture Y displacment rotation, useful for animation
  7146. * @param {Number} value the amount to rotaion the texture
  7147. */
  7148. GLGE.MaterialLayer.prototype.setDRotY=function(value){
  7149. this.matrix=null;
  7150. this.dRotY=value;
  7151. return this;
  7152. };
  7153. /**
  7154. * Gets the layers texture Y displacment rotation, useful for animation
  7155. * @return {Number} the current rotation
  7156. */
  7157. GLGE.MaterialLayer.prototype.getDRotY=function(){
  7158. return this.dRotY;
  7159. };
  7160. /**
  7161. * Sets the layers texture Z displacment rotation, useful for animation
  7162. * @param {Number} value the amount to rotation the texture
  7163. */
  7164. GLGE.MaterialLayer.prototype.setDRotZ=function(value){
  7165. this.matrix=null;
  7166. this.dRotZ=value;
  7167. return this;
  7168. };
  7169. /**
  7170. * Gets the layers texture X displacment rotation, useful for animation
  7171. * @return {Number} the current rotation
  7172. */
  7173. GLGE.MaterialLayer.prototype.getDRotZ=function(){
  7174. return this.dRotZ;
  7175. };
  7176. /**
  7177. * Sets the layers blending mode
  7178. * @param {Number} value the blend mode for the layer
  7179. */
  7180. GLGE.MaterialLayer.prototype.setBlendMode=function(value){
  7181. this.blendMode=value;
  7182. this.fireEvent("shaderupdate",{});
  7183. return this;
  7184. };
  7185. /**
  7186. * Gets the layers tblending mode
  7187. * @return {Number} the blend mode for the layer
  7188. */
  7189. GLGE.MaterialLayer.prototype.getBlendMode=function(){
  7190. return this.blendMode;
  7191. };
  7192. })(GLGE);/*
  7193. GLGE WebGL Graphics Engine
  7194. Copyright (c) 2010, Paul Brunt
  7195. All rights reserved.
  7196. Redistribution and use in source and binary forms, with or without
  7197. modification, are permitted provided that the following conditions are met:
  7198. * Redistributions of source code must retain the above copyright
  7199. notice, this list of conditions and the following disclaimer.
  7200. * Redistributions in binary form must reproduce the above copyright
  7201. notice, this list of conditions and the following disclaimer in the
  7202. documentation and/or other materials provided with the distribution.
  7203. * Neither the name of GLGE nor the
  7204. names of its contributors may be used to endorse or promote products
  7205. derived from this software without specific prior written permission.
  7206. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  7207. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  7208. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  7209. DISCLAIMED. IN NO EVENT SHALL PAUL BRUNT BE LIABLE FOR ANY
  7210. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  7211. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  7212. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  7213. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  7214. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  7215. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  7216. */
  7217. /**
  7218. * @fileOverview
  7219. * @name glge_multimaterial.js
  7220. * @author me@paulbrunt.co.uk
  7221. */
  7222. (function(GLGE){
  7223. /**
  7224. * @name GLGE.MultiMaterial#downloadComplete
  7225. * @event fires when all the assets for this class have finished loading
  7226. * @param {object} data
  7227. */
  7228. /**
  7229. * @class Creates a new mesh/material to add to an object
  7230. * @augments GLGE.QuickNotation
  7231. * @augments GLGE.JSONLoader
  7232. * @augments GLGE.Events
  7233. */
  7234. GLGE.MultiMaterial=function(uid){
  7235. var multiMaterial=this;
  7236. this.downloadComplete=function(){
  7237. if(multiMaterial.isComplete()) multiMaterial.fireEvent("downloadComplete");
  7238. }
  7239. this.boundUpdate=function(){
  7240. multiMaterial.fireEvent("boundupdate");
  7241. }
  7242. this.lods=[new GLGE.ObjectLod];
  7243. this.lods[0].addEventListener("downloadComplete",this.downloadComplete);
  7244. this.lods[0].addEventListener("boundupdate",this.boundUpdate);
  7245. GLGE.Assets.registerAsset(this,uid);
  7246. }
  7247. GLGE.augment(GLGE.QuickNotation,GLGE.MultiMaterial);
  7248. GLGE.augment(GLGE.JSONLoader,GLGE.MultiMaterial);
  7249. GLGE.augment(GLGE.Events,GLGE.MultiMaterial);
  7250. GLGE.MultiMaterial.prototype.className="MultiMaterial";
  7251. GLGE.MultiMaterial.prototype.oneLod=true;
  7252. /**
  7253. * Checks if resources have finished downloading
  7254. * @returns {boolean}
  7255. */
  7256. GLGE.MultiMaterial.prototype.isComplete=function(){
  7257. for(var i=0;i<this.lods.length;i++){
  7258. if(!this.lods[i].isComplete()) return false;
  7259. }
  7260. return true;
  7261. }
  7262. /**
  7263. * sets the mesh
  7264. * @param {GLGE.Mesh} mesh
  7265. */
  7266. GLGE.MultiMaterial.prototype.setMesh=function(mesh){
  7267. this.lods[0].setMesh(mesh);
  7268. return this;
  7269. }
  7270. /**
  7271. * gets the mesh
  7272. * @returns {GLGE.Mesh}
  7273. */
  7274. GLGE.MultiMaterial.prototype.getMesh=function(){
  7275. return this.lods[0].getMesh();
  7276. }
  7277. /**
  7278. * sets the material
  7279. * @param {GLGE.Material} material
  7280. */
  7281. GLGE.MultiMaterial.prototype.setMaterial=function(material){
  7282. this.lods[0].setMaterial(material);
  7283. return this;
  7284. }
  7285. /**
  7286. * gets the material
  7287. * @returns {GLGE.Material}
  7288. */
  7289. GLGE.MultiMaterial.prototype.getMaterial=function(){
  7290. return this.lods[0].getMaterial();
  7291. }
  7292. /**
  7293. * returns the load for a given pixel size
  7294. * @param {number} pixelsize the current pixel size of the object
  7295. * @returns {GLGE.ObjectLod}
  7296. */
  7297. GLGE.MultiMaterial.prototype.getLOD=function(pixelsize){
  7298. var currentSize=0;
  7299. var currentLOD=this.lods[0];
  7300. if(this.lods.length>1){
  7301. for(var i=1; i<this.lods.length;i++){
  7302. var size=this.lods[i].pixelSize;
  7303. if(size>currentSize && size<pixelsize && this.lods[i].mesh && this.lods[i].mesh.loaded){
  7304. currentSize=size;
  7305. currentLOD=this.lods[i];
  7306. }
  7307. }
  7308. }
  7309. return currentLOD;
  7310. }
  7311. /**
  7312. * adds a lod to this multimaterial
  7313. * @param {GLGE.ObjectLod} lod the lod to add
  7314. */
  7315. GLGE.MultiMaterial.prototype.addObjectLod=function(lod){
  7316. if(this.oneLod){
  7317. this.oneLod=false;
  7318. this.lods=[];
  7319. }
  7320. this.lods.push(lod);
  7321. lod.addEventListener("downloadComplete",this.downloadComplete);
  7322. return this;
  7323. }
  7324. /**
  7325. * Updates the GL shader program for the object
  7326. * @private
  7327. */
  7328. GLGE.MultiMaterial.prototype.updateProgram=function(){
  7329. for(var i=0; i<this.lods.length;i++){
  7330. this.lods[i].GLShaderProgram=null;
  7331. }
  7332. return this;
  7333. }
  7334. /**
  7335. * removes a lod to this multimaterial
  7336. * @param {GLGE.ObjectLod} lod the lod to remove
  7337. */
  7338. GLGE.MultiMaterial.prototype.removeObjectLod=function(lod){
  7339. var idx=this.lods.indexOf(lod);
  7340. lods[idx].removeEventListener("downloadComplete",this.downloadComplete);
  7341. if(idx) this.lods.splice(idx,1);
  7342. return this;
  7343. }
  7344. })(GLGE);/*
  7345. GLGE WebGL Graphics Engine
  7346. Copyright (c) 2010, Paul Brunt
  7347. All rights reserved.
  7348. Redistribution and use in source and binary forms, with or without
  7349. modification, are permitted provided that the following conditions are met:
  7350. * Redistributions of source code must retain the above copyright
  7351. notice, this list of conditions and the following disclaimer.
  7352. * Redistributions in binary form must reproduce the above copyright
  7353. notice, this list of conditions and the following disclaimer in the
  7354. documentation and/or other materials provided with the distribution.
  7355. * Neither the name of GLGE nor the
  7356. names of its contributors may be used to endorse or promote products
  7357. derived from this software without specific prior written permission.
  7358. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  7359. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  7360. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  7361. DISCLAIMED. IN NO EVENT SHALL PAUL BRUNT BE LIABLE FOR ANY
  7362. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  7363. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  7364. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  7365. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  7366. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  7367. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  7368. */
  7369. /**
  7370. * @fileOverview
  7371. * @name glge_texture.js
  7372. * @author me@paulbrunt.co.uk
  7373. */
  7374. (function(GLGE){
  7375. /**
  7376. * @name GLGE.Texture#downloadComplete
  7377. * @event fires when all the assets for this texture have finished loading
  7378. * @param {object} data
  7379. */
  7380. /**
  7381. * @class A texture to be included in a material
  7382. * @param {string} uid the unique id for this texture
  7383. * @see GLGE.Material
  7384. * @augments GLGE.QuickNotation
  7385. * @augments GLGE.JSONLoader
  7386. * @augments GLGE.Events
  7387. */
  7388. GLGE.Texture=function(uid){
  7389. GLGE.Assets.registerAsset(this,uid);
  7390. }
  7391. GLGE.augment(GLGE.QuickNotation,GLGE.Texture);
  7392. GLGE.augment(GLGE.JSONLoader,GLGE.Texture);
  7393. GLGE.augment(GLGE.Events,GLGE.Texture);
  7394. GLGE.Texture.prototype.className="Texture";
  7395. GLGE.Texture.prototype.image=null;
  7396. GLGE.Texture.prototype.glTexture=null;
  7397. GLGE.Texture.prototype.url=null;
  7398. GLGE.Texture.prototype.state=0;
  7399. /**
  7400. * Gets the textures used by the layer
  7401. * @return {string} The textures image url
  7402. */
  7403. GLGE.Texture.prototype.getSrc=function(){
  7404. return this.url;
  7405. };
  7406. /**
  7407. * Sets the textures image location
  7408. * @param {string} url the texture image url
  7409. */
  7410. GLGE.Texture.prototype.setSrc=function(url){
  7411. this.url=url;
  7412. this.state=0;
  7413. this.image=new Image();
  7414. if(url.indexOf('@')!=-1)
  7415. this.image.crossOrigin = "use-credentials";
  7416. else
  7417. this.image.crossOrigin = 'anonymous';
  7418. var texture=this;
  7419. this.image.onload = function(){
  7420. texture.state=1;
  7421. texture.fireEvent("downloadComplete");
  7422. }
  7423. this.image.src=url;
  7424. if(this.glTexture && this.gl){
  7425. this.gl.deleteTexture(this.glTexture);
  7426. this.glTexture=null;
  7427. }
  7428. return this;
  7429. };
  7430. /**
  7431. * Sets the textures image location
  7432. * @private
  7433. **/
  7434. GLGE.Texture.prototype.doTexture=function(gl){
  7435. this.gl=gl;
  7436. if(!gl.urlTextures) gl.urlTextures={};
  7437. if(gl.urlTextures[this.url]){
  7438. this.glTexture=gl.urlTextures[this.url];
  7439. this.state=2;
  7440. }
  7441. //create the texture if it's not already created
  7442. if(!this.image) this.setSrc(this.url);
  7443. if(!this.glTexture) this.glTexture=gl.createTexture();
  7444. //if the image is loaded then set in the texture data
  7445. if(this.state==1){
  7446. gl.bindTexture(gl.TEXTURE_2D, this.glTexture);
  7447. //START... FRANCISCO REIS: to accept Non Power of Two Images
  7448. var w = Math.pow( 2, Math.round( Math.log( this.image.width ) / Math.log( 2 ) ) );
  7449. var h = Math.pow( 2, Math.round( Math.log( this.image.height ) / Math.log( 2 ) ) );
  7450. var imageOrCanvas;
  7451. if(w == this.image.width && h == this.image.height)
  7452. imageOrCanvas = this.image;
  7453. else
  7454. {
  7455. imageOrCanvas = document.createElement("canvas");
  7456. imageOrCanvas.width=w;
  7457. imageOrCanvas.height=h;
  7458. var context = imageOrCanvas.getContext("2d");
  7459. context.drawImage(this.image,0,0,w,h);
  7460. }
  7461. gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE,imageOrCanvas);//this line was replaced from ",this.image)" to ",imageOrCanvas)"
  7462. //...END FRANCISCO REIS: to accept Non Power of Two Images
  7463. gl.urlTextures[this.url]=this.glTexture;
  7464. gl.generateMipmap(gl.TEXTURE_2D);
  7465. gl.bindTexture(gl.TEXTURE_2D, null);
  7466. this.state=2;
  7467. }
  7468. gl.bindTexture(gl.TEXTURE_2D, this.glTexture);
  7469. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
  7470. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);
  7471. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
  7472. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
  7473. if(this.state==2) return true;
  7474. else return false;
  7475. }
  7476. /**
  7477. * Determin if the image resource has been downloaded
  7478. **/
  7479. GLGE.Texture.prototype.isComplete=function(){
  7480. return this.state>0;
  7481. }
  7482. })(GLGE);/*
  7483. GLGE WebGL Graphics Engine
  7484. Copyright (c) 2010, Paul Brunt
  7485. All rights reserved.
  7486. Redistribution and use in source and binary forms, with or without
  7487. modification, are permitted provided that the following conditions are met:
  7488. * Redistributions of source code must retain the above copyright
  7489. notice, this list of conditions and the following disclaimer.
  7490. * Redistributions in binary form must reproduce the above copyright
  7491. notice, this list of conditions and the following disclaimer in the
  7492. documentation and/or other materials provided with the distribution.
  7493. * Neither the name of GLGE nor the
  7494. names of its contributors may be used to endorse or promote products
  7495. derived from this software without specific prior written permission.
  7496. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  7497. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  7498. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  7499. DISCLAIMED. IN NO EVENT SHALL PAUL BRUNT BE LIABLE FOR ANY
  7500. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  7501. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  7502. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  7503. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  7504. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  7505. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  7506. */
  7507. /**
  7508. * @fileOverview
  7509. * @name glge_texturecamera.js
  7510. * @author me@paulbrunt.co.uk
  7511. */
  7512. (function(GLGE){
  7513. /**
  7514. * @class A reflection texture will reflect in a plane for a specified transform
  7515. * @param {string} uid the unique id for this texture
  7516. * @see GLGE.Material
  7517. * @augments GLGE.QuickNotation
  7518. * @augments GLGE.JSONLoader
  7519. */
  7520. GLGE.TextureCamera=function(uid){
  7521. GLGE.Assets.registerAsset(this,uid);
  7522. }
  7523. GLGE.augment(GLGE.QuickNotation,GLGE.TextureCamera);
  7524. GLGE.augment(GLGE.JSONLoader,GLGE.TextureCamera);
  7525. GLGE.augment(GLGE.Events,GLGE.TextureCamera);
  7526. GLGE.TextureCamera.prototype.className="Texture";
  7527. GLGE.TextureCamera.prototype.texture=null;
  7528. GLGE.TextureCamera.prototype.glTexture=null;
  7529. GLGE.TextureCamera.prototype.object=null;
  7530. GLGE.TextureCamera.prototype.camera=null;
  7531. GLGE.TextureCamera.prototype.bufferHeight=0;
  7532. GLGE.TextureCamera.prototype.bufferWidth=0;
  7533. GLGE.TextureCamera.prototype.planeOffset=0;
  7534. GLGE.TextureCamera.prototype.mirrorAxis=GLGE.NONE;
  7535. GLGE.TextureCamera.prototype.clipAxis=GLGE.NONE;
  7536. /**
  7537. * sets the RTT render clipping plane offset
  7538. * @param {number} buffer width
  7539. **/
  7540. GLGE.TextureCamera.prototype.setPlaneOffset=function(planeoffset){
  7541. this.planeOffset=planeoffset;
  7542. return this;
  7543. }
  7544. /**
  7545. * gets the RTT render clipping plane offset
  7546. * @returns the width
  7547. **/
  7548. GLGE.TextureCamera.prototype.getPlaneOffset=function(){
  7549. return this.planeOffset;
  7550. }
  7551. /**
  7552. * sets the RTT render buffer width
  7553. * @param {number} buffer width
  7554. **/
  7555. GLGE.TextureCamera.prototype.setBufferWidth=function(width){
  7556. this.bufferWidth=width;
  7557. this.update=true;
  7558. return this;
  7559. }
  7560. /**
  7561. * gets the RTT render buffer width
  7562. * @returns the width
  7563. **/
  7564. GLGE.TextureCamera.prototype.getBufferWidth=function(){
  7565. return this.bufferWidth;
  7566. }
  7567. /**
  7568. * sets the RTT render buffer height
  7569. * @param {number} buffer height
  7570. **/
  7571. GLGE.TextureCamera.prototype.setBufferHeight=function(height){
  7572. this.bufferHeight=height;
  7573. this.update=true;
  7574. return this;
  7575. }
  7576. /**
  7577. * gets the RTT render buffer height
  7578. * @returns the height
  7579. **/
  7580. GLGE.TextureCamera.prototype.getBufferHeight=function(){
  7581. return this.bufferHeight;
  7582. }
  7583. /**
  7584. * sets the RTT clip axis
  7585. * @param {number} the axis
  7586. **/
  7587. GLGE.TextureCamera.prototype.setClipAxis=function(camera){
  7588. this.clipAxis=camera;
  7589. return this;
  7590. }
  7591. /**
  7592. * gets the RTT clip axis
  7593. * @returns the axis
  7594. **/
  7595. GLGE.TextureCamera.prototype.getClipAxis=function(){
  7596. return this.clipAxis;
  7597. }
  7598. /**
  7599. * sets the RTT mirror axis
  7600. * @param {number} the axis
  7601. **/
  7602. GLGE.TextureCamera.prototype.setMirrorAxis=function(camera){
  7603. this.mirrorAxis=camera;
  7604. return this;
  7605. }
  7606. /**
  7607. * gets the RTT mirror axis
  7608. * @returns the axis
  7609. **/
  7610. GLGE.TextureCamera.prototype.getMirrorAxis=function(){
  7611. return this.mirrorAxis;
  7612. }
  7613. /**
  7614. * sets the RTT camera to use
  7615. * @param {GLGE.Camera} the source camera
  7616. **/
  7617. GLGE.TextureCamera.prototype.setCamera=function(camera){
  7618. this.camera=camera;
  7619. return this;
  7620. }
  7621. /**
  7622. * gets the RTT source camera
  7623. * @returns {GLGE.Camera} the source camera
  7624. **/
  7625. GLGE.TextureCamera.prototype.getCamera=function(){
  7626. return this.camera;
  7627. }
  7628. /**
  7629. * does what is needed to get the texture
  7630. * @private
  7631. **/
  7632. GLGE.TextureCamera.prototype.doTexture=function(gl,object){
  7633. if(this.camera){
  7634. this.gl=gl;
  7635. var modelmatrix=object.getModelMatrix();
  7636. var pmatrix=gl.scene.camera.getProjectionMatrix();
  7637. var cameramatrix=this.camera.getViewMatrix();
  7638. var matrix;
  7639. if(this.mirrorAxis){
  7640. switch(this.mirrorAxis){
  7641. case GLGE.XAXIS:
  7642. matrix=GLGE.mulMat4(GLGE.mulMat4(GLGE.mulMat4(cameramatrix,modelmatrix),GLGE.scaleMatrix(-1,1,1)),GLGE.inverseMat4(modelmatrix));
  7643. break;
  7644. case GLGE.YAXIS:
  7645. matrix=GLGE.mulMat4(GLGE.mulMat4(GLGE.mulMat4(cameramatrix,modelmatrix),GLGE.scaleMatrix(1,-1,1)),GLGE.inverseMat4(modelmatrix));
  7646. break;
  7647. case GLGE.ZAXIS:
  7648. matrix=GLGE.mulMat4(GLGE.mulMat4(GLGE.mulMat4(cameramatrix,modelmatrix),GLGE.scaleMatrix(1,1,-1)),GLGE.inverseMat4(modelmatrix));
  7649. break;
  7650. }
  7651. }else{
  7652. matrix=cameramatrix;
  7653. }
  7654. if(this.clipAxis){
  7655. var clipplane
  7656. switch(this.clipAxis){
  7657. case GLGE.NEG_XAXIS:
  7658. var dirnorm=GLGE.toUnitVec3([-modelmatrix[0],-modelmatrix[4],-modelmatrix[8]]);
  7659. clipplane=[dirnorm[0],dirnorm[1],dirnorm[2],-GLGE.dotVec3([modelmatrix[3],modelmatrix[7],modelmatrix[11]],dirnorm)-this.planeOffset];
  7660. break;
  7661. case GLGE.POS_XAXIS:
  7662. var dirnorm=GLGE.toUnitVec3([modelmatrix[0],modelmatrix[4],modelmatrix[8]]);
  7663. clipplane=[dirnorm[0],dirnorm[1],dirnorm[2],-GLGE.dotVec3([modelmatrix[3],modelmatrix[7],modelmatrix[11]],dirnorm)-this.planeOffset];
  7664. break;
  7665. case GLGE.NEG_YAXIS:
  7666. var dirnorm=GLGE.toUnitVec3([-modelmatrix[1],-modelmatrix[5],-modelmatrix[9]]);
  7667. clipplane=[dirnorm[0],dirnorm[1],dirnorm[2],-GLGE.dotVec3([modelmatrix[3],modelmatrix[7],modelmatrix[11]],dirnorm)-this.planeOffset];
  7668. break;
  7669. case GLGE.POS_YAXIS:
  7670. var dirnorm=GLGE.toUnitVec3([modelmatrix[1],modelmatrix[5],modelmatrix[9]]);
  7671. clipplane=[dirnorm[0],dirnorm[1],dirnorm[2],-GLGE.dotVec3([modelmatrix[3],modelmatrix[7],modelmatrix[11]],dirnorm)-this.planeOffset];
  7672. break;
  7673. case GLGE.NEG_ZAXIS:
  7674. var dirnorm=GLGE.toUnitVec3([-modelmatrix[2],-modelmatrix[6],-modelmatrix[10]]);
  7675. clipplane=[dirnorm[0],dirnorm[1],dirnorm[2],-GLGE.dotVec3([modelmatrix[3],modelmatrix[7],modelmatrix[11]],dirnorm)-this.planeOffset];
  7676. break;
  7677. case GLGE.POS_ZAXIS:
  7678. var dirnorm=GLGE.toUnitVec3([modelmatrix[2],modelmatrix[6],modelmatrix[10]]);
  7679. clipplane=[dirnorm[0],dirnorm[1],dirnorm[2],-GLGE.dotVec3([modelmatrix[3],modelmatrix[7],modelmatrix[11]],dirnorm)-this.planeOffset];
  7680. break;
  7681. }
  7682. var itmvp=GLGE.transposeMat4(GLGE.inverseMat4(GLGE.mulMat4(pmatrix,matrix)));
  7683. clipplane=GLGE.mulMat4Vec4(itmvp,clipplane);
  7684. clipplane=GLGE.scaleVec4(clipplane,pmatrix[10]);
  7685. clipplane[3] -= 1;
  7686. if(clipplane[2]<0) GLGE.scaleVec4(clipplane,-1);
  7687. var suffix=[ 1,0,0,0,
  7688. 0,1,0,0,
  7689. clipplane[0],clipplane[1],clipplane[2],clipplane[3],
  7690. 0,0,0,1];
  7691. pmatrix=GLGE.mulMat4(suffix,pmatrix);
  7692. }
  7693. var height=(!this.bufferHeight ? gl.scene.renderer.canvas.height : this.bufferHeight);
  7694. var width=(!this.bufferWidth ? gl.scene.renderer.canvas.width : this.bufferWidth);
  7695. //create the texture if it's not already created
  7696. if(!this.glTexture || this.update){
  7697. this.createFrameBuffer(gl);
  7698. gl.scene.addRenderPass(this.frameBuffer,matrix, gl.scene.camera.getProjectionMatrix(),width,height,object);
  7699. gl.bindTexture(gl.TEXTURE_2D, this.glTexture);
  7700. this.update=false;
  7701. return false;
  7702. }else{
  7703. gl.bindTexture(gl.TEXTURE_2D, this.glTexture);
  7704. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
  7705. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
  7706. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
  7707. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
  7708. gl.scene.addRenderPass(this.frameBuffer,matrix, pmatrix,width,height,object);
  7709. return true;
  7710. }
  7711. }else{
  7712. return false;
  7713. }
  7714. }
  7715. GLGE.TextureCamera.prototype.registerPasses=GLGE.TextureCamera.prototype.doTexture;
  7716. /**
  7717. * Creates the frame buffer for our texture
  7718. * @private
  7719. */
  7720. GLGE.TextureCamera.prototype.createFrameBuffer=function(gl){
  7721. var height=(!this.bufferHeight ? gl.scene.renderer.canvas.height : this.bufferHeight);
  7722. var width=(!this.bufferWidth ? gl.scene.renderer.canvas.width : this.bufferWidth);
  7723. if(!this.frameBuffer) this.frameBuffer = gl.createFramebuffer();
  7724. if(!this.renderBuffer) this.renderBuffer = gl.createRenderbuffer();
  7725. if(!this.glTexture) this.glTexture=gl.createTexture();
  7726. gl.bindTexture(gl.TEXTURE_2D, this.glTexture);
  7727. var tex = new Uint8Array(width*height*4);
  7728. gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width,height, 0, gl.RGBA, gl.UNSIGNED_BYTE, tex);
  7729. gl.bindFramebuffer(gl.FRAMEBUFFER, this.frameBuffer);
  7730. gl.bindRenderbuffer(gl.RENDERBUFFER, this.renderBuffer);
  7731. //dpeth stencil doesn't seem to work in either webkit or mozilla so don't use for now - reflected particles will be messed up!
  7732. //gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_STENCIL,width, height);
  7733. //gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, this.renderBuffer);
  7734. gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16,width, height);
  7735. gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, this.renderBuffer);
  7736. gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.glTexture, 0);
  7737. gl.bindRenderbuffer(gl.RENDERBUFFER, null);
  7738. gl.bindFramebuffer(gl.FRAMEBUFFER, null);
  7739. gl.bindTexture(gl.TEXTURE_2D, null);
  7740. }
  7741. })(GLGE);/*
  7742. GLGE WebGL Graphics Engine
  7743. Copyright (c) 2010, Paul Brunt
  7744. All rights reserved.
  7745. Redistribution and use in source and binary forms, with or without
  7746. modification, are permitted provided that the following conditions are met:
  7747. * Redistributions of source code must retain the above copyright
  7748. notice, this list of conditions and the following disclaimer.
  7749. * Redistributions in binary form must reproduce the above copyright
  7750. notice, this list of conditions and the following disclaimer in the
  7751. documentation and/or other materials provided with the distribution.
  7752. * Neither the name of GLGE nor the
  7753. names of its contributors may be used to endorse or promote products
  7754. derived from this software without specific prior written permission.
  7755. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  7756. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  7757. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  7758. DISCLAIMED. IN NO EVENT SHALL PAUL BRUNT BE LIABLE FOR ANY
  7759. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  7760. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  7761. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  7762. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  7763. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  7764. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  7765. */
  7766. /**
  7767. * @fileOverview
  7768. * @name glge_texturecanvas.js
  7769. * @author me@paulbrunt.co.uk
  7770. */
  7771. (function(GLGE){
  7772. /**
  7773. * @class A canvase texture to be included in a material
  7774. * @param {string} uid the unique id for this texture
  7775. * @see GLGE.Material
  7776. * @augments GLGE.QuickNotation
  7777. * @augments GLGE.JSONLoader
  7778. */
  7779. GLGE.TextureCanvas=function( uid, width, height, ID, canvas ){
  7780. if ( canvas === undefined ) {
  7781. this.canvas=document.createElement("canvas");
  7782. } else {
  7783. this.canvas = canvas;
  7784. }
  7785. //temp canvas to force chrome to update FIX ME when bug sorted!
  7786. this.t=document.createElement("canvas");
  7787. this.t.width=1;
  7788. this.t.height=1;
  7789. GLGE.Assets.registerAsset(this,uid);
  7790. this.canvas.style.display="none";
  7791. if ( ID !== undefined ) {
  7792. this.canvas.setAttribute("id",ID);
  7793. }
  7794. this.canvas.setAttribute("width", width ? width : "256" );
  7795. this.canvas.setAttribute("height", height ? height : "256" );
  7796. document.getElementsByTagName("body")[0].appendChild(this.canvas);
  7797. }
  7798. GLGE.augment(GLGE.QuickNotation,GLGE.TextureCanvas);
  7799. GLGE.augment(GLGE.JSONLoader,GLGE.TextureCanvas);
  7800. GLGE.augment(GLGE.Events,GLGE.TextureCanvas);
  7801. GLGE.TextureCanvas.prototype.className="TextureCanvas";
  7802. GLGE.TextureCanvas.prototype.glTexture=null;
  7803. GLGE.TextureCanvas.prototype.autoUpdate=true;
  7804. /**
  7805. * Gets the auto update flag
  7806. * @return {boolean} The auto update flag
  7807. */
  7808. GLGE.TextureCanvas.prototype.getAutoUpdate=function(){
  7809. return this.autoUpdate;
  7810. };
  7811. /**
  7812. * Sets the auto update flag
  7813. * @param {boolean} value The auto update flag
  7814. */
  7815. GLGE.TextureCanvas.prototype.setAutoUpdate=function(value){
  7816. this.autoUpdate=value;
  7817. return this;
  7818. };
  7819. /**
  7820. * Gets the canvas used by the texture
  7821. * @return {canvas} The textures image url
  7822. */
  7823. GLGE.TextureCanvas.prototype.getCanvas=function(){
  7824. return this.canvas;
  7825. };
  7826. /**
  7827. * Sets the canvas used by the texture
  7828. * @param {canvas} canvas The canvas to use
  7829. */
  7830. GLGE.TextureCanvas.prototype.setCanvas=function(canvas){
  7831. this.canvas=canvas;
  7832. return this;
  7833. };
  7834. /**
  7835. * Sets the canvas height
  7836. * @param {number} value The canvas height
  7837. */
  7838. GLGE.TextureCanvas.prototype.setHeight=function(value){
  7839. this.canvas.height=value;
  7840. return this;
  7841. };
  7842. /**
  7843. * Sets the canvas width
  7844. * @param {number} value The canvas width
  7845. */
  7846. GLGE.TextureCanvas.prototype.setWidth=function(value){
  7847. this.canvas.width=value;
  7848. return this;
  7849. };
  7850. /**
  7851. * gets the canvas height
  7852. * @returns {number} The canvas height
  7853. */
  7854. GLGE.TextureCanvas.prototype.getHeight=function(){
  7855. return this.canvas.height;
  7856. };
  7857. /**
  7858. * gets the canvas width
  7859. * @returns {number} The canvas width
  7860. */
  7861. GLGE.TextureCanvas.prototype.getWidth=function(){
  7862. return this.canvas.width;
  7863. };
  7864. /**
  7865. * does the canvas texture GL stuff
  7866. * @private
  7867. **/
  7868. GLGE.TextureCanvas.prototype.doTexture=function(gl){
  7869. this.gl=gl;
  7870. //create the texture if it's not already created
  7871. if(!this.glTexture){
  7872. this.glTexture=gl.createTexture();
  7873. gl.bindTexture(gl.TEXTURE_2D, this.glTexture);
  7874. this.updateCanvas(gl);
  7875. }else{
  7876. gl.bindTexture(gl.TEXTURE_2D, this.glTexture);
  7877. if(this.autoUpdate || this.doUpdate) this.updateCanvas(gl);
  7878. }
  7879. this.doUpdate=false;
  7880. return true;
  7881. }
  7882. /**
  7883. * Manually updates the canvas Texture
  7884. */
  7885. GLGE.TextureCanvas.prototype.update=function(){
  7886. this.doUpdate=true;
  7887. }
  7888. /**
  7889. * Updates the canvas texture
  7890. * @private
  7891. */
  7892. GLGE.TextureCanvas.prototype.updateCanvas=function(gl){
  7893. var canvas = this.canvas;
  7894. gl.bindTexture(gl.TEXTURE_2D, this.glTexture);
  7895. gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this.t); //force chrome to update remove when chrome bug fixed
  7896. gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, canvas);
  7897. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
  7898. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
  7899. gl.generateMipmap(gl.TEXTURE_2D);
  7900. }
  7901. })(GLGE);/*
  7902. GLGE WebGL Graphics Engine
  7903. Copyright (c) 2010, Paul Brunt
  7904. All rights reserved.
  7905. Redistribution and use in source and binary forms, with or without
  7906. modification, are permitted provided that the following conditions are met:
  7907. * Redistributions of source code must retain the above copyright
  7908. notice, this list of conditions and the following disclaimer.
  7909. * Redistributions in binary form must reproduce the above copyright
  7910. notice, this list of conditions and the following disclaimer in the
  7911. documentation and/or other materials provided with the distribution.
  7912. * Neither the name of GLGE nor the
  7913. names of its contributors may be used to endorse or promote products
  7914. derived from this software without specific prior written permission.
  7915. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  7916. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  7917. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  7918. DISCLAIMED. IN NO EVENT SHALL PAUL BRUNT BE LIABLE FOR ANY
  7919. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  7920. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  7921. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  7922. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  7923. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  7924. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  7925. */
  7926. /**
  7927. * @fileOverview
  7928. * @name glge_texturecube.js
  7929. * @author me@paulbrunt.co.uk
  7930. */
  7931. (function(GLGE){
  7932. /**
  7933. * @class A texture to be included in a material
  7934. * @param {string} uid the unique id for this texture
  7935. * @see GLGE.Material
  7936. * @augments GLGE.QuickNotation
  7937. * @augments GLGE.JSONLoader
  7938. */
  7939. GLGE.TextureCube=function(uid){
  7940. GLGE.Assets.registerAsset(this,uid);
  7941. }
  7942. GLGE.augment(GLGE.QuickNotation,GLGE.TextureCube);
  7943. GLGE.augment(GLGE.JSONLoader,GLGE.TextureCube);
  7944. GLGE.augment(GLGE.Events,GLGE.TextureCube);
  7945. GLGE.TextureCube.prototype.className="TextureCube";
  7946. GLGE.TextureCube.prototype.posX=null;
  7947. GLGE.TextureCube.prototype.negX=null;
  7948. GLGE.TextureCube.prototype.posY=null;
  7949. GLGE.TextureCube.prototype.negY=null;
  7950. GLGE.TextureCube.prototype.posZ=null;
  7951. GLGE.TextureCube.prototype.negZ=null;
  7952. GLGE.TextureCube.prototype.texture=null;
  7953. GLGE.TextureCube.prototype.glTexture=null;
  7954. GLGE.TextureCube.prototype.loadState=0;
  7955. /**
  7956. * Sets the url for a given image
  7957. * @param {string} url the texture image url
  7958. * @param {string} image the image element to load
  7959. */
  7960. GLGE.TextureCube.prototype.setSrc=function(url,image,mask){
  7961. this.url=url;
  7962. this.state=0;
  7963. this[image]=new Image();
  7964. var texture=this;
  7965. this[image].onload = function(){
  7966. texture.loadState+=mask;
  7967. }
  7968. this[image].src=url;
  7969. if(this.glTexture && this.gl) {
  7970. this.gl.deleteTexture(this.glTexture);
  7971. this.glTexture=null;
  7972. }
  7973. return this;
  7974. }
  7975. /**
  7976. * Sets the positive X cube image
  7977. * @param {string} url the texture image url
  7978. */
  7979. GLGE.TextureCube.prototype.setSrcPosX=function(url){
  7980. this.setSrc(url,"posX",1);
  7981. return this;
  7982. };
  7983. /**
  7984. * Sets the negative X cube image
  7985. * @param {string} url the texture image url
  7986. */
  7987. GLGE.TextureCube.prototype.setSrcNegX=function(url){
  7988. this.setSrc(url,"negX",2);
  7989. return this;
  7990. };
  7991. /**
  7992. * Sets the positive Y cube image
  7993. * @param {string} url the texture image url
  7994. */
  7995. GLGE.TextureCube.prototype.setSrcPosY=function(url){
  7996. this.setSrc(url,"posY",4);
  7997. return this;
  7998. };
  7999. /**
  8000. * Sets the negative Y cube image
  8001. * @param {string} url the texture image url
  8002. */
  8003. GLGE.TextureCube.prototype.setSrcNegY=function(url){
  8004. if(typeof url!="string"){
  8005. this.negY=url;
  8006. this.loadState+=8;
  8007. }else{
  8008. this.setSrc(url,"negY",8);
  8009. }
  8010. return this;
  8011. };
  8012. /**
  8013. * Sets the positive Z cube image
  8014. * @param {string} url the texture image url
  8015. */
  8016. GLGE.TextureCube.prototype.setSrcPosZ=function(url){
  8017. this.setSrc(url,"posZ",16);
  8018. return this;
  8019. };
  8020. /**
  8021. * Sets the negative Z cube image
  8022. * @param {string} url the texture image url
  8023. */
  8024. GLGE.TextureCube.prototype.setSrcNegZ=function(url){
  8025. this.setSrc(url,"negZ",32);
  8026. return this;
  8027. };
  8028. /**
  8029. * Sets the textures image location
  8030. * @private
  8031. **/
  8032. GLGE.TextureCube.prototype.doTexture=function(gl,object){
  8033. this.gl=gl;
  8034. //create the texture if it's not already created
  8035. if(!this.glTexture) this.glTexture=gl.createTexture();
  8036. //if the image is loaded then set in the texture data
  8037. gl.bindTexture(gl.TEXTURE_CUBE_MAP, this.glTexture);
  8038. if(this.loadState==63 && this.state==0){
  8039. gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this.posX);
  8040. gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this.negX);
  8041. gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this.posY);
  8042. gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this.negY);
  8043. gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this.posZ);
  8044. gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this.negZ);
  8045. gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
  8046. gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);
  8047. gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
  8048. gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
  8049. gl.generateMipmap(gl.TEXTURE_CUBE_MAP);
  8050. gl.bindTexture(gl.TEXTURE_CUBE_MAP, null);
  8051. this.state=1;
  8052. }
  8053. gl.bindTexture(gl.TEXTURE_CUBE_MAP, this.glTexture);
  8054. if(this.state==1) return true;
  8055. else return false;
  8056. }
  8057. })(GLGE);/*
  8058. GLGE WebGL Graphics Engine
  8059. Copyright (c) 2010, Paul Brunt
  8060. All rights reserved.
  8061. Redistribution and use in source and binary forms, with or without
  8062. modification, are permitted provided that the following conditions are met:
  8063. * Redistributions of source code must retain the above copyright
  8064. notice, this list of conditions and the following disclaimer.
  8065. * Redistributions in binary form must reproduce the above copyright
  8066. notice, this list of conditions and the following disclaimer in the
  8067. documentation and/or other materials provided with the distribution.
  8068. * Neither the name of GLGE nor the
  8069. names of its contributors may be used to endorse or promote products
  8070. derived from this software without specific prior written permission.
  8071. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  8072. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  8073. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  8074. DISCLAIMED. IN NO EVENT SHALL PAUL BRUNT BE LIABLE FOR ANY
  8075. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  8076. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  8077. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  8078. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  8079. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  8080. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  8081. */
  8082. /**
  8083. * @fileOverview
  8084. * @name glge_texturevideo.js
  8085. * @author me@paulbrunt.co.uk
  8086. */
  8087. (function(GLGE){
  8088. /**
  8089. * @class A video texture to be included in a material
  8090. * @param {string} uid the unique id for this texture
  8091. * @see GLGE.Material
  8092. * @augments GLGE.QuickNotation
  8093. * @augments GLGE.JSONLoader
  8094. */
  8095. GLGE.TextureVideo=function( uid, width, height, ID, video ){
  8096. if ( video === undefined ) {
  8097. this.video=document.createElement("video");
  8098. } else {
  8099. this.video = video;
  8100. }
  8101. this.video.style.display="none";
  8102. this.video.setAttribute("loop","loop");
  8103. if ( ID !== undefined ) {
  8104. this.video.setAttribute("id",ID);
  8105. }
  8106. this.video.setAttribute("width", width ? width : "256" );
  8107. this.video.setAttribute("height", height ? height : "256" );
  8108. this.video.autoplay=true;
  8109. //looping isn't working in firefox so quick fix!
  8110. this.video.addEventListener("ended", function() { this.play(); }, true);
  8111. //video needs to be part of page to work for some reason :-s
  8112. document.getElementsByTagName("body")[0].appendChild(this.video);
  8113. //used to get webkit working
  8114. this.canvas=document.createElement("canvas");
  8115. this.ctx=this.canvas.getContext("2d");
  8116. GLGE.Assets.registerAsset(this,uid);
  8117. }
  8118. GLGE.augment(GLGE.QuickNotation,GLGE.TextureVideo);
  8119. GLGE.augment(GLGE.JSONLoader,GLGE.TextureVideo);
  8120. GLGE.augment(GLGE.Events,GLGE.TextureVideo);
  8121. GLGE.TextureVideo.prototype.className="TextureVideo";
  8122. GLGE.TextureVideo.prototype.glTexture=null;
  8123. /**
  8124. * Gets the canvas used by the texture
  8125. * @return {video} The textures image url
  8126. */
  8127. GLGE.TextureVideo.prototype.getVideo=function(){
  8128. return this.video;
  8129. };
  8130. /**
  8131. * Sets the video used by the texture
  8132. * @param {video} canvas The canvas to use
  8133. */
  8134. GLGE.TextureVideo.prototype.setVideo=function(video){
  8135. this.video=video;
  8136. return this;
  8137. };
  8138. /**
  8139. * Sets the source used for the video
  8140. * @param {string} src The URL of the video
  8141. */
  8142. GLGE.TextureVideo.prototype.setSrc=function(src){
  8143. this.video.src=src;
  8144. return this;
  8145. };
  8146. /**
  8147. * gets the source used for the video
  8148. * @returns {string} The URL of the video
  8149. */
  8150. GLGE.TextureVideo.prototype.getSrc=function(src){
  8151. return this.video.src;
  8152. };
  8153. /**
  8154. * does the canvas texture GL stuff
  8155. * @private
  8156. **/
  8157. GLGE.TextureVideo.prototype.doTexture=function(gl){
  8158. this.gl=gl;
  8159. //create the texture if it's not already created
  8160. if(!this.glTexture){
  8161. this.glTexture=gl.createTexture();
  8162. gl.bindTexture(gl.TEXTURE_2D, this.glTexture);
  8163. this.updateTexture(gl);
  8164. }else{
  8165. gl.bindTexture(gl.TEXTURE_2D, this.glTexture);
  8166. this.updateTexture(gl);
  8167. }
  8168. return true;
  8169. }
  8170. /**
  8171. * Updates the canvas texture
  8172. * @private
  8173. */
  8174. GLGE.TextureVideo.prototype.updateTexture=function(gl){
  8175. var video = this.video;
  8176. gl.bindTexture(gl.TEXTURE_2D, this.glTexture);
  8177. //TODO: fix this when minefield is upto spec
  8178. if(video.readyState>0){
  8179. if(video.height<=0){
  8180. video.style.display="";
  8181. video.height=video.offsetHeight;
  8182. video.width=video.offsetWidth;
  8183. video.style.display="none";
  8184. }
  8185. this.canvas.height=video.height;
  8186. this.canvas.width=video.width;
  8187. this.ctx.drawImage(video, 0, 0);
  8188. try{gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this.canvas);}
  8189. catch(e){gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this.canvas,null);}
  8190. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
  8191. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
  8192. gl.generateMipmap(gl.TEXTURE_2D);
  8193. /*
  8194. use when video is working in webkit
  8195. try{gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, video);}
  8196. catch(e){gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, video,null);}
  8197. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
  8198. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
  8199. gl.generateMipmap(gl.TEXTURE_2D);
  8200. */
  8201. }
  8202. }
  8203. })(GLGE);/*
  8204. GLGE WebGL Graphics Engine
  8205. Copyright (c) 2010, Paul Brunt
  8206. All rights reserved.
  8207. Redistribution and use in source and binary forms, with or without
  8208. modification, are permitted provided that the following conditions are met:
  8209. * Redistributions of source code must retain the above copyright
  8210. notice, this list of conditions and the following disclaimer.
  8211. * Redistributions in binary form must reproduce the above copyright
  8212. notice, this list of conditions and the following disclaimer in the
  8213. documentation and/or other materials provided with the distribution.
  8214. * Neither the name of GLGE nor the
  8215. names of its contributors may be used to endorse or promote products
  8216. derived from this software without specific prior written permission.
  8217. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  8218. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  8219. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  8220. DISCLAIMED. IN NO EVENT SHALL PAUL BRUNT BE LIABLE FOR ANY
  8221. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  8222. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  8223. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  8224. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  8225. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  8226. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  8227. */
  8228. /**
  8229. * @fileOverview
  8230. * @name glge_lod.js
  8231. * @author me@paulbrunt.co.uk
  8232. */
  8233. (function(GLGE){
  8234. /**
  8235. * @name GLGE.ObjectLod#downloadComplete
  8236. * @event fires when all the assets for this LOD have finished loading
  8237. * @param {object} data
  8238. */
  8239. /**
  8240. * @class Creates a new load for a multimaterial
  8241. * @augments GLGE.QuickNotation
  8242. * @augments GLGE.JSONLoader
  8243. * @augments GLGE.Events
  8244. */
  8245. GLGE.ObjectLod=function(uid){
  8246. this.setMaterial(GLGE.DEFAULT_MATERIAL);
  8247. GLGE.Assets.registerAsset(this,uid);
  8248. }
  8249. GLGE.augment(GLGE.QuickNotation,GLGE.ObjectLod);
  8250. GLGE.augment(GLGE.JSONLoader,GLGE.ObjectLod);
  8251. GLGE.augment(GLGE.Events,GLGE.ObjectLod);
  8252. GLGE.ObjectLod.prototype.mesh=null;
  8253. GLGE.ObjectLod.prototype.className="ObjectLod";
  8254. GLGE.ObjectLod.prototype.material=null;
  8255. GLGE.ObjectLod.prototype.program=null;
  8256. GLGE.ObjectLod.prototype.GLShaderProgramPick=null;
  8257. GLGE.ObjectLod.prototype.GLShaderProgramShadow=null;
  8258. GLGE.ObjectLod.prototype.GLShaderProgram=null;
  8259. GLGE.ObjectLod.prototype.pixelSize=0;
  8260. /**
  8261. * sets the mesh
  8262. * @param {GLGE.Mesh} mesh
  8263. */
  8264. GLGE.ObjectLod.prototype.setMesh=function(mesh){
  8265. if(typeof mesh=="string") mesh=GLGE.Assets.get(mesh);
  8266. //remove event listener from current material
  8267. if(this.mesh){
  8268. this.mesh.removeEventListener("shaderupdate",this.meshupdated);
  8269. this.mesh.removeEventListener("boundupdate",this.boundupdated);
  8270. }
  8271. var multiMaterial=this;
  8272. this.meshupdated=function(event){
  8273. multiMaterial.GLShaderProgram=null;
  8274. };
  8275. this.boundupdated=function(event){
  8276. multiMaterial.fireEvent("boundupdate",{});
  8277. };
  8278. //set event listener for new material
  8279. mesh.addEventListener("shaderupdate",this.meshupdated);
  8280. mesh.addEventListener("boundupdate",this.boundupdated);
  8281. this.GLShaderProgram=null;
  8282. this.mesh=mesh;
  8283. return this;
  8284. }
  8285. /**
  8286. * Checks if resources have finished downloading
  8287. * @returns {boolean}
  8288. */
  8289. GLGE.ObjectLod.prototype.isComplete=function(){
  8290. return this.material.isComplete();
  8291. }
  8292. /**
  8293. * gets the mesh
  8294. * @returns {GLGE.Mesh}
  8295. */
  8296. GLGE.ObjectLod.prototype.getMesh=function(){
  8297. return this.mesh;
  8298. }
  8299. /**
  8300. * sets the material
  8301. * @param {GLGE.Material} material
  8302. */
  8303. GLGE.ObjectLod.prototype.setMaterial=function(material){
  8304. if(typeof material=="string") material=GLGE.Assets.get(material);
  8305. //remove event listener from current material
  8306. if(this.material){
  8307. this.material.removeEventListener("shaderupdate",this.materialupdated);
  8308. this.material.removeEventListener("downloadComplete",this.downloadComplete);
  8309. }
  8310. var ObjectLOD=this;
  8311. this.materialupdated=function(event){
  8312. ObjectLOD.GLShaderProgram=null;
  8313. };
  8314. //set event listener for new material
  8315. material.addEventListener("shaderupdate",this.materialupdated);
  8316. this.downloadComplete=function(){
  8317. ObjectLOD.fireEvent("downloadComplete");
  8318. };
  8319. material.addEventListener("downloadComplete",this.downloadComplete);
  8320. this.GLShaderProgram=null;
  8321. this.material=material;
  8322. return this;
  8323. }
  8324. /**
  8325. * gets the material
  8326. * @returns {GLGE.Material}
  8327. */
  8328. GLGE.ObjectLod.prototype.getMaterial=function(){
  8329. return this.material;
  8330. }
  8331. /**
  8332. * gets the pixelsize limit for this lod
  8333. * @returns {number}
  8334. */
  8335. GLGE.ObjectLod.prototype.getPixelSize=function(){
  8336. return this.pixelSize;
  8337. }
  8338. /**
  8339. * sets the pixelsize limit for this lod
  8340. * @returns {number}
  8341. */
  8342. GLGE.ObjectLod.prototype.setPixelSize=function(value){
  8343. this.pixelSize=parseFloat(value);
  8344. }
  8345. })(GLGE);/*
  8346. GLGE WebGL Graphics Engine
  8347. Copyright (c) 2010, Paul Brunt
  8348. All rights reserved.
  8349. Redistribution and use in source and binary forms, with or without
  8350. modification, are permitted provided that the following conditions are met:
  8351. * Redistributions of source code must retain the above copyright
  8352. notice, this list of conditions and the following disclaimer.
  8353. * Redistributions in binary form must reproduce the above copyright
  8354. notice, this list of conditions and the following disclaimer in the
  8355. documentation and/or other materials provided with the distribution.
  8356. * Neither the name of GLGE nor the
  8357. names of its contributors may be used to endorse or promote products
  8358. derived from this software without specific prior written permission.
  8359. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  8360. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  8361. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  8362. DISCLAIMED. IN NO EVENT SHALL PAUL BRUNT BE LIABLE FOR ANY
  8363. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  8364. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  8365. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  8366. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  8367. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  8368. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  8369. */
  8370. /**
  8371. * @fileOverview
  8372. * @name glge_object.js
  8373. * @author me@paulbrunt.co.uk
  8374. */
  8375. (function(GLGE){
  8376. /**
  8377. * @name GLGE.Object#downloadComplete
  8378. * @event fires when all the assets for this class have finished loading
  8379. * @param {object} data
  8380. */
  8381. /**
  8382. * @name GLGE.Object#willRender
  8383. * @event fires when all the assets will be rendered
  8384. * @param {object} data
  8385. */
  8386. /**
  8387. * @name GLGE.Object#willRender
  8388. * @event fires when all the assets will culled
  8389. * @param {object} data
  8390. */
  8391. /**
  8392. * @class An object that can be rendered in a scene
  8393. * @augments GLGE.Animatable
  8394. * @augments GLGE.Placeable
  8395. * @augments GLGE.QuickNotation
  8396. * @augments GLGE.JSONLoader
  8397. */
  8398. GLGE.Object=function(uid){
  8399. this.multimaterials=[];
  8400. this.renderCaches=[];
  8401. var that=this;
  8402. this.downloadComplete=function(){
  8403. if(that.isComplete()) that.fireEvent("downloadComplete");
  8404. }
  8405. GLGE.Assets.registerAsset(this,uid);
  8406. }
  8407. GLGE.augment(GLGE.Placeable,GLGE.Object);
  8408. GLGE.augment(GLGE.Animatable,GLGE.Object);
  8409. GLGE.augment(GLGE.QuickNotation,GLGE.Object);
  8410. GLGE.augment(GLGE.JSONLoader,GLGE.Object);
  8411. GLGE.Object.prototype.className="Object";
  8412. GLGE.Object.prototype.mesh=null;
  8413. GLGE.Object.prototype.skeleton=null;
  8414. GLGE.Object.prototype.scene=null;
  8415. GLGE.Object.prototype.transformMatrix=GLGE.identMatrix();
  8416. GLGE.Object.prototype.material=null;
  8417. GLGE.Object.prototype.gl=null;
  8418. GLGE.Object.prototype.multimaterials=null;
  8419. GLGE.Object.prototype.zTrans=false;
  8420. GLGE.Object.prototype.renderCaches=null;
  8421. GLGE.Object.prototype.id="";
  8422. GLGE.Object.prototype.pickable=true;
  8423. GLGE.Object.prototype.drawType=GLGE.DRAW_TRIS;
  8424. GLGE.Object.prototype.pointSize=1;
  8425. GLGE.Object.prototype.lineWidth=1;
  8426. GLGE.Object.prototype.cull=true;
  8427. GLGE.Object.prototype.culled=true;
  8428. GLGE.Object.prototype.visible=true;
  8429. GLGE.Object.prototype.depthTest=true;
  8430. GLGE.Object.prototype.meshFrame1=0;
  8431. GLGE.Object.prototype.meshFrame2=0;
  8432. GLGE.Object.prototype.meshBlendFactor=0;
  8433. GLGE.Object.prototype.noCastShadows=null;
  8434. //shadow fragment
  8435. var shfragStr=[];
  8436. shfragStr.push("#ifdef GL_ES\nprecision highp float;\n#endif\n");
  8437. shfragStr.push("uniform float distance;\n");
  8438. shfragStr.push("uniform bool shadowtype;\n");
  8439. shfragStr.push("varying vec3 eyevec;\n");
  8440. shfragStr.push("void main(void)\n ");
  8441. shfragStr.push("{\n");
  8442. shfragStr.push("float depth = gl_FragCoord.z / gl_FragCoord.w;\n");
  8443. shfragStr.push("if(shadowtype) depth=length(eyevec);\n");
  8444. shfragStr.push("vec4 rgba=fract(depth/distance * vec4(16777216.0, 65536.0, 256.0, 1.0));\n");
  8445. shfragStr.push("gl_FragColor=rgba-rgba.rrgb*vec4(0.0,0.00390625,0.00390625,0.00390625);\n");
  8446. shfragStr.push("}\n");
  8447. GLGE.Object.prototype.shfragStr=shfragStr.join("");
  8448. //normal fragment
  8449. var nfragStr=[];
  8450. nfragStr.push("#ifdef GL_ES\nprecision highp float;\n#endif\n");
  8451. nfragStr.push("varying vec3 n;\n");
  8452. nfragStr.push("void main(void)\n");
  8453. nfragStr.push("{\n");
  8454. nfragStr.push("float depth = gl_FragCoord.z / gl_FragCoord.w;\n");
  8455. nfragStr.push("gl_FragColor=vec4(normalize(n)/2.0+0.5,depth/1000.0);\n");
  8456. nfragStr.push("}\n");
  8457. GLGE.Object.prototype.nfragStr=nfragStr.join("");
  8458. //picking fragment
  8459. var pkfragStr=[];
  8460. pkfragStr.push("#ifdef GL_ES\nprecision highp float;\n#endif\n");
  8461. pkfragStr.push("uniform float far;\n");
  8462. pkfragStr.push("uniform vec3 pickcolor;\n");
  8463. pkfragStr.push("varying vec3 n;\n");
  8464. pkfragStr.push("varying vec4 UVCoord;\n");
  8465. pkfragStr.push("void main(void)\n");
  8466. pkfragStr.push("{\n");
  8467. pkfragStr.push("float Xcoord = gl_FragCoord.x+0.5;\n");
  8468. pkfragStr.push("if(Xcoord>0.0) gl_FragColor = vec4(pickcolor,1.0);\n");
  8469. pkfragStr.push("if(Xcoord>1.0) gl_FragColor = vec4(n,1.0);\n");
  8470. pkfragStr.push("if(Xcoord>2.0){");
  8471. pkfragStr.push("vec3 rgb=fract((gl_FragCoord.z/gl_FragCoord.w) * vec3(65536.0, 256.0, 1.0));\n");
  8472. pkfragStr.push("gl_FragColor=vec4(rgb-rgb.rrg*vec3(0.0,0.00390625,0.00390625),1.0);\n");
  8473. pkfragStr.push("}");
  8474. //x tex coord
  8475. pkfragStr.push("if(Xcoord>3.0){");
  8476. pkfragStr.push("vec3 rgb=fract(UVCoord.x * vec3(65536.0, 256.0, 1.0));\n");
  8477. pkfragStr.push("gl_FragColor=vec4(rgb-rgb.rrg*vec3(0.0,0.00390625,0.00390625),1.0);\n");
  8478. pkfragStr.push("}");
  8479. //y tex coord
  8480. pkfragStr.push("if(Xcoord>4.0){");
  8481. pkfragStr.push("vec3 rgb=fract(UVCoord.y * vec3(65536.0, 256.0, 1.0));\n");
  8482. pkfragStr.push("gl_FragColor=vec4(rgb-rgb.rrg*vec3(0.0,0.00390625,0.00390625),1.0);\n");
  8483. pkfragStr.push("}");
  8484. pkfragStr.push("}\n");
  8485. GLGE.Object.prototype.pkfragStr=pkfragStr.join("");
  8486. /**
  8487. * Sets the object visibility
  8488. * @param {boolean} visable flag to indicate the objects visibility
  8489. */
  8490. GLGE.Object.prototype.setVisible=function(visible){
  8491. this.visible=visible;
  8492. return this;
  8493. }
  8494. /**
  8495. * Gets the object visibility
  8496. * @returns flag to indicate the objects visibility
  8497. */
  8498. GLGE.Object.prototype.getVisible=function(){
  8499. return this.visible;
  8500. }
  8501. /**
  8502. * Sets the first mesh frame to use when using an animated mesh
  8503. * @param {boolean} frame the inital frame
  8504. */
  8505. GLGE.Object.prototype.setMeshFrame1=function(frame){
  8506. this.meshFrame1=frame;
  8507. return this;
  8508. }
  8509. /**
  8510. * Sets the second mesh frame to use when using an animated mesh
  8511. * @param {boolean} frame the final frame
  8512. */
  8513. GLGE.Object.prototype.setMeshFrame2=function(frame){
  8514. this.meshFrame2=frame;
  8515. return this;
  8516. }
  8517. /**
  8518. * blending between frames
  8519. * @param {boolean} frame value 0-1 morth between frame1 and frame2
  8520. */
  8521. GLGE.Object.prototype.setMeshBlendFactor=function(factor){
  8522. this.meshBlendFactor=factor;
  8523. return this;
  8524. }
  8525. /**
  8526. * Gets blending between frames
  8527. * @returns blender factor
  8528. */
  8529. GLGE.Object.prototype.getMeshBlendFactor=function(){
  8530. return this.meshBlendFactor;
  8531. }
  8532. /**
  8533. * Gets the pickable flag for the object
  8534. */
  8535. GLGE.Object.prototype.getPickable=function(){
  8536. return this.pickable;
  8537. }
  8538. /**
  8539. * Sets the pickable flag for the object
  8540. * @param {boolean} value the culling flag
  8541. */
  8542. GLGE.Object.prototype.setPickable=function(pickable){
  8543. this.pickable=pickable;
  8544. return this;
  8545. }
  8546. /**
  8547. * Gets the depth test flag for the object
  8548. */
  8549. GLGE.Object.prototype.getDepthTest=function(){
  8550. return this.depthTest;
  8551. }
  8552. /**
  8553. * Sets the depth test flag for the object
  8554. * @param {boolean} value the culling flag
  8555. */
  8556. GLGE.Object.prototype.setDepthTest=function(test){
  8557. this.depthTest=test;
  8558. return this;
  8559. }
  8560. /**
  8561. * Gets the culling flag for the object
  8562. */
  8563. GLGE.Object.prototype.getCull=function(){
  8564. return this.cull;
  8565. }
  8566. /**
  8567. * Sets the culling flag for the object
  8568. * @param {boolean} value the culling flag
  8569. */
  8570. GLGE.Object.prototype.setCull=function(cull){
  8571. this.cull=cull;
  8572. return this;
  8573. }
  8574. /**
  8575. * Gets the objects draw type
  8576. */
  8577. GLGE.Object.prototype.getDrawType=function(){
  8578. return this.drawType;
  8579. }
  8580. /**
  8581. * Sets the objects draw type
  8582. * @param {GLGE.number} value the draw type of this object
  8583. */
  8584. GLGE.Object.prototype.setDrawType=function(value){
  8585. this.drawType=value;
  8586. return this;
  8587. }
  8588. /**
  8589. * Gets the objects draw point size
  8590. */
  8591. GLGE.Object.prototype.getPointSize=function(){
  8592. return this.pointSize;
  8593. }
  8594. /**
  8595. * Sets the objects draw points size
  8596. * @param {GLGE.number} value the point size to render
  8597. */
  8598. GLGE.Object.prototype.setPointSize=function(value){
  8599. this.pointSize=parseFloat(value);
  8600. return this;
  8601. }
  8602. /**
  8603. * Gets the objects line width
  8604. */
  8605. GLGE.Object.prototype.getLineWidth=function(){
  8606. return this.lineWidth;
  8607. }
  8608. /**
  8609. * Sets the objects line width
  8610. * @param {GLGE.number} value the line width
  8611. */
  8612. GLGE.Object.prototype.setLineWidth=function(value){
  8613. this.lineWidth=parseFloat(value);
  8614. return this;
  8615. }
  8616. /**
  8617. * Sets a custom usinform on this object
  8618. * @param {string} type the uniform type eg 1i, 3fv, Matrix4fv, etc
  8619. * @param {string} name the uniform name
  8620. * @param {array} value the value of the uniform
  8621. */
  8622. GLGE.Object.prototype.setUniform=function(type,name,value){
  8623. if(!this.uniforms) this.uniforms={};
  8624. this.uniforms[name]={type:type,value:value};
  8625. }
  8626. /**
  8627. * Gets the value of a custom uniform
  8628. * @param {string} name the name of the uniform to return
  8629. * @returns {number} the value of the uniform
  8630. */
  8631. GLGE.Object.prototype.getUniform=function(name){
  8632. if(!this.uniforms) this.uniforms={};
  8633. return this.uniforms[name].value
  8634. }
  8635. /**
  8636. * Gets the type of a custom uniform
  8637. * @param {string} name the name of the uniform to return
  8638. * @returns {number} the type of the uniform
  8639. */
  8640. GLGE.Object.prototype.getUniformType=function(name){
  8641. if(!this.uniforms) this.uniforms={};
  8642. return this.uniforms[name].type;
  8643. }
  8644. /**
  8645. * Sets the code to inject into the vertex shader
  8646. * @param {string} shader the glsl code to inject into the vertex shader of this object GLGE will call the function GLGE_Position(vec4 position) to modify the position
  8647. */
  8648. GLGE.Object.prototype.setVertexShaderInjection=function(shader){
  8649. this.shaderVertexInjection=shader;
  8650. this.updateProgram();
  8651. return this;
  8652. }
  8653. /**
  8654. * Gets the glsl code injected into the vertex shader of this object
  8655. * @returns {string} shader the glsl code injected into the vertex shader of this object
  8656. */
  8657. GLGE.Object.prototype.getVertexShaderInjection=function(shader){
  8658. return this.shaderVertexInjection;
  8659. }
  8660. /**
  8661. * Gets the objects skeleton
  8662. * @returns GLGE.Group
  8663. */
  8664. GLGE.Object.prototype.getSkeleton=function(){
  8665. return this.skeleton;
  8666. }
  8667. /**
  8668. * Sets the objects skeleton
  8669. * @param {GLGE.Group} value the skeleton group to set
  8670. */
  8671. GLGE.Object.prototype.setSkeleton=function(value){
  8672. this.skeleton=value;
  8673. this.bones=null;
  8674. return this;
  8675. }
  8676. GLGE.Object.prototype.getBoundingVolume=function(local){
  8677. if(!local) local=0;
  8678. if(!this.boundingVolume) this.boundingVolume=[];
  8679. if(!this.boundmatrix) this.boundmatrix=[];
  8680. var matrix=this.getModelMatrix();
  8681. if(matrix!=this.boundmatrix[local] || !this.boundingVolume[local]){
  8682. var multimaterials=this.multimaterials;
  8683. var boundingVolume;
  8684. for(var i=0;i<multimaterials.length;i++){
  8685. if(multimaterials[i].lods[0].mesh){
  8686. if(!boundingVolume){
  8687. boundingVolume=multimaterials[i].lods[0].mesh.getBoundingVolume().clone();
  8688. }else{
  8689. boundingVolume.addBoundingVolume(multimaterials[i].lods[0].mesh.getBoundingVolume());
  8690. }
  8691. }
  8692. }
  8693. if(!boundingVolume) boundingVolume=new GLGE.BoundingVolume(0,0,0,0,0,0);
  8694. if(local){
  8695. boundingVolume.applyMatrix(this.getLocalMatrix());
  8696. }else{
  8697. boundingVolume.applyMatrix(this.getModelMatrix());
  8698. }
  8699. this.boundingVolume[local]=boundingVolume;
  8700. }
  8701. this.boundmatrix[local]=matrix;
  8702. return this.boundingVolume[local];
  8703. }
  8704. /**
  8705. * Sets the the show casting flag
  8706. * @param {boolean} value cast or not
  8707. */
  8708. GLGE.Object.prototype.setCastShadows=function(value){
  8709. this.noCastShadows=!value;
  8710. return this;
  8711. }
  8712. /**
  8713. * Gets the the show casting flag
  8714. * @returns boolean
  8715. */
  8716. GLGE.Object.prototype.getCastShadows=function(){
  8717. return !this.noCastShadows;
  8718. }
  8719. /**
  8720. * Sets the Z Transparency of this object
  8721. * @param {boolean} value Does this object need blending?
  8722. */
  8723. GLGE.Object.prototype.setZtransparent=function(value){
  8724. this.zTrans=value;
  8725. return this;
  8726. }
  8727. /**
  8728. * Gets the z transparency
  8729. * @returns boolean
  8730. */
  8731. GLGE.Object.prototype.isZtransparent=function(){
  8732. return this.zTrans;
  8733. }
  8734. /**
  8735. * Checks if resources have finished downloading
  8736. * @returns {boolean}
  8737. */
  8738. GLGE.Object.prototype.isComplete=function(){
  8739. for(var i=0;i<this.multimaterials.length;i++){
  8740. if(!this.multimaterials[i].isComplete()) return false;
  8741. }
  8742. return true;
  8743. }
  8744. /**
  8745. * Sets the material associated with the object
  8746. * @param GLGE.Material
  8747. */
  8748. GLGE.Object.prototype.setMaterial=function(material,idx){
  8749. if(typeof material=="string") material=GLGE.Assets.get(material);
  8750. if(!idx) idx=0;
  8751. if(!this.multimaterials[idx]){
  8752. this.multimaterials[idx]=new GLGE.MultiMaterial();
  8753. this.multimaterials[idx].addEventListener("downloadComplete",this.downloadComplete);
  8754. }
  8755. if(this.multimaterials[idx].getMaterial()!=material){
  8756. this.multimaterials[idx].setMaterial(material);
  8757. this.updateProgram();
  8758. }
  8759. return this;
  8760. }
  8761. /**
  8762. * Gets the material associated with the object
  8763. * @returns GLGE.Material
  8764. */
  8765. GLGE.Object.prototype.getMaterial=function(idx){
  8766. if(!idx) idx=0;
  8767. if(this.multimaterials[idx]) {
  8768. return this.multimaterials[idx].getMaterial();
  8769. }else{
  8770. return false;
  8771. }
  8772. }
  8773. /**
  8774. * Sets the mesh associated with the object
  8775. * @param GLGE.Mesh
  8776. */
  8777. GLGE.Object.prototype.setMesh=function(mesh,idx){
  8778. if(typeof mesh=="string") mesh=GLGE.Assets.get(mesh);
  8779. if(!idx) idx=0;
  8780. if(!this.multimaterials[idx]){
  8781. var object=this;
  8782. this.multimaterials[idx]=new GLGE.MultiMaterial();
  8783. this.multimaterials[idx].addEventListener("downloadComplete",this.downloadComplete);
  8784. this.multimaterials[idx].addEventListener("boundupdate",function(){object.boundingVolume=null});
  8785. }
  8786. this.multimaterials[idx].setMesh(mesh);
  8787. this.boundingVolume=null;
  8788. return this;
  8789. }
  8790. /**
  8791. * Gets the mesh associated with the object
  8792. * @returns GLGE.Mesh
  8793. */
  8794. GLGE.Object.prototype.getMesh=function(idx){
  8795. if(!idx) idx=0;
  8796. if(this.multimaterials[idx]) {
  8797. return this.multimaterials[idx].getMesh();
  8798. }else{
  8799. return false;
  8800. }
  8801. }
  8802. /**
  8803. * Initiallize all the GL stuff needed to render to screen
  8804. * @private
  8805. */
  8806. GLGE.Object.prototype.GLInit=function(gl){
  8807. this.gl=gl;
  8808. }
  8809. /**
  8810. * Cleans up all the GL stuff we sets
  8811. * @private
  8812. */
  8813. GLGE.Object.prototype.GLDestory=function(gl){
  8814. }
  8815. /**
  8816. * Updates the GL shader program for the object
  8817. * @private
  8818. */
  8819. GLGE.Object.prototype.updateProgram=function(){
  8820. for(var i=0; i<this.multimaterials.length;i++){
  8821. this.multimaterials[i].updateProgram();
  8822. }
  8823. }
  8824. /**
  8825. * Adds another material to this object
  8826. * @returns GLGE.Material
  8827. */
  8828. GLGE.Object.prototype.addMultiMaterial=function(multimaterial){
  8829. if(typeof multimaterial=="string") multimaterial=GLGE.Assets.get(multimaterial);
  8830. this.multimaterials.push(multimaterial);
  8831. multimaterial.addEventListener("downloadComplete",this.downloadComplete);
  8832. var object=this;
  8833. multimaterial.addEventListener("boundupdate",function(){object.boundingVolume=null});
  8834. this.boundingVolume=null;
  8835. return this;
  8836. }
  8837. /**
  8838. * gets all of the objects materials and meshes
  8839. * @returns array of GLGE.MultiMaterial objects
  8840. */
  8841. GLGE.Object.prototype.getMultiMaterials=function(){
  8842. return this.multimaterials;
  8843. }
  8844. /**
  8845. * Creates the shader program for the object
  8846. * @private
  8847. */
  8848. GLGE.Object.prototype.GLGenerateShader=function(gl){
  8849. //create the programs strings
  8850. //Vertex Shader
  8851. var colors=UV=joints1=joints2=false;
  8852. var lights=gl.lights;
  8853. var vertexStr=["#define GLGE_VERTEX\n"];
  8854. var tangent=false;
  8855. if(!this.mesh.normals) this.mesh.calcNormals();
  8856. vertexStr.push("attribute vec3 position;\n");
  8857. vertexStr.push("attribute vec3 normal;\n");
  8858. for(var i=0;i<this.mesh.buffers.length;i++){
  8859. if(this.mesh.buffers[i].name=="tangent0") tangent=true;
  8860. if(this.mesh.buffers[i].exclude) continue;
  8861. if(this.mesh.buffers[i].size>1){
  8862. vertexStr.push("attribute vec"+this.mesh.buffers[i].size+" "+this.mesh.buffers[i].name+";\n");
  8863. }else{
  8864. vertexStr.push("attribute float "+this.mesh.buffers[i].name+";\n");
  8865. }
  8866. if(this.mesh.buffers[i].name=="UV") UV=true;
  8867. if(this.mesh.buffers[i].name=="color") colors=true;
  8868. if(this.mesh.buffers[i].name=="joints1") joints1=this.mesh.buffers[i];
  8869. if(this.mesh.buffers[i].name=="joints2") joints2=this.mesh.buffers[i];
  8870. }
  8871. if(this.mesh.framePositions.length>1){
  8872. var morph=true;
  8873. vertexStr.push("attribute vec3 position2;\n");
  8874. vertexStr.push("attribute vec3 normal2;\n");
  8875. vertexStr.push("uniform float framesBlend;\n");
  8876. if(tangent) vertexStr.push("attribute vec3 tangent2;\n");
  8877. }
  8878. if(tangent) vertexStr.push("attribute vec3 tangent;\n");
  8879. vertexStr.push("uniform mat4 worldView;\n");
  8880. vertexStr.push("uniform mat4 projection;\n");
  8881. vertexStr.push("uniform mat4 worldInverseTranspose;\n");
  8882. vertexStr.push("uniform mat4 envMat;\n");
  8883. //vertexStr.push("uniform vec3 cameraPos;\n");
  8884. vertexStr.push("uniform float cascadeLevel;\n");
  8885. for(var i=0; i<lights.length;i++){
  8886. if(lights[i].type==GLGE.L_OFF) continue;
  8887. vertexStr.push("uniform vec3 lightpos"+i+";\n");
  8888. vertexStr.push("uniform vec3 lightdir"+i+";\n");
  8889. if((lights[i].type==GLGE.L_SPOT || lights[i].type==GLGE.L_DIR) && lights[i].getCastShadows() ){
  8890. vertexStr.push("uniform mat4 lightmat"+i+";\n");
  8891. vertexStr.push("varying vec4 spotcoord"+i+";\n");
  8892. }
  8893. }
  8894. vertexStr.push("varying vec3 eyevec;\n");
  8895. for(var i=0; i<lights.length;i++){
  8896. if(lights[i].type==GLGE.L_OFF) continue;
  8897. vertexStr.push("varying vec3 lightvec"+i+";\n");
  8898. vertexStr.push("varying float lightdist"+i+";\n");
  8899. }
  8900. if(this.mesh.joints && this.mesh.joints.length>0){
  8901. vertexStr.push("uniform vec4 jointMat["+(3*this.mesh.joints.length)+"];\n");
  8902. }
  8903. if(this.material) vertexStr.push(this.material.getVertexVarying(vertexStr));
  8904. vertexStr.push("varying vec3 n;\n");
  8905. vertexStr.push("varying vec3 t;\n");
  8906. if(colors) vertexStr.push("varying vec4 vcolor;\n");
  8907. vertexStr.push("varying vec4 UVCoord;\n");
  8908. vertexStr.push("varying vec3 OBJCoord;\n");
  8909. if(this.shaderVertexInjection){
  8910. vertexStr.push(this.shaderVertexInjection);
  8911. }
  8912. vertexStr.push("void main(void)\n");
  8913. vertexStr.push("{\n");
  8914. if(colors) vertexStr.push("vcolor=color;\n");
  8915. if(UV) vertexStr.push("UVCoord=UV;\n");
  8916. else vertexStr.push("UVCoord=vec4(0.0,0.0,0.0,0.0);\n");
  8917. vertexStr.push("OBJCoord = position;\n");
  8918. vertexStr.push("vec3 tang;\n");
  8919. vertexStr.push("vec4 pos = vec4(0.0, 0.0, 0.0, 1.0);\n");
  8920. vertexStr.push("vec4 norm = vec4(0.0, 0.0, 0.0, 1.0);\n");
  8921. if(tangent) vertexStr.push("vec4 tang4 = vec4(0.0, 0.0, 0.0, 1.0);\n");
  8922. if(joints1){
  8923. if(joints1.size==1){
  8924. vertexStr.push("pos += vec4(dot(jointMat[int(3.0*joints1)],vec4(position,1.0)),\n"+
  8925. " dot(jointMat[int(3.0*joints1+1.0)],vec4(position,1.0)),\n"+
  8926. " dot(jointMat[int(3.0*joints1+2.0)],vec4(position,1.0)),1.0)*weights1;\n");
  8927. vertexStr.push("norm += vec4(dot(jointMat[int(3.0*joints1)].xyz,normal),\n"+
  8928. " dot(jointMat[int(3.0*joints1+1.0)].xyz,normal),\n"+
  8929. " dot(jointMat[int(3.0*joints1+2.0)].xyz,normal),1.0)*weights1;\n");
  8930. if (tangent)
  8931. vertexStr.push("tang4 += vec4(dot(jointMat[int(3.0*joints1)].xyz,tangent),\n"+
  8932. " dot(jointMat[int(3.0*joints1+1.0)].xyz,tangent),\n"+
  8933. " dot(jointMat[int(3.0*joints1+2.0)].xyz,tangent),1.0)*weights1;\n");
  8934. }else{
  8935. for(var i=0;i<joints1.size;i++){
  8936. vertexStr.push("pos += vec4(dot(jointMat[int(3.0*joints1["+i+"])],vec4(position,1.0)),\n"+
  8937. " dot(jointMat[int(3.0*joints1["+i+"]+1.0)],vec4(position,1.0)),\n"+
  8938. " dot(jointMat[int(3.0*joints1["+i+"]+2.0)],vec4(position,1.0)),1.0)*weights1["+i+"];\n");
  8939. vertexStr.push("norm += vec4(dot(jointMat[int(3.0*joints1["+i+"])].xyz,normal),\n"+
  8940. " dot(jointMat[int(3.0*joints1["+i+"]+1.0)].xyz,normal),\n"+
  8941. " dot(jointMat[int(3.0*joints1["+i+"]+2.0)].xyz,normal),1.0)*weights1["+i+"];\n");
  8942. if (tangent)
  8943. vertexStr.push("tang4 += vec4(dot(jointMat[int(3.0*joints1["+i+"])].xyz,tangent),\n"+
  8944. " dot(jointMat[int(3.0*joints1["+i+"]+1.0)].xyz,tangent),\n"+
  8945. " dot(jointMat[int(3.0*joints1["+i+"]+2.0)].xyz,tangent),1.0)*weights1["+i+"];\n");
  8946. }
  8947. }
  8948. if(joints2){
  8949. if(joints2.size==1){
  8950. vertexStr.push("pos += vec4(dot(jointMat[int(3.0*joints2)],vec4(position,1.0)),\n"+
  8951. " dot(jointMat[int(3.0*joints2+1.0)],vec4(position,1.0)),\n"+
  8952. " dot(jointMat[int(3.0*joints2+2.0)],vec4(position,1.0)),1.0)*weights2;\n");
  8953. vertexStr.push("norm += vec4(dot(jointMat[int(3.0*joints2)].xyz,normal),\n"+
  8954. " dot(jointMat[int(3.0*joints2+1.0)].xyz,normal),\n"+
  8955. " dot(jointMat[int(3.0*joints2+2.0)].xyz,normal),1.0)*weights2;\n");
  8956. if (tangent)
  8957. vertexStr.push("tang4 += vec4(dot(jointMat[int(3.0*joints2)].xyz,tangent),\n"+
  8958. " dot(jointMat[int(3.0*joints2+1.0)].xyz,tangent),\n"+
  8959. " dot(jointMat[int(3.0*joints2+2.0)].xyz,tangent),1.0)*weights2;\n");
  8960. }else{
  8961. for(var i=0;i<joints2.size;i++){
  8962. vertexStr.push("pos += vec4(dot(jointMat[int(3.0*joints2["+i+"])],vec4(position,1.0)),\n"+
  8963. " dot(jointMat[int(3.0*joints2["+i+"]+1.0)],vec4(position,1.0)),\n"+
  8964. " dot(jointMat[int(3.0*joints2["+i+"]+2.0)],vec4(position,1.0)),1.0)*weights2["+i+"];\n");
  8965. vertexStr.push("norm += vec4(dot(jointMat[int(3.0*joints2["+i+"])].xyz,normal),\n"+
  8966. " dot(jointMat[int(3.0*joints2["+i+"]+1.0)].xyz,normal),\n"+
  8967. " dot(jointMat[int(3.0*joints2["+i+"]+2.0)].xyz,normal),1.0)*weights2["+i+"];\n");
  8968. if (tangent)
  8969. vertexStr.push("tang4 += vec4(dot(jointMat[int(3.0*joints2["+i+"])].xyz,tangent),\n"+
  8970. " dot(jointMat[int(3.0*joints2["+i+"]+1.0)].xyz,tangent),\n"+
  8971. " dot(jointMat[int(3.0*joints2["+i+"]+2.0)].xyz,tangent),1.0)*weights2["+i+"];\n");
  8972. }
  8973. }
  8974. }
  8975. for(var i=0; i<lights.length;i++){
  8976. if(lights[i].type==GLGE.L_OFF) continue;
  8977. if((lights[i].type==GLGE.L_SPOT || lights[i].type==GLGE.L_DIR) && lights[i].getCastShadows() ){
  8978. vertexStr.push("spotcoord"+i+"=lightmat"+i+"*vec4(pos.xyz,1.0);\n");
  8979. }
  8980. }
  8981. if(this.shaderVertexInjection && this.shaderVertexInjection.indexOf("GLGE_Position")>-1){
  8982. vertexStr.push("pos=GLGE_Position(vec4(pos.xyz, 1.0));\n");
  8983. }
  8984. vertexStr.push("pos = worldView * vec4(pos.xyz, 1.0);\n");
  8985. vertexStr.push("norm = worldInverseTranspose * vec4(norm.xyz, 1.0);\n");
  8986. if(tangent) vertexStr.push("tang = (worldInverseTranspose*vec4(tang4.xyz,1.0)).xyz;\n");
  8987. }else{
  8988. if(morph){
  8989. vertexStr.push("vec4 pos4=vec4(mix(position,position2,framesBlend),1.0);\n");
  8990. }else{
  8991. vertexStr.push("vec4 pos4=vec4(position,1.0);\n");
  8992. }
  8993. if(this.shaderVertexInjection && this.shaderVertexInjection.indexOf("GLGE_Position")>-1){
  8994. vertexStr.push("pos4=GLGE_Position(pos4);\n");
  8995. }
  8996. //vertexStr.push("pos4.xyz = (pos4.xyz-cameraPos.xyz)/(pow(length(pos4.xyz-cameraPos.xyz),0.5))+cameraPos.xyz;\n");
  8997. for(var i=0; i<lights.length;i++){
  8998. if(lights[i].type==GLGE.L_OFF) continue;
  8999. if((lights[i].type==GLGE.L_SPOT || lights[i].type==GLGE.L_DIR) && lights[i].getCastShadows() ){
  9000. vertexStr.push("spotcoord"+i+"=lightmat"+i+"*pos4;\n");
  9001. //vertexStr.push("spotcoord"+i+".w/=2.0;\n");
  9002. }
  9003. }
  9004. vertexStr.push("pos = worldView * pos4;\n");
  9005. if(morph){
  9006. vertexStr.push("norm = worldInverseTranspose * vec4(mix(normal,normal2,framesBlend), 1.0);\n");
  9007. if(tangent) vertexStr.push("tang = (worldInverseTranspose*vec4(mix(tangent,tangent2,framesBlend),1.0)).xyz;\n");
  9008. }else{
  9009. vertexStr.push("norm = worldInverseTranspose * vec4(normal, 1.0);\n");
  9010. if(tangent) vertexStr.push("tang = (worldInverseTranspose*vec4(tangent,1.0)).xyz;\n");
  9011. }
  9012. }
  9013. vertexStr.push("eyevec = -pos.xyz;\n");
  9014. if(tangent) vertexStr.push("t = normalize(tang);");
  9015. else vertexStr.push("t = vec3(0.0,0.0,0.0);");
  9016. vertexStr.push("n = normalize(norm.rgb);");
  9017. for(var i=0; i<lights.length;i++){
  9018. if(lights[i].type==GLGE.L_OFF) continue;
  9019. if(lights[i].getType()==GLGE.L_DIR){
  9020. vertexStr.push("lightvec"+i+" = -lightdir"+i+";\n");
  9021. }else{
  9022. vertexStr.push("lightvec"+i+" = pos.xyz-lightpos"+i+";\n");
  9023. }
  9024. vertexStr.push("lightdist"+i+" = length(lightpos"+i+".xyz-pos.xyz);\n");
  9025. }
  9026. if(this.material) vertexStr.push(this.material.getLayerCoords(this.shaderVertexInjection));
  9027. vertexStr.push("gl_Position = projection * pos;\n");
  9028. vertexStr.push("gl_PointSize="+(this.pointSize.toFixed(5))+";\n");
  9029. vertexStr.push("}\n");
  9030. vertexStr=vertexStr.join("");
  9031. //Fragment Shader
  9032. fragStr=this.material.getFragmentShader(lights,colors,this.shaderVertexInjection);
  9033. this.GLFragmentShaderNormal=GLGE.getGLShader(gl,gl.FRAGMENT_SHADER,this.nfragStr);
  9034. this.GLFragmentShaderShadow=GLGE.getGLShader(gl,gl.FRAGMENT_SHADER,this.shfragStr);
  9035. this.GLFragmentShaderPick=GLGE.getGLShader(gl,gl.FRAGMENT_SHADER,this.pkfragStr);
  9036. this.GLFragmentShader=GLGE.getGLShader(gl,gl.FRAGMENT_SHADER,fragStr);
  9037. this.GLVertexShader=GLGE.getGLShader(gl,gl.VERTEX_SHADER,vertexStr+"//default");
  9038. this.GLVertexShaderShadow=GLGE.getGLShader(gl,gl.VERTEX_SHADER,vertexStr+"//shadow");
  9039. this.GLVertexShaderPick=GLGE.getGLShader(gl,gl.VERTEX_SHADER,vertexStr+"//pick");
  9040. this.GLVertexShaderNormal=GLGE.getGLShader(gl,gl.VERTEX_SHADER,vertexStr+"//normal");
  9041. this.GLShaderProgramPick=GLGE.getGLProgram(gl,this.GLVertexShaderPick,this.GLFragmentShaderPick);
  9042. this.GLShaderProgramNormal=GLGE.getGLProgram(gl,this.GLVertexShaderNormal,this.GLFragmentShaderNormal);
  9043. this.GLShaderProgramShadow=GLGE.getGLProgram(gl,this.GLVertexShaderShadow,this.GLFragmentShaderShadow);
  9044. this.GLShaderProgram=GLGE.getGLProgram(gl,this.GLVertexShaderShadow,this.GLFragmentShader);
  9045. //if we failed then check for fallback option
  9046. if (!gl.getProgramParameter(this.GLShaderProgram, gl.LINK_STATUS)) {
  9047. if(this.material.fallback){
  9048. this.material=this.material.fallback;
  9049. this.multimaterial.material=this.material;
  9050. this.GLGenerateShader(gl);
  9051. }
  9052. }
  9053. }
  9054. /**
  9055. * creates shader programs;
  9056. * @param multimaterial the multimaterial object to create the shader programs for
  9057. * @private
  9058. */
  9059. GLGE.Object.prototype.createShaders=function(multimaterial){
  9060. if(this.gl){
  9061. this.mesh=multimaterial.mesh;
  9062. this.material=multimaterial.material;
  9063. this.multimaterial=multimaterial;
  9064. this.GLGenerateShader(this.gl);
  9065. multimaterial.GLShaderProgramPick=this.GLShaderProgramPick;
  9066. multimaterial.GLShaderProgramShadow=this.GLShaderProgramShadow;
  9067. multimaterial.GLShaderProgram=this.GLShaderProgram;
  9068. }
  9069. }
  9070. /**
  9071. * Sets the shader program uniforms ready for rendering
  9072. * @private
  9073. */
  9074. GLGE.Object.prototype.GLUniforms=function(gl,renderType,pickindex){
  9075. var program;
  9076. switch(renderType){
  9077. case GLGE.RENDER_DEFAULT:
  9078. program=this.GLShaderProgram;
  9079. GLGE.setUniform(gl,"1i",GLGE.getUniformLocation(gl,program, "emitpass"), 0);
  9080. break;
  9081. case GLGE.RENDER_EMIT:
  9082. program=this.GLShaderProgram;
  9083. GLGE.setUniform(gl,"1i",GLGE.getUniformLocation(gl,program, "emitpass"), 1);
  9084. break;
  9085. case GLGE.RENDER_SHADOW:
  9086. program=this.GLShaderProgramShadow;
  9087. GLGE.setUniform(gl,"1i",GLGE.getUniformLocation(gl,program, "shadowtype"), 1);
  9088. break;
  9089. case GLGE.RENDER_DEPTH:
  9090. program=this.GLShaderProgramShadow;
  9091. GLGE.setUniform(gl,"1f",GLGE.getUniformLocation(gl,program, "cascadeLevel"), 2);
  9092. GLGE.setUniform(gl,"1i",GLGE.getUniformLocation(gl,program, "shadowtype"), 0);
  9093. break;
  9094. case GLGE.RENDER_NORMAL:
  9095. program=this.GLShaderProgramNormal;
  9096. break;
  9097. case GLGE.RENDER_PICK:
  9098. program=this.GLShaderProgramPick;
  9099. var b = pickindex >> 16 & 0xFF;
  9100. var g = pickindex >> 8 & 0xFF;
  9101. var r = pickindex & 0xFF;
  9102. GLGE.setUniform3(gl,"3f",GLGE.getUniformLocation(gl,program, "pickcolor"), r/255,g/255,b/255);
  9103. break;
  9104. }
  9105. //set the line width
  9106. gl.lineWidth(this.lineWidth);
  9107. //set custom uinforms
  9108. for(var key in this.uniforms){
  9109. var uniform=this.uniforms[key];
  9110. if(uniform.type=="Matrix4fv"){
  9111. GLGE.setUniformMatrix(gl,"Matrix4fv",GLGE.getUniformLocation(gl,program, key),false,uniform.value);
  9112. }else{
  9113. GLGE.setUniform(gl,uniform.type,GLGE.getUniformLocation(gl,program, key),uniform.value);
  9114. }
  9115. }
  9116. if(!program.caches) program.caches={};
  9117. if(!program.glarrays) program.glarrays={};
  9118. var pc=program.caches;
  9119. var pgl=program.glarrays;
  9120. var scene=gl.scene;
  9121. var camera=scene.camera;
  9122. if(pc.far!=camera.far){
  9123. GLGE.setUniform(gl,"1i",GLGE.getUniformLocation(gl,program, "far"), camera.far);
  9124. pc.far=camera.far;
  9125. }
  9126. if(renderType==GLGE.RENDER_DEFAULT || renderType==GLGE.RENDER_EMIT){
  9127. if(pc.ambientColor!=scene.ambientColor){
  9128. var ambientColor=scene.ambientColor;
  9129. GLGE.setUniform3(gl,"3f",GLGE.getUniformLocation(gl,program, "amb"), ambientColor.r,ambientColor.g,ambientColor.b);
  9130. pc.ambientColor=ambientColor;
  9131. }
  9132. if(pc.fogFar!=scene.fogFar){
  9133. GLGE.setUniform(gl,"1f",GLGE.getUniformLocation(gl,program, "fogfar"), scene.fogFar);
  9134. pc.fogFar=scene.fogFar;
  9135. }
  9136. if(pc.fogNear!=scene.fogNear){
  9137. GLGE.setUniform(gl,"1f",GLGE.getUniformLocation(gl,program, "fognear"), scene.fogNear);
  9138. pc.fogNear=scene.fogNear;
  9139. }
  9140. if(pc.fogType!=scene.fogType){
  9141. GLGE.setUniform(gl,"1i",GLGE.getUniformLocation(gl,program, "fogtype"), scene.fogType);
  9142. pc.fogType=scene.fogType;
  9143. }
  9144. if(pc.fogType!=scene.fogcolor){
  9145. GLGE.setUniform3(gl,"3f",GLGE.getUniformLocation(gl,program, "fogcolor"), scene.fogColor.r,scene.fogColor.g,scene.fogColor.b);
  9146. pc.fogcolor=scene.fogcolor;
  9147. }
  9148. }
  9149. if(pc.meshBlendFactor!=this.meshBlendFactor){
  9150. GLGE.setUniform(gl,"1f",GLGE.getUniformLocation(gl,program, "framesBlend"), this.meshBlendFactor);
  9151. pc.meshBlendFactor=this.meshBlendFactor;
  9152. }
  9153. var cameraMatrix=camera.getViewMatrix();
  9154. var objMatrix=modelMatrix=this.getModelMatrix();
  9155. if(!pc.mvMatrix) pc.mvMatrix={cameraMatrix:null,modelMatrix:null};
  9156. var mvCache=pc.mvMatrix;
  9157. if(mvCache.cameraMatrix!=cameraMatrix || mvCache.modelMatrix!=modelMatrix){
  9158. //generate and set the modelView matrix
  9159. if(!this.caches.mvMatrix) this.caches.mvMatrix=GLGE.mulMat4(cameraMatrix,modelMatrix);
  9160. mvMatrix=this.caches.mvMatrix;
  9161. if(this.mesh.joints){
  9162. mvMatrix=cameraMatrix;
  9163. }
  9164. //GLGE.setUniform3(gl,"3f",GLGE.getUniformLocation(gl,program, "cameraPos"),camera.location[0],camera.location[1],camera.location[2]);
  9165. var mvUniform = GLGE.getUniformLocation(gl,program, "worldView");
  9166. var M1=GLGE.transposeMat4(mvMatrix);
  9167. if(!pgl.mvMatrix){
  9168. pgl.mvMatrixT=new Float32Array(M1);
  9169. }else{
  9170. GLGE.mat4gl(M1,pgl.mvMatrixT);
  9171. }
  9172. //GLGE.reuseMatrix4(M1);
  9173. pgl.mvMatrix=mvMatrix;
  9174. GLGE.setUniformMatrix(gl,"Matrix4fv",mvUniform, false, program.glarrays.mvMatrixT);
  9175. //invCamera matrix
  9176. var icUniform = GLGE.getUniformLocation(gl,program, "envMat");
  9177. if(icUniform){
  9178. if(!this.caches.envMat){
  9179. var envMat = GLGE.inverseMat4(mvMatrix);
  9180. envMat[3]=0;
  9181. envMat[7]=0;
  9182. envMat[11]=0;
  9183. this.caches.envMat = envMat;
  9184. }
  9185. envMat=this.caches.envMat;
  9186. M1=GLGE.transposeMat4(envMat);
  9187. if(!program.glarrays.envMat){
  9188. pgl.envMatT=new Float32Array(M1);
  9189. }else{
  9190. GLGE.mat4gl(M1,pgl.envMatT);
  9191. }
  9192. //GLGE.reuseMatrix4(M1);
  9193. pgl.envMat=envMat;
  9194. GLGE.setUniformMatrix(gl,"Matrix4fv",icUniform, false, pgl.envMatT);
  9195. }
  9196. //normalising matrix
  9197. if(!this.caches.normalMatrix){
  9198. var normalMatrix = GLGE.inverseMat4(mvMatrix);
  9199. this.caches.normalMatrix = normalMatrix;
  9200. }
  9201. normalMatrix=this.caches.normalMatrix;
  9202. var nUniform = GLGE.getUniformLocation(gl,program, "worldInverseTranspose");
  9203. if(!pgl.normalMatrix) pgl.normalMatrix=new Float32Array(normalMatrix);
  9204. else GLGE.mat4gl(normalMatrix,pgl.normalMatrix);
  9205. GLGE.setUniformMatrix(gl,"Matrix4fv",nUniform, false, pgl.normalMatrix);
  9206. var cUniform = GLGE.getUniformLocation(gl,program, "view");
  9207. M1=GLGE.transposeMat4(cameraMatrix);
  9208. if(!pgl.cameraMatrix){
  9209. pgl.cameraMatrixT=new Float32Array(M1);
  9210. }else{
  9211. GLGE.mat4gl(M1,pgl.cameraMatrixT);
  9212. }
  9213. //GLGE.reuseMatrix4(M1);
  9214. pgl.cameraMatrix=cameraMatrix;
  9215. GLGE.setUniformMatrix(gl,"Matrix4fv",cUniform, false, pgl.cameraMatrixT);
  9216. mvCache.cameraMatrix=cameraMatrix;
  9217. mvCache.modelMatrix=modelMatrix;
  9218. }
  9219. var pUniform = GLGE.getUniformLocation(gl,program, "projection");
  9220. M1=GLGE.transposeMat4(camera.getProjectionMatrix());
  9221. if(!pgl.pMatrix){
  9222. pgl.pMatrixT=new Float32Array(M1);
  9223. }else{
  9224. GLGE.mat4gl(M1,pgl.pMatrixT);
  9225. }
  9226. //GLGE.reuseMatrix4(M1);
  9227. pgl.pMatrix=camera.getProjectionMatrix();
  9228. GLGE.setUniformMatrix(gl,"Matrix4fv",pUniform, false, pgl.pMatrixT);
  9229. //light
  9230. //dont' need lighting for picking
  9231. if(renderType==GLGE.RENDER_DEFAULT || renderType==GLGE.RENDER_SHADOW || renderType==GLGE.RENDER_DEPTH || renderType==GLGE.RENDER_EMIT){
  9232. var pos,lpos;
  9233. var lights=gl.lights
  9234. if(!pc.lights) pc.lights=[];
  9235. if(!pgl.lights) pgl.lights=[];
  9236. if(!this.caches.lights) this.caches.lights=[];
  9237. var lightCache=pc.lights;
  9238. for(var i=0; i<lights.length;i++){
  9239. if(lights[i].type==GLGE.L_OFF) continue;
  9240. if(!lightCache[i]) lightCache[i]={modelMatrix:null,cameraMatrix:null};
  9241. if(lightCache[i].modelMatrix!=modelMatrix || lightCache[i].cameraMatrix!=cameraMatrix){
  9242. if(!this.caches.lights[i])this.caches.lights[i]={};
  9243. if(!this.caches.lights[i].pos) this.caches.lights[i].pos=GLGE.mulMat4Vec4(GLGE.mulMat4(cameraMatrix,lights[i].getModelMatrix()),[0,0,0,1]);
  9244. pos=this.caches.lights[i].pos;
  9245. GLGE.setUniform3(gl,"3f",GLGE.getUniformLocation(gl,program, "lightpos"+i), pos[0],pos[1],pos[2]);
  9246. if(!this.caches.lights[i].lpos) this.caches.lights[i].lpos=GLGE.mulMat4Vec4(GLGE.mulMat4(cameraMatrix,lights[i].getModelMatrix()),[0,0,1,1]);
  9247. lpos=this.caches.lights[i].lpos;
  9248. GLGE.setUniform3(gl,"3f",GLGE.getUniformLocation(gl,program, "lightdir"+i),lpos[0]-pos[0],lpos[1]-pos[1],lpos[2]-pos[2]);
  9249. if(lights[i].s_cache){
  9250. var lightmat=GLGE.mulMat4(lights[i].s_cache.smatrix,modelMatrix);
  9251. if(!pgl.lights[i]) pgl.lights[i]=new Float32Array(lightmat);
  9252. else GLGE.mat4gl(lightmat,pgl.lights[i]);
  9253. GLGE.setUniformMatrix(gl,"Matrix4fv",GLGE.getUniformLocation(gl,program, "lightmat"+i), true,pgl.lights[i]);
  9254. GLGE.setUniform2(gl,"2f",GLGE.getUniformLocation(gl,program, "shadowoffset"+i), lights[i].s_cache.pmatrix[3],lights[i].s_cache.pmatrix[7]);
  9255. lightCache[i].modelMatrix=modelMatrix;
  9256. lightCache[i].cameraMatrix=cameraMatrix;
  9257. }else{
  9258. lightCache[i].modelMatrix=modelMatrix;
  9259. lightCache[i].cameraMatrix=cameraMatrix;
  9260. }
  9261. }
  9262. }
  9263. }
  9264. if(this.mesh.joints){
  9265. if(!pc.joints) pc.joints=[];
  9266. if(!pgl.joints) pgl.joints=[];
  9267. if(!pgl.jointsT) pgl.jointsT=[];
  9268. if(!pgl.jointsinv) pgl.jointsinv=[];
  9269. if ((!pgl.jointsCombined)||pgl.jointsCombined.length!=this.mesh.joints.length*12)
  9270. pgl.jointsCombined = new Float32Array(this.mesh.joints.length*12);
  9271. var jointCache=pc.joints;
  9272. var ident=GLGE.identMatrix();
  9273. for(i=0;i<this.mesh.joints.length;i++){
  9274. if(!jointCache[i]) jointCache[i]={modelMatrix:null,invBind:null};
  9275. if(typeof this.mesh.joints[i]=="string"){
  9276. if(!this.bones) this.bones=this.skeleton.getNames();
  9277. if(this.bones){
  9278. var modelMatrix=this.bones[this.mesh.joints[i]].getModelMatrix();
  9279. }
  9280. }else{
  9281. var modelMatrix=this.mesh.joints[i].getModelMatrix();
  9282. }
  9283. var invBind=this.mesh.invBind[i];
  9284. if(jointCache[i].modelMatrix!=modelMatrix || jointCache[i].invBind!=invBind){
  9285. var jointmat=GLGE.mulMat4(modelMatrix,invBind);
  9286. //jointmat=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1];
  9287. if(!pgl.joints[i]){
  9288. pgl.jointsT[i]=new Float32Array(GLGE.transposeMat4(jointmat));
  9289. }else{
  9290. GLGE.mat4gl(GLGE.transposeMat4(jointmat),pgl.jointsT[i]);
  9291. }
  9292. pgl.joints[i]=jointmat;
  9293. if(!pgl.jointsinv[i]) pgl.jointsinv[i]=new Float32Array(GLGE.inverseMat4(jointmat));
  9294. else GLGE.mat4gl(GLGE.inverseMat4(jointmat),pgl.jointsinv[i]);
  9295. var mat=pgl.jointsT[i];
  9296. var combinedMat=pgl.jointsCombined;
  9297. combinedMat[i*12]=mat[0];
  9298. combinedMat[i*12+1]=mat[4];
  9299. combinedMat[i*12+2]=mat[8];
  9300. combinedMat[i*12+3]=mat[12];
  9301. combinedMat[i*12+4]=mat[1];
  9302. combinedMat[i*12+5]=mat[5];
  9303. combinedMat[i*12+6]=mat[9];
  9304. combinedMat[i*12+7]=mat[13];
  9305. combinedMat[i*12+8]=mat[2];
  9306. combinedMat[i*12+9]=mat[6];
  9307. combinedMat[i*12+10]=mat[10];
  9308. combinedMat[i*12+11]=mat[14];
  9309. //GLGE.setUniform4(gl,"4f",GLGE.getUniformLocation(gl,program, "jointMat["+(i*3)+"]"), mat[0],mat[4],mat[8],mat[12]);
  9310. //GLGE.setUniform4(gl,"4f",GLGE.getUniformLocation(gl,program, "jointMat["+(i*3+1)+"]"), mat[1],mat[5],mat[9],mat[13]);
  9311. //GLGE.setUniform4(gl,"4f",GLGE.getUniformLocation(gl,program, "jointMat["+(i*3+2)+"]"), mat[2],mat[6],mat[10],mat[14]);
  9312. jointCache[i].modelMatrix=modelMatrix;
  9313. jointCache[i].invBind=invBind;
  9314. }
  9315. }
  9316. gl.uniform4fv(GLGE.getUniformLocation(gl,program, "jointMat"),pgl.jointsCombined);
  9317. }
  9318. if(this.material && (renderType==GLGE.RENDER_DEFAULT || renderType==GLGE.RENDER_EMIT) && gl.scene.lastMaterial!=this.material){
  9319. this.material.textureUniforms(gl,program,lights,this);
  9320. gl.scene.lastMaterial=this.material;
  9321. }
  9322. }
  9323. /**
  9324. * Renders the object to the screen
  9325. * @private
  9326. */
  9327. GLGE.Object.prototype.GLRender=function(gl,renderType,pickindex,multiMaterial,distance){
  9328. if(!gl) return;
  9329. if(!this.gl) this.GLInit(gl);
  9330. //if look at is set then look
  9331. if(this.lookAt) this.Lookat(this.lookAt);
  9332. //animate this object
  9333. if(renderType==GLGE.RENDER_DEFAULT){
  9334. if(this.animation) this.animate();
  9335. }
  9336. if(!this.renderCaches[renderType]) this.renderCaches[renderType]={};
  9337. var cameraMatrix=gl.scene.camera.getViewMatrix();
  9338. var modelMatrix=this.getModelMatrix();
  9339. if(this.renderCaches[renderType].cameraMatrix!=cameraMatrix || this.renderCaches[renderType].modelMatrix!=modelMatrix){
  9340. this.renderCaches[renderType]={};
  9341. this.renderCaches[renderType].cameraMatrix=cameraMatrix;
  9342. this.renderCaches[renderType].modelMatrix=modelMatrix;
  9343. }
  9344. this.caches=this.renderCaches[renderType];
  9345. var pixelsize;
  9346. if(multiMaterial==undefined){
  9347. var start=0;
  9348. var end=this.multimaterials.length;
  9349. }else{
  9350. var start=multiMaterial;
  9351. var end=multiMaterial+1;
  9352. }
  9353. for(var i=start; i<end;i++){
  9354. if(this.multimaterials[i].lods.length>1 && !pixelsize){
  9355. var camerapos=gl.scene.camera.getPosition();
  9356. var modelpos=this.getPosition();
  9357. var dist=GLGE.lengthVec3([camerapos.x-modelpos.x,camerapos.y-modelpos.y,camerapos.z-modelpos.z]);
  9358. dist=GLGE.mulMat4Vec4(gl.scene.camera.getProjectionMatrix(),[this.getBoundingVolume().getSphereRadius(),0,-dist,1]);
  9359. pixelsize=dist[0]/dist[3]*gl.scene.renderer.canvas.width;
  9360. }
  9361. var lod=this.multimaterials[i].getLOD(pixelsize);
  9362. if(lod.mesh && lod.mesh.loaded){
  9363. if(renderType==GLGE.RENDER_NULL){
  9364. if(lod.material) lod.material.registerPasses(gl,this);
  9365. break;
  9366. }
  9367. if(!lod.GLShaderProgram){
  9368. this.createShaders(lod);
  9369. }else{
  9370. this.GLShaderProgramPick=lod.GLShaderProgramPick;
  9371. this.GLShaderProgramShadow=lod.GLShaderProgramShadow;
  9372. this.GLShaderProgram=lod.GLShaderProgram;
  9373. }
  9374. this.mesh=lod.mesh;
  9375. this.material=lod.material;
  9376. var drawType;
  9377. switch(this.drawType){
  9378. case GLGE.DRAW_LINES:
  9379. drawType=gl.LINES;
  9380. break;
  9381. case GLGE.DRAW_POINTS:
  9382. drawType=gl.POINTS;
  9383. break;
  9384. case GLGE.DRAW_LINELOOPS:
  9385. drawType=gl.LINE_LOOP;
  9386. break;
  9387. case GLGE.DRAW_LINESTRIPS:
  9388. drawType=gl.LINE_STRIP;
  9389. break;
  9390. case GLGE.DRAW_TRIANGLESTRIP:
  9391. drawType=gl.TRIANGLE_STRIP;
  9392. break;
  9393. default:
  9394. drawType=gl.TRIANGLES;
  9395. break;
  9396. }
  9397. switch(renderType){
  9398. case GLGE.RENDER_DEFAULT:
  9399. case GLGE.RENDER_EMIT:
  9400. if(gl.program!=this.GLShaderProgram){
  9401. gl.useProgram(this.GLShaderProgram);
  9402. gl.program=this.GLShaderProgram;
  9403. }
  9404. this.mesh.GLAttributes(gl,this.GLShaderProgram,this.meshFrame1,this.meshFrame2);
  9405. break;
  9406. case GLGE.RENDER_SHADOW:
  9407. case GLGE.RENDER_DEPTH:
  9408. if(gl.program!=this.GLShaderProgramShadow){
  9409. gl.useProgram(this.GLShaderProgramShadow,this.meshFrame1,this.meshFrame2);
  9410. gl.program=this.GLShaderProgramShadow;
  9411. }
  9412. if(!distance) distance=gl.scene.camera.getFar();
  9413. GLGE.setUniform(gl,"1f",GLGE.getUniformLocation(gl,this.GLShaderProgramShadow, "distance"), distance);
  9414. this.mesh.GLAttributes(gl,this.GLShaderProgramShadow,this.meshFrame1,this.meshFrame2);
  9415. break;
  9416. case GLGE.RENDER_NORMAL:
  9417. if(gl.program!=this.GLShaderProgramNormal){
  9418. gl.useProgram(this.GLShaderProgramNormal);
  9419. gl.program=this.GLShaderProgramNormal;
  9420. }
  9421. this.mesh.GLAttributes(gl,this.GLShaderProgramNormal,this.meshFrame1,this.meshFrame2);
  9422. break;
  9423. case GLGE.RENDER_PICK:
  9424. if(gl.program!=this.GLShaderProgramPick){
  9425. gl.useProgram(this.GLShaderProgramPick);
  9426. gl.program=this.GLShaderProgramPick;
  9427. }
  9428. this.mesh.GLAttributes(gl,this.GLShaderProgramPick,this.meshFrame1,this.meshFrame2);
  9429. drawType=gl.TRIANGLES;
  9430. break;
  9431. }
  9432. //render the object
  9433. this.GLUniforms(gl,renderType,pickindex);
  9434. switch (this.mesh.windingOrder) {
  9435. case GLGE.Mesh.WINDING_ORDER_UNKNOWN:
  9436. if (gl.scene.renderer.cullFaces)
  9437. gl.enable(gl.CULL_FACE);
  9438. else
  9439. gl.disable(gl.CULL_FACE);
  9440. break;
  9441. case GLGE.Mesh.WINDING_ORDER_CLOCKWISE:
  9442. gl.enable(gl.CULL_FACE);
  9443. break;
  9444. case GLGE.Mesh.WINDING_ORDER_COUNTER:
  9445. gl.cullFace(gl.FRONT);
  9446. gl.enable(gl.CULL_FACE);
  9447. default:
  9448. break;
  9449. }
  9450. if(this.noDepthMask) gl.depthMask(false);
  9451. if(this.mesh.GLfaces){
  9452. gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.mesh.GLfaces);
  9453. gl.drawElements(drawType, this.mesh.GLfaces.numItems, gl.UNSIGNED_SHORT, 0);
  9454. }else{
  9455. gl.drawArrays(drawType, 0, this.mesh.positions.length/3);
  9456. }
  9457. gl.depthMask(true);
  9458. switch (this.mesh.windingOrder) {
  9459. case GLGE.Mesh.WINDING_ORDER_UNKNOWN:
  9460. if (gl.scene.renderer.cullFaces)
  9461. gl.enable(gl.CULL_FACE);
  9462. break;
  9463. case GLGE.Mesh.WINDING_ORDER_COUNTER:
  9464. gl.cullFace(gl.BACK);
  9465. default:
  9466. break;
  9467. }
  9468. var matrix=this.matrix;
  9469. var caches=this.caches;
  9470. this.matrix=matrix;
  9471. this.caches=caches;
  9472. }
  9473. }
  9474. }
  9475. })(GLGE);/*
  9476. GLGE WebGL Graphics Engine
  9477. Copyright (c) 2010, Paul Brunt
  9478. All rights reserved.
  9479. Redistribution and use in source and binary forms, with or without
  9480. modification, are permitted provided that the following conditions are met:
  9481. * Redistributions of source code must retain the above copyright
  9482. notice, this list of conditions and the following disclaimer.
  9483. * Redistributions in binary form must reproduce the above copyright
  9484. notice, this list of conditions and the following disclaimer in the
  9485. documentation and/or other materials provided with the distribution.
  9486. * Neither the name of GLGE nor the
  9487. names of its contributors may be used to endorse or promote products
  9488. derived from this software without specific prior written permission.
  9489. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  9490. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  9491. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  9492. DISCLAIMED. IN NO EVENT SHALL PAUL BRUNT BE LIABLE FOR ANY
  9493. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  9494. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  9495. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  9496. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  9497. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  9498. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  9499. */
  9500. /**
  9501. * @fileOverview
  9502. * @name glge_text.js
  9503. * @author me@paulbrunt.co.uk
  9504. */
  9505. (function(GLGE){
  9506. /**
  9507. * @class Text that can be rendered in a scene
  9508. * @augments GLGE.Animatable
  9509. * @augments GLGE.Placeable
  9510. * @augments GLGE.QuickNotation
  9511. * @augments GLGE.JSONLoader
  9512. */
  9513. GLGE.Text=function(uid){
  9514. this.canvas=document.createElement("canvas");
  9515. this.scaleCanvas=document.createElement("canvas");
  9516. this.color={r:1.0,g:1.0,b:1.0};
  9517. GLGE.Assets.registerAsset(this,uid);
  9518. }
  9519. GLGE.augment(GLGE.Placeable,GLGE.Text);
  9520. GLGE.augment(GLGE.Animatable,GLGE.Text);
  9521. GLGE.augment(GLGE.QuickNotation,GLGE.Text);
  9522. GLGE.augment(GLGE.JSONLoader,GLGE.Text);
  9523. GLGE.Text.prototype.className="Text";
  9524. GLGE.Text.prototype.zTrans=true;
  9525. GLGE.Text.prototype.canvas=null;
  9526. GLGE.Text.prototype.aspect=1.0;
  9527. GLGE.Text.prototype.color=null;
  9528. GLGE.Text.prototype.text="";
  9529. GLGE.Text.prototype.font="Times";
  9530. GLGE.Text.prototype.size=100;
  9531. GLGE.Text.prototype.pickType=GLGE.TEXT_TEXTPICK;
  9532. GLGE.Text.prototype.pickable=true;
  9533. GLGE.Text.prototype.alpha=1;
  9534. GLGE.Text.prototype.dirty=true;
  9535. /**
  9536. * Gets the pick type for this text
  9537. * @returns {string} the pick type
  9538. */
  9539. GLGE.Text.prototype.getPickType=function(){
  9540. return this.pickType;
  9541. };
  9542. /**
  9543. * Sets the pick type GLGE.TEXT_BOXPICK for picking based on bound box or GLGE.TEXT_TEXTPICK for pixel perfect text picking
  9544. * @param {Number} value the picking type
  9545. */
  9546. GLGE.Text.prototype.setPickType=function(value){
  9547. this.pickType=value;
  9548. return this;
  9549. };
  9550. /**
  9551. * Gets the aspect of the text
  9552. * @returns {Number} the aspect of the text
  9553. */
  9554. GLGE.Text.prototype.getAspect=function(){
  9555. return this.aspect;
  9556. };
  9557. /**
  9558. * Sets the aspect of the text
  9559. * @param {Number} value the aspect of the text
  9560. */
  9561. GLGE.Text.prototype.setAspect=function(value){
  9562. this.aspect=value;
  9563. this.dirty=true;
  9564. return this;
  9565. };
  9566. /**
  9567. * Gets the font of the text
  9568. * @returns {string} the font of the text
  9569. */
  9570. GLGE.Text.prototype.getFont=function(){
  9571. return this.size;
  9572. };
  9573. /**
  9574. * Sets the font of the text
  9575. * @param {string} value the font of the text
  9576. */
  9577. GLGE.Text.prototype.setFont=function(value){
  9578. this.font=value;
  9579. this.dirty=true;
  9580. return this;
  9581. };
  9582. /**
  9583. * Gets the size of the text
  9584. * @returns {string} the size of the text
  9585. */
  9586. GLGE.Text.prototype.getSize=function(){
  9587. return this.size;
  9588. };
  9589. /**
  9590. * Sets the size of the text
  9591. * @param {Number} value the size of the text
  9592. */
  9593. GLGE.Text.prototype.setSize=function(value){
  9594. this.size=value;
  9595. this.dirty=true;
  9596. return this;
  9597. };
  9598. /**
  9599. * Gets the rendered text
  9600. * @returns {string} the text rendered
  9601. */
  9602. GLGE.Text.prototype.getText=function(){
  9603. return this.text;
  9604. };
  9605. /**
  9606. * Sets the text to be rendered
  9607. * @param {Number} value the text to render
  9608. */
  9609. GLGE.Text.prototype.setText=function(value){
  9610. this.text=value;
  9611. this.dirty=true;
  9612. return this;
  9613. };
  9614. /**
  9615. * Sets the base colour of the text
  9616. * @param {string} color The colour of the material
  9617. */
  9618. GLGE.Text.prototype.setColor=function(color){
  9619. color=GLGE.colorParse(color);
  9620. this.color={r:color.r,g:color.g,b:color.b};
  9621. return this;
  9622. };
  9623. /**
  9624. * Sets the red base colour of the text
  9625. * @param {Number} r The new red level 0-1
  9626. */
  9627. GLGE.Text.prototype.setColorR=function(value){
  9628. this.color.r=value;
  9629. return this;
  9630. };
  9631. /**
  9632. * Sets the green base colour of the text
  9633. * @param {Number} g The new green level 0-1
  9634. */
  9635. GLGE.Text.prototype.setColorG=function(value){
  9636. this.color.g=value;
  9637. return this;
  9638. };
  9639. /**
  9640. * Sets the blue base colour of the text
  9641. * @param {Number} b The new blue level 0-1
  9642. */
  9643. GLGE.Text.prototype.setColorB=function(value){
  9644. this.color.b=value;
  9645. return this;
  9646. };
  9647. /**
  9648. * Gets the current base color of the text
  9649. * @return {[r,g,b]} The current base color
  9650. */
  9651. GLGE.Text.prototype.getColor=function(){
  9652. return this.color;
  9653. return this;
  9654. };
  9655. /**
  9656. * Sets the alpha
  9657. * @param {Number} b The new alpha level 0-1
  9658. */
  9659. GLGE.Text.prototype.setAlpha=function(value){
  9660. this.alpha=value;
  9661. return this;
  9662. };
  9663. /**
  9664. * Gets the alpha
  9665. * @returns The alpha level
  9666. */
  9667. GLGE.Text.prototype.getAlpha=function(){
  9668. return this.alpha;
  9669. };
  9670. /**
  9671. * Sets the Z Transparency of this text
  9672. * @param {boolean} value Does this object need blending?
  9673. */
  9674. GLGE.Text.prototype.setZtransparent=function(value){
  9675. this.zTrans=value;
  9676. return this;
  9677. }
  9678. /**
  9679. * Gets the z transparency
  9680. * @returns boolean
  9681. */
  9682. GLGE.Text.prototype.isZtransparent=function(){
  9683. return this.zTrans;
  9684. }
  9685. /**
  9686. * Creates the shader program for the object
  9687. * @private
  9688. */
  9689. GLGE.Text.prototype.GLGenerateShader=function(gl){
  9690. if(this.GLShaderProgram) gl.deleteProgram(this.GLShaderProgram);
  9691. //Vertex Shader
  9692. var vertexStr="";
  9693. vertexStr+="attribute vec3 position;\n";
  9694. vertexStr+="attribute vec2 uvcoord;\n";
  9695. vertexStr+="varying vec2 texcoord;\n";
  9696. vertexStr+="uniform mat4 Matrix;\n";
  9697. vertexStr+="uniform mat4 PMatrix;\n";
  9698. vertexStr+="varying vec4 pos;\n";
  9699. vertexStr+="void main(void){\n";
  9700. vertexStr+="texcoord=uvcoord;\n";
  9701. vertexStr+="pos = Matrix * vec4(position,1.0);\n";
  9702. vertexStr+="gl_Position = PMatrix * pos;\n";
  9703. vertexStr+="}\n";
  9704. //Fragment Shader
  9705. var fragStr="#ifdef GL_ES\nprecision highp float;\n#endif\n";
  9706. fragStr=fragStr+"uniform sampler2D TEXTURE;\n";
  9707. fragStr=fragStr+"varying vec2 texcoord;\n";
  9708. fragStr=fragStr+"uniform mat4 Matrix;\n";
  9709. fragStr=fragStr+"varying vec4 pos;\n";
  9710. fragStr=fragStr+"uniform float far;\n";
  9711. fragStr=fragStr+"uniform bool depthrender;\n";
  9712. fragStr=fragStr+"uniform float distance;\n";
  9713. fragStr=fragStr+"uniform int picktype;\n";
  9714. fragStr=fragStr+"uniform vec3 pickcolor;\n";
  9715. fragStr=fragStr+"uniform vec3 color;\n";
  9716. fragStr=fragStr+"uniform float alpha;\n";
  9717. fragStr=fragStr+"void main(void){\n";
  9718. fragStr=fragStr+"float ob=pow(min(1.0,abs(dot(normalize(Matrix[2].rgb),vec3(0.0,0.0,1.0)))*2.0),1.5);\n";
  9719. fragStr=fragStr+"float a=texture2D(TEXTURE,texcoord).a*alpha*ob;\n";
  9720. fragStr=fragStr+"if(picktype=="+GLGE.TEXT_BOXPICK+"){gl_FragColor = vec4(pickcolor,1.0);}"
  9721. fragStr=fragStr+"else if(picktype=="+GLGE.TEXT_TEXTPICK+"){if(alpha<1.0) discard; gl_FragColor = vec4(pickcolor,alpha);}"
  9722. fragStr=fragStr+"else{gl_FragColor = vec4(color.rgb,a);};\n";
  9723. fragStr=fragStr+"if (depthrender) { if(a<0.5) discard; float depth = gl_FragCoord.z / gl_FragCoord.w;\n";
  9724. fragStr=fragStr+"vec4 rgba=fract(depth/distance * vec4(16777216.0, 65536.0, 256.0, 1.0));\n";
  9725. fragStr=fragStr+"gl_FragColor=rgba-rgba.rrgb*vec4(0.0,0.00390625,0.00390625,0.00390625);}\n";
  9726. fragStr=fragStr+"}\n";
  9727. this.GLFragmentShader=gl.createShader(gl.FRAGMENT_SHADER);
  9728. this.GLVertexShader=gl.createShader(gl.VERTEX_SHADER);
  9729. gl.shaderSource(this.GLFragmentShader, fragStr);
  9730. gl.compileShader(this.GLFragmentShader);
  9731. if (!gl.getShaderParameter(this.GLFragmentShader, gl.COMPILE_STATUS)) {
  9732. GLGE.error(gl.getShaderInfoLog(this.GLFragmentShader));
  9733. return;
  9734. }
  9735. //set and compile the vertex shader
  9736. //need to set str
  9737. gl.shaderSource(this.GLVertexShader, vertexStr);
  9738. gl.compileShader(this.GLVertexShader);
  9739. if (!gl.getShaderParameter(this.GLVertexShader, gl.COMPILE_STATUS)) {
  9740. GLGE.error(gl.getShaderInfoLog(this.GLVertexShader));
  9741. return;
  9742. }
  9743. this.GLShaderProgram = gl.createProgram();
  9744. gl.attachShader(this.GLShaderProgram, this.GLVertexShader);
  9745. gl.attachShader(this.GLShaderProgram, this.GLFragmentShader);
  9746. gl.linkProgram(this.GLShaderProgram);
  9747. }
  9748. /**
  9749. * Initiallize all the GL stuff needed to render to screen
  9750. * @private
  9751. */
  9752. GLGE.Text.prototype.GLInit=function(gl){
  9753. this.gl=gl;
  9754. this.createPlane(gl);
  9755. this.GLGenerateShader(gl);
  9756. this.glTexture=gl.createTexture();
  9757. this.dirty=true;
  9758. }
  9759. /**
  9760. * Updates the canvas texture
  9761. * @private
  9762. */
  9763. GLGE.Text.prototype.updateCanvas=function(gl){
  9764. var canvas = this.canvas;
  9765. canvas.width=1;
  9766. canvas.height=this.size*1.2;
  9767. var ctx = canvas.getContext("2d");
  9768. ctx.font = this.size+"px "+this.font;
  9769. canvas.width= ctx.measureText(this.text).width || 80;
  9770. canvas.height=this.size*1.2;
  9771. ctx = canvas.getContext("2d");
  9772. ctx.textBaseline="top";
  9773. ctx.font = (this.extra||"") + " " + this.size+"px "+this.font;
  9774. this.aspect=canvas.width/canvas.height;
  9775. ctx.fillText(this.text, 0, 0);
  9776. var height=Math.pow(2,Math.ceil(Math.log(canvas.height))/(Math.log(2)));
  9777. var width=Math.pow(2,Math.ceil(Math.log(canvas.width))/(Math.log(2)));
  9778. this.scaleCanvas.height=height;
  9779. this.scaleCanvas.width=width;
  9780. this.scaleContext=this.scaleCanvas.getContext("2d");
  9781. this.scaleContext.clearRect(0,0,width,height);
  9782. this.scaleContext.drawImage(canvas, 0, 0, width, height);
  9783. gl.bindTexture(gl.TEXTURE_2D, this.glTexture);
  9784. //TODO: fix this when minefield is upto spec
  9785. try{gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this.scaleCanvas);}
  9786. catch(e){gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this.scaleCanvas,null);}
  9787. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
  9788. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
  9789. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR_MIPMAP_LINEAR);
  9790. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
  9791. gl.generateMipmap(gl.TEXTURE_2D);
  9792. gl.bindTexture(gl.TEXTURE_2D, null);
  9793. this.dirty=false;
  9794. }
  9795. /**
  9796. * Renders the text to the render buffer
  9797. * @private
  9798. */
  9799. GLGE.Text.prototype.GLRender=function(gl,renderType,pickindex){
  9800. if(!this.gl){
  9801. this.GLInit(gl);
  9802. }
  9803. if(this.dirty) this.updateCanvas(gl);
  9804. if(renderType==GLGE.RENDER_DEFAULT || renderType==GLGE.RENDER_PICK || renderType==GLGE.RENDER_SHADOW){
  9805. //if look at is set then look
  9806. if(this.lookAt) this.Lookat(this.lookAt);
  9807. if(gl.program!=this.GLShaderProgram){
  9808. gl.useProgram(this.GLShaderProgram);
  9809. gl.program=this.GLShaderProgram;
  9810. }
  9811. var attribslot;
  9812. //disable all the attribute initially arrays - do I really need this?
  9813. for(var i=0; i<8; i++) gl.disableVertexAttribArray(i);
  9814. attribslot=GLGE.getAttribLocation(gl,this.GLShaderProgram, "position");
  9815. gl.bindBuffer(gl.ARRAY_BUFFER, this.posBuffer);
  9816. gl.enableVertexAttribArray(attribslot);
  9817. gl.vertexAttribPointer(attribslot, this.posBuffer.itemSize, gl.FLOAT, false, 0, 0);
  9818. attribslot=GLGE.getAttribLocation(gl,this.GLShaderProgram, "uvcoord");
  9819. gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer);
  9820. gl.enableVertexAttribArray(attribslot);
  9821. gl.vertexAttribPointer(attribslot, this.uvBuffer.itemSize, gl.FLOAT, false, 0, 0);
  9822. gl.activeTexture(gl["TEXTURE0"]);
  9823. gl.bindTexture(gl.TEXTURE_2D, this.glTexture);
  9824. GLGE.setUniform(gl,"1i",GLGE.getUniformLocation(gl,this.GLShaderProgram, "TEXTURE"),0);
  9825. if(!pickindex) pickindex=0;
  9826. var b = pickindex >> 16 & 0xFF;
  9827. var g = pickindex >> 8 & 0xFF;
  9828. var r = pickindex & 0xFF;
  9829. GLGE.setUniform3(gl,"3f",GLGE.getUniformLocation(gl,this.GLShaderProgram, "pickcolor"),r/255,g/255,b/255);
  9830. if(renderType==GLGE.RENDER_PICK){
  9831. GLGE.setUniform(gl,"1i",GLGE.getUniformLocation(gl,this.GLShaderProgram, "picktype"), this.pickType);
  9832. }else{
  9833. GLGE.setUniform(gl,"1i",GLGE.getUniformLocation(gl,this.GLShaderProgram, "picktype"), 0);
  9834. }
  9835. var distance=gl.scene.camera.getFar();
  9836. GLGE.setUniform(gl,"1f",GLGE.getUniformLocation(gl,this.GLShaderProgram, "distance"), distance);
  9837. if(renderType==GLGE.RENDER_SHADOW){
  9838. GLGE.setUniform(gl,"1i",GLGE.getUniformLocation(gl,this.GLShaderProgram, "depthrender"), 1);
  9839. }else{
  9840. GLGE.setUniform(gl,"1i",GLGE.getUniformLocation(gl,this.GLShaderProgram, "depthrender"), 0);
  9841. }
  9842. if(!this.GLShaderProgram.glarrays) this.GLShaderProgram.glarrays={};
  9843. //generate and set the modelView matrix
  9844. var scalefactor=this.size/100;
  9845. var mMatrix=GLGE.mulMat4(gl.scene.camera.getViewMatrix(),GLGE.mulMat4(this.getModelMatrix(),GLGE.scaleMatrix(this.aspect*scalefactor,scalefactor,scalefactor)));
  9846. var mUniform = GLGE.getUniformLocation(gl,this.GLShaderProgram, "Matrix");
  9847. if(!this.GLShaderProgram.glarrays.mMatrix) this.GLShaderProgram.glarrays.mMatrix=new Float32Array(mMatrix);
  9848. else GLGE.mat4gl(mMatrix,this.GLShaderProgram.glarrays.mMatrix);
  9849. GLGE.setUniformMatrix(gl,"Matrix4fv",mUniform, true, this.GLShaderProgram.glarrays.mMatrix);
  9850. var mUniform = GLGE.getUniformLocation(gl,this.GLShaderProgram, "PMatrix");
  9851. if(!this.GLShaderProgram.glarrays.pMatrix) this.GLShaderProgram.glarrays.pMatrix=new Float32Array(gl.scene.camera.getProjectionMatrix());
  9852. else GLGE.mat4gl(gl.scene.camera.getProjectionMatrix(),this.GLShaderProgram.glarrays.pMatrix);
  9853. GLGE.setUniformMatrix(gl,"Matrix4fv",mUniform, true, this.GLShaderProgram.glarrays.pMatrix);
  9854. var farUniform = GLGE.getUniformLocation(gl,this.GLShaderProgram, "far");
  9855. GLGE.setUniform(gl,"1f",farUniform, gl.scene.camera.getFar());
  9856. var alphaUniform = GLGE.getUniformLocation(gl,this.GLShaderProgram, "alpha");
  9857. GLGE.setUniform(gl,"1f",alphaUniform, this.alpha);
  9858. //set the color
  9859. GLGE.setUniform3(gl,"3f",GLGE.getUniformLocation(gl,this.GLShaderProgram, "color"), this.color.r,this.color.g,this.color.b);
  9860. gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.GLfaces);
  9861. gl.drawElements(gl.TRIANGLES, this.GLfaces.numItems, gl.UNSIGNED_SHORT, 0);
  9862. gl.scene.lastMaterial=null;
  9863. }
  9864. }
  9865. /**
  9866. * creates the plane mesh to draw
  9867. * @private
  9868. */
  9869. GLGE.Text.prototype.createPlane=function(gl){
  9870. //create the vertex positions
  9871. if(!this.posBuffer) this.posBuffer = gl.createBuffer();
  9872. gl.bindBuffer(gl.ARRAY_BUFFER, this.posBuffer);
  9873. gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([1,1,0,-1,1,0,-1,-1,0,1,-1,0]), gl.STATIC_DRAW);
  9874. this.posBuffer.itemSize = 3;
  9875. this.posBuffer.numItems = 4;
  9876. //create the vertex uv coords
  9877. if(!this.uvBuffer) this.uvBuffer = gl.createBuffer();
  9878. gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer);
  9879. gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([0,0,1,0,1,1,0,1]), gl.STATIC_DRAW);
  9880. this.uvBuffer.itemSize = 2;
  9881. this.uvBuffer.numItems = 4;
  9882. //create the faces
  9883. if(!this.GLfaces) this.GLfaces = gl.createBuffer();
  9884. gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.GLfaces);
  9885. gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array([2,1,0,0,3,2]), gl.STATIC_DRAW);
  9886. this.GLfaces.itemSize = 1;
  9887. this.GLfaces.numItems = 6;
  9888. }
  9889. })(GLGE);/*
  9890. GLGE WebGL Graphics Engine
  9891. Copyright (c) 2010, Paul Brunt
  9892. All rights reserved.
  9893. Redistribution and use in source and binary forms, with or without
  9894. modification, are permitted provided that the following conditions are met:
  9895. * Redistributions of source code must retain the above copyright
  9896. notice, this list of conditions and the following disclaimer.
  9897. * Redistributions in binary form must reproduce the above copyright
  9898. notice, this list of conditions and the following disclaimer in the
  9899. documentation and/or other materials provided with the distribution.
  9900. * Neither the name of GLGE nor the
  9901. names of its contributors may be used to endorse or promote products
  9902. derived from this software without specific prior written permission.
  9903. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  9904. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  9905. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  9906. DISCLAIMED. IN NO EVENT SHALL PAUL BRUNT BE LIABLE FOR ANY
  9907. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  9908. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  9909. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  9910. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  9911. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  9912. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  9913. */
  9914. /**
  9915. * @fileOverview
  9916. * @name glge_renderer.js
  9917. * @author me@paulbrunt.co.uk
  9918. */
  9919. (function(GLGE){
  9920. /**
  9921. * @class Sets the scene to render
  9922. * @param {object} canvas The canvas element to render to
  9923. * @augments GLGE.QuickNotation
  9924. */
  9925. GLGE.Renderer=function(canvas,error,props){
  9926. this.viewport=[];
  9927. this.canvas=canvas;
  9928. if(!props) props={alpha:true,depth:true,stencil:true,antialias:true,premultipliedAlpha:true};
  9929. try {
  9930. this.gl = canvas.getContext("experimental-webgl",props);
  9931. } catch(e) {}
  9932. try {
  9933. if(!this.gl) this.gl = canvas.getContext("webgl",props);
  9934. } catch(e) {}
  9935. if(!this.gl) {
  9936. console.log("GLGE err:", typeof(globalNoWebGLError)=="undefined")
  9937. if( (!error) && (typeof(globalNoWebGLError)=="undefined")){
  9938. var div=document.createElement("div");
  9939. div.setAttribute("style","position: absolute; top: 10px; left: 10px; font-family: sans-serif; font-size: 14px; padding: 10px;background-color: #fcffcb;color: #800; width: 200px; border:2px solid #f00");
  9940. div.innerHTML="WebGL compatible Browser Required(Firefox 4 or Chrome 9 and up) or you may need to update your graphics card driver.";
  9941. document.getElementsByTagName("body")[0].appendChild(div);
  9942. throw "cannot create webgl context";
  9943. }else{
  9944. error();
  9945. throw "cannot create webgl context";
  9946. }
  9947. }
  9948. //firefox is doing something here?
  9949. try{
  9950. this.gl.canvas=canvas;
  9951. }catch(e){};
  9952. //this.gl = WebGLDebugUtils.makeDebugContext(this.gl);
  9953. //this.gl.setTracing(true);
  9954. //chome compatibility
  9955. //TODO: Remove this when chome is right
  9956. if (!this.gl.getProgramParameter)
  9957. {
  9958. this.gl.getProgramParameter = this.gl.getProgrami
  9959. }
  9960. if (!this.gl.getShaderParameter)
  9961. {
  9962. this.gl.getShaderParameter = this.gl.getShaderi
  9963. }
  9964. // End of Chrome compatibility code
  9965. this.gl.uniformMatrix4fvX=this.gl.uniformMatrix4fv
  9966. this.gl.uniformMatrix4fv=function(uniform,transpose,array){
  9967. if(!transpose){
  9968. this.uniformMatrix4fvX(uniform,false,array);
  9969. }else{
  9970. GLGE.mat4gl(GLGE.transposeMat4(array),array);
  9971. this.uniformMatrix4fvX(uniform,false,array);
  9972. }
  9973. }
  9974. var gl=this.gl;
  9975. /*this.gl.texImage2Dx=this.gl.texImage2D;
  9976. this.gl.texImage2D=function(){
  9977. if(arguments.length==9){
  9978. gl.texImage2Dx(arguments[0], arguments[1], arguments[2],arguments[3],arguments[4],arguments[5],arguments[6],arguments[7],arguments[8]);
  9979. }else{
  9980. gl.texImage2Dx(arguments[0], arguments[1], arguments[5],false,false);
  9981. }
  9982. }*/
  9983. //set up defaults
  9984. this.gl.clearDepth(1.0);
  9985. this.gl.clearStencil(0);
  9986. this.gl.enable(this.gl.DEPTH_TEST);
  9987. this.gl.depthFunc(this.gl.LEQUAL);
  9988. this.gl.blendFuncSeparate(this.gl.SRC_ALPHA,this.gl.ONE_MINUS_SRC_ALPHA,this.gl.ZERO,this.gl.ONE);
  9989. };
  9990. GLGE.augment(GLGE.QuickNotation,GLGE.Renderer);
  9991. GLGE.Renderer.prototype.gl=null;
  9992. GLGE.Renderer.prototype.scene=null;
  9993. GLGE.C_STENCIL=1;
  9994. GLGE.C_DEPTH=2;
  9995. GLGE.C_COLOR=4;
  9996. GLGE.C_ALL=7;
  9997. GLGE.Renderer.prototype.clearType=GLGE.C_ALL;
  9998. /**
  9999. * Sets the width of the viewport to render
  10000. * @param width the width of the viewport to render
  10001. */
  10002. GLGE.Renderer.prototype.setViewportWidth=function(width){
  10003. this.viewport[0]=width;
  10004. return this;
  10005. };
  10006. /**
  10007. * Sets the height of the viewport to render
  10008. * @param height the height of the viewport to render
  10009. */
  10010. GLGE.Renderer.prototype.setViewportHeight=function(height){
  10011. this.viewport[1]=height;
  10012. return this;
  10013. };
  10014. /**
  10015. * Sets the left offset of the viewport to render
  10016. * @param left the left offset of the viewport to render
  10017. */
  10018. GLGE.Renderer.prototype.setViewportOffsetX=function(left){
  10019. this.viewport[2]=left;
  10020. return this;
  10021. };
  10022. /**
  10023. * Sets the top offset of the viewport to render
  10024. * @param top the top offset of the viewport to render
  10025. */
  10026. GLGE.Renderer.prototype.setViewportOffsetY=function(top){
  10027. this.viewport[3]=top;
  10028. return this;
  10029. };
  10030. /**
  10031. * Clears all viewport data and defaults back to canvas size
  10032. */
  10033. GLGE.Renderer.prototype.clearViewport=function(){
  10034. this.viewport=[];
  10035. };
  10036. /**
  10037. * Gets the width of the viewport to render
  10038. * @returns the viewport width
  10039. */
  10040. GLGE.Renderer.prototype.getViewportWidth=function(){
  10041. if(this.viewport.length>0){
  10042. return this.viewport[0];
  10043. }else{
  10044. return this.canvas.width;
  10045. }
  10046. };
  10047. /**
  10048. * Gets the height of the viewport to render
  10049. * @returns the viewport height
  10050. */
  10051. GLGE.Renderer.prototype.getViewportHeight=function(){
  10052. if(this.viewport.length>0){
  10053. return this.viewport[1];
  10054. }else{
  10055. return this.canvas.height;
  10056. }
  10057. };
  10058. /**
  10059. * Gets the left offset of the viewport to render
  10060. * @returns the left viewport offset
  10061. */
  10062. GLGE.Renderer.prototype.getViewportOffsetX=function(){
  10063. if(this.viewport.length>0){
  10064. return this.viewport[2];
  10065. }else{
  10066. return 0;
  10067. }
  10068. };
  10069. /**
  10070. * Gets the top offset of the viewport to render
  10071. * @returns the top viewport offset
  10072. */
  10073. GLGE.Renderer.prototype.getViewportOffsetY=function(){
  10074. if(this.viewport.length>0){
  10075. return this.viewport[3];
  10076. }else{
  10077. return 0;
  10078. }
  10079. };
  10080. /**
  10081. * Sets the clear type for rendering GLGE.C_ALL, GLGE.C_STENCIL, GLGE.C_DEPTH, GLGE.C_COLOR
  10082. * @param type how to clear the viewport for the next render
  10083. */
  10084. GLGE.Renderer.prototype.setClearType=function(type){
  10085. this.clearType=type;
  10086. return this;
  10087. };
  10088. /**
  10089. * Gets the clear type for rendering GLGE.C_ALL, GLGE.C_STENCIL, GLGE.C_DEPTH, GLGE.C_COLOR
  10090. * @returns how to clear the viewport for the next render
  10091. */
  10092. GLGE.Renderer.prototype.getClearType=function(){
  10093. return this.clearType;
  10094. };
  10095. /**
  10096. * Clears the viewport
  10097. * @private
  10098. */
  10099. GLGE.Renderer.prototype.GLClear=function(){
  10100. var gl=this.gl;
  10101. var clearType=this.clearType;
  10102. var clear=0;
  10103. if((clearType & GLGE.C_COLOR) == GLGE.C_COLOR){
  10104. clear=clear | gl.COLOR_BUFFER_BIT;
  10105. }
  10106. if((clearType & GLGE.C_DEPTH) == GLGE.C_DEPTH){
  10107. clear=clear | gl.DEPTH_BUFFER_BIT;
  10108. }
  10109. if((clearType & GLGE.C_STENCIL) == GLGE.C_STENCIL){
  10110. clear=clear | gl.STENCIL_BUFFER_BIT;
  10111. }
  10112. gl.clear(clear);
  10113. };
  10114. /**
  10115. * Gets the scene which is set to be rendered
  10116. * @returns the current render scene
  10117. */
  10118. GLGE.Renderer.prototype.getScene=function(){
  10119. return this.scene;
  10120. };
  10121. /**
  10122. * Sets the scene to render
  10123. * @param {GLGE.Scene} scene The scene to be rendered
  10124. */
  10125. GLGE.Renderer.prototype.setScene=function(scene){
  10126. scene.renderer=this;
  10127. this.scene=scene;
  10128. if(!scene.gl) scene.GLInit(this.gl);
  10129. //this.render();
  10130. scene.camera.updateMatrix(); //reset camera matrix to force cache update
  10131. return this;
  10132. };
  10133. /**
  10134. * Renders the current scene to the canvas
  10135. */
  10136. GLGE.Renderer.prototype.render=function(){
  10137. if(this.transitonFilter){
  10138. var now=+new Date;
  10139. if(now<this.transStarted+this.transDuration) {
  10140. this.GLRenderTransition((now-this.transStarted)/this.transDuration);
  10141. return;
  10142. }
  10143. if(this.transStarted==1){
  10144. this.GLRenderTransition(0);
  10145. this.transStarted=+new Date;
  10146. }
  10147. }
  10148. if(this.cullFaces) this.gl.enable(this.gl.CULL_FACE);
  10149. if (this.scene) this.scene.render(this.gl);
  10150. //if this is the first ever pass then render twice to fill shadow buffers
  10151. if(!this.rendered&&this.scene){
  10152. this.scene.render(this.gl);
  10153. this.rendered=true;
  10154. }
  10155. };
  10156. /**
  10157. * Uses the transitions filter to transition to the new scene
  10158. * @param {GLGE.Scene} scene The scene to transition to
  10159. * @param {Number} duration The transiton time in ms
  10160. */
  10161. GLGE.Renderer.prototype.transitionTo=function(scene,duration){
  10162. if(this.transitonFilter){
  10163. this.transitonFilter.clearPersist(this.gl);
  10164. this.oldScene=this.scene;
  10165. this.transStarted=1;
  10166. this.transDuration=duration;
  10167. }
  10168. this.setScene(scene);
  10169. };
  10170. /**
  10171. * Creates the buffers needed for transitions
  10172. * @private
  10173. */
  10174. GLGE.Renderer.prototype.createTransitionBuffers=function(){
  10175. var gl=this.gl;
  10176. //Transition source buffer
  10177. this.frameBufferTS = gl.createFramebuffer();
  10178. this.renderBufferTS = gl.createRenderbuffer();
  10179. this.textureTS = gl.createTexture();
  10180. gl.bindTexture(gl.TEXTURE_2D, this.textureTS);
  10181. this.widthTS=this.getViewportWidth();
  10182. this.heightTS=this.getViewportHeight();
  10183. gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.widthTS,this.heightTS, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
  10184. gl.bindFramebuffer(gl.FRAMEBUFFER, this.frameBufferTS);
  10185. gl.bindRenderbuffer(gl.RENDERBUFFER, this.renderBufferTS);
  10186. gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, this.widthTS, this.heightTS);
  10187. gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.textureTS, 0);
  10188. gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, this.renderBufferTS);
  10189. gl.bindFramebuffer(gl.FRAMEBUFFER, null);
  10190. gl.bindRenderbuffer(gl.RENDERBUFFER, null);
  10191. gl.bindTexture(gl.TEXTURE_2D, null);
  10192. //Transition destination buffer
  10193. this.frameBufferTD = gl.createFramebuffer();
  10194. this.renderBufferTD = gl.createRenderbuffer();
  10195. this.textureTD = gl.createTexture();
  10196. gl.bindTexture(gl.TEXTURE_2D, this.textureTD);
  10197. this.widthTD=this.getViewportWidth();
  10198. this.heightTD=this.getViewportHeight();
  10199. gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.widthTD,this.heightTD, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
  10200. gl.bindFramebuffer(gl.FRAMEBUFFER, this.frameBufferTD);
  10201. gl.bindRenderbuffer(gl.RENDERBUFFER, this.renderBufferTD);
  10202. gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, this.widthTD, this.heightTD);
  10203. gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.textureTD, 0);
  10204. gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, this.renderBufferTD);
  10205. gl.bindFramebuffer(gl.FRAMEBUFFER, null);
  10206. gl.bindRenderbuffer(gl.RENDERBUFFER, null);
  10207. gl.bindTexture(gl.TEXTURE_2D, null);
  10208. };
  10209. /**
  10210. * Sets the filter to use for the transition
  10211. * @param {GLGE.Filter2d} filter2d the 2d filter to use for transitions
  10212. */
  10213. GLGE.Renderer.prototype.setTransitionFilter=function(filter2d){
  10214. if(this.gl) filter2d.getFrameBuffer(this.gl);
  10215. this.transitonFilter=filter2d;
  10216. var renderer=this;
  10217. filter2d.textures=[
  10218. {
  10219. name: "GLGE_SOURCE",
  10220. doTexture: function(gl){
  10221. gl.bindTexture(gl.TEXTURE_2D, renderer.textureTS);
  10222. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
  10223. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
  10224. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
  10225. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
  10226. }
  10227. },
  10228. {
  10229. name: "GLGE_DEST",
  10230. doTexture: function(gl){
  10231. gl.bindTexture(gl.TEXTURE_2D, renderer.textureTD);
  10232. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
  10233. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
  10234. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
  10235. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
  10236. }
  10237. }
  10238. ];
  10239. return this;
  10240. }
  10241. /**
  10242. * Renders the transition effect
  10243. * @private
  10244. */
  10245. GLGE.Renderer.prototype.GLRenderTransition=function(time){
  10246. this.transitonFilter.setUniform("1f","time",time);
  10247. if(!this.frameBufferTS){
  10248. this.createTransitionBuffers();
  10249. this.transitonFilter.getFrameBuffer(this.gl);
  10250. }
  10251. this.scene.transbuffer=this.frameBufferTS;
  10252. this.scene.render(this.gl);
  10253. this.scene.transbuffer=null;
  10254. this.oldScene.transbuffer=this.frameBufferTD;
  10255. this.oldScene.render(this.gl);
  10256. this.oldScene.transbuffer=null;
  10257. this.transitonFilter.GLRender(this.gl);
  10258. }
  10259. })(GLGE);/*
  10260. GLGE WebGL Graphics Engine
  10261. Copyright (c) 2010, Paul Brunt
  10262. All rights reserved.
  10263. Redistribution and use in source and binary forms, with or without
  10264. modification, are permitted provided that the following conditions are met:
  10265. * Redistributions of source code must retain the above copyright
  10266. notice, this list of conditions and the following disclaimer.
  10267. * Redistributions in binary form must reproduce the above copyright
  10268. notice, this list of conditions and the following disclaimer in the
  10269. documentation and/or other materials provided with the distribution.
  10270. * Neither the name of GLGE nor the
  10271. names of its contributors may be used to endorse or promote products
  10272. derived from this software without specific prior written permission.
  10273. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  10274. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  10275. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  10276. DISCLAIMED. IN NO EVENT SHALL PAUL BRUNT BE LIABLE FOR ANY
  10277. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  10278. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  10279. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  10280. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  10281. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  10282. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  10283. */
  10284. /**
  10285. * @fileOverview
  10286. * @name glge_camera.js
  10287. * @author me@paulbrunt.co.uk
  10288. */
  10289. (function(GLGE){
  10290. /**
  10291. * @constant
  10292. * @description Enumeration for a perspective camera
  10293. */
  10294. GLGE.C_PERSPECTIVE=1;
  10295. /**
  10296. * @constant
  10297. * @description Enumeration for a orthographic camera
  10298. */
  10299. GLGE.C_ORTHO=2;
  10300. /**
  10301. * @class Creates a new camera object
  10302. * @augments GLGE.Animatable
  10303. * @augments GLGE.Placeable
  10304. * @augments GLGE.QuickNotation
  10305. * @augments GLGE.JSONLoader
  10306. */
  10307. GLGE.Camera=function(uid){
  10308. GLGE.Assets.registerAsset(this,uid);
  10309. };
  10310. GLGE.augment(GLGE.Placeable,GLGE.Camera);
  10311. GLGE.augment(GLGE.Animatable,GLGE.Camera);
  10312. GLGE.augment(GLGE.QuickNotation,GLGE.Camera);
  10313. GLGE.augment(GLGE.JSONLoader,GLGE.Camera);
  10314. GLGE.Camera.prototype.className="Camera";
  10315. GLGE.Camera.prototype.fovy=35;
  10316. GLGE.Camera.prototype.aspect=1.0;
  10317. GLGE.Camera.prototype.near=0.1;
  10318. GLGE.Camera.prototype.far=1000.0;
  10319. GLGE.Camera.prototype.orthoscale=5;
  10320. GLGE.Camera.prototype.type=GLGE.C_PERSPECTIVE;
  10321. GLGE.Camera.prototype.pMatrix=null;
  10322. /**
  10323. * Method gets the orthographic scale for the camers
  10324. * @return {Matrix} Returns the orthographic scale
  10325. */
  10326. GLGE.Camera.prototype.getOrthoScale=function(){
  10327. if(this.type==GLGE.C_ORTHO) {
  10328. return this.orthoscale
  10329. }else{
  10330. GLGE.error("You may only get a scale for a orthographic camera");
  10331. return 1;
  10332. }
  10333. };
  10334. /**
  10335. * Method sets the orthographic scale for the camers
  10336. * @param {number} scale The new orthographic scale
  10337. */
  10338. GLGE.Camera.prototype.setOrthoScale=function(scale){
  10339. if(this.type==GLGE.C_ORTHO) {
  10340. this.orthoscale=scale;
  10341. this.pMatrix=null;
  10342. }
  10343. else
  10344. {
  10345. GLGE.error("You may only set a scale for a orthographic camera");
  10346. }
  10347. return this;
  10348. };
  10349. /**
  10350. * Method gets the far drawing distance
  10351. * @return {Matrix} Returns the cameras far draw distance
  10352. */
  10353. GLGE.Camera.prototype.getFar=function(){
  10354. return this.far;
  10355. };
  10356. /**
  10357. * Method sets the far draw distance of the camera
  10358. * @param {number} distance The far draw distance
  10359. */
  10360. GLGE.Camera.prototype.setFar=function(distance){
  10361. this.pMatrix=null;
  10362. this.far=+distance;
  10363. return this;
  10364. };
  10365. /**
  10366. * Method gets the near drawing distance
  10367. * @return {Matrix} Returns the cameras near draw distance
  10368. */
  10369. GLGE.Camera.prototype.getNear=function(){
  10370. return this.near;
  10371. };
  10372. /**
  10373. * Method sets the near draw distance of the camera
  10374. * @param {number} distance The near draw distance
  10375. */
  10376. GLGE.Camera.prototype.setNear=function(distance){
  10377. this.pMatrix=null;
  10378. this.near=+distance;
  10379. return this;
  10380. };
  10381. /**
  10382. * Method gets the current camera type
  10383. * @return {Matrix} Returns the camera type
  10384. */
  10385. GLGE.Camera.prototype.getType=function(){
  10386. this.pMatrix=null;
  10387. return this.type
  10388. };
  10389. /**
  10390. * Method sets the type of camera GLGE.C_PERSPECTIVE or GLGE.C_ORTHO
  10391. * @param {number} type The type of this camera
  10392. */
  10393. GLGE.Camera.prototype.setType=function(type){
  10394. if(type==GLGE.C_PERSPECTIVE || type==GLGE.C_ORTHO){
  10395. this.type=type;
  10396. this.pMatrix=null;
  10397. }else{
  10398. GLGE.error("unsuported camera type");
  10399. }
  10400. return this;
  10401. };
  10402. /**
  10403. * Method gets the current yfov if the camera type is GLGE.C_PERSPECTIVE
  10404. * @return {Matrix} Returns the yfov
  10405. */
  10406. GLGE.Camera.prototype.getFovY=function(){
  10407. if(this.type==GLGE.C_PERSPECTIVE) {
  10408. return this.fovy
  10409. }else{
  10410. GLGE.error("You may only get a yfov for a perspective camera");
  10411. return 1;
  10412. }
  10413. };
  10414. /**
  10415. * Method sets the yfov of the camera
  10416. * @param {number} yfov The new yfov of the camera
  10417. */
  10418. GLGE.Camera.prototype.setFovY=function(fovy){
  10419. if(this.type==GLGE.C_PERSPECTIVE) {
  10420. this.fovy=+fovy;
  10421. this.ymax=null;
  10422. this.pMatrix=null;
  10423. }
  10424. else
  10425. {
  10426. GLGE.error("You may only set a yfov for a perspective camera");
  10427. }
  10428. return this;
  10429. };
  10430. /**
  10431. * Method gets the current aspect if the camera type is GLGE.C_PERSPECTIVE
  10432. * @return {Matrix} Returns the yfov
  10433. */
  10434. GLGE.Camera.prototype.getAspect=function(){
  10435. if(this.type==GLGE.C_PERSPECTIVE || this.type==GLGE.C_ORTHO) {
  10436. return this.aspect
  10437. }
  10438. else
  10439. {
  10440. GLGE.error("You may only set a aspect for a perspective or orthographic camera");
  10441. return 1;
  10442. }
  10443. };
  10444. /**
  10445. * Method sets the aspect of the camera
  10446. * @param {number} aspect The new projection matrix
  10447. */
  10448. GLGE.Camera.prototype.setAspect=function(aspect){
  10449. if(this.type==GLGE.C_PERSPECTIVE || this.type==GLGE.C_ORTHO) {
  10450. this.aspect=+aspect;
  10451. this.pMatrix=null;
  10452. }
  10453. else
  10454. {
  10455. GLGE.error("You may only set a aspect for a perspective or orthographic camera");
  10456. }
  10457. return this;
  10458. };
  10459. /**
  10460. * Method gets the current projection matrix of this camera
  10461. * @return {Matrix} Returns the camera projection matrix
  10462. */
  10463. GLGE.Camera.prototype.getProjectionMatrix=function(){
  10464. if(!this.pMatrix){
  10465. if(this.pMatrixOveride){
  10466. this.pMatrix=this.pMatrixOveride;
  10467. }else{
  10468. switch(this.type){
  10469. case GLGE.C_PERSPECTIVE:
  10470. this.pMatrix=GLGE.makePerspective(this.fovy, this.aspect, this.near, this.far);
  10471. break;
  10472. case GLGE.C_ORTHO:
  10473. this.pMatrix=GLGE.makeOrtho(-this.orthoscale*this.aspect,this.orthoscale*this.aspect,-this.orthoscale,this.orthoscale, this.near, this.far);
  10474. break;
  10475. }
  10476. }
  10477. }
  10478. return this.pMatrix;
  10479. };
  10480. /**
  10481. * Method generates the projection matrix based on the
  10482. * camera paramaters
  10483. * @param {Matrix} projection The new projection matrix
  10484. */
  10485. GLGE.Camera.prototype.setProjectionMatrix=function(projection){
  10486. this.pMatrix=projection;
  10487. return this;
  10488. };
  10489. /**
  10490. * Method sets a custom projection matrix
  10491. * @param {Matrix} projection The new projection matrix
  10492. */
  10493. GLGE.Camera.prototype.setCustomProjectionMatrix=function(projection){
  10494. this.pMatrix=projection;
  10495. this.pMatrixOveride=projection;
  10496. return this;
  10497. };
  10498. /**
  10499. * Method generates the cameras view matrix
  10500. * @return Returns the view matrix based on this camera
  10501. * @type Matrix
  10502. */
  10503. GLGE.Camera.prototype.updateMatrix=function(){
  10504. var position=this.getPosition();
  10505. var vMatrix=GLGE.translateMatrix(position.x,position.y,position.z);
  10506. vMatrix=GLGE.mulMat4(vMatrix,this.getRotMatrix());
  10507. if(this.parent) vMatrix=GLGE.mulMat4(this.parent.getModelMatrix(),vMatrix);
  10508. this.location=[vMatrix[3],vMatrix[7],vMatrix[11]];
  10509. this.matrix=GLGE.inverseMat4(vMatrix);
  10510. };
  10511. /**
  10512. * Method generates the cameras view matrix
  10513. * @return Returns the view matrix based on this camera
  10514. * @type Matrix
  10515. */
  10516. GLGE.Camera.prototype.getViewMatrix=function(){
  10517. if(!this.matrix || !this.rotmatrix) this.updateMatrix();
  10518. return this.matrix;
  10519. };
  10520. /**
  10521. * Method generates the cameras view projection matrix
  10522. * @return Returns the view projection matrix based on this camera
  10523. * @type Matrix
  10524. */
  10525. GLGE.Camera.prototype.getViewProjection=function(){
  10526. var projectionMatrix=this.getProjectionMatrix();
  10527. var viewMatrix=this.getViewMatrix();
  10528. if(projectionMatrix!=this.vpProjectionMatrix || viewMatrix!=this.vpViewMatrix){
  10529. this.cameraViewProjection=GLGE.mulMat4(projectionMatrix,viewMatrix);
  10530. this.vpProjectionMatrix=projectionMatrix;
  10531. this.vpViewMatrix=viewMatrix;
  10532. }
  10533. return this.cameraViewProjection;
  10534. };
  10535. })(GLGE);/*
  10536. GLGE WebGL Graphics Engine
  10537. Copyright (c) 2010, Paul Brunt
  10538. All rights reserved.
  10539. Redistribution and use in source and binary forms, with or without
  10540. modification, are permitted provided that the following conditions are met:
  10541. * Redistributions of source code must retain the above copyright
  10542. notice, this list of conditions and the following disclaimer.
  10543. * Redistributions in binary form must reproduce the above copyright
  10544. notice, this list of conditions and the following disclaimer in the
  10545. documentation and/or other materials provided with the distribution.
  10546. * Neither the name of GLGE nor the
  10547. names of its contributors may be used to endorse or promote products
  10548. derived from this software without specific prior written permission.
  10549. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  10550. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  10551. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  10552. DISCLAIMED. IN NO EVENT SHALL PAUL BRUNT BE LIABLE FOR ANY
  10553. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  10554. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  10555. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  10556. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  10557. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  10558. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  10559. */
  10560. /**
  10561. * @fileOverview
  10562. * @name glge_light.js
  10563. * @author me@paulbrunt.co.uk
  10564. */
  10565. (function(GLGE){
  10566. /**
  10567. * @class Creates a new light source to be added to a scene
  10568. * @property {Boolean} diffuse Dose this light source effect diffuse shading
  10569. * @property {Boolean} specular Dose this light source effect specular shading
  10570. * @augments GLGE.Animatable
  10571. * @augments GLGE.Placeable
  10572. * @augments GLGE.QuickNotation
  10573. * @augments GLGE.JSONLoader
  10574. */
  10575. GLGE.Light=function(uid){
  10576. this.color={r:1,g:1,b:1};
  10577. GLGE.Assets.registerAsset(this,uid);
  10578. }
  10579. GLGE.augment(GLGE.Placeable,GLGE.Light);
  10580. GLGE.augment(GLGE.Animatable,GLGE.Light);
  10581. GLGE.augment(GLGE.QuickNotation,GLGE.Light);
  10582. GLGE.augment(GLGE.JSONLoader,GLGE.Light);
  10583. GLGE.Light.prototype.className="Light";
  10584. /**
  10585. * @name GLGE.Light#shaderupdate
  10586. * @event fires when a light has changed resulting in need to recompile shaders
  10587. * @param {object} data
  10588. */
  10589. /**
  10590. * @constant
  10591. * @description Enumeration for an point light source
  10592. */
  10593. GLGE.L_POINT=1;
  10594. /**
  10595. * @constant
  10596. * @description Enumeration for an directional light source
  10597. */
  10598. GLGE.L_DIR=2;
  10599. /**
  10600. * @constant
  10601. * @description Enumeration for an spot light source
  10602. */
  10603. GLGE.L_SPOT=3;
  10604. /**
  10605. * @constant
  10606. * @description Enumeration a light that is disabled
  10607. */
  10608. GLGE.L_OFF=4;
  10609. GLGE.Light.prototype.constantAttenuation=1;
  10610. GLGE.Light.prototype.linearAttenuation=0.002;
  10611. GLGE.Light.prototype.quadraticAttenuation=0.0008;
  10612. GLGE.Light.prototype.spotCosCutOff=0.95;
  10613. GLGE.Light.prototype.spotCutOff=true;
  10614. GLGE.Light.prototype.spotPMatrix=null;
  10615. GLGE.Light.prototype.spotExponent=10;
  10616. GLGE.Light.prototype.color=null;
  10617. GLGE.Light.prototype.diffuse=true;
  10618. GLGE.Light.prototype.specular=true;
  10619. GLGE.Light.prototype.samples=0;
  10620. GLGE.Light.prototype.softness=0.01;
  10621. GLGE.Light.prototype.type=GLGE.L_POINT;
  10622. GLGE.Light.prototype.frameBuffer=null;
  10623. GLGE.Light.prototype.renderBuffer=null;
  10624. GLGE.Light.prototype.texture=null;
  10625. GLGE.Light.prototype.bufferHeight=256;
  10626. GLGE.Light.prototype.bufferWidth=256;
  10627. GLGE.Light.prototype.shadowBias=0.002;
  10628. GLGE.Light.prototype.castShadows=false;
  10629. GLGE.Light.prototype.cascadeLevels=3;
  10630. GLGE.Light.prototype.distance=500;
  10631. GLGE.Light.prototype.spotSoftness=0;
  10632. GLGE.Light.prototype.spotSoftnessDistance=0.3;
  10633. /**
  10634. * Gets the number of cascade levels to use for directional shadows
  10635. * @returns {number} the number of cascades
  10636. */
  10637. GLGE.Light.prototype.getCascadeLevels=function(){
  10638. return this.cascadeLevels;
  10639. }
  10640. /**
  10641. * Sets the number of cascade levels for directions shadows
  10642. * @param {number} cascadeLevels The number of cascade levels(higher slower better quailty)
  10643. */
  10644. GLGE.Light.prototype.setCascadeLevels=function(cascadeLevels){
  10645. this.cascadeLevels=+cascadeLevels;
  10646. this.fireEvent("shaderupdate",{});
  10647. return this;
  10648. }
  10649. /**
  10650. * Gets the spot lights projection matrix
  10651. * @returns the lights spot projection matrix
  10652. * @private
  10653. */
  10654. GLGE.Light.prototype.getPMatrix=function(cvp,invlight,projectedDistance,distance){
  10655. if(!this.spotPMatrix){
  10656. var far;
  10657. if(this.scene && this.scene.camera) far=this.scene.camera.far;
  10658. else far=1000;
  10659. if(this.type==GLGE.L_SPOT){
  10660. this.spotPMatrix=GLGE.makePerspective(Math.acos(this.spotCosCutOff)/3.14159*360, 1.0, 0.1, far);
  10661. }
  10662. }
  10663. if(this.type==GLGE.L_DIR){
  10664. this.spotPMatrix=GLGE.getDirLightProjection(cvp,invlight,projectedDistance,distance);
  10665. }
  10666. return this.spotPMatrix;
  10667. }
  10668. /**
  10669. * Sets the shadow casting flag
  10670. * @param {number} distance
  10671. */
  10672. GLGE.Light.prototype.setDistance=function(value){
  10673. this.distance=value;
  10674. this.fireEvent("shaderupdate",{});
  10675. return this;
  10676. }
  10677. /**
  10678. * Gets the shadow casting distance
  10679. * @returns {number} distance
  10680. */
  10681. GLGE.Light.prototype.getDistance=function(){
  10682. return this.distance;
  10683. }
  10684. /**
  10685. * Sets negative shadow flag
  10686. * @param {boolean} negative shadow
  10687. */
  10688. GLGE.Light.prototype.setNegativeShadow=function(value){
  10689. this.negativeShadow=value;
  10690. this.fireEvent("shaderupdate",{});
  10691. return this;
  10692. }
  10693. /**
  10694. * Gets negative shadow flag
  10695. * @param {boolean} negative shadow
  10696. */
  10697. GLGE.Light.prototype.getNegative=function(){
  10698. return this.negativeShadow;
  10699. }
  10700. /**
  10701. * Sets the shadow casting flag
  10702. * @param {number} value should cast shadows?
  10703. */
  10704. GLGE.Light.prototype.setCastShadows=function(value){
  10705. this.castShadows=value;
  10706. this.fireEvent("shaderupdate",{});
  10707. return this;
  10708. }
  10709. /**
  10710. * Gets the shadow casting flag
  10711. * @returns {number} true if casts shadows
  10712. */
  10713. GLGE.Light.prototype.getCastShadows=function(){
  10714. return this.castShadows;
  10715. return this;
  10716. }
  10717. /**
  10718. * Sets the shadow bias
  10719. * @param {number} value The shadow bias
  10720. */
  10721. GLGE.Light.prototype.setShadowBias=function(value){
  10722. this.shadowBias=value;
  10723. return this;
  10724. }
  10725. /**
  10726. * Gets the shadow bias
  10727. * @returns {number} The shadow buffer bias
  10728. */
  10729. GLGE.Light.prototype.getShadowBias=function(){
  10730. return this.shadowBias;
  10731. }
  10732. /**
  10733. * Sets the number of samples for this shadow
  10734. * @param {number} value The number of samples to perform
  10735. */
  10736. GLGE.Light.prototype.setShadowSamples=function(value){
  10737. this.samples=value;
  10738. this.fireEvent("shaderupdate",{});
  10739. return this;
  10740. }
  10741. /**
  10742. * Gets the number of samples for this shadow
  10743. * @returns {number} The number of samples
  10744. */
  10745. GLGE.Light.prototype.getShadowSamples=function(){
  10746. return this.samples;
  10747. }
  10748. /**
  10749. * Sets the shadow softness
  10750. * @param {number} value The number of samples to perform
  10751. */
  10752. GLGE.Light.prototype.setShadowSoftness=function(value){
  10753. this.softness=value;
  10754. this.fireEvent("shaderupdate",{});
  10755. return this;
  10756. }
  10757. /**
  10758. * Gets the shadow softness
  10759. * @returns {number} The softness of the shadows
  10760. */
  10761. GLGE.Light.prototype.getShadowSoftness=function(){
  10762. return this.softness;
  10763. }
  10764. /**
  10765. * Sets the shadow buffer width
  10766. * @param {number} value The shadow buffer width
  10767. */
  10768. GLGE.Light.prototype.setBufferWidth=function(value){
  10769. this.bufferWidth=value;
  10770. return this;
  10771. }
  10772. /**
  10773. * Gets the shadow buffer width
  10774. * @returns {number} The shadow buffer width
  10775. */
  10776. GLGE.Light.prototype.getBufferHeight=function(){
  10777. return this.bufferHeight;
  10778. }
  10779. /**
  10780. * Sets the shadow buffer width
  10781. * @param {number} value The shadow buffer width
  10782. */
  10783. GLGE.Light.prototype.setBufferHeight=function(value){
  10784. this.bufferHeight=value;
  10785. return this;
  10786. }
  10787. /**
  10788. * Gets the shadow buffer width
  10789. * @returns {number} The shadow buffer width
  10790. */
  10791. GLGE.Light.prototype.getBufferWidth=function(){
  10792. return this.bufferWidth;
  10793. }
  10794. /**
  10795. * Sets the spot light cut off
  10796. * @param {number} value The cos of the angle to limit
  10797. */
  10798. GLGE.Light.prototype.setSpotCosCutOff=function(value){
  10799. this.spotPMatrix=null;
  10800. this.spotCosCutOff=value;
  10801. return this;
  10802. }
  10803. /**
  10804. * Gets the spot light cut off
  10805. * @returns {number} The cos of the limiting angle
  10806. */
  10807. GLGE.Light.prototype.getSpotCosCutOff=function(){
  10808. return this.spotCosCutOff;
  10809. }
  10810. /**
  10811. * Sets the spot light cut off true results in circle spot light otherwise square
  10812. * @param {number} value The spot cutoff flag
  10813. */
  10814. GLGE.Light.prototype.setSpotCutOff=function(value){
  10815. this.spotCutOff=value;
  10816. this.fireEvent("shaderupdate",{});
  10817. return this;
  10818. }
  10819. /**
  10820. * Gets the spot light cut off flag
  10821. * @returns {number} The spot cutoff flag
  10822. */
  10823. GLGE.Light.prototype.getSpotCutOff=function(){
  10824. return this.spotCutOff;
  10825. }
  10826. /**
  10827. * Sets the spot light exponent
  10828. * @param {number} value The spot lights exponent
  10829. */
  10830. GLGE.Light.prototype.setSpotExponent=function(value){
  10831. this.spotExponent=value;
  10832. return this;
  10833. }
  10834. /**
  10835. * Gets the spot light exponent
  10836. * @returns {number} The exponent of the spot light
  10837. */
  10838. GLGE.Light.prototype.getSpotExponent=function(){
  10839. return this.spotExponent;
  10840. }
  10841. /**
  10842. * Sets the light sources Attenuation
  10843. * @returns {Object} The components of the light sources attenuation
  10844. */
  10845. GLGE.Light.prototype.getAttenuation=function(){
  10846. var attenuation={};
  10847. attenuation.constant=this.constantAttenuation;
  10848. attenuation.linear=this.linearAttenuation;
  10849. attenuation.quadratic=this.quadraticAttenuation;
  10850. return attenuation;
  10851. }
  10852. /**
  10853. * Sets the light sources Attenuation
  10854. * @param {Number} constant The constant part of the attenuation
  10855. * @param {Number} linear The linear part of the attenuation
  10856. * @param {Number} quadratic The quadratic part of the attenuation
  10857. */
  10858. GLGE.Light.prototype.setAttenuation=function(constant,linear,quadratic){
  10859. this.constantAttenuation=constant;
  10860. this.linearAttenuation=linear;
  10861. this.quadraticAttenuation=quadratic;
  10862. return this;
  10863. }
  10864. /**
  10865. * Sets the light sources constant attenuation
  10866. * @param {Number} value The constant part of the attenuation
  10867. */
  10868. GLGE.Light.prototype.setAttenuationConstant=function(value){
  10869. this.constantAttenuation=value;
  10870. return this;
  10871. }
  10872. /**
  10873. * Sets the light sources linear attenuation
  10874. * @param {Number} value The linear part of the attenuation
  10875. */
  10876. GLGE.Light.prototype.setAttenuationLinear=function(value){
  10877. this.linearAttenuation=value;
  10878. return this;
  10879. }
  10880. /**
  10881. * Sets the light sources quadratic attenuation
  10882. * @param {Number} value The quadratic part of the attenuation
  10883. */
  10884. GLGE.Light.prototype.setAttenuationQuadratic=function(value){
  10885. this.quadraticAttenuation=value;
  10886. return this;
  10887. }
  10888. /**
  10889. * Sets the color of the light source
  10890. * @param {string} color The color of the light
  10891. */
  10892. GLGE.Light.prototype.setColor=function(color){
  10893. color=GLGE.colorParse(color);
  10894. this.color={r:color.r,g:color.g,b:color.b};
  10895. return this;
  10896. }
  10897. /**
  10898. * Sets the red color of the light source
  10899. * @param {Number} value The new red level 0-1
  10900. */
  10901. GLGE.Light.prototype.setColorR=function(value){
  10902. this.color.r=value;
  10903. return this;
  10904. }
  10905. /**
  10906. * Sets the green color of the light source
  10907. * @param {Number} value The new green level 0-1
  10908. */
  10909. GLGE.Light.prototype.setColorG=function(value){
  10910. this.color.g=value;
  10911. return this;
  10912. }
  10913. /**
  10914. * Sets the blue color of the light source
  10915. * @param {Number} value The new blue level 0-1
  10916. */
  10917. GLGE.Light.prototype.setColorB=function(value){
  10918. this.color.b=value;
  10919. return this;
  10920. }
  10921. /**
  10922. * Gets the current color of the light source
  10923. * @return {[r,g,b]} The current position
  10924. */
  10925. GLGE.Light.prototype.getColor=function(){
  10926. return this.color;
  10927. }
  10928. /**
  10929. * Gets the type of the light
  10930. * @return {Number} The type of the light source eg GLGE.L_POINT
  10931. */
  10932. GLGE.Light.prototype.getType=function(){
  10933. return this.type;
  10934. }
  10935. /**
  10936. * Sets the type of the light
  10937. * @param {Number} type The type of the light source eg GLGE.L_POINT
  10938. */
  10939. GLGE.Light.prototype.setType=function(type){
  10940. this.type=type;
  10941. this.fireEvent("shaderupdate",{});
  10942. return this;
  10943. }
  10944. /**
  10945. * Gets the softness of the spot shadow
  10946. * @return {Number} The type of the light source eg GLGE.L_POINT
  10947. */
  10948. GLGE.Light.prototype.getSpotSoftness=function(){
  10949. return this.spotSoftness;
  10950. }
  10951. /**
  10952. * Sets the softness of the spot shadow
  10953. * @param {Number} spotSoftness The type of the light source eg GLGE.L_POINT
  10954. */
  10955. GLGE.Light.prototype.setSpotSoftness=function(spotSoftness){
  10956. this.spotSoftness=+spotSoftness;
  10957. if(this.gl) this.createSoftPrograms(this.gl);
  10958. this.fireEvent("shaderupdate",{});
  10959. return this;
  10960. }
  10961. /**
  10962. * Gets the spotlights blur distance in pixels
  10963. * @return {Number} The blur distance for spot lights
  10964. */
  10965. GLGE.Light.prototype.getSpotSoftDistance=function(){
  10966. return this.spotSoftnessDistance;
  10967. }
  10968. /**
  10969. * Sets the spotlights variance cutoff used to reduce light bleed
  10970. * @param {Number} spotSoftnessDistance the spotlights variance cutoff
  10971. */
  10972. GLGE.Light.prototype.setSpotSoftDistance=function(spotSoftnessDistance){
  10973. this.spotSoftnessDistance=+spotSoftnessDistance;
  10974. this.fireEvent("shaderupdate",{});
  10975. return this;
  10976. }
  10977. GLGE.Light.prototype.getEnable=function() {
  10978. return !( this.type == GLGE.L_OFF && this.old_type !== undefined );
  10979. }
  10980. GLGE.Light.prototype.enableLight=function(){
  10981. if (this.type == GLGE.L_OFF && this.old_type !== undefined) {
  10982. this.setType(this.old_type);
  10983. delete this.old_type;
  10984. }
  10985. };
  10986. GLGE.Light.prototype.disableLight=function(){
  10987. if (this.type != GLGE.L_OFF) {
  10988. this.old_type=this.type;
  10989. this.setType(GLGE.L_OFF);
  10990. }
  10991. };
  10992. /**
  10993. * init for the rendering
  10994. * @private
  10995. */
  10996. GLGE.Light.prototype.GLInit=function(gl){
  10997. this.gl=gl;
  10998. if((this.type==GLGE.L_SPOT || this.type==GLGE.L_DIR) && !this.texture){
  10999. this.createSpotBuffer(gl);
  11000. this.createSoftBuffer(gl);
  11001. this.createSoftPrograms(gl);
  11002. }
  11003. }
  11004. /**
  11005. * Sets up the WebGL needed to render the depth map for this light source. Only used for spot lights which produce shadows
  11006. * @private
  11007. */
  11008. GLGE.Light.prototype.createSpotBuffer=function(gl){
  11009. this.frameBuffer = gl.createFramebuffer();
  11010. this.renderBuffer = gl.createRenderbuffer();
  11011. this.texture = gl.createTexture();
  11012. gl.bindTexture(gl.TEXTURE_2D, this.texture);
  11013. try {
  11014. gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.bufferWidth, this.bufferHeight, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
  11015. } catch (e) {
  11016. GLGE.error("incompatible texture creation method");
  11017. var width=parseFloat(this.bufferWidth);
  11018. var height=parseFloat(this.bufferHeight);
  11019. var tex = new Uint8Array(width * height * 4);
  11020. gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, tex);
  11021. }
  11022. gl.bindFramebuffer(gl.FRAMEBUFFER, this.frameBuffer);
  11023. gl.bindRenderbuffer(gl.RENDERBUFFER, this.renderBuffer);
  11024. gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, this.bufferWidth, this.bufferHeight);
  11025. gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.texture, 0);
  11026. gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, this.renderBuffer);
  11027. gl.bindFramebuffer(gl.FRAMEBUFFER, null);
  11028. gl.bindRenderbuffer(gl.RENDERBUFFER, null);
  11029. gl.bindTexture(gl.TEXTURE_2D, null);
  11030. }
  11031. /**
  11032. * Sets up the buffers needed for the gaussian blured shadow buffer
  11033. * @private
  11034. */
  11035. GLGE.Light.prototype.createSoftBuffer=function(gl){
  11036. this.frameBufferSf = gl.createFramebuffer();
  11037. this.renderBufferSf = gl.createRenderbuffer();
  11038. this.textureSf = gl.createTexture();
  11039. gl.bindTexture(gl.TEXTURE_2D, this.textureSf);
  11040. try {
  11041. gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.bufferWidth, this.bufferHeight, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
  11042. } catch (e) {
  11043. GLGE.error("incompatible texture creation method");
  11044. var width=parseFloat(this.bufferWidth);
  11045. var height=parseFloat(this.bufferHeight);
  11046. var tex = new Uint8Array(width * height * 4);
  11047. gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, tex);
  11048. }
  11049. gl.bindFramebuffer(gl.FRAMEBUFFER, this.frameBufferSf);
  11050. gl.bindRenderbuffer(gl.RENDERBUFFER, this.renderBufferSf);
  11051. gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, this.bufferWidth, this.bufferHeight);
  11052. gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.textureSf, 0);
  11053. gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, this.renderBufferSf);
  11054. gl.bindFramebuffer(gl.FRAMEBUFFER, null);
  11055. gl.bindRenderbuffer(gl.RENDERBUFFER, null);
  11056. gl.bindTexture(gl.TEXTURE_2D, null);
  11057. //create the vertex positions
  11058. if(!this.posBuffer) this.posBuffer = gl.createBuffer();
  11059. gl.bindBuffer(gl.ARRAY_BUFFER, this.posBuffer);
  11060. gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([1,1,0,-1,1,0,-1,-1,0,1,-1,0]), gl.STATIC_DRAW);
  11061. this.posBuffer.itemSize = 3;
  11062. this.posBuffer.numItems = 4;
  11063. //create the vertex uv coords
  11064. if(!this.uvBuffer) this.uvBuffer = gl.createBuffer();
  11065. gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer);
  11066. gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([1,1,0,1,0,0,1,0]), gl.STATIC_DRAW);
  11067. this.uvBuffer.itemSize = 2;
  11068. this.uvBuffer.numItems = 4;
  11069. //create the faces
  11070. if(!this.GLfaces) this.GLfaces = gl.createBuffer();
  11071. gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.GLfaces);
  11072. gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array([2,1,0,0,3,2]), gl.STATIC_DRAW);
  11073. this.GLfaces.itemSize = 1;
  11074. this.GLfaces.numItems = 6;
  11075. }
  11076. /**
  11077. * Sets up the programs require to do the soft shadows
  11078. * @private
  11079. */
  11080. GLGE.Light.prototype.createSoftPrograms=function(gl){
  11081. if(this.GLShaderProgram) gl.deleteProgram(this.GLShaderProgram);
  11082. var vertexStr="";
  11083. vertexStr+="attribute vec3 position;\n";
  11084. vertexStr+="attribute vec2 uvcoord;\n";
  11085. vertexStr+="varying vec2 texCoord;\n";
  11086. vertexStr+="void main(void){\n";
  11087. vertexStr+="texCoord=uvcoord;\n";
  11088. vertexStr+="gl_Position = vec4(position,1.0);\n";
  11089. vertexStr+="}\n";
  11090. var SAMPLES=this.spotSoftness;
  11091. var fragStr="precision mediump float;\n";
  11092. fragStr=fragStr+"uniform sampler2D TEXTURE;\n";
  11093. fragStr=fragStr+"varying vec2 texCoord;\n";
  11094. fragStr=fragStr+"uniform bool xpass;\n";
  11095. fragStr=fragStr+"float blurSize = "+(1/this.bufferWidth).toFixed(10)+";\n";
  11096. fragStr=fragStr+"float unpack(sampler2D TEX, vec2 co){;";
  11097. fragStr=fragStr+"float value = dot(texture2D(TEX, co), vec4(0.000000059604644775390625,0.0000152587890625,0.00390625,1.0));";
  11098. fragStr=fragStr+"return value;";
  11099. fragStr=fragStr+"}";
  11100. fragStr=fragStr+"vec2 unpack2(sampler2D TEX, vec2 co){;";
  11101. fragStr=fragStr+"vec4 color = texture2D(TEX, co);";
  11102. fragStr=fragStr+"float value1 = dot(color.rg, vec2(0.00390625,1.0));";
  11103. fragStr=fragStr+"float value2 = dot(color.ba, vec2(0.00390625,1.0));";
  11104. fragStr=fragStr+"return vec2(value1,value2);";
  11105. fragStr=fragStr+"}";
  11106. fragStr=fragStr+"vec4 pack(float value){;";
  11107. fragStr=fragStr+"vec4 rgba=fract(value * vec4(16777216.0, 65536.0, 256.0, 1.0));\n";
  11108. fragStr=fragStr+"return rgba-rgba.rrgb*vec4(0.0,0.00390625,0.00390625,0.00390625);";
  11109. fragStr=fragStr+"}";
  11110. fragStr=fragStr+"vec2 pack2(float value){;";
  11111. fragStr=fragStr+"vec2 rg=fract(value * vec2(256.0, 1.0));\n";
  11112. fragStr=fragStr+"return rg-rg.rr*vec2(0.0,0.00390625);";
  11113. fragStr=fragStr+"}";
  11114. fragStr=fragStr+"void main(void){\n";
  11115. fragStr=fragStr+"float value = 0.0;";
  11116. fragStr=fragStr+"vec2 value2;";
  11117. fragStr=fragStr+"float mean = 0.0;";
  11118. fragStr=fragStr+"float mean2 = 0.0;";
  11119. fragStr=fragStr+"float color = 0.0;";
  11120. fragStr=fragStr+"if(xpass){";
  11121. for(var i=-SAMPLES;i<SAMPLES;i++){
  11122. fragStr=fragStr+"value = unpack(TEXTURE, vec2(texCoord.x - "+(i+0.5).toFixed(1)+"*blurSize, texCoord.y));";
  11123. fragStr=fragStr+"mean += value;";
  11124. fragStr=fragStr+"mean2 += value*value;";
  11125. }
  11126. fragStr=fragStr+"gl_FragColor = vec4(pack2(pow(mean2/"+(SAMPLES*2).toFixed(2)+",0.5)),pack2(mean/"+(SAMPLES*2).toFixed(2)+"));\n";
  11127. fragStr=fragStr+"}else{";
  11128. for(var i=-SAMPLES;i<SAMPLES;i++){
  11129. fragStr=fragStr+"value2 = unpack2(TEXTURE, vec2(texCoord.x, texCoord.y - "+(i+0.5).toFixed(1)+"*blurSize));";
  11130. fragStr=fragStr+"mean += value2.g;";
  11131. fragStr=fragStr+"mean2 += pow(value2.r,2.0);";
  11132. }
  11133. fragStr=fragStr+"gl_FragColor = vec4(pack2(pow(mean2/"+(SAMPLES*2).toFixed(2)+",0.5)),pack2(mean/"+(SAMPLES*2).toFixed(2)+"));\n";
  11134. fragStr=fragStr+"}";
  11135. fragStr=fragStr+"}\n";
  11136. this.GLFragmentShader=gl.createShader(gl.FRAGMENT_SHADER);
  11137. this.GLVertexShader=gl.createShader(gl.VERTEX_SHADER);
  11138. gl.shaderSource(this.GLFragmentShader, fragStr);
  11139. gl.compileShader(this.GLFragmentShader);
  11140. if (!gl.getShaderParameter(this.GLFragmentShader, gl.COMPILE_STATUS)) {
  11141. GLGE.error(gl.getShaderInfoLog(this.GLFragmentShader));
  11142. return;
  11143. }
  11144. gl.shaderSource(this.GLVertexShader, vertexStr);
  11145. gl.compileShader(this.GLVertexShader);
  11146. if (!gl.getShaderParameter(this.GLVertexShader, gl.COMPILE_STATUS)) {
  11147. GLGE.error(gl.getShaderInfoLog(this.GLVertexShader));
  11148. return;
  11149. }
  11150. this.GLShaderProgram = gl.createProgram();
  11151. gl.attachShader(this.GLShaderProgram, this.GLVertexShader);
  11152. gl.attachShader(this.GLShaderProgram, this.GLFragmentShader);
  11153. gl.linkProgram(this.GLShaderProgram);
  11154. }
  11155. /**
  11156. * Renders the blured shadow
  11157. * @private
  11158. */
  11159. GLGE.Light.prototype.GLRenderSoft=function(gl){
  11160. if(this.spotSoftness==0) return;
  11161. if(!this.gl){
  11162. this.GLInit(gl);
  11163. }
  11164. gl.bindFramebuffer(gl.FRAMEBUFFER, this.frameBufferSf);
  11165. if(gl.program!=this.GLShaderProgram){
  11166. gl.useProgram(this.GLShaderProgram);
  11167. gl.program=this.GLShaderProgram;
  11168. }
  11169. var attribslot;
  11170. for(var i=0; i<8; i++) gl.disableVertexAttribArray(i);
  11171. attribslot=GLGE.getAttribLocation(gl,this.GLShaderProgram, "position");
  11172. gl.bindBuffer(gl.ARRAY_BUFFER, this.posBuffer);
  11173. gl.enableVertexAttribArray(attribslot);
  11174. gl.vertexAttribPointer(attribslot, this.posBuffer.itemSize, gl.FLOAT, false, 0, 0);
  11175. attribslot=GLGE.getAttribLocation(gl,this.GLShaderProgram, "uvcoord");
  11176. gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer);
  11177. gl.enableVertexAttribArray(attribslot);
  11178. gl.vertexAttribPointer(attribslot, this.uvBuffer.itemSize, gl.FLOAT, false, 0, 0);
  11179. gl.activeTexture(gl["TEXTURE0"]);
  11180. gl.bindTexture(gl.TEXTURE_2D, this.texture);
  11181. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
  11182. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
  11183. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
  11184. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
  11185. GLGE.setUniform(gl,"1i",GLGE.getUniformLocation(gl,this.GLShaderProgram, "TEXTURE"),0);
  11186. GLGE.setUniform(gl,"1i",GLGE.getUniformLocation(gl,this.GLShaderProgram, "xpass"),1);
  11187. gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.GLfaces);
  11188. gl.clear(gl.DEPTH_BUFFER_BIT | gl.COLOR_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
  11189. gl.drawElements(gl.TRIANGLES, this.GLfaces.numItems, gl.UNSIGNED_SHORT, 0);
  11190. //gl.disable(gl.BLEND);
  11191. gl.activeTexture(gl["TEXTURE0"]);
  11192. gl.bindTexture(gl.TEXTURE_2D, this.textureSf);
  11193. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
  11194. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
  11195. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
  11196. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
  11197. GLGE.setUniform(gl,"1i",GLGE.getUniformLocation(gl,this.GLShaderProgram, "TEXTURE"),0);
  11198. GLGE.setUniform(gl,"1i",GLGE.getUniformLocation(gl,this.GLShaderProgram, "xpass"),0);
  11199. gl.bindFramebuffer(gl.FRAMEBUFFER, this.frameBuffer);
  11200. gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.GLfaces);
  11201. gl.drawElements(gl.TRIANGLES, this.GLfaces.numItems, gl.UNSIGNED_SHORT, 0);
  11202. gl.bindTexture(gl.TEXTURE_2D, null);
  11203. gl.bindFramebuffer(gl.FRAMEBUFFER, null);
  11204. }
  11205. })(GLGE);
  11206. /*
  11207. GLGE WebGL Graphics Engine
  11208. Copyright (c) 2010, Paul Brunt
  11209. All rights reserved.
  11210. Redistribution and use in source and binary forms, with or without
  11211. modification, are permitted provided that the following conditions are met:
  11212. * Redistributions of source code must retain the above copyright
  11213. notice, this list of conditions and the following disclaimer.
  11214. * Redistributions in binary form must reproduce the above copyright
  11215. notice, this list of conditions and the following disclaimer in the
  11216. documentation and/or other materials provided with the distribution.
  11217. * Neither the name of GLGE nor the
  11218. names of its contributors may be used to endorse or promote products
  11219. derived from this software without specific prior written permission.
  11220. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  11221. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  11222. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  11223. DISCLAIMED. IN NO EVENT SHALL PAUL BRUNT BE LIABLE FOR ANY
  11224. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  11225. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  11226. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  11227. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  11228. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  11229. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  11230. */
  11231. /**
  11232. * @fileOverview
  11233. * @name glge_scene.js
  11234. * @author me@paulbrunt.co.uk
  11235. */
  11236. (function(GLGE){
  11237. /**
  11238. * @constant
  11239. * @description Enumeration for no fog
  11240. */
  11241. GLGE.FOG_NONE=1;
  11242. /**
  11243. * @constant
  11244. * @description Enumeration for linear fall off fog
  11245. */
  11246. GLGE.FOG_LINEAR=2;
  11247. /**
  11248. * @constant
  11249. * @description Enumeration for exponential fall off fog
  11250. */
  11251. GLGE.FOG_QUADRATIC=3;
  11252. /**
  11253. * @constant
  11254. * @description Enumeration for linear fall off fog fading to sky
  11255. */
  11256. GLGE.FOG_SKYLINEAR=4;
  11257. /**
  11258. * @constant
  11259. * @description Enumeration for exponential fall off fog fading to sky
  11260. */
  11261. GLGE.FOG_SKYQUADRATIC=5;
  11262. /**
  11263. * @class Scene class containing the camera, lights and objects
  11264. * @augments GLGE.Group
  11265. * @augments GLGE.QuickNotation
  11266. * @augments GLGE.JSONLoader
  11267. */
  11268. GLGE.Scene=function(uid){
  11269. GLGE.Group.call(this);
  11270. this.children=[];
  11271. this.camera=new GLGE.Camera();
  11272. this.backgroundColor={r:1,g:1,b:1,a:1};
  11273. this.ambientColor={r:0,g:0,b:0};
  11274. this.fogColor={r:0.5,g:0.5,b:0.5};
  11275. this.passes=[];
  11276. GLGE.Assets.registerAsset(this,uid);
  11277. }
  11278. GLGE.augment(GLGE.Group,GLGE.Scene);
  11279. GLGE.Scene.prototype.camera=null;
  11280. GLGE.Scene.prototype.className="Scene";
  11281. GLGE.Scene.prototype.renderer=null;
  11282. GLGE.Scene.prototype.backgroundColor=null;
  11283. GLGE.Scene.prototype.filter=null;
  11284. GLGE.Scene.prototype.fogColor=null;
  11285. GLGE.Scene.prototype.ambientColor=null;
  11286. GLGE.Scene.prototype.fogNear=10;
  11287. GLGE.Scene.prototype.fogFar=80;
  11288. GLGE.Scene.prototype.fogType=GLGE.FOG_NONE;
  11289. GLGE.Scene.prototype.passes=null;
  11290. GLGE.Scene.prototype.transbuffer=null;
  11291. GLGE.Scene.prototype.culling=true;
  11292. /**
  11293. * Gets the fog falloff type
  11294. * @returns {number} the far falloff type
  11295. */
  11296. GLGE.Scene.prototype.getFogType=function(){
  11297. return this.fogType;
  11298. }
  11299. /**
  11300. * Sets the scenes fog falloff type
  11301. * @param {number} type The fog falloff type FOG_NONE,FOG_LINEAR,FOG_QUADRATIC
  11302. */
  11303. GLGE.Scene.prototype.setFogType=function(type){
  11304. this.fogType=type;
  11305. return this;
  11306. }
  11307. /**
  11308. * Gets the far fog distance
  11309. * @returns {number} the far distance of the fog
  11310. */
  11311. GLGE.Scene.prototype.getFogFar=function(){
  11312. return this.fogFar;
  11313. }
  11314. /**
  11315. * Sets the scenes fog far distance
  11316. * @param {number} dist The fog far distance
  11317. */
  11318. GLGE.Scene.prototype.setFogFar=function(dist){
  11319. this.fogFar=dist;
  11320. return this;
  11321. }
  11322. /**
  11323. * Gets the near fog distance
  11324. * @returns {number} the near distance of the fog
  11325. */
  11326. GLGE.Scene.prototype.getFogNear=function(){
  11327. return this.fogNear;
  11328. }
  11329. /**
  11330. * Sets the scenes fog near distance
  11331. * @param {number} dist The fog near distance
  11332. */
  11333. GLGE.Scene.prototype.setFogNear=function(dist){
  11334. this.fogNear=dist;
  11335. return this;
  11336. }
  11337. /**
  11338. * Gets the fog color
  11339. * @returns {object} An assoiative array r,g,b
  11340. */
  11341. GLGE.Scene.prototype.getFogColor=function(){
  11342. return this.fogColor;
  11343. }
  11344. /**
  11345. * Sets the scenes fog color
  11346. * @param {string} color The fog color
  11347. */
  11348. GLGE.Scene.prototype.setFogColor=function(color){
  11349. color=GLGE.colorParse(color);
  11350. this.fogColor={r:color.r,g:color.g,b:color.b};
  11351. return this;
  11352. }
  11353. /**
  11354. * Gets the scenes background color
  11355. * @returns {object} An assoiative array r,g,b
  11356. */
  11357. GLGE.Scene.prototype.getBackgroundColor=function(){
  11358. return this.backgroundColor;
  11359. }
  11360. /**
  11361. * Sets the scenes background color
  11362. * @param {string} color The backgorund color
  11363. */
  11364. GLGE.Scene.prototype.setBackgroundColor=function(color){
  11365. color=GLGE.colorParse(color);
  11366. this.backgroundColor={r:color.r,g:color.g,b:color.b,a:color.a};
  11367. return this;
  11368. }
  11369. /**
  11370. * Gets the scenes ambient light
  11371. * @returns {object} An assoiative array r,g,b
  11372. */
  11373. GLGE.Scene.prototype.getAmbientColor=function(){
  11374. return this.ambientColor;
  11375. }
  11376. /**
  11377. * Sets the scenes ambient light
  11378. * @param {string} color The ambient light color
  11379. */
  11380. GLGE.Scene.prototype.setAmbientColor=function(color){
  11381. color=GLGE.colorParse(color);
  11382. this.ambientColor={r:color.r,g:color.g,b:color.b};
  11383. if(this.renderer){
  11384. this.renderer.gl.clearColor(this.backgroundColor.r, this.backgroundColor.g, this.backgroundColor.b, 1.0);
  11385. }
  11386. return this;
  11387. }
  11388. /**
  11389. * Sets the scenes ambient light
  11390. * @param {number} value the red componenent of the ambient light 0-1
  11391. */
  11392. GLGE.Scene.prototype.setAmbientColorR=function(value){
  11393. this.ambientColor.r=value;
  11394. return this;
  11395. }
  11396. /**
  11397. * Sets the scenes ambient light
  11398. * @param {number} value the green componenent of the ambient light 0-1
  11399. */
  11400. GLGE.Scene.prototype.setAmbientColorG=function(value){
  11401. this.ambientColor.g=value;
  11402. return this;
  11403. }
  11404. /**
  11405. * Sets the scenes ambient light
  11406. * @param {number} value the blue componenent of the ambient light 0-1
  11407. */
  11408. GLGE.Scene.prototype.setAmbientColorB=function(value){
  11409. this.ambientColor.b=value;
  11410. return this;
  11411. }
  11412. /**
  11413. * Sets the active camera for this scene
  11414. * @property {GLGE.Camera} object The object to be added
  11415. */
  11416. GLGE.Scene.prototype.setCamera=function(camera){
  11417. if(typeof camera=="string") camera=GLGE.Assets.get(camera);
  11418. this.camera=camera;
  11419. return this;
  11420. }
  11421. /**
  11422. * Gets the scenes active camera
  11423. * @returns {GLGE.Camera} The current camera
  11424. */
  11425. GLGE.Scene.prototype.getCamera=function(){
  11426. return this.camera;
  11427. }
  11428. /**
  11429. * Sets the Culling Flag
  11430. */
  11431. GLGE.Scene.prototype.setCull=function(cull){
  11432. this.culling=cull;
  11433. return this;
  11434. }
  11435. /**
  11436. * Gets the Culling Flag
  11437. */
  11438. GLGE.Scene.prototype.getCull=function(){
  11439. return this.culling;
  11440. }
  11441. /**
  11442. * used to initialize all the WebGL buffers etc need for this scene
  11443. * @private
  11444. */
  11445. GLGE.Scene.prototype.GLInit=function(gl){
  11446. this.gl=gl;
  11447. gl.lights=this.getLights();
  11448. //sets the camera aspect to same aspect as the canvas
  11449. this.camera.setAspect(this.renderer.canvas.width/this.renderer.canvas.height);
  11450. //this.createPickBuffer(gl);
  11451. this.renderer.gl.clearColor(this.backgroundColor.r, this.backgroundColor.g, this.backgroundColor.b, 1.0);
  11452. for(var i=0;i<this.children;i++){
  11453. if(this.children[i].GLInit) children[i].GLInit(gl);
  11454. }
  11455. }
  11456. /**
  11457. * used to clean up all the WebGL buffers etc need for this scene
  11458. * @private
  11459. */
  11460. GLGE.Scene.prototype.GLDestroy=function(gl){
  11461. }
  11462. /**
  11463. * sort function
  11464. */
  11465. GLGE.Scene.sortFunc=function(a,b){
  11466. return a.zdepth-b.zdepth;
  11467. }
  11468. /**
  11469. * z sorts the objects
  11470. * @private
  11471. */
  11472. GLGE.Scene.prototype.zSort=function(gl,objects){
  11473. var cameraMatrix=gl.scene.camera.getViewMatrix();
  11474. var transMatrix;
  11475. for(var i=0;i<objects.length;i++){
  11476. if(objects[i].object.getBoundingVolume){
  11477. var center=objects[i].object.getBoundingVolume().getCenter();
  11478. }else{
  11479. var matrix=objects[i].object.getModelMatrix();
  11480. var center=[matrix[3],matrix[7],matrix[11]];
  11481. }
  11482. objects[i].zdepth=center[0]*cameraMatrix[8]+center[1]*cameraMatrix[9]+center[2]*cameraMatrix[10]+cameraMatrix[11];
  11483. if(objects[i].object.zDepth) {objects[i].zdepth=objects[i].object.zDepth;}
  11484. }
  11485. objects.sort(GLGE.Scene.sortFunc);
  11486. return objects;
  11487. }
  11488. /**
  11489. * sets the 2d filter to apply
  11490. * @param {GLGE.Filter2d} filter the filter to apply when rendering the scene
  11491. */
  11492. GLGE.Scene.prototype.setFilter2d=function(value){
  11493. this.filter=value;
  11494. return this;
  11495. }
  11496. /**
  11497. * gets the 2d filter being applied apply
  11498. * @returns {GLGE.Filter2d}
  11499. */
  11500. GLGE.Scene.prototype.getFilter2d=function(filter){
  11501. return this.filter;
  11502. }
  11503. /**
  11504. * sets the sky filter to apply
  11505. * @param {GLGE.Filter2d} filter tthe filter used to render the sky
  11506. */
  11507. GLGE.Scene.prototype.setSkyFilter=function(value){
  11508. this.skyfilter=value;
  11509. return this;
  11510. }
  11511. /**
  11512. * gets the sky filter
  11513. * @returns {GLGE.Filter2d}
  11514. */
  11515. GLGE.Scene.prototype.getSkyFilter=function(filter){
  11516. return this.skyfilter;
  11517. }
  11518. /**
  11519. * gets the scenes frame buffer
  11520. * @private
  11521. */
  11522. GLGE.Scene.prototype.getFrameBuffer=function(gl){
  11523. if(this.filter) return this.filter.getFrameBuffer(gl);
  11524. return null;
  11525. }
  11526. /**
  11527. * culls objects from the scene
  11528. * @private
  11529. */
  11530. GLGE.Scene.prototype.objectsInViewFrustum=function(renderObjects,cvp){
  11531. var obj;
  11532. var returnObjects=[];
  11533. var planes=GLGE.cameraViewProjectionToPlanes(cvp);
  11534. for(var i=0;i<renderObjects.length;i++){
  11535. obj=renderObjects[i];
  11536. if(obj.getBoundingVolume && obj.cull){
  11537. var boundingVolume=obj.getBoundingVolume();
  11538. var center=boundingVolume.getCenter();
  11539. var radius=boundingVolume.getSphereRadius();
  11540. if(GLGE.sphereInFrustumPlanes([center[0],center[1],center[2],radius],planes)){
  11541. var points=boundingVolume.getCornerPoints();
  11542. if(GLGE.pointsInFrustumPlanes(points,planes)){
  11543. returnObjects.push(obj);
  11544. if(obj.culled) obj.fireEvent("willRender",{});
  11545. obj.culled=false;
  11546. }else{
  11547. if(!obj.culled) obj.fireEvent("willCull",{});
  11548. obj.culled=true;
  11549. }
  11550. }else{
  11551. if(!obj.culled) obj.fireEvent("willCull",{});
  11552. obj.culled=true;
  11553. }
  11554. }else{
  11555. returnObjects.push(obj);
  11556. }
  11557. }
  11558. return returnObjects;
  11559. }
  11560. /**
  11561. * Extracts all of the scene elements that need rendering
  11562. * @private
  11563. */
  11564. GLGE.Scene.prototype.unfoldRenderObject=function(renderObjects){
  11565. var returnObjects=[];
  11566. for(var i=0;i<renderObjects.length;i++){
  11567. var renderObject=renderObjects[i];
  11568. if(renderObject.getMultiMaterials){
  11569. var multiMaterials=renderObject.getMultiMaterials();
  11570. for(var j=0;j<multiMaterials.length;j++){
  11571. var mat=multiMaterials[j].getMaterial();
  11572. var mesh=multiMaterials[j].getMesh();
  11573. if(!mat.meshIdx) mat.matIdx=j;
  11574. if(!mat.meshIdx) mat.meshIdx=j;
  11575. returnObjects.push({object:renderObject, multiMaterial:j});
  11576. }
  11577. }else{
  11578. returnObjects.push({object:renderObject, multiMaterial:0});
  11579. }
  11580. }
  11581. return returnObjects;
  11582. }
  11583. /**
  11584. * State sorting function
  11585. * @private
  11586. */
  11587. GLGE.Scene.prototype.stateSort=function(a,b){
  11588. if(!a.object.GLShaderProgram) return 1;
  11589. if(!b.object.GLShaderProgram) return -1;
  11590. var aidx=a.object.GLShaderProgram.progIdx;
  11591. var bidx=b.object.GLShaderProgram.progIdx;
  11592. if(aidx>bidx){
  11593. return 1;
  11594. }else if(aidx<bidx){
  11595. return -1;
  11596. }else{
  11597. if(!a.object.multimaterials || !b.object.multimaterials) return -1;
  11598. var aidx=a.object.multimaterials[a.multiMaterial].getMaterial().matIdx;
  11599. var bidx=b.object.multimaterials[b.multiMaterial].getMaterial().matIdx;
  11600. if(aidx>bidx){
  11601. return 1;
  11602. }else if(aidx<bidx){
  11603. return -1;
  11604. }else{
  11605. var amesh=a.object.multimaterials[a.multiMaterial].getMesh();
  11606. var bmesh=a.object.multimaterials[a.multiMaterial].getMesh();
  11607. if(!amesh) return -1;
  11608. if(!bmesh) return 1;
  11609. var aidx=amesh.meshIdx;
  11610. var bidx=bmesh.meshIdx;
  11611. if(aidx>bidx){
  11612. return 1;
  11613. }else if(aidx<bidx){
  11614. return -1;
  11615. }else{
  11616. return 0;
  11617. }
  11618. }
  11619. }
  11620. }
  11621. /**
  11622. * Sets up the WebGL needed to render the sky for use in sky fog
  11623. * @private
  11624. */
  11625. GLGE.Scene.prototype.createSkyBuffer=function(gl){
  11626. this.skyTexture = gl.createTexture();
  11627. gl.bindTexture(gl.TEXTURE_2D, this.skyTexture);
  11628. gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, this.renderer.canvas.width,this.renderer.canvas.height, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
  11629. }
  11630. /**
  11631. * renders the scene
  11632. * @private
  11633. */
  11634. GLGE.Scene.prototype.render=function(gl){
  11635. this.animate();
  11636. //if look at is set then look
  11637. if(this.camera.lookAt) this.camera.Lookat(this.camera.lookAt);
  11638. gl.lights=this.getLights();
  11639. var lights=gl.lights;
  11640. gl.scene=this;
  11641. this.lastMaterial=null;
  11642. gl.disable(gl.BLEND);
  11643. this.framebuffer=this.getFrameBuffer(gl);
  11644. var renderObjects=this.getObjects();
  11645. var cvp=this.camera.getViewProjection();
  11646. if(this.culling){
  11647. var cvp=this.camera.getViewProjection();
  11648. renderObjects=this.objectsInViewFrustum(renderObjects,cvp);
  11649. }
  11650. renderObjects=this.unfoldRenderObject(renderObjects);
  11651. renderObjects=renderObjects.sort(this.stateSort);
  11652. //shadow stuff
  11653. for(var i=0; i<lights.length;i++){
  11654. if(lights[i].castShadows){
  11655. if(!lights[i].gl) lights[i].GLInit(gl);
  11656. var cameraMatrix=this.camera.matrix;
  11657. var cameraPMatrix=this.camera.getProjectionMatrix();
  11658. var projectedDistance=0;
  11659. if(lights[i].getType()==GLGE.L_DIR){
  11660. var mat=lights[i].getModelMatrix();
  11661. var cmat=GLGE.inverseMat4(cameraMatrix);
  11662. mat[3]=(mat[2])*lights[i].distance/2+cmat[3];
  11663. mat[7]=(mat[6])*lights[i].distance/2+cmat[7];
  11664. mat[11]=(mat[10])*lights[i].distance/2+cmat[11];
  11665. lights[i].matrix=mat;
  11666. var tvec=GLGE.mulMat4Vec4(cameraPMatrix,[0,0,lights[i].distance,1]);
  11667. projectedDistance=tvec[3]/tvec[2]; //this is wrong?
  11668. }
  11669. gl.bindFramebuffer(gl.FRAMEBUFFER, lights[i].frameBuffer);
  11670. if(!lights[i].s_cache) lights[i].s_cache={};
  11671. lights[i].s_cache.imvmatrix=GLGE.inverseMat4(lights[i].getModelMatrix());
  11672. lights[i].s_cache.mvmatrix=lights[i].getModelMatrix();
  11673. lights[i].s_cache.pmatrix=lights[i].getPMatrix(cvp,lights[i].s_cache.imvmatrix,projectedDistance,this.camera.far/2);
  11674. lights[i].s_cache.smatrix=GLGE.mulMat4(lights[i].s_cache.pmatrix,lights[i].s_cache.imvmatrix);
  11675. lights[i].shadowRendered=false;
  11676. if(lights[i].getType()==GLGE.L_DIR){
  11677. var levels=lights[i].getCascadeLevels();
  11678. }else{
  11679. levels=1;
  11680. }
  11681. gl.viewport(0,0,parseFloat(lights[i].bufferWidth),parseFloat(lights[i].bufferHeight));
  11682. gl.clearDepth(1.0);
  11683. gl.clearColor(1, 1, 1, 1);
  11684. gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
  11685. var height=(parseFloat(lights[i].bufferHeight)/levels)|0;
  11686. var width=parseFloat(lights[i].bufferWidth);
  11687. for(var l=0;l<levels;l++){
  11688. gl.viewport(0,l*height,width,height);
  11689. this.camera.setProjectionMatrix(lights[i].s_cache.pmatrix);
  11690. this.camera.matrix=lights[i].s_cache.imvmatrix;
  11691. //draw shadows
  11692. for(var n=0; n<renderObjects.length;n++){
  11693. if(renderObjects[n].object.getCastShadows && !renderObjects[n].object.getCastShadows()) continue;
  11694. if(renderObjects[n].object.className=="ParticleSystem") {continue;}
  11695. if(lights[i].getType()==GLGE.L_SPOT){
  11696. renderObjects[n].object.GLRender(gl, GLGE.RENDER_SHADOW,n,renderObjects[n].multiMaterial,lights[i].distance);
  11697. }else{
  11698. renderObjects[n].object.GLRender(gl, GLGE.RENDER_DEPTH,n,renderObjects[n].multiMaterial,lights[i].distance);
  11699. }
  11700. }
  11701. lights[i].s_cache.pmatrix[0]*=2;
  11702. lights[i].s_cache.pmatrix[5]*=2;
  11703. }
  11704. lights[i].s_cache.pmatrix[0]/=2;
  11705. lights[i].s_cache.pmatrix[5]/=2;
  11706. lights[i].s_cache.smatrix=GLGE.mulMat4(lights[i].s_cache.pmatrix,lights[i].s_cache.imvmatrix);
  11707. lights[i].GLRenderSoft(gl);
  11708. this.camera.matrix=null;
  11709. this.camera.setProjectionMatrix(cameraPMatrix);
  11710. }
  11711. }
  11712. if(this.culling){
  11713. var cvp=this.camera.getViewProjection();
  11714. renderObjects=this.objectsInViewFrustum(renderObjects,cvp);
  11715. }
  11716. gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);
  11717. if(this.camera.animation) this.camera.animate();
  11718. //null render pass to findout what else needs rendering
  11719. this.getPasses(gl,renderObjects);
  11720. //first off render the passes
  11721. var cameraMatrix=this.camera.matrix;
  11722. var cameraPMatrix=this.camera.getProjectionMatrix();
  11723. this.allowPasses=false;
  11724. while(this.passes.length>0){
  11725. var pass=this.passes.pop();
  11726. gl.bindFramebuffer(gl.FRAMEBUFFER, pass.frameBuffer);
  11727. this.camera.matrix=pass.cameraMatrix;
  11728. this.camera.setProjectionMatrix(pass.projectionMatrix);
  11729. this.renderPass(gl,renderObjects,0,0,pass.width,pass.height,GLGE.RENDER_DEFAULT,pass.self);
  11730. }
  11731. this.camera.matrix=cameraMatrix;
  11732. this.camera.setProjectionMatrix(cameraPMatrix);
  11733. gl.bindFramebuffer(gl.FRAMEBUFFER, this.filter ? this.framebuffer : this.transbuffer);
  11734. this.renderPass(gl,renderObjects,this.renderer.getViewportOffsetX(),this.renderer.getViewportOffsetY(),this.renderer.getViewportWidth(),this.renderer.getViewportHeight());
  11735. this.applyFilter(gl,renderObjects, this.transbuffer);
  11736. this.allowPasses=true;
  11737. }
  11738. /**
  11739. * gets the passes needed to render this scene
  11740. * @private
  11741. */
  11742. GLGE.Scene.prototype.getPasses=function(gl,renderObjects){
  11743. for(var i=0; i<renderObjects.length;i++){
  11744. renderObjects[i].object.GLRender(gl,GLGE.RENDER_NULL,0,renderObjects[i].multiMaterial);
  11745. }
  11746. }
  11747. /**
  11748. * renders the scene
  11749. * @private
  11750. */
  11751. GLGE.Scene.prototype.renderPass=function(gl,renderObjects,offsetx,offsety,width,height,type,self){
  11752. gl.clearDepth(1.0);
  11753. gl.depthFunc(gl.LEQUAL);
  11754. gl.viewport(offsetx,offsety,width,height);
  11755. gl.enable(this.gl.DEPTH_TEST);
  11756. gl.clearColor(this.backgroundColor.r, this.backgroundColor.g, this.backgroundColor.b, this.backgroundColor.a);
  11757. if(!type) {
  11758. gl.scissor(offsetx,offsety,width,height);
  11759. gl.enable(gl.SCISSOR_TEST);
  11760. this.renderer.GLClear();
  11761. gl.disable(gl.SCISSOR_TEST);
  11762. }else{
  11763. gl.clear(gl.DEPTH_BUFFER_BIT | gl.COLOR_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
  11764. }
  11765. if(!type) type=GLGE.RENDER_DEFAULT;
  11766. if(this.skyfilter && type==GLGE.RENDER_DEFAULT){
  11767. this.skyfilter.GLRender(gl);
  11768. gl.clear(gl.DEPTH_BUFFER_BIT);
  11769. if(this.skyfilter && this.fogType==GLGE.FOG_SKYQUADRATIC || this.fogType==GLGE.FOG_SKYLINEAR){
  11770. if(!this.skyTexture) this.createSkyBuffer(gl);
  11771. gl.bindTexture(gl.TEXTURE_2D, this.skyTexture);
  11772. gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.RGB, 0, 0, width, height, 0);
  11773. }
  11774. }
  11775. var transObjects=[];
  11776. gl.disable(gl.BLEND);
  11777. for(var i=0; i<renderObjects.length;i++){
  11778. if((!renderObjects[i].object.zTrans || type!=GLGE.RENDER_DEFAULT) && renderObjects[i].object!=self) renderObjects[i].object.GLRender(gl,type,0,renderObjects[i].multiMaterial);
  11779. else if(renderObjects[i].object!=self) transObjects.push(renderObjects[i]);
  11780. }
  11781. gl.enable(gl.BLEND);
  11782. transObjects=this.zSort(gl,transObjects);
  11783. for(var i=0; i<transObjects.length;i++){
  11784. if(transObjects[i].object.blending){
  11785. if(transObjects[i].object.blending.length=4){
  11786. gl.blendFuncSeparate(gl[transObjects[i].object.blending[0]],gl[transObjects[i].object.blending[1]],gl[transObjects[i].object.blending[2]],gl[transObjects[i].object.blending[3]]);
  11787. }else{
  11788. gl.blendFunc(gl[transObjects[i].object.blending[0]],gl[transObjects[i].object.blending[1]]);
  11789. }
  11790. }
  11791. if(transObjects[i].object.depthTest===false){
  11792. gl.disable(this.gl.DEPTH_TEST);
  11793. }else{
  11794. gl.enable(this.gl.DEPTH_TEST);
  11795. }
  11796. if(renderObjects[i]!=self) transObjects[i].object.GLRender(gl, type,0,transObjects[i].multiMaterial);
  11797. }
  11798. }
  11799. GLGE.Scene.prototype.applyFilter=function(gl,renderObject,framebuffer){
  11800. if(this.filter && this.filter.renderDepth){
  11801. gl.clearDepth(1.0);
  11802. gl.depthFunc(gl.LEQUAL);
  11803. gl.bindFramebuffer(gl.FRAMEBUFFER, this.filter.getDepthBuffer(gl));
  11804. this.renderPass(gl,renderObject,0,0,this.filter.getDepthBufferWidth(), this.filter.getDepthBufferHeight(),GLGE.RENDER_SHADOW);
  11805. }
  11806. if(this.filter && this.filter.renderEmit){
  11807. gl.clearDepth(1.0);
  11808. gl.depthFunc(gl.LEQUAL);
  11809. gl.bindFramebuffer(gl.FRAMEBUFFER, this.filter.getEmitBuffer(gl));
  11810. this.renderPass(gl,renderObject,0,0,this.filter.getEmitBufferWidth(),this.filter.getEmitBufferHeight(),GLGE.RENDER_EMIT);
  11811. }
  11812. if(this.filter && this.filter.renderNormal){
  11813. gl.clearDepth(1.0);
  11814. gl.depthFunc(gl.LEQUAL);
  11815. gl.bindFramebuffer(gl.FRAMEBUFFER, this.filter.getNormalBuffer(gl));
  11816. this.renderPass(gl,renderObject,0,0,this.filter.getNormalBufferWidth(),this.filter.getNormalBufferHeight(),GLGE.RENDER_NORMAL);
  11817. }
  11818. if(this.filter) this.filter.GLRender(gl,framebuffer);
  11819. }
  11820. /**
  11821. * Adds and additional render pass to the scene for RTT, reflections and refractions
  11822. * @private
  11823. */
  11824. GLGE.Scene.prototype.addRenderPass=function(frameBuffer,cameraMatrix,projectionMatrix,width,height,self){
  11825. if(this.allowPasses) this.passes.push({frameBuffer:frameBuffer, cameraMatrix:cameraMatrix, projectionMatrix:projectionMatrix, height:height, width:width,self:self});
  11826. return this;
  11827. }
  11828. /**
  11829. * Sets up the WebGL needed create a picking frame and render buffer
  11830. * @private
  11831. */
  11832. /*GLGE.Scene.prototype.createPickBuffer=function(gl){
  11833. this.framePickBuffer = gl.createFramebuffer();
  11834. this.renderPickBufferD = gl.createRenderbuffer();
  11835. this.renderPickBufferC = gl.createRenderbuffer();
  11836. //this.pickTexture = gl.createTexture();
  11837. //gl.bindTexture(gl.TEXTURE_2D, this.pickTexture);
  11838. //TODO update when null is accepted
  11839. /* try {
  11840. gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 4, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
  11841. } catch (e) {
  11842. var tex = new WebGLUnsignedByteArray(4*1*4);
  11843. gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 4,1, 0, gl.RGBA, gl.UNSIGNED_BYTE, tex);
  11844. }
  11845. gl.bindFramebuffer(gl.FRAMEBUFFER, this.framePickBuffer);
  11846. gl.bindRenderbuffer(gl.RENDERBUFFER, this.renderPickBufferD);
  11847. gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16,4, 1);
  11848. //gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.pickTexture, 0);
  11849. gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, this.renderPickBufferD);
  11850. gl.bindRenderbuffer(gl.RENDERBUFFER, this.renderPickBufferC);
  11851. gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA,4, 1);
  11852. gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, this.renderPickBufferC);
  11853. gl.bindRenderbuffer(gl.RENDERBUFFER, null);
  11854. gl.bindFramebuffer(gl.FRAMEBUFFER, null);
  11855. gl.bindTexture(gl.TEXTURE_2D, null);
  11856. }*/
  11857. /**
  11858. * ray query from origin in the given direction
  11859. * @param origin the source of the ray
  11860. * @param direction the direction of the ray
  11861. */
  11862. GLGE.Scene.prototype.ray=function(origin,direction){
  11863. var gl=this.renderer.gl;
  11864. var origmatrix=this.camera.matrix;
  11865. var origpmatrix=this.camera.pMatrix;
  11866. this.camera.matrix=GLGE.inverseMat4(GLGE.Mat4([direction[2], direction[1], direction[0], origin[0],
  11867. direction[0], direction[2], direction[1], origin[1],
  11868. direction[1], direction[0], direction[2], origin[2],
  11869. 0, 0, 0, 1]));
  11870. if(!this.pickPMatrix) this.pickPMatrix=GLGE.makeOrtho(-0.0001,0.0001,-0.0001,0.0001,this.camera.near,this.camera.far);
  11871. this.camera.pMatrix=this.pickPMatrix;
  11872. gl.viewport(0,0,8,1);
  11873. gl.clear(gl.DEPTH_BUFFER_BIT);
  11874. gl.disable(gl.BLEND);
  11875. gl.scene=this;
  11876. var objects=this.getObjects();
  11877. /*if(this.culling){
  11878. var cvp=this.camera.getViewProjection();
  11879. objects=this.objectsInViewFrustum(objects,cvp);
  11880. }*/
  11881. var pickableDepthTestObjects = [];
  11882. var pickableNoDepthObjects = [];
  11883. var ordermap = {}
  11884. for(var i=0; i<objects.length;i++){
  11885. if(objects[i].pickable && objects[i].depthTest) pickableDepthTestObjects.push(objects[i]);//objects[i].GLRender(gl,GLGE.RENDER_PICK,i+1);
  11886. if(objects[i].pickable && !objects[i].depthTest) pickableNoDepthObjects.push(objects[i]);
  11887. ordermap[objects[i].uid] = i+1;
  11888. }
  11889. gl.enable(this.gl.DEPTH_TEST);
  11890. gl.depthFunc(gl.LEQUAL);
  11891. for(var i=0; i<pickableDepthTestObjects.length;i++){
  11892. pickableDepthTestObjects[i].GLRender(gl,GLGE.RENDER_PICK,ordermap[pickableDepthTestObjects[i].uid]);
  11893. }
  11894. gl.disable(this.gl.DEPTH_TEST);
  11895. for(var i=0; i<pickableNoDepthObjects.length;i++){
  11896. pickableNoDepthObjects[i].GLRender(gl,GLGE.RENDER_PICK,ordermap[pickableNoDepthObjects[i].uid]);
  11897. }
  11898. gl.enable(this.gl.DEPTH_TEST);
  11899. //gl.flush();
  11900. var data = new Uint8Array(8 * 1 * 4);
  11901. gl.readPixels(0, 0, 8, 1, gl.RGBA,gl.UNSIGNED_BYTE, data);
  11902. var norm=[data[4]/255,data[5]/255,data[6]/255];
  11903. var normalsize=Math.sqrt(norm[0]*norm[0]+norm[1]*norm[1]+norm[2]*norm[2])*0.5;
  11904. norm=[norm[0]/normalsize-1,norm[1]/normalsize-1,norm[2]/normalsize-1];
  11905. var obj=objects[data[0]+data[1]*256+data[2]*65536-1];
  11906. var dist=(data[10]/255+0.00390625*data[9]/255+0.0000152587890625*data[8]/255)*this.camera.far;
  11907. var tex=[];
  11908. tex[0]=(data[14]/255+0.00390625*data[13]/255+0.0000152587890625*data[12]/255);
  11909. tex[1]=(data[18]/255+0.00390625*data[17]/255+0.0000152587890625*data[16]/255);
  11910. gl.bindFramebuffer(gl.FRAMEBUFFER, null);
  11911. gl.viewport(0,0,this.renderer.canvas.width,this.renderer.canvas.height);
  11912. //revert the view matrix
  11913. this.camera.matrix=origmatrix;
  11914. this.camera.pMatrix=origpmatrix;
  11915. if (obj) {
  11916. return {object:obj,distance:dist,coord:[origin[0]-direction[0]*dist,origin[1]-direction[1]*dist,origin[2]-direction[2]*dist],normal:norm,texture:tex};
  11917. }
  11918. return null;
  11919. }
  11920. /**
  11921. * Picks and object from canvas coords
  11922. * @param x the canvas x coord to pick
  11923. * @param y the canvas y coord to pick
  11924. */
  11925. GLGE.Scene.prototype.pick=function(x,y){
  11926. var ray = this.makeRay(x,y);
  11927. if (!ray) {
  11928. return null;
  11929. }
  11930. return this.ray(ray.origin,ray.coord);
  11931. };
  11932. /**
  11933. * Returns an object containing origin and coord, starting from the camera and pointing towards (x,y)
  11934. * @param x the canvas x coord to pick
  11935. * @param y the canvas y coord to pick
  11936. */
  11937. GLGE.Scene.prototype.makeRay=function(x,y){
  11938. if(!this.camera){
  11939. GLGE.error("No camera set for picking");
  11940. return null;
  11941. }else if(this.camera.matrix && this.camera.pMatrix){
  11942. //correct xy account for canvas scaling
  11943. var canvas=this.renderer.canvas;
  11944. var computedStyle=document.defaultView.getComputedStyle(canvas);
  11945. var paddingWidth=(parseFloat(computedStyle.getPropertyValue("padding-left"))||0)+
  11946. (parseFloat(computedStyle.getPropertyValue("padding-right"))||0);
  11947. var paddingHeight=(parseFloat(computedStyle.getPropertyValue("padding-top"))||0)+
  11948. (parseFloat(computedStyle.getPropertyValue("padding-bottom"))||0);
  11949. x=x/(canvas.clientWidth-paddingWidth)*canvas.width;
  11950. y=y/(canvas.clientHeight-paddingHeight)*canvas.height;
  11951. var height=this.renderer.getViewportHeight();
  11952. var width=this.renderer.getViewportWidth();
  11953. var offsetx=this.renderer.getViewportOffsetX();
  11954. var offsety=this.renderer.getViewportHeight()-this.renderer.canvas.height+this.renderer.getViewportOffsetY();
  11955. var xcoord = ((x-offsetx)/width-0.5)*2;
  11956. var ycoord = -((y+offsety)/height-0.5)*2;
  11957. var invViewProj=GLGE.mulMat4(GLGE.inverseMat4(this.camera.matrix),GLGE.inverseMat4(this.camera.pMatrix));
  11958. var origin =GLGE.mulMat4Vec4(invViewProj,[xcoord,ycoord,-1,1]);
  11959. origin=[origin[0]/origin[3],origin[1]/origin[3],origin[2]/origin[3]];
  11960. var coord =GLGE.mulMat4Vec4(invViewProj,[xcoord,ycoord,1,1]);
  11961. coord=[-(coord[0]/coord[3]-origin[0]),-(coord[1]/coord[3]-origin[1]),-(coord[2]/coord[3]-origin[2])];
  11962. coord=GLGE.toUnitVec3(coord);
  11963. return {origin: origin, coord: coord};
  11964. }else{
  11965. return null;
  11966. }
  11967. };
  11968. })(GLGE);
  11969. /*
  11970. GLGE WebGL Graphics Engine
  11971. Copyright (c) 2010, Paul Brunt
  11972. All rights reserved.
  11973. Redistribution and use in source and binary forms, with or without
  11974. modification, are permitted provided that the following conditions are met:
  11975. * Redistributions of source code must retain the above copyright
  11976. notice, this list of conditions and the following disclaimer.
  11977. * Redistributions in binary form must reproduce the above copyright
  11978. notice, this list of conditions and the following disclaimer in the
  11979. documentation and/or other materials provided with the distribution.
  11980. * Neither the name of GLGE nor the
  11981. names of its contributors may be used to endorse or promote products
  11982. derived from this software without specific prior written permission.
  11983. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  11984. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  11985. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  11986. DISCLAIMED. IN NO EVENT SHALL PAUL BRUNT BE LIABLE FOR ANY
  11987. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  11988. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  11989. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  11990. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  11991. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  11992. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  11993. */
  11994. /**
  11995. * @fileOverview
  11996. * @name glge_particles.js
  11997. */
  11998. (function(GLGE){
  11999. /**
  12000. * @class A texture to be included in a material
  12001. * @param {string} uid the unique id for this texture
  12002. * @augments GLGE.Placeable
  12003. * @augments GLGE.Animatable
  12004. */
  12005. GLGE.ParticleSystem=function(uid){
  12006. this.startTime=GLGE.now();
  12007. this.texture={};
  12008. this.startMaxVelocity={x:0,y:0,z:0};
  12009. this.startMinVelocity={x:0,y:0,z:0};
  12010. this.startMaxAcceleration={x:0,y:0,z:0};
  12011. this.endMaxAcceleration={x:0,y:0,z:0};
  12012. this.startMinAcceleration={x:0,y:0,z:0};
  12013. this.endMinAcceleration={x:0,y:0,z:0};
  12014. this.startColor={r:0,g:0,b:0,a:1};
  12015. this.endColor={r:0,g:0,b:0,a:1};
  12016. GLGE.Assets.registerAsset(this,uid);
  12017. }
  12018. GLGE.augment(GLGE.Placeable,GLGE.ParticleSystem);
  12019. GLGE.augment(GLGE.Animatable,GLGE.ParticleSystem);
  12020. /**
  12021. * Sets the max velocity in the X direction
  12022. * @param {number} value the maximum velocity
  12023. */
  12024. GLGE.ParticleSystem.prototype.setMaxVelX=function(value){
  12025. this.startMaxVelocity.x=parseFloat(value);
  12026. this.attribute=null;
  12027. }
  12028. /**
  12029. * Sets the max velocity in the Y direction
  12030. * @param {number} value the maximum velocity
  12031. */
  12032. GLGE.ParticleSystem.prototype.setMaxVelY=function(value){
  12033. this.startMaxVelocity.y=parseFloat(value);
  12034. this.attribute=null;
  12035. }
  12036. /**
  12037. * Sets the max velocity in the Z direction
  12038. * @param {number} value the maximum velocity
  12039. */
  12040. GLGE.ParticleSystem.prototype.setMaxVelZ=function(value){
  12041. this.startMaxVelocity.z=parseFloat(value);
  12042. this.attribute=null;
  12043. }
  12044. /**
  12045. * Sets the max velocity in the all direction
  12046. * @param {number} x the maximum velocity in x axis
  12047. * @param {number} y the maximum velocity in y axis
  12048. * @param {number} z the maximum velocity in z axis
  12049. */
  12050. GLGE.ParticleSystem.prototype.setMaxVelocity=function(x,y,z){
  12051. this.startMaxVelocity={x:parseFloat(x),y:parseFloat(y),z:parseFloat(z)};
  12052. this.attribute=null;
  12053. }
  12054. GLGE.ParticleSystem.prototype.getMaxVelocity=function(){
  12055. return this.startMaxVelocity;
  12056. }
  12057. /**
  12058. * Sets the min velocity in the X direction
  12059. * @param {number} value the minimum velocity
  12060. */
  12061. GLGE.ParticleSystem.prototype.setMinVelX=function(value){
  12062. this.startMinVelocity.x=parseFloat(value);
  12063. this.attribute=null;
  12064. }
  12065. /**
  12066. * Sets the min velocity in the Y direction
  12067. * @param {number} value the minimum velocity
  12068. */
  12069. GLGE.ParticleSystem.prototype.setMinVelY=function(value){
  12070. this.startMinVelocity.y=parseFloat(value);
  12071. this.attribute=null;
  12072. }
  12073. /**
  12074. * Sets the min velocity in the Z direction
  12075. * @param {number} value the minimum velocity
  12076. */
  12077. GLGE.ParticleSystem.prototype.setMinVelZ=function(value){
  12078. this.startMinVelocity.z=parseFloat(value);
  12079. this.attribute=null;
  12080. }
  12081. /**
  12082. * Sets the min velocity in the all direction
  12083. * @param {number} x the minimum velocity in x axis
  12084. * @param {number} y the minimum velocity in y axis
  12085. * @param {number} z the minimum velocity in z axis
  12086. */
  12087. GLGE.ParticleSystem.prototype.setMinVelocity=function(x,y,z){
  12088. this.startMinVelocity={x:parseFloat(x),y:parseFloat(y),z:parseFloat(z)};
  12089. this.attribute=null;
  12090. }
  12091. GLGE.ParticleSystem.prototype.getMinVelocity=function(){
  12092. return this.startMinVelocity;
  12093. }
  12094. /**
  12095. * Sets the velocity in the X direction
  12096. * @param {number} value the minimum velocity
  12097. */
  12098. GLGE.ParticleSystem.prototype.setVelX=function(value){
  12099. this.startMaxVelocity.x=parseFloat(value);
  12100. this.startMinVelocity.x=parseFloat(value);
  12101. this.attribute=null;
  12102. }
  12103. /**
  12104. * Sets the velocity in the Y direction
  12105. * @param {number} value the minimum velocity
  12106. */
  12107. GLGE.ParticleSystem.prototype.setVelY=function(value){
  12108. this.startMaxVelocity.y=parseFloat(value);
  12109. this.startMinVelocity.y=parseFloat(value);
  12110. this.attribute=null;
  12111. }
  12112. /**
  12113. * Sets the velocity in the Z direction
  12114. * @param {number} value the minimum velocity
  12115. */
  12116. GLGE.ParticleSystem.prototype.setVelZ=function(value){
  12117. this.startMaxVelocity.z=parseFloat(value);
  12118. this.startMinVelocity.z=parseFloat(value);
  12119. this.attribute=null;
  12120. }
  12121. /**
  12122. * Sets the velocity in the all direction
  12123. * @param {number} x the minimum velocity in x axis
  12124. * @param {number} y the minimum velocity in y axis
  12125. * @param {number} z the minimum velocity in z axis
  12126. */
  12127. GLGE.ParticleSystem.prototype.setVelocity=function(x,y,z){
  12128. this.startMaxVelocity={x:parseFloat(x),y:parseFloat(y),z:parseFloat(z)};
  12129. this.startMinVelocity={x:parseFloat(x),y:parseFloat(y),z:parseFloat(z)};
  12130. this.attribute=null;
  12131. }
  12132. /**
  12133. * Sets the max starting acceleration in the X direction
  12134. * @param {number} value the maximum acceleration
  12135. */
  12136. GLGE.ParticleSystem.prototype.setMaxStartAccX=function(value){
  12137. this.startMaxAcceleration.x=parseFloat(value);
  12138. this.attribute=null;
  12139. }
  12140. /**
  12141. * Sets the max starting acceleration in the Y direction
  12142. * @param {number} value the maximum acceleration
  12143. */
  12144. GLGE.ParticleSystem.prototype.setMaxStartAccY=function(value){
  12145. this.startMaxAcceleration.y=parseFloat(value);
  12146. this.attribute=null;
  12147. }
  12148. /**
  12149. * Sets the max starting acceleration in the Z direction
  12150. * @param {number} value the maximum acceleration
  12151. */
  12152. GLGE.ParticleSystem.prototype.setMaxStartAccZ=function(value){
  12153. this.startMaxAcceleration.z=parseFloat(value);
  12154. this.attribute=null;
  12155. }
  12156. /**
  12157. * Sets the max starting acceleration in the all direction
  12158. * @param {number} x the minimum velocity in x axis
  12159. * @param {number} y the minimum velocity in y axis
  12160. * @param {number} z the minimum velocity in z axis
  12161. */
  12162. GLGE.ParticleSystem.prototype.setMaxStartAccelertaion=function(x,y,z){
  12163. this.startMaxAcceleration={x:parseFloat(x),y:parseFloat(y),z:parseFloat(z)};
  12164. this.attribute=null;
  12165. }
  12166. GLGE.ParticleSystem.prototype.getMaxStartAccelertaion=function(){
  12167. return this.startMaxAcceleration;
  12168. }
  12169. /**
  12170. * Sets the min starting acceleration in the X direction
  12171. * @param {number} value the minimum acceleration
  12172. */
  12173. GLGE.ParticleSystem.prototype.setMinStartAccX=function(value){
  12174. this.startMinAcceleration.x=parseFloat(value);
  12175. this.attribute=null;
  12176. }
  12177. /**
  12178. * Sets the min starting acceleration in the Y direction
  12179. * @param {number} value the minimum acceleration
  12180. */
  12181. GLGE.ParticleSystem.prototype.setMinStartAccY=function(value){
  12182. this.startMinAcceleration.y=parseFloat(value);
  12183. this.attribute=null;
  12184. }
  12185. /**
  12186. * Sets the min starting acceleration in the Z direction
  12187. * @param {number} value the minimum acceleration
  12188. */
  12189. GLGE.ParticleSystem.prototype.setMinStartAccZ=function(value){
  12190. this.startMinAcceleration.z=parseFloat(value);
  12191. this.attribute=null;
  12192. }
  12193. /**
  12194. * Sets the min starting acceleration in the all direction
  12195. * @param {number} x the minimum velocity in x axis
  12196. * @param {number} y the minimum velocity in y axis
  12197. * @param {number} z the minimum velocity in z axis
  12198. */
  12199. GLGE.ParticleSystem.prototype.setMinStartAccelertaion=function(x,y,z){
  12200. this.startMinAcceleration={x:parseFloat(x),y:parseFloat(y),z:parseFloat(z)};
  12201. this.attribute=null;
  12202. }
  12203. GLGE.ParticleSystem.prototype.getMinStartAccelertaion=function(){
  12204. return this.startMinAcceleration;
  12205. }
  12206. /**
  12207. * Sets the starting acceleration in the X direction
  12208. * @param {number} value the minimum acceleration
  12209. */
  12210. GLGE.ParticleSystem.prototype.setStartAccX=function(value){
  12211. this.startMaxAcceleration.x=parseFloat(value);
  12212. this.startMinAcceleration.x=parseFloat(value);
  12213. this.attribute=null;
  12214. }
  12215. /**
  12216. * Sets the starting acceleration in the Y direction
  12217. * @param {number} value the minimum acceleration
  12218. */
  12219. GLGE.ParticleSystem.prototype.setStartAccY=function(value){
  12220. this.startMaxAcceleration.y=parseFloat(value);
  12221. this.startMinAcceleration.y=parseFloat(value);
  12222. this.attribute=null;
  12223. }
  12224. /**
  12225. * Sets the starting acceleration in the Z direction
  12226. * @param {number} value the minimum acceleration
  12227. */
  12228. GLGE.ParticleSystem.prototype.setStartAccZ=function(value){
  12229. this.startMaxAcceleration.z=parseFloat(value);
  12230. this.startMinAcceleration.z=parseFloat(value);
  12231. this.attribute=null;
  12232. }
  12233. /**
  12234. * Sets the starting acceleration in the all direction
  12235. * @param {number} x the minimum velocity in x axis
  12236. * @param {number} y the minimum velocity in y axis
  12237. * @param {number} z the minimum velocity in z axis
  12238. */
  12239. GLGE.ParticleSystem.prototype.setStartAccelertaion=function(x,y,z){
  12240. this.startMaxAcceleration={x:parseFloat(x),y:parseFloat(y),z:parseFloat(z)};
  12241. this.startMinAcceleration={x:parseFloat(x),y:parseFloat(y),z:parseFloat(z)};
  12242. this.attribute=null;
  12243. }
  12244. /**
  12245. * Sets the maximum ending acceleration in the X direction
  12246. * @param {number} value the maximum acceleration
  12247. */
  12248. GLGE.ParticleSystem.prototype.setMaxEndAccX=function(value){
  12249. this.endMaxAcceleration.x=parseFloat(value);
  12250. this.attribute=null;
  12251. }
  12252. /**
  12253. * Sets the maximum ending acceleration in the Y direction
  12254. * @param {number} value the maximum acceleration
  12255. */
  12256. GLGE.ParticleSystem.prototype.setMaxEndAccY=function(value){
  12257. this.endMaxAcceleration.y=parseFloat(value);
  12258. this.attribute=null;
  12259. }
  12260. /**
  12261. * Sets the maximum ending acceleration in the Z direction
  12262. * @param {number} value the maximum acceleration
  12263. */
  12264. GLGE.ParticleSystem.prototype.setMaxEndAccZ=function(value){
  12265. this.endMaxAcceleration.z=parseFloat(value);
  12266. this.attribute=null;
  12267. }
  12268. /**
  12269. * Sets the maximum ending acceleration in the all direction
  12270. * @param {number} x the maximum velocity in x axis
  12271. * @param {number} y the maximum velocity in y axis
  12272. * @param {number} z the maximum velocity in z axis
  12273. */
  12274. GLGE.ParticleSystem.prototype.setMaxEndAccelertaion=function(x,y,z){
  12275. this.endMaxAcceleration={x:parseFloat(x),y:parseFloat(y),z:parseFloat(z)};
  12276. this.attribute=null;
  12277. }
  12278. GLGE.ParticleSystem.prototype.getMaxEndAccelertaion=function(){
  12279. return this.endMaxAcceleration;
  12280. }
  12281. /**
  12282. * Sets the minimum ending acceleration in the X direction
  12283. * @param {number} value the minimum acceleration
  12284. */
  12285. GLGE.ParticleSystem.prototype.setMinEndAccX=function(value){
  12286. this.endMinAcceleration.x=parseFloat(value);
  12287. this.attribute=null;
  12288. }
  12289. /**
  12290. * Sets the minimum ending acceleration in the Y direction
  12291. * @param {number} value the minimum acceleration
  12292. */
  12293. GLGE.ParticleSystem.prototype.setMinEndAccY=function(value){
  12294. this.endMinAcceleration.y=parseFloat(value);
  12295. this.attribute=null;
  12296. }
  12297. /**
  12298. * Sets the minimum ending acceleration in the Z direction
  12299. * @param {number} value the minimum acceleration
  12300. */
  12301. GLGE.ParticleSystem.prototype.setMinEndAccZ=function(value){
  12302. this.endMinAcceleration.z=parseFloat(value);
  12303. this.attribute=null;
  12304. }
  12305. /**
  12306. * Sets the minimum ending acceleration in the all direction
  12307. * @param {number} x the minimum velocity in x axis
  12308. * @param {number} y the minimum velocity in y axis
  12309. * @param {number} z the minimum velocity in z axis
  12310. */
  12311. GLGE.ParticleSystem.prototype.setMinEndAccelertaion=function(x,y,z){
  12312. this.endMinAcceleration={x:parseFloat(x),y:parseFloat(y),z:parseFloat(z)};
  12313. this.attribute=null;
  12314. }
  12315. GLGE.ParticleSystem.prototype.getMinEndAccelertaion=function(){
  12316. return this.endMinAcceleration;
  12317. }
  12318. /**
  12319. * Sets the ending acceleration in the X direction
  12320. * @param {number} value the acceleration
  12321. */
  12322. GLGE.ParticleSystem.prototype.setEndAccX=function(value){
  12323. this.endMinAcceleration.x=parseFloat(value);
  12324. this.endMaxAcceleration.x=parseFloat(value);
  12325. this.attribute=null;
  12326. }
  12327. /**
  12328. * Sets the ending acceleration in the Y direction
  12329. * @param {number} value the acceleration
  12330. */
  12331. GLGE.ParticleSystem.prototype.setEndAccY=function(value){
  12332. this.endMinAcceleration.y=parseFloat(value);
  12333. this.endMaxAcceleration.y=parseFloat(value);
  12334. this.attribute=null;
  12335. }
  12336. /**
  12337. * Sets the ending acceleration in the Z direction
  12338. * @param {number} value the acceleration
  12339. */
  12340. GLGE.ParticleSystem.prototype.setEndAccZ=function(value){
  12341. this.endMinAcceleration.z=parseFloat(value);
  12342. this.endMaxAcceleration.z=parseFloat(value);
  12343. this.attribute=null;
  12344. }
  12345. /**
  12346. * Sets the ending acceleration in the all direction
  12347. * @param {number} x the minimum velocity in x axis
  12348. * @param {number} y the minimum velocity in y axis
  12349. * @param {number} z the minimum velocity in z axis
  12350. */
  12351. GLGE.ParticleSystem.prototype.setEndAccelertaion=function(x,y,z){
  12352. this.endMinAcceleration={x:parseFloat(x),y:parseFloat(y),z:parseFloat(z)};
  12353. this.endMaxAcceleration={x:parseFloat(x),y:parseFloat(y),z:parseFloat(z)};
  12354. this.attribute=null;
  12355. }
  12356. /**
  12357. * Sets the starting color of the particle
  12358. * @param {number} value the start color
  12359. */
  12360. GLGE.ParticleSystem.prototype.setStartColor=function(value){
  12361. var color=GLGE.colorParse(value);
  12362. this.startColor=color;
  12363. this.attribute=null;
  12364. }
  12365. GLGE.ParticleSystem.prototype.getStartColor=function(){
  12366. return this.startColor;
  12367. }
  12368. /**
  12369. * Sets the ending color of the particle
  12370. * @param {number} value the end color
  12371. */
  12372. GLGE.ParticleSystem.prototype.setEndColor=function(value){
  12373. var color=GLGE.colorParse(value);
  12374. this.endColor=color;
  12375. this.attribute=null;
  12376. }
  12377. GLGE.ParticleSystem.prototype.getEndColor=function(){
  12378. return this.endColor;
  12379. }
  12380. /**
  12381. * Sets the starting size of the particle
  12382. * @param {number} value the start size
  12383. */
  12384. GLGE.ParticleSystem.prototype.setStartSize=function(value){
  12385. this.startSize=parseFloat(value);
  12386. this.attribute=null;
  12387. }
  12388. GLGE.ParticleSystem.prototype.getStartSize=function(){
  12389. return this.startSize;
  12390. }
  12391. /**
  12392. * Sets the ending size of the particle
  12393. * @param {number} value the end size
  12394. */
  12395. GLGE.ParticleSystem.prototype.setEndSize=function(value){
  12396. this.endSize=parseFloat(value);
  12397. this.attribute=null;
  12398. }
  12399. GLGE.ParticleSystem.prototype.getEndSize=function(){
  12400. return this.endSize;
  12401. }
  12402. /**
  12403. * Sets the particles lifetime
  12404. * @param {number} value the particles life time
  12405. */
  12406. GLGE.ParticleSystem.prototype.setLifeTime=function(value){
  12407. this.maxLifeTime=parseFloat(value);
  12408. this.minLifeTime=parseFloat(value);
  12409. this.attribute=null;
  12410. }
  12411. /**
  12412. * Sets the particles maximum lifetime
  12413. * @param {number} value the particles life time
  12414. */
  12415. GLGE.ParticleSystem.prototype.setMaxLifeTime=function(value){
  12416. this.maxLifeTime=parseFloat(value);
  12417. this.attribute=null;
  12418. }
  12419. GLGE.ParticleSystem.prototype.getMaxLifeTime=function(){
  12420. return this.maxLifeTime;
  12421. }
  12422. /**
  12423. * Sets the particles minimum lifetime
  12424. * @param {number} value the particles life time
  12425. */
  12426. GLGE.ParticleSystem.prototype.setMinLifeTime=function(value){
  12427. this.minLifeTime=parseFloat(value);
  12428. this.attribute=null;
  12429. }
  12430. GLGE.ParticleSystem.prototype.getMinLifeTime=function(){
  12431. return this.minLifeTime;
  12432. }
  12433. /**
  12434. * Sets the total number of particles
  12435. * @param {number} value the number of particles
  12436. */
  12437. GLGE.ParticleSystem.prototype.setNumParticles=function(value){
  12438. this.numParticles=parseFloat(value);
  12439. this.attribute=null;
  12440. }
  12441. GLGE.ParticleSystem.prototype.getNumParticles=function(){
  12442. return this.numParticles;
  12443. }
  12444. /**
  12445. * The particles velocity function used to generate the initial particles velocities
  12446. */
  12447. GLGE.ParticleSystem.prototype.velocityFunction=function(i){
  12448. return [
  12449. (this.startMaxVelocity.x-this.startMinVelocity.x) * Math.random()+this.startMinVelocity.x,
  12450. (this.startMaxVelocity.y-this.startMinVelocity.y) * Math.random()+this.startMinVelocity.y,
  12451. (this.startMaxVelocity.z-this.startMinVelocity.z) * Math.random()+this.startMinVelocity.z
  12452. ];
  12453. }
  12454. /**
  12455. * The particles acceleration function used to generate the initial particles accelerations
  12456. */
  12457. GLGE.ParticleSystem.prototype.accelerationFunction=function(i){
  12458. return [[
  12459. (this.startMaxAcceleration.x-this.startMinAcceleration.x) * Math.random()+this.startMinAcceleration.x,
  12460. (this.startMaxAcceleration.y-this.startMinAcceleration.y) * Math.random()+this.startMinAcceleration.y,
  12461. (this.startMaxAcceleration.z-this.startMinAcceleration.z) * Math.random()+this.startMinAcceleration.z,
  12462. ],
  12463. [
  12464. (this.endMaxAcceleration.x-this.endMinAcceleration.x) * Math.random()+this.endMinAcceleration.x,
  12465. (this.endMaxAcceleration.y-this.endMinAcceleration.y) * Math.random()+this.endMinAcceleration.y,
  12466. (this.endMaxAcceleration.z-this.endMinAcceleration.z) * Math.random()+this.endMinAcceleration.z,
  12467. ]];
  12468. }
  12469. /**
  12470. * The particles color function used to generate the initial colors
  12471. */
  12472. GLGE.ParticleSystem.prototype.colorFunction=function(i){
  12473. return [[this.startColor.r,this.startColor.g,this.startColor.b,this.startColor.a],[this.endColor.r,this.endColor.g,this.endColor.b,this.endColor.a]];
  12474. }
  12475. /**
  12476. * The particles position function used to generate the initial positions
  12477. */
  12478. GLGE.ParticleSystem.prototype.positionFunction=function(i){
  12479. return [0,0,0];
  12480. }
  12481. /**
  12482. * The particles size function used to generate the initial sizes
  12483. */
  12484. GLGE.ParticleSystem.prototype.sizeFunction=function(i){
  12485. return [this.startSize,this.endSize];
  12486. }
  12487. /**
  12488. * The particles life time function used to generate the initial lifetimes
  12489. */
  12490. GLGE.ParticleSystem.prototype.lifeTimeFunction=function(i){
  12491. return (this.maxLifeTime-this.minLifeTime)*Math.random()+this.minLifeTime;
  12492. }
  12493. //lifetime of a particle
  12494. GLGE.ParticleSystem.prototype.minLifeTime=2000;
  12495. GLGE.ParticleSystem.prototype.maxLifeTime=2000;
  12496. //particle emit rate
  12497. GLGE.ParticleSystem.prototype.numParticles=200;
  12498. GLGE.ParticleSystem.prototype.startTime=0;
  12499. GLGE.ParticleSystem.prototype.startSize=0;
  12500. GLGE.ParticleSystem.prototype.endSize=1;
  12501. GLGE.ParticleSystem.prototype.toRender=true;
  12502. GLGE.ParticleSystem.prototype.renderFirst=true;
  12503. GLGE.ParticleSystem.prototype.className="ParticleSystem";
  12504. GLGE.ParticleSystem.prototype.zTrans=true;
  12505. GLGE.ParticleSystem.prototype.velocity=null;
  12506. GLGE.ParticleSystem.prototype.loop=1;
  12507. /**
  12508. * Sets a new velocity function for this particle system
  12509. * @param {function} func the new function
  12510. */
  12511. GLGE.ParticleSystem.prototype.setVelocityFunction=function(func){
  12512. this.velocityFunction=func;
  12513. this.particles=null;
  12514. }
  12515. /**
  12516. * Sets a new acceleration function for this particle system
  12517. * @param {function} func the new function
  12518. */
  12519. GLGE.ParticleSystem.prototype.setAccelerationFunction=function(func){
  12520. this.accelerationFunction=func;
  12521. this.particles=null;
  12522. }
  12523. /**
  12524. * Sets a new position function for this particle system
  12525. * @param {function} func the new function
  12526. */
  12527. GLGE.ParticleSystem.prototype.setPositionFunction=function(func){
  12528. this.colorFunction=func;
  12529. this.particles=null;
  12530. }
  12531. /**
  12532. * Sets a new color function for this particle system
  12533. * @param {function} func the new function
  12534. */
  12535. GLGE.ParticleSystem.prototype.setColorFunction=function(func){
  12536. this.positionFunction=func;
  12537. this.particles=null;
  12538. }
  12539. /**
  12540. * Sets a new size function for this particle system
  12541. * @param {function} func the new function
  12542. */
  12543. GLGE.ParticleSystem.prototype.setSizeFunction=function(func){
  12544. this.sizeFunction=func;
  12545. this.particles=null;
  12546. }
  12547. /**
  12548. * generates the particles
  12549. * @private
  12550. */
  12551. GLGE.ParticleSystem.prototype.generateParticles=function(gl){
  12552. var num_particles=this.numParticles;
  12553. this.attribute={initPos:[],initAcc:[],endAcc:[],initVel:[],initColor:[],endColor:[],sizeAndOffset:[]};
  12554. this.faces=[];
  12555. for(var i=0; i<num_particles;i++){
  12556. var position=this.positionFunction(i);
  12557. var velocity=this.velocityFunction(i);
  12558. var acceleration=this.accelerationFunction(i);
  12559. var color=this.colorFunction(i);
  12560. var size=this.sizeFunction(i);
  12561. var lifetime=this.lifeTimeFunction(i);
  12562. var offsetTime=Math.floor(Math.random()*lifetime);
  12563. for(var y=-1;y<=1;y=y+2){
  12564. for(var x=-1;x<=1;x=x+2){
  12565. this.attribute.initPos.push(parseFloat(position[0])+x,parseFloat(position[1])+y,parseFloat(position[2]));
  12566. this.attribute.initAcc.push(acceleration[0][0],acceleration[0][1],acceleration[0][2]);
  12567. this.attribute.endAcc.push(acceleration[1][0],acceleration[1][1],acceleration[1][2]);
  12568. this.attribute.initVel.push(velocity[0],velocity[1],velocity[2]);
  12569. this.attribute.initColor.push(color[0][0],color[0][1],color[0][2],color[0][3]);
  12570. this.attribute.endColor.push(color[1][0],color[1][1],color[1][2],color[1][3]);
  12571. this.attribute.sizeAndOffset.push(size[0],size[1],offsetTime,lifetime);
  12572. }
  12573. }
  12574. }
  12575. //create the face buffer
  12576. for(var i=0; i<num_particles;i=i+4){
  12577. this.faces.push(0+i,1+i,2+i);
  12578. this.faces.push(1+i,2+i,3+i);
  12579. }
  12580. this.facesGL=gl.createBuffer();
  12581. gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.facesGL);
  12582. gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(this.faces), gl.STATIC_DRAW);
  12583. this.facesGL.num=this.faces.length;
  12584. this.attribute.initPosGL=this.createBuffer(gl,this.attribute.initPos);
  12585. this.attribute.initAccGL=this.createBuffer(gl,this.attribute.initAcc);
  12586. this.attribute.endAccGL=this.createBuffer(gl,this.attribute.endAcc);
  12587. this.attribute.initVelGL=this.createBuffer(gl,this.attribute.initVel);
  12588. this.attribute.initColorGL=this.createBuffer(gl,this.attribute.initColor);
  12589. this.attribute.endColorGL=this.createBuffer(gl,this.attribute.endColor);
  12590. this.attribute.sizeAndOffsetGL=this.createBuffer(gl,this.attribute.sizeAndOffset);
  12591. }
  12592. /**
  12593. * Show the paricle system loop
  12594. * @param {boolean} value the lopping flag
  12595. */
  12596. GLGE.ParticleSystem.prototype.setLoop=function(value){
  12597. this.loop=value;
  12598. }
  12599. /**
  12600. * Resets the particle system
  12601. */
  12602. GLGE.ParticleSystem.prototype.reset=function(){
  12603. this.startTime=GLGE.now();
  12604. }
  12605. /**
  12606. * Creates the particle system shader programs
  12607. * @private
  12608. */
  12609. GLGE.ParticleSystem.prototype.generateProgram=function(gl){
  12610. var vtxShader=[
  12611. //attributes
  12612. "attribute vec3 position;",
  12613. "attribute vec3 initVel;",
  12614. "attribute vec3 initAcc;",
  12615. "attribute vec3 endAcc;",
  12616. "attribute vec4 initColor;",
  12617. "attribute vec4 endColor;",
  12618. "attribute vec4 sizeTimeLife;",
  12619. //uniforms
  12620. "uniform float time;",
  12621. "uniform bool loop;",
  12622. "uniform mat4 mvMatrix;",
  12623. "uniform mat4 pMatrix;",
  12624. //varying
  12625. "varying vec2 UV;",
  12626. "varying vec4 color;",
  12627. //main
  12628. "void main(){",
  12629. "UV = (position.xy+1.0)/2.0;",
  12630. "if((time>sizeTimeLife[2] && (time-sizeTimeLife[2])<sizeTimeLife[3]) || loop){",
  12631. "float localTime = mod((time - sizeTimeLife[2]), sizeTimeLife[3]);",
  12632. "color = (endColor-initColor)/sizeTimeLife[3]*localTime+initColor;",
  12633. "float size = (sizeTimeLife[1]-sizeTimeLife[0])/sizeTimeLife[3]*localTime+sizeTimeLife[0];",
  12634. "vec3 pos = (endAcc-initAcc)*(localTime*log(localTime)-localTime)+0.5*initAcc*localTime*localTime+initVel*localTime;",
  12635. "pos = (mvMatrix*vec4(pos,1.0)).xyz;",
  12636. "vec3 positions = pos+(position*size);",
  12637. "gl_Position = pMatrix*vec4(positions,1.0);",
  12638. "}else{",
  12639. "gl_Position = vec4(0.0,0.0,0.0,1.0);",
  12640. "}",
  12641. "}"
  12642. ].join("");
  12643. frgShader=[
  12644. "#ifdef GL_ES\nprecision mediump float;\n#endif\n",
  12645. //uniforms
  12646. "uniform sampler2D texture;",
  12647. //varying
  12648. "varying vec2 UV;",
  12649. "varying vec4 color;",
  12650. //main
  12651. "void main(){",
  12652. "gl_FragColor=texture2D(texture,UV)*color;",
  12653. "}"
  12654. ].join("");
  12655. var vertexShader=gl.createShader(gl.VERTEX_SHADER);
  12656. var fragmentShader=gl.createShader(gl.FRAGMENT_SHADER);
  12657. gl.shaderSource(vertexShader, vtxShader);
  12658. gl.compileShader(vertexShader);
  12659. if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {
  12660. GLGE.error(gl.getShaderInfoLog(vertexShader));
  12661. return;
  12662. }
  12663. gl.shaderSource(fragmentShader,frgShader);
  12664. gl.compileShader(fragmentShader);
  12665. if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {
  12666. GLGE.error(gl.getShaderInfoLog(fragmentShader));
  12667. return;
  12668. }
  12669. if(this.program) gl.deleteProgram(this.Program);
  12670. this.program = gl.createProgram();
  12671. gl.attachShader(this.program, vertexShader);
  12672. gl.attachShader(this.program, fragmentShader);
  12673. gl.linkProgram(this.program);
  12674. }
  12675. /**
  12676. * Creates the particle system buffers
  12677. * @private
  12678. */
  12679. GLGE.ParticleSystem.prototype.createBuffer=function(gl,array){
  12680. var buffer = gl.createBuffer();
  12681. gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
  12682. gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(array), gl.STATIC_DRAW);
  12683. return buffer;
  12684. }
  12685. /**
  12686. * Sets the uniforms
  12687. * @private
  12688. */
  12689. GLGE.ParticleSystem.prototype.setUniforms=function(gl){
  12690. var program=this.program;
  12691. if(!program.glarrays) program.glarrays={};
  12692. var cameraMatrix=gl.scene.camera.getViewMatrix();
  12693. var pos=this.getPosition();
  12694. //var camerapos=gl.scene.camera.getPosition();
  12695. var mvMatrix=GLGE.mulMat4(cameraMatrix,[
  12696. 1,0,0,pos.x,
  12697. 0,1,0,pos.y,
  12698. 0,0,1,pos.z,
  12699. 0,0,0,1]);
  12700. var mvUniform = GLGE.getUniformLocation(gl,program, "mvMatrix");
  12701. if(!program.glarrays.mvMatrix) program.glarrays.mvMatrix=new Float32Array(mvMatrix);
  12702. else GLGE.mat4gl(mvMatrix,program.glarrays.mvMatrix);
  12703. gl.uniformMatrix4fv(mvUniform, true, program.glarrays.mvMatrix);
  12704. var pUniform = GLGE.getUniformLocation(gl,program, "pMatrix");
  12705. if(!program.glarrays.pMatrix) program.glarrays.pMatrix=new Float32Array(gl.scene.camera.getProjectionMatrix());
  12706. else GLGE.mat4gl(gl.scene.camera.getProjectionMatrix(),program.glarrays.pMatrix);
  12707. gl.uniformMatrix4fv(pUniform, true, program.glarrays.pMatrix);
  12708. gl.uniform1f(GLGE.getUniformLocation(gl,program, "time"), (GLGE.now()-this.startTime));
  12709. gl.uniform1i(GLGE.getUniformLocation(gl,program, "loop"), this.loop);
  12710. gl.activeTexture(gl.TEXTURE0);
  12711. //create the texture if it's not already created
  12712. if(!this.glTexture) this.glTexture=gl.createTexture();
  12713. //if the image is loaded then set in the texture data
  12714. if(this.texture.state==1){
  12715. gl.bindTexture(gl.TEXTURE_2D, this.glTexture);
  12716. gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE,this.texture.image);
  12717. gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, 1);
  12718. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
  12719. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);
  12720. gl.generateMipmap(gl.TEXTURE_2D);
  12721. gl.bindTexture(gl.TEXTURE_2D, null);
  12722. this.texture.state=2;
  12723. program.texture=true;
  12724. }
  12725. gl.bindTexture(gl.TEXTURE_2D, this.glTexture);
  12726. if(program.texture){
  12727. gl.uniform1i(GLGE.getUniformLocation(gl,program, "texture"), 0);
  12728. }
  12729. }
  12730. /**
  12731. * Sets the particle image
  12732. * @param {string} url the image url
  12733. */
  12734. GLGE.ParticleSystem.prototype.setImage=function(url){
  12735. var texture=this.texture;
  12736. texture.image=new Image();
  12737. texture.image.onload=function(e){
  12738. texture.state=1;
  12739. }
  12740. texture.image.src=url;
  12741. }
  12742. /**
  12743. * Sets the attributes
  12744. * @private
  12745. */
  12746. GLGE.ParticleSystem.prototype.setAttributes=function(gl){
  12747. for(var i=0; i<8; i++) gl.disableVertexAttribArray(i);
  12748. var attrib=GLGE.getAttribLocation(gl,this.program, "position");
  12749. if(attrib>-1){
  12750. gl.bindBuffer(gl.ARRAY_BUFFER, this.attribute.initPosGL);
  12751. gl.enableVertexAttribArray(attrib);
  12752. gl.vertexAttribPointer(attrib, 3, gl.FLOAT, false, 0, 0);
  12753. }
  12754. var attrib=GLGE.getAttribLocation(gl,this.program, "initAcc");
  12755. if(attrib>-1){
  12756. gl.bindBuffer(gl.ARRAY_BUFFER, this.attribute.initAccGL);
  12757. gl.enableVertexAttribArray(attrib);
  12758. gl.vertexAttribPointer(attrib, 3, gl.FLOAT, false, 0, 0);
  12759. }
  12760. var attrib=GLGE.getAttribLocation(gl,this.program, "endAcc");
  12761. if(attrib>-1){
  12762. gl.bindBuffer(gl.ARRAY_BUFFER, this.attribute.endAccGL);
  12763. gl.enableVertexAttribArray(attrib);
  12764. gl.vertexAttribPointer(attrib, 3, gl.FLOAT, false, 0, 0);
  12765. }
  12766. var attrib=GLGE.getAttribLocation(gl,this.program, "initColor");
  12767. if(attrib>-1){
  12768. gl.bindBuffer(gl.ARRAY_BUFFER, this.attribute.initColorGL);
  12769. gl.enableVertexAttribArray(attrib);
  12770. gl.vertexAttribPointer(attrib, 4, gl.FLOAT, false, 0, 0);
  12771. }
  12772. var attrib=GLGE.getAttribLocation(gl,this.program, "endColor");
  12773. if(attrib>-1){
  12774. gl.bindBuffer(gl.ARRAY_BUFFER, this.attribute.endColorGL);
  12775. gl.enableVertexAttribArray(attrib);
  12776. gl.vertexAttribPointer(attrib, 4, gl.FLOAT, false, 0, 0);
  12777. }
  12778. var attrib=GLGE.getAttribLocation(gl,this.program, "sizeTimeLife");
  12779. if(attrib>-1){
  12780. gl.bindBuffer(gl.ARRAY_BUFFER, this.attribute.sizeAndOffsetGL);
  12781. gl.enableVertexAttribArray(attrib);
  12782. gl.vertexAttribPointer(attrib, 4, gl.FLOAT, false, 0, 0);
  12783. }
  12784. var attrib=GLGE.getAttribLocation(gl,this.program, "initVel");
  12785. if(attrib>-1){
  12786. gl.bindBuffer(gl.ARRAY_BUFFER, this.attribute.initVelGL);
  12787. gl.enableVertexAttribArray(attrib);
  12788. gl.vertexAttribPointer(attrib, 3, gl.FLOAT, false, 0, 0);
  12789. }
  12790. }
  12791. /**
  12792. * Renders the particle system
  12793. * @private
  12794. */
  12795. GLGE.ParticleSystem.prototype.GLRender=function(gl){
  12796. if(!this.attribute) this.generateParticles(gl);
  12797. if(!this.program) this.generateProgram(gl);
  12798. gl.useProgram(this.program);
  12799. this.setAttributes(gl);
  12800. this.setUniforms(gl);
  12801. gl.colorMask(0,0,0,0);
  12802. gl.disable(gl.BLEND);
  12803. gl.enable(gl.STENCIL_TEST);
  12804. gl.stencilFunc(gl.ALWAYS, 1, 1);
  12805. gl.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE);
  12806. gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.facesGL);
  12807. gl.drawElements(gl.TRIANGLES,this.facesGL.num, gl.UNSIGNED_SHORT, 0);
  12808. gl.stencilFunc(gl.EQUAL, 1, 1);
  12809. gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP);
  12810. gl.colorMask(1,1,1,1);
  12811. gl.disable(gl.DEPTH_TEST);
  12812. gl.enable(gl.BLEND);
  12813. gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.facesGL);
  12814. gl.drawElements(gl.TRIANGLES,this.facesGL.num, gl.UNSIGNED_SHORT, 0);
  12815. gl.stencilOp(gl.REPLACE, gl.REPLACE, gl.REPLACE);
  12816. gl.stencilFunc(gl.ALWAYS, 0, 0);
  12817. gl.enable(gl.DEPTH_TEST);
  12818. gl.scene.lastMaterial=null;
  12819. }
  12820. /**
  12821. * @function Adds a particle system to the scene
  12822. * @param {GLGE.ParticleSystem} the particle system to add
  12823. */
  12824. GLGE.Scene.prototype.addParticleSystem=GLGE.Scene.prototype.addGroup;
  12825. /**
  12826. * @function Adds a particle system to the group
  12827. * @param {GLGE.ParticleSystem} the particle system to add
  12828. */
  12829. GLGE.Group.prototype.addParticleSystem=GLGE.Group.prototype.addGroup;
  12830. })(GLGE);/*
  12831. GLGE WebGL Graphics Engine
  12832. Copyright (c) 2010, Paul Brunt
  12833. All rights reserved.
  12834. Redistribution and use in source and binary forms, with or without
  12835. modification, are permitted provided that the following conditions are met:
  12836. * Redistributions of source code must retain the above copyright
  12837. notice, this list of conditions and the following disclaimer.
  12838. * Redistributions in binary form must reproduce the above copyright
  12839. notice, this list of conditions and the following disclaimer in the
  12840. documentation and/or other materials provided with the distribution.
  12841. * Neither the name of GLGE nor the
  12842. names of its contributors may be used to endorse or promote products
  12843. derived from this software without specific prior written permission.
  12844. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  12845. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  12846. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  12847. DISCLAIMED. IN NO EVENT SHALL PAUL BRUNT BE LIABLE FOR ANY
  12848. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  12849. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  12850. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  12851. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  12852. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  12853. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  12854. */
  12855. /**
  12856. * @fileOverview
  12857. * @name glge_md2.js
  12858. * @author me@paulbrunt.co.uk
  12859. */
  12860. (function(GLGE){
  12861. /**
  12862. * @name GLGE.MD2#md2AnimFinished
  12863. * @event fired when the the animation has finished
  12864. * @param {object} data
  12865. */
  12866. /**
  12867. * @class A quake MD2 model class
  12868. * @augments GLGE.Object
  12869. */
  12870. GLGE.MD2=function(uid){
  12871. this.MD2Started=+new Date;
  12872. this.setAnimation(new GLGE.AnimationVector);
  12873. GLGE.Object.call(this,uid);
  12874. }
  12875. GLGE.augment(GLGE.Object,GLGE.MD2);
  12876. GLGE.MD2.prototype.loadingCache={};
  12877. GLGE.MD2.prototype.headersCache={};
  12878. GLGE.MD2.prototype.meshCache={};
  12879. GLGE.MD2.prototype.MD2Animations={};
  12880. GLGE.MD2.prototype.MD2StartFrame=0;
  12881. GLGE.MD2.prototype.MD2EndFrame=0;
  12882. GLGE.MD2.prototype.MD2Loop=true;
  12883. GLGE.MD2.prototype.MD2AnimFinished=false;
  12884. GLGE.MD2.prototype.headerNames=[
  12885. "ident",
  12886. "version",
  12887. "skinwidth",
  12888. "skinheight",
  12889. "framesize",
  12890. "num_skins",
  12891. "num_xyz",
  12892. "num_st",
  12893. "num_tris",
  12894. "num_glcmds",
  12895. "num_frames",
  12896. "ofs_skins",
  12897. "ofs_st",
  12898. "ofs_tris",
  12899. "ofs_frames",
  12900. "ofs_glcmds",
  12901. "ofs_end"];
  12902. GLGE.MD2.prototype.preNormals = [
  12903. [-0.525731, 0.000000, 0.850651], [-0.442863, 0.238856, 0.864188], [-0.295242, 0.000000, 0.955423],
  12904. [-0.309017, 0.500000, 0.809017], [-0.162460, 0.262866, 0.951056], [ 0.000000, 0.000000, 1.000000],
  12905. [ 0.000000, 0.850651, 0.525731], [-0.147621, 0.716567, 0.681718], [ 0.147621, 0.716567, 0.681718],
  12906. [ 0.000000, 0.525731, 0.850651], [ 0.309017, 0.500000, 0.809017], [ 0.525731, 0.000000, 0.850651],
  12907. [ 0.295242, 0.000000, 0.955423], [ 0.442863, 0.238856, 0.864188], [ 0.162460, 0.262866, 0.951056],
  12908. [-0.681718, 0.147621, 0.716567], [-0.809017, 0.309017, 0.500000], [-0.587785, 0.425325, 0.688191],
  12909. [-0.850651, 0.525731, 0.000000], [-0.864188, 0.442863, 0.238856], [-0.716567, 0.681718, 0.147621],
  12910. [-0.688191, 0.587785, 0.425325], [-0.500000, 0.809017, 0.309017], [-0.238856, 0.864188, 0.442863],
  12911. [-0.425325, 0.688191, 0.587785], [-0.716567, 0.681718, -0.147621], [-0.500000, 0.809017, -0.309017],
  12912. [-0.525731, 0.850651, 0.000000], [ 0.000000, 0.850651, -0.525731], [-0.238856, 0.864188, -0.442863],
  12913. [ 0.000000, 0.955423, -0.295242], [-0.262866, 0.951056, -0.162460], [ 0.000000, 1.000000, 0.000000],
  12914. [ 0.000000, 0.955423, 0.295242], [-0.262866, 0.951056, 0.162460], [ 0.238856, 0.864188, 0.442863],
  12915. [ 0.262866, 0.951056, 0.162460], [ 0.500000, 0.809017, 0.309017], [ 0.238856, 0.864188, -0.442863],
  12916. [ 0.262866, 0.951056, -0.162460], [ 0.500000, 0.809017, -0.309017], [ 0.850651, 0.525731, 0.000000],
  12917. [ 0.716567, 0.681718, 0.147621], [ 0.716567, 0.681718, -0.147621], [ 0.525731, 0.850651, 0.000000],
  12918. [ 0.425325, 0.688191, 0.587785], [ 0.864188, 0.442863, 0.238856], [ 0.688191, 0.587785, 0.425325],
  12919. [ 0.809017, 0.309017, 0.500000], [ 0.681718, 0.147621, 0.716567], [ 0.587785, 0.425325, 0.688191],
  12920. [ 0.955423, 0.295242, 0.000000], [ 1.000000, 0.000000, 0.000000], [ 0.951056, 0.162460, 0.262866],
  12921. [ 0.850651, -0.525731, 0.000000], [ 0.955423, -0.295242, 0.000000], [ 0.864188, -0.442863, 0.238856],
  12922. [ 0.951056, -0.162460, 0.262866], [ 0.809017, -0.309017, 0.500000], [ 0.681718, -0.147621, 0.716567],
  12923. [ 0.850651, 0.000000, 0.525731], [ 0.864188, 0.442863, -0.238856], [ 0.809017, 0.309017, -0.500000],
  12924. [ 0.951056, 0.162460, -0.262866], [ 0.525731, 0.000000, -0.850651], [ 0.681718, 0.147621, -0.716567],
  12925. [ 0.681718, -0.147621, -0.716567], [ 0.850651, 0.000000, -0.525731], [ 0.809017, -0.309017, -0.500000],
  12926. [ 0.864188, -0.442863, -0.238856], [ 0.951056, -0.162460, -0.262866], [ 0.147621, 0.716567, -0.681718],
  12927. [ 0.309017, 0.500000, -0.809017], [ 0.425325, 0.688191, -0.587785], [ 0.442863, 0.238856, -0.864188],
  12928. [ 0.587785, 0.425325, -0.688191], [ 0.688191, 0.587785, -0.425325], [-0.147621, 0.716567, -0.681718],
  12929. [-0.309017, 0.500000, -0.809017], [ 0.000000, 0.525731, -0.850651], [-0.525731, 0.000000, -0.850651],
  12930. [-0.442863, 0.238856, -0.864188], [-0.295242, 0.000000, -0.955423], [-0.162460, 0.262866, -0.951056],
  12931. [ 0.000000, 0.000000, -1.000000], [ 0.295242, 0.000000, -0.955423], [ 0.162460, 0.262866, -0.951056],
  12932. [-0.442863, -0.238856, -0.864188], [-0.309017, -0.500000, -0.809017], [-0.162460, -0.262866, -0.951056],
  12933. [ 0.000000, -0.850651, -0.525731], [-0.147621, -0.716567, -0.681718], [ 0.147621, -0.716567, -0.681718],
  12934. [ 0.000000, -0.525731, -0.850651], [ 0.309017, -0.500000, -0.809017], [ 0.442863, -0.238856, -0.864188],
  12935. [ 0.162460, -0.262866, -0.951056], [ 0.238856, -0.864188, -0.442863], [ 0.500000, -0.809017, -0.309017],
  12936. [ 0.425325, -0.688191, -0.587785], [ 0.716567, -0.681718, -0.147621], [ 0.688191, -0.587785, -0.425325],
  12937. [ 0.587785, -0.425325, -0.688191], [ 0.000000, -0.955423, -0.295242], [ 0.000000, -1.000000, 0.000000],
  12938. [ 0.262866, -0.951056, -0.162460], [ 0.000000, -0.850651, 0.525731], [ 0.000000, -0.955423, 0.295242],
  12939. [ 0.238856, -0.864188, 0.442863], [ 0.262866, -0.951056, 0.162460], [ 0.500000, -0.809017, 0.309017],
  12940. [ 0.716567, -0.681718, 0.147621], [ 0.525731, -0.850651, 0.000000], [-0.238856, -0.864188, -0.442863],
  12941. [-0.500000, -0.809017, -0.309017], [-0.262866, -0.951056, -0.162460], [-0.850651, -0.525731, 0.000000],
  12942. [-0.716567, -0.681718, -0.147621], [-0.716567, -0.681718, 0.147621], [-0.525731, -0.850651, 0.000000],
  12943. [-0.500000, -0.809017, 0.309017], [-0.238856, -0.864188, 0.442863], [-0.262866, -0.951056, 0.162460],
  12944. [-0.864188, -0.442863, 0.238856], [-0.809017, -0.309017, 0.500000], [-0.688191, -0.587785, 0.425325],
  12945. [-0.681718, -0.147621, 0.716567], [-0.442863, -0.238856, 0.864188], [-0.587785, -0.425325, 0.688191],
  12946. [-0.309017, -0.500000, 0.809017], [-0.147621, -0.716567, 0.681718], [-0.425325, -0.688191, 0.587785],
  12947. [-0.162460, -0.262866, 0.951056], [ 0.442863, -0.238856, 0.864188], [ 0.162460, -0.262866, 0.951056],
  12948. [ 0.309017, -0.500000, 0.809017], [ 0.147621, -0.716567, 0.681718], [ 0.000000, -0.525731, 0.850651],
  12949. [ 0.425325, -0.688191, 0.587785], [ 0.587785, -0.425325, 0.688191], [ 0.688191, -0.587785, 0.425325],
  12950. [-0.955423, 0.295242, 0.000000], [-0.951056, 0.162460, 0.262866], [-1.000000, 0.000000, 0.000000],
  12951. [-0.850651, 0.000000, 0.525731], [-0.955423, -0.295242, 0.000000], [-0.951056, -0.162460, 0.262866],
  12952. [-0.864188, 0.442863, -0.238856], [-0.951056, 0.162460, -0.262866], [-0.809017, 0.309017, -0.500000],
  12953. [-0.864188, -0.442863, -0.238856], [-0.951056, -0.162460, -0.262866], [-0.809017, -0.309017, -0.500000],
  12954. [-0.681718, 0.147621, -0.716567], [-0.681718, -0.147621, -0.716567], [-0.850651, 0.000000, -0.525731],
  12955. [-0.688191, 0.587785, -0.425325], [-0.587785, 0.425325, -0.688191], [-0.425325, 0.688191, -0.587785],
  12956. [-0.425325, -0.688191, -0.587785], [-0.587785, -0.425325, -0.688191], [-0.688191, -0.587785, -0.425325]
  12957. ];
  12958. GLGE.MD2.prototype.MD2FrameRate=6;
  12959. /**
  12960. * Gets the absolute path given an import path and the path it's relative to
  12961. * @param {string} path the path to get the absolute path for
  12962. * @param {string} relativeto the path the supplied path is relativeto
  12963. * @returns {string} absolute path
  12964. * @private
  12965. */
  12966. GLGE.MD2.prototype.getAbsolutePath=function(path,relativeto){
  12967. if(path.substr(0,7)=="http://" || path.substr(0,7)=="file://" || path.substr(0,7)=="https://"){
  12968. return path;
  12969. }
  12970. else
  12971. {
  12972. if(!relativeto){
  12973. relativeto=window.location.href;
  12974. }
  12975. if (relativeto.indexOf("://")==-1){
  12976. return relativeto.slice(0,relativeto.lastIndexOf("/"))+"/"+path;
  12977. }
  12978. //find the path compoents
  12979. var bits=relativeto.split("/");
  12980. var domain=bits[2];
  12981. var proto=bits[0];
  12982. var initpath=[];
  12983. for(var i=3;i<bits.length-1;i++){
  12984. initpath.push(bits[i]);
  12985. }
  12986. //relative to domain
  12987. if(path.substr(0,1)=="/"){
  12988. initpath=[];
  12989. }
  12990. var locpath=path.split("/");
  12991. for(var i=0;i<locpath.length;i++){
  12992. if(locpath[i]=="..") initpath.pop();
  12993. else if(locpath[i]!="") initpath.push(locpath[i]);
  12994. }
  12995. return proto+"//"+domain+"/"+initpath.join("/");
  12996. }
  12997. }
  12998. /**
  12999. * Sets the MD2 framerate
  13000. * @param {string} framerate the MD2 files framerate
  13001. */
  13002. GLGE.MD2.prototype.setMD2FrameRate=function(framerate){
  13003. this.MD2FrameRate=framerate;
  13004. return this;
  13005. }
  13006. /**
  13007. * Should GLGE Generate the tangents for the model
  13008. * @param {boolean} value tflag inidcating auto generation of tangents
  13009. */
  13010. GLGE.MD2.prototype.setAutoTangents=function(value){
  13011. this.doTangents=value;
  13012. return this;
  13013. }
  13014. /**
  13015. * Sets the MD2 animation
  13016. * @param {string} framerate the MD2 files framerate
  13017. */
  13018. GLGE.MD2.prototype.setMD2Animation=function(anim,loop){
  13019. this.MD2Anim=anim;
  13020. this.MD2AnimFinished=false;
  13021. if(loop!=undefined) this.MD2Loop=loop;
  13022. this.MD2Started=+new Date;
  13023. if(this.MD2Animations[this.url] && this.MD2Animations[this.url][anim]){
  13024. this.MD2LastAnimFrame=this.lastMD2Frame;
  13025. var a=this.MD2Animations[this.url][anim];
  13026. this.MD2StartFrame=a[0];
  13027. this.MD2EndFrame=a[1];
  13028. }
  13029. return this;
  13030. }
  13031. /**
  13032. * Gets a list of availalbe animations
  13033. * @returns {array} array
  13034. */
  13035. GLGE.MD2.prototype.getAnimations=function(){
  13036. var animations=[];
  13037. for(var name in this.MD2Animations[this.url]) animations.push(name);
  13038. return animations;
  13039. }
  13040. /**
  13041. * Sets the MD2 frame number
  13042. * @param {string} frame the frame to display
  13043. */
  13044. GLGE.MD2.prototype.setMD2Frame=function(frame){
  13045. var totalframes=this.MD2EndFrame-this.MD2StartFrame+1;
  13046. if(totalframes==1) return;
  13047. if(this.MD2Loop){
  13048. frame=frame%totalframes;
  13049. var frame2=((Math.floor(frame)+1)%totalframes);
  13050. }else{
  13051. frame=Math.min(totalframes-1,frame);
  13052. frame2=Math.min(totalframes-1,Math.floor(frame)+1);
  13053. if(frame==(totalframes-1) && !this.MD2AnimFinished){
  13054. this.MD2AnimFinished=true;
  13055. this.fireEvent("md2AnimFinished",{});
  13056. }
  13057. }
  13058. var framefrac=frame%1;
  13059. if(frame<1 && this.MD2LastAnimFrame!=undefined){
  13060. frame=this.MD2LastAnimFrame-this.MD2StartFrame;
  13061. }else{
  13062. this.MD2LastAnimFrame=null;
  13063. this.lastMD2Frame=Math.floor(frame)+this.MD2StartFrame;
  13064. }
  13065. this.setMeshFrame1(Math.floor(frame)+this.MD2StartFrame);
  13066. this.setMeshFrame2(frame2+this.MD2StartFrame);
  13067. this.setMeshBlendFactor(framefrac);
  13068. }
  13069. GLGE.MD2.prototype.animate=function(now,nocache){
  13070. if(!now) now=+new Date;
  13071. if(this.header){
  13072. var frame=(now-this.MD2Started)/1000*this.MD2FrameRate;
  13073. this.setMD2Frame(frame);
  13074. }
  13075. GLGE.Object.prototype.animate.call(this,now,nocache);
  13076. }
  13077. /**
  13078. * Sets the url of the MD2 model
  13079. * @param {string} url the url to the MD2 file
  13080. */
  13081. GLGE.MD2.prototype.setSrc=function(url,relativeTo){
  13082. if(relativeTo) url=this.getAbsolutePath(url,relativeTo);
  13083. this.url=url;
  13084. //prevent the same model parsing multiple times
  13085. if(this.loadingCache[this.url] && !this.headersCache[url]){
  13086. var that=this;
  13087. setTimeout(function(){that.setSrc(url)},15);
  13088. return;
  13089. }
  13090. this.loadingCache[this.url]=true;
  13091. if(this.headersCache[url]){
  13092. this.header=this.headersCache[url];
  13093. this.setMesh(this.meshCache[url]);
  13094. if(this.MD2Anim) this.setMD2Animation(this.MD2Anim);
  13095. this.fireEvent("loaded",{url:this.url});
  13096. return;
  13097. }
  13098. var that=this;
  13099. var xhr = new XMLHttpRequest();
  13100. xhr.overrideMimeType('text/plain; charset=x-user-defined');
  13101. xhr.open("GET", url, true);
  13102. xhr.send(null);
  13103. this.verts=[];
  13104. this.normals=[];
  13105. xhr.onreadystatechange = function (aEvt) {
  13106. if (xhr.readyState == 4) {
  13107. if(xhr.status == 200){
  13108. response = xhr.responseText;
  13109. if (response) {
  13110. var buffer = new ArrayBuffer(response.length);
  13111. var byteArray = new Uint8Array(buffer);
  13112. var byteArray = [];
  13113. for(var i=0;i<response.length;i++){
  13114. byteArray[i]=response.charCodeAt(i) & 0xff;
  13115. }
  13116. that.bufferLoaded(byteArray);
  13117. }
  13118. }else{
  13119. alert("Error loading page\n");
  13120. }
  13121. }
  13122. };
  13123. }
  13124. /**
  13125. * Called when the model has loaded
  13126. * @private
  13127. */
  13128. GLGE.MD2.prototype.bufferLoaded=function(byteArray){
  13129. this.byteArray=byteArray;
  13130. this.parseHeader();
  13131. this.parseFrames();
  13132. this.parseUVs();
  13133. this.parseFaces();
  13134. if(this.MD2Anim) this.setMD2Animation(this.MD2Anim,this.MD2Loop);
  13135. }
  13136. /**
  13137. * Extract header info
  13138. * @private
  13139. */
  13140. GLGE.MD2.prototype.parseHeader=function(){
  13141. this.header={};
  13142. for (var i=0; i<this.headerNames.length; i++) {
  13143. this.header[this.headerNames[i]]=this.getUint16At(i*4);
  13144. }
  13145. this.headersCache[this.url]=this.header;
  13146. }
  13147. /**
  13148. * get 16 bit int at location
  13149. * @private
  13150. */
  13151. GLGE.MD2.prototype.getUint16At=function(index){
  13152. return this.byteArray[index]+this.byteArray[index+1]*256;
  13153. }
  13154. /**
  13155. * get 32 bit float at location
  13156. * @private
  13157. */
  13158. GLGE.MD2.prototype.getFloat32At=function(index){
  13159. var b3=this.byteArray[index];
  13160. var b2=this.byteArray[index+1];
  13161. var b1=this.byteArray[index+2];
  13162. var b0=this.byteArray[index+3];
  13163. sign = 1 - (2 * (b0 >> 7)),
  13164. exponent = (((b0 << 1) & 0xff) | (b1 >> 7)) - 127,
  13165. mantissa = ((b1 & 0x7f) << 16) | (b2 << 8) | b3;
  13166. if (mantissa == 0 && exponent == -127) {
  13167. return 0.0;
  13168. }
  13169. if (exponent == -127) { // Denormalized
  13170. return sign * mantissa * Math.pow(2, -126 - 23);
  13171. }
  13172. return sign * (1 + mantissa * Math.pow(2, -23)) * Math.pow(2, exponent);
  13173. }
  13174. /**
  13175. * process the frame data
  13176. * @private
  13177. */
  13178. GLGE.MD2.prototype.parseFrames=function(){
  13179. var vertsArray = this.byteArray;
  13180. var startFrame=0;
  13181. var MD2Animations={};
  13182. for(var j=0;j<this.header.num_frames;j++){
  13183. var scaleTrans=[
  13184. this.getFloat32At(this.header.ofs_frames+j*this.header.framesize),
  13185. this.getFloat32At(this.header.ofs_frames+4+j*this.header.framesize),
  13186. this.getFloat32At(this.header.ofs_frames+8+j*this.header.framesize),
  13187. this.getFloat32At(this.header.ofs_frames+12+j*this.header.framesize),
  13188. this.getFloat32At(this.header.ofs_frames+16+j*this.header.framesize),
  13189. this.getFloat32At(this.header.ofs_frames+20+j*this.header.framesize)
  13190. ];
  13191. var verts=[];
  13192. var normals=[];
  13193. var start=this.header.ofs_frames+24+j*this.header.framesize;
  13194. var frameName="";
  13195. for(var i=start;i<start+16;i++){
  13196. if(vertsArray[i]==0) break;
  13197. frameName+=String.fromCharCode(vertsArray[i]);
  13198. }
  13199. frameName=frameName.replace(/[0-9]/g,'');
  13200. if(lastFrameName && frameName!=lastFrameName){
  13201. MD2Animations[lastFrameName]=[startFrame,j-1];
  13202. startFrame=j;
  13203. }
  13204. var lastFrameName=frameName;
  13205. start=this.header.ofs_frames+40+j*this.header.framesize;
  13206. for(var i=start;i<start+this.header.framesize-40;i=i+12){
  13207. verts.push(vertsArray[i]*scaleTrans[0]+scaleTrans[3]);
  13208. verts.push(vertsArray[i+1]*scaleTrans[1]+scaleTrans[4]);
  13209. verts.push(vertsArray[i+2]*scaleTrans[2]+scaleTrans[5]);
  13210. verts.push(vertsArray[i+4]*scaleTrans[0]+scaleTrans[3]);
  13211. verts.push(vertsArray[i+5]*scaleTrans[1]+scaleTrans[4]);
  13212. verts.push(vertsArray[i+6]*scaleTrans[2]+scaleTrans[5]);
  13213. verts.push(vertsArray[i+8]*scaleTrans[0]+scaleTrans[3]);
  13214. verts.push(vertsArray[i+9]*scaleTrans[1]+scaleTrans[4]);
  13215. verts.push(vertsArray[i+10]*scaleTrans[2]+scaleTrans[5]);
  13216. var n=this.preNormals[vertsArray[i+3]];
  13217. if(!n) n=[0,0,1]; //sanity check
  13218. normals.push(n[0]);normals.push(n[1]);normals.push(n[2]);
  13219. n=this.preNormals[vertsArray[i+7]];
  13220. if(!n) n=[0,0,1]; //sanity check
  13221. normals.push(n[0]);normals.push(n[1]);normals.push(-n[2]);
  13222. n=this.preNormals[vertsArray[i+11]];
  13223. if(!n) n=[0,0,1]; //sanity check
  13224. normals.push(n[0]);normals.push(n[1]);normals.push(n[2]);
  13225. }
  13226. this.verts[j]=verts;
  13227. this.normals[j]=normals;
  13228. }
  13229. MD2Animations[lastFrameName]=[startFrame,j-2];
  13230. this.MD2Animations[this.url]=MD2Animations;
  13231. }
  13232. /**
  13233. * Process the UV data
  13234. * @private
  13235. */
  13236. GLGE.MD2.prototype.parseUVs=function(){
  13237. var uvs=[];
  13238. var byteArray=this.byteArray;
  13239. var start=this.header.ofs_st;
  13240. for(var i=start;i<start+this.header.num_st*4;i=i+4){
  13241. uvs.push(this.getUint16At(i)/this.header.skinwidth);
  13242. uvs.push(1-this.getUint16At(i+2)/this.header.skinheight);
  13243. }
  13244. this.globaluvs=uvs;
  13245. }
  13246. /**
  13247. * parses the face data in the md2 file
  13248. * @private
  13249. */
  13250. GLGE.MD2.prototype.parseFaces=function(){
  13251. var start=this.header.ofs_tris;
  13252. var len=start+this.header.num_tris*12;
  13253. var faces=[];
  13254. var uvs=[];
  13255. var verts=[];
  13256. var normals=[];
  13257. var idx=0;
  13258. for(var i=start;i<len;i=i+12){
  13259. faces.push(idx++);
  13260. faces.push(idx++);
  13261. faces.push(idx++);
  13262. var n1=this.getUint16At(i);
  13263. var n2=this.getUint16At(i+2);
  13264. var n3=this.getUint16At(i+4);
  13265. for(var j=0;j<this.verts.length;j++){
  13266. if(!verts[j]){verts[j]=[];normals[j]=[];}
  13267. var v=this.verts[j];
  13268. var n=this.normals[j];
  13269. verts[j].push(v[n1*3]);
  13270. verts[j].push(v[n1*3+1]);
  13271. verts[j].push(v[n1*3+2]);
  13272. normals[j].push(n[n1*3]);
  13273. normals[j].push(n[n1*3+1]);
  13274. normals[j].push(n[n1*3+2]);
  13275. verts[j].push(v[n2*3]);
  13276. verts[j].push(v[n2*3+1]);
  13277. verts[j].push(v[n2*3+2]);
  13278. normals[j].push(n[n2*3]);
  13279. normals[j].push(n[n2*3+1]);
  13280. normals[j].push(n[n2*3+2]);
  13281. verts[j].push(v[n3*3]);
  13282. verts[j].push(v[n3*3+1]);
  13283. verts[j].push(v[n3*3+2]);
  13284. normals[j].push(n[n3*3]);
  13285. normals[j].push(n[n3*3+1]);
  13286. normals[j].push(n[n3*3+2]);
  13287. }
  13288. uvs.push(this.globaluvs[this.getUint16At(i+6)*2]);
  13289. uvs.push(this.globaluvs[this.getUint16At(i+6)*2+1]);
  13290. uvs.push(this.globaluvs[this.getUint16At(i+8)*2]);
  13291. uvs.push(this.globaluvs[this.getUint16At(i+8)*2+1]);
  13292. uvs.push(this.globaluvs[this.getUint16At(i+10)*2]);
  13293. uvs.push(this.globaluvs[this.getUint16At(i+10)*2+1]);
  13294. }
  13295. this.normals=normals;
  13296. this.verts=verts;
  13297. this.uvs=uvs;
  13298. this.faces=faces;
  13299. this.createMesh()
  13300. }
  13301. /**
  13302. * creates the mesh
  13303. * @private
  13304. */
  13305. GLGE.MD2.prototype.createMesh=function(){
  13306. var m=new GLGE.Mesh;
  13307. var verts=this.verts;
  13308. var normals=this.normals;
  13309. var uvs=this.uvs;
  13310. var faces=this.faces;
  13311. for(var i=0;i<verts.length;i++){
  13312. m.setPositions(verts[i],i).setNormals(normals[i],i);
  13313. }
  13314. if(this.doTangents){
  13315. m.setUV(uvs).setFaces(faces);
  13316. }else{
  13317. m.setFaces(faces).setUV(uvs);
  13318. }
  13319. this.setMesh(m);
  13320. this.meshCache[this.url]=m;
  13321. this.fireEvent("loaded",{url:this.url});
  13322. }
  13323. GLGE.Group.prototype.addMD2=GLGE.Group.prototype.addObject;
  13324. GLGE.Scene.prototype.addMD2=GLGE.Scene.prototype.addObject;
  13325. })(GLGE);/*
  13326. GLGE WebGL Graphics Engine
  13327. Copyright (c) 2010, Paul Brunt
  13328. All rights reserved.
  13329. Redistribution and use in source and binary forms, with or without
  13330. modification, are permitted provided that the following conditions are met:
  13331. * Redistributions of source code must retain the above copyright
  13332. notice, this list of conditions and the following disclaimer.
  13333. * Redistributions in binary form must reproduce the above copyright
  13334. notice, this list of conditions and the following disclaimer in the
  13335. documentation and/or other materials provided with the distribution.
  13336. * Neither the name of GLGE nor the
  13337. names of its contributors may be used to endorse or promote products
  13338. derived from this software without specific prior written permission.
  13339. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  13340. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  13341. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  13342. DISCLAIMED. IN NO EVENT SHALL PAUL BRUNT BE LIABLE FOR ANY
  13343. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  13344. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  13345. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  13346. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  13347. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  13348. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  13349. */
  13350. /**
  13351. * @fileOverview
  13352. * @name glge_md3.js
  13353. * @author me@paulbrunt.co.uk
  13354. */
  13355. (function(GLGE){
  13356. /**
  13357. * @name GLGE.MD3#md3AnimFinished
  13358. * @event fired when the the animation has finished
  13359. * @param {object} data
  13360. */
  13361. /**
  13362. * @class A quake MD3 model class
  13363. * @augments GLGE.Group
  13364. */
  13365. GLGE.MD3=function(uid){
  13366. this.MD3Started=+new Date;
  13367. this.MD3Materials=[];
  13368. this.surfaces=[];
  13369. this.MD3Children=[];
  13370. this.loaded=false;
  13371. this.setAnimation(new GLGE.AnimationVector); //set animation to force animation
  13372. GLGE.Group.call(this,uid);
  13373. }
  13374. GLGE.augment(GLGE.Group,GLGE.MD3);
  13375. GLGE.MD3.prototype.MD3FrameRate=10;
  13376. GLGE.MD3.prototype.MD3Animations={};
  13377. GLGE.MD3.prototype.MD3Tags={};
  13378. GLGE.MD3.prototype.MD3StartFrame=0;
  13379. GLGE.MD3.prototype.MD3EndFrame=0;
  13380. GLGE.MD3.prototype.MD3Loop=true;
  13381. GLGE.MD3.prototype.headerNames=[
  13382. "NUM_FRAMES",
  13383. "NUM_TAGS",
  13384. "NUM_SURFACES",
  13385. "NUM_SKINS",
  13386. "OFS_FRAMES",
  13387. "OFS_TAGS",
  13388. "OFS_SURFACES",
  13389. "OFS_EOF"
  13390. ];
  13391. GLGE.MD3.prototype.surfaceHeaderNames=[
  13392. "NUM_FRAMES",
  13393. "NUM_SHADERS",
  13394. "NUM_VERTS",
  13395. "NUM_TRIANGLES",
  13396. "OFS_TRIANGLES",
  13397. "OFS_SHADERS",
  13398. "OFS_ST",
  13399. "OFS_XYZNORMAL",
  13400. "OFS_END"
  13401. ]
  13402. /**
  13403. * Gets the absolute path given an import path and the path it's relative to
  13404. * @param {string} path the path to get the absolute path for
  13405. * @param {string} relativeto the path the supplied path is relativeto
  13406. * @returns {string} absolute path
  13407. * @private
  13408. */
  13409. GLGE.MD3.prototype.getAbsolutePath=function(path,relativeto){
  13410. if(path.substr(0,7)=="http://" || path.substr(0,7)=="file://" || path.substr(0,7)=="https://"){
  13411. return path;
  13412. }
  13413. else
  13414. {
  13415. if(!relativeto){
  13416. relativeto=window.location.href;
  13417. }
  13418. if (relativeto.indexOf("://")==-1){
  13419. return relativeto.slice(0,relativeto.lastIndexOf("/"))+"/"+path;
  13420. }
  13421. //find the path compoents
  13422. var bits=relativeto.split("/");
  13423. var domain=bits[2];
  13424. var proto=bits[0];
  13425. var initpath=[];
  13426. for(var i=3;i<bits.length-1;i++){
  13427. initpath.push(bits[i]);
  13428. }
  13429. //relative to domain
  13430. if(path.substr(0,1)=="/"){
  13431. initpath=[];
  13432. }
  13433. var locpath=path.split("/");
  13434. for(var i=0;i<locpath.length;i++){
  13435. if(locpath[i]=="..") initpath.pop();
  13436. else if(locpath[i]!="") initpath.push(locpath[i]);
  13437. }
  13438. return proto+"//"+domain+"/"+initpath.join("/");
  13439. }
  13440. }
  13441. /**
  13442. * Sets the url of the MD3 model
  13443. * @param {string} url the url to the MD3 file
  13444. */
  13445. GLGE.MD3.prototype.setSrc=function(url,relativeTo){
  13446. if(relativeTo) url=this.getAbsolutePath(url,relativeTo);
  13447. this.url=url;
  13448. var that=this;
  13449. var xhr = new XMLHttpRequest();
  13450. xhr.overrideMimeType('text/plain; charset=x-user-defined');
  13451. xhr.open("GET", url, true);
  13452. xhr.send(null);
  13453. this.verts=[];
  13454. this.normals=[];
  13455. xhr.onreadystatechange = function (aEvt) {
  13456. if (xhr.readyState == 4) {
  13457. if(xhr.status == 200){
  13458. response = xhr.responseText;
  13459. if (response) {
  13460. var buffer = new ArrayBuffer(response.length);
  13461. var byteArray = new Uint8Array(buffer);
  13462. var byteArray = [];
  13463. for(var i=0;i<response.length;i++){
  13464. byteArray[i]=response.charCodeAt(i) & 0xff;
  13465. }
  13466. that.bufferLoaded(byteArray);
  13467. }
  13468. }else{
  13469. alert("Error loading page\n");
  13470. }
  13471. }
  13472. };
  13473. }
  13474. /**
  13475. * Sets the MD3 framerate
  13476. * @param {string} framerate the MD3 files framerate
  13477. */
  13478. GLGE.MD3.prototype.setMD3FrameRate=function(framerate){
  13479. this.MD3FrameRate=framerate;
  13480. return this;
  13481. }
  13482. /**
  13483. * Sets the tag to attach the model to
  13484. * @param {string} tag The name of the tag to attach to.
  13485. */
  13486. GLGE.MD3.prototype.setTag=function(tag){
  13487. this.MD3Tag=tag;
  13488. return this;
  13489. }
  13490. /**
  13491. * Called when the model has loaded
  13492. * @private
  13493. */
  13494. GLGE.MD3.prototype.bufferLoaded=function(byteArray){
  13495. this.byteArray=byteArray;
  13496. this.parseHeader();
  13497. this.parseFrames();
  13498. this.parseTags();
  13499. this.createTags();
  13500. this.parseSurfaces();
  13501. this.addSurfaces(); //adds the surfaces to this group
  13502. if(this.MD3Anim) this.setMD3Animation(this.MD3Anim,this.MD3Loop);
  13503. if(this.MD3Children.length>0) this.addMD3Childred();
  13504. this.loaded=true;
  13505. this.fireEvent("loaded",{url:this.url});
  13506. }
  13507. /**
  13508. * Adds the child md3 object
  13509. * @private
  13510. */
  13511. GLGE.MD3.prototype.addMD3Childred=function(){
  13512. for(var i=0; i<this.MD3Children.length;i++){
  13513. this.addMD3(this.MD3Children[i]);
  13514. }
  13515. }
  13516. /**
  13517. * Adds the surfaces to this group
  13518. * @private
  13519. */
  13520. GLGE.MD3.prototype.addSurfaces=function(){
  13521. for(var i=0;i<this.surfaces.length;i++){
  13522. if(this.MD3Tag) {
  13523. t=this.MD3Tags[this.url][this.MD3Tag];
  13524. this.surfaces[i].setLocX(t[0][0]).setLocY(t[0][1]).setLocX(t[0][1]).setRotMatrix(t[1]);
  13525. }
  13526. this.addObject(this.surfaces[i]);
  13527. }
  13528. return this;
  13529. }
  13530. /**
  13531. * Gets a list of availalbe animations
  13532. * @returns {array} array
  13533. */
  13534. GLGE.MD3.prototype.getAnimations=function(){
  13535. var animations=[];
  13536. for(var name in this.MD3Animations[this.url]) animations.push(name);
  13537. return animations;
  13538. }
  13539. /**
  13540. * Sets the MD3 animation
  13541. * @param {string} framerate the MD3 files framerate
  13542. */
  13543. GLGE.MD3.prototype.setMD3Animation=function(anim,loop){
  13544. this.MD3Anim=anim;
  13545. if(loop!=undefined) this.MD3Loop=loop;
  13546. this.MD3Started=+new Date;
  13547. if(this.MD3Animations[this.url] && this.MD3Animations[this.url][anim]){
  13548. this.MD3LastAnimFrame=this.lastMD2Frame;
  13549. var a=this.MD3Animations[this.url][anim];
  13550. this.MD3StartFrame=a[0];
  13551. this.MD3EndFrame=a[1];
  13552. }
  13553. return this;
  13554. }
  13555. /**
  13556. * Creates the tag groups
  13557. * @private
  13558. */
  13559. GLGE.MD3.prototype.createTags=function(){
  13560. var tags=this.MD3Tags[this.url];
  13561. this.MD3TagGroups={};
  13562. for(var tag in tags){
  13563. var t=tags[tag];
  13564. var g=(new GLGE.Group).setLocX(t[0][0]).setLocY(t[0][1]).setLocX(t[0][1]).setRotMatrix(t[1]);
  13565. this.addGroup(g);
  13566. this.MD3TagGroups[tag]=g;
  13567. }
  13568. }
  13569. /**
  13570. * Extract tag info
  13571. * @private
  13572. */
  13573. GLGE.MD3.prototype.parseTags=function(){
  13574. //alert(this.url);
  13575. var start=this.headers.OFS_TAGS;
  13576. var tagSize=112;
  13577. var data=this.MD3Tags[this.url]={};
  13578. for(var i=0;i<this.headers.NUM_TAGS;i++){
  13579. var name=this.getStringAt(start+i*tagSize,64).replace(/[0-9_]/g,'');
  13580. var posStart=start+i*tagSize+64
  13581. var pos=[this.getFloat32At(posStart)*10,this.getFloat32At(posStart+4)*10,this.getFloat32At(posStart+8)*10];
  13582. var rotStart=posStart+12;
  13583. var rot=[this.getFloat32At(rotStart),this.getFloat32At(rotStart+4),this.getFloat32At(rotStart+8),0,
  13584. this.getFloat32At(rotStart+12),this.getFloat32At(rotStart+16),this.getFloat32At(rotStart+20),0,
  13585. this.getFloat32At(rotStart+24),this.getFloat32At(rotStart+28),this.getFloat32At(rotStart+32),0,
  13586. 0,0,0,1];
  13587. /*var rot=[this.getFloat32At(rotStart),this.getFloat32At(rotStart+12),this.getFloat32At(rotStart+24),0,
  13588. this.getFloat32At(rotStart+4),this.getFloat32At(rotStart+16),this.getFloat32At(rotStart+28),0,
  13589. this.getFloat32At(rotStart+8),this.getFloat32At(rotStart+20),this.getFloat32At(rotStart+32),0,
  13590. 0,0,0,1];*/
  13591. data[name]=[pos,rot];
  13592. //alert(name);
  13593. //alert(pos);
  13594. }
  13595. }
  13596. /**
  13597. * Extract frame info
  13598. * @private
  13599. */
  13600. GLGE.MD3.prototype.parseFrames=function(){
  13601. var start=this.headers.OFS_FRAMES+40;
  13602. var frameSize=56;
  13603. var animations={};
  13604. var lastName=false;
  13605. var firstFrame=0;
  13606. for(var i=0;i<this.headers.NUM_FRAMES;i++){
  13607. var name=this.getStringAt(start+i*frameSize,16).replace(/[0-9_]/g,'');
  13608. if(lastName && lastName!=name){
  13609. animations[lastName]=[firstFrame,i-1];
  13610. firstFrame=i;
  13611. }
  13612. lastName=name;
  13613. }
  13614. animations[lastName]=[firstFrame,i-3];
  13615. this.MD3Animations[this.url]=animations;
  13616. }
  13617. /**
  13618. * Extract header info
  13619. * @private
  13620. */
  13621. GLGE.MD3.prototype.parseHeader=function(){
  13622. this.headers={};
  13623. for (var i=0; i<this.headerNames.length; i++) {
  13624. this.headers[this.headerNames[i]]=this.getSint32At(i*4+76);
  13625. }
  13626. }
  13627. /**
  13628. * Parse the surfaces
  13629. * @private
  13630. */
  13631. GLGE.MD3.prototype.parseSurfaces=function(){
  13632. this.surfaceHeaders=[];
  13633. var offset=this.headers.OFS_SURFACES;
  13634. for(var i=0;i<this.headers.NUM_SURFACES;i++){
  13635. var start=offset+72;
  13636. var sHeaders=this.surfaceHeaders[i]={offset:offset};
  13637. var idx=0;
  13638. for(var j=start;j<start+36;j=j+4){
  13639. sHeaders[this.surfaceHeaderNames[idx++]]=this.getSint32At(j);
  13640. }
  13641. var normverts=this.parseNormVerts(i);
  13642. var uvs=this.parseUVs(i);
  13643. var faces=this.parseFaces(i);
  13644. var mesh=this.createMesh(normverts[0],normverts[1],uvs,faces);
  13645. var surface=new GLGE.Object;
  13646. if(!this.MD3Materials[i]) this.MD3Materials[i]=new GLGE.Material;
  13647. surface.setMaterial(this.MD3Materials[i]);
  13648. surface.setMesh(mesh);
  13649. this.surfaces.push(surface);
  13650. offset+=this.surfaceHeaders[i].OFS_END;
  13651. }
  13652. }
  13653. /**
  13654. * Creates a mesh
  13655. * @private
  13656. */
  13657. GLGE.MD3.prototype.createMesh=function(verts,normals,uvs,faces){
  13658. var m=new GLGE.Mesh;
  13659. for(var i=0;i<verts.length;i++){
  13660. m.setPositions(verts[i],i).setNormals(normals[i],i);
  13661. }
  13662. m.setFaces(faces).setUV(uvs);
  13663. return m;
  13664. }
  13665. /**
  13666. * Parse the Faces
  13667. * @private
  13668. */
  13669. GLGE.MD3.prototype.parseFaces=function(surface){
  13670. var header=this.surfaceHeaders[surface];
  13671. var faces=[];
  13672. var start=header.offset+header.OFS_TRIANGLES;
  13673. var end=12*header.NUM_TRIANGLES;
  13674. for(var i=start; i<start+end;i=i+12){
  13675. faces.push(this.getSint32At(i));
  13676. faces.push(this.getSint32At(i+4));
  13677. faces.push(this.getSint32At(i+8));
  13678. }
  13679. return faces;
  13680. }
  13681. /**
  13682. * Parse the vertex UVs
  13683. * @private
  13684. */
  13685. GLGE.MD3.prototype.parseUVs=function(surface){
  13686. var header=this.surfaceHeaders[surface];
  13687. var uvs=[];
  13688. var start=header.offset+header.OFS_ST;
  13689. var end=8*header.NUM_VERTS;
  13690. for(var i=start; i<start+end;i=i+8){
  13691. uvs.push(this.getFloat32At(i));
  13692. uvs.push(1-this.getFloat32At(i+4));
  13693. }
  13694. return uvs;
  13695. }
  13696. /**
  13697. * Parse the verts for each frame
  13698. * @private
  13699. */
  13700. GLGE.MD3.prototype.parseNormVerts=function(surface){
  13701. var header=this.surfaceHeaders[surface];
  13702. var verts=[];
  13703. var normals=[];
  13704. var start=header.offset+header.OFS_XYZNORMAL;
  13705. var frameSize=8*header.NUM_VERTS;
  13706. for(var frame=0; frame<header.NUM_FRAMES; frame++){
  13707. var frameVerts=[];
  13708. var frameNormals=[];
  13709. for(var i=start+frame*frameSize; i<start+(frame+1)*frameSize;i=i+8){
  13710. frameVerts.push(this.getSint16At(i)/64);
  13711. frameVerts.push(this.getSint16At(i+2)/64);
  13712. frameVerts.push(this.getSint16At(i+4)/64);
  13713. var norm=this.decodeNormal(this.byteArray[i+6],this.byteArray[i+7]);
  13714. frameNormals.push(norm[0]);
  13715. frameNormals.push(norm[1]);
  13716. frameNormals.push(norm[2]);
  13717. }
  13718. verts[frame]=frameVerts;
  13719. normals[frame]=frameNormals;
  13720. }
  13721. return [verts,normals];
  13722. }
  13723. /**
  13724. * Decode the normal coords
  13725. * @private
  13726. */
  13727. GLGE.MD3.prototype.decodeNormal=function(zenith,azimuth){
  13728. var lat = zenith * (2 * Math.PI) / 255;
  13729. var lng = azimuth * (2 * Math.PI) / 255;
  13730. var clat=Math.cos(lat);
  13731. var slat=Math.sin(lat);
  13732. var clng=Math.cos(lng);
  13733. var slng=Math.sin(lng);
  13734. return [-clat*slng,-slat*slng,clng];
  13735. }
  13736. /**
  13737. * Gets the attach points(tags) availalbe
  13738. * @returns Array of availalbe attach points
  13739. */
  13740. GLGE.MD3.prototype.getAttachPoints=function(){
  13741. var attachPoints=[];
  13742. for(var tag in this.MD3TagGroups) attachPoints.push(tag);
  13743. return attachPoints
  13744. }
  13745. /**
  13746. * get 16 bit int at location
  13747. * @private
  13748. */
  13749. GLGE.MD3.prototype.getSint16At=function(index){
  13750. var value=this.byteArray[index]|(this.byteArray[index+1]<<8);
  13751. if(value>0x8000) value=value-0x10000;
  13752. return value;
  13753. }
  13754. /**
  13755. * get 32 bit signed int at location
  13756. * @private
  13757. */
  13758. GLGE.MD3.prototype.getSint32At=function(index){
  13759. var value=this.byteArray[index]|(this.byteArray[index+1]<<8)|(this.byteArray[index+2]<<16)|(this.byteArray[index+3]<<24);
  13760. if(value>0x80000000) value=value-0x100000000;
  13761. return value;
  13762. }
  13763. /**
  13764. * Get 32 bit float at location
  13765. * @private
  13766. */
  13767. GLGE.MD3.prototype.getFloat32At=function(index){
  13768. var b3=this.byteArray[index];
  13769. var b2=this.byteArray[index+1];
  13770. var b1=this.byteArray[index+2];
  13771. var b0=this.byteArray[index+3];
  13772. sign = 1 - (2 * (b0 >> 7)),
  13773. exponent = (((b0 << 1) & 0xff) | (b1 >> 7)) - 127,
  13774. mantissa = ((b1 & 0x7f) << 16) | (b2 << 8) | b3;
  13775. if (mantissa == 0 && exponent == -127) {
  13776. return 0.0;
  13777. }
  13778. if (exponent == -127) { // Denormalized
  13779. return sign * mantissa * Math.pow(2, -126 - 23);
  13780. }
  13781. return sign * (1 + mantissa * Math.pow(2, -23)) * Math.pow(2, exponent);
  13782. }
  13783. /**
  13784. * Get 32 bit float at location
  13785. * @private
  13786. */
  13787. GLGE.MD3.prototype.getStringAt=function(index,size){
  13788. var name="";
  13789. for(var i=index;i<index+size;i++){
  13790. if(this.byteArray[i]==0) break;
  13791. name+=String.fromCharCode(this.byteArray[i]);
  13792. }
  13793. return name;
  13794. }
  13795. /**
  13796. * Adds an MD3 model as a child of this MD3 Group
  13797. * @param {GLGE.MD3} md3 the md3 group to attach
  13798. */
  13799. GLGE.MD3.prototype.addMD3=function(md3){
  13800. if(!this.loaded){
  13801. this.addEventListener("loaded",function(){
  13802. this.addMD3(md3);
  13803. });
  13804. return;
  13805. }
  13806. if(this.MD3TagGroups){
  13807. var attach=md3.MD3Tag;
  13808. if(attach && this.MD3TagGroups[attach]){
  13809. this.MD3TagGroups[attach].addGroup(md3);
  13810. }else{
  13811. this.addGroup(md3);
  13812. }
  13813. }else{
  13814. this.MD3Children.push(md3);
  13815. }
  13816. return this;
  13817. }
  13818. /**
  13819. * sets the attach tag for this md3 model
  13820. * @param {String} tag the tag to attach to
  13821. */
  13822. GLGE.MD3.prototype.setMD3Tag=function(tag){
  13823. this.MD3Tag=tag;
  13824. return this;
  13825. }
  13826. /**
  13827. * Sets the MD3 frame number
  13828. * @param {string} frame the frame to display
  13829. */
  13830. GLGE.MD3.prototype.setMD3Frame=function(frame){
  13831. var totalframes=this.MD3EndFrame-this.MD3StartFrame;
  13832. if(totalframes==0) return;
  13833. if(this.MD3Loop){
  13834. frame=frame%totalframes;
  13835. var frame2=((Math.floor(frame)+1)%totalframes);
  13836. }else{
  13837. frame=Math.min(totalframes,frame);
  13838. frame2=Math.min(totalframes,Math.floor(frame)+1);
  13839. if(frame==totalframes){
  13840. this.fireEvent("md3AnimFinished",{});
  13841. }
  13842. }
  13843. var framefrac=frame%1;
  13844. if(frame<1 && this.MD3LastAnimFrame){
  13845. frame=this.MD3LastAnimFrame-this.MD3StartFrame;
  13846. }else{
  13847. this.MD3LastAnimFrame=null;
  13848. this.lastMD3Frame=Math.floor(frame)+this.MD3StartFrame;
  13849. }
  13850. for(var i=0;i<this.surfaces.length;i++){
  13851. this.surfaces[i].setMeshFrame1(Math.floor(frame)+this.MD3StartFrame);
  13852. this.surfaces[i].setMeshFrame2(frame2+this.MD3StartFrame);
  13853. this.surfaces[i].setMeshBlendFactor(framefrac);
  13854. }
  13855. }
  13856. GLGE.MD3.prototype.animate=function(now,nocache){
  13857. if(!now) now=+new Date;
  13858. if(this.headers){
  13859. var frame=(now-this.MD3Started)/1000*this.MD3FrameRate;
  13860. this.setMD3Frame(frame);
  13861. }
  13862. GLGE.Object.prototype.animate.call(this,now,nocache);
  13863. }
  13864. /**
  13865. * Sets the Material to use
  13866. * @param {GLGE.Material} material the material to use
  13867. * @param {number} surface the surface to attach the material to
  13868. */
  13869. GLGE.MD3.prototype.setMaterial=function(material,surface){
  13870. if(!surface) surface=0;
  13871. this.MD3Materials[surface]=material;
  13872. if(this.surfaces[surface]) this.surfaces[surface].setMaterial(material);
  13873. }
  13874. var matfunc=function(idx){
  13875. return function(material){
  13876. this.setMaterial(material,idx);
  13877. }
  13878. }
  13879. for(var i=1;i<32;i++){
  13880. GLGE.MD3.prototype["setMaterial"+i]=matfunc(i);
  13881. }
  13882. GLGE.Group.prototype.addMD3=GLGE.Group.prototype.addGroup;
  13883. GLGE.Scene.prototype.addMD3=GLGE.Scene.prototype.addGroup;
  13884. })(GLGE);
  13885. /*
  13886. GLGE WebGL Graphics Engine
  13887. Copyright (c) 2010, Paul Brunt
  13888. All rights reserved.
  13889. Redistribution and use in source and binary forms, with or without
  13890. modification, are permitted provided that the following conditions are met:
  13891. * Redistributions of source code must retain the above copyright
  13892. notice, this list of conditions and the following disclaimer.
  13893. * Redistributions in binary form must reproduce the above copyright
  13894. notice, this list of conditions and the following disclaimer in the
  13895. documentation and/or other materials provided with the distribution.
  13896. * Neither the name of GLGE nor the
  13897. names of its contributors may be used to endorse or promote products
  13898. derived from this software without specific prior written permission.
  13899. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  13900. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  13901. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  13902. DISCLAIMED. IN NO EVENT SHALL PAUL BRUNT BE LIABLE FOR ANY
  13903. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  13904. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  13905. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  13906. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  13907. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  13908. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  13909. */
  13910. /**
  13911. * @fileOverview
  13912. * @name glge_filter2d.js
  13913. * @author me@paulbrunt.co.uk
  13914. */
  13915. if(!window["GLGE"]){
  13916. window["GLGE"]={};
  13917. }
  13918. (function(GLGE){
  13919. GLGE.FILTER_POST=0;
  13920. GLGE.FILTER_SKY=1;
  13921. GLGE.Filter2d=function(uid){
  13922. GLGE.Assets.registerAsset(this,uid);
  13923. }
  13924. GLGE.augment(GLGE.QuickNotation,GLGE.Filter2d);
  13925. GLGE.Filter2d.prototype.renderDepth=false;
  13926. GLGE.Filter2d.prototype.renderNormal=false;
  13927. GLGE.Filter2d.prototype.renderEmit=false;
  13928. GLGE.Filter2d.prototype.persist=false;
  13929. GLGE.Filter2d.prototype.passes=null;
  13930. GLGE.Filter2d.prototype.textures=null;
  13931. GLGE.Filter2d.prototype.uniforms=null;
  13932. GLGE.Filter2d.prototype.buffers=null;
  13933. GLGE.Filter2d.prototype.filterType=GLGE.FILTER_POST;
  13934. GLGE.Filter2d.prototype.depthBufferWidth=null;
  13935. GLGE.Filter2d.prototype.depthBufferHeight=null;
  13936. GLGE.Filter2d.prototype.emitBufferWidth=null;
  13937. GLGE.Filter2d.prototype.emitBufferHeight=null;
  13938. GLGE.Filter2d.prototype.normalBufferWidth=null;
  13939. GLGE.Filter2d.prototype.normalBufferHeight=null;
  13940. GLGE.Filter2d.prototype.setFilterType=function(filterType){
  13941. this.filterType=filterType;
  13942. return this;
  13943. }
  13944. GLGE.Filter2d.prototype.getFilterType=function(){
  13945. return this.filterType;
  13946. }
  13947. GLGE.Filter2d.prototype.addTexture=function(texture){
  13948. if(!this.textures) this.textures=[];
  13949. this.textures.push(texture);
  13950. }
  13951. GLGE.Filter2d.prototype.removeTexture=function(texture){
  13952. var idx=this.textures.indexOf(texture);
  13953. if(idx>-1) this.textures.splice(idx,1);
  13954. }
  13955. GLGE.Filter2d.prototype.createBuffer=function(gl,width,height){
  13956. if(!width) width=gl.canvas.width;
  13957. if(!height) height=gl.canvas.height;
  13958. var frameBuffer = gl.createFramebuffer();
  13959. var renderBuffer = gl.createRenderbuffer();
  13960. var texture = gl.createTexture();
  13961. gl.bindTexture(gl.TEXTURE_2D, texture);
  13962. var tex = new Uint8Array(width*height*4);
  13963. gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, tex);
  13964. gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer);
  13965. gl.bindRenderbuffer(gl.RENDERBUFFER, renderBuffer);
  13966. gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, width, height);
  13967. gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, renderBuffer);
  13968. gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
  13969. gl.bindRenderbuffer(gl.RENDERBUFFER, null);
  13970. gl.bindFramebuffer(gl.FRAMEBUFFER, null);
  13971. gl.bindTexture(gl.TEXTURE_2D, null);
  13972. return [frameBuffer,renderBuffer,texture];
  13973. }
  13974. GLGE.Filter2d.prototype.getFrameBuffer=function(gl){
  13975. if(!this.passes) return null;
  13976. if(!this.gl) this.gl=gl;
  13977. if(!this.buffers){
  13978. this.buffers=this.createBuffer(gl);
  13979. }
  13980. return this.buffers[0];
  13981. }
  13982. GLGE.Filter2d.prototype.getEmitBuffer=function(gl){
  13983. if(!this.passes) return null;
  13984. if(!this.gl) this.gl=gl;
  13985. if(!this.emitBuffers){
  13986. this.emitBuffers=this.createBuffer(gl,this.getEmitBufferWidth(),this.getEmitBufferHeight());
  13987. }
  13988. return this.emitBuffers[0];
  13989. }
  13990. GLGE.Filter2d.prototype.setEmitBufferWidth=function(value){
  13991. this.emitBufferWidth=value;
  13992. this.emitBuffers=null;
  13993. }
  13994. GLGE.Filter2d.prototype.getEmitBufferWidth=function(){
  13995. return (this.emitBufferWidth ? this.emitBufferWidth : this.gl.canvas.width);
  13996. }
  13997. GLGE.Filter2d.prototype.setEmitBufferHeight=function(value){
  13998. this.emitBufferHeight=value;
  13999. this.emitBuffers=null;
  14000. }
  14001. GLGE.Filter2d.prototype.getEmitBufferHeight=function(){
  14002. return (this.emitBufferHeight ? this.emitBufferHeight : this.gl.canvas.height);
  14003. }
  14004. GLGE.Filter2d.prototype.getDepthBuffer=function(gl){
  14005. if(!this.passes) return null;
  14006. if(!this.gl) this.gl=gl;
  14007. if(!this.depthBuffers){
  14008. this.depthBuffers=this.createBuffer(gl,this.getDepthBufferWidth(),this.getDepthBufferHeight());
  14009. }
  14010. return this.depthBuffers[0];
  14011. }
  14012. GLGE.Filter2d.prototype.setDepthBufferWidth=function(value){
  14013. this.depthBufferWidth=value;
  14014. this.depthBuffers=null;
  14015. }
  14016. GLGE.Filter2d.prototype.getDepthBufferWidth=function(){
  14017. return (this.depthBufferWidth ? this.depthBufferWidth : this.gl.canvas.width);
  14018. }
  14019. GLGE.Filter2d.prototype.setDepthBufferHeight=function(value){
  14020. this.depthBufferHeight=value;
  14021. this.depthBuffers=null;
  14022. }
  14023. GLGE.Filter2d.prototype.getDepthBufferHeight=function(){
  14024. return (this.depthBufferHeight ? this.depthBufferHeight : this.gl.canvas.height);
  14025. }
  14026. GLGE.Filter2d.prototype.setNormalBufferWidth=function(value){
  14027. this.normalBufferWidth=value;
  14028. this.normalBuffers=null;
  14029. }
  14030. GLGE.Filter2d.prototype.getNormalBufferWidth=function(){
  14031. return (this.normalBufferWidth ? this.normalBufferWidth : this.gl.canvas.width);
  14032. }
  14033. GLGE.Filter2d.prototype.setNormalBufferHeight=function(value){
  14034. this.normalBufferHeight=value;
  14035. this.normalBuffers=null;
  14036. }
  14037. GLGE.Filter2d.prototype.getNormalBufferHeight=function(){
  14038. return (this.normalBufferHeight ? this.normalBufferHeight : this.gl.canvas.height);
  14039. }
  14040. GLGE.Filter2d.prototype.getNormalBuffer=function(gl){
  14041. if(!this.gl) this.gl=gl;
  14042. if(!this.normalBuffers){
  14043. this.normalBuffers=this.createBuffer(gl,this.getNormalBufferWidth(),this.getNormalBufferHeight());
  14044. }
  14045. return this.normalBuffers[0];
  14046. }
  14047. GLGE.Filter2d.prototype.setUniform=function(type,name,value){
  14048. if(!this.uniforms) this.uniforms={};
  14049. this.uniforms[name]={type:type,value:value};
  14050. }
  14051. GLGE.Filter2d.prototype.getUniform=function(name){
  14052. if(!this.uniforms) this.uniforms={};
  14053. return this.uniforms[name].value
  14054. }
  14055. GLGE.Filter2d.prototype.getUniformType=function(name){
  14056. if(!this.uniforms) this.uniforms={};
  14057. return this.uniforms[name].type;
  14058. }
  14059. GLGE.Filter2d.prototype.addPassFile=function(url){
  14060. var req = new XMLHttpRequest();
  14061. var filter=this;
  14062. if(req) {
  14063. req.open("GET", url, false);
  14064. req.send("");
  14065. filter.addPass(req.responseText);
  14066. }
  14067. }
  14068. GLGE.Filter2d.prototype.addPass=function(GLSL,width,height){
  14069. if(!this.passes) this.passes=[];
  14070. this.passes.push({GLSL:GLSL,height:height,width:width});
  14071. }
  14072. /**
  14073. * Creates the preserve texture
  14074. * @private
  14075. */
  14076. GLGE.Filter2d.prototype.createPersistTexture=function(gl){
  14077. this.persistTexture = gl.createTexture();
  14078. gl.bindTexture(gl.TEXTURE_2D, this.persistTexture);
  14079. gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.canvas.width,gl.canvas.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
  14080. }
  14081. //does all passes and renders result to screen
  14082. GLGE.Filter2d.prototype.GLRender=function(gl,buffer){
  14083. gl.disable(gl.BLEND);
  14084. if(!buffer) buffer=null;
  14085. if(this.passes){
  14086. for(var i=0;i<this.passes.length;i++){
  14087. //set the frame buffer here
  14088. if(this.passes.length-1==i){
  14089. gl.bindFramebuffer(gl.FRAMEBUFFER, buffer);
  14090. }else{
  14091. if(!this.passes[i].buffer) this.passes[i].buffer=this.createBuffer(gl,this.passes[i].width,this.passes[i].height);
  14092. gl.bindFramebuffer(gl.FRAMEBUFFER, this.passes[i].buffer[0]);
  14093. }
  14094. var width=(this.passes[i].width ? this.passes[i].width : gl.canvas.width);
  14095. var height=(this.passes[i].height ? this.passes[i].height : gl.canvas.height);
  14096. gl.viewport(0,0,width,height);
  14097. gl.clearDepth(1.0);
  14098. gl.depthFunc(gl.LEQUAL);
  14099. gl.clearColor(0, 0, 0, 0);
  14100. gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
  14101. if(!this.passes[i].program){
  14102. this.passes[i].program=this.GLCreateShader(gl,this.passes[i].GLSL);
  14103. }
  14104. gl.useProgram(this.passes[i].program);
  14105. gl.program=this.passes[i].program;
  14106. for(var j=0; j<8; j++) gl.disableVertexAttribArray(j);
  14107. attribslot=GLGE.getAttribLocation(gl,this.passes[i].program, "position");
  14108. if(!this.posBuffer) this.createPlane(gl);
  14109. gl.bindBuffer(gl.ARRAY_BUFFER, this.posBuffer);
  14110. gl.enableVertexAttribArray(attribslot);
  14111. gl.vertexAttribPointer(attribslot, this.posBuffer.itemSize, gl.FLOAT, false, 0, 0);
  14112. this.GLSetUniforms(gl,i);
  14113. gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.GLfaces);
  14114. gl.drawElements(gl.TRIANGLES, this.GLfaces.numItems, gl.UNSIGNED_SHORT, 0);
  14115. }
  14116. if(this.persist){
  14117. if(!this.persistTexture) this.createPersistTexture(gl);
  14118. gl.bindTexture(gl.TEXTURE_2D, this.persistTexture);
  14119. gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 0, 0, gl.canvas.width, gl.canvas.height, 0);
  14120. }
  14121. }
  14122. }
  14123. GLGE.Filter2d.prototype.clearPersist=function(gl){
  14124. if(!this.persistTexture) this.createPersistTexture(gl);
  14125. gl.bindTexture(gl.TEXTURE_2D, this.persistTexture);
  14126. gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.canvas.width,gl.canvas.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
  14127. gl.bindTexture(gl.TEXTURE_2D, null);
  14128. }
  14129. var glmat=new Float32Array(16);
  14130. GLGE.Filter2d.prototype.GLSetUniforms=function(gl,pass){
  14131. if(this.filterType==GLGE.FILTER_SKY){
  14132. var invViewProj=GLGE.transposeMat4(GLGE.mulMat4(GLGE.inverseMat4(gl.scene.camera.matrix),GLGE.inverseMat4(gl.scene.camera.pMatrix)));
  14133. GLGE.mat4gl(invViewProj,glmat)
  14134. GLGE.setUniformMatrix(gl,"Matrix4fv",GLGE.getUniformLocation(gl,this.passes[pass].program, "invViewProj"),false,glmat);
  14135. }
  14136. for(var key in this.uniforms){
  14137. var uniform=this.uniforms[key];
  14138. if(uniform.type=="Matrix4fv"){
  14139. GLGE.setUniformMatrix(gl,"Matrix4fv",GLGE.getUniformLocation(gl,this.passes[pass].program, key),false,uniform.value);
  14140. }else{
  14141. GLGE.setUniform(gl,uniform.type,GLGE.getUniformLocation(gl,this.passes[pass].program, key),uniform.value);
  14142. }
  14143. }
  14144. var tidx=0;
  14145. if(this.buffers){
  14146. if(pass==0){
  14147. gl.activeTexture(gl["TEXTURE"+tidx]);
  14148. gl.bindTexture(gl.TEXTURE_2D, this.buffers[2]);
  14149. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
  14150. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
  14151. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
  14152. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
  14153. }
  14154. GLGE.setUniform(gl,"1i",GLGE.getUniformLocation(gl,this.passes[pass].program, "GLGE_RENDER"), tidx);
  14155. tidx++;
  14156. if(this.persist){
  14157. if(pass==0){
  14158. gl.activeTexture(gl["TEXTURE"+tidx]);
  14159. gl.bindTexture(gl.TEXTURE_2D, this.persistTexture);
  14160. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
  14161. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
  14162. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
  14163. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
  14164. }
  14165. GLGE.setUniform(gl,"1i",GLGE.getUniformLocation(gl,this.passes[pass].program, "GLGE_PERSIST"), tidx);
  14166. tidx++;
  14167. }
  14168. if(this.renderDepth){
  14169. if(pass==0){
  14170. gl.activeTexture(gl["TEXTURE"+tidx]);
  14171. gl.bindTexture(gl.TEXTURE_2D, this.depthBuffers[2]);
  14172. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
  14173. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
  14174. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
  14175. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
  14176. }
  14177. GLGE.setUniform(gl,"1i",GLGE.getUniformLocation(gl,this.passes[pass].program, "GLGE_DEPTH"), tidx);
  14178. tidx++;
  14179. }
  14180. if(this.renderEmit){
  14181. if(pass==0){
  14182. gl.activeTexture(gl["TEXTURE"+tidx]);
  14183. gl.bindTexture(gl.TEXTURE_2D, this.emitBuffers[2]);
  14184. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
  14185. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
  14186. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
  14187. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
  14188. }
  14189. GLGE.setUniform(gl,"1i",GLGE.getUniformLocation(gl,this.passes[pass].program, "GLGE_EMIT"), tidx);
  14190. tidx++;
  14191. }
  14192. if(this.renderNormal){
  14193. if(pass==0){
  14194. gl.activeTexture(gl["TEXTURE"+tidx]);
  14195. gl.bindTexture(gl.TEXTURE_2D, this.normalBuffers[2]);
  14196. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
  14197. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
  14198. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
  14199. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
  14200. }
  14201. GLGE.setUniform(gl,"1i",GLGE.getUniformLocation(gl,this.passes[pass].program, "GLGE_NORMAL"), tidx);
  14202. tidx++;
  14203. }
  14204. for(var i=0;i<this.passes.length;i++){
  14205. if(this.passes[i].buffer){
  14206. gl.activeTexture(gl["TEXTURE"+tidx]);
  14207. gl.bindTexture(gl.TEXTURE_2D, this.passes[i].buffer[2]);
  14208. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
  14209. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
  14210. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
  14211. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
  14212. }
  14213. GLGE.setUniform(gl,"1i",GLGE.getUniformLocation(gl,this.passes[pass].program, "GLGE_PASS"+i), tidx);
  14214. tidx++;
  14215. }
  14216. }
  14217. if(!this.textures) this.textures=[];
  14218. for(var i=0; i<this.textures.length;i++){
  14219. gl.activeTexture(gl["TEXTURE"+(i+tidx)]);
  14220. this.textures[i].doTexture(gl,null);
  14221. var name = "TEXTURE"+i
  14222. if(this.textures[i].name) name=this.textures[i].name;
  14223. GLGE.setUniform(gl,"1i",GLGE.getUniformLocation(gl,this.passes[pass].program, name), i+tidx);
  14224. }
  14225. }
  14226. /**
  14227. * creates the screen aligned plane mesh
  14228. * @private
  14229. */
  14230. GLGE.Filter2d.prototype.createPlane=function(gl){
  14231. //create the vertex positions
  14232. if(!this.posBuffer) this.posBuffer = gl.createBuffer();
  14233. gl.bindBuffer(gl.ARRAY_BUFFER, this.posBuffer);
  14234. gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([1,1,0.5,-1,1,0.5,-1,-1,0.5,1,-1,0.5]), gl.STATIC_DRAW);
  14235. this.posBuffer.itemSize = 3;
  14236. this.posBuffer.numItems = 4;
  14237. //create the faces
  14238. if(!this.GLfaces) this.GLfaces = gl.createBuffer();
  14239. gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.GLfaces);
  14240. gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array([0,1,2,2,3,0]), gl.STATIC_DRAW);
  14241. this.GLfaces.itemSize = 1;
  14242. this.GLfaces.numItems = 6;
  14243. }
  14244. /**
  14245. * Creates a shader program
  14246. * @private
  14247. */
  14248. GLGE.Filter2d.prototype.GLCreateShader=function(gl,fragStr){
  14249. //Vertex Shader
  14250. var vertexStr=[];
  14251. vertexStr.push("uniform mat4 invViewProj;\n");
  14252. vertexStr.push("attribute vec3 position;\n");
  14253. vertexStr.push("varying vec2 texCoord;\n");
  14254. vertexStr.push("varying vec3 rayCoord;\n");
  14255. vertexStr.push("void main(void){\n");
  14256. vertexStr.push("vec4 near=invViewProj * vec4(position.xy,-1.0,1.0);\n");
  14257. vertexStr.push("near/=near.w;\n");
  14258. vertexStr.push("vec4 far=invViewProj * vec4(position.xy,1.0,1.0);\n");
  14259. vertexStr.push("far/=far.w;\n");
  14260. vertexStr.push("rayCoord=normalize(far.xyz-near.xyz);\n");
  14261. vertexStr.push("texCoord=(position.xy+vec2(1.0,1.0))/2.0;\n");
  14262. vertexStr.push("gl_Position = vec4(position.xyz,1.0);\n");
  14263. vertexStr.push("}\n");
  14264. var GLVertexShader=GLGE.getGLShader(gl,gl.VERTEX_SHADER,vertexStr.join(""));
  14265. var GLFragmentShader=GLGE.getGLShader(gl,gl.FRAGMENT_SHADER,fragStr);
  14266. return GLGE.getGLProgram(gl,GLVertexShader,GLFragmentShader);
  14267. }
  14268. })(GLGE);
  14269. /*
  14270. GLGE WebGL Graphics Engine
  14271. Copyright (c) 2010, Paul Brunt
  14272. All rights reserved.
  14273. Redistribution and use in source and binary forms, with or without
  14274. modification, are permitted provided that the following conditions are met:
  14275. * Redistributions of source code must retain the above copyright
  14276. notice, this list of conditions and the following disclaimer.
  14277. * Redistributions in binary form must reproduce the above copyright
  14278. notice, this list of conditions and the following disclaimer in the
  14279. documentation and/or other materials provided with the distribution.
  14280. * Neither the name of GLGE nor the
  14281. names of its contributors may be used to endorse or promote products
  14282. derived from this software without specific prior written permission.
  14283. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  14284. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  14285. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  14286. DISCLAIMED. IN NO EVENT SHALL PAUL BRUNT BE LIABLE FOR ANY
  14287. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  14288. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  14289. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  14290. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  14291. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  14292. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14293. */
  14294. /**
  14295. * @fileOverview
  14296. * @name glge_filter_glow.js
  14297. * @author me@paulbrunt.co.uk
  14298. */
  14299. (function(GLGE){
  14300. /**
  14301. * @class Postprocessing glow filter
  14302. * @augments GLGE.Filter2d
  14303. */
  14304. GLGE.FilterGlow=function(uid){
  14305. this.setEmitBufferWidth(256);
  14306. this.setEmitBufferHeight(256);
  14307. GLGE.Assets.registerAsset(this,uid);
  14308. };
  14309. GLGE.augment(GLGE.Filter2d,GLGE.FilterGlow);
  14310. GLGE.FilterGlow.prototype.renderEmit=true;
  14311. GLGE.FilterGlow.prototype.blur=1.2;
  14312. GLGE.FilterGlow.prototype.intensity=3;
  14313. GLGE.FilterGlow.prototype.fxaacutoff=2;
  14314. GLGE.FilterGlow.prototype.fxaastartintensity=0;
  14315. GLGE.FilterGlow.prototype.setEmitBufferWidth=function(value){
  14316. GLGE.Filter2d.prototype.setEmitBufferWidth.call(this,value);
  14317. this.createPasses();
  14318. return this;
  14319. }
  14320. GLGE.FilterGlow.prototype.setEmitBufferHeight=function(value){
  14321. GLGE.Filter2d.prototype.setEmitBufferHeight.call(this,value);
  14322. this.createPasses();
  14323. return this;
  14324. }
  14325. GLGE.FilterGlow.prototype.setBlur=function(blur){
  14326. this.blur=blur;
  14327. this.createPasses();
  14328. return this;
  14329. }
  14330. GLGE.FilterGlow.prototype.setIntensity=function(intensity){
  14331. this.intensity=intensity;
  14332. this.createPasses();
  14333. return this;
  14334. }
  14335. GLGE.FilterGlow.prototype.setFXAA=function(value){
  14336. this.useFXAA=value;
  14337. this.createPasses();
  14338. return this;
  14339. }
  14340. GLGE.FilterGlow.prototype.setFXAACutoff=function(value){
  14341. this.fxaacutoff=value;
  14342. this.createPasses();
  14343. return this;
  14344. }
  14345. GLGE.FilterGlow.prototype.setFXAAStartIntensity=function(value){
  14346. this.fxaastartintensity=value;
  14347. this.createPasses();
  14348. return this;
  14349. }
  14350. GLGE.FilterGlow.prototype.createPasses=function(){
  14351. var pass1=[];
  14352. pass1.push("precision highp float;");
  14353. pass1.push("uniform sampler2D GLGE_EMIT;");
  14354. pass1.push("varying vec2 texCoord;");
  14355. pass1.push("float blurSize="+(1/this.emitBufferWidth*this.blur).toFixed(10)+";");
  14356. pass1.push("float rand(vec2 co){;");
  14357. pass1.push("return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);");
  14358. pass1.push("}");
  14359. pass1.push("void main(void){");
  14360. pass1.push("vec4 color=vec4(0.0,0.0,0.0,0.0);");
  14361. pass1.push("float rnd=1.0-rand(texCoord.xy)*4.0*blurSize;");
  14362. pass1.push("color += texture2D(GLGE_EMIT, vec2(texCoord.x - 4.0*blurSize, texCoord.y)) * 0.05 * rnd;");
  14363. pass1.push("color += texture2D(GLGE_EMIT, vec2(texCoord.x - 3.0*blurSize, texCoord.y)) * 0.09 * rnd;");
  14364. pass1.push("color += texture2D(GLGE_EMIT, vec2(texCoord.x - 2.0*blurSize, texCoord.y)) * 0.12 * rnd;");
  14365. pass1.push("color += texture2D(GLGE_EMIT, vec2(texCoord.x - blurSize, texCoord.y)) * 0.15 * rnd;");
  14366. pass1.push("color += texture2D(GLGE_EMIT, vec2(texCoord.x, texCoord.y)) * 0.18 * rnd;");
  14367. pass1.push("color += texture2D(GLGE_EMIT, vec2(texCoord.x + blurSize, texCoord.y)) * 0.15 * rnd;");
  14368. pass1.push("color += texture2D(GLGE_EMIT, vec2(texCoord.x + 2.0*blurSize, texCoord.y)) * 0.12 * rnd;");
  14369. pass1.push("color += texture2D(GLGE_EMIT, vec2(texCoord.x + 3.0*blurSize, texCoord.y)) * 0.09 * rnd;");
  14370. pass1.push("color += texture2D(GLGE_EMIT, vec2(texCoord.x + 4.0*blurSize, texCoord.y)) * 0.05 * rnd;");
  14371. pass1.push("gl_FragColor = vec4(color.rgb,1.0);");
  14372. pass1.push("}");
  14373. var pass2=[];
  14374. pass2.push("precision highp float;");
  14375. pass2.push("uniform sampler2D GLGE_PASS0;");
  14376. pass2.push("uniform sampler2D GLGE_RENDER;");
  14377. pass2.push("uniform sampler2D GLGE_EMIT;");
  14378. pass2.push("varying vec2 texCoord;");
  14379. pass2.push("float blurSize="+(1/this.emitBufferHeight*this.blur).toFixed(10)+";");
  14380. pass2.push("float rand(vec2 co){;");
  14381. pass2.push("return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);");
  14382. pass2.push("}");
  14383. pass2.push("void main(void){");
  14384. pass2.push("vec4 color=vec4(0.0,0.0,0.0,0.0);");
  14385. pass2.push("float rnd=1.0-rand(texCoord.xy)*4.0*blurSize;");
  14386. pass2.push("color += texture2D(GLGE_PASS0, vec2(texCoord.x, texCoord.y - 4.0*blurSize)) * 0.05 * rnd;");
  14387. pass2.push("color += texture2D(GLGE_PASS0, vec2(texCoord.x, texCoord.y - 3.0*blurSize)) * 0.09 * rnd;");
  14388. pass2.push("color += texture2D(GLGE_PASS0, vec2(texCoord.x, texCoord.y - 2.0*blurSize)) * 0.12 * rnd;");
  14389. pass2.push("color += texture2D(GLGE_PASS0, vec2(texCoord.x, texCoord.y - blurSize)) * 0.15 * rnd;");
  14390. pass2.push("color += texture2D(GLGE_PASS0, vec2(texCoord.x, texCoord.y)) * 0.18 * rnd;");
  14391. pass2.push("color += texture2D(GLGE_PASS0, vec2(texCoord.x, texCoord.y + blurSize)) * 0.15 * rnd;");
  14392. pass2.push("color += texture2D(GLGE_PASS0, vec2(texCoord.x, texCoord.y + 2.0*blurSize)) * 0.12 * rnd;");
  14393. pass2.push("color += texture2D(GLGE_PASS0, vec2(texCoord.x, texCoord.y + 3.0*blurSize)) * 0.09 * rnd;");
  14394. pass2.push("color += texture2D(GLGE_PASS0, vec2(texCoord.x, texCoord.y + 4.0*blurSize)) * 0.05 * rnd;");
  14395. pass2.push("gl_FragColor = vec4(color.rgb*"+(this.intensity.toFixed(5))+"+texture2D(GLGE_RENDER,texCoord).rgb,1.0);");
  14396. pass2.push("}");
  14397. this.passes=[];
  14398. this.addPass(pass1.join(""));
  14399. this.addPass(pass2.join(""));
  14400. if(this.useFXAA){
  14401. var pass3=[]
  14402. pass3.push("precision highp float;");
  14403. pass3.push("uniform sampler2D GLGE_PASS1;");
  14404. pass3.push("varying vec2 texCoord;");
  14405. pass3.push("vec2 inverse_buffer_size=vec2(1.0/1280.0,1.0/720.0);");
  14406. pass3.push("#define FXAA_REDUCE_MIN (1.0/128.0)");
  14407. pass3.push("#define FXAA_REDUCE_MUL (1.0/16.0)");
  14408. pass3.push("#define FXAA_SPAN_MAX 8.0");
  14409. pass3.push("void main(){");
  14410. pass3.push(" vec3 rgbNW = texture2D(GLGE_PASS1, (gl_FragCoord.xy + vec2(-1.0,-1.0)) * inverse_buffer_size).xyz;");
  14411. pass3.push(" vec3 rgbNE = texture2D(GLGE_PASS1, (gl_FragCoord.xy + vec2(1.0,-1.0)) * inverse_buffer_size).xyz;");
  14412. pass3.push(" vec3 rgbSW = texture2D(GLGE_PASS1, (gl_FragCoord.xy + vec2(-1.0,1.0)) * inverse_buffer_size).xyz;");
  14413. pass3.push(" vec3 rgbSE = texture2D(GLGE_PASS1, (gl_FragCoord.xy + vec2(1.0,1.0)) * inverse_buffer_size).xyz;");
  14414. pass3.push(" vec3 rgbM = texture2D(GLGE_PASS1, gl_FragCoord.xy * inverse_buffer_size).xyz;");
  14415. pass3.push(" vec3 luma = vec3(0.299, 0.587, 0.114);");
  14416. pass3.push(" float lumaNW = dot(rgbNW, luma);");
  14417. pass3.push(" float lumaNE = dot(rgbNE, luma);");
  14418. pass3.push(" float lumaSW = dot(rgbSW, luma);");
  14419. pass3.push(" float lumaSE = dot(rgbSE, luma);");
  14420. pass3.push(" float lumaM = dot(rgbM, luma);");
  14421. pass3.push(" float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));");
  14422. pass3.push(" float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));");
  14423. pass3.push(" vec2 dir;");
  14424. pass3.push(" dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));");
  14425. pass3.push(" dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));");
  14426. pass3.push(" float dirReduce = max(");
  14427. pass3.push(" (lumaNW + lumaNE + lumaSW + lumaSE) * (0.25 * FXAA_REDUCE_MUL),");
  14428. pass3.push(" FXAA_REDUCE_MIN);");
  14429. pass3.push(" float rcpDirMin = 1.0/(min(abs(dir.x), abs(dir.y)) + dirReduce);");
  14430. pass3.push(" dir = min(vec2( FXAA_SPAN_MAX, FXAA_SPAN_MAX),");
  14431. pass3.push(" max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),");
  14432. pass3.push(" dir * rcpDirMin)) * inverse_buffer_size;");
  14433. pass3.push(" vec3 rgbA = 0.5 * (");
  14434. pass3.push(" texture2D(GLGE_PASS1, gl_FragCoord.xy * inverse_buffer_size + dir * (1.0/3.0 - 0.5)).xyz +");
  14435. pass3.push(" texture2D(GLGE_PASS1, gl_FragCoord.xy * inverse_buffer_size + dir * (2.0/3.0 - 0.5)).xyz);");
  14436. pass3.push(" vec3 rgbB = rgbA * 0.5 + 0.25 * (");
  14437. pass3.push(" texture2D(GLGE_PASS1, gl_FragCoord.xy * inverse_buffer_size + dir * - 0.5).xyz +");
  14438. pass3.push(" texture2D(GLGE_PASS1, gl_FragCoord.xy * inverse_buffer_size + dir * 0.5).xyz);");
  14439. pass3.push(" float lumaB = dot(rgbB, luma);");
  14440. pass3.push(" if((lumaB < lumaMin) || (lumaB > lumaMax)) gl_FragColor = vec4(rgbA,1.0);");
  14441. pass3.push(" else gl_FragColor = vec4(rgbB,1.0);");
  14442. pass3.push(" if(length(rgbM)>"+this.fxaacutoff.toFixed(2)+") gl_FragColor = vec4(rgbM,1.0);");
  14443. pass3.push(" if(length(rgbM)<"+this.fxaastartintensity.toFixed(2)+") gl_FragColor = vec4(rgbM,1.0);");
  14444. pass3.push("}");
  14445. this.addPass(pass3.join("\n"));
  14446. }
  14447. }
  14448. })(GLGE);/*
  14449. GLGE WebGL Graphics Engine
  14450. Copyright (c) 2010, Paul Brunt
  14451. All rights reserved.
  14452. Redistribution and use in source and binary forms, with or without
  14453. modification, are permitted provided that the following conditions are met:
  14454. * Redistributions of source code must retain the above copyright
  14455. notice, this list of conditions and the following disclaimer.
  14456. * Redistributions in binary form must reproduce the above copyright
  14457. notice, this list of conditions and the following disclaimer in the
  14458. documentation and/or other materials provided with the distribution.
  14459. * Neither the name of GLGE nor the
  14460. names of its contributors may be used to endorse or promote products
  14461. derived from this software without specific prior written permission.
  14462. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  14463. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  14464. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  14465. DISCLAIMED. IN NO EVENT SHALL PAUL BRUNT BE LIABLE FOR ANY
  14466. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  14467. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  14468. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  14469. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  14470. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  14471. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14472. */
  14473. /**
  14474. * @fileOverview
  14475. * @name glge_filter_ao.js
  14476. * @author me@paulbrunt.co.uk
  14477. */
  14478. (function(GLGE){
  14479. /**
  14480. * @class Postprocessing Ambient Occlusion filter
  14481. * @augments GLGE.Filter2d
  14482. */
  14483. GLGE.FilterAO=function(){
  14484. this.setUniform("1f","cavitygamma",1/3);
  14485. this.setUniform("1f","whiteMul",2);
  14486. this.setUniform("1f","aogamma",1/3);
  14487. this.setUniform("1f","maxDist",0.025);
  14488. this.passes=[];
  14489. };
  14490. GLGE.augment(GLGE.Filter2d,GLGE.FilterAO);
  14491. GLGE.FilterAO.prototype.renderNormal=true;
  14492. GLGE.FilterAO.prototype.quality=1;
  14493. GLGE.FilterAO.prototype.range=80;
  14494. GLGE.FilterAO.prototype.samples=16;
  14495. GLGE.FilterAO.prototype.useRender=true;
  14496. GLGE.FilterAO.prototype.getNormalBufferHeight=function(){
  14497. return (this.normalBufferHeight ? this.normalBufferHeight : (this.gl.canvas.height*this.quality|0));
  14498. }
  14499. GLGE.FilterAO.prototype.getNormalBufferWidth=function(){
  14500. return (this.normalBufferWidth ? this.normalBufferWidth : (this.gl.canvas.width*this.quality|0));
  14501. }
  14502. GLGE.FilterAO.prototype.setUseRender=function(value){
  14503. this.useRender=value;
  14504. this.normalBuffers=null;
  14505. this.passes=[];
  14506. return this;
  14507. }
  14508. GLGE.FilterAO.prototype.setSamples=function(value){
  14509. this.samples=value;
  14510. this.normalBuffers=null;
  14511. this.passes=[];
  14512. return this;
  14513. }
  14514. GLGE.FilterAO.prototype.setQuality=function(value){
  14515. this.quality=value;
  14516. this.normalBuffers=null;
  14517. this.passes=[];
  14518. return this;
  14519. }
  14520. GLGE.FilterAO.prototype.setRange=function(value){
  14521. this.range=value;
  14522. if(this.gl){
  14523. this.setUniform("1f","blurX",this.range/this.getNormalBufferWidth()*this.quality/this.samples);
  14524. this.setUniform("1f","blurY",this.range/this.getNormalBufferHeight()/this.samples);
  14525. }
  14526. return this;
  14527. }
  14528. GLGE.FilterAO.prototype.setCavityGamma=function(value){
  14529. this.setUniform("1f","cavitygamma",1/value);
  14530. return this;
  14531. }
  14532. GLGE.FilterAO.prototype.setAmbientMultiplier=function(value){
  14533. this.setUniform("1f","whiteMul",value);
  14534. return this;
  14535. }
  14536. GLGE.FilterAO.prototype.setAmbientGamma=function(value){
  14537. this.setUniform("1f","aogamma",1/value);
  14538. return this;
  14539. }
  14540. GLGE.FilterAO.prototype.setMaximumDistance=function(value){
  14541. this.setUniform("1f","maxDist",value);
  14542. return this;
  14543. }
  14544. GLGE.FilterAO.prototype.GLRender=function(gl,buffer){
  14545. this.gl=gl;
  14546. if(this.passes.length==0){
  14547. this.createPasses();
  14548. }
  14549. return GLGE.Filter2d.prototype.GLRender.call(this,gl,buffer)
  14550. }
  14551. GLGE.FilterAO.prototype.createPasses=function(){
  14552. if(!this.gl) return;
  14553. var width=this.getNormalBufferWidth();
  14554. var height=this.getNormalBufferHeight();
  14555. var size=(this.samples/4)|0;
  14556. var weights=[];
  14557. for(var i=-size,cnt=0; i<=size;i++,cnt++){
  14558. var n=size-Math.abs(i)+1;
  14559. weights[cnt]=n/(size*size+size);
  14560. }
  14561. weights[size]=0;
  14562. this.setUniform("1f","blurX",this.range/width*this.quality/this.samples);
  14563. this.setUniform("1f","blurY",this.range/height/this.samples);
  14564. var pass1=[];
  14565. pass1.push("precision highp float;");
  14566. pass1.push("uniform sampler2D GLGE_NORMAL;");
  14567. pass1.push("uniform float maxDist;");
  14568. pass1.push("varying vec2 texCoord;");
  14569. pass1.push("uniform float blurX;");
  14570. pass1.push("float rand(vec2 co){");
  14571. pass1.push("return (fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453)-0.5)*2.0;");
  14572. pass1.push("}");
  14573. pass1.push("void main(void){");
  14574. pass1.push("vec4 n=texture2D(GLGE_NORMAL,texCoord.xy).rgba;");
  14575. pass1.push("vec4 color=vec4(0.0,0.0,0.0,n.a);");
  14576. pass1.push("float blurSize=blurX/(n.a*n.a+1.0);");
  14577. pass1.push("float offset=rand(texCoord.xy)*blurSize+texCoord.x;");
  14578. pass1.push("vec3 samp;");
  14579. pass1.push("float delta;");
  14580. for(var i=-size,cnt=0;i<=size;i++,cnt++){
  14581. if(i==0) continue;
  14582. pass1.push("samp = texture2D(GLGE_NORMAL, vec2("+i+".0*blurSize+offset, texCoord.y)).rga;");
  14583. pass1.push("delta=abs(n.a-samp.b);");
  14584. pass1.push("if(delta<maxDist){");
  14585. pass1.push("delta/=maxDist;");
  14586. pass1.push("color.b -= (samp.r-0.5) * "+weights[cnt]+" * "+((2*i)/Math.abs(i) | 0)+".0;");
  14587. pass1.push("color.rg += samp.rg * "+weights[cnt]+" * (1.0-delta);");
  14588. pass1.push("color.rg += n.rg * "+weights[cnt]+" * delta;");
  14589. pass1.push("}else{");
  14590. pass1.push("color.rg +=n.rg * "+weights[cnt]+";");
  14591. pass1.push("}");
  14592. }
  14593. pass1.push("color.b = (color.b+1.0)*0.5;");
  14594. pass1.push("gl_FragColor = color;");
  14595. pass1.push("}");
  14596. var pass2=[];
  14597. pass2.push("precision highp float;");
  14598. pass2.push("uniform sampler2D GLGE_PASS0;");
  14599. pass2.push("uniform sampler2D GLGE_RENDER;");
  14600. pass2.push("uniform sampler2D GLGE_NORMAL;");
  14601. pass2.push("varying vec2 texCoord;");
  14602. pass2.push("uniform float blurY;");
  14603. pass2.push("uniform float cavitygamma;");
  14604. pass2.push("uniform float whiteMul;");
  14605. pass2.push("uniform float aogamma;");
  14606. pass2.push("uniform float maxDist;");
  14607. pass2.push("float rand(vec2 co){");
  14608. pass2.push("return (fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453)-0.5)*2.0;");
  14609. pass2.push("}");
  14610. pass2.push("void main(void){");
  14611. pass2.push("vec4 color=vec4(0.0,0.0,0.0,1.0);");
  14612. pass2.push("vec4 samp=vec4(0.0);");
  14613. pass2.push("float random=rand(texCoord.xy);");
  14614. if(this.quality<1){
  14615. pass2.push("vec2 displace=vec2("+(0.5/width)+","+(0.5/height)+")*random;");
  14616. pass2.push("vec4 n=texture2D(GLGE_PASS0, texCoord.xy+displace);");
  14617. }else{
  14618. pass2.push("vec4 n=texture2D(GLGE_PASS0, texCoord.xy);");
  14619. }
  14620. pass2.push("float delta;");
  14621. pass2.push("float blurSize=blurY/(n.a*n.a+1.0);");
  14622. pass2.push("float offset=random*blurSize+texCoord.y;");
  14623. for(var i=-size,cnt=0;i<=size;i++,cnt++){
  14624. if(i==0) continue;
  14625. if(this.quality<1){
  14626. pass2.push("samp = texture2D(GLGE_PASS0, vec2(texCoord.x, "+i+".0*blurSize + offset)+displace);");
  14627. }else{
  14628. pass2.push("samp = texture2D(GLGE_PASS0, vec2(texCoord.x, "+i+".0*blurSize + offset));");
  14629. }
  14630. pass2.push("delta=abs(n.a-samp.a);");
  14631. pass2.push("if(delta<maxDist){");
  14632. pass2.push("delta/=maxDist;");
  14633. pass2.push("color.a -= (samp.g-0.5) * "+weights[cnt]+" * "+((i*2)/Math.abs(i) | 0)+".0;");
  14634. pass2.push("color.rg += samp.rg * "+weights[cnt]+" * (1.0-delta);");
  14635. pass2.push("color.rg += n.rg * "+weights[cnt]+" * delta;");
  14636. pass2.push("}else{");
  14637. pass2.push("color.rg += n.rg * "+weights[cnt]+";");
  14638. pass2.push("}");
  14639. }
  14640. pass2.push("color.a = (color.a+1.0)*n.b;");
  14641. pass2.push("color.a = pow(color.a,cavitygamma);");
  14642. if(this.quality<1){
  14643. pass2.push("float dif = length(color.rg-texture2D(GLGE_NORMAL, texCoord.xy+displace).rg);");
  14644. pass2.push("samp = texture2D(GLGE_NORMAL, texCoord.xy+displace+"+(1/this.gl.canvas.height)+").rgba;");
  14645. pass2.push("if(abs(n.a-samp.a)<maxDist) dif = max(length(color.rg-samp.rg),dif);");
  14646. pass2.push("samp = texture2D(GLGE_NORMAL, texCoord.xy+displace-"+(1/this.gl.canvas.height)+").rgba;");
  14647. pass2.push("if(abs(n.a-samp.a)<maxDist) dif = max(length(color.rg-samp.rg),dif);");
  14648. }else{
  14649. pass2.push("float dif = length(color.rg-texture2D(GLGE_NORMAL, texCoord.xy).rg);");
  14650. }
  14651. pass2.push("float result = 1.0-((dif*(color.a-0.5)*2.0)+1.0)*0.5;");
  14652. pass2.push("result = pow(min(result*whiteMul,1.0),aogamma);");
  14653. pass2.push("gl_FragColor = vec4(vec3(result),1.0);");
  14654. if(this.useRender) pass2.push("gl_FragColor = vec4(texture2D(GLGE_RENDER, texCoord.xy).rgb*gl_FragColor.r,1.0);");
  14655. pass2.push("}");
  14656. var pass3=[]
  14657. pass3.push("precision highp float;");
  14658. pass3.push("uniform sampler2D GLGE_PASS1;");
  14659. pass3.push("varying vec2 texCoord;");
  14660. pass3.push("vec2 inverse_buffer_size=vec2(1.0/"+this.gl.canvas.width.toFixed(1)+",1.0/"+this.gl.canvas.height.toFixed(1)+");");
  14661. pass3.push("#define FXAA_REDUCE_MIN (1.0/128.0)");
  14662. pass3.push("#define FXAA_REDUCE_MUL (1.0/16.0)");
  14663. pass3.push("#define FXAA_SPAN_MAX 8.0");
  14664. pass3.push("void main(){");
  14665. pass3.push(" vec3 rgbNW = texture2D(GLGE_PASS1, (gl_FragCoord.xy + vec2(-1.0,-1.0)) * inverse_buffer_size).xyz;");
  14666. pass3.push(" vec3 rgbNE = texture2D(GLGE_PASS1, (gl_FragCoord.xy + vec2(1.0,-1.0)) * inverse_buffer_size).xyz;");
  14667. pass3.push(" vec3 rgbSW = texture2D(GLGE_PASS1, (gl_FragCoord.xy + vec2(-1.0,1.0)) * inverse_buffer_size).xyz;");
  14668. pass3.push(" vec3 rgbSE = texture2D(GLGE_PASS1, (gl_FragCoord.xy + vec2(1.0,1.0)) * inverse_buffer_size).xyz;");
  14669. pass3.push(" vec3 rgbM = texture2D(GLGE_PASS1, gl_FragCoord.xy * inverse_buffer_size).xyz;");
  14670. pass3.push(" vec3 luma = vec3(0.299, 0.587, 0.114);");
  14671. pass3.push(" float lumaNW = dot(rgbNW, luma);");
  14672. pass3.push(" float lumaNE = dot(rgbNE, luma);");
  14673. pass3.push(" float lumaSW = dot(rgbSW, luma);");
  14674. pass3.push(" float lumaSE = dot(rgbSE, luma);");
  14675. pass3.push(" float lumaM = dot(rgbM, luma);");
  14676. pass3.push(" float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));");
  14677. pass3.push(" float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));");
  14678. pass3.push(" vec2 dir;");
  14679. pass3.push(" dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));");
  14680. pass3.push(" dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));");
  14681. pass3.push(" float dirReduce = max(");
  14682. pass3.push(" (lumaNW + lumaNE + lumaSW + lumaSE) * (0.25 * FXAA_REDUCE_MUL),");
  14683. pass3.push(" FXAA_REDUCE_MIN);");
  14684. pass3.push(" float rcpDirMin = 1.0/(min(abs(dir.x), abs(dir.y)) + dirReduce);");
  14685. pass3.push(" dir = min(vec2( FXAA_SPAN_MAX, FXAA_SPAN_MAX),");
  14686. pass3.push(" max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),");
  14687. pass3.push(" dir * rcpDirMin)) * inverse_buffer_size;");
  14688. pass3.push(" vec3 rgbA = 0.5 * (");
  14689. pass3.push(" texture2D(GLGE_PASS1, gl_FragCoord.xy * inverse_buffer_size + dir * (1.0/3.0 - 0.5)).xyz +");
  14690. pass3.push(" texture2D(GLGE_PASS1, gl_FragCoord.xy * inverse_buffer_size + dir * (2.0/3.0 - 0.5)).xyz);");
  14691. pass3.push(" vec3 rgbB = rgbA * 0.5 + 0.25 * (");
  14692. pass3.push(" texture2D(GLGE_PASS1, gl_FragCoord.xy * inverse_buffer_size + dir * - 0.5).xyz +");
  14693. pass3.push(" texture2D(GLGE_PASS1, gl_FragCoord.xy * inverse_buffer_size + dir * 0.5).xyz);");
  14694. pass3.push(" float lumaB = dot(rgbB, luma);");
  14695. pass3.push(" if((lumaB < lumaMin) || (lumaB > lumaMax)) gl_FragColor = vec4(rgbA,1.0);");
  14696. pass3.push(" else gl_FragColor = vec4(rgbB,1.0);");
  14697. pass3.push(" if(length(rgbM)>10.0) gl_FragColor = vec4(rgbM,1.0);");
  14698. pass3.push("}");
  14699. this.passes=[];
  14700. this.addPass(pass1.join(""),width,height);
  14701. this.addPass(pass2.join(""));
  14702. this.addPass(pass3.join("\n"));
  14703. }
  14704. })(GLGE);/*
  14705. GLGE WebGL Graphics Engine
  14706. Copyright (c) 2010, Paul Brunt
  14707. All rights reserved.
  14708. Redistribution and use in source and binary forms, with or without
  14709. modification, are permitted provided that the following conditions are met:
  14710. * Redistributions of source code must retain the above copyright
  14711. notice, this list of conditions and the following disclaimer.
  14712. * Redistributions in binary form must reproduce the above copyright
  14713. notice, this list of conditions and the following disclaimer in the
  14714. documentation and/or other materials provided with the distribution.
  14715. * Neither the name of GLGE nor the
  14716. names of its contributors may be used to endorse or promote products
  14717. derived from this software without specific prior written permission.
  14718. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  14719. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  14720. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  14721. DISCLAIMED. IN NO EVENT SHALL PAUL BRUNT BE LIABLE FOR ANY
  14722. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  14723. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  14724. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  14725. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  14726. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  14727. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14728. */
  14729. /**
  14730. * @fileOverview
  14731. * @name glge_collada.js
  14732. * @author me@paulbrunt.co.uk
  14733. */
  14734. if(typeof(GLGE) == "undefined"){
  14735. /**
  14736. * @namespace Holds the functionality of the library
  14737. */
  14738. GLGE = {};
  14739. }
  14740. (function(GLGE){
  14741. GLGE.ColladaDocuments=[];
  14742. /**
  14743. * @class Class to represent a collada object
  14744. * @augments GLGE.Group
  14745. */
  14746. GLGE.Collada=function(uid){
  14747. GLGE.Group.call(this);
  14748. this.children=[];
  14749. this.actions={};
  14750. this.boneIdx=0;
  14751. this.objIdx=0;
  14752. this.actionsIdx=0;
  14753. GLGE.Assets.registerAsset(this,uid);
  14754. };
  14755. GLGE.augment(GLGE.Group,GLGE.Collada);
  14756. GLGE.Collada.prototype.type=GLGE.G_NODE;
  14757. GLGE.Collada.prototype.useLights=false;
  14758. GLGE.Collada.prototype.useCamera=false
  14759. GLGE.Collada.prototype.useBinaryAlpha=false;
  14760. /**
  14761. * Gets the absolute path given an import path and the path it's relative to
  14762. * @param {string} path the path to get the absolute path for
  14763. * @param {string} relativeto the path the supplied path is relativeto
  14764. * @returns {string} absolute path
  14765. * @private
  14766. */
  14767. GLGE.Collada.prototype.getAbsolutePath=function(path,relativeto){
  14768. if(path.substr(0,7)=="http://" || path.substr(0,7)=="file://" || path.substr(0,7)=="https://"){
  14769. return path;
  14770. }
  14771. else
  14772. {
  14773. if(!relativeto){
  14774. relativeto=window.location.href;
  14775. }
  14776. if (relativeto.indexOf("://")==-1){
  14777. return relativeto.slice(0,relativeto.lastIndexOf("/"))+"/"+path;
  14778. }
  14779. //find the path compoents
  14780. var bits=relativeto.split("/");
  14781. var domain=bits[2];
  14782. var proto=bits[0];
  14783. var initpath=[];
  14784. for(var i=3;i<bits.length-1;i++){
  14785. initpath.push(bits[i]);
  14786. }
  14787. //relative to domain
  14788. if(path.substr(0,1)=="/"){
  14789. initpath=[];
  14790. }
  14791. var locpath=path.split("/");
  14792. for(i=0;i<locpath.length;i++){
  14793. if(locpath[i]=="..") initpath.pop();
  14794. else if(locpath[i]!="") initpath.push(locpath[i]);
  14795. }
  14796. return proto+"//"+domain+"/"+initpath.join("/");
  14797. }
  14798. }
  14799. /**
  14800. * function to get the element with a specified id
  14801. * @param {string} id the id of the element
  14802. * @private
  14803. */
  14804. GLGE.Collada.prototype.getElementById=function(id){
  14805. if(!this.idcache){
  14806. var tags=this.getElementsByTagName("*");
  14807. var attribid;
  14808. this.idcache={};
  14809. for(var i=0; i<tags.length;i++){
  14810. attribid=tags[i].getAttribute("id");
  14811. if(attribid!="") this.idcache[attribid]=tags[i];
  14812. }
  14813. }
  14814. return this.idcache[id];
  14815. }
  14816. /**
  14817. * function extracts a javascript array from the document
  14818. * @param {DOM Element} node the value to parse
  14819. * @private
  14820. */
  14821. GLGE.Collada.prototype.parseArray=function(node){
  14822. var value;
  14823. var child=node.firstChild;
  14824. var prev="";
  14825. var output=[];
  14826. var currentArray;
  14827. var i;
  14828. while(child){
  14829. currentArray=(prev+child.nodeValue).replace(/\s+/g," ").replace(/^\s+/g,"").split(" ");
  14830. child=child.nextSibling;
  14831. if(currentArray[0]=="") currentArray.unshift();
  14832. if(child) prev=currentArray.pop();
  14833. for(i=0;i<currentArray.length;i++) if(currentArray[i]!="") output.push(currentArray[i]);
  14834. }
  14835. return output;
  14836. };
  14837. /**
  14838. * determine if this is a sketchupfile
  14839. * @private
  14840. */
  14841. GLGE.Collada.prototype.isSketchupFile = function() {
  14842. var asset=this.xml.getElementsByTagName("asset");
  14843. if (!asset || asset.length==0)
  14844. return false;
  14845. for (var i=0;i<asset.length;++i){
  14846. var contributor=asset[i].getElementsByTagName("contributor");
  14847. if (!contributor || contributor.length==0)
  14848. return false;
  14849. for (var j=0;j<contributor.length;++j) {
  14850. var authoring=contributor[j].getElementsByTagName("authoring_tool");
  14851. if (!authoring || authoring.length==0)
  14852. return false;
  14853. for (var k=0;k<authoring.length;++k) {
  14854. var tool=authoring[k].firstChild.nodeValue;
  14855. if (tool.indexOf("Google")==0) {
  14856. return true;
  14857. }
  14858. }
  14859. }
  14860. }
  14861. return false;
  14862. };
  14863. /**
  14864. * set flag indicating if binary alpha should be used
  14865. * @param {boolean} flag the flag indicating binary alpha use
  14866. */
  14867. GLGE.Collada.prototype.setUseBinaryAlpha=function(flag){
  14868. this.useBinaryAlpha=flag;
  14869. return this;
  14870. }
  14871. /**
  14872. * set flag indicating if camera should be extracted from the collada document
  14873. * @param {boolean} node the value to parse
  14874. */
  14875. GLGE.Collada.prototype.setUseCamera=function(usecamera){
  14876. this.useCamera=usecamera;
  14877. return this;
  14878. }
  14879. /**
  14880. * get flag indicating if camera should be extracted from the collada document
  14881. * @returns {boolean} node the value to parse
  14882. */
  14883. GLGE.Collada.prototype.getUseCamera=function(){
  14884. return this.useCamera;
  14885. }
  14886. /**
  14887. * set flag indicating if lights should be extracted from the collada document
  14888. * @param {boolean} node the value to parse
  14889. */
  14890. GLGE.Collada.prototype.setUseLights=function(uselights){
  14891. this.useLights=uselights;
  14892. return this;
  14893. }
  14894. /**
  14895. * get flag indicating if lights should be extracted from the collada document
  14896. * @returns {boolean} node the value to parse
  14897. */
  14898. GLGE.Collada.prototype.getUseLights=function(uselights){
  14899. return this.useLights;
  14900. }
  14901. /**
  14902. * loads an collada file from a given url
  14903. * @param {DOM Element} node the value to parse
  14904. * @param {string} relativeTo optional the path the url is relative to
  14905. */
  14906. GLGE.Collada.prototype.setDocument=function(url,relativeTo,cb){
  14907. this.url=url;
  14908. this.loadedCallback=cb;
  14909. //use # to determine the is of the asset to extract
  14910. if(url.indexOf("#")!=-1){
  14911. this.rootId=url.substr(url.indexOf("#")+1);
  14912. url=url.substr(0,url.indexOf("#"));
  14913. }
  14914. this.sourceURL=url;
  14915. if(relativeTo) url=this.getAbsolutePath(url,relativeTo);
  14916. this.docURL=url;
  14917. if(GLGE.ColladaDocuments[url]){
  14918. this.xml=GLGE.ColladaDocuments[url];
  14919. }else{
  14920. var req = new XMLHttpRequest();
  14921. if(req) {
  14922. req.overrideMimeType("text/xml")
  14923. var docurl=url;
  14924. var docObj=this;
  14925. req.onreadystatechange = function() {
  14926. if(this.readyState == 4)
  14927. {
  14928. if(this.status == 200 || this.status==0){
  14929. this.responseXML.getElementById=docObj.getElementById;
  14930. docObj.loaded(docurl,this.responseXML);
  14931. }else{
  14932. GLGE.error("Error loading Document: "+docurl+" status "+this.status);
  14933. }
  14934. }
  14935. };
  14936. req.open("GET", url, true);
  14937. req.send("");
  14938. }
  14939. }
  14940. };
  14941. /**
  14942. * gets data for a given source element
  14943. * @param {string} id the id of the source element
  14944. * @private
  14945. */
  14946. GLGE.Collada.prototype.getSource=function(id){
  14947. var element=this.xml.getElementById(id);
  14948. if (!element )
  14949. return []
  14950. if(!element.jsArray || this.badAccessor){
  14951. var value;
  14952. if(element.tagName=="vertices"){
  14953. value=[];
  14954. var inputs=element.getElementsByTagName("input");
  14955. for(var i=0;i<inputs.length;i++){
  14956. value[i]=this.getSource(inputs[i].getAttribute("source").substr(1));
  14957. value[i].block=inputs[i].getAttribute("semantic");
  14958. }
  14959. }else{
  14960. var accessor=element.getElementsByTagName("technique_common")[0].getElementsByTagName("accessor")[0];
  14961. var sourceArray=this.xml.getElementById(accessor.getAttribute("source").substr(1));
  14962. var type=sourceArray.tagName;
  14963. value=this.parseArray(sourceArray);
  14964. stride=parseInt(accessor.getAttribute("stride"));
  14965. offset=parseInt(accessor.getAttribute("offset"));
  14966. if(!offset) offset=0;
  14967. if(!stride) stride=1;
  14968. count=parseInt(accessor.getAttribute("count"));
  14969. var params=accessor.getElementsByTagName("param");
  14970. var pmask=[];
  14971. for(var i=0;i<params.length;i++){if(params[i].hasAttribute("name") || this.exceptions.badAccessor || this.badAccessor) pmask.push({type:params[i].getAttribute("type"),name:params[i].getAttribute("name")}); else pmask.push(false);}
  14972. value={array:value,stride:stride,offset:offset,count:count,pmask:pmask,type:type};
  14973. }
  14974. element.jsArray=value;
  14975. }
  14976. return element.jsArray;
  14977. };
  14978. var meshCache={};
  14979. /**
  14980. * Creates a new object and added the meshes parse in the geomertry
  14981. * @param {string} id id of the geomerty to parse
  14982. * @private
  14983. */
  14984. GLGE.Collada.prototype.getMeshes=function(id,skeletonData){
  14985. if(!meshCache[this.url]) meshCache[this.url]=[];
  14986. if(meshCache[this.url][id]) return meshCache[this.url][id];
  14987. var i,n;
  14988. var mesh;
  14989. var inputs;
  14990. var inputArray;
  14991. var vertexJoints;
  14992. var vertexWeights;
  14993. var faces;
  14994. var outputData;
  14995. var block;
  14996. var set;
  14997. var rootNode=this.xml.getElementById(id);
  14998. if (!rootNode) {
  14999. GLGE.error("Collada.getMeshes returning [], id: " + id);
  15000. return [];
  15001. }
  15002. var temp = rootNode.getElementsByTagName("mesh");
  15003. if (!temp){
  15004. GLGE.error("Collada.getMeshes returning [], id: " + id);
  15005. return [];
  15006. }
  15007. meshNode = null;
  15008. if (temp.length) {
  15009. meshNode = temp[0];
  15010. }
  15011. else {
  15012. GLGE.error("Collada.getMeshes returning [], id: " + id);
  15013. }
  15014. var meshes=[];
  15015. if(!meshNode) return meshes;
  15016. //convert polylists to triangles my head hurts now :-(
  15017. var polylists=meshNode.getElementsByTagName("polylist");
  15018. for(i=0;i<polylists.length;i++){
  15019. faces=this.parseArray(polylists[i].getElementsByTagName("p")[0]);
  15020. vcount=this.parseArray(polylists[i].getElementsByTagName("vcount")[0]);
  15021. var inputcount=polylists[i].getElementsByTagName("input");
  15022. var maxoffset=0;
  15023. for(n=0;n<inputcount.length;n++) maxoffset=Math.max(maxoffset,inputcount[n].getAttribute("offset"));
  15024. var tris=[];
  15025. var cnt=0;
  15026. for(n=0;n<vcount.length;n++){
  15027. for(var j=0; j<vcount[n]-2;j++){
  15028. for(var k=0;k<=maxoffset;k++){
  15029. tris.push(faces[cnt+k]);
  15030. }
  15031. for(k=0;k<=maxoffset;k++){
  15032. tris.push(faces[cnt+(maxoffset+1)*(j+1)+k]);
  15033. }
  15034. for(k=0;k<=maxoffset;k++){
  15035. tris.push(faces[cnt+(maxoffset+1)*(j+2)+k]);
  15036. }
  15037. }
  15038. cnt=cnt+(maxoffset+1)*vcount[n];
  15039. }
  15040. polylists[i].getElementsByTagName("p")[0].data=tris;
  15041. }
  15042. //convert polygons to tris
  15043. var polygons=meshNode.getElementsByTagName("polygons");
  15044. for(i=0;i<polygons.length;i++){
  15045. var polys=polygons[i].getElementsByTagName("p");
  15046. var tris=[];
  15047. for(var l=0;l<polys.length;l++){
  15048. var faces=this.parseArray(polys[l]);
  15049. var inputcount=polygons[i].getElementsByTagName("input");
  15050. var maxoffset=0;
  15051. for(n=0;n<inputcount.length;n++) maxoffset=Math.max(maxoffset,inputcount[n].getAttribute("offset"));
  15052. var cnt=0;
  15053. for(j=0; j<(faces.length/(maxoffset+1))-2;j++){
  15054. for(k=0;k<=maxoffset;k++){
  15055. tris.push(faces[cnt+k]);
  15056. }
  15057. for(k=0;k<=maxoffset;k++){
  15058. tris.push(faces[cnt+(maxoffset+1)*(j+1)+k]);
  15059. }
  15060. for(k=0;k<=maxoffset;k++){
  15061. tris.push(faces[cnt+(maxoffset+1)*(j+2)+k]);
  15062. }
  15063. }
  15064. cnt=cnt+(maxoffset+1)*(faces.length/(maxoffset+1));
  15065. }
  15066. if(polys.length>0) polygons[i].getElementsByTagName("p")[0].data=tris;
  15067. }
  15068. //create a mesh for each set of faces
  15069. var triangles=[];
  15070. var tris=meshNode.getElementsByTagName("triangles");
  15071. for(i=0;i<polylists.length;i++){triangles.push(polylists[i])};
  15072. for(i=0;i<polygons.length;i++){if(polygons[i].getElementsByTagName("p").length>0) triangles.push(polygons[i])};
  15073. for(i=0;i<tris.length;i++){triangles.push(tris[i])};
  15074. for(i=0;i<triangles.length;i++){
  15075. //go though the inputs to get the data layout
  15076. inputs=triangles[i].getElementsByTagName("input");
  15077. vertexJoints=[];
  15078. vertexWeights=[];
  15079. inputArray=[];
  15080. outputData={};
  15081. for(n=0;n<inputs.length;n++){
  15082. inputs[n].data=this.getSource(inputs[n].getAttribute("source").substr(1));
  15083. block=inputs[n].getAttribute("semantic");
  15084. if(block=="TEXCOORD"){
  15085. set=inputs[n].getAttribute("set");
  15086. if(!set) set=0;
  15087. block=block+set;
  15088. }
  15089. if(block=="VERTEX"){
  15090. for(var l=0;l<inputs[n].data.length;l++){
  15091. outputData[inputs[n].data[l].block]=[];
  15092. }
  15093. }
  15094. inputs[n].block=block;
  15095. inputs[n].offset=parseInt(inputs[n].getAttribute("offset"));
  15096. outputData[block]=[];
  15097. inputArray.push(inputs[n]);
  15098. //inputArray[inputs[n].getAttribute("offset")]=inputs[n];
  15099. }
  15100. //get the face data and push the data into the mesh
  15101. if(triangles[i].getElementsByTagName("p")[0].data) faces=triangles[i].getElementsByTagName("p")[0].data;
  15102. else faces=this.parseArray(triangles[i].getElementsByTagName("p")[0]);
  15103. for(var n=0;n<inputArray.length;n++){
  15104. if(inputArray[n].block!="VERTEX"){
  15105. inputArray[n].data=[inputArray[n].data];
  15106. inputArray[n].data[0].block=inputArray[n].block;
  15107. }
  15108. }
  15109. //get max offset
  15110. var maxoffset=0;
  15111. for(n=0;n<inputArray.length;n++){
  15112. maxoffset=Math.max(inputArray[n].offset+1,maxoffset);
  15113. }
  15114. for(j=0;j<faces.length;j=j+maxoffset){
  15115. for(n=0;n<inputArray.length;n++){
  15116. for(var l=0;l<inputArray[n].data.length;l++){
  15117. var block=inputArray[n].data[l].block;
  15118. var pcnt=inputArray[n].data[l].stride;
  15119. for(k=0;k<inputArray[n].data[l].stride;k++){
  15120. if(inputArray[n].data[l].pmask[k]){
  15121. outputData[block].push(inputArray[n].data[l].array[faces[j+inputArray[n].offset]*inputArray[n].data[l].stride+k+inputArray[n].data[l].offset]);
  15122. }
  15123. }
  15124. if(skeletonData && block=="POSITION"){
  15125. for(k=0;k<skeletonData.count;k++){
  15126. vertexJoints.push(skeletonData.vertexJoints[faces[j+inputArray[n].offset]*skeletonData.count+k]);
  15127. vertexWeights.push(skeletonData.vertexWeight[faces[j+inputArray[n].offset]*skeletonData.count+k]);
  15128. }
  15129. }
  15130. //account for 1D and 2D
  15131. if(block=="POSITION" && pcnt==1) {outputData[block].push(0);outputData[block].push(0);}
  15132. if(block=="POSITION" && pcnt==2) outputData[block].push(0);
  15133. //we can't handle 3d texcoords at the moment so try two
  15134. if(block=="TEXCOORD0" && pcnt==3) outputData[block].pop();
  15135. if(block=="TEXCOORD1" && pcnt==3) outputData[block].pop();
  15136. }
  15137. }
  15138. }
  15139. //create faces array
  15140. faces=[];
  15141. //create mesh
  15142. var windingOrder=GLGE.Mesh.WINDING_ORDER_CLOCKWISE;
  15143. if(!outputData.NORMAL){
  15144. console.log("Autogenerating normals, do not know facings");
  15145. outputData.NORMAL=[];
  15146. for(n=0;n<outputData.POSITION.length;n=n+9){
  15147. var vec1=GLGE.subVec3([outputData.POSITION[n],outputData.POSITION[n+1],outputData.POSITION[n+2]],[outputData.POSITION[n+3],outputData.POSITION[n+4],outputData.POSITION[n+5]]);
  15148. var vec2=GLGE.subVec3([outputData.POSITION[n+6],outputData.POSITION[n+7],outputData.POSITION[n+8]],[outputData.POSITION[n],outputData.POSITION[n+1],outputData.POSITION[n+2]]);
  15149. var vec3=GLGE.toUnitVec3(GLGE.crossVec3(GLGE.toUnitVec3(vec2),GLGE.toUnitVec3(vec1)));
  15150. outputData.NORMAL.push(vec3[0]);
  15151. outputData.NORMAL.push(vec3[1]);
  15152. outputData.NORMAL.push(vec3[2]);
  15153. outputData.NORMAL.push(vec3[0]);
  15154. outputData.NORMAL.push(vec3[1]);
  15155. outputData.NORMAL.push(vec3[2]);
  15156. outputData.NORMAL.push(vec3[0]);
  15157. outputData.NORMAL.push(vec3[1]);
  15158. outputData.NORMAL.push(vec3[2]);
  15159. }
  15160. var len=outputData.POSITION.length/3;
  15161. for(n=0;n<len;n++) faces.push(n);
  15162. }else {
  15163. windingOrder=GLGE.Mesh.WINDING_ORDER_CLOCKWISE;
  15164. for(n=0;n<outputData.POSITION.length;n=n+9){
  15165. var vec1=GLGE.subVec3([outputData.POSITION[n],outputData.POSITION[n+1],outputData.POSITION[n+2]],[outputData.POSITION[n+3],outputData.POSITION[n+4],outputData.POSITION[n+5]]);
  15166. var vec2=GLGE.subVec3([outputData.POSITION[n+6],outputData.POSITION[n+7],outputData.POSITION[n+8]],[outputData.POSITION[n],outputData.POSITION[n+1],outputData.POSITION[n+2]]);
  15167. var vec3=GLGE.crossVec3(vec2,vec1);
  15168. var clockwise_winding_order=0;
  15169. for (var dp=0;dp<9;dp+=3) {
  15170. if (
  15171. vec3[0]*outputData.NORMAL[n+dp]
  15172. + vec3[1]*outputData.NORMAL[n+dp+1]
  15173. + vec3[2]*outputData.NORMAL[n+dp+2]<0) {
  15174. clockwise_winding_order-=1;
  15175. }else clockwise_winding_order+=1;
  15176. }
  15177. if (clockwise_winding_order<0) {
  15178. var len=outputData.POSITION.length/3;
  15179. faces.push(n/3);
  15180. faces.push(n/3+2);
  15181. faces.push(n/3+1);//invert
  15182. }else {
  15183. faces.push(n/3);
  15184. faces.push(n/3+1);
  15185. faces.push(n/3+2);
  15186. }
  15187. }
  15188. }
  15189. if (!this.isSketchupFile())
  15190. windingOrder=GLGE.Mesh.WINDING_ORDER_UNKNOWN;
  15191. function min(a,b){
  15192. return (a>b?b:a);
  15193. }
  15194. var MAXVERTS=21843;
  15195. MAXVERTS*=3;//always must be a multiple of 3 (3 vertices)
  15196. var nummesh=((faces.length-faces.length%MAXVERTS)/MAXVERTS)+(faces.length%MAXVERTS?1:0);
  15197. var trimesh=[];
  15198. var vstride=3;
  15199. var nstride=3;
  15200. var tstride=2;
  15201. for (var index=0;index<nummesh;++index) {
  15202. trimesh.push(new GLGE.Mesh(undefined,windingOrder));
  15203. trimesh[index].setPositions(outputData.POSITION.slice(MAXVERTS*index*vstride,min(MAXVERTS*vstride*(index+1),outputData.POSITION.length)));
  15204. trimesh[index].setNormals(outputData.NORMAL.slice(MAXVERTS*index*nstride,min(MAXVERTS*(index+1)*nstride,outputData.POSITION.length)));
  15205. if(outputData.TEXCOORD0) trimesh[index].setUV(outputData.TEXCOORD0.slice(MAXVERTS*index*tstride,min(MAXVERTS*(index+1)*tstride,outputData.TEXCOORD0.length)));
  15206. if(!outputData.TEXCOORD0 && outputData.TEXCOORD1) trimesh[index].setUV(outputData.TEXCOORD1.slice(MAXVERTS*index*tstride,min(MAXVERTS*(index+1)*tstride,outputData.TEXCOORD1.length)));
  15207. if(outputData.TEXCOORD1) trimesh[index].setUV2(outputData.TEXCOORD1.slice(MAXVERTS*index*tstride,min(MAXVERTS*(index+1)*tstride,outputData.TEXCOORD1.length)));
  15208. }
  15209. if(skeletonData){
  15210. if(skeletonData.count>8){
  15211. var newjoints=[];
  15212. var newweights=[];
  15213. for(var j=0;j<vertexWeights.length;j=j+skeletonData.count){
  15214. var tmp=[];
  15215. for(k=0;k<skeletonData.count;k++){
  15216. tmp.push({weight:vertexWeights[j+k],joint:vertexJoints[j+k]});
  15217. }
  15218. tmp.sort(function(a,b){return parseFloat(b.weight)-parseFloat(a.weight)});
  15219. for(k=0;k<8;k++){
  15220. newjoints.push(tmp[k].joint);
  15221. newweights.push(tmp[k].weight);
  15222. }
  15223. }
  15224. vertexJoints=newjoints;
  15225. vertexWeights=newweights;
  15226. skeletonData.count=8;
  15227. }
  15228. for (var index=0;index<nummesh;++index) {
  15229. trimesh[index].setJoints(skeletonData.joints);
  15230. trimesh[index].setInvBindMatrix(skeletonData.inverseBindMatrix);
  15231. var maxval=min(MAXVERTS*(index+1)*skeletonData.count,vertexJoints.length);
  15232. var minval=MAXVERTS*index*skeletonData.count;
  15233. trimesh[index].setVertexJoints(vertexJoints.slice(minval,maxval),skeletonData.count);
  15234. trimesh[index].setVertexWeights(vertexWeights.slice(minval,maxval),skeletonData.count);
  15235. }
  15236. }
  15237. for (var index=0;index<nummesh;++index) {
  15238. trimesh[index].setFaces(faces.slice(0,min(MAXVERTS*(index+1),faces.length)-MAXVERTS*(index)));
  15239. trimesh[index].matName=triangles[i].getAttribute("material");
  15240. meshes.push(trimesh[index]);
  15241. }
  15242. }
  15243. meshCache[this.url][id]=meshes;
  15244. return meshes;
  15245. };
  15246. /**
  15247. * Gets the float4 parameter for a shader
  15248. * @private
  15249. */
  15250. GLGE.Collada.prototype.getFloat4=function(profile,sid){
  15251. // MCB: it's possible for newparam to be in effect scope
  15252. var params=profile.getElementsByTagName("newparam");
  15253. for(var i=0;i<params.length;i++){
  15254. if(params[i].getAttribute("sid")==sid){
  15255. return params[i].getElementsByTagName("float4")[0].firstChild.nodeValue;
  15256. break;
  15257. }
  15258. }
  15259. return null;
  15260. }
  15261. /**
  15262. * Gets the float parameter for a shader
  15263. * @private
  15264. */
  15265. GLGE.Collada.prototype.getFloat=function(profile,sid){
  15266. // MCB: it's possible for newparam to be in effect scope
  15267. var params=profile.getElementsByTagName("newparam");
  15268. for(var i=0;i<params.length;i++){
  15269. if(params[i].getAttribute("sid")==sid){
  15270. return params[i].getElementsByTagName("float")[0].firstChild.nodeValue;
  15271. break;
  15272. }
  15273. }
  15274. return null;
  15275. }
  15276. /**
  15277. * Gets the sampler for a texture
  15278. * @private
  15279. */
  15280. GLGE.Collada.prototype.getSampler=function(profile,sid){
  15281. // MCB: it's possible for newparam to be in effect scope
  15282. var params=profile.getElementsByTagName("newparam");
  15283. for(var i=0;i<params.length;i++){
  15284. if(params[i].getAttribute("sid")==sid){
  15285. //only do 2d atm.
  15286. return params[i].getElementsByTagName("sampler2D")[0].getElementsByTagName("source")[0].firstChild.nodeValue;
  15287. break;
  15288. }
  15289. }
  15290. return null;
  15291. }
  15292. /**
  15293. * Gets the surface for a texture
  15294. * @private
  15295. */
  15296. GLGE.Collada.prototype.getSurface=function(profile,sid){
  15297. // MCB: it's possible for newparam to be in effect scope
  15298. var params=profile.getElementsByTagName("newparam");
  15299. for(var i=0;i<params.length;i++){
  15300. if(params[i].getAttribute("sid")==sid){
  15301. return params[i].getElementsByTagName("surface")[0].getElementsByTagName("init_from")[0].firstChild.nodeValue;
  15302. break;
  15303. }
  15304. }
  15305. return null;
  15306. }
  15307. /**
  15308. * Gets the the collada image location
  15309. * @private
  15310. */
  15311. GLGE.Collada.prototype.getImage=function(id){
  15312. var image=this.xml.getElementById(id);
  15313. if(!image) return;
  15314. return this.getAbsolutePath(image.getElementsByTagName("init_from")[0].firstChild.nodeValue,this.docURL);
  15315. }
  15316. /**
  15317. * creates a material layer
  15318. * @private
  15319. */
  15320. GLGE.Collada.prototype.createMaterialLayer=function(node,material,common,mapto,bvi){
  15321. var textureImage;
  15322. var imageid=this.getSurface(common,this.getSampler(common,node.getAttribute("texture")));
  15323. if(!imageid) imageid=node.getAttribute("texture"); //assume converter bug - workround
  15324. textureImage=this.getImage(imageid);
  15325. var texture=new GLGE.Texture();
  15326. texture.setSrc(textureImage);
  15327. material.addTexture(texture);
  15328. var layer=new GLGE.MaterialLayer();
  15329. layer.setTexture(texture);
  15330. layer.setMapto(mapto);
  15331. if(node.hasAttribute("texcoord") && bvi[node.getAttribute("texcoord")]){
  15332. if(bvi[node.getAttribute("texcoord")]==1) {
  15333. layer.setMapinput(GLGE.UV2);
  15334. }else if (bvi[node.getAttribute("texcoord")]==0) {
  15335. layer.setMapinput(GLGE.UV1);
  15336. } else {
  15337. GLGE.error("GLGE only supports 2 texture sets\n");
  15338. layer.setMapinput(GLGE.UV1);
  15339. }
  15340. }else {
  15341. GLGE.error("Collada material does not specify texture coordinates, but it may have them: defaulting to set 0\n");
  15342. layer.setMapinput(GLGE.UV1);
  15343. }
  15344. // JHD: Added correct bracket enclosing for the "true" case.
  15345. if (node.getElementsByTagName("blend_mode")[0]) {
  15346. var blend = node.getElementsByTagName("blend_mode")[0].firstChild.nodeValue;
  15347. if (blend == "MULTIPLY")
  15348. layer.setBlendMode(GLGE.BL_MUL);
  15349. }
  15350. // JDH - End
  15351. material.addMaterialLayer(layer);
  15352. }
  15353. /**
  15354. * Function will get element by id starting from specified node.
  15355. * Author: Renato Bebić <renato.bebic@gmail.com>
  15356. *
  15357. * The material getter below borked if there is e.g. a scene node with the same name as the material.
  15358. * This is used to fix that by only looking for materials in the library_materials element.
  15359. */
  15360. function getChildElementById( dNode, id ) {
  15361. var dResult = null;
  15362. if ( dNode.getAttribute('id') == id )
  15363. return dNode;
  15364. for ( var i = 0; i < dNode.childNodes.length; i++ ) {
  15365. if ( dNode.childNodes[i].nodeType == 1 ) {
  15366. dResult = getChildElementById( dNode.childNodes[i], id ); //note: 1-level deep would suffice here, doesn't need to recurse into further childs. but this works.
  15367. if ( dResult != null )
  15368. break;
  15369. }
  15370. }
  15371. return dResult;
  15372. }
  15373. var MaterialCache={};
  15374. /**
  15375. * Gets the sampler for a texture
  15376. * @param {string} id the id or the material element
  15377. * @private
  15378. */
  15379. GLGE.Collada.prototype.getMaterial=function(id,bvi){
  15380. // JHD: Added "else" and enclosing brackets
  15381. if (!MaterialCache[this.url]) {
  15382. MaterialCache[this.url] = {};
  15383. } else if (MaterialCache[this.url][id]) {
  15384. return MaterialCache[this.url][id];
  15385. }
  15386. var materialLib=this.xml.getElementsByTagName("library_materials")[0];
  15387. var materialNode=getChildElementById(materialLib, id); //this.xml.getElementById(id);
  15388. if (!materialNode) {
  15389. var returnMaterial=new GLGE.Material();
  15390. MaterialCache[this.url][id]=returnMaterial;
  15391. return returnMaterial;
  15392. }
  15393. var effectid=materialNode.getElementsByTagName("instance_effect")[0].getAttribute("url").substr(1);
  15394. var effect=this.xml.getElementById(effectid);
  15395. var common=effect.getElementsByTagName("profile_COMMON")[0];
  15396. //glge only supports one technique currently so try and match as best we can
  15397. var technique=common.getElementsByTagName("technique")[0];
  15398. var returnMaterial=new GLGE.Material();
  15399. returnMaterial.setBinaryAlpha(this.useBinaryAlpha);
  15400. returnMaterial.setSpecular(0);
  15401. MaterialCache[this.url][id]=returnMaterial;
  15402. var child;
  15403. var color;
  15404. //do ambient lighting
  15405. var ambient=technique.getElementsByTagName("ambient");
  15406. if(ambient.length>0){
  15407. child=ambient[0].firstChild;
  15408. do{
  15409. switch(child.tagName){
  15410. case "color":
  15411. color=child.firstChild.nodeValue.replace(/\s+/g,' ').split(" ");
  15412. returnMaterial.setAmbient({r:color[0],g:color[1],b:color[2]});
  15413. break;
  15414. case "param":
  15415. color=this.getFloat4(common,child.getAttribute("ref")).replace(/\s+/g,' ').split(" ");
  15416. returnMaterial.setAmbient({r:color[0],g:color[1],b:color[2]});
  15417. break;
  15418. case "texture":
  15419. this.createMaterialLayer(child,returnMaterial,common,GLGE.M_AMBIENT,bvi);
  15420. break;
  15421. }
  15422. }while(child=child.nextSibling);
  15423. }
  15424. //do diffuse color
  15425. var diffuse=technique.getElementsByTagName("diffuse");
  15426. if(diffuse.length>0){
  15427. child=diffuse[0].firstChild;
  15428. do{
  15429. switch(child.tagName){
  15430. case "color":
  15431. color=child.firstChild.nodeValue.replace(/\s+/g,' ').split(" ");
  15432. returnMaterial.setColor({r:color[0],g:color[1],b:color[2]});
  15433. break;
  15434. case "param":
  15435. color=this.getFloat4(common,child.getAttribute("ref")).replace(/\s+/g,' ').split(" ");
  15436. returnMaterial.setColor({r:color[0],g:color[1],b:color[2]});
  15437. break;
  15438. case "texture":
  15439. this.createMaterialLayer(child,returnMaterial,common,GLGE.M_COLOR,bvi);
  15440. break;
  15441. }
  15442. }while(child=child.nextSibling);
  15443. }
  15444. var bump=technique.getElementsByTagName("bump");
  15445. if(bump.length>0){
  15446. child=bump[0].firstChild;
  15447. do{
  15448. switch(child.tagName){
  15449. case "texture":
  15450. this.createMaterialLayer(child,returnMaterial,common,GLGE.M_NOR,bvi);
  15451. break;
  15452. }
  15453. }while(child=child.nextSibling);
  15454. }
  15455. //do shininess
  15456. var shininess=technique.getElementsByTagName("shininess");
  15457. if(shininess.length>0){
  15458. returnMaterial.setSpecular(1);
  15459. child=technique.getElementsByTagName("shininess")[0].firstChild;
  15460. do{
  15461. switch(child.tagName){
  15462. case "float":
  15463. if(parseFloat(child.firstChild.nodeValue)>1) returnMaterial.setShininess(parseFloat(child.firstChild.nodeValue));
  15464. else returnMaterial.setShininess(parseFloat(child.firstChild.nodeValue)*128);
  15465. break;
  15466. case "param":
  15467. var value=parseFloat(this.getFloat(common,child.getAttribute("ref")));
  15468. if(value>1) returnMaterial.setShininess(value);
  15469. else returnMaterial.setShininess(value*128);
  15470. break;
  15471. // MCB: texture is invalid here. should remove this case.
  15472. case "texture":
  15473. this.createMaterialLayer(child,returnMaterial,common,GLGE.M_SHINE,bvi);
  15474. break;
  15475. }
  15476. }while(child=child.nextSibling);
  15477. }
  15478. //do specular color
  15479. var specular=technique.getElementsByTagName("specular");
  15480. if(specular.length>0){
  15481. returnMaterial.setSpecular(1);
  15482. child=specular[0].firstChild;
  15483. do{
  15484. switch(child.tagName){
  15485. case "color":
  15486. color=child.firstChild.nodeValue.replace(/\s+/g,' ').split(" ");
  15487. returnMaterial.setSpecularColor({r:color[0],g:color[1],b:color[2]});
  15488. break;
  15489. case "param":
  15490. color=this.getFloat4(common,child.getAttribute("ref")).replace(/\s+/g,' ').split(" ");
  15491. returnMaterial.setSpecularColor({r:color[0],g:color[1],b:color[2]});
  15492. break;
  15493. case "texture":
  15494. this.createMaterialLayer(child,returnMaterial,common,GLGE.M_SPECCOLOR,bvi);
  15495. break;
  15496. }
  15497. }while(child=child.nextSibling);
  15498. }
  15499. //do reflectivity
  15500. /*
  15501. var reflectivity=technique.getElementsByTagName("reflectivity");
  15502. if(reflectivity.length>0){
  15503. child=reflectivity[0].firstChild;
  15504. do{
  15505. switch(child.tagName){
  15506. case "float":
  15507. //returnMaterial.setReflectivity(parseFloat(child.firstChild.nodeValue))
  15508. break;
  15509. case "param":
  15510. //returnMaterial.setReflectivity(parseFloat(this.getFloat(common,child.getAttribute("ref"))));
  15511. break;
  15512. // MCB: texture is invalid here. should remove this case.
  15513. case "texture":
  15514. var imageid=this.getSurface(common,this.getSampler(common,child.getAttribute("texture")));
  15515. textureImage=this.getImage(imageid);
  15516. var texture=new GLGE.Texture(textureImage);
  15517. returnMaterial.addTexture(texture);
  15518. returnMaterial.addMaterialLayer(new GLGE.MaterialLayer(texture,GLGE.M_REFLECT,GLGE.UV1));
  15519. break;
  15520. }
  15521. }while(child=child.nextSibling);
  15522. }*/
  15523. //do emission color
  15524. var emission=technique.getElementsByTagName("emission");
  15525. if(emission.length>0){
  15526. child=emission[0].firstChild;
  15527. do{
  15528. switch(child.tagName){
  15529. case "color":
  15530. color=child.firstChild.nodeValue.split(" ");
  15531. returnMaterial.setEmit({r:color[0],g:color[1],b:color[2]});
  15532. break;
  15533. case "param":
  15534. color=this.getFloat4(common,child.getAttribute("ref")).split(" ");
  15535. returnMaterial.setEmit(color[0]);
  15536. break;
  15537. case "texture":
  15538. this.createMaterialLayer(child,returnMaterial,common,GLGE.M_EMIT,bvi);
  15539. break;
  15540. }
  15541. }while(child=child.nextSibling);
  15542. }
  15543. //do reflective color
  15544. var reflective=technique.getElementsByTagName("reflective");
  15545. if(reflective.length>0){
  15546. child=reflective[0].firstChild;
  15547. do{
  15548. switch(child.tagName){
  15549. case "color":
  15550. color=child.firstChild.nodeValue.replace(/\s+/g,' ').split(" ");
  15551. //TODO returnMaterial.setReflectiveColor({r:color[0],g:color[1],b:color[2]});
  15552. break;
  15553. case "param":
  15554. color=this.getFloat4(common,child.getAttribute("ref")).replace(/\s+/g,' ').split(" ");
  15555. //TODO returnMaterial.setReflectiveColor({r:color[0],g:color[1],b:color[2]});
  15556. break;
  15557. case "texture":
  15558. this.createMaterialLayer(child,returnMaterial,common,GLGE.M_REFLECT,bvi);
  15559. break;
  15560. }
  15561. }while(child=child.nextSibling);
  15562. }
  15563. //do transparency
  15564. var transparency=technique.getElementsByTagName("transparency");
  15565. if(transparency.length>0){
  15566. child=transparency[0].firstChild;
  15567. do{
  15568. switch(child.tagName){
  15569. case "float":
  15570. //TODO returnMaterial.setTransparency(parseFloat(child.firstChild.nodeValue))
  15571. //Causing issues with a couple of models
  15572. //returnMaterial.setAlpha(parseFloat(child.firstChild.nodeValue));
  15573. //returnMaterial.trans=true;
  15574. break;
  15575. case "param":
  15576. //TODO returnMaterial.setTransparency(parseFloat(this.getFloat(common,child.getAttribute("ref"))));
  15577. break;
  15578. }
  15579. }while(child=child.nextSibling);
  15580. }
  15581. //do transparent color
  15582. var transparent=technique.getElementsByTagName("transparent");
  15583. if(transparent.length>0){
  15584. var opaque=transparent[0].getAttribute("opaque");
  15585. if(!opaque) opaque="A_ONE"; // schema default
  15586. child=transparent[0].firstChild;
  15587. do{
  15588. switch(child.tagName){
  15589. // MCB: float is invalid here. should remove this case.
  15590. case "float":
  15591. var alpha=parseFloat(child.firstChild.nodeValue);
  15592. if(alpha<1){
  15593. returnMaterial.setAlpha(parseFloat(child.firstChild.nodeValue));
  15594. returnMaterial.trans=true;
  15595. }
  15596. break;
  15597. case "color":
  15598. color=child.firstChild.nodeValue.replace(/\s+/g,' ').split(" ");
  15599. var alpha=this.getMaterialAlpha(color,opaque,1);
  15600. //TODO var alpha=this.getMaterialAlpha(color,opaque,returnMaterial.getTransparency());
  15601. if(alpha<1){
  15602. returnMaterial.setAlpha(alpha);
  15603. returnMaterial.trans=true;
  15604. }
  15605. break;
  15606. case "param":
  15607. color=this.getFloat4(common,child.getAttribute("ref")).replace(/\s+/g,' ').split(" ");
  15608. var alpha=this.getMaterialAlpha(color,opaque,1);
  15609. //TODO var alpha=this.getMaterialAlpha(color,opaque,returnMaterial.getTransparency());
  15610. if(alpha<1){
  15611. returnMaterial.setAlpha(alpha);
  15612. returnMaterial.trans=true;
  15613. }
  15614. break;
  15615. // MCB: this case assumes opaque="A_ONE" and transparency="1.0"
  15616. case "texture":
  15617. this.createMaterialLayer(child,returnMaterial,common,GLGE.M_ALPHA,bvi);
  15618. returnMaterial.trans=true;
  15619. break;
  15620. }
  15621. }while(child=child.nextSibling);
  15622. }
  15623. return returnMaterial;
  15624. };
  15625. /**
  15626. * gets the material alpha from the transparent color
  15627. * @param {color} the transparent color
  15628. * @param {opaque} the transparent color opaque attribute value
  15629. * @param {transparency} the transparency value
  15630. * @private
  15631. */
  15632. GLGE.Collada.prototype.getMaterialAlpha=function(color,opaque,transparency){
  15633. var returnAlpha;
  15634. switch(opaque){
  15635. case "A_ONE":
  15636. returnAlpha=parseFloat(color[3])*transparency;
  15637. break;
  15638. case "A_ZERO":
  15639. returnAlpha=1-parseFloat(color[3])*transparency;
  15640. break;
  15641. case "RGB_ONE":
  15642. var luminance=parseFloat(color[0])*0.212671
  15643. +parseFloat(color[1])*0.715160
  15644. +parseFloat(color[2])*0.072169;
  15645. returnAlpha=luminance*transparency;
  15646. break;
  15647. case "RGB_ZERO":
  15648. var luminance=parseFloat(color[0])*0.212671
  15649. +parseFloat(color[1])*0.715160
  15650. +parseFloat(color[2])*0.072169;
  15651. returnAlpha=1-luminance*transparency;
  15652. break;
  15653. }
  15654. return returnAlpha;
  15655. };
  15656. GLGE.Collada.prototype.setMaterialOntoMesh=function(meshes,node) {
  15657. var materials=node.getElementsByTagName("instance_material");
  15658. var objMaterials={};
  15659. for(var i=0; i<materials.length;i++){
  15660. var bvis=materials[i].getElementsByTagName("bind_vertex_input");
  15661. var bvi={};
  15662. for(var j=0;j<bvis.length;j++){
  15663. if (bvis[j].hasAttribute("input_set")) {
  15664. bvi[bvis[j].getAttribute("semantic")]=bvis[j].getAttribute("input_set");
  15665. }else {//the exporter is buggy eg VCGLab | MeshLab and does not specify input_set
  15666. function getLastNumber(str){
  15667. var retval="";
  15668. for (var i=str.length-1;i>=0;--i)
  15669. if (str[i]>="0"&&str[i]<="9")
  15670. retval=str[i]+retval;
  15671. if (retval.length==0) return "0";
  15672. return retval;
  15673. }
  15674. bvi[bvis[j].getAttribute("semantic")]=getLastNumber(bvis[j].getAttribute("semantic"));
  15675. }
  15676. }
  15677. mat=this.getMaterial(materials[i].getAttribute("target").substr(1),bvi);
  15678. objMaterials[materials[i].getAttribute("symbol")]=mat;
  15679. }
  15680. //create GLGE object
  15681. var obj=new GLGE.Object();
  15682. if ( !obj.name || obj.name == "" ) {
  15683. obj.name = "glgeObj" + ( ++this.objIdx );
  15684. }
  15685. for(i=0; i<meshes.length;i++){
  15686. if(objMaterials[meshes[i].matName] && objMaterials[meshes[i].matName].trans){
  15687. obj.setZtransparent(true);
  15688. //default to not pickable for transparent objects
  15689. obj.setPickable(false);
  15690. }
  15691. var multimat=new GLGE.MultiMaterial();
  15692. multimat.setMesh(meshes[i]);
  15693. if(!objMaterials[meshes[i].matName]){
  15694. objMaterials[meshes[i].matName]=new GLGE.Material();
  15695. objMaterials[meshes[i].matName].setColor("lightgrey");
  15696. }
  15697. multimat.setMaterial(objMaterials[meshes[i].matName]);
  15698. obj.addMultiMaterial(multimat);
  15699. }
  15700. obj.setSkeleton(this);
  15701. node.GLGEObj=obj;
  15702. };
  15703. /**
  15704. * creates a GLGE Object from a given instance Geomertry
  15705. * @param {node} node the element to parse
  15706. * @private
  15707. */
  15708. GLGE.Collada.prototype.getInstanceGeometry=function(node){
  15709. if(node.GLGEObj && false){
  15710. var obj=new GLGE.ObjectInstance();
  15711. obj.setObject(node.GLGEObj);
  15712. return obj;
  15713. }else{
  15714. // JHD
  15715. var geometryId = node.getAttribute("url").substr(1);
  15716. var meshes = this.getMeshes(geometryId);
  15717. // JHD - End
  15718. this.setMaterialOntoMesh(meshes, node);
  15719. // JHD
  15720. node.GLGEObj.id = geometryId;
  15721. // JHD - End
  15722. return node.GLGEObj;
  15723. }
  15724. };
  15725. /**
  15726. * creates an array of animation curves
  15727. * @param {string} id the id of the sampler
  15728. * @private
  15729. */
  15730. GLGE.Collada.prototype.getAnimationSampler=function(id,rotation){
  15731. var frameRate=30;
  15732. var inputs=this.xml.getElementById(id).getElementsByTagName("input");
  15733. var outputData={};
  15734. var inputsArray=[];
  15735. var data,block;
  15736. for(var i=0;i<inputs.length;i++){
  15737. //modify get source to return the array and element length
  15738. data=this.getSource(inputs[i].getAttribute("source").substr(1));
  15739. block=inputs[i].getAttribute("semantic");
  15740. inputsArray.push({block:block,data:data});
  15741. }
  15742. for(var n=0;n<inputsArray.length;n++){
  15743. block=inputsArray[n].block;
  15744. outputData[block]={};
  15745. outputData[block].data=[];
  15746. outputData[block].names=[];
  15747. for(var k=0;k<inputsArray[n].data.array.length;k=k+inputsArray[n].data.stride){
  15748. var pcnt=0;
  15749. for(i=0;i<inputsArray[n].data.pmask.length;i++){
  15750. if(inputsArray[n].data.pmask[i]){
  15751. outputData[block].names.push(inputsArray[n].data.pmask[i].name);
  15752. if(inputsArray[n].data.pmask[i].type=="float4x4"){
  15753. outputData[block].stride=16;
  15754. for(var j=0;j<16;j++){
  15755. outputData[block].data.push(inputsArray[n].data.array[j+k+inputsArray[n].data.offset+i]);
  15756. }
  15757. }else{
  15758. pcnt++;
  15759. outputData[block].stride=pcnt;
  15760. outputData[block].data.push(inputsArray[n].data.array[k+inputsArray[n].data.offset+i]);
  15761. }
  15762. }
  15763. }
  15764. }
  15765. }
  15766. //this should return an array of curves
  15767. var point;
  15768. var anim=[];
  15769. for(var i=0; i<outputData["OUTPUT"].stride;i++){
  15770. anim.push(new GLGE.AnimationCurve());
  15771. }
  15772. for(var i=0;i<outputData["INPUT"].data.length;i++){
  15773. for(var j=0;j<outputData["OUTPUT"].stride;j++){
  15774. anim[j].name=outputData["OUTPUT"].names[j];
  15775. //fix if type is bezier and no tangent the fallback to linear
  15776. if(outputData["INTERPOLATION"] && outputData["INTERPOLATION"].data[i]=="BEZIER" && !outputData["IN_TANGENT"]){
  15777. outputData["INTERPOLATION"].data[i]="LINEAR";
  15778. }
  15779. if((!outputData["INTERPOLATION"]) || outputData["INTERPOLATION"].data[i]=="LINEAR"){
  15780. point=new GLGE.LinearPoint();
  15781. point.setX(outputData["INPUT"].data[i]*frameRate);
  15782. var val=parseFloat(outputData["OUTPUT"].data[i*outputData["OUTPUT"].stride+j]);
  15783. if(val==-180) val=-179.9;
  15784. if(val==180) val=179.9;
  15785. if(this.exceptions["flipangle"] && rotation){
  15786. if(anim[j].lastval){
  15787. if(Math.abs(anim[j].lastval-(360+val))<Math.abs(anim[j].lastval-val)){
  15788. val=360+val;
  15789. }else if(Math.abs(anim[j].lastval-(val-360))<Math.abs(anim[j].lastval-val)){
  15790. val=val-360;
  15791. }
  15792. }
  15793. }
  15794. point.setY(val);
  15795. anim[j].lastval=val;
  15796. anim[j].addPoint(point);
  15797. }
  15798. if(outputData["INTERPOLATION"] && outputData["INTERPOLATION"].data[i]=="BEZIER"){
  15799. point=new GLGE.BezTriple();
  15800. point.setX1(outputData["IN_TANGENT"].data[(i*outputData["OUTPUT"].stride+j)*2]*frameRate);
  15801. point.setY1(outputData["IN_TANGENT"].data[(i*outputData["OUTPUT"].stride+j)*2+1]);
  15802. point.setX2(Math.round(outputData["INPUT"].data[i]*frameRate));
  15803. point.setY2(outputData["OUTPUT"].data[i*outputData["OUTPUT"].stride+j]);
  15804. point.setX3(outputData["OUT_TANGENT"].data[(i*outputData["OUTPUT"].stride+j)*2]*frameRate);
  15805. point.setY3(outputData["OUT_TANGENT"].data[(i*outputData["OUTPUT"].stride+j)*2+1]);
  15806. anim[j].addPoint(point);
  15807. }
  15808. }
  15809. }
  15810. return anim;
  15811. }
  15812. /**
  15813. * Gets the animation vector for a node
  15814. * @param {object} channels the animation channels effecting this node
  15815. * @private
  15816. */
  15817. GLGE.Collada.prototype.getAnimationVector=function(channels){
  15818. //I can see no nice way to map a seuqnce of animated transforms onto a single transform
  15819. //so instead calc transform for each frame then use quat and trans then linear between them
  15820. var maxFrame=0;
  15821. //get the initial state of the target
  15822. var targetNode=this.xml.getElementById(channels[0].target[0]);
  15823. //blender 2.5a bug work round
  15824. var target=channels[0].target[0].toString()
  15825. if(!targetNode){
  15826. var target=target.substring(target.indexOf("_")+1);
  15827. targetNode=this.xml.getElementById(target);
  15828. }
  15829. if(!targetNode){
  15830. var target=target.substring(target.indexOf("_")+1);
  15831. targetNode=this.xml.getElementById(target);
  15832. }
  15833. //end work round
  15834. //get the initial transforms for the target node
  15835. var child=targetNode.firstChild;
  15836. var transforms=[];
  15837. var sids={};
  15838. do{
  15839. switch(child.tagName){
  15840. case "matrix":
  15841. case "translate":
  15842. case "rotate":
  15843. case "scale":
  15844. def={type:child.tagName,data:this.parseArray(child),animations:[]};
  15845. if(child.hasAttribute("sid")) sids[child.getAttribute("sid")]=def;
  15846. transforms.push(def);
  15847. break;
  15848. }
  15849. child=child.nextSibling
  15850. }while(child);
  15851. //loop though the animation channels effecting this node
  15852. var anim={};
  15853. for(var i=0;i<channels.length;i++){
  15854. var target=channels[i].target;
  15855. var animcurves=this.getAnimationSampler(channels[i].source,/ANGLE/i.test(target));
  15856. for(j=0;j<animcurves.length;j++){
  15857. maxFrame=Math.round(Math.max(maxFrame,animcurves[j].keyFrames[animcurves[j].keyFrames.length-1].x));
  15858. }
  15859. if(target[1].indexOf(".")!=-1){
  15860. var splittarget=target[1].split(".");
  15861. switch(splittarget[1]){
  15862. case "X":
  15863. sids[splittarget[0]].animations[0]=animcurves[0];
  15864. break;
  15865. case "Y":
  15866. sids[splittarget[0]].animations[1]=animcurves[0];
  15867. break;
  15868. case "Z":
  15869. sids[splittarget[0]].animations[2]=animcurves[0];
  15870. break;
  15871. case "ANGLE":
  15872. sids[splittarget[0]].animations[3]=animcurves[0];
  15873. break;
  15874. }
  15875. }else if(target[1].indexOf("(")!=-1){
  15876. //do bracket type
  15877. var idx=target[1].split("(");
  15878. sidtarget=idx.shift();
  15879. if(idx.length>1) idx=parseInt(idx[0])+4*parseInt(idx[1]);
  15880. else idx=parseInt(idx[0]);
  15881. sids[sidtarget].animations[idx]=animcurves[0];
  15882. }else{
  15883. //do all
  15884. for(var j=0;j<animcurves.length;j++){
  15885. switch(animcurves[j].name){
  15886. case "X":
  15887. sids[target[1]].animations[0]=animcurves[j];
  15888. break;
  15889. case "Y":
  15890. sids[target[1]].animations[1]=animcurves[j];
  15891. break;
  15892. case "Z":
  15893. sids[target[1]].animations[2]=animcurves[j];
  15894. break;
  15895. case "ANGLE":
  15896. sids[target[1]].animations[3]=animcurves[j];
  15897. break;
  15898. default:
  15899. sids[target[1]].animations[j]=animcurves[j];
  15900. break;
  15901. }
  15902. }
  15903. }
  15904. }
  15905. var animVector=new GLGE.AnimationVector();
  15906. animVector.setFrames(maxFrame);
  15907. var quatxcurve=new GLGE.AnimationCurve(); quatxcurve.setChannel("QuatX");
  15908. var quatycurve=new GLGE.AnimationCurve(); quatycurve.setChannel("QuatY");
  15909. var quatzcurve=new GLGE.AnimationCurve(); quatzcurve.setChannel("QuatZ");
  15910. var quatwcurve=new GLGE.AnimationCurve(); quatwcurve.setChannel("QuatW");
  15911. var locxcurve=new GLGE.AnimationCurve(); locxcurve.setChannel("LocX");
  15912. var locycurve=new GLGE.AnimationCurve(); locycurve.setChannel("LocY");
  15913. var loczcurve=new GLGE.AnimationCurve(); loczcurve.setChannel("LocZ");
  15914. var scalexcurve=new GLGE.AnimationCurve(); scalexcurve.setChannel("ScaleX");
  15915. var scaleycurve=new GLGE.AnimationCurve(); scaleycurve.setChannel("ScaleY");
  15916. var scalezcurve=new GLGE.AnimationCurve(); scalezcurve.setChannel("ScaleZ");
  15917. animVector.addAnimationCurve(quatxcurve);
  15918. animVector.addAnimationCurve(quatycurve);
  15919. animVector.addAnimationCurve(quatzcurve);
  15920. animVector.addAnimationCurve(quatwcurve);
  15921. animVector.addAnimationCurve(locxcurve);
  15922. animVector.addAnimationCurve(locycurve);
  15923. animVector.addAnimationCurve(loczcurve);
  15924. animVector.addAnimationCurve(scalexcurve);
  15925. animVector.addAnimationCurve(scaleycurve);
  15926. animVector.addAnimationCurve(scalezcurve);
  15927. var lastQuat=null;
  15928. for(var frame=0; frame<maxFrame;frame++){
  15929. var matrix=GLGE.identMatrix();
  15930. for(var i=0;i<transforms.length;i++){
  15931. //get full transform for this frame
  15932. switch(transforms[i].type){
  15933. case "matrix":
  15934. var matrix_array=[
  15935. (transforms[i].animations[0] ? transforms[i].animations[0].getValue(frame) : transforms[i].data[0]),
  15936. (transforms[i].animations[1] ? transforms[i].animations[1].getValue(frame) : transforms[i].data[1]),
  15937. (transforms[i].animations[2] ? transforms[i].animations[2].getValue(frame) : transforms[i].data[2]),
  15938. (transforms[i].animations[3] ? transforms[i].animations[3].getValue(frame) : transforms[i].data[3]),
  15939. (transforms[i].animations[4] ? transforms[i].animations[4].getValue(frame) : transforms[i].data[4]),
  15940. (transforms[i].animations[5] ? transforms[i].animations[5].getValue(frame) : transforms[i].data[5]),
  15941. (transforms[i].animations[6] ? transforms[i].animations[6].getValue(frame) : transforms[i].data[6]),
  15942. (transforms[i].animations[7] ? transforms[i].animations[7].getValue(frame) : transforms[i].data[7]),
  15943. (transforms[i].animations[8] ? transforms[i].animations[8].getValue(frame) : transforms[i].data[8]),
  15944. (transforms[i].animations[9] ? transforms[i].animations[9].getValue(frame) : transforms[i].data[9]),
  15945. (transforms[i].animations[10] ? transforms[i].animations[10].getValue(frame) : transforms[i].data[10]),
  15946. (transforms[i].animations[11] ? transforms[i].animations[11].getValue(frame) : transforms[i].data[11]),
  15947. (transforms[i].animations[12] ? transforms[i].animations[12].getValue(frame) : transforms[i].data[12]),
  15948. (transforms[i].animations[13] ? transforms[i].animations[13].getValue(frame) : transforms[i].data[13]),
  15949. (transforms[i].animations[14] ? transforms[i].animations[14].getValue(frame) : transforms[i].data[14]),
  15950. (transforms[i].animations[15] ? transforms[i].animations[15].getValue(frame) : transforms[i].data[15])
  15951. ];
  15952. matrix=GLGE.mulMat4(matrix,GLGE.Mat4(matrix_array));
  15953. break;
  15954. case "rotate":
  15955. var rotate_array=[
  15956. (transforms[i].animations[0] ? transforms[i].animations[0].getValue(frame) : transforms[i].data[0]),
  15957. (transforms[i].animations[1] ? transforms[i].animations[1].getValue(frame) : transforms[i].data[1]),
  15958. (transforms[i].animations[2] ? transforms[i].animations[2].getValue(frame) : transforms[i].data[2]),
  15959. (transforms[i].animations[3] ? transforms[i].animations[3].getValue(frame) : transforms[i].data[3])
  15960. ];
  15961. matrix=GLGE.mulMat4(matrix,GLGE.angleAxis(rotate_array[3]*0.017453278,[ rotate_array[0], rotate_array[1], rotate_array[2]]));
  15962. break;
  15963. case "translate":
  15964. var translate_array=[
  15965. (transforms[i].animations[0] ? transforms[i].animations[0].getValue(frame) : transforms[i].data[0]),
  15966. (transforms[i].animations[1] ? transforms[i].animations[1].getValue(frame) : transforms[i].data[1]),
  15967. (transforms[i].animations[2] ? transforms[i].animations[2].getValue(frame) : transforms[i].data[2])
  15968. ];
  15969. matrix=GLGE.mulMat4(matrix,GLGE.translateMatrix(translate_array[0],translate_array[1],translate_array[2]));
  15970. break;
  15971. case "scale":
  15972. var scale_array=[
  15973. (transforms[i].animations[0] ? transforms[i].animations[0].getValue(frame) : transforms[i].data[0]),
  15974. (transforms[i].animations[1] ? transforms[i].animations[1].getValue(frame) : transforms[i].data[1]),
  15975. (transforms[i].animations[2] ? transforms[i].animations[2].getValue(frame) : transforms[i].data[2])
  15976. ];
  15977. matrix=GLGE.mulMat4(matrix,GLGE.scaleMatrix(scale_array[0],scale_array[1],scale_array[2]));
  15978. break;
  15979. }
  15980. }
  15981. scale=GLGE.matrix2Scale(matrix);
  15982. matrix=GLGE.mulMat4(matrix,GLGE.scaleMatrix(1/scale[0],1/scale[1],1/scale[2]));
  15983. //convert to quat and trans and add to the curve
  15984. quat=GLGE.rotationMatrix2Quat(matrix);
  15985. if(lastQuat){
  15986. //make sure we are in the same range as previous!
  15987. if((lastQuat[0]*quat[0]+lastQuat[1]*quat[1]+lastQuat[2]*quat[2]+lastQuat[3]*quat[3])<0){
  15988. quat[0]=quat[0]*-1;
  15989. quat[1]=quat[1]*-1;
  15990. quat[2]=quat[2]*-1;
  15991. quat[3]=quat[3]*-1;
  15992. }
  15993. }
  15994. lastQuat=quat;
  15995. point=new GLGE.LinearPoint();
  15996. point.setX(frame);
  15997. point.setY(quat[0]);
  15998. quatxcurve.addPoint(point);
  15999. point=new GLGE.LinearPoint();
  16000. point.setX(frame);
  16001. point.setY(quat[1]);
  16002. quatycurve.addPoint(point);
  16003. point=new GLGE.LinearPoint();
  16004. point.setX(frame);
  16005. point.setY(quat[2]);
  16006. quatzcurve.addPoint(point);
  16007. point=new GLGE.LinearPoint();
  16008. point.setX(frame);
  16009. point.setY(quat[3]);
  16010. quatwcurve.addPoint(point);
  16011. point=new GLGE.LinearPoint();
  16012. point.setX(frame);
  16013. point.setY(matrix[3]);
  16014. locxcurve.addPoint(point);
  16015. point=new GLGE.LinearPoint();
  16016. point.setX(frame);
  16017. point.setY(matrix[7]);
  16018. locycurve.addPoint(point);
  16019. point=new GLGE.LinearPoint();
  16020. point.setX(frame);
  16021. point.setY(matrix[11]);
  16022. loczcurve.addPoint(point);
  16023. point=new GLGE.LinearPoint();
  16024. point.setX(frame);
  16025. point.setY(scale[0].toFixed(4));
  16026. scalexcurve.addPoint(point);
  16027. point=new GLGE.LinearPoint();
  16028. point.setX(frame);
  16029. point.setY(scale[1].toFixed(4));
  16030. scaleycurve.addPoint(point);
  16031. point=new GLGE.LinearPoint();
  16032. point.setX(frame);
  16033. point.setY(scale[2].toFixed(4));
  16034. scalezcurve.addPoint(point);
  16035. }
  16036. //return the animation vector
  16037. /*for(var i=0; i<targetNode.GLGEObjects.length;i++){
  16038. targetNode.GLGEObjects[i].setAnimation(animVector);
  16039. targetNode.GLGEObjects[i].animationStart=0;
  16040. targetNode.GLGEObjects[i].setFrameRate(30);
  16041. }*/
  16042. return animVector;
  16043. }
  16044. var actionCache={};
  16045. /**
  16046. * creates an action form the intially animation within the document
  16047. * @private
  16048. */
  16049. GLGE.Collada.prototype.getAnimations=function(){
  16050. if(actionCache[this.url]){
  16051. this.actions=actionCache[this.url];
  16052. }else{
  16053. var animationClips=this.xml.getElementsByTagName("animation_clip");
  16054. var animations=this.xml.getElementsByTagName("animation");
  16055. if(animationClips.length==0){
  16056. animations.name="default";
  16057. var clips=[animations];
  16058. }else{
  16059. var clips=[];
  16060. for(var i=0;i<animationClips.length;i++){
  16061. var anim=[];
  16062. var instances=animationClips[i].getElementsByTagName("instance_animation");
  16063. for(var j=0;j<instances.length;j++){
  16064. anim.push(this.xml.getElementById(instances[j].getAttribute("url").substr(1)));
  16065. }
  16066. anim.name=animationClips[i].getAttribute("id");
  16067. clips.push(anim);
  16068. }
  16069. }
  16070. for(var k=0;k<clips.length;k++){
  16071. var animations=clips[k];
  16072. var channels,target,source;
  16073. var channelGroups={};
  16074. for(var i=0;i<animations.length;i++){
  16075. channels=animations[i].getElementsByTagName("channel");
  16076. for(var j=0;j<channels.length;j++){
  16077. var target=channels[j].getAttribute("target").split("/");
  16078. source=channels[j].getAttribute("source").substr(1);
  16079. if(!channelGroups[target[0]]) channelGroups[target[0]]=[];
  16080. channelGroups[target[0]].push({source:source,target:target});
  16081. }
  16082. }
  16083. var action=new GLGE.Action();
  16084. for(var target in channelGroups){
  16085. var animVector=this.getAnimationVector(channelGroups[target]);
  16086. var targetNode=this.xml.getElementById(target);
  16087. //blender 2.5a bug work round
  16088. if(!targetNode){
  16089. target=target.substring(target.indexOf("_")+1);
  16090. targetNode=this.xml.getElementById(target);
  16091. }
  16092. if(!targetNode){
  16093. target=target.substring(target.indexOf("_")+1);
  16094. targetNode=this.xml.getElementById(target);
  16095. }
  16096. //end work round
  16097. for(var i=0; i<targetNode.GLGEObjects.length;i++){
  16098. var ac=new GLGE.ActionChannel();
  16099. var name=targetNode.GLGEObjects[i].getName();
  16100. ac.setTarget(name);
  16101. ac.setAnimation(animVector);
  16102. action.addActionChannel(ac);
  16103. }
  16104. }
  16105. this.addColladaAction({name:animations.name,action:action});
  16106. }
  16107. }
  16108. actionCache[this.url]=this.actions;
  16109. for(var n in this.actions) {this.setAction(this.actions[n],0,true);break}
  16110. }
  16111. /**
  16112. * Adds a collada action
  16113. * @param {object} action object hold action info
  16114. * @private
  16115. */
  16116. GLGE.Collada.prototype.addColladaAction=function(action){
  16117. this.actions[action.name]=action.action;
  16118. }
  16119. /**
  16120. * Gets the available actions from the collada file
  16121. * @returns {object} all the available actions within the collada file
  16122. */
  16123. GLGE.Collada.prototype.getColladaActions=function(){
  16124. return this.actions;
  16125. }
  16126. /**
  16127. * creates a GLGE Object from a given instance controler
  16128. * @param {node} node the element to parse
  16129. * @private
  16130. */
  16131. GLGE.Collada.prototype.getInstanceController=function(node){
  16132. var obj=new GLGE.Object();
  16133. if ( !obj.name || obj.name == "" ) {
  16134. obj.name = "glgeObj" + ( ++this.objIdx );
  16135. }
  16136. var controller=this.xml.getElementById(node.getAttribute("url").substr(1));
  16137. var skeletons=node.getElementsByTagName("skeleton");
  16138. var joints=controller.getElementsByTagName("joints")[0];
  16139. var inputs=joints.getElementsByTagName("input");
  16140. var bindShapeMatrix;
  16141. if(controller.getElementsByTagName("bind_shape_matrix").length>0){
  16142. bindShapeMatrix=this.parseArray(controller.getElementsByTagName("bind_shape_matrix")[0]);
  16143. }else{
  16144. //assume identity
  16145. bindShapeMatrix=GLGE.identMatrix();
  16146. }
  16147. var inverseBindMatrix=[bindShapeMatrix];
  16148. var base=this.newGroup( undefined );
  16149. this.addGroup(base);
  16150. var joints=[base];
  16151. var mat;
  16152. for(var i=0; i<inputs.length;i++){
  16153. if(inputs[i].getAttribute("semantic")=="JOINT"){
  16154. var jointdata=this.getSource(inputs[i].getAttribute("source").substr(1));
  16155. if(jointdata.type=="IDREF_array"){
  16156. var all_items_incorrect=(jointdata.array.length!=0);
  16157. for(var k=0;k<jointdata.array.length;k=k+jointdata.stride){
  16158. var curNode=this.getNode(this.xml.getElementById(jointdata.array[k]),true);
  16159. var name=curNode.getName();
  16160. if (!this.xml.getElementById(jointdata.array[k])) {
  16161. GLGE.error("Bone is not specified "+jointdata.array[k]);
  16162. inverseBindMatrix=[bindShapeMatrix=GLGE.identMatrix()];
  16163. }else all_items_incorrect=false;
  16164. joints.push(name);
  16165. }
  16166. if (all_items_incorrect)
  16167. inverseBindMatrix=[bindShapeMatrix=GLGE.identMatrix()];
  16168. }else if(jointdata.type=="Name_array"){
  16169. var sidArray={};
  16170. var sid,name;
  16171. //is this right controller with no skeleton set, export bug??
  16172. if(skeletons.length==0){
  16173. var elements=this.xml.getElementsByTagName("node");
  16174. for(k=0; k<elements.length;k++){
  16175. sid=elements[k].getAttribute("sid");
  16176. if(sid){
  16177. sidArray[sid]=elements[k];
  16178. }
  16179. name=elements[k].getAttribute("name");
  16180. if(name && !sidArray[name]){
  16181. sidArray[name]=elements[k];
  16182. }
  16183. }
  16184. }else{
  16185. for(var n=0; n<skeletons.length;n++){
  16186. var skeletonElement=this.xml.getElementById(skeletons[n].firstChild.nodeValue.substr(1));
  16187. sid=skeletonElement.getAttribute("sid");
  16188. if(sid) sidArray[sid]=skeletonElement;
  16189. var elements=skeletonElement.getElementsByTagName("*");
  16190. for(k=0; k<elements.length;k++){
  16191. sid=elements[k].getAttribute("sid");
  16192. if(sid){
  16193. sidArray[sid]=elements[k];
  16194. }
  16195. name=elements[k].getAttribute("name");
  16196. if(name && !sidArray[name]){
  16197. sidArray[name]=elements[k];
  16198. }
  16199. }
  16200. }
  16201. }
  16202. for(var k=0;k<jointdata.array.length;k=k+jointdata.stride){
  16203. if(jointdata.array[k]!=""){
  16204. var name=this.getNode(sidArray[jointdata.array[k]],true).getName();
  16205. joints.push(name);
  16206. }
  16207. }
  16208. }
  16209. }
  16210. }
  16211. for(var i=0; i<inputs.length;i++){
  16212. //TODO: sort out correct use of accessors for these source
  16213. if(inputs[i].getAttribute("semantic")=="INV_BIND_MATRIX"){
  16214. var matrixdata=this.getSource(inputs[i].getAttribute("source").substr(1));
  16215. for(var k=0;k<matrixdata.array.length;k=k+matrixdata.stride){
  16216. mat=matrixdata.array.slice(k,k+16);
  16217. inverseBindMatrix.push(GLGE.mulMat4(GLGE.Mat4(mat),GLGE.Mat4(bindShapeMatrix.slice(0,16))));
  16218. }
  16219. }
  16220. }
  16221. //go though the inputs to get the data layout
  16222. var vertexWeight=controller.getElementsByTagName("vertex_weights")[0];
  16223. inputs=vertexWeight.getElementsByTagName("input");
  16224. var inputArray=[];
  16225. var outputData={};
  16226. for(var n=0;n<inputs.length;n++){
  16227. block=inputs[n].getAttribute("semantic");
  16228. inputs[n].data=this.getSource(inputs[n].getAttribute("source").substr(1));
  16229. inputs[n].block=block;
  16230. outputData[block]=[];
  16231. var offset=inputs[n].getAttribute("offset");
  16232. if (!inputArray[offset])
  16233. inputArray[offset]=[];//may be more than 1 input per offset -DRH
  16234. inputArray[offset].push(inputs[n]);
  16235. }
  16236. var vcounts=this.parseArray(vertexWeight.getElementsByTagName("vcount")[0]);
  16237. var vs=this.parseArray(vertexWeight.getElementsByTagName("v")[0]);
  16238. //find the maximum vcount
  16239. var maxJoints=0;
  16240. for(var i=0; i<vcounts.length;i++) if(vcounts[i]) maxJoints=Math.max(maxJoints,parseInt(vcounts[i]));
  16241. vPointer=0;
  16242. var block;
  16243. for(var i=0; i<vcounts.length;i++){
  16244. for(var j=0; j<vcounts[i];j++){
  16245. for(var k=0; k<inputArray.length;k++){
  16246. for (var ksub=0; ksub < inputArray[k].length; ++ksub) {
  16247. block=inputArray[k][ksub].block;
  16248. for(n=0;n<inputArray[k][ksub].data.stride;n++){
  16249. if(inputArray[k][ksub].data.pmask[n]){
  16250. if(block!="JOINT"){
  16251. outputData[block].push(inputArray[k][ksub].data.array[parseInt(vs[vPointer])+parseInt(inputArray[k][ksub].data.offset)]);
  16252. }else{
  16253. outputData[block].push(parseInt(vs[vPointer]));
  16254. }
  16255. vPointer++;
  16256. }
  16257. }
  16258. }
  16259. }
  16260. }
  16261. //pad out the remaining data
  16262. for(j=j; j<maxJoints;j++){
  16263. for(var k=0; k<inputArray.length;k++){
  16264. for (var ksub=0; ksub < inputArray[k].length; ++ksub) {
  16265. block=inputArray[k][ksub].block;
  16266. outputData[block].push(0);
  16267. }
  16268. }
  16269. }
  16270. }
  16271. if(!this.badAccessor && outputData["JOINT"].length==0){
  16272. this.badAccessor=true;
  16273. return this.getInstanceController(node);
  16274. }
  16275. for(var i=0;i<outputData["JOINT"].length;i++){
  16276. outputData["JOINT"][i]++;
  16277. }
  16278. //blender fix
  16279. if(this.exceptions.negjoints){
  16280. for(var i=0;i<outputData["JOINT"].length;i++){
  16281. if(outputData["JOINT"][i]==0){
  16282. outputData["WEIGHT"][i]=0;
  16283. }
  16284. }
  16285. }
  16286. var skeletonData={vertexJoints:outputData["JOINT"],vertexWeight:outputData["WEIGHT"],joints:joints,inverseBindMatrix:inverseBindMatrix,count:maxJoints};
  16287. var meshes=this.getMeshes(controller.getElementsByTagName("skin")[0].getAttribute("source").substr(1),skeletonData);
  16288. this.setMaterialOntoMesh(meshes,node);
  16289. return node.GLGEObj;
  16290. };
  16291. /**
  16292. * creates a GLGE lights from a given instance light
  16293. * @param {node} node the element to parse
  16294. * @private
  16295. */
  16296. GLGE.Collada.prototype.getInstanceLight=function(node){
  16297. var type=node.getElementsByTagName("technique_common")[0].getElementsByTagName("*")[0];
  16298. var light=new GLGE.Light;
  16299. var color=type.getElementsByTagName("color");
  16300. if(color.length>0){
  16301. var colors=color[0].firstChild.nodeValue.split(" ");
  16302. var c="rgb("+((colors[0]*255)|0)+","+((colors[1]*255)|0)+","+((colors[2]*255)|0)+")";
  16303. light.setColor(c);
  16304. }
  16305. switch (type.tagName) {
  16306. // JHD
  16307. case "point":
  16308. light.setType(GLGE.L_POINT);
  16309. case "spot":
  16310. // JHD - End
  16311. var ca = type.getElementsByTagName("constant_attenuation");
  16312. if (ca.length > 0)
  16313. light.setAttenuationConstant(parseFloat(ca[0].firstChild.nodeValue));
  16314. var la = type.getElementsByTagName("linear_attenuation");
  16315. if (la.length > 0)
  16316. light.setAttenuationLinear(parseFloat(la[0].firstChild.nodeValue));
  16317. var qa = type.getElementsByTagName("quadratic_attenuation");
  16318. if (qa.length > 0)
  16319. light.setAttenuationQuadratic(parseFloat(qa[0].firstChild.nodeValue));
  16320. // JHD
  16321. if (type.tagName == "spot") {
  16322. light.setType(GLGE.L_SPOT);
  16323. } else {
  16324. break;
  16325. }
  16326. // case "spot":
  16327. // JHD - End
  16328. var se = type.getElementsByTagName("falloff_exponent");
  16329. if (se.length > 0) {
  16330. var exp = parseFloat(se[0].firstChild.nodeValue);
  16331. if (exp < 1.0001)
  16332. exp *= 128; // if less then one then assume they
  16333. // are using 0-1 so convert to 0-128
  16334. light.setSpotExponent(exp);
  16335. }
  16336. var fa = type.getElementsByTagName("falloff_angle");
  16337. if (fa.length > 0)
  16338. light.setSpotCosCutOff(Math.cos(parseFloat(fa[0].firstChild.nodeValue) / 180
  16339. * Math.PI));
  16340. break;
  16341. }
  16342. return light;
  16343. }
  16344. GLGE.Collada.prototype.newGroup=function( node ){
  16345. var newGroup = new GLGE.Group();
  16346. var name="bone"+(++this.boneIdx);
  16347. newGroup.setName(name);
  16348. if ( node ) {
  16349. newGroup.colladaId = node.getAttribute( "id" );
  16350. newGroup.colladaName = node.getAttribute( "name" );
  16351. }
  16352. return newGroup;
  16353. }
  16354. // JHD
  16355. /**
  16356. * Creates a new group and parses it's children
  16357. * @param {DOM Element} node the element to parse
  16358. * @param {boolean} ref should this just get a reference for later addition
  16359. * @private
  16360. */
  16361. GLGE.Collada.prototype.addColladaCamera = function(object) {
  16362. object.matrix = null; // Clear any cache
  16363. object.parent = this;
  16364. this.children.push(object);
  16365. this.hasCamera = true;
  16366. return this;
  16367. }
  16368. // JHD - End
  16369. /**
  16370. * Creates a new group and parses it's children
  16371. * @param {DOM Element} node the element to parse
  16372. * @param {boolean} ref should this just get a reference for later addition
  16373. * @private
  16374. */
  16375. GLGE.Collada.prototype.getNode=function(node,ref){
  16376. //if a reference has previously been created then add it now
  16377. if(!ref && node.GLGEObject){
  16378. newGroup=node.GLGEObject;
  16379. delete(this.GLGEObject);
  16380. return newGroup;
  16381. }
  16382. //if a reference is requested a the node previously created then return here
  16383. if(ref && node && node.GLGEObjects){
  16384. return node.GLGEObjects[0];
  16385. }
  16386. var newGroup = this.newGroup( node );
  16387. var name="bone"+(++this.boneIdx);
  16388. newGroup.setName(name);
  16389. if (!node) {
  16390. return newGroup;
  16391. }
  16392. if(!node.GLGEObjects) node.GLGEObjects=[];
  16393. node.GLGEObjects.push(newGroup); //map Collada DOM to GLGE
  16394. var child=node.firstChild;
  16395. var matrix=GLGE.identMatrix();
  16396. var data;
  16397. if(child) do{
  16398. switch(child.tagName){
  16399. case "node":
  16400. newGroup.addGroup(this.getNode(child));
  16401. break;
  16402. case "instance_node":
  16403. newGroup.addGroup(this.getNode(this.xml.getElementById(child.getAttribute("url").substr(1))));
  16404. break;
  16405. case "instance_visual_scene":
  16406. newGroup.addGroup(this.getNode(this.xml.getElementById(child.getAttribute("url").substr(1))));
  16407. break;
  16408. case "instance_light":
  16409. if(this.useLights) newGroup.addLight(this.getInstanceLight(this.xml.getElementById(child.getAttribute("url").substr(1))));
  16410. break;
  16411. case "instance_geometry":
  16412. newGroup.addObject(this.getInstanceGeometry(child));
  16413. break;
  16414. case "instance_controller":
  16415. newGroup.addObject(this.getInstanceController(child));
  16416. break;
  16417. // JHD
  16418. case "instance_camera":
  16419. if(!this.useCamera) break;
  16420. newGroup.addColladaCamera(this.getNode(this.xml.getElementById(child.getAttribute("url").substr(1))));
  16421. break;
  16422. case "optics":
  16423. if(!this.useCamera) break;
  16424. var opticChild = child.getElementsByTagName("technique_common");
  16425. if (opticChild && opticChild.length > 0) {
  16426. opticChild = opticChild[0].getElementsByTagName("perspective");
  16427. if (opticChild && opticChild.length > 0) {
  16428. var yFov = opticChild[0].getElementsByTagName("yfov");
  16429. if (yFov && yFov.length > 0) {
  16430. newGroup.yFov = parseFloat(yFov[0].textContent);
  16431. }
  16432. var zNear = opticChild[0].getElementsByTagName("znear");
  16433. if (zNear && zNear.length > 0) {
  16434. newGroup.zNear = parseFloat(zNear[0].textContent);
  16435. }
  16436. var zFar = opticChild[0].getElementsByTagName("zfar");
  16437. if (zFar && zFar.length > 0) {
  16438. newGroup.zFar = parseFloat(zFar[0].textContent);
  16439. }
  16440. }
  16441. }
  16442. break;
  16443. // JHD - End
  16444. case "matrix":
  16445. matrix=this.parseArray(child);
  16446. break;
  16447. case "translate":
  16448. data=this.parseArray(child);
  16449. matrix=GLGE.mulMat4(matrix,GLGE.translateMatrix(data[0],data[1],data[2]));
  16450. break;
  16451. case "rotate":
  16452. data=this.parseArray(child);
  16453. matrix=GLGE.mulMat4(matrix,GLGE.angleAxis(data[3]*0.017453278,[data[0],data[1],data[2]]));
  16454. break;
  16455. case "scale":
  16456. data=this.parseArray(child);
  16457. matrix=GLGE.mulMat4(matrix,GLGE.scaleMatrix(data[0],data[1],data[2]));
  16458. break;
  16459. }
  16460. }while(child=child.nextSibling);
  16461. newGroup.setLoc(matrix[3],matrix[7],matrix[11]);
  16462. var mat=GLGE.Mat4([matrix[0], matrix[1], matrix[2], 0,
  16463. matrix[4], matrix[5], matrix[6], 0,
  16464. matrix[8], matrix[9], matrix[10], 0,
  16465. 0, 0, 0, 1]);
  16466. newGroup.setRotMatrix(mat);
  16467. if(ref) node.GLGEObject=newGroup;
  16468. return newGroup;
  16469. };
  16470. /**
  16471. * Initializes the Object/Scene when the collada document has been loaded
  16472. * @private
  16473. */
  16474. GLGE.Collada.prototype.initVisualScene=function(){
  16475. var metadata=this.xml.getElementsByTagName("asset");
  16476. var up_axis="Z_UP";
  16477. var app_up_axis = "Z_UP";
  16478. if(metadata.length) {
  16479. var up_axis_node=metadata[0].getElementsByTagName("up_axis");
  16480. if (up_axis_node.length) {
  16481. up_axis_node=up_axis_node[0];
  16482. var cur_axis=up_axis_node.firstChild.nodeValue;
  16483. if (cur_axis.length)
  16484. up_axis=cur_axis;
  16485. }
  16486. }
  16487. var transformRoot=this;
  16488. if ( app_up_axis == "Z_UP" ) {
  16489. switch ( up_axis[0] ) {
  16490. case "Z":
  16491. case "z":
  16492. // do nothing
  16493. break;
  16494. case "Y":
  16495. case "y":
  16496. transformRoot = this.newGroup( undefined );
  16497. this.addChild( transformRoot );
  16498. transformRoot.setRotMatrix( GLGE.Mat4(
  16499. [1, 0, 0, 0,
  16500. 0, 0, -1, 0,
  16501. 0, 1, 0, 0,
  16502. 0, 0, 0, 1] ));
  16503. break;
  16504. case "X":
  16505. case "x":
  16506. break;
  16507. }
  16508. //{1,0,0,0,
  16509. //0,0,-1,0,
  16510. //0,1,0,"11":0,"12":0,
  16511. //"13":0,"14":0,"15":1,"length":16,"buffer":{"byteLength":64},"byteLength":64,"byteOffset":0}
  16512. } else {
  16513. if (up_axis[0]!="Y"&&up_axis[0]!="y") {
  16514. transformRoot = this.newGroup( undefined );
  16515. this.addChild(transformRoot);
  16516. if (up_axis[0]!="Z"&&up_axis[0]!="z") {
  16517. transformRoot.setRotMatrix(GLGE.Mat4([0, -1 , 0, 0,
  16518. 1, 0, 0, 0,
  16519. 0, 0, 1, 0,
  16520. 0, 0, 0, 1]));
  16521. }else {
  16522. transformRoot.setRotMatrix(GLGE.Mat4([1, 0 , 0, 0,
  16523. 0, 0, 1, 0,
  16524. 0, -1, 0, 0,
  16525. 0, 0, 0, 1]));
  16526. }
  16527. }
  16528. }
  16529. if(!this.rootId){
  16530. var scene=this.xml.getElementsByTagName("scene");
  16531. if(scene.length>0){
  16532. transformRoot.addGroup(this.getNode(scene[0]));
  16533. }else{
  16534. GLGE.error("Please indicate the asset to render in Collada Document"+this.url);
  16535. }
  16536. }else{
  16537. var root=this.xml.getElementById(this.rootId);
  16538. if(root){
  16539. transformRoot.addGroup(this.getNode(root));
  16540. }else{
  16541. GLGE.error("Asset "+this.rootId+" not found in document"+this.url);
  16542. }
  16543. }
  16544. if(this.useCamera){
  16545. // JHD
  16546. var tempCamera;
  16547. var findChild = function(root) {
  16548. if (root.hasCamera) {
  16549. tempCamera = root;
  16550. return;
  16551. }
  16552. if (!root.children) {
  16553. return;
  16554. }
  16555. for ( var i = 0; i < root.children.length && !tempCamera; i++) {
  16556. findChild(root.children[i]);
  16557. }
  16558. };
  16559. findChild(transformRoot);
  16560. if (tempCamera) {
  16561. pp = transformRoot.parent.parent;
  16562. pp.camera.locX = tempCamera.locX;
  16563. pp.camera.locY = tempCamera.locY;
  16564. pp.camera.locZ = tempCamera.locZ;
  16565. if (tempCamera.children && tempCamera.children.length > 0) {
  16566. var child = tempCamera.children[0];
  16567. if (child.yFov) {
  16568. pp.camera.fovy = child.yFov;
  16569. pp.camera.pMatrix = null;
  16570. }
  16571. // TODO: Does this really get applied into WebGL states?
  16572. if (child.zNear) {
  16573. pp.camera.near = child.zNear;
  16574. }
  16575. if (child.zFar) {
  16576. pp.camera.far = child.zFar;
  16577. }
  16578. }
  16579. // Clear camera cache - The camera has, at this point, already been
  16580. // calculated!
  16581. pp.camera.matrix = null;
  16582. pp.camera.rotmatrix = tempCamera.rotmatrix;
  16583. pp.camera.lookAt = null;
  16584. }
  16585. // JHD - End
  16586. }
  16587. };
  16588. /**
  16589. * Exceptions for the bad exports out there, I'm sure there will be many more :-(
  16590. */
  16591. var exceptions={
  16592. "default":{},
  16593. "COLLADA Mixamo exporter":{badAccessor:true},
  16594. "FBX COLLADA exporter":{badAccessor:true},
  16595. "Blender2.5":{flipangle:true,negjoints:true}
  16596. }
  16597. GLGE.Collada.prototype.getExceptions=function(){
  16598. if(this.xml.getElementsByTagName("authoring_tool").length>0 && this.xml.getElementsByTagName("authoring_tool")[0].firstChild.nodeValue=="COLLADA Mixamo exporter"){
  16599. return exceptions["COLLADA Mixamo exporter"];
  16600. }
  16601. if(this.xml.getElementsByTagName("authoring_tool").length>0 && this.xml.getElementsByTagName("authoring_tool")[0].firstChild.nodeValue=="FBX COLLADA exporter"){
  16602. return exceptions["FBX COLLADA exporter"];
  16603. }
  16604. if(this.xml.getElementsByTagName("authoring_tool").length>0 && /Blender 2.5/.test(this.xml.getElementsByTagName("authoring_tool")[0].firstChild.nodeValue)){
  16605. return exceptions["Blender2.5"];
  16606. }
  16607. }
  16608. /**
  16609. * Called when a collada document has is loaded
  16610. * @param {string} url the url of the loaded document
  16611. * @param {DOM Document} xml the xml document
  16612. * @private
  16613. */
  16614. GLGE.Collada.prototype.loaded=function(url,xml){
  16615. this.xml=xml;
  16616. if(xml.getElementsByTagName("authoring_tool").length>0) this.exceptions=exceptions[xml.getElementsByTagName("authoring_tool")[0].firstChild.nodeValue];
  16617. this.exceptions=this.getExceptions();
  16618. if(!this.exceptions) this.exceptions=exceptions['default'];
  16619. /// FIXME -- I used to have some try/catches going on here to avoid silent fails
  16620. this.initVisualScene();
  16621. this.getAnimations();
  16622. if (this.loadedCallback) {
  16623. this.loadedCallback(this);
  16624. }
  16625. //WTF firefox gets here too soon????
  16626. var collada=this;
  16627. setTimeout(function(){
  16628. collada.fireEvent("loaded",{url:this.url});
  16629. if(collada.isComplete()) collada.fireEvent("downloadComplete",{});
  16630. },1);
  16631. };
  16632. GLGE.Scene.prototype.addCollada=GLGE.Scene.prototype.addGroup;
  16633. GLGE.Group.prototype.addCollada=GLGE.Group.prototype.addGroup;
  16634. if(GLGE.Document){
  16635. /**
  16636. * Parses the dom element and creates a collada object
  16637. * @param {domelement} ele the element to create the objects from
  16638. * @private
  16639. */
  16640. GLGE.Document.prototype.getCollada=function(ele){
  16641. if(!ele.object){
  16642. ele.object=new GLGE[this.classString(ele.tagName)]();
  16643. ele.object.setDocument(ele.getAttribute("document"),this.getAbsolutePath(this.rootURL,null));
  16644. ele.removeAttribute("document");
  16645. this.setProperties(ele);
  16646. }
  16647. return ele.object;
  16648. }
  16649. }
  16650. })(GLGE);
  16651. /*
  16652. GLGE WebGL Graphics Engine
  16653. Copyright (c) 2010, Paul Brunt
  16654. All rights reserved.
  16655. Redistribution and use in source and binary forms, with or without
  16656. modification, are permitted provided that the following conditions are met:
  16657. * Redistributions of source code must retain the above copyright
  16658. notice, this list of conditions and the following disclaimer.
  16659. * Redistributions in binary form must reproduce the above copyright
  16660. notice, this list of conditions and the following disclaimer in the
  16661. documentation and/or other materials provided with the distribution.
  16662. * Neither the name of GLGE nor the
  16663. names of its contributors may be used to endorse or promote products
  16664. derived from this software without specific prior written permission.
  16665. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  16666. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  16667. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  16668. DISCLAIMED. IN NO EVENT SHALL PAUL BRUNT BE LIABLE FOR ANY
  16669. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  16670. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  16671. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  16672. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  16673. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  16674. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  16675. */
  16676. /**
  16677. * @fileOverview
  16678. * @name glge_input.js
  16679. * @author me@paulbrunt.co.uk
  16680. */
  16681. if(!GLGE){
  16682. /**
  16683. * @namespace Holds the functionality of the library
  16684. */
  16685. var GLGE={};
  16686. }
  16687. (function(GLGE){
  16688. /**
  16689. * @class Creates a heightmap for a region of the world based on an image. Originally created as a quick and easy collision detection. At least until we have a better physics implementation.
  16690. * @deprecated not intended as a permanent addition
  16691. * @param {string} imageURL The url of the image to generate the hightmap for
  16692. * @param {number} imageWidth The width of the image
  16693. * @param {number} imageHeight The height of the image
  16694. * @param {number} x1 The lower X bound of the height map in world coords
  16695. * @param {number} x2 The upper X bound of the height map in world coords
  16696. * @param {number} y1 The lower Y bound of the height map in world coords
  16697. * @param {number} y2 The upper Y bound of the height map in world coords
  16698. * @param {number} z1 The lower Z bound of the height map in world coords
  16699. * @param {number} z2 The upper Z bound of the height map in world coords
  16700. */
  16701. GLGE.HeightMap = function(imageURL, imageWidth, imageHeight, x1, x2, y1, y2, z1, z2){
  16702. this.canvas = document.createElement("canvas");
  16703. this.context = this.canvas.getContext('2d');
  16704. this.canvas.width = imageWidth;
  16705. this.canvas.height = imageHeight;
  16706. this.minX = x1;
  16707. this.maxX = x2;
  16708. this.minY = y1;
  16709. this.maxY = y2;
  16710. this.minZ = z1;
  16711. this.maxZ = z2;
  16712. var image = new Image();
  16713. image.heightmap = this;
  16714. image.onload = function(e){
  16715. this.heightmap.context.drawImage(this, 0, 0);
  16716. this.heightmap.data = this.heightmap.context.getImageData(0, 0, this.heightmap.canvas.width, this.heightmap.canvas.height).data;
  16717. this.heightmap.minImgValue = this.heightmap.data[0];
  16718. this.heightmap.maxImgValue = this.heightmap.data[0];
  16719. for (i = 0; i < this.heightmap.data.length; i += 4) {
  16720. if (this.heightmap.data[i] < this.heightmap.minImgValue) {
  16721. this.heightmap.minImgValue = this.heightmap.data[i];
  16722. }
  16723. if (this.heightmap.data[i] > this.heightmap.maxImgValue) {
  16724. this.heightmap.maxImgValue = this.heightmap.data[i];
  16725. }
  16726. }
  16727. };
  16728. image.src = imageURL;
  16729. }
  16730. GLGE.HeightMap.prototype.canvas = null;
  16731. GLGE.HeightMap.prototype.context = null;
  16732. GLGE.HeightMap.prototype.minZ = null;
  16733. GLGE.HeightMap.prototype.maxZ = null;
  16734. GLGE.HeightMap.prototype.minY = null;
  16735. GLGE.HeightMap.prototype.maxY = null;
  16736. GLGE.HeightMap.prototype.minX = null;
  16737. GLGE.HeightMap.prototype.maxX = null;
  16738. GLGE.HeightMap.prototype.data = null;
  16739. /**
  16740. * Gets the pixel height at the specified image coords
  16741. * @param {number} x the x image coord
  16742. * @param {number} y the y image coord
  16743. * @private
  16744. */
  16745. GLGE.HeightMap.prototype.getPixelAt = function(x, y){
  16746. if (this.data) {
  16747. return (((this.data[(this.canvas.width * y + x) * 4]) - this.minImgValue) / (this.maxImgValue - this.minImgValue)) * (this.maxZ - this.minZ) + this.minZ;
  16748. }
  16749. else {
  16750. return 0;
  16751. }
  16752. }
  16753. /**
  16754. * Function to get he height as specified x, y world coords
  16755. * @param {number} x the x world coord
  16756. * @param {number} y the y world coord
  16757. * @returns {number} the height of the level in world units
  16758. */
  16759. GLGE.HeightMap.prototype.getHeightAt = function(x, y){
  16760. var retValue;
  16761. if (this.lastx != undefined && x == this.lastx && y == this.lasty) {
  16762. retValue = this.lastValue;
  16763. }
  16764. else {
  16765. var imgX = Math.round((x - this.minX) / (this.maxX - this.minX) * this.canvas.width);
  16766. var imgY = Math.round((y - this.minY) / (this.maxY - this.minY) * this.canvas.height);
  16767. retValue = this.getPixelAt(imgX, imgY);
  16768. this.lastValue = retValue;
  16769. }
  16770. this.lastx = x;
  16771. this.lasty = y;
  16772. return retValue;
  16773. }
  16774. /**
  16775. * @class Monitors keyboard input for use in render loops
  16776. */
  16777. GLGE.KeyInput=function(){
  16778. if(!document.keyStates) document.keyStates=[];
  16779. document.addEventListener("keydown",this.onKeyDown,false);
  16780. document.addEventListener("keyup",this.onKeyUp,false);
  16781. }
  16782. /**
  16783. * Tests if a key is pressed
  16784. * @param {number} the keycode to check
  16785. * @returns {boolean} key returns true if the key is being pressed
  16786. */
  16787. GLGE.KeyInput.prototype.isKeyPressed=function(key){
  16788. if(document.keyStates[key]) return true;
  16789. else return false;
  16790. };
  16791. var skiptimmer=null;
  16792. /**
  16793. * document keydown event used to monitor the key states
  16794. * @param {event} e the event being fired
  16795. * @private
  16796. */
  16797. GLGE.KeyInput.prototype.onKeyDown=function(e){
  16798. document.keyStates[e.keyCode]=true;
  16799. };
  16800. /**
  16801. * Document keyup event used to monitor the key states
  16802. * @param {event} e the event being fired
  16803. * @private
  16804. */
  16805. GLGE.KeyInput.prototype.onKeyUp=function(e){
  16806. document.keyStates[e.keyCode]=false;
  16807. };
  16808. /**
  16809. * @class Monitors mouse input for use in render loops
  16810. */
  16811. GLGE.MouseInput=function(element){
  16812. this.element=element;
  16813. this.element.mouseX=0;
  16814. this.element.mouseY=0;
  16815. if(!this.element.buttonState) this.element.buttonState=[];
  16816. element.addEventListener("mousemove",this.onMouseMove,false);
  16817. element.addEventListener("mousedown",this.onMouseDown,false);
  16818. element.addEventListener("mouseup",this.onMouseUp,false);
  16819. }
  16820. GLGE.MouseInput.prototype.element=null;
  16821. /**
  16822. * Elements mousemove event used to monitor the mouse states
  16823. * @param {event} e the event being fired
  16824. * @private
  16825. */
  16826. GLGE.MouseInput.prototype.onMouseMove=function(e){
  16827. this.mouseX=e.clientX;
  16828. this.mouseY=e.clientY;
  16829. }
  16830. /**
  16831. * Elements mousedown event used to monitor the mouse states
  16832. * @param {event} e the event being fired
  16833. * @private
  16834. */
  16835. GLGE.MouseInput.prototype.onMouseDown=function(e){
  16836. this.buttonState[e.button]=true;
  16837. }
  16838. /**
  16839. * Elements mouseup event used to monitor the mouse states
  16840. * @param {event} e the event being fired
  16841. * @private
  16842. */
  16843. GLGE.MouseInput.prototype.onMouseUp=function(e){
  16844. this.buttonState[e.button]=false;
  16845. }
  16846. /**
  16847. * Tests if a mouse button is pressed
  16848. * @param {number} button the button to check
  16849. * @returns {boolean} returns true if the button is being pressed
  16850. */
  16851. GLGE.MouseInput.prototype.isButtonDown=function(button){
  16852. if(this.element.buttonState[button]) return true;
  16853. else return false;
  16854. }
  16855. /**
  16856. * Gets the mouse coords
  16857. * @returns {object} the current mouse coors
  16858. */
  16859. GLGE.MouseInput.prototype.getMousePosition=function(){
  16860. return {x:this.element.mouseX,y:this.element.mouseY}
  16861. }
  16862. /**
  16863. * @constant
  16864. * @description Enumeration for the left mouse button
  16865. */
  16866. GLGE.MI_LEFT=0;
  16867. /**
  16868. * @constant
  16869. * @description Enumeration for the middle mouse button
  16870. */
  16871. GLGE.MI_MIDDLE=1;
  16872. /**
  16873. * @constant
  16874. * @description Enumeration for the right mouse button
  16875. */
  16876. GLGE.MI_RIGHT=2;
  16877. /**
  16878. * @constant
  16879. * @description Enumeration for the backspace key
  16880. */
  16881. GLGE.KI_BACKSPACE=8;
  16882. /**
  16883. * @constant
  16884. * @description Enumeration for the tab key
  16885. */
  16886. GLGE.KI_TAB=9;
  16887. /**
  16888. * @constant
  16889. * @description Enumeration for the enter key
  16890. */
  16891. GLGE.KI_ENTER=13;
  16892. /**
  16893. * @constant
  16894. * @description Enumeration for the shift key
  16895. */
  16896. GLGE.KI_SHIFT=16;
  16897. /**
  16898. * @constant
  16899. * @description Enumeration for the ctrl key
  16900. */
  16901. GLGE.KI_CTRL=17;
  16902. /**
  16903. * @constant
  16904. * @description Enumeration for the alt key
  16905. */
  16906. GLGE.KI_ALT=18;
  16907. /**
  16908. * @constant
  16909. * @description Enumeration for the pause/break key
  16910. */
  16911. GLGE.KI_PAUSE_BREAK=19;
  16912. /**
  16913. * @constant
  16914. * @description Enumeration for the caps lock key
  16915. */
  16916. GLGE.KI_CAPS_LOCK=20;
  16917. /**
  16918. * @constant
  16919. * @description Enumeration for the escape key
  16920. */
  16921. GLGE.KI_ESCAPE=27;
  16922. /**
  16923. * @constant
  16924. * @description Enumeration for the page up key
  16925. */
  16926. GLGE.KI_PAGE_UP=33;
  16927. /**
  16928. * @constant
  16929. * @description Enumeration for the page down key
  16930. */
  16931. GLGE.KI_PAGE_DOWN=34;
  16932. /**
  16933. * @constant
  16934. * @description Enumeration for the end key
  16935. */
  16936. GLGE.KI_END=35;
  16937. /**
  16938. * @constant
  16939. * @description Enumeration for the home key
  16940. */
  16941. GLGE.KI_HOME=36;
  16942. /**
  16943. * @constant
  16944. * @description Enumeration for the left arrow key
  16945. */
  16946. GLGE.KI_LEFT_ARROW=37;
  16947. /**
  16948. * @constant
  16949. * @description Enumeration for the up arrow key
  16950. */
  16951. GLGE.KI_UP_ARROW=38;
  16952. /**
  16953. * @constant
  16954. * @description Enumeration for the right arrow key
  16955. */
  16956. GLGE.KI_RIGHT_ARROW=39;
  16957. /**
  16958. * @constant
  16959. * @description Enumeration for the down arrow key
  16960. */
  16961. GLGE.KI_DOWN_ARROW=40;
  16962. /**
  16963. * @constant
  16964. * @description Enumeration for the insert key
  16965. */
  16966. GLGE.KI_INSERT=45;
  16967. /**
  16968. * @constant
  16969. * @description Enumeration for the delete key
  16970. */
  16971. GLGE.KI_DELETE=46;
  16972. /**
  16973. * @constant
  16974. * @description Enumeration for the 0 key
  16975. */
  16976. GLGE.KI_0=48;
  16977. /**
  16978. * @constant
  16979. * @description Enumeration for the 1 key
  16980. */
  16981. GLGE.KI_1=49;
  16982. /**
  16983. * @constant
  16984. * @description Enumeration for the 2 key
  16985. */
  16986. GLGE.KI_2=50;
  16987. /**
  16988. * @constant
  16989. * @description Enumeration for the 3 key
  16990. */
  16991. GLGE.KI_3=51;
  16992. /**
  16993. * @constant
  16994. * @description Enumeration for the 4 key
  16995. */
  16996. GLGE.KI_4=52;
  16997. /**
  16998. * @constant
  16999. * @description Enumeration for the 5 key
  17000. */
  17001. GLGE.KI_5=53;
  17002. /**
  17003. * @constant
  17004. * @description Enumeration for the 6 key
  17005. */
  17006. GLGE.KI_6=54;
  17007. /**
  17008. * @constant
  17009. * @description Enumeration for the 7 key
  17010. */
  17011. GLGE.KI_7=55;
  17012. /**
  17013. * @constant
  17014. * @description Enumeration for the 8 key
  17015. */
  17016. GLGE.KI_8=56;
  17017. /**
  17018. * @constant
  17019. * @description Enumeration for the 9 key
  17020. */
  17021. GLGE.KI_9=57;
  17022. /**
  17023. * @constant
  17024. * @description Enumeration for the a key
  17025. */
  17026. GLGE.KI_A=65;
  17027. /**
  17028. * @constant
  17029. * @description Enumeration for the b key
  17030. */
  17031. GLGE.KI_B=66;
  17032. /**
  17033. * @constant
  17034. * @description Enumeration for the c key
  17035. */
  17036. GLGE.KI_C=67;
  17037. /**
  17038. * @constant
  17039. * @description Enumeration for the d key
  17040. */
  17041. GLGE.KI_D=68;
  17042. /**
  17043. * @constant
  17044. * @description Enumeration for the e key
  17045. */
  17046. GLGE.KI_E=69;
  17047. /**
  17048. * @constant
  17049. * @description Enumeration for the f key
  17050. */
  17051. GLGE.KI_F=70;
  17052. /**
  17053. * @constant
  17054. * @description Enumeration for the g key
  17055. */
  17056. GLGE.KI_G=71;
  17057. /**
  17058. * @constant
  17059. * @description Enumeration for the h key
  17060. */
  17061. GLGE.KI_H=72;
  17062. /**
  17063. * @constant
  17064. * @description Enumeration for the i key
  17065. */
  17066. GLGE.KI_I=73;
  17067. /**
  17068. * @constant
  17069. * @description Enumeration for the j key
  17070. */
  17071. GLGE.KI_J=74;
  17072. /**
  17073. * @constant
  17074. * @description Enumeration for the k key
  17075. */
  17076. GLGE.KI_K=75;
  17077. /**
  17078. * @constant
  17079. * @description Enumeration for the l key
  17080. */
  17081. GLGE.KI_L=76;
  17082. /**
  17083. * @constant
  17084. * @description Enumeration for the m key
  17085. */
  17086. GLGE.KI_M=77;
  17087. /**
  17088. * @constant
  17089. * @description Enumeration for the n key
  17090. */
  17091. GLGE.KI_N=78;
  17092. /**
  17093. * @constant
  17094. * @description Enumeration for the o key
  17095. */
  17096. GLGE.KI_O=79;
  17097. /**
  17098. * @constant
  17099. * @description Enumeration for the p key
  17100. */
  17101. GLGE.KI_P=80;
  17102. /**
  17103. * @constant
  17104. * @description Enumeration for the q key
  17105. */
  17106. GLGE.KI_Q=81;
  17107. /**
  17108. * @constant
  17109. * @description Enumeration for the r key
  17110. */
  17111. GLGE.KI_R=82;
  17112. /**
  17113. * @constant
  17114. * @description Enumeration for the s key
  17115. */
  17116. GLGE.KI_S=83;
  17117. /**
  17118. * @constant
  17119. * @description Enumeration for the t key
  17120. */
  17121. GLGE.KI_T=84;
  17122. /**
  17123. * @constant
  17124. * @description Enumeration for the u key
  17125. */
  17126. GLGE.KI_U=85;
  17127. /**
  17128. * @constant
  17129. * @description Enumeration for the v key
  17130. */
  17131. GLGE.KI_V=86;
  17132. /**
  17133. * @constant
  17134. * @description Enumeration for the w key
  17135. */
  17136. GLGE.KI_W=87;
  17137. /**
  17138. * @constant
  17139. * @description Enumeration for the x key
  17140. */
  17141. GLGE.KI_X=88;
  17142. /**
  17143. * @constant
  17144. * @description Enumeration for the y key
  17145. */
  17146. GLGE.KI_Y=89;
  17147. /**
  17148. * @constant
  17149. * @description Enumeration for the z key
  17150. */
  17151. GLGE.KI_Z=90;
  17152. /**
  17153. * @constant
  17154. * @description Enumeration for the left window key key
  17155. */
  17156. GLGE.KI_LEFT_WINDOW_KEY=91;
  17157. /**
  17158. * @constant
  17159. * @description Enumeration for the right window key key
  17160. */
  17161. GLGE.KI_RIGHT_WINDOW_KEY=92;
  17162. /**
  17163. * @constant
  17164. * @description Enumeration for the select key key
  17165. */
  17166. GLGE.KI_SELECT_KEY=93;
  17167. /**
  17168. * @constant
  17169. * @description Enumeration for the numpad 0 key
  17170. */
  17171. GLGE.KI_NUMPAD_0=96;
  17172. /**
  17173. * @constant
  17174. * @description Enumeration for the numpad 1 key
  17175. */
  17176. GLGE.KI_NUMPAD_1=97;
  17177. /**
  17178. * @constant
  17179. * @description Enumeration for the numpad 2 key
  17180. */
  17181. GLGE.KI_NUMPAD_2=98;
  17182. /**
  17183. * @constant
  17184. * @description Enumeration for the numpad 3 key
  17185. */
  17186. GLGE.KI_NUMPAD_3=99;
  17187. /**
  17188. * @constant
  17189. * @description Enumeration for the numpad 4 key
  17190. */
  17191. GLGE.KI_NUMPAD_4=100;
  17192. /**
  17193. * @constant
  17194. * @description Enumeration for the numpad 5 key
  17195. */
  17196. GLGE.KI_NUMPAD_5=101;
  17197. /**
  17198. * @constant
  17199. * @description Enumeration for the numpad 6 key
  17200. */
  17201. GLGE.KI_NUMPAD_6=102;
  17202. /**
  17203. * @constant
  17204. * @description Enumeration for the numpad 7 key
  17205. */
  17206. GLGE.KI_NUMPAD_7=103;
  17207. /**
  17208. * @constant
  17209. * @description Enumeration for the numpad 8 key
  17210. */
  17211. GLGE.KI_NUMPAD_8=104;
  17212. /**
  17213. * @constant
  17214. * @description Enumeration for the numpad 9 key
  17215. */
  17216. GLGE.KI_NUMPAD_9=105;
  17217. /**
  17218. * @constant
  17219. * @description Enumeration for the multiply key
  17220. */
  17221. GLGE.KI_MULTIPLY=106;
  17222. /**
  17223. * @constant
  17224. * @description Enumeration for the add key
  17225. */
  17226. GLGE.KI_ADD=107;
  17227. /**
  17228. * @constant
  17229. * @description Enumeration for the subtract key
  17230. */
  17231. GLGE.KI_SUBTRACT=109;
  17232. /**
  17233. * @constant
  17234. * @description Enumeration for the decimal point key
  17235. */
  17236. GLGE.KI_DECIMAL_POINT=110;
  17237. /**
  17238. * @constant
  17239. * @description Enumeration for the divide key
  17240. */
  17241. GLGE.KI_DIVIDE=111;
  17242. /**
  17243. * @constant
  17244. * @description Enumeration for the f1 key
  17245. */
  17246. GLGE.KI_F1=112;
  17247. /**
  17248. * @constant
  17249. * @description Enumeration for the f2 key
  17250. */
  17251. GLGE.KI_F2=113;
  17252. /**
  17253. * @constant
  17254. * @description Enumeration for the f3 key
  17255. */
  17256. GLGE.KI_F3=114;
  17257. /**
  17258. * @constant
  17259. * @description Enumeration for the f4 key
  17260. */
  17261. GLGE.KI_F4=115;
  17262. /**
  17263. * @constant
  17264. * @description Enumeration for the f5 key
  17265. */
  17266. GLGE.KI_F5=116;
  17267. /**
  17268. * @constant
  17269. * @description Enumeration for the f6 key
  17270. */
  17271. GLGE.KI_F6=117;
  17272. /**
  17273. * @constant
  17274. * @description Enumeration for the f7 key
  17275. */
  17276. GLGE.KI_F7=118;
  17277. /**
  17278. * @constant
  17279. * @description Enumeration for the f8 key
  17280. */
  17281. GLGE.KI_F8=119;
  17282. /**
  17283. * @constant
  17284. * @description Enumeration for the f9 key
  17285. */
  17286. GLGE.KI_F9=120;
  17287. /**
  17288. * @constant
  17289. * @description Enumeration for the f10 key
  17290. */
  17291. GLGE.KI_F10=121;
  17292. /**
  17293. * @constant
  17294. * @description Enumeration for the f11 key
  17295. */
  17296. GLGE.KI_F11=122;
  17297. /**
  17298. * @constant
  17299. * @description Enumeration for the f12 key
  17300. */
  17301. GLGE.KI_F12=123;
  17302. /**
  17303. * @constant
  17304. * @description Enumeration for the num lock key
  17305. */
  17306. GLGE.KI_NUM_LOCK=144;
  17307. /**
  17308. * @constant
  17309. * @description Enumeration for the scroll lock key
  17310. */
  17311. GLGE.KI_SCROLL_LOCK=145;
  17312. /**
  17313. * @constant
  17314. * @description Enumeration for the semi-colon key
  17315. */
  17316. GLGE.KI_SEMI_COLON=186;
  17317. /**
  17318. * @constant
  17319. * @description Enumeration for the equal sign key
  17320. */
  17321. GLGE.KI_EQUAL_SIGN=187;
  17322. /**
  17323. * @constant
  17324. * @description Enumeration for the comma key
  17325. */
  17326. GLGE.KI_COMMA=188;
  17327. /**
  17328. * @constant
  17329. * @description Enumeration for the dash key
  17330. */
  17331. GLGE.KI_DASH=189;
  17332. /**
  17333. * @constant
  17334. * @description Enumeration for the period key
  17335. */
  17336. GLGE.KI_PERIOD=190;
  17337. /**
  17338. * @constant
  17339. * @description Enumeration for the forward slash key
  17340. */
  17341. GLGE.KI_FORWARD_SLASH=191;
  17342. /**
  17343. * @constant
  17344. * @description Enumeration for the grave accent key
  17345. */
  17346. GLGE.KI_GRAVE_ACCENT=192;
  17347. /**
  17348. * @constant
  17349. * @description Enumeration for the open bracket key
  17350. */
  17351. GLGE.KI_OPEN_BRACKET=219;
  17352. /**
  17353. * @constant
  17354. * @description Enumeration for the back slash key
  17355. */
  17356. GLGE.KI_BACK_SLASH=220;
  17357. /**
  17358. * @constant
  17359. * @description Enumeration for the close braket key
  17360. */
  17361. GLGE.KI_CLOSE_BRAKET=221;
  17362. /**
  17363. * @constant
  17364. * @description Enumeration for the single quote key
  17365. */
  17366. GLGE.KI_SINGLE_QUOTE=222;
  17367. /**
  17368. * @constant
  17369. * @description Enumeration for the space key
  17370. */
  17371. GLGE.KI_SPACE=32;
  17372. //code by @paul_irish
  17373. if ( !window.requestAnimationFrame ) {
  17374. window.requestAnimationFrame = ( function() {
  17375. return window.webkitRequestAnimationFrame ||
  17376. window.mozRequestAnimationFrame ||
  17377. window.oRequestAnimationFrame ||
  17378. window.msRequestAnimationFrame ||
  17379. function( /* function FrameRequestCallback */ callback, /* DOMElement Element */ element ) {
  17380. window.setTimeout( callback, 1000 / 60 );
  17381. };
  17382. } )();
  17383. }
  17384. })(GLGE);
  17385. /*
  17386. GLGE WebGL Graphics Engine
  17387. Copyright (c) 2010, Paul Brunt
  17388. All rights reserved.
  17389. Redistribution and use in source and binary forms, with or without
  17390. modification, are permitted provided that the following conditions are met:
  17391. * Redistributions of source code must retain the above copyright
  17392. notice, this list of conditions and the following disclaimer.
  17393. * Redistributions in binary form must reproduce the above copyright
  17394. notice, this list of conditions and the following disclaimer in the
  17395. documentation and/or other materials provided with the distribution.
  17396. * Neither the name of GLGE nor the
  17397. names of its contributors may be used to endorse or promote products
  17398. derived from this software without specific prior written permission.
  17399. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  17400. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  17401. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  17402. DISCLAIMED. IN NO EVENT SHALL PAUL BRUNT BE LIABLE FOR ANY
  17403. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  17404. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  17405. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  17406. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  17407. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  17408. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  17409. */
  17410. /**
  17411. * @fileOverview
  17412. * @name glge_wavefront.js
  17413. * @author me@paulbrunt.co.uk
  17414. */
  17415. (function(GLGE){
  17416. /**
  17417. * @class parses and displays a warefront object file with mtl material
  17418. * @param {string} uid the unique id for this object
  17419. * @augments GLGE.Object
  17420. */
  17421. GLGE.Wavefront=function(uid){
  17422. this.multimaterials=[];
  17423. this.materials={};
  17424. this.instances=[];
  17425. this.queue=[];
  17426. this.idMaterials = [];//storaged name of material (string)
  17427. GLGE.Object.call(this,uid);
  17428. GLGE.Assets.registerAsset(this,uid);
  17429. }
  17430. GLGE.augment(GLGE.Object,GLGE.Wavefront);
  17431. /**
  17432. * Gets the absolute path given an import path and the path it's relative to
  17433. * @param {string} path the path to get the absolute path for
  17434. * @param {string} relativeto the path the supplied path is relativeto
  17435. * @returns {string} absolute path
  17436. * @private
  17437. */
  17438. GLGE.Wavefront.prototype.getAbsolutePath=function(path,relativeto){
  17439. if(path.substr(0,7)=="http://" || path.substr(0,7)=="file://" || path.substr(0,7)=="https://"){
  17440. return path;
  17441. }
  17442. else
  17443. {
  17444. if(!relativeto){
  17445. relativeto=window.location.href;
  17446. }
  17447. if(relativeto.indexOf("?")>0){
  17448. relativeto=relativeto.substr(0,relativeto.indexOf("?"));
  17449. }
  17450. //find the path compoents
  17451. var bits=relativeto.split("/");
  17452. var domain=bits[2];
  17453. var proto=bits[0];
  17454. var initpath=[];
  17455. for(var i=3;i<bits.length-1;i++){
  17456. initpath.push(bits[i]);
  17457. }
  17458. //relative to domain
  17459. if(path.substr(0,1)=="/"){
  17460. initpath=[];
  17461. }
  17462. var locpath=path.split("/");
  17463. for(i=0;i<locpath.length;i++){
  17464. if(locpath[i]=="..") initpath.pop();
  17465. else if(locpath[i]!="") initpath.push(locpath[i]);
  17466. }
  17467. return proto+"//"+domain+"/"+initpath.join("/");
  17468. }
  17469. };
  17470. /**
  17471. * Loads a material file from a url
  17472. * @param {string} url the url of the material file
  17473. * @private
  17474. */
  17475. GLGE.Wavefront.prototype.loadMaterials=function(url){
  17476. if(!this.loading){
  17477. this.loadFile(url,null,function(url,text){
  17478. this.parseMaterials(text.split("\n"));
  17479. if(this.queue.length>0){
  17480. var matUrl=this.queue.pop();
  17481. this.loadMaterials(matUrl,this.src);
  17482. }else{
  17483. this.parseMesh();
  17484. this.fireEvent("loaded",{});
  17485. }
  17486. });
  17487. }else{
  17488. this.queue.push(url);
  17489. }
  17490. };
  17491. /**
  17492. * creates the GLGE materials from a mtl file
  17493. * @param {string} file the file to parse
  17494. * @private
  17495. */
  17496. GLGE.Wavefront.prototype.parseMaterials=function(file){
  17497. //loop though all lines and look for matlibs
  17498. var j = 0;
  17499. var i = 0;
  17500. var index = 0;
  17501. var idNameMaterial;
  17502. while(i<file.length)
  17503. {
  17504. //newmtl
  17505. if(file[i].substr(0,6)=="newmtl")
  17506. {
  17507. var data=file[i].replace(/^\s+|\s+$/g,"").replace(/\s+/g," ").split(" ");
  17508. var material=new GLGE.Material;
  17509. idNameMaterial = file[j].substr(7);
  17510. j=i+1;
  17511. while(file[j].substr(0,6) != "newmtl")
  17512. {
  17513. data=file[j].replace(/^\s+|\s+$/g,"").replace(/\s+/g," ").split(" ");
  17514. if(data.length>1)
  17515. {
  17516. switch(data[0]){
  17517. case "Kd":
  17518. material.setColorR(parseFloat(data[1]));
  17519. material.setColorG(parseFloat(data[2]));
  17520. material.setColorB(parseFloat(data[3]));
  17521. break;
  17522. case "Ks":
  17523. material.setSpecularColor({r:parseFloat(data[1]),g:parseFloat(data[2]),b:parseFloat(data[3])});
  17524. break;
  17525. case "Ns":
  17526. material.setShininess(parseFloat(data[1]));
  17527. break;
  17528. case "d":
  17529. this.setZtransparent(true);
  17530. material.setAlpha(parseFloat(data[1]));
  17531. break;
  17532. case "map_Kd":
  17533. var ml=new GLGE.MaterialLayer;
  17534. ml.setMapto(GLGE.M_COLOR);
  17535. ml.setMapinput(GLGE.UV1);
  17536. var tex=new GLGE.Texture();
  17537. var k=1;
  17538. while(data[k][0]=="-") k=k+2;
  17539. tex.setSrc(this.getAbsolutePath(data[k],this.relativeTo));
  17540. material.addTexture(tex);
  17541. ml.setTexture(tex);
  17542. material.addMaterialLayer(ml);
  17543. break;
  17544. case "map_Ks":
  17545. case "map_spec":
  17546. var ml=new GLGE.MaterialLayer;
  17547. ml.setMapto(GLGE.M_SPECULAR);
  17548. ml.setMapinput(GLGE.UV1);
  17549. var tex=new GLGE.Texture();
  17550. var k=1;
  17551. while(data[k][0]=="-") k=k+2;
  17552. tex.setSrc(this.getAbsolutePath(data[k],this.relativeTo));
  17553. material.addTexture(tex);
  17554. ml.setTexture(tex);
  17555. material.addMaterialLayer(ml);
  17556. break;
  17557. case "bump":
  17558. case "map_bump":
  17559. var ml=new GLGE.MaterialLayer;
  17560. ml.setMapto(GLGE.M_NOR);
  17561. ml.setMapinput(GLGE.UV1);
  17562. var tex=new GLGE.Texture();
  17563. var k=1;
  17564. while(data[k][0]=="-") k=k+2;
  17565. tex.setSrc(this.getAbsolutePath(data[k],this.relativeTo));
  17566. material.addTexture(tex);
  17567. ml.setTexture(tex);
  17568. material.addMaterialLayer(ml);
  17569. break;
  17570. }
  17571. }
  17572. j++;
  17573. if(j>=file.length)
  17574. break;
  17575. }
  17576. i=j-1;
  17577. this.materials[index]=material;
  17578. this.idMaterials.push(idNameMaterial);
  17579. index++;
  17580. }
  17581. i++;
  17582. }
  17583. };
  17584. /**
  17585. * loads a resource from a url
  17586. * @param {string} url the url of the resource to load
  17587. * @param {string} relativeTo the url to load relative to
  17588. * @param {function} callback thefunction to call once the file is loaded
  17589. * @private
  17590. */
  17591. GLGE.Wavefront.prototype.loadFile=function(url,relativeTo,callback){
  17592. this.loading=true;
  17593. if(!callback) callback=this.loaded;
  17594. if(!relativeTo && this.relativeTo) relativeTo=this.relativeTo;
  17595. url=this.getAbsolutePath(url,relativeTo);
  17596. if(!this.relativeTo) this.relativeTo=url;
  17597. var req = new XMLHttpRequest();
  17598. var that=this;
  17599. if(req) {
  17600. req.overrideMimeType("text/plain")
  17601. req.onreadystatechange = function() {
  17602. if(this.readyState == 4)
  17603. {
  17604. if(this.status == 200 || this.status==0){
  17605. that.loading=false;
  17606. callback.call(that,url,this.responseText);
  17607. }else{
  17608. GLGE.error("Error loading Document: "+url+" status "+this.status);
  17609. }
  17610. }
  17611. };
  17612. req.open("GET", url, true);
  17613. req.send("");
  17614. }
  17615. }
  17616. /**
  17617. * loads a wavefront ojvect from a given url
  17618. * @param {DOM Element} url the url to retrieve
  17619. * @param {string} relativeTo optional the path the url is relative to
  17620. */
  17621. GLGE.Wavefront.prototype.setSrc=function(url,relativeTo){
  17622. this.src=this.getAbsolutePath(url,relativeTo);
  17623. this.loadFile(this.src,relativeTo);
  17624. };
  17625. /**
  17626. * loads a resource from a url
  17627. * @param {string} url the url of the resource loaded
  17628. * @param {string} objfile the loaded file
  17629. * @private
  17630. */
  17631. GLGE.Wavefront.prototype.loaded=function(url,objfile){
  17632. this.file=objArray=objfile.split("\n");
  17633. var hasMaterial=false;
  17634. //loop through the file and load the Materials
  17635. for(var i=0;i<objArray.length;i++){
  17636. var data=objArray[i].split(" ");
  17637. if(data.length>1){
  17638. if(data[0]=="mtllib"){
  17639. hasMaterial=true;
  17640. this.loadMaterials(data[1]);
  17641. }
  17642. }
  17643. }
  17644. if(!hasMaterial){
  17645. this.parseMesh();
  17646. this.fireEvent("loaded",{});
  17647. }
  17648. };
  17649. /**
  17650. * creates a new multimaterial
  17651. * @private
  17652. */
  17653. GLGE.Wavefront.prototype.createMultiMaterial=function(idxDataOrig,verts,norms,texCoords,faces,material,smooth){
  17654. //loop though the indexes to produce streams
  17655. var positions=[];
  17656. var normals=[];
  17657. var uv=[];
  17658. var newfaces=[];
  17659. var idxData=[];
  17660. for(var i=0;i<faces.length;i++){
  17661. var data=idxDataOrig[faces[i]];
  17662. if(idxData.indexOf(data)==-1 || !smooth){
  17663. idxData.push(data);
  17664. newfaces.push(idxData.length-1);
  17665. }else{
  17666. newfaces.push(idxData.indexOf(data));
  17667. }
  17668. }
  17669. faces=newfaces;
  17670. for(i=0;i<idxData.length;i++){
  17671. if(idxData[i].indexOf("/")>0) var vertData=idxData[i].split("/");
  17672. else var vertData=[idxData[i]];
  17673. if(!verts[vertData[0]-1]) GLGE.error(vertData[0]);
  17674. positions.push(verts[vertData[0]-1][1]);
  17675. positions.push(verts[vertData[0]-1][2]);
  17676. positions.push(verts[vertData[0]-1][3]);
  17677. if(vertData[1]){
  17678. uv.push(texCoords[vertData[1]-1][1]);
  17679. uv.push(texCoords[vertData[1]-1][2]);
  17680. }
  17681. if(vertData[2]){
  17682. normals.push(norms[vertData[2]-1][1]);
  17683. normals.push(norms[vertData[2]-1][2]);
  17684. normals.push(norms[vertData[2]-1][3]);
  17685. }
  17686. }
  17687. var multiMat=new GLGE.MultiMaterial;
  17688. var mesh=new GLGE.Mesh;
  17689. mesh.setPositions(positions);
  17690. if(uv.length>0) mesh.setUV(uv);
  17691. if(normals.length>0) mesh.setNormals(normals);
  17692. mesh.setFaces(faces);
  17693. multiMat.setMesh(mesh);
  17694. multiMat.setMaterial(material);
  17695. this.addMultiMaterial(multiMat);
  17696. }
  17697. /**
  17698. * Parses the mesh
  17699. * @private
  17700. */
  17701. GLGE.Wavefront.prototype.parseMesh=function(){
  17702. objArray=this.file;
  17703. var texCoords=[];
  17704. var verts=[];
  17705. var norms=[];
  17706. var faces=[];
  17707. var idxData=[];
  17708. var vertoffset=0;
  17709. var smooth=true;
  17710. var material=new GLGE.Material;
  17711. for(var i=0;i<objArray.length;i++){
  17712. if(objArray[i][0]!="#"){
  17713. var data=objArray[i].replace(/^\s+|\s+$/g,"").replace(/\s+/g," ").split(" ");
  17714. if(data.length>0){
  17715. switch(data[0]){
  17716. case "s":
  17717. if(data[1]=="1") smooth=true;
  17718. else smooth=false;
  17719. case "o":
  17720. if(faces.length>0){
  17721. this.createMultiMaterial(idxData,verts,norms,texCoords,faces,material,smooth);
  17722. faces=[];
  17723. material=new GLGE.Material;
  17724. }
  17725. break;
  17726. case "usemtl":
  17727. if(faces.length>0){
  17728. this.createMultiMaterial(idxData,verts,norms,texCoords,faces,material,smooth);
  17729. faces=[];
  17730. }
  17731. if(this.idMaterials.indexOf(data[1]) == -1)//Material no name
  17732. material=this.materials[0];//default
  17733. else
  17734. material=this.materials[this.idMaterials.indexOf(data[1])];//get Idname material
  17735. break;
  17736. case "v":
  17737. verts.push(data);
  17738. break;
  17739. case "vt":
  17740. texCoords.push(data);
  17741. break;
  17742. case "vn":
  17743. norms.push(data);
  17744. break;
  17745. case "f":
  17746. var tmpface=[];
  17747. for(var j=1;j<data.length;j++){
  17748. var idx=idxData.indexOf(data[j]);
  17749. if(idx==-1 || !smooth){
  17750. idxData.push(data[j]);
  17751. idx=idxData.length-1;
  17752. }
  17753. tmpface.push(idx);
  17754. }
  17755. for(j=0;j<tmpface.length-2;j++){
  17756. faces.push(tmpface[0]-vertoffset);
  17757. faces.push(tmpface[1+j]-vertoffset);
  17758. faces.push(tmpface[2+j]-vertoffset);
  17759. }
  17760. break;
  17761. }
  17762. }
  17763. }
  17764. }
  17765. this.createMultiMaterial(idxData,verts,norms,texCoords,faces,material,smooth);
  17766. };
  17767. /**
  17768. * Parses the dom element and creates a texture
  17769. * @param {domelement} ele the element to create the objects from
  17770. * @private
  17771. */
  17772. GLGE.Document.prototype.getWavefront=function(ele){
  17773. if(!ele.object){
  17774. var rel=this.getAbsolutePath(this.rootURL,null);
  17775. ele.object=new GLGE[this.classString(ele.tagName)];
  17776. //ele.object.setSrc(this.getAbsolutePath(ele.getAttribute("src"),rel));
  17777. ele.object.setSrc(ele.getAttribute("src"),rel);
  17778. ele.removeAttribute("src");
  17779. this.setProperties(ele);
  17780. }
  17781. return ele.object;
  17782. }
  17783. })(GLGE);
  17784. /*
  17785. GLGE WebGL Graphics Engine
  17786. Copyright (c) 2011, Paul Brunt
  17787. All rights reserved.
  17788. Redistribution and use in source and binary forms, with or without
  17789. modification, are permitted provided that the following conditions are met:
  17790. * Redistributions of source code must retain the above copyright
  17791. notice, this list of conditions and the following disclaimer.
  17792. * Redistributions in binary form must reproduce the above copyright
  17793. notice, this list of conditions and the following disclaimer in the
  17794. documentation and/or other materials provided with the distribution.
  17795. * Neither the name of GLGE nor the
  17796. names of its contributors may be used to endorse or promote products
  17797. derived from this software without specific prior written permission.
  17798. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  17799. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  17800. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  17801. DISCLAIMED. IN NO EVENT SHALL PAUL BRUNT BE LIABLE FOR ANY
  17802. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  17803. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  17804. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  17805. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  17806. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  17807. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  17808. */
  17809. /**
  17810. * @fileOverview
  17811. * @name glge_physicsext.js
  17812. * @author me@paulbrunt.co.uk
  17813. */
  17814. (function(GLGE){
  17815. GLGE.Scene.prototype.physicsGravity=[0,0,-9.8,0];
  17816. /**
  17817. * retrives the phsyics assets from the scene
  17818. * @returns {array} the physics assets
  17819. */
  17820. GLGE.Scene.prototype.getPhysicsNodes=function(ret){
  17821. if(!ret) ret=[];
  17822. if(this.jigLibObj) ret.push(this);
  17823. if(this.children){
  17824. for(var i=0;i<this.children.length;i++){
  17825. GLGE.Scene.prototype.getPhysicsNodes.call(this.children[i],ret);
  17826. }
  17827. }
  17828. return ret;
  17829. }
  17830. /**
  17831. * Picks within the physics system
  17832. * @param {number} x screen x coord
  17833. * @param {number} y screen y coord
  17834. * @param {object} self optionally don't pick self
  17835. * @returns picking result
  17836. */
  17837. GLGE.Scene.prototype.physicsPick=function(x,y,self){
  17838. if(!this.physicsSystem) this.physicsTick(0,true); //make sure the physics is set up
  17839. var ray=this.makeRay(x,y);
  17840. if(!ray) return;
  17841. var cs=this.physicsSystem.getCollisionSystem();
  17842. var seg=new jigLib.JSegment(ray.origin,GLGE.scaleVec3(ray.coord,-1000));
  17843. var out={};
  17844. if(cs.segmentIntersect(out, seg, self ? self.jigLibObj : null)){
  17845. return {object:out.rigidBody.GLGE,normal:out.normal,distance:out.frac*1000,position:out.position};
  17846. }else{
  17847. return false;
  17848. }
  17849. }
  17850. /**
  17851. * Picks a single objectwithin the physics system
  17852. * @param {number} x screen x coord
  17853. * @param {number} y screen y coord
  17854. * @param {object} self the object to perform the pick on
  17855. * @returns picking result
  17856. */
  17857. GLGE.Scene.prototype.physicsPickObject=function(x,y,self){
  17858. if(!this.physicsSystem) this.physicsTick(0,true); //make sure the physics is set up
  17859. var ray=this.makeRay(x,y);
  17860. if(!ray) return;
  17861. var cs=self.jigLibObj;
  17862. var seg=new jigLib.JSegment(ray.origin,GLGE.scaleVec3(ray.coord,-1000));
  17863. var out={};
  17864. if(cs.segmentIntersect(out, seg)){
  17865. return {normal:out.normal,distance:out.frac*1000,position:out.position};
  17866. }else{
  17867. return false;
  17868. }
  17869. }
  17870. /**
  17871. * Does and intesection test on a given segment
  17872. * @param {array} start starting position of segment
  17873. * @param {array} delta the segment delta
  17874. * @returns segment test result object {object,normal,distance,position}
  17875. */
  17876. GLGE.Scene.prototype.segmentTest=function(start, delta,self){
  17877. if(!this.physicsSystem || !this.physicsSystem._collisionSystem) return false;
  17878. var seg=new jigLib.JSegment(start,delta);
  17879. var out={};
  17880. if(this.physicsSystem._collisionSystem.segmentIntersect(out,seg, self ? self.jigLibObj : null)){
  17881. var length=Math.sqrt(delta[0]*delta[0]+delta[1]*delta[1]+delta[2]*delta[2]);
  17882. return {object:out.rigidBody.GLGE,normal:out.normal,distance:out.frac*length,position:out.position};
  17883. }
  17884. return false
  17885. }
  17886. /**
  17887. * Integrate the phsyics system
  17888. * @param {number} dt the delta time to integrate for
  17889. */
  17890. GLGE.Scene.prototype.physicsTick=function(dt,noIntegrate){
  17891. var objects=this.getPhysicsNodes();
  17892. if(!this.physicsSystem){
  17893. //create the physics system
  17894. this.physicsSystem=jigLib.PhysicsSystem.getInstance();
  17895. //this.physicsSystem.setCollisionSystem(true,-1000,-1000,-1000,2000,1000,2000,1,1,1);
  17896. this.physicsSystem.setGravity(this.physicsGravity);
  17897. for(var i=0;i<objects.length;i++){
  17898. if(objects[i].jigLibObj) this.physicsSystem.addBody(objects[i].jigLibObj);
  17899. }
  17900. var that=this;
  17901. this.addEventListener("childAdded",function(data){
  17902. if(data.obj.jigLibObj) that.physicsSystem.addBody(data.obj.jigLibObj);
  17903. });
  17904. this.addEventListener("childRemoved",function(data){
  17905. if(data.obj.jigLibObj) that.physicsSystem.removeBody(data.obj.jigLibObj);
  17906. });
  17907. }
  17908. for(var i=0;i<objects.length;i++){
  17909. if(objects[i].jigLibObj) {
  17910. objects[i].preProcess(dt);
  17911. }
  17912. }
  17913. if(!noIntegrate) this.physicsSystem.integrate(dt);
  17914. }
  17915. /**
  17916. * Sets the gravity of the physics system
  17917. * @param {number} gravity the gravity to apply to the physics system
  17918. */
  17919. GLGE.Scene.prototype.setGravity=function(gravity){
  17920. this.physicsGravity=gravity;
  17921. if(this.physicsSystem){
  17922. this.physicsSystem.setGravity(gravity);
  17923. }
  17924. return this;
  17925. }
  17926. /**
  17927. * Gets the gravity of the physics system
  17928. * @returns {number}
  17929. */
  17930. GLGE.Scene.prototype.getGravity=function(gravity){
  17931. return this.physicsSystem.getGravity(gravity);
  17932. }
  17933. GLGE.Group.prototype.addPhysicsPlane=GLGE.Group.prototype.addChild;
  17934. GLGE.Group.prototype.addPhysicsBox=GLGE.Group.prototype.addChild;
  17935. GLGE.Group.prototype.addPhysicsSphere=GLGE.Group.prototype.addChild;
  17936. GLGE.Group.prototype.addPhysicsMesh=GLGE.Group.prototype.addChild;
  17937. GLGE.Scene.prototype.addPhysicsPlane=GLGE.Group.prototype.addChild;
  17938. GLGE.Scene.prototype.addPhysicsBox=GLGE.Group.prototype.addChild;
  17939. GLGE.Scene.prototype.addPhysicsSphere=GLGE.Group.prototype.addChild;
  17940. GLGE.Scene.prototype.addPhysicsMesh=GLGE.Group.prototype.addChild;
  17941. })(GLGE);/*
  17942. GLGE WebGL Graphics Engine
  17943. Copyright (c) 2010, Paul Brunt
  17944. All rights reserved.
  17945. Redistribution and use in source and binary forms, with or without
  17946. modification, are permitted provided that the following conditions are met:
  17947. * Redistributions of source code must retain the above copyright
  17948. notice, this list of conditions and the following disclaimer.
  17949. * Redistributions in binary form must reproduce the above copyright
  17950. notice, this list of conditions and the following disclaimer in the
  17951. documentation and/or other materials provided with the distribution.
  17952. * Neither the name of GLGE nor the
  17953. names of its contributors may be used to endorse or promote products
  17954. derived from this software without specific prior written permission.
  17955. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  17956. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  17957. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  17958. DISCLAIMED. IN NO EVENT SHALL PAUL BRUNT BE LIABLE FOR ANY
  17959. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  17960. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  17961. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  17962. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  17963. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  17964. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  17965. */
  17966. /**
  17967. * @fileOverview
  17968. * @name glge_physicsabstract.js
  17969. * @author me@paulbrunt.co.uk
  17970. */
  17971. (function(GLGE){
  17972. /**
  17973. * @class An abstract class used when constructing jiglib rigidbodies
  17974. * @augments GLGE.Group
  17975. */
  17976. GLGE.PhysicsAbstract=function(uid){
  17977. this.children=[];
  17978. }
  17979. GLGE.augment(GLGE.Group,GLGE.PhysicsAbstract);
  17980. /**
  17981. * Enumeration for copy of rotation and location
  17982. **/
  17983. GLGE.PHYSICS_ALL=1;
  17984. /**
  17985. * Enumeration for copy of location
  17986. **/
  17987. GLGE.PHYSICS_LOC=2;
  17988. GLGE.PhysicsAbstract.prototype.physicsType=GLGE.PHYSICS_ALL;
  17989. GLGE.PhysicsAbstract.prototype.sync=true;
  17990. /**
  17991. * Sets the physics type either GLGE.PHYSICS_ALL or GLGE.PHYSICS_LOC
  17992. * @param {number} value the enumerations for physics type
  17993. **/
  17994. GLGE.PhysicsAbstract.prototype.setType=function(value){
  17995. this.physicsType=value;
  17996. return this;
  17997. }
  17998. /**
  17999. * Gets the physics type either GLGE.PHYSICS_ALL or GLGE.PHYSICS_LOC
  18000. **/
  18001. GLGE.PhysicsAbstract.prototype.getType=function(value){
  18002. return this.physicsType;
  18003. }
  18004. /**
  18005. * function run before proceeding with the physics sim
  18006. */
  18007. GLGE.PhysicsAbstract.prototype.preProcess=function(dt){
  18008. if(this.sync){
  18009. //update the oriantation and position within jiglib
  18010. var matrix=this.getModelMatrix();
  18011. this.jigLibObj.moveTo([matrix[3],matrix[7],matrix[11],0]);
  18012. if(this.physicsType==1){
  18013. var sx=Math.sqrt(matrix[0]*matrix[0]+matrix[1]*matrix[1]+matrix[2]*matrix[2]);
  18014. var sy=Math.sqrt(matrix[4]*matrix[4]+matrix[5]*matrix[5]+matrix[6]*matrix[6]);
  18015. var sz=Math.sqrt(matrix[8]*matrix[8]+matrix[9]*matrix[9]+matrix[10]*matrix[10]);
  18016. this.jigLibObj.setOrientation(new jigLib.Matrix3D([matrix[0]/sx,matrix[1]/sx,matrix[2]/sx,0,matrix[4]/sy,matrix[5]/sy,matrix[6]/sy,0,matrix[8]/sz,matrix[9]/sz,matrix[10]/sz,0,0,0,0,1]));
  18017. }
  18018. this.sync=false;
  18019. }
  18020. }
  18021. /**
  18022. * get_transform gets the transform matrix
  18023. * @type jigLib.Matrix3D
  18024. * @private
  18025. **/
  18026. GLGE.PhysicsAbstract.prototype.get_transform=function(){
  18027. return new jigLib.Matrix3D(this.getModelMatrix());
  18028. }
  18029. /**
  18030. * Updates the model matrix and flag physics system to sync
  18031. * @private
  18032. */
  18033. GLGE.PhysicsAbstract.prototype.updateMatrix=function(){
  18034. this.globalMatrix=null;
  18035. this.sync=true;
  18036. GLGE.Placeable.prototype.updateMatrix.call(this);
  18037. }
  18038. /**
  18039. * Gets the model matrix to transform the model within the world
  18040. */
  18041. GLGE.PhysicsAbstract.prototype.getModelMatrix=function(){
  18042. if(this.globalMatrix) return this.globalMatrix;
  18043. return GLGE.Placeable.prototype.getModelMatrix.call(this);
  18044. }
  18045. /**
  18046. * set_transform sets the transform matrix
  18047. * @param {Matrix3D} value
  18048. * @private
  18049. **/
  18050. GLGE.PhysicsAbstract.prototype.set_transform=function(value){
  18051. value=value.glmatrix;
  18052. var matrix=[value[0],value[1],value[2],value[3],value[4],value[5],value[6],value[7],value[8],value[9],value[10],value[11],value[12],value[13],value[14],value[15]];
  18053. this.locX=value[3];
  18054. this.locY=value[7];
  18055. this.locZ=value[11];
  18056. matrix=GLGE.mulMat4(matrix,this.getScaleMatrix());
  18057. if(this.physicsType!=1){
  18058. var M=this.getModelMatrix();
  18059. matrix[0]=M[0];
  18060. matrix[1]=M[1];
  18061. matrix[2]=M[2];
  18062. matrix[4]=M[4];
  18063. matrix[5]=M[5];
  18064. matrix[6]=M[6];
  18065. matrix[8]=M[8];
  18066. matrix[9]=M[9];
  18067. matrix[10]=M[10];
  18068. }
  18069. this.globalMatrix=matrix;
  18070. if(this.children){
  18071. for(var i=0;i<this.children.length;i++){
  18072. this.children[i].updateMatrix();
  18073. }
  18074. }
  18075. return this;
  18076. }
  18077. /**
  18078. * Sets the velocity of the physics body
  18079. * @param {array} value The velocity to set
  18080. */
  18081. GLGE.PhysicsAbstract.prototype.setVelocity=function(value,local){
  18082. if(!this.getMovable()) GLGE.error("Cannot set velocity on static object");
  18083. this.jigLibObj.setVelocity(value,local);
  18084. return this;
  18085. }
  18086. /**
  18087. * Sets the x velocity of the physics body
  18088. * @param {number} value The x velocity to set
  18089. */
  18090. GLGE.PhysicsAbstract.prototype.setVelocityX=function(value){
  18091. if(!this.getMovable()) GLGE.error("Cannot set velocity on static object");
  18092. var vel=this.jigLibObj.getVelocity([0,0,0]);
  18093. vel[0]=+value;
  18094. this.jigLibObj.setVelocity(vel);
  18095. return this;
  18096. }
  18097. /**
  18098. * Sets the y velocity of the physics body
  18099. * @param {number} value The y velocity to set
  18100. */
  18101. GLGE.PhysicsAbstract.prototype.setVelocityY=function(value){
  18102. if(!this.getMovable()) GLGE.error("Cannot set velocity on static object");
  18103. var vel=this.jigLibObj.getVelocity([0,0,0]);
  18104. vel[1]=+value;
  18105. this.jigLibObj.setVelocity(vel);
  18106. return this;
  18107. }
  18108. /**
  18109. * Sets the z velocity of the physics body
  18110. * @param {number} value The z velocity to set
  18111. */
  18112. GLGE.PhysicsAbstract.prototype.setVelocityZ=function(value){
  18113. if(!this.getMovable()) GLGE.error("Cannot set velocity on static object");
  18114. var vel=this.jigLibObj.getVelocity([0,0,0]);
  18115. vel[2]=+value;
  18116. this.jigLibObj.setVelocity(vel);
  18117. return this;
  18118. }
  18119. /**
  18120. * Gets the velocity of the physics body
  18121. * @returns {array} The velocity to set
  18122. */
  18123. GLGE.PhysicsAbstract.prototype.getVelocity=function(){
  18124. return this.jigLibObj.getVelocity([0,0,0]);
  18125. }
  18126. /**
  18127. * Gets the x velocity of the physics body
  18128. * @returns {number} The x velocity to set
  18129. */
  18130. GLGE.PhysicsAbstract.prototype.getVelocityX=function(){
  18131. return this.jigLibObj.getVelocity([0,0,0])[0];
  18132. }
  18133. /**
  18134. * Gets the y velocity of the physics body
  18135. * @returns {number} The y velocity to set
  18136. */
  18137. GLGE.PhysicsAbstract.prototype.getVelocityY=function(){
  18138. return this.jigLibObj.getVelocity([0,0,0])[1];
  18139. }
  18140. /**
  18141. * Gets the z velocity of the physics body
  18142. * @returns {number} The z velocity to set
  18143. */
  18144. GLGE.PhysicsAbstract.prototype.getVelocityZ=function(){
  18145. return this.jigLibObj.getVelocity([0,0,0])[2];
  18146. }
  18147. /**
  18148. * Sets the angular velocity of the physics body
  18149. * @param {array} value The velocity to set
  18150. */
  18151. GLGE.PhysicsAbstract.prototype.setAngularVelocity=function(value){
  18152. if(!this.getMovable()) GLGE.error("Cannot set velocity on static object");
  18153. this.jigLibObj.setAngVel(value);
  18154. return this;
  18155. }
  18156. /**
  18157. * Sets the x-axis angular velocity of the physics body
  18158. * @param {number} value The x velocity to set
  18159. */
  18160. GLGE.PhysicsAbstract.prototype.setAngularVelocityX=function(value){
  18161. if(!this.getMovable()) GLGE.error("Cannot set velocity on static object");
  18162. var vel=this.jigLibObj.getAngVel();
  18163. vel[0]=+value;
  18164. this.jigLibObj.setAngVel(vel);
  18165. return this;
  18166. }
  18167. /**
  18168. * Sets the y-axis angular velocity of the physics body
  18169. * @param {number} value The y velocity to set
  18170. */
  18171. GLGE.PhysicsAbstract.prototype.setAngularVelocityY=function(value){
  18172. if(!this.getMovable()) GLGE.error("Cannot set velocity on static object");
  18173. var vel=this.jigLibObj.getAngVel();
  18174. vel[1]=+value;
  18175. this.jigLibObj.setAngVel(vel);
  18176. return this;
  18177. }
  18178. /**
  18179. * Sets the z-axis angular velocity of the physics body
  18180. * @param {number} value The z velocity to set
  18181. */
  18182. GLGE.PhysicsAbstract.prototype.setAngularVelocityZ=function(value){
  18183. if(!this.getMovable()) GLGE.error("Cannot set velocity on static object");
  18184. var vel=this.jigLibObj.getAngVel();
  18185. vel[2]=+value;
  18186. this.jigLibObj.setAngVel(vel);
  18187. return this;
  18188. }
  18189. /**
  18190. * Gets the angular velocity of the physics body
  18191. * @returns {array} The velocity to set
  18192. */
  18193. GLGE.PhysicsAbstract.prototype.getAngularVelocity=function(){
  18194. return this.jigLibObj.getAngVel();
  18195. }
  18196. /**
  18197. * Gets the x-axis angular velocity of the physics body
  18198. * @returns {number} The x velocity to set
  18199. */
  18200. GLGE.PhysicsAbstract.prototype.getAngularVelocityX=function(){
  18201. return this.jigLibObj.getAngVel()[0];
  18202. }
  18203. /**
  18204. * Gets the y-axis angular velocity of the physics body
  18205. * @returns {number} The y velocity to set
  18206. */
  18207. GLGE.PhysicsAbstract.prototype.getAngularVelocityY=function(){
  18208. return this.jigLibObj.getAngVel()[1];
  18209. }
  18210. /**
  18211. * Gets the z-axis angular velocity of the physics body
  18212. * @returns {number} The z velocity to set
  18213. */
  18214. GLGE.PhysicsAbstract.prototype.getAngularVelocityZ=function(){
  18215. return this.jigLibObj.getAngVel()[2];
  18216. }
  18217. /**
  18218. * Sets the movable flag for the object
  18219. * @param {boolean} value The movable flag
  18220. */
  18221. GLGE.PhysicsAbstract.prototype.setMovable=function(value){
  18222. this.jigLibObj.set_movable(value);
  18223. return this;
  18224. }
  18225. /**
  18226. * Gets the movable flag for the object
  18227. * @returns {boolean} The movable flag
  18228. */
  18229. GLGE.PhysicsAbstract.prototype.getMovable=function(){
  18230. return this.jigLibObj.get_movable();
  18231. }
  18232. /**
  18233. * Sets the friction for the object
  18234. * @param {number} value The friction 0-1
  18235. */
  18236. GLGE.PhysicsAbstract.prototype.setFriction=function(value){
  18237. this.jigLibObj.set_friction(value);
  18238. return this;
  18239. }
  18240. /**
  18241. * Gets the friction for the object
  18242. * @returns {number} The friction
  18243. */
  18244. GLGE.PhysicsAbstract.prototype.getFriction=function(){
  18245. return this.jigLibObj.get_friction();
  18246. }
  18247. /**
  18248. * Sets the mass for the object
  18249. * @param {number} value The mass
  18250. */
  18251. GLGE.PhysicsAbstract.prototype.setMass=function(value){
  18252. this.jigLibObj.set_mass(value);
  18253. return this;
  18254. }
  18255. /**
  18256. * Gets the mass for the object
  18257. * @returns {number} The mass
  18258. */
  18259. GLGE.PhysicsAbstract.prototype.getMass=function(){
  18260. return this.jigLibObj.get_mass();
  18261. }
  18262. /**
  18263. * Sets the restitution for the object
  18264. * @param {number} value The restitution 0-1
  18265. */
  18266. GLGE.PhysicsAbstract.prototype.setRestitution=function(value){
  18267. this.jigLibObj.set_restitution(value);
  18268. return this;
  18269. }
  18270. /**
  18271. * Gets the restitution for the object
  18272. * @returns {number} The restitution
  18273. */
  18274. GLGE.PhysicsAbstract.prototype.getRestitution=function(){
  18275. return this.jigLibObj.get_restitution();
  18276. }
  18277. /**
  18278. * Add forces in the body coordinate frame
  18279. * @param {array} f force expressed as a 3D vector
  18280. * @param {array} p position of origin of the force expressed as a 3D vector
  18281. **/
  18282. GLGE.PhysicsAbstract.prototype.addBodyForce=function(f, p){
  18283. this.jigLibObj.addBodyForce(f,p);
  18284. return this;
  18285. }
  18286. /**
  18287. * Add forces in the world coordinate frame
  18288. * @param {array} f force expressed as a 3D vector
  18289. * @param {array} p position of origin of the force expressed as a 3D vector
  18290. **/
  18291. GLGE.PhysicsAbstract.prototype.addWorldForce=function(f, p){
  18292. this.jigLibObj.addWorldForce(f,p);
  18293. return this;
  18294. }
  18295. /**
  18296. * Add torque in the world coordinate frame
  18297. * @param {array} t torque expressed as a 3D vector
  18298. **/
  18299. GLGE.PhysicsAbstract.prototype.addWorldTorque=function(t){
  18300. this.jigLibObj.addWorldTorque(t);
  18301. return this;
  18302. }
  18303. /**
  18304. * Add torque in the body coordinate frame
  18305. * @param {array} t torque expressed as a 3D vector
  18306. **/
  18307. GLGE.PhysicsAbstract.prototype.addBodyTorque=function(t){
  18308. this.jigLibObj.addBodyTorque(t);
  18309. return this;
  18310. }
  18311. /**
  18312. * Sets the linear velocity damping
  18313. * @param {array} damping 3D vector for linear damping
  18314. **/
  18315. GLGE.PhysicsAbstract.prototype.setLinearVelocityDamping=function(v){
  18316. this.jigLibObj.set_linVelocityDamping(v);
  18317. return this;
  18318. }
  18319. /**
  18320. * Gets the rotational velocity Damping
  18321. * @returns 3D vector for rotational damping
  18322. **/
  18323. GLGE.PhysicsAbstract.prototype.getRotationalVelocityDamping=function(v){
  18324. return this.jigLibObj.get_rotVelocityDamping();
  18325. }
  18326. /**
  18327. * Gets the linear velocity damping
  18328. * @returns 3D vector for linear damping
  18329. **/
  18330. GLGE.PhysicsAbstract.prototype.getLinearVelocityDamping=function(v){
  18331. return this.jigLibObj.get_linVelocityDamping();
  18332. }
  18333. /**
  18334. * Sets the rotational velocity Damping
  18335. * @param {array} damping 3D vector for rotational damping
  18336. **/
  18337. GLGE.PhysicsAbstract.prototype.setRotationalVelocityDamping=function(v){
  18338. this.jigLibObj.set_rotVelocityDamping(v);
  18339. return this;
  18340. }
  18341. /**
  18342. * Remove active force and torque
  18343. **/
  18344. GLGE.PhysicsAbstract.prototype.clearForces=function(){
  18345. this.jigLibObj.clearForces();
  18346. return this;
  18347. }
  18348. })(GLGE);/*
  18349. GLGE WebGL Graphics Engine
  18350. Copyright (c) 2010, Paul Brunt
  18351. All rights reserved.
  18352. Redistribution and use in source and binary forms, with or without
  18353. modification, are permitted provided that the following conditions are met:
  18354. * Redistributions of source code must retain the above copyright
  18355. notice, this list of conditions and the following disclaimer.
  18356. * Redistributions in binary form must reproduce the above copyright
  18357. notice, this list of conditions and the following disclaimer in the
  18358. documentation and/or other materials provided with the distribution.
  18359. * Neither the name of GLGE nor the
  18360. names of its contributors may be used to endorse or promote products
  18361. derived from this software without specific prior written permission.
  18362. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  18363. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  18364. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  18365. DISCLAIMED. IN NO EVENT SHALL PAUL BRUNT BE LIABLE FOR ANY
  18366. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  18367. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  18368. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  18369. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  18370. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  18371. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  18372. */
  18373. /**
  18374. * @fileOverview
  18375. * @name glge_physicssphere.js
  18376. * @author me@paulbrunt.co.uk
  18377. */
  18378. (function(GLGE){
  18379. /**
  18380. * @class A wrapping class for jiglib spheres
  18381. * @augments GLGE.PhysicsAbstract
  18382. */
  18383. GLGE.PhysicsBox=function(uid){
  18384. this.jigLibObj=new jigLib.JBox(this,this.width,this.height,this.depth);
  18385. this.jigLibObj.GLGE=this;
  18386. this.jigLibObj.addEventListener(jigLib.JCollisionEvent.COLLISION, function(event){this.GLGE.fireEvent("collision",{obj:event.collisionBody.GLGE,impulse:event.collisionImpulse})});
  18387. GLGE.PhysicsAbstract.call(this,uid);
  18388. }
  18389. GLGE.augment(GLGE.PhysicsAbstract,GLGE.PhysicsBox);
  18390. GLGE.PhysicsBox.prototype.width=1;
  18391. GLGE.PhysicsBox.prototype.height=1;
  18392. GLGE.PhysicsBox.prototype.depth=1;
  18393. GLGE.PhysicsBox.prototype.className="PhysicsBox";
  18394. /**
  18395. * Sets the width of the box
  18396. * @param {number} value The width to set
  18397. */
  18398. GLGE.PhysicsBox.prototype.setWidth=function(value){
  18399. this.width=value;
  18400. var sides=this.jigLibObj.get_sideLengths();
  18401. sides[0]=+value
  18402. this.jigLibObj.set_sideLengths(sides);
  18403. return this;
  18404. }
  18405. /**
  18406. * Sets the height of the box
  18407. * @param {number} value The height to set
  18408. */
  18409. GLGE.PhysicsBox.prototype.setHeight=function(value){
  18410. this.height=value;
  18411. var sides=this.jigLibObj.get_sideLengths();
  18412. sides[1]=+value
  18413. this.jigLibObj.set_sideLengths(sides);
  18414. return this;
  18415. }
  18416. /**
  18417. * Sets the height of the box
  18418. * @param {number} value The depth to set
  18419. */
  18420. GLGE.PhysicsBox.prototype.setDepth=function(value){
  18421. this.depth=value;
  18422. var sides=this.jigLibObj.get_sideLengths();
  18423. sides[2]=+value
  18424. this.jigLibObj.set_sideLengths(sides);
  18425. return this;
  18426. }
  18427. /**
  18428. * Gets the width of the box
  18429. * @returns {number} The width to set
  18430. */
  18431. GLGE.PhysicsBox.prototype.getWidth=function(){
  18432. return this.jigLibObj.get_sideLengths()[0];
  18433. }
  18434. /**
  18435. * Gets the height of the box
  18436. * @returns {number} The height to set
  18437. */
  18438. GLGE.PhysicsBox.prototype.getHeight=function(){
  18439. return this.jigLibObj.get_sideLengths()[1];
  18440. }
  18441. /**
  18442. * Gets the depth of the box
  18443. * @returns {number} The depth to set
  18444. */
  18445. GLGE.PhysicsBox.prototype.getDepth=function(){
  18446. return this.jigLibObj.get_sideLengths()[2];
  18447. }
  18448. })(GLGE);/*
  18449. GLGE WebGL Graphics Engine
  18450. Copyright (c) 2010, Paul Brunt
  18451. All rights reserved.
  18452. Redistribution and use in source and binary forms, with or without
  18453. modification, are permitted provided that the following conditions are met:
  18454. * Redistributions of source code must retain the above copyright
  18455. notice, this list of conditions and the following disclaimer.
  18456. * Redistributions in binary form must reproduce the above copyright
  18457. notice, this list of conditions and the following disclaimer in the
  18458. documentation and/or other materials provided with the distribution.
  18459. * Neither the name of GLGE nor the
  18460. names of its contributors may be used to endorse or promote products
  18461. derived from this software without specific prior written permission.
  18462. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  18463. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  18464. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  18465. DISCLAIMED. IN NO EVENT SHALL PAUL BRUNT BE LIABLE FOR ANY
  18466. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  18467. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  18468. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  18469. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  18470. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  18471. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  18472. */
  18473. /**
  18474. * @fileOverview
  18475. * @name glge_physicsmesh.js
  18476. * @author me@paulbrunt.co.uk
  18477. */
  18478. (function(GLGE){
  18479. /**
  18480. * @class A wrapping class for jiglib triangle mesh
  18481. * @augments GLGE.PhysicsAbstract
  18482. */
  18483. GLGE.PhysicsMesh=function(uid){
  18484. this.jigLibObj=new jigLib.JTriangleMesh(null, 100, 0.1);
  18485. this.jigLibObj.GLGE=this;
  18486. this.jigLibObj.addEventListener(jigLib.JCollisionEvent.COLLISION, function(event){this.GLGE.fireEvent("collision",{obj:event.collisionBody.GLGE,impulse:event.collisionImpulse})});
  18487. this.dirty=true;
  18488. this.addEventListener("matrixUpdate",this.makeDirty);
  18489. this.addEventListener("childMatrixUpdate",this.makeDirty);
  18490. this.addEventListener("childAdded",this.makeDirty);
  18491. this.addEventListener("childRemoved",this.makeDirty);
  18492. GLGE.PhysicsAbstract.call(this,uid);
  18493. }
  18494. GLGE.augment(GLGE.PhysicsAbstract,GLGE.PhysicsMesh);
  18495. GLGE.PhysicsMesh.prototype.className="PhysicsMesh";
  18496. /**
  18497. * Forces and update of the triangle mesh
  18498. */
  18499. GLGE.PhysicsMesh.prototype.forceUpdate=function(){
  18500. this.dirty=true;
  18501. return this;
  18502. }
  18503. /**
  18504. * flag to regenerate trimesh and redo octtree
  18505. * @private
  18506. */
  18507. GLGE.PhysicsMesh.prototype.makeDirty=function(e){
  18508. this.dirty=true;
  18509. }
  18510. /**
  18511. * called before a system intergrate
  18512. * @private
  18513. */
  18514. GLGE.PhysicsMesh.prototype.preProcess=function(){
  18515. //recreate mesh and build octree
  18516. if(this.dirty){
  18517. var triangles=this.getTriangles();
  18518. this.jigLibObj.createMesh(triangles.verts, triangles.faces);
  18519. this.dirty=false;
  18520. }
  18521. }
  18522. /**
  18523. * Creates the jiglib triangle arrays from the containing objects
  18524. * @private
  18525. */
  18526. GLGE.PhysicsMesh.prototype.getTriangles=function(){
  18527. var objs=this.getObjects();
  18528. var verts=[];
  18529. var faces=[];
  18530. for(var i=0;i<objs.length;i++){
  18531. if(objs[i].multimaterials){
  18532. var matrix=objs[i].getModelMatrix();
  18533. for(var j=0;j<objs[i].multimaterials.length;j++){
  18534. var mesh=objs[i].multimaterials[j].getMesh();
  18535. var vertcnt=verts.length;
  18536. if(mesh){
  18537. for(var k=0;k<mesh.positions.length;k=k+3){
  18538. var vert=[mesh.positions[k],mesh.positions[k+1],mesh.positions[k+2],1];
  18539. var v=GLGE.mulMat4Vec4(matrix,vert);
  18540. verts.push([v[0],v[1],v[2],1]);
  18541. }
  18542. var mfaces=mesh.faces.data
  18543. if(mfaces){
  18544. var len=mfaces.length;
  18545. len=((len/3)|0)*3;
  18546. for(var k=0;k<len;k=k+3){
  18547. faces.push([+mfaces[k]+vertcnt,+mfaces[k+1]+vertcnt,+mfaces[k+2]+vertcnt]);
  18548. }
  18549. }else{
  18550. for(var k=0;k<mesh.positions.length/3;k=k+3){
  18551. faces.push([k+vertcnt,k+1+vertcnt,k+2+vertcnt]);
  18552. }
  18553. }
  18554. }
  18555. }
  18556. }
  18557. }
  18558. return {verts:verts,faces:faces};
  18559. }
  18560. })(GLGE);/*
  18561. GLGE WebGL Graphics Engine
  18562. Copyright (c) 2010, Paul Brunt
  18563. All rights reserved.
  18564. Redistribution and use in source and binary forms, with or without
  18565. modification, are permitted provided that the following conditions are met:
  18566. * Redistributions of source code must retain the above copyright
  18567. notice, this list of conditions and the following disclaimer.
  18568. * Redistributions in binary form must reproduce the above copyright
  18569. notice, this list of conditions and the following disclaimer in the
  18570. documentation and/or other materials provided with the distribution.
  18571. * Neither the name of GLGE nor the
  18572. names of its contributors may be used to endorse or promote products
  18573. derived from this software without specific prior written permission.
  18574. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  18575. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  18576. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  18577. DISCLAIMED. IN NO EVENT SHALL PAUL BRUNT BE LIABLE FOR ANY
  18578. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  18579. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  18580. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  18581. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  18582. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  18583. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  18584. */
  18585. /**
  18586. * @fileOverview
  18587. * @name glge_physicssphere.js
  18588. * @author me@paulbrunt.co.uk
  18589. */
  18590. (function(GLGE){
  18591. GLGE.PHYSICS_XAXIS=[1,0,0,0];
  18592. GLGE.PHYSICS_YAXIS=[0,1,0,0];
  18593. GLGE.PHYSICS_ZAXIS=[0,0,1,0];
  18594. GLGE.PHYSICS_NEGXAXIS=[-1,0,0,0];
  18595. GLGE.PHYSICS_NEGYAXIS=[0,-1,0,0];
  18596. GLGE.PHYSICS_NEGZAXIS=[0,0,-1,0];
  18597. /**
  18598. * @class A wrapping class for jiglib spheres
  18599. * @augments GLGE.PhysicsAbstract
  18600. */
  18601. GLGE.PhysicsPlane=function(uid){
  18602. this.jigLibObj=new jigLib.JPlane(this,this.normal,this.distance);
  18603. this.jigLibObj.GLGE=this;
  18604. this.jigLibObj.addEventListener(jigLib.JCollisionEvent.COLLISION, function(event){this.GLGE.fireEvent("collision",{obj:event.collisionBody.GLGE,impulse:event.collisionImpulse})});
  18605. GLGE.PhysicsAbstract.call(this,uid);
  18606. }
  18607. GLGE.augment(GLGE.PhysicsAbstract,GLGE.PhysicsPlane);
  18608. GLGE.PhysicsPlane.prototype.normal=[0,0,1,0];
  18609. GLGE.PhysicsPlane.prototype.distance=0;
  18610. GLGE.PhysicsPlane.prototype.className="PhysicsPlane";
  18611. /**
  18612. * Sets the normal of the plane
  18613. * @param {number} value The normal to set
  18614. */
  18615. GLGE.PhysicsPlane.prototype.setNormal=function(value){
  18616. this.normal=value;
  18617. this.jigLibObj.set_normal(value);
  18618. return this;
  18619. }
  18620. /**
  18621. * Sets the distance of the plane
  18622. * @param {number} value The distance to set
  18623. */
  18624. GLGE.PhysicsPlane.prototype.setDistance=function(value){
  18625. this.distance=value;
  18626. this.jigLibObj.set_distance(value);
  18627. return this;
  18628. }
  18629. /**
  18630. * Gets the normal of the plane
  18631. * @returns {number} The current normal
  18632. */
  18633. GLGE.PhysicsPlane.prototype.getNormal=function(){
  18634. return this.jigLibObj.get_normal();
  18635. }
  18636. /**
  18637. * Gets the distance of the plane
  18638. * @returns {number} The current distance
  18639. */
  18640. GLGE.PhysicsPlane.prototype.getDistance=function(){
  18641. return this.jigLibObj.get_distance();
  18642. }
  18643. })(GLGE);/*
  18644. GLGE WebGL Graphics Engine
  18645. Copyright (c) 2010, Paul Brunt
  18646. All rights reserved.
  18647. Redistribution and use in source and binary forms, with or without
  18648. modification, are permitted provided that the following conditions are met:
  18649. * Redistributions of source code must retain the above copyright
  18650. notice, this list of conditions and the following disclaimer.
  18651. * Redistributions in binary form must reproduce the above copyright
  18652. notice, this list of conditions and the following disclaimer in the
  18653. documentation and/or other materials provided with the distribution.
  18654. * Neither the name of GLGE nor the
  18655. names of its contributors may be used to endorse or promote products
  18656. derived from this software without specific prior written permission.
  18657. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  18658. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  18659. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  18660. DISCLAIMED. IN NO EVENT SHALL PAUL BRUNT BE LIABLE FOR ANY
  18661. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  18662. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  18663. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  18664. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  18665. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  18666. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  18667. */
  18668. /**
  18669. * @fileOverview
  18670. * @name glge_physicssphere.js
  18671. * @author me@paulbrunt.co.uk
  18672. */
  18673. (function(GLGE){
  18674. /**
  18675. * @class A wrapping class for jiglib spheres
  18676. * @augments GLGE.PhysicsAbstract
  18677. */
  18678. GLGE.PhysicsSphere=function(uid){
  18679. this.jigLibObj=new jigLib.JSphere(this,this.radius);
  18680. this.jigLibObj.GLGE=this;
  18681. this.jigLibObj.addEventListener(jigLib.JCollisionEvent.COLLISION, function(event){this.GLGE.fireEvent("collision",{obj:event.collisionBody.GLGE,impulse:event.collisionImpulse})});
  18682. GLGE.PhysicsAbstract.call(this,uid);
  18683. }
  18684. GLGE.augment(GLGE.PhysicsAbstract,GLGE.PhysicsSphere);
  18685. GLGE.PhysicsSphere.prototype.radius=1;
  18686. GLGE.PhysicsSphere.prototype.className="PhysicsSphere";
  18687. /**
  18688. * Sets the radius of the sphere
  18689. * @param {number} value The radius to set
  18690. */
  18691. GLGE.PhysicsSphere.prototype.setRadius=function(value){
  18692. this.physicsRadius=+value;
  18693. this.jigLibObj.set_radius(+value);
  18694. return this;
  18695. }
  18696. /**
  18697. * Gets the radius of the sphere
  18698. * @returns {number} The radius to set
  18699. */
  18700. GLGE.PhysicsSphere.prototype.getRadius=function(value){
  18701. return this.jigLibObj.get_radius();
  18702. }
  18703. })(GLGE);/*
  18704. GLGE WebGL Graphics Engine
  18705. Copyright (c) 2011, Paul Brunt
  18706. All rights reserved.
  18707. Redistribution and use in source and binary forms, with or without
  18708. modification, are permitted provided that the following conditions are met:
  18709. * Redistributions of source code must retain the above copyright
  18710. notice, this list of conditions and the following disclaimer.
  18711. * Redistributions in binary form must reproduce the above copyright
  18712. notice, this list of conditions and the following disclaimer in the
  18713. documentation and/or other materials provided with the distribution.
  18714. * Neither the name of GLGE nor the
  18715. names of its contributors may be used to endorse or promote products
  18716. derived from this software without specific prior written permission.
  18717. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  18718. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  18719. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  18720. DISCLAIMED. IN NO EVENT SHALL PAUL BRUNT BE LIABLE FOR ANY
  18721. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  18722. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  18723. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  18724. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  18725. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  18726. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  18727. */
  18728. /**
  18729. * @fileOverview
  18730. * @name glge_constraintpoint.js
  18731. * @author me@paulbrunt.co.uk
  18732. */
  18733. (function(GLGE){
  18734. /**
  18735. * @class A wrapping class for jiglib constraint point
  18736. * @augments GLGE.QuickNotation
  18737. * @augments GLGE.JSONLoader
  18738. */
  18739. GLGE.PhysicsConstraintPoint=function(){
  18740. }
  18741. GLGE.augment(GLGE.QuickNotation,GLGE.PhysicsConstraintPoint);
  18742. GLGE.augment(GLGE.JSONLoader,GLGE.PhysicsConstraintPoint);
  18743. GLGE.PhysicsConstraintPoint.constraint=null;
  18744. GLGE.PhysicsConstraintPoint.prototype.className="PhysicsConstraintPoint";
  18745. /**
  18746. * Sets the first body to use with this constraint
  18747. * @param {GLGE.PhysicsAbstract} body1 The first body
  18748. */
  18749. GLGE.PhysicsConstraintPoint.prototype.setBody1=function(body1){
  18750. this.body1=body1;
  18751. this.updateConstraint();
  18752. return this;
  18753. }
  18754. /**
  18755. * Sets the second body to use with this constraint
  18756. * @param {GLGE.PhysicsAbstract} body2 The second body
  18757. */
  18758. GLGE.PhysicsConstraintPoint.prototype.setBody2=function(body2){
  18759. this.body2=body2;
  18760. this.updateConstraint();
  18761. return this;
  18762. }
  18763. /**
  18764. * Sets the constraing point on the first body
  18765. * @param {array} bodypos1 The first body constraint point
  18766. */
  18767. GLGE.PhysicsConstraintPoint.prototype.setBodyPos1=function(bodypos1){
  18768. if(typeof(bodypos1)=="string") bodypos1=bodypos1.split(",");
  18769. this.bodypos1=[parseFloat(bodypos1[0]),parseFloat(bodypos1[1]),parseFloat(bodypos1[2])];
  18770. this.updateConstraint();
  18771. return this;
  18772. }
  18773. /**
  18774. * Sets the constraing point on the second body
  18775. * @param {array} bodypos2 The second body constraint point
  18776. */
  18777. GLGE.PhysicsConstraintPoint.prototype.setBodyPos2=function(bodypos2){
  18778. if(typeof(bodypos2)=="string") bodypos2=bodypos2.split(",");
  18779. this.bodypos2=[parseFloat(bodypos2[0]),parseFloat(bodypos2[1]),parseFloat(bodypos2[2])];
  18780. this.updateConstraint();
  18781. return this;
  18782. }
  18783. /**
  18784. * Updates the jiglib constraint
  18785. * @private
  18786. */
  18787. GLGE.PhysicsConstraintPoint.prototype.updateConstraint=function(){
  18788. if(this.body1 && this.body2 && this.bodypos1 && this.bodypos2){
  18789. if(this.constraint){
  18790. if(this.parent && this.parent.physicsSystem) this.parent.physicsSystem.removeConstraint(this.constraint);
  18791. this.body1.removeConstraint(this.constraint);
  18792. this.body2.removeConstraint(this.constraint);
  18793. }
  18794. this.constraint=new jigLib.JConstraintPoint(this.body1.jigLibObj,this.bodypos1,this.body2.jigLibObj,this.bodypos2);
  18795. if(this.parent && this.parent.physicsSystem) this.parent.physicsSystem.addConstraint(this.constraint);
  18796. }
  18797. }
  18798. /**
  18799. * Add a new physics constraint to the scene
  18800. * @param {GLGE.PhysicsConstraintPoint} constraint The constraint to add to the scene
  18801. */
  18802. GLGE.Scene.prototype.addPhysicsConstraintPoint=function(constraint){
  18803. if(!this.constraints) this.constraints=[];
  18804. this.constraints.push(constraint);
  18805. if(this.physicsSystem) this.physicsSystem.addConstraint(constraint.constraint);
  18806. return this;
  18807. }
  18808. /**
  18809. * Removes a physics constraint to the scene
  18810. * @param {GLGE.PhysicsConstraintPoint} constraint The constraint to remove from the scene
  18811. */
  18812. GLGE.Scene.prototype.removePhysicsConstraintPoint=function(constraint){
  18813. if(!this.constraints) this.constraints=[];
  18814. if(this.constraints.indexOf(constraint)>-1){
  18815. this.constraints.push(constraint);
  18816. if(this.physicsSystem) this.physicsSystem.removeConstraint(constraint.constraint);
  18817. }
  18818. return this;
  18819. }
  18820. })(GLGE);/*
  18821. GLGE WebGL Graphics Engine
  18822. Copyright (c) 2010, Paul Brunt
  18823. All rights reserved.
  18824. Redistribution and use in source and binary forms, with or without
  18825. modification, are permitted provided that the following conditions are met:
  18826. * Redistributions of source code must retain the above copyright
  18827. notice, this list of conditions and the following disclaimer.
  18828. * Redistributions in binary form must reproduce the above copyright
  18829. notice, this list of conditions and the following disclaimer in the
  18830. documentation and/or other materials provided with the distribution.
  18831. * Neither the name of GLGE nor the
  18832. names of its contributors may be used to endorse or promote products
  18833. derived from this software without specific prior written permission.
  18834. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  18835. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  18836. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  18837. DISCLAIMED. IN NO EVENT SHALL PAUL BRUNT BE LIABLE FOR ANY
  18838. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  18839. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  18840. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  18841. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  18842. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  18843. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  18844. */
  18845. /**
  18846. * @fileOverview
  18847. * @name glge_physicscar.js
  18848. * @author me@paulbrunt.co.uk
  18849. */
  18850. (function(GLGE){
  18851. /**
  18852. * @class Physics Car class
  18853. * @augments GLGE.PhysicsBox
  18854. * @see GLGE.PhysicsWheel
  18855. */
  18856. GLGE.PhysicsCar=function(uid){
  18857. GLGE.PhysicsBox.call(this,uid);
  18858. this.wheels=[];
  18859. this.setRotationalVelocityDamping([0.1,0.6,0.1]);
  18860. this.setLinearVelocityDamping([0.996,0.92,0.996]);
  18861. return this;
  18862. }
  18863. GLGE.augment(GLGE.PhysicsBox,GLGE.PhysicsCar);
  18864. GLGE.PhysicsCar.prototype.className="PhysicsCar";
  18865. GLGE.Group.prototype.addPhysicsCar=GLGE.Group.prototype.addChild;
  18866. GLGE.Scene.prototype.addPhysicsCar=GLGE.Group.prototype.addChild;
  18867. /**
  18868. * Applies a driving force to the car
  18869. * @param {number} force the item driving force to apply to each powered wheel
  18870. */
  18871. GLGE.PhysicsCar.prototype.drive=function(force){
  18872. for(var i=0;i<this.wheels.length;i++){
  18873. var wheel=this.wheels[i];
  18874. if(wheel.powered) wheel.drive(force);
  18875. }
  18876. return this;
  18877. }
  18878. /**
  18879. * Applies a brake to the car
  18880. * @param {number} brake the level of braking
  18881. */
  18882. GLGE.PhysicsCar.prototype.brake=function(brake){
  18883. for(var i=0;i<this.wheels.length;i++){
  18884. if(this.wheels[i].powered) this.wheels[i].brake(brake);
  18885. }
  18886. return this;
  18887. }
  18888. /**
  18889. * Adds a wheel to the car
  18890. * @param {GLGE.PhysicsWheel} wheel a wheel to add to the car
  18891. */
  18892. GLGE.PhysicsCar.prototype.addPhysicsWheel=function(wheel){
  18893. this.wheels.push(wheel);
  18894. return GLGE.PhysicsBox.prototype.addChild.call(this,wheel);
  18895. }
  18896. /**
  18897. * Removes a wheel from the car
  18898. * @param {GLGE.PhysicsWheel} wheel a wheel to remove
  18899. */
  18900. GLGE.PhysicsCar.prototype.removeWheel=function(wheel){
  18901. var idx=this.wheels.indexOf(wheel);
  18902. if(idx>-1) this.wheels.splice(idx,1);
  18903. return GLGE.PhsyicsBox.prototype.addChild.call(this,wheel);
  18904. }
  18905. /**
  18906. * does the physics stuff
  18907. * @private
  18908. */
  18909. GLGE.PhysicsCar.prototype.getScene=function(){
  18910. var child=this;
  18911. while(child.parent) child=child.parent;
  18912. return child;
  18913. }
  18914. /**
  18915. * does the physics stuff
  18916. * @private
  18917. */
  18918. GLGE.PhysicsCar.prototype.preProcess=function(dt){
  18919. var scene=this.getScene();
  18920. var velocity=this.getVelocity();
  18921. var carMass=this.getMass();
  18922. var wheels=this.wheels
  18923. for(var i=0;i<wheels.length;i++){
  18924. var wheel=wheels[i];
  18925. var mat=wheel.getModelMatrix();
  18926. var tangent=GLGE.toUnitVec3([mat[2],mat[6],mat[10]]);
  18927. var up=GLGE.toUnitVec3([mat[1],mat[5],mat[9]]);
  18928. var forward=GLGE.toUnitVec3([mat[0],mat[4],mat[8]]);
  18929. var position=[mat[3],mat[7],mat[11]];
  18930. var wheelRadius=wheel.radius;
  18931. var travel=wheel.travel;
  18932. var spring=wheel.spring;
  18933. var sideFriction=wheel.sideFriction;
  18934. var frontFriction=wheel.frontFriction;
  18935. var springForce=0;
  18936. var result=scene.segmentTest(position,GLGE.scaleVec3(up,-travel-wheelRadius),this);
  18937. if(result){
  18938. var distanceToFloor=result.distance-wheelRadius;
  18939. if(distanceToFloor<travel){
  18940. springForce=(travel-distanceToFloor)/travel*spring;
  18941. this.addWorldForce(GLGE.scaleVec3(up,springForce),position);
  18942. wheel.innerGroup.setLocY(wheelRadius-result.distance);
  18943. }
  18944. //turning force
  18945. //var sideForce=springForce*sideFriction; //although correct having a varible side force makes things very difficult to control
  18946. var sideForce=sideFriction;
  18947. var dot=GLGE.scaleVec3(tangent,-GLGE.dotVec3(tangent,velocity)*sideForce);
  18948. this.addWorldForce(dot,position);
  18949. }else{
  18950. wheel.innerGroup.setLocY(-travel);
  18951. }
  18952. var maxForwardForce=springForce*frontFriction; //frictional force
  18953. var maxdw=(maxForwardForce*dt*dt)/wheelRadius;
  18954. var dw=0;
  18955. //do the wheel turn
  18956. if(wheel.oldPos){
  18957. var delta=GLGE.dotVec3(GLGE.subVec3(position,wheel.oldPos),forward)/wheelRadius;
  18958. var dw=delta/dt-wheel.angVel;
  18959. if(dw<-maxdw) dw=-maxdw;
  18960. if(dw>maxdw) dw=maxdw;
  18961. }
  18962. if(wheel.driveForce){
  18963. var drive=wheel.driveForce*(1-wheel.braking);
  18964. if(drive<-maxForwardForce) drive=maxForwardForce;
  18965. if(drive>maxForwardForce) drive=maxForwardForce;
  18966. this.addWorldForce(GLGE.scaleVec3(forward,drive),position);
  18967. dw+=(wheel.driveForce/carMass*dt)/wheelRadius;
  18968. }
  18969. if(wheel.braking){
  18970. var frontVel=GLGE.dotVec3(velocity,forward);
  18971. var braking=-wheel.braking*frontVel/dt
  18972. if(braking<-maxForwardForce) braking=-maxForwardForce;
  18973. if(braking>maxForwardForce) braking=maxForwardForce;
  18974. this.addWorldForce(GLGE.scaleVec3(forward,braking),position);
  18975. }
  18976. wheel.angVel+=dw;
  18977. if(wheel.brake) wheel.angVel*=(1-wheel.braking);
  18978. wheel.innerGroup.setRotZ(wheel.innerGroup.getRotZ()-wheel.angVel*dt);
  18979. wheel.angVel*=0.995;
  18980. wheel.oldPos=position;
  18981. }
  18982. GLGE.PhysicsBox.prototype.preProcess.call(this,dt);
  18983. }
  18984. /**
  18985. * @class physics wheel class used with PhysicsCar class
  18986. * @augments GLGE.Group
  18987. * @see GLGE.PhysicsBox
  18988. */
  18989. GLGE.PhysicsWheel=function(uid){
  18990. GLGE.Group.call(this,uid);
  18991. this.innerGroup=new GLGE.Group;
  18992. GLGE.Group.prototype.addChild.call(this,this.innerGroup);
  18993. return this;
  18994. }
  18995. GLGE.augment(GLGE.Group,GLGE.PhysicsWheel);
  18996. GLGE.PhysicsWheel.prototype.radius=1;
  18997. GLGE.PhysicsWheel.prototype.travel=0.75;
  18998. GLGE.PhysicsWheel.prototype.angVel=0;
  18999. GLGE.PhysicsWheel.prototype.spring=90;
  19000. GLGE.PhysicsWheel.prototype.braking=0;
  19001. GLGE.PhysicsWheel.prototype.driveForce=0;
  19002. GLGE.PhysicsWheel.prototype.powered=false;
  19003. GLGE.PhysicsWheel.prototype.sideFriction=3; //sideways friction co-efficient
  19004. GLGE.PhysicsWheel.prototype.frontFriction=3; //front friction force
  19005. GLGE.PhysicsWheel.prototype.className="PhysicsWheel";
  19006. /**
  19007. * Adds a child to the wheel container
  19008. * @param {object} child a GLGE object to represent the wheel
  19009. */
  19010. GLGE.PhysicsWheel.prototype.addChild=function(child){
  19011. return this.innerGroup.addChild(child);
  19012. }
  19013. /**
  19014. * Removes a child to the wheel container
  19015. * @param {object} child a GLGE object to represent the wheel
  19016. */
  19017. GLGE.PhysicsWheel.prototype.removeChild=function(child){
  19018. return this.innerGroup.removeChild(child);
  19019. }
  19020. GLGE.PhysicsWheel.prototype.addGroup=GLGE.PhysicsWheel.prototype.addChild;
  19021. GLGE.PhysicsWheel.prototype.addCollada=GLGE.PhysicsWheel.prototype.addChild;
  19022. GLGE.PhysicsWheel.prototype.addObject=GLGE.PhysicsWheel.prototype.addChild;
  19023. GLGE.PhysicsWheel.prototype.addMD2=GLGE.PhysicsWheel.prototype.addChild;
  19024. GLGE.PhysicsWheel.prototype.addMD3=GLGE.PhysicsWheel.prototype.addChild;
  19025. GLGE.PhysicsWheel.prototype.addWavefront=GLGE.PhysicsWheel.prototype.addChild;
  19026. /**
  19027. * Sets the wheel to be a powered wheel
  19028. * @param {boolean} powered flag indicateding if wheel is powered
  19029. */
  19030. GLGE.PhysicsWheel.prototype.setPowered=function(powered){
  19031. this.powered=powered;
  19032. return this;
  19033. }
  19034. /**
  19035. * Sets the wheel Radius
  19036. * @param {number} radius the wheel radius
  19037. */
  19038. GLGE.PhysicsWheel.prototype.setRadius=function(radius){
  19039. this.radius=radius;
  19040. return this;
  19041. }
  19042. /**
  19043. * Sets the suspension spring distance
  19044. * @param {number} radius the wheel radius
  19045. */
  19046. GLGE.PhysicsWheel.prototype.setSpring=function(spring){
  19047. this.spring=spring;
  19048. return this;
  19049. }
  19050. /**
  19051. * Sets the suspension travel distance
  19052. * @param {number} travel the suspension travel
  19053. */
  19054. GLGE.PhysicsWheel.prototype.setTravel=function(travel){
  19055. this.travel=travel;
  19056. return this;
  19057. }
  19058. /**
  19059. * Sets the front friction coefficient
  19060. * @param {number} friction the front fricition coefficient
  19061. */
  19062. GLGE.PhysicsWheel.prototype.setFrontFriction=function(friction){
  19063. this.frontFriction=friction;
  19064. return this;
  19065. }
  19066. /**
  19067. * Sets the side friction coefficient
  19068. * @param {number} friction the side fricition coefficient
  19069. */
  19070. GLGE.PhysicsWheel.prototype.setSideFriction=function(friction){
  19071. this.sideFriction=friction;
  19072. return this;
  19073. }
  19074. /**
  19075. * Sets the wheel Rotation
  19076. * @param {number} rotation the rotation of the wheel
  19077. */
  19078. GLGE.PhysicsWheel.prototype.setWheelRotation=function(rotation){
  19079. this.setRotY(rotation);
  19080. return this;
  19081. }
  19082. /**
  19083. * Gets the wheel Rotation
  19084. * @returns the wheel roation in radians
  19085. */
  19086. GLGE.PhysicsWheel.prototype.getWheelRotation=function(rotation){
  19087. return this.getRotY();
  19088. }
  19089. /**
  19090. * Gets the wheel Radius
  19091. * @returns the wheel radius
  19092. */
  19093. GLGE.PhysicsWheel.prototype.getRadius=function(){
  19094. return this.radius;
  19095. }
  19096. /**
  19097. * Gets the suspension spring
  19098. * @returns the wheel radius
  19099. */
  19100. GLGE.PhysicsWheel.prototype.getSpring=function(){
  19101. return this.spring;
  19102. }
  19103. /**
  19104. * Gets the suspension travel distance
  19105. * @returns the suspension travel
  19106. */
  19107. GLGE.PhysicsWheel.prototype.getTravel=function(){
  19108. return this.travel;
  19109. }
  19110. /**
  19111. * Gets the front friction coefficient
  19112. * @returns the front fricition coefficient
  19113. */
  19114. GLGE.PhysicsWheel.prototype.getFrontFriction=function(){
  19115. return this.frontFriction;
  19116. }
  19117. /**
  19118. * Gets the side friction coefficient
  19119. * @returns the side fricition coefficient
  19120. */
  19121. GLGE.PhysicsWheel.prototype.getSideFriction=function(){
  19122. return this.sideFriction;
  19123. }
  19124. /**
  19125. * Sets a driving force for the wheel
  19126. * @param {number} force the driving force in N
  19127. */
  19128. GLGE.PhysicsWheel.prototype.drive=function(force){
  19129. this.driveForce=force;
  19130. return this;
  19131. }
  19132. /**
  19133. * Sets the braking level
  19134. * @param {number} brake 0-1 value indicating the level of braking
  19135. */
  19136. GLGE.PhysicsWheel.prototype.brake=function(brake){
  19137. this.braking=brake;
  19138. return this;
  19139. }
  19140. })(GLGE);/*
  19141. Copyright (c) 2011 Martin Ruenz
  19142. Permission is hereby granted, free of charge, to any person obtaining a copy
  19143. of this software and associated documentation files (the "Software"), to deal
  19144. in the Software without restriction, including without limitation the rights
  19145. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  19146. copies of the Software, and to permit persons to whom the Software is
  19147. furnished to do so, subject to the following conditions:
  19148. The above copyright notice and this permission notice shall be included in
  19149. all copies or substantial portions of the Software.
  19150. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19151. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19152. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  19153. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19154. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19155. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  19156. THE SOFTWARE.
  19157. */
  19158. /**
  19159. * @fileOverview Base class for preloaders. Enables the handling of multiple files.
  19160. * @name glge_filepreloader.js
  19161. * @author seamonkey@uni-koblenz.de
  19162. */
  19163. (function(GLGE){
  19164. /**
  19165. * @class FilePreloader class
  19166. * @augments GLGE.Events
  19167. */
  19168. GLGE.FilePreloader=function(){
  19169. this.files=[];
  19170. }
  19171. GLGE.augment(GLGE.Events,GLGE.FilePreloader);
  19172. GLGE.FilePreloader.prototype.loadedBytes=0;
  19173. GLGE.FilePreloader.prototype.totalBytes=0;
  19174. GLGE.FilePreloader.prototype.numLoadedFiles=0;
  19175. GLGE.FilePreloader.prototype.numTotalFiles=0;
  19176. GLGE.FilePreloader.prototype.sizesCount=0; /** @description Specifies how many file sizes has been collected */
  19177. GLGE.FilePreloader.prototype.progress=0; /** @description 0 - 100 */
  19178. GLGE.FilePreloader.prototype.files=null; /** @description List of files. file: { "url":url,"loaded":fileloaded,"size":filesize,"bytesLoaded":loadedSize,
  19179. "type":'xml'/'image',"callback":called when loaded,"content":content, "preloader":GLGE.FilePreloader} */
  19180. /**
  19181. * Add a file which has to be loaded
  19182. * @param {string} url The url of the file.
  19183. * @param {string} type Defines the type of the requested file. "image" or "xml"
  19184. * @param {function} [callback] Call this function when the file is loaded and pass the loaded content.
  19185. * @public
  19186. */
  19187. GLGE.FilePreloader.prototype.addFile=function(url, type, callback){
  19188. //if(this.files.indexOf(url) != -1) return;
  19189. this.files.push({"url":url,"loaded":false,"size":-1,"bytesLoaded":0,"type":type,"callback":callback,"content":null,"preloader":this});
  19190. this.numTotalFiles++;
  19191. }
  19192. /**
  19193. * Same as addFile. But instead of creating a new file object use an existing one.
  19194. * @param {object} file The file to add.
  19195. * @public
  19196. */
  19197. GLGE.FilePreloader.prototype.addFileRef=function(file){
  19198. //if(this.files.indexOf(url) != -1) return;
  19199. this.files.push(file);
  19200. this.numTotalFiles++;
  19201. }
  19202. /**
  19203. * This function accumulates the size of all files. When done it triggers loadFiles(). It has to be called for each file.
  19204. * @param {object} file Current file.
  19205. * @private
  19206. */
  19207. GLGE.FilePreloader.prototype.accumulateFileSize=function(file)
  19208. {
  19209. var req = new XMLHttpRequest();
  19210. req.preloader = this;
  19211. req.active = true;
  19212. req.file = file;
  19213. req.overrideMimeType("text/xml");
  19214. req.onreadystatechange = function() {
  19215. if(this.readyState > 1 && req.active)
  19216. {
  19217. this.active = false;
  19218. this.file.size = parseFloat(this.getResponseHeader('Content-length'));
  19219. this.preloader.totalBytes += this.file.size;
  19220. if(++this.preloader.sizesCount >= this.preloader.files.length) // are all file sizes collected?
  19221. this.preloader.loadFiles();
  19222. this.abort();
  19223. this.onreadystatechange = null;
  19224. }
  19225. };
  19226. req.open("GET", file.url, true);
  19227. req.send("");
  19228. }
  19229. /**
  19230. * Start loading
  19231. * @public
  19232. */
  19233. GLGE.FilePreloader.prototype.start=function(){
  19234. for(i in this.files)
  19235. this.accumulateFileSize(this.files[i]);
  19236. }
  19237. /**
  19238. * Load files. Assumes that the file sizes have been accumulated.
  19239. * @private
  19240. */
  19241. GLGE.FilePreloader.prototype.loadFiles=function(){
  19242. for(i in this.files){
  19243. var file = this.files[i];
  19244. if(file.type == "image")
  19245. {
  19246. // only update the preloader, when the file is completely loaded (no ajax)
  19247. var image = new Image();
  19248. file.content = image;
  19249. var that = this;
  19250. image.file = file;
  19251. image.onload = function(){ that.fileLoaded(this.file, this.file.size); }
  19252. image.src=file.url;
  19253. }else{
  19254. // update the preloader each 0.1 seconds (ajax)
  19255. var req = new XMLHttpRequest();
  19256. req.overrideMimeType("text/xml");
  19257. req.preloader = this;
  19258. req.file = file;
  19259. var updateTrigger = setInterval (function ()
  19260. {
  19261. if (req.readyState == 3)
  19262. {
  19263. // TODO: Check if the file reference is always correct
  19264. var stepBytes = req.responseText.length - file.bytesLoaded;
  19265. file.bytesLoaded = req.responseText.length;
  19266. req.preloader.update(stepBytes);
  19267. }
  19268. }, 100);
  19269. req.onreadystatechange = function() {
  19270. if(this.readyState >= 4)
  19271. {
  19272. clearInterval(updateTrigger);
  19273. this.file.content = this.responseXML;
  19274. var stepBytes = this.responseText.length - this.file.bytesLoaded;
  19275. this.preloader.update(stepBytes);
  19276. this.preloader.fileLoaded(this.file, stepBytes);
  19277. }
  19278. };
  19279. req.open("GET", file.url, true);
  19280. req.send();
  19281. }
  19282. }
  19283. }
  19284. /**
  19285. * This functions updates the progress.
  19286. * @param {number} stepBytes Amount of bytes that have been loaded since the last call.
  19287. * @private
  19288. */
  19289. GLGE.FilePreloader.prototype.update=function(stepBytes){
  19290. this.loadedBytes += stepBytes;
  19291. this.progress = (100.0 * this.loadedBytes) / this.totalBytes;
  19292. this.fireEvent("progress", {"progress":this.progress, "stepBytes":stepBytes, "loadedBytes":this.loadedBytes, "totalBytes":this.totalBytes, "loadedFiles": this.numLoadedFiles, "totalFiles": this.numTotalFiles});
  19293. }
  19294. /**
  19295. * Called when a file has been loaded. This function triggers an event and updates the state.
  19296. * @param {object} file The file that has been loaded.
  19297. * @param {number} stepBytes Amount of bytes that have been loaded since the last call.
  19298. * @private
  19299. */
  19300. GLGE.FilePreloader.prototype.fileLoaded=function(file, stepBytes){
  19301. this.numLoadedFiles++;
  19302. // update file
  19303. file.loaded = true;
  19304. file.bytesLoaded = file.size;
  19305. // update progress
  19306. if(this.numLoadedFiles >= this.files.length){
  19307. this.progress = 100;
  19308. this.fireEvent("downloadComplete", {"file":file,"stepBytes":stepBytes});
  19309. }else{
  19310. this.update(stepBytes);
  19311. }
  19312. // events
  19313. this.fireEvent("fileLoaded", {"file":file,"stepBytes":stepBytes});
  19314. if(file.callback) file.callback(file);
  19315. }
  19316. /**
  19317. * This function returns a list (an array) of all loaded files.
  19318. * @public
  19319. */
  19320. GLGE.FilePreloader.prototype.getLoadedFiles=function(){
  19321. var result = [];
  19322. for(i in this.files)
  19323. if(this.files[i].loaded)
  19324. result.push(this.files[i]);
  19325. return result;
  19326. }
  19327. /**
  19328. * This function returns information about one file.
  19329. * @param {string} url The url of the file.
  19330. * @public
  19331. */
  19332. GLGE.FilePreloader.prototype.getFile=function(url){
  19333. for(i in this.files)
  19334. if(this.files[i].url==url)
  19335. return this.files[i];
  19336. return -1;
  19337. }
  19338. })(GLGE);
  19339. /*
  19340. Copyright (c) 2011 Martin Ruenz
  19341. Permission is hereby granted, free of charge, to any person obtaining a copy
  19342. of this software and associated documentation files (the "Software"), to deal
  19343. in the Software without restriction, including without limitation the rights
  19344. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  19345. copies of the Software, and to permit persons to whom the Software is
  19346. furnished to do so, subject to the following conditions:
  19347. The above copyright notice and this permission notice shall be included in
  19348. all copies or substantial portions of the Software.
  19349. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19350. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19351. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  19352. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19353. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19354. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  19355. THE SOFTWARE.
  19356. */
  19357. /**
  19358. * @fileOverview
  19359. * @name glge_documentpreloader.js
  19360. * @author seamonkey@uni-koblenz.de
  19361. */
  19362. (function(GLGE){
  19363. /**
  19364. * @class Document preloader class
  19365. * @augments GLGE.Events
  19366. */
  19367. GLGE.DocumentPreloader=function(doc, args){
  19368. // create image preloader
  19369. this.imagePreloader = new GLGE.FilePreloader();
  19370. this.document = doc;
  19371. if(args.XMLQuota)
  19372. this.XMLQuota = args.XMLQuota;
  19373. else
  19374. this.XMLQuota = 0.2; // 20% XML, 80% images
  19375. this.imageQuota = 1-this.XMLQuota;
  19376. // Passing the size of all xml files will improve the accuracy of the preloader. Alternative: Pass the number of xml files (approximation)
  19377. if(args.XMLBytes)
  19378. this.XMLBytes = args.XMLBytes;
  19379. else if(args.numXMLFiles)
  19380. this.numXMLFiles = args.numXMLFiles;
  19381. else
  19382. this.numXMLFiles = 3; //TODO necessary?
  19383. }
  19384. GLGE.augment(GLGE.Events,GLGE.DocumentPreloader);
  19385. GLGE.DocumentPreloader.prototype.progress = 0;
  19386. GLGE.DocumentPreloader.prototype.imageQuota = 0; // size quota of images (Textures) [0..1]
  19387. GLGE.DocumentPreloader.prototype.XMLQuota = 0; // size quota XML (Documents) [0..1]
  19388. GLGE.DocumentPreloader.prototype.XMLBytes = -1; // XML size in bytes (for higher accuracy)
  19389. GLGE.DocumentPreloader.prototype.totalBytes = -1; // XML size in bytes (highest accuracy)
  19390. GLGE.DocumentPreloader.prototype.loadedBytes=0;
  19391. GLGE.DocumentPreloader.prototype.numXMLFiles = 3; // default value
  19392. GLGE.DocumentPreloader.prototype.state = 0; // 0: not yet started, 1: loading XML, 2: loading images, 3: completed
  19393. GLGE.DocumentPreloader.prototype.imagePreloader = null; // GLGE.Peloader
  19394. GLGE.DocumentPreloader.prototype.document = null; // GLGE.Document
  19395. /**
  19396. * Add an image, which should be loaded by the preloader.
  19397. * @param {string} url Url of the image.
  19398. */
  19399. GLGE.DocumentPreloader.prototype.addImage=function(url){
  19400. this.imagePreloader.addFile(url, "image");
  19401. }
  19402. /**
  19403. * Start loading all images in all xml files. Assumes that XML-files have finished loading.
  19404. */
  19405. GLGE.DocumentPreloader.prototype.loadImages=function(){
  19406. this.changeState(2);
  19407. if(this.progress < this.XMLQuota * 100.0) this.progress = this.XMLQuota * 100.0; // correct progress.
  19408. var that = this;
  19409. this.imagePreloader.addEventListener("progress", function(args){that.updateProgress.call(that, args);});
  19410. this.imagePreloader.addEventListener("downloadComplete", function(args){that.finish.call(that, args);});
  19411. this.imagePreloader.addEventListener("fileLoaded", function(args){that.fireEvent("fileLoaded", args.file);});
  19412. this.imagePreloader.start();
  19413. }
  19414. /**
  19415. * Update preloader progress.
  19416. * @param {object} args Progress information.
  19417. * <br />args.stepBytes describes how many bytes have been loaded since the last update.
  19418. */
  19419. GLGE.DocumentPreloader.prototype.updateProgress=function(args){
  19420. if(this.state < 2){ // loading xml
  19421. if(this.XMLBytes > 0){ // high accuracy
  19422. //if(!args.stepBytes) args.stepBytes = 0;
  19423. this.loadedBytes += args.stepBytes;
  19424. this.progress = this.XMLQuota * 100.0 * this.loadedBytes / this.XMLBytes;
  19425. }
  19426. else{ // low accuracy
  19427. this.progress += this.XMLQuota * 100.0 / this.numXMLFiles;
  19428. if(this.progress > this.XMLQuota * 100) this.progress = this.XMLQuota * 100;
  19429. }
  19430. }
  19431. else{ // loading images
  19432. this.progress = this.XMLQuota * 100 + this.imageQuota * this.imagePreloader.progress;
  19433. }
  19434. this.fireEvent("progress", {"progress":this.progress, "stepBytes":args.stepBytes, "loadedBytes":args.loadedBytes, "totalBytes":args.totalBytes, "loadedFiles": args.loadedFiles, "totalFiles": args.totalFiles});
  19435. }
  19436. /**
  19437. * This function loads a XML-file. Assumes that loading images hasn't yet begun.
  19438. * @param {string} url Url of the XML-file.
  19439. */
  19440. GLGE.DocumentPreloader.prototype.loadXMLFile=function(url){
  19441. this.changeState(1);
  19442. var xmlPreloader = new GLGE.FilePreloader();
  19443. xmlPreloader.addFile(url, "xml");
  19444. var that = this;
  19445. if(this.XMLBytes > 0) xmlPreloader.addEventListener("progress", function(arg){that.updateProgress.call(that, arg);}); // high accuracy
  19446. else xmlPreloader.addEventListener("downloadComplete", function(arg){that.updateProgress.call(that, arg);}); // low accuracy
  19447. var doc = this.document;
  19448. xmlPreloader.addEventListener("fileLoaded", function(args){
  19449. args.file.content.getElementById=doc.getElementById;
  19450. doc.loaded(args.file.url,args.file.content);
  19451. that.fireEvent("fileLoaded", args.file);
  19452. });
  19453. xmlPreloader.start();
  19454. }
  19455. /**
  19456. * Sets the state of the document preloader.
  19457. * @param {number} newState New state
  19458. */
  19459. GLGE.DocumentPreloader.prototype.changeState = function(newState) {
  19460. //if(this.state > newState) GLGE.warning("GLGE.DocumentPreloader.prototype.changeState: The new state is lower than the old.");
  19461. this.state = newState;
  19462. this.fireEvent("stateChange", newState);
  19463. }
  19464. /**
  19465. * Called when the document preloader loaded all files.
  19466. * @param {object} event Event parameter. Not used at all.
  19467. */
  19468. GLGE.DocumentPreloader.prototype.finish=function(event){
  19469. this.changeState(3);
  19470. this.progress = 100;
  19471. this.fireEvent("downloadComplete");
  19472. }
  19473. })(GLGE);
  19474. /*
  19475. Copyright (c) 2011 Martin Ruenz
  19476. Permission is hereby granted, free of charge, to any person obtaining a copy
  19477. of this software and associated documentation files (the "Software"), to deal
  19478. in the Software without restriction, including without limitation the rights
  19479. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  19480. copies of the Software, and to permit persons to whom the Software is
  19481. furnished to do so, subject to the following conditions:
  19482. The above copyright notice and this permission notice shall be included in
  19483. all copies or substantial portions of the Software.
  19484. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19485. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19486. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  19487. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19488. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19489. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  19490. THE SOFTWARE.
  19491. */
  19492. /**
  19493. * @fileOverview
  19494. * @name widget.js
  19495. * @author seamonkey@uni-koblenz.de
  19496. */
  19497. (function(GLGE){
  19498. if(typeof(GLGE.GUI) == "undefined"){
  19499. /**
  19500. * @namespace Holds the functionality of the GUI
  19501. */
  19502. GLGE.GUI = {};
  19503. }
  19504. (function(GUI){
  19505. /**
  19506. * Replace as much gui-objects as possible, with those provided by the library
  19507. */
  19508. GUI.useLibrary = function(library){
  19509. if((library == "jQuery") && jQuery) {
  19510. // progressbar
  19511. GUI.Progressbar.prototype.setValue = function(value){$(this.domRoot).progressbar({'value': value });}
  19512. GUI.Progressbar.prototype.init = function(){ $(this.domRoot).progressbar({value: 0 }); }
  19513. }
  19514. // TODO: Support for more libraries and widgets
  19515. }
  19516. /**
  19517. * @class Widget Widgets are gui objects like progressbars or sliders
  19518. */
  19519. GUI.Widget = function(){
  19520. this.domRoot = document.createElement('div');
  19521. this.domRoot.setAttribute('class','glge-gui-widget-root');
  19522. this.init();
  19523. }
  19524. GUI.Widget.prototype.domRoot = null;
  19525. GUI.Widget.prototype.init = function(){};
  19526. /**
  19527. * @class Progressbar A progressbar widget
  19528. */
  19529. GUI.Progressbar = function(){
  19530. // call super constructor
  19531. this.baseclass.call(this);
  19532. this.domRoot.className += ' glge-gui-progressbar';
  19533. }
  19534. GUI.Progressbar.prototype.value = 0;
  19535. /**
  19536. * Set the progress value
  19537. * @param {number} value progress value
  19538. */
  19539. GUI.Progressbar.prototype.setValue = function(value){
  19540. this.value = value;
  19541. }
  19542. GLGE.augment(GUI.Widget,GUI.Progressbar);
  19543. })(GLGE.GUI);})(GLGE);
  19544. /*
  19545. Copyright (c) 2011 Martin Ruenz
  19546. Permission is hereby granted, free of charge, to any person obtaining a copy
  19547. of this software and associated documentation files (the "Software"), to deal
  19548. in the Software without restriction, including without limitation the rights
  19549. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  19550. copies of the Software, and to permit persons to whom the Software is
  19551. furnished to do so, subject to the following conditions:
  19552. The above copyright notice and this permission notice shall be included in
  19553. all copies or substantial portions of the Software.
  19554. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19555. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19556. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  19557. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19558. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19559. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  19560. THE SOFTWARE.
  19561. */
  19562. /**
  19563. * @fileOverview
  19564. * @name gadget.js
  19565. * @author seamonkey@uni-koblenz.de
  19566. */
  19567. (function(GLGE){
  19568. if(typeof(GLGE.GUI) == "undefined"){
  19569. /**
  19570. * @namespace Holds the functionality of the GUI
  19571. */
  19572. GLGE.GUI = {};
  19573. }
  19574. (function(GUI){
  19575. /**
  19576. * @class Gadget Gadgets are more complex widgets. One could think of them as windows. They may contain widgets.
  19577. */
  19578. GUI.Gadget=function(){
  19579. // setup new DOM-Object
  19580. // root
  19581. this.domGadgetRoot = document.createElement('div');
  19582. this.domGadgetRoot.setAttribute('class','glge-gui-gadget-root');
  19583. this.domGadgetRoot.style.position = 'absolute';
  19584. this.domGadgetRoot.style.top = '0px';
  19585. // Outer Wrapper
  19586. this.domGadgetOuterWrapper = document.createElement('div');
  19587. this.domGadgetOuterWrapper.setAttribute('class','glge-gui-gadget-OuterWrapper');
  19588. this.domGadgetOuterWrapper.style.position = 'relative';
  19589. this.domGadgetRoot.appendChild(this.domGadgetOuterWrapper);
  19590. // Inner Wrapper
  19591. this.domGadgetInnerWrapper = document.createElement('div');
  19592. this.domGadgetInnerWrapper.setAttribute('class','glge-gui-gadget-InnerWrapper');
  19593. this.domGadgetInnerWrapper.style.position = 'relative';
  19594. this.domGadgetOuterWrapper.appendChild(this.domGadgetInnerWrapper);
  19595. // object
  19596. this.domGadgetObject = document.createElement('div');
  19597. this.domGadgetObject.setAttribute('class','glge-gui-gadget');
  19598. this.domGadgetObject.style.position = 'relative';
  19599. this.domGadgetInnerWrapper.appendChild(this.domGadgetObject);
  19600. // footer
  19601. this.domGadgetFooter = document.createElement('div');
  19602. this.domGadgetFooter.setAttribute('class','glge-gui-gadget-footer');
  19603. this.domGadgetFooter.style.clear = 'both';
  19604. this.domGadgetRoot.appendChild(this.domGadgetFooter);
  19605. // variables
  19606. this.position = {};
  19607. this.position.x = 'middle';
  19608. this.position.y = 'middle';
  19609. this.updatePosition();
  19610. }
  19611. GUI.Gadget.prototype.domGadgetRoot = null; // div: attached to dom
  19612. GUI.Gadget.prototype.domGadgetOuterWrapper = null; // div: wrapper for css (vertical align)
  19613. GUI.Gadget.prototype.domGadgetInnerWrapper = null; // div: wrapper for css (horizontal align)
  19614. GUI.Gadget.prototype.domGadgetObject = null; // div: actual gadget
  19615. GUI.Gadget.prototype.domGadgetFooter = null; // div: footer
  19616. GUI.Gadget.prototype.domGadgetParent = null; // parent object, already in dom
  19617. GUI.Gadget.prototype.position = null; // position.x, position.y
  19618. /**
  19619. * This function sets the position of the gadget
  19620. * @param {object} position position.x, possible values: "left", "middle", "right", number<br />
  19621. * position.y, possible values: "top", "middle", "bottom", number
  19622. */
  19623. GUI.Gadget.prototype.setPosition = function(position){
  19624. if(position){
  19625. if(position.x)
  19626. this.position.x = position.x;
  19627. if(position.y)
  19628. this.position.y = position.y;
  19629. }
  19630. this.updatePosition();
  19631. }
  19632. /**
  19633. * This function changes css attributes in order to position the gadget
  19634. * @param {object} position position.x, possible values: "left", "middle", "right"<br />
  19635. * position.y, possible values: "top", "middle", "bottom"
  19636. */
  19637. // TODO: Possibility to set the position absolute (e.g. x= 15, y=20)
  19638. GUI.Gadget.prototype.updatePosition = function(){
  19639. if(!this.domGadgetParent) return;
  19640. var parentPosition = '';
  19641. if(document.defaultView && document.defaultView.getComputedStyle)
  19642. parentPosition = document.defaultView.getComputedStyle(this.domGadgetParent,null).getPropertyValue('position');
  19643. else if (this.domGadgetParent.currentStyle)
  19644. parentPosition = this.domGadgetParent.currentStyle['position'];
  19645. if(parentPosition == 'absolute'){
  19646. this.domGadgetRoot.style.width = '100%';
  19647. this.domGadgetRoot.style.height = '100%';
  19648. this.domGadgetRoot.style.display = 'table';
  19649. this.domGadgetOuterWrapper.style.display = 'table-cell';
  19650. if(this.position.y == "top"){
  19651. this.domGadgetOuterWrapper.style.verticalAlign = 'top';
  19652. }
  19653. else if(this.position.y == "middle"){
  19654. this.domGadgetOuterWrapper.style.verticalAlign = 'middle';
  19655. }
  19656. else if(this.position.y == "bottom"){
  19657. this.domGadgetOuterWrapper.style.verticalAlign = 'bottom';
  19658. }
  19659. if(this.position.x == "left"){
  19660. this.domGadgetInnerWrapper.style.cssFloat = 'left';
  19661. this.domGadgetInnerWrapper.style.left = '0px';
  19662. this.domGadgetObject.style.cssFloat = 'left';
  19663. this.domGadgetObject.style.left = '0px';
  19664. }
  19665. else if(this.position.x == "middle"){
  19666. this.domGadgetInnerWrapper.style.cssFloat = 'right';
  19667. this.domGadgetInnerWrapper.style.right = '50%';
  19668. this.domGadgetObject.style.cssFloat = 'left';
  19669. this.domGadgetObject.style.right = '-50%';
  19670. }
  19671. else if(this.position.x == "right"){
  19672. this.domGadgetInnerWrapper.style.cssFloat = 'right';
  19673. this.domGadgetInnerWrapper.style.right = '0px';
  19674. this.domGadgetObject.style.cssFloat = 'right';
  19675. this.domGadgetObject.style.right = '0px';
  19676. }
  19677. }else{ // TODO: css would be much better!
  19678. if(this.position.y == "top"){
  19679. this.domGadgetRoot.style.top = this.domGadgetParent.offsetTop;
  19680. }
  19681. else if(this.position.y == "middle"){
  19682. this.domGadgetRoot.style.top = this.domGadgetParent.offsetTop + this.domGadgetParent.offsetHeight / 2 - this.domGadgetRoot.offsetHeight / 2;
  19683. }
  19684. else if(this.position.y == "bottom"){
  19685. this.domGadgetRoot.style.top = this.domGadgetParent.offsetTop + this.domGadgetParent.offsetHeight - this.domGadgetRoot.offsetHeight;
  19686. }
  19687. if(this.position.x == "left"){
  19688. this.domGadgetRoot.style.left = this.domGadgetParent.offsetLeft;
  19689. }
  19690. else if(this.position.x == "middle"){
  19691. this.domGadgetRoot.style.left = this.domGadgetParent.offsetLeft + this.domGadgetParent.offsetWidth / 2 - this.domGadgetRoot.offsetWidth / 2;
  19692. }
  19693. else if(this.position.x == "right"){
  19694. this.domGadgetRoot.style.left = this.domGadgetParent.offsetLeft + this.domGadgetParent.offsetWidth - this.domGadgetRoot.offsetWidth;
  19695. }
  19696. }
  19697. }
  19698. /**
  19699. * Add Gadget to DOM
  19700. * @param {object} element Parent element of the gadget
  19701. * @param {object} [position] position.x, possible values: "left", "middle", "right"<br />
  19702. * position.y, possible values: "top", "middle", "bottom"
  19703. */
  19704. GUI.Gadget.prototype.addToDOM = function(element, position){
  19705. this.domGadgetParent = element;
  19706. // add gadget to the document
  19707. this.domGadgetParent.appendChild(this.domGadgetRoot);
  19708. this.setPosition(position);
  19709. }
  19710. })(GLGE.GUI);})(GLGE);
  19711. /*
  19712. Copyright (c) 2011 Martin Ruenz
  19713. Permission is hereby granted, free of charge, to any person obtaining a copy
  19714. of this software and associated documentation files (the "Software"), to deal
  19715. in the Software without restriction, including without limitation the rights
  19716. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  19717. copies of the Software, and to permit persons to whom the Software is
  19718. furnished to do so, subject to the following conditions:
  19719. The above copyright notice and this permission notice shall be included in
  19720. all copies or substantial portions of the Software.
  19721. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19722. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19723. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  19724. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19725. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19726. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  19727. THE SOFTWARE.
  19728. */
  19729. /**
  19730. * @fileOverview
  19731. * @name preloader_gadget.js
  19732. * @author seamonkey@uni-koblenz.de
  19733. */
  19734. (function(GLGE){
  19735. (function(GUI){
  19736. /**
  19737. * @class Preloader gadget
  19738. * @augments GLGE.GUI.Gadget
  19739. */
  19740. GUI.Preloader=function(){
  19741. // call super constructor
  19742. this.baseclass.call(this);
  19743. this.domGadgetObject.innerHTML = "<h1>Loading</h1>";
  19744. this.domGadgetObject.className += ' glge-gui-gadget-preloader';
  19745. // progress bar
  19746. this.progressBar = new GUI.Progressbar();
  19747. this.domGadgetObject.appendChild(this.progressBar.domRoot);
  19748. this.domPercentageLabel = document.createElement('div');
  19749. this.domPercentageLabel.setAttribute('class','glge-gui-gadget-preloader-percentage');
  19750. this.domPercentageLabel.innerHTML = "<div style='float:left;'>0%</div><div style='float:right;'>100%</div></div>";
  19751. this.domGadgetObject.appendChild(this.domPercentageLabel);
  19752. // information box
  19753. this.domInfoBox = document.createElement('div');
  19754. this.domInfoBox.setAttribute('class','glge-gui-gadget-preloader-info');
  19755. this.domInfoBox.setAttribute('style','clear:both;');
  19756. this.domGadgetObject.appendChild(this.domInfoBox);
  19757. // state label
  19758. this.domStateLabel = document.createElement('div');
  19759. this.domInfoBox.appendChild(this.domStateLabel);
  19760. // bytes label
  19761. this.domBytesLabel = document.createElement('div');
  19762. this.domInfoBox.appendChild(this.domBytesLabel);
  19763. // files label
  19764. this.domFilesLabel = document.createElement('div');
  19765. this.domInfoBox.appendChild(this.domFilesLabel);
  19766. // last file label
  19767. this.domLastFileLabel = document.createElement('div');
  19768. this.domInfoBox.appendChild(this.domLastFileLabel);
  19769. }
  19770. GUI.Preloader.prototype.progressBar = null;
  19771. GUI.Preloader.prototype.documentLoader = null;
  19772. GUI.Preloader.prototype.domInfoBox = null;
  19773. GUI.Preloader.prototype.domStateLabel = null;
  19774. GUI.Preloader.prototype.domBytesLabel = null;
  19775. GUI.Preloader.prototype.domFilesLabel = null;
  19776. GUI.Preloader.prototype.domLastFileLabel = null;
  19777. GUI.Preloader.prototype.domPercentageLabel = null;
  19778. /**
  19779. * Combine the preloader gadget with an actual preloader
  19780. * @param {GLGE.DocumentPreloader} docLoader preloader
  19781. */
  19782. GUI.Preloader.prototype.setDocumentLoader = function(docLoader){
  19783. this.documentLoader = docLoader;
  19784. // add listeners
  19785. var that = this;
  19786. this.documentLoader.addEventListener("downloadComplete", function(args){that.complete(args);});
  19787. this.documentLoader.addEventListener("progress", function(args){that.progress(args);});
  19788. this.documentLoader.addEventListener("stateChange", function(args){that.stateChange(args);});
  19789. this.documentLoader.addEventListener("fileLoaded", function(args){that.fileLoaded(args);});
  19790. }
  19791. /**
  19792. * Add preloader-gadget to DOM. Creates the content of the DOM-object (domGadgetObject).
  19793. * @param {object} element Parent element of the gadget
  19794. * @param {string|object} [position] Gadget position
  19795. */
  19796. GUI.Preloader.prototype.addToDOM = function(element, position){
  19797. // update labels
  19798. this.stateChange(this.documentLoader.state);
  19799. this.progress({progress:0, loadedBytes:0, loadedFiles:0, totalFiles:0, totalBytes: 0});
  19800. this.fileLoaded({});
  19801. this.baseclass.addToDOM.call(this, element, position)
  19802. }
  19803. /**
  19804. * Called on progress
  19805. */
  19806. GUI.Preloader.prototype.progress = function(args){
  19807. //this.domProgressBar.progressbar({value: args.progress });
  19808. this.progressBar.setValue(args.progress);
  19809. this.domBytesLabel.innerHTML = args.loadedBytes + " of " + args.totalBytes + " Bytes loaded";
  19810. this.domFilesLabel.innerHTML = args.loadedFiles + " of " + args.totalFiles + " Files loaded";
  19811. }
  19812. /**
  19813. * Called when the preloader finished loading
  19814. */
  19815. GUI.Preloader.prototype.complete = function(args){
  19816. //this.domProgressBar.progressbar({value: 100 });
  19817. this.progressBar.setValue(100);
  19818. var that = this;
  19819. setTimeout ( function(){that.domGadgetRoot.parentNode.removeChild(that.domGadgetRoot)}, 300);
  19820. }
  19821. /**
  19822. * Called when the preloader changed it's state
  19823. */
  19824. GUI.Preloader.prototype.stateChange = function(args){
  19825. switch(args)
  19826. {
  19827. case 0:
  19828. case 1: this.domStateLabel.innerHTML = "Step 1 of 2: Loading XML"; break;
  19829. case 2:
  19830. case 3: this.domStateLabel.innerHTML = "Step 2 of 2: Loading Textures"; break;
  19831. }
  19832. }
  19833. /**
  19834. * Called when a file has been loaded
  19835. */
  19836. GUI.Preloader.prototype.fileLoaded = function(args){
  19837. if(args.url){
  19838. var path = args.url;
  19839. // use only 40 letters
  19840. if(path.length > 40){
  19841. path = path.slice(-37);
  19842. path = "..." + path;
  19843. }
  19844. this.domLastFileLabel.innerHTML = "Last file loaded: \"" + path + "\"";
  19845. }
  19846. else
  19847. if(this.domLastFileLabel.innerHTML == "") this.domLastFileLabel.innerHTML = "Last file loaded: <i>none</i>";
  19848. }
  19849. GLGE.augment(GUI.Gadget,GUI.Preloader);
  19850. })(GLGE.GUI);})(GLGE);