jiglib.js 454 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854108551085610857108581085910860108611086210863108641086510866108671086810869108701087110872108731087410875108761087710878108791088010881108821088310884108851088610887108881088910890108911089210893108941089510896108971089810899109001090110902109031090410905109061090710908109091091010911109121091310914109151091610917109181091910920109211092210923109241092510926109271092810929109301093110932109331093410935109361093710938109391094010941109421094310944109451094610947109481094910950109511095210953109541095510956109571095810959109601096110962109631096410965109661096710968109691097010971109721097310974109751097610977109781097910980109811098210983109841098510986109871098810989109901099110992109931099410995109961099710998109991100011001110021100311004110051100611007110081100911010110111101211013110141101511016110171101811019110201102111022110231102411025110261102711028110291103011031110321103311034110351103611037110381103911040110411104211043110441104511046110471104811049110501105111052110531105411055110561105711058110591106011061110621106311064110651106611067110681106911070110711107211073110741107511076110771107811079110801108111082110831108411085110861108711088110891109011091110921109311094110951109611097110981109911100111011110211103111041110511106111071110811109111101111111112111131111411115111161111711118111191112011121111221112311124111251112611127111281112911130111311113211133111341113511136111371113811139111401114111142111431114411145111461114711148111491115011151111521115311154111551115611157111581115911160111611116211163111641116511166111671116811169111701117111172111731117411175111761117711178111791118011181111821118311184111851118611187111881118911190111911119211193111941119511196111971119811199112001120111202112031120411205112061120711208112091121011211112121121311214112151121611217112181121911220112211122211223112241122511226112271122811229112301123111232112331123411235112361123711238112391124011241112421124311244112451124611247112481124911250112511125211253112541125511256112571125811259112601126111262112631126411265112661126711268112691127011271112721127311274112751127611277112781127911280112811128211283112841128511286112871128811289112901129111292112931129411295112961129711298112991130011301113021130311304113051130611307113081130911310113111131211313113141131511316113171131811319113201132111322113231132411325113261132711328113291133011331113321133311334113351133611337113381133911340113411134211343113441134511346113471134811349113501135111352113531135411355113561135711358113591136011361113621136311364113651136611367113681136911370113711137211373113741137511376113771137811379113801138111382113831138411385113861138711388113891139011391113921139311394113951139611397113981139911400114011140211403114041140511406114071140811409114101141111412114131141411415114161141711418114191142011421114221142311424114251142611427114281142911430114311143211433114341143511436114371143811439114401144111442114431144411445114461144711448114491145011451114521145311454114551145611457114581145911460114611146211463114641146511466114671146811469114701147111472114731147411475114761147711478114791148011481114821148311484114851148611487114881148911490114911149211493114941149511496114971149811499115001150111502115031150411505115061150711508115091151011511115121151311514115151151611517115181151911520115211152211523115241152511526115271152811529115301153111532115331153411535115361153711538115391154011541115421154311544115451154611547115481154911550115511155211553115541155511556115571155811559115601156111562115631156411565115661156711568115691157011571115721157311574115751157611577115781157911580115811158211583115841158511586115871158811589115901159111592115931159411595115961159711598115991160011601116021160311604116051160611607116081160911610116111161211613116141161511616116171161811619116201162111622116231162411625116261162711628116291163011631116321163311634116351163611637116381163911640116411164211643116441164511646116471164811649116501165111652116531165411655116561165711658116591166011661116621166311664116651166611667116681166911670116711167211673116741167511676116771167811679116801168111682116831168411685116861168711688116891169011691116921169311694116951169611697116981169911700117011170211703117041170511706117071170811709117101171111712117131171411715117161171711718117191172011721117221172311724117251172611727117281172911730117311173211733117341173511736117371173811739117401174111742117431174411745117461174711748117491175011751117521175311754117551175611757117581175911760117611176211763117641176511766117671176811769117701177111772117731177411775117761177711778117791178011781117821178311784117851178611787117881178911790117911179211793117941179511796117971179811799118001180111802118031180411805118061180711808118091181011811118121181311814118151181611817118181181911820118211182211823118241182511826118271182811829118301183111832118331183411835118361183711838118391184011841118421184311844118451184611847118481184911850118511185211853118541185511856118571185811859118601186111862118631186411865118661186711868118691187011871118721187311874118751187611877118781187911880118811188211883118841188511886118871188811889118901189111892118931189411895118961189711898118991190011901119021190311904119051190611907119081190911910119111191211913119141191511916119171191811919119201192111922119231192411925119261192711928119291193011931119321193311934119351193611937119381193911940119411194211943119441194511946119471194811949119501195111952119531195411955119561195711958119591196011961119621196311964119651196611967119681196911970119711197211973119741197511976119771197811979119801198111982119831198411985119861198711988119891199011991119921199311994119951199611997119981199912000120011200212003120041200512006120071200812009120101201112012120131201412015120161201712018120191202012021120221202312024120251202612027120281202912030120311203212033120341203512036120371203812039120401204112042120431204412045120461204712048120491205012051120521205312054120551205612057120581205912060120611206212063120641206512066120671206812069120701207112072120731207412075120761207712078120791208012081120821208312084120851208612087120881208912090120911209212093120941209512096120971209812099121001210112102121031210412105121061210712108121091211012111121121211312114121151211612117121181211912120121211212212123121241212512126121271212812129121301213112132121331213412135121361213712138121391214012141121421214312144121451214612147121481214912150121511215212153121541215512156121571215812159121601216112162121631216412165121661216712168121691217012171121721217312174121751217612177121781217912180121811218212183121841218512186121871218812189121901219112192121931219412195121961219712198121991220012201122021220312204122051220612207122081220912210122111221212213122141221512216122171221812219122201222112222122231222412225122261222712228122291223012231122321223312234122351223612237122381223912240122411224212243122441224512246122471224812249122501225112252122531225412255122561225712258122591226012261122621226312264122651226612267122681226912270122711227212273122741227512276122771227812279122801228112282122831228412285122861228712288122891229012291122921229312294122951229612297122981229912300123011230212303123041230512306123071230812309123101231112312123131231412315123161231712318123191232012321123221232312324123251232612327123281232912330123311233212333123341233512336123371233812339123401234112342123431234412345123461234712348123491235012351123521235312354123551235612357123581235912360123611236212363123641236512366123671236812369123701237112372123731237412375123761237712378123791238012381123821238312384123851238612387123881238912390123911239212393123941239512396123971239812399124001240112402124031240412405124061240712408124091241012411124121241312414124151241612417124181241912420124211242212423124241242512426124271242812429124301243112432124331243412435124361243712438124391244012441124421244312444124451244612447124481244912450124511245212453124541245512456124571245812459124601246112462124631246412465124661246712468124691247012471124721247312474124751247612477124781247912480124811248212483124841248512486124871248812489124901249112492124931249412495124961249712498124991250012501125021250312504125051250612507125081250912510125111251212513125141251512516125171251812519125201252112522125231252412525125261252712528125291253012531125321253312534125351253612537125381253912540125411254212543125441254512546125471254812549125501255112552125531255412555125561255712558125591256012561125621256312564125651256612567125681256912570125711257212573125741257512576125771257812579125801258112582125831258412585125861258712588125891259012591125921259312594125951259612597125981259912600126011260212603126041260512606126071260812609126101261112612126131261412615126161261712618126191262012621126221262312624126251262612627126281262912630126311263212633126341263512636126371263812639126401264112642126431264412645126461264712648126491265012651126521265312654126551265612657126581265912660126611266212663126641266512666126671266812669126701267112672126731267412675126761267712678126791268012681126821268312684126851268612687126881268912690126911269212693126941269512696126971269812699127001270112702127031270412705127061270712708127091271012711127121271312714127151271612717127181271912720127211272212723127241272512726127271272812729127301273112732127331273412735127361273712738127391274012741127421274312744127451274612747127481274912750127511275212753127541275512756127571275812759127601276112762127631276412765127661276712768127691277012771127721277312774127751277612777127781277912780127811278212783127841278512786127871278812789127901279112792127931279412795127961279712798127991280012801128021280312804128051280612807128081280912810128111281212813128141281512816128171281812819128201282112822128231282412825128261282712828128291283012831128321283312834128351283612837128381283912840128411284212843128441284512846128471284812849128501285112852128531285412855128561285712858128591286012861128621286312864128651286612867128681286912870128711287212873128741287512876128771287812879128801288112882128831288412885128861288712888128891289012891128921289312894128951289612897128981289912900129011290212903129041290512906129071290812909129101291112912129131291412915129161291712918129191292012921129221292312924129251292612927129281292912930129311293212933129341293512936129371293812939129401294112942129431294412945129461294712948129491295012951129521295312954129551295612957129581295912960129611296212963129641296512966129671296812969129701297112972129731297412975129761297712978129791298012981129821298312984129851298612987129881298912990129911299212993129941299512996129971299812999130001300113002130031300413005130061300713008130091301013011130121301313014130151301613017130181301913020130211302213023130241302513026130271302813029130301303113032130331303413035130361303713038130391304013041130421304313044130451304613047130481304913050130511305213053130541305513056130571305813059130601306113062130631306413065130661306713068130691307013071130721307313074130751307613077130781307913080130811308213083130841308513086130871308813089130901309113092130931309413095130961309713098130991310013101131021310313104131051310613107131081310913110131111311213113131141311513116131171311813119131201312113122131231312413125131261312713128131291313013131131321313313134131351313613137131381313913140131411314213143131441314513146131471314813149131501315113152131531315413155131561315713158131591316013161131621316313164131651316613167131681316913170131711317213173131741317513176131771317813179131801318113182131831318413185131861318713188131891319013191131921319313194131951319613197131981319913200132011320213203132041320513206132071320813209132101321113212132131321413215132161321713218132191322013221132221322313224132251322613227132281322913230132311323213233132341323513236132371323813239132401324113242132431324413245132461324713248132491325013251132521325313254132551325613257132581325913260132611326213263132641326513266132671326813269132701327113272132731327413275132761327713278132791328013281132821328313284132851328613287132881328913290132911329213293132941329513296132971329813299133001330113302133031330413305133061330713308133091331013311133121331313314133151331613317133181331913320133211332213323133241332513326133271332813329133301333113332133331333413335133361333713338133391334013341133421334313344133451334613347133481334913350133511335213353133541335513356133571335813359133601336113362133631336413365133661336713368133691337013371133721337313374133751337613377133781337913380133811338213383133841338513386133871338813389133901339113392133931339413395133961339713398133991340013401134021340313404134051340613407134081340913410134111341213413134141341513416134171341813419134201342113422134231342413425134261342713428134291343013431134321343313434134351343613437134381343913440134411344213443134441344513446134471344813449134501345113452134531345413455134561345713458134591346013461134621346313464134651346613467134681346913470134711347213473134741347513476134771347813479134801348113482134831348413485134861348713488134891349013491134921349313494134951349613497134981349913500135011350213503135041350513506135071350813509135101351113512135131351413515135161351713518135191352013521135221352313524135251352613527135281352913530135311353213533135341353513536135371353813539135401354113542135431354413545135461354713548135491355013551135521355313554135551355613557135581355913560135611356213563135641356513566135671356813569135701357113572135731357413575135761357713578135791358013581135821358313584135851358613587135881358913590135911359213593135941359513596135971359813599136001360113602136031360413605136061360713608136091361013611136121361313614136151361613617136181361913620136211362213623136241362513626136271362813629136301363113632136331363413635136361363713638136391364013641136421364313644136451364613647136481364913650136511365213653136541365513656136571365813659136601366113662136631366413665136661366713668136691367013671136721367313674136751367613677136781367913680136811368213683136841368513686136871368813689136901369113692136931369413695136961369713698136991370013701137021370313704137051370613707137081370913710137111371213713137141371513716137171371813719137201372113722137231372413725137261372713728137291373013731137321373313734137351373613737137381373913740137411374213743137441374513746137471374813749137501375113752137531375413755137561375713758137591376013761137621376313764137651376613767137681376913770137711377213773137741377513776137771377813779137801378113782137831378413785137861378713788137891379013791137921379313794137951379613797137981379913800138011380213803138041380513806138071380813809138101381113812138131381413815138161381713818138191382013821138221382313824138251382613827138281382913830138311383213833138341383513836138371383813839138401384113842138431384413845138461384713848138491385013851138521385313854138551385613857138581385913860138611386213863138641386513866138671386813869138701387113872138731387413875138761387713878138791388013881138821388313884138851388613887138881388913890138911389213893138941389513896138971389813899139001390113902139031390413905139061390713908139091391013911139121391313914139151391613917139181391913920139211392213923139241392513926139271392813929139301393113932139331393413935139361393713938139391394013941139421394313944139451394613947139481394913950139511395213953139541395513956139571395813959139601396113962139631396413965139661396713968139691397013971139721397313974139751397613977139781397913980139811398213983139841398513986139871398813989139901399113992139931399413995139961399713998139991400014001140021400314004140051400614007140081400914010140111401214013140141401514016140171401814019140201402114022140231402414025140261402714028140291403014031140321403314034140351403614037140381403914040140411404214043140441404514046140471404814049140501405114052140531405414055140561405714058140591406014061140621406314064140651406614067140681406914070140711407214073140741407514076140771407814079140801408114082140831408414085140861408714088140891409014091140921409314094140951409614097140981409914100141011410214103141041410514106141071410814109141101411114112141131411414115141161411714118141191412014121141221412314124141251412614127141281412914130141311413214133141341413514136141371413814139141401414114142141431414414145141461414714148141491415014151141521415314154141551415614157141581415914160141611416214163141641416514166141671416814169141701417114172141731417414175141761417714178141791418014181141821418314184141851418614187141881418914190141911419214193141941419514196141971419814199142001420114202142031420414205142061420714208142091421014211142121421314214142151421614217142181421914220142211422214223142241422514226142271422814229142301423114232142331423414235142361423714238142391424014241142421424314244142451424614247142481424914250142511425214253142541425514256142571425814259142601426114262142631426414265142661426714268142691427014271142721427314274142751427614277142781427914280142811428214283142841428514286142871428814289142901429114292142931429414295142961429714298142991430014301143021430314304143051430614307143081430914310143111431214313143141431514316143171431814319143201432114322143231432414325143261432714328143291433014331143321433314334143351433614337143381433914340143411434214343143441434514346143471434814349143501435114352143531435414355143561435714358143591436014361143621436314364143651436614367143681436914370143711437214373143741437514376143771437814379143801438114382143831438414385143861438714388143891439014391143921439314394143951439614397143981439914400144011440214403144041440514406144071440814409144101441114412144131441414415144161441714418144191442014421144221442314424144251442614427144281442914430144311443214433144341443514436144371443814439144401444114442144431444414445144461444714448144491445014451144521445314454144551445614457144581445914460144611446214463144641446514466144671446814469144701447114472144731447414475144761447714478144791448014481144821448314484144851448614487144881448914490144911449214493144941449514496144971449814499145001450114502145031450414505145061450714508145091451014511145121451314514145151451614517145181451914520145211452214523145241452514526145271452814529145301453114532145331453414535145361453714538145391454014541145421454314544145451454614547145481454914550145511455214553145541455514556145571455814559145601456114562145631456414565145661456714568145691457014571145721457314574145751457614577145781457914580145811458214583145841458514586145871458814589145901459114592145931459414595145961459714598145991460014601146021460314604146051460614607146081460914610146111461214613146141461514616146171461814619146201462114622146231462414625146261462714628146291463014631146321463314634146351463614637146381463914640146411464214643146441464514646146471464814649146501465114652146531465414655146561465714658146591466014661146621466314664146651466614667146681466914670146711467214673146741467514676146771467814679146801468114682146831468414685146861468714688
  1. /**
  2. This version of jiglib.js was taken from the latest version of the
  3. physicscar demo from the glge sources Scott Haynes
  4. **/
  5. /**
  6. * @name jigLib
  7. * @class jigLib the main library class
  8. * @constructor
  9. **/
  10. jigLib={};
  11. /**
  12. * @function extend handles class inheritance
  13. * @param {} dest the child class
  14. * @param {} source the parent class
  15. * @type void
  16. **/
  17. jigLib.extend=function(dest,source){
  18. for(proto in source.prototype){
  19. dest.prototype[proto]=source.prototype[proto];
  20. }
  21. dest.prototype.Super=source;
  22. };(function(jigLib){
  23. /**
  24. * @namespace JConfig a collection of configuration values
  25. * @property {string} solverType the solver to use - can be one of FAST NORMAL or ACCUMULATED
  26. * @property {string} boxCollisionsType can be one of EDGEBASE or SORTBASE
  27. * @property {string} rotationType the unit of rotation - can be one of DEGREES or RADIANS
  28. * @property {boolean} aabbDetection whether to execute aabb detection
  29. * @property {boolean} doShockStep whether to perform the shock step (helps with stacking)
  30. * @property {number} allowedPenetration the amount of penetration to be permitted
  31. * @property {number} collToll collision detection tolerance
  32. * @property {number} velThreshold the line velocity threshold for freezing
  33. * @property {number} angVelThreshold the angle velocity threshold for freezing
  34. * @property {number} posThreshold the threshold for detecting position changes during deactivation
  35. * @property {number} orientThreshold the threshold for detecting orientation changes during deactivation
  36. * @property {number} deactivationTime how long it takes to go from active to frozen when stationary
  37. * @property {number} numPenetrationRelaxationTimesteps the number of timesteps over which to resolve penetration
  38. * @property {number} numCollisionIterations the number of collision iterations
  39. * @property {number} numContactIterations the number of contact iterations
  40. * @property {number} numConstraintIterations number of constraint iterations
  41. **/
  42. jigLib.JConfig={
  43. solverType: "ACCUMULATED",
  44. boxCollisionsType: "EDGEBASE",
  45. rotationType: "DEGREES",
  46. aabbDetection: true,
  47. doShockStep: false,
  48. allowedPenetration: 0.015,
  49. collToll: 0.01,
  50. velThreshold: 0.1,
  51. angVelThreshold: 5,
  52. posThreshold: 0.1,
  53. orientThreshold: 0.1,
  54. deactivationTime: 0.1,
  55. numPenetrationRelaxationTimesteps: 20,
  56. numCollisionIterations: 4,
  57. numContactIterations: 5,
  58. numConstraintIterations: 15
  59. };
  60. })(jigLib);
  61. /*
  62. * glMatrix.js - High performance matrix and vector operations for WebGL
  63. * version 0.9.5
  64. */
  65. /*
  66. * Copyright (c) 2010 Brandon Jones
  67. *
  68. * This software is provided 'as-is', without any express or implied
  69. * warranty. In no event will the authors be held liable for any damages
  70. * arising from the use of this software.
  71. *
  72. * Permission is granted to anyone to use this software for any purpose,
  73. * including commercial applications, and to alter it and redistribute it
  74. * freely, subject to the following restrictions:
  75. *
  76. * 1. The origin of this software must not be misrepresented; you must not
  77. * claim that you wrote the original software. If you use this software
  78. * in a product, an acknowledgment in the product documentation would be
  79. * appreciated but is not required.
  80. *
  81. * 2. Altered source versions must be plainly marked as such, and must not
  82. * be misrepresented as being the original software.
  83. *
  84. * 3. This notice may not be removed or altered from any source
  85. * distribution.
  86. */
  87. (function(jigLib){
  88. // Fallback for systems that don't support WebGL
  89. if(typeof Float32Array != 'undefined') {
  90. glMatrixArrayType = Float32Array;
  91. } else if(typeof WebGLFloatArray != 'undefined') {
  92. glMatrixArrayType = WebGLFloatArray; // This is officially deprecated and should dissapear in future revisions.
  93. } else {
  94. glMatrixArrayType = Array;
  95. }
  96. /*
  97. * vec3 - 3 Dimensional Vector
  98. */
  99. var vec3 = {};
  100. /*
  101. * vec3.create
  102. * Creates a new instance of a vec3 using the default array type
  103. * Any javascript array containing at least 3 numeric elements can serve as a vec3
  104. *
  105. * Params:
  106. * vec - Optional, vec3 containing values to initialize with
  107. *
  108. * Returns:
  109. * New vec3
  110. */
  111. vec3.create = function(vec) {
  112. var dest = new glMatrixArrayType(3);
  113. if(vec) {
  114. dest[0] = vec[0];
  115. dest[1] = vec[1];
  116. dest[2] = vec[2];
  117. }
  118. return dest;
  119. };
  120. /*
  121. * vec3.set
  122. * Copies the values of one vec3 to another
  123. *
  124. * Params:
  125. * vec - vec3 containing values to copy
  126. * dest - vec3 receiving copied values
  127. *
  128. * Returns:
  129. * dest
  130. */
  131. vec3.set = function(vec, dest) {
  132. dest[0] = vec[0];
  133. dest[1] = vec[1];
  134. dest[2] = vec[2];
  135. return dest;
  136. };
  137. /*
  138. * vec3.add
  139. * Performs a vector addition
  140. *
  141. * Params:
  142. * vec - vec3, first operand
  143. * vec2 - vec3, second operand
  144. * dest - Optional, vec3 receiving operation result. If not specified result is written to vec
  145. *
  146. * Returns:
  147. * dest if specified, vec otherwise
  148. */
  149. vec3.add = function(vec, vec2, dest) {
  150. if(!dest || vec == dest) {
  151. vec[0] += vec2[0];
  152. vec[1] += vec2[1];
  153. vec[2] += vec2[2];
  154. return vec;
  155. }
  156. dest[0] = vec[0] + vec2[0];
  157. dest[1] = vec[1] + vec2[1];
  158. dest[2] = vec[2] + vec2[2];
  159. return dest;
  160. };
  161. /*
  162. * vec3.subtract
  163. * Performs a vector subtraction
  164. *
  165. * Params:
  166. * vec - vec3, first operand
  167. * vec2 - vec3, second operand
  168. * dest - Optional, vec3 receiving operation result. If not specified result is written to vec
  169. *
  170. * Returns:
  171. * dest if specified, vec otherwise
  172. */
  173. vec3.subtract = function(vec, vec2, dest) {
  174. if(!dest || vec == dest) {
  175. vec[0] -= vec2[0];
  176. vec[1] -= vec2[1];
  177. vec[2] -= vec2[2];
  178. return vec;
  179. }
  180. dest[0] = vec[0] - vec2[0];
  181. dest[1] = vec[1] - vec2[1];
  182. dest[2] = vec[2] - vec2[2];
  183. return dest;
  184. };
  185. /*
  186. * vec3.negate
  187. * Negates the components of a vec3
  188. *
  189. * Params:
  190. * vec - vec3 to negate
  191. * dest - Optional, vec3 receiving operation result. If not specified result is written to vec
  192. *
  193. * Returns:
  194. * dest if specified, vec otherwise
  195. */
  196. vec3.negate = function(vec, dest) {
  197. if(!dest) { dest = vec; }
  198. dest[0] = -vec[0];
  199. dest[1] = -vec[1];
  200. dest[2] = -vec[2];
  201. return dest;
  202. };
  203. /*
  204. * vec3.scale
  205. * Multiplies the components of a vec3 by a scalar value
  206. *
  207. * Params:
  208. * vec - vec3 to scale
  209. * val - Numeric value to scale by
  210. * dest - Optional, vec3 receiving operation result. If not specified result is written to vec
  211. *
  212. * Returns:
  213. * dest if specified, vec otherwise
  214. */
  215. vec3.scale = function(vec, val, dest) {
  216. if(!dest || vec == dest) {
  217. vec[0] *= val;
  218. vec[1] *= val;
  219. vec[2] *= val;
  220. return vec;
  221. }
  222. dest[0] = vec[0]*val;
  223. dest[1] = vec[1]*val;
  224. dest[2] = vec[2]*val;
  225. return dest;
  226. };
  227. /*
  228. * vec3.normalize
  229. * Generates a unit vector of the same direction as the provided vec3
  230. * If vector length is 0, returns [0, 0, 0]
  231. *
  232. * Params:
  233. * vec - vec3 to normalize
  234. * dest - Optional, vec3 receiving operation result. If not specified result is written to vec
  235. *
  236. * Returns:
  237. * dest if specified, vec otherwise
  238. */
  239. vec3.normalize = function(vec, dest) {
  240. if(!dest) { dest = vec; }
  241. var x = vec[0], y = vec[1], z = vec[2];
  242. var len = Math.sqrt(x*x + y*y + z*z);
  243. if (!len) {
  244. dest[0] = 0;
  245. dest[1] = 0;
  246. dest[2] = 0;
  247. return dest;
  248. } else if (len == 1) {
  249. dest[0] = x;
  250. dest[1] = y;
  251. dest[2] = z;
  252. return dest;
  253. }
  254. len = 1 / len;
  255. dest[0] = x*len;
  256. dest[1] = y*len;
  257. dest[2] = z*len;
  258. return dest;
  259. };
  260. /*
  261. * vec3.cross
  262. * Generates the cross product of two vec3s
  263. *
  264. * Params:
  265. * vec - vec3, first operand
  266. * vec2 - vec3, second operand
  267. * dest - Optional, vec3 receiving operation result. If not specified result is written to vec
  268. *
  269. * Returns:
  270. * dest if specified, vec otherwise
  271. */
  272. vec3.cross = function(vec, vec2, dest){
  273. if(!dest) { dest = vec; }
  274. var x = vec[0], y = vec[1], z = vec[2];
  275. var x2 = vec2[0], y2 = vec2[1], z2 = vec2[2];
  276. dest[0] = y*z2 - z*y2;
  277. dest[1] = z*x2 - x*z2;
  278. dest[2] = x*y2 - y*x2;
  279. return dest;
  280. };
  281. /*
  282. * vec3.length
  283. * Caclulates the length of a vec3
  284. *
  285. * Params:
  286. * vec - vec3 to calculate length of
  287. *
  288. * Returns:
  289. * Length of vec
  290. */
  291. vec3.length = function(vec){
  292. var x = vec[0], y = vec[1], z = vec[2];
  293. return Math.sqrt(x*x + y*y + z*z);
  294. };
  295. /*
  296. * vec3.dot
  297. * Caclulates the dot product of two vec3s
  298. *
  299. * Params:
  300. * vec - vec3, first operand
  301. * vec2 - vec3, second operand
  302. *
  303. * Returns:
  304. * Dot product of vec and vec2
  305. */
  306. vec3.dot = function(vec, vec2){
  307. return vec[0]*vec2[0] + vec[1]*vec2[1] + vec[2]*vec2[2];
  308. };
  309. /*
  310. * vec3.direction
  311. * Generates a unit vector pointing from one vector to another
  312. *
  313. * Params:
  314. * vec - origin vec3
  315. * vec2 - vec3 to point to
  316. * dest - Optional, vec3 receiving operation result. If not specified result is written to vec
  317. *
  318. * Returns:
  319. * dest if specified, vec otherwise
  320. */
  321. vec3.direction = function(vec, vec2, dest) {
  322. if(!dest) { dest = vec; }
  323. var x = vec[0] - vec2[0];
  324. var y = vec[1] - vec2[1];
  325. var z = vec[2] - vec2[2];
  326. var len = Math.sqrt(x*x + y*y + z*z);
  327. if (!len) {
  328. dest[0] = 0;
  329. dest[1] = 0;
  330. dest[2] = 0;
  331. return dest;
  332. }
  333. len = 1 / len;
  334. dest[0] = x * len;
  335. dest[1] = y * len;
  336. dest[2] = z * len;
  337. return dest;
  338. };
  339. /*
  340. * vec3.str
  341. * Returns a string representation of a vector
  342. *
  343. * Params:
  344. * vec - vec3 to represent as a string
  345. *
  346. * Returns:
  347. * string representation of vec
  348. */
  349. vec3.str = function(vec) {
  350. return '[' + vec[0] + ', ' + vec[1] + ', ' + vec[2] + ']';
  351. };
  352. /*
  353. * mat3 - 3x3 Matrix
  354. */
  355. var mat3 = {};
  356. /*
  357. * mat3.create
  358. * Creates a new instance of a mat3 using the default array type
  359. * Any javascript array containing at least 9 numeric elements can serve as a mat3
  360. *
  361. * Params:
  362. * mat - Optional, mat3 containing values to initialize with
  363. *
  364. * Returns:
  365. * New mat3
  366. */
  367. mat3.create = function(mat) {
  368. var dest = new glMatrixArrayType(9);
  369. if(mat) {
  370. dest[0] = mat[0];
  371. dest[1] = mat[1];
  372. dest[2] = mat[2];
  373. dest[3] = mat[3];
  374. dest[4] = mat[4];
  375. dest[5] = mat[5];
  376. dest[6] = mat[6];
  377. dest[7] = mat[7];
  378. dest[8] = mat[8];
  379. dest[9] = mat[9];
  380. }
  381. return dest;
  382. };
  383. /*
  384. * mat3.set
  385. * Copies the values of one mat3 to another
  386. *
  387. * Params:
  388. * mat - mat3 containing values to copy
  389. * dest - mat3 receiving copied values
  390. *
  391. * Returns:
  392. * dest
  393. */
  394. mat3.set = function(mat, dest) {
  395. dest[0] = mat[0];
  396. dest[1] = mat[1];
  397. dest[2] = mat[2];
  398. dest[3] = mat[3];
  399. dest[4] = mat[4];
  400. dest[5] = mat[5];
  401. dest[6] = mat[6];
  402. dest[7] = mat[7];
  403. dest[8] = mat[8];
  404. return dest;
  405. };
  406. /*
  407. * mat3.identity
  408. * Sets a mat3 to an identity matrix
  409. *
  410. * Params:
  411. * dest - mat3 to set
  412. *
  413. * Returns:
  414. * dest
  415. */
  416. mat3.identity = function(dest) {
  417. dest[0] = 1;
  418. dest[1] = 0;
  419. dest[2] = 0;
  420. dest[3] = 0;
  421. dest[4] = 1;
  422. dest[5] = 0;
  423. dest[6] = 0;
  424. dest[7] = 0;
  425. dest[8] = 1;
  426. return dest;
  427. };
  428. /*
  429. * mat3.toMat4
  430. * Copies the elements of a mat3 into the upper 3x3 elements of a mat4
  431. *
  432. * Params:
  433. * mat - mat3 containing values to copy
  434. * dest - Optional, mat4 receiving copied values
  435. *
  436. * Returns:
  437. * dest if specified, a new mat4 otherwise
  438. */
  439. mat3.toMat4 = function(mat, dest) {
  440. if(!dest) { dest = mat4.create(); }
  441. dest[0] = mat[0];
  442. dest[1] = mat[1];
  443. dest[2] = mat[2];
  444. dest[3] = 0;
  445. dest[4] = mat[3];
  446. dest[5] = mat[4];
  447. dest[6] = mat[5];
  448. dest[7] = 0;
  449. dest[8] = mat[6];
  450. dest[9] = mat[7];
  451. dest[10] = mat[8];
  452. dest[11] = 0;
  453. dest[12] = 0;
  454. dest[13] = 0;
  455. dest[14] = 0;
  456. dest[15] = 1;
  457. return dest;
  458. };
  459. /*
  460. * mat3.str
  461. * Returns a string representation of a mat3
  462. *
  463. * Params:
  464. * mat - mat3 to represent as a string
  465. *
  466. * Returns:
  467. * string representation of mat
  468. */
  469. mat3.str = function(mat) {
  470. return '[' + mat[0] + ', ' + mat[1] + ', ' + mat[2] +
  471. ', ' + mat[3] + ', '+ mat[4] + ', ' + mat[5] +
  472. ', ' + mat[6] + ', ' + mat[7] + ', '+ mat[8] + ']';
  473. };
  474. /*
  475. * mat4 - 4x4 Matrix
  476. */
  477. var mat4 = {};
  478. /*
  479. * mat4.create
  480. * Creates a new instance of a mat4 using the default array type
  481. * Any javascript array containing at least 16 numeric elements can serve as a mat4
  482. *
  483. * Params:
  484. * mat - Optional, mat4 containing values to initialize with
  485. *
  486. * Returns:
  487. * New mat4
  488. */
  489. mat4.create = function(mat) {
  490. var dest = new glMatrixArrayType(16);
  491. if(mat) {
  492. dest[0] = mat[0];
  493. dest[1] = mat[1];
  494. dest[2] = mat[2];
  495. dest[3] = mat[3];
  496. dest[4] = mat[4];
  497. dest[5] = mat[5];
  498. dest[6] = mat[6];
  499. dest[7] = mat[7];
  500. dest[8] = mat[8];
  501. dest[9] = mat[9];
  502. dest[10] = mat[10];
  503. dest[11] = mat[11];
  504. dest[12] = mat[12];
  505. dest[13] = mat[13];
  506. dest[14] = mat[14];
  507. dest[15] = mat[15];
  508. }
  509. return dest;
  510. };
  511. /*
  512. * mat4.set
  513. * Copies the values of one mat4 to another
  514. *
  515. * Params:
  516. * mat - mat4 containing values to copy
  517. * dest - mat4 receiving copied values
  518. *
  519. * Returns:
  520. * dest
  521. */
  522. mat4.set = function(mat, dest) {
  523. dest[0] = mat[0];
  524. dest[1] = mat[1];
  525. dest[2] = mat[2];
  526. dest[3] = mat[3];
  527. dest[4] = mat[4];
  528. dest[5] = mat[5];
  529. dest[6] = mat[6];
  530. dest[7] = mat[7];
  531. dest[8] = mat[8];
  532. dest[9] = mat[9];
  533. dest[10] = mat[10];
  534. dest[11] = mat[11];
  535. dest[12] = mat[12];
  536. dest[13] = mat[13];
  537. dest[14] = mat[14];
  538. dest[15] = mat[15];
  539. return dest;
  540. };
  541. /*
  542. * mat4.identity
  543. * Sets a mat4 to an identity matrix
  544. *
  545. * Params:
  546. * dest - mat4 to set
  547. *
  548. * Returns:
  549. * dest
  550. */
  551. mat4.identity = function(dest) {
  552. dest[0] = 1;
  553. dest[1] = 0;
  554. dest[2] = 0;
  555. dest[3] = 0;
  556. dest[4] = 0;
  557. dest[5] = 1;
  558. dest[6] = 0;
  559. dest[7] = 0;
  560. dest[8] = 0;
  561. dest[9] = 0;
  562. dest[10] = 1;
  563. dest[11] = 0;
  564. dest[12] = 0;
  565. dest[13] = 0;
  566. dest[14] = 0;
  567. dest[15] = 1;
  568. return dest;
  569. };
  570. /*
  571. * mat4.transpose
  572. * Transposes a mat4 (flips the values over the diagonal)
  573. *
  574. * Params:
  575. * mat - mat4 to transpose
  576. * dest - Optional, mat4 receiving transposed values. If not specified result is written to mat
  577. *
  578. * Returns:
  579. * dest is specified, mat otherwise
  580. */
  581. mat4.transpose = function(mat, dest) {
  582. // If we are transposing ourselves we can skip a few steps but have to cache some values
  583. if(!dest || mat == dest) {
  584. var a01 = mat[1], a02 = mat[2], a03 = mat[3];
  585. var a12 = mat[6], a13 = mat[7];
  586. var a23 = mat[11];
  587. mat[1] = mat[4];
  588. mat[2] = mat[8];
  589. mat[3] = mat[12];
  590. mat[4] = a01;
  591. mat[6] = mat[9];
  592. mat[7] = mat[13];
  593. mat[8] = a02;
  594. mat[9] = a12;
  595. mat[11] = mat[14];
  596. mat[12] = a03;
  597. mat[13] = a13;
  598. mat[14] = a23;
  599. return mat;
  600. }
  601. dest[0] = mat[0];
  602. dest[1] = mat[4];
  603. dest[2] = mat[8];
  604. dest[3] = mat[12];
  605. dest[4] = mat[1];
  606. dest[5] = mat[5];
  607. dest[6] = mat[9];
  608. dest[7] = mat[13];
  609. dest[8] = mat[2];
  610. dest[9] = mat[6];
  611. dest[10] = mat[10];
  612. dest[11] = mat[14];
  613. dest[12] = mat[3];
  614. dest[13] = mat[7];
  615. dest[14] = mat[11];
  616. dest[15] = mat[15];
  617. return dest;
  618. };
  619. /*
  620. * mat4.determinant
  621. * Calculates the determinant of a mat4
  622. *
  623. * Params:
  624. * mat - mat4 to calculate determinant of
  625. *
  626. * Returns:
  627. * determinant of mat
  628. */
  629. mat4.determinant = function(mat) {
  630. // Cache the matrix values (makes for huge speed increases!)
  631. var a00 = mat[0], a01 = mat[1], a02 = mat[2], a03 = mat[3];
  632. var a10 = mat[4], a11 = mat[5], a12 = mat[6], a13 = mat[7];
  633. var a20 = mat[8], a21 = mat[9], a22 = mat[10], a23 = mat[11];
  634. var a30 = mat[12], a31 = mat[13], a32 = mat[14], a33 = mat[15];
  635. return a30*a21*a12*a03 - a20*a31*a12*a03 - a30*a11*a22*a03 + a10*a31*a22*a03 +
  636. a20*a11*a32*a03 - a10*a21*a32*a03 - a30*a21*a02*a13 + a20*a31*a02*a13 +
  637. a30*a01*a22*a13 - a00*a31*a22*a13 - a20*a01*a32*a13 + a00*a21*a32*a13 +
  638. a30*a11*a02*a23 - a10*a31*a02*a23 - a30*a01*a12*a23 + a00*a31*a12*a23 +
  639. a10*a01*a32*a23 - a00*a11*a32*a23 - a20*a11*a02*a33 + a10*a21*a02*a33 +
  640. a20*a01*a12*a33 - a00*a21*a12*a33 - a10*a01*a22*a33 + a00*a11*a22*a33;
  641. };
  642. /*
  643. * mat4.inverse
  644. * Calculates the inverse matrix of a mat4
  645. *
  646. * Params:
  647. * mat - mat4 to calculate inverse of
  648. * dest - Optional, mat4 receiving inverse matrix. If not specified result is written to mat
  649. *
  650. * Returns:
  651. * dest is specified, mat otherwise
  652. */
  653. mat4.inverse = function(mat, dest) {
  654. if(!dest) { dest = mat; }
  655. // Cache the matrix values (makes for huge speed increases!)
  656. var a00 = mat[0], a01 = mat[1], a02 = mat[2], a03 = mat[3];
  657. var a10 = mat[4], a11 = mat[5], a12 = mat[6], a13 = mat[7];
  658. var a20 = mat[8], a21 = mat[9], a22 = mat[10], a23 = mat[11];
  659. var a30 = mat[12], a31 = mat[13], a32 = mat[14], a33 = mat[15];
  660. var b00 = a00*a11 - a01*a10;
  661. var b01 = a00*a12 - a02*a10;
  662. var b02 = a00*a13 - a03*a10;
  663. var b03 = a01*a12 - a02*a11;
  664. var b04 = a01*a13 - a03*a11;
  665. var b05 = a02*a13 - a03*a12;
  666. var b06 = a20*a31 - a21*a30;
  667. var b07 = a20*a32 - a22*a30;
  668. var b08 = a20*a33 - a23*a30;
  669. var b09 = a21*a32 - a22*a31;
  670. var b10 = a21*a33 - a23*a31;
  671. var b11 = a22*a33 - a23*a32;
  672. // Calculate the determinant (inlined to avoid double-caching)
  673. var invDet = 1/(b00*b11 - b01*b10 + b02*b09 + b03*b08 - b04*b07 + b05*b06);
  674. dest[0] = (a11*b11 - a12*b10 + a13*b09)*invDet;
  675. dest[1] = (-a01*b11 + a02*b10 - a03*b09)*invDet;
  676. dest[2] = (a31*b05 - a32*b04 + a33*b03)*invDet;
  677. dest[3] = (-a21*b05 + a22*b04 - a23*b03)*invDet;
  678. dest[4] = (-a10*b11 + a12*b08 - a13*b07)*invDet;
  679. dest[5] = (a00*b11 - a02*b08 + a03*b07)*invDet;
  680. dest[6] = (-a30*b05 + a32*b02 - a33*b01)*invDet;
  681. dest[7] = (a20*b05 - a22*b02 + a23*b01)*invDet;
  682. dest[8] = (a10*b10 - a11*b08 + a13*b06)*invDet;
  683. dest[9] = (-a00*b10 + a01*b08 - a03*b06)*invDet;
  684. dest[10] = (a30*b04 - a31*b02 + a33*b00)*invDet;
  685. dest[11] = (-a20*b04 + a21*b02 - a23*b00)*invDet;
  686. dest[12] = (-a10*b09 + a11*b07 - a12*b06)*invDet;
  687. dest[13] = (a00*b09 - a01*b07 + a02*b06)*invDet;
  688. dest[14] = (-a30*b03 + a31*b01 - a32*b00)*invDet;
  689. dest[15] = (a20*b03 - a21*b01 + a22*b00)*invDet;
  690. return dest;
  691. };
  692. /*
  693. * mat4.toRotationMat
  694. * Copies the upper 3x3 elements of a mat4 into another mat4
  695. *
  696. * Params:
  697. * mat - mat4 containing values to copy
  698. * dest - Optional, mat4 receiving copied values
  699. *
  700. * Returns:
  701. * dest is specified, a new mat4 otherwise
  702. */
  703. mat4.toRotationMat = function(mat, dest) {
  704. if(!dest) { dest = mat4.create(); }
  705. dest[0] = mat[0];
  706. dest[1] = mat[1];
  707. dest[2] = mat[2];
  708. dest[3] = mat[3];
  709. dest[4] = mat[4];
  710. dest[5] = mat[5];
  711. dest[6] = mat[6];
  712. dest[7] = mat[7];
  713. dest[8] = mat[8];
  714. dest[9] = mat[9];
  715. dest[10] = mat[10];
  716. dest[11] = mat[11];
  717. dest[12] = 0;
  718. dest[13] = 0;
  719. dest[14] = 0;
  720. dest[15] = 1;
  721. return dest;
  722. };
  723. /*
  724. * mat4.toMat3
  725. * Copies the upper 3x3 elements of a mat4 into a mat3
  726. *
  727. * Params:
  728. * mat - mat4 containing values to copy
  729. * dest - Optional, mat3 receiving copied values
  730. *
  731. * Returns:
  732. * dest is specified, a new mat3 otherwise
  733. */
  734. mat4.toMat3 = function(mat, dest) {
  735. if(!dest) { dest = mat3.create(); }
  736. dest[0] = mat[0];
  737. dest[1] = mat[1];
  738. dest[2] = mat[2];
  739. dest[3] = mat[4];
  740. dest[4] = mat[5];
  741. dest[5] = mat[6];
  742. dest[6] = mat[8];
  743. dest[7] = mat[9];
  744. dest[8] = mat[10];
  745. return dest;
  746. };
  747. /*
  748. * mat4.toInverseMat3
  749. * Calculates the inverse of the upper 3x3 elements of a mat4 and copies the result into a mat3
  750. * The resulting matrix is useful for calculating transformed normals
  751. *
  752. * Params:
  753. * mat - mat4 containing values to invert and copy
  754. * dest - Optional, mat3 receiving values
  755. *
  756. * Returns:
  757. * dest is specified, a new mat3 otherwise
  758. */
  759. mat4.toInverseMat3 = function(mat, dest) {
  760. // Cache the matrix values (makes for huge speed increases!)
  761. var a00 = mat[0], a01 = mat[1], a02 = mat[2];
  762. var a10 = mat[4], a11 = mat[5], a12 = mat[6];
  763. var a20 = mat[8], a21 = mat[9], a22 = mat[10];
  764. var b01 = a22*a11-a12*a21;
  765. var b11 = -a22*a10+a12*a20;
  766. var b21 = a21*a10-a11*a20;
  767. var d = a00*b01 + a01*b11 + a02*b21;
  768. if (!d) { return null; }
  769. var id = 1/d;
  770. if(!dest) { dest = mat3.create(); }
  771. dest[0] = b01*id;
  772. dest[1] = (-a22*a01 + a02*a21)*id;
  773. dest[2] = (a12*a01 - a02*a11)*id;
  774. dest[3] = b11*id;
  775. dest[4] = (a22*a00 - a02*a20)*id;
  776. dest[5] = (-a12*a00 + a02*a10)*id;
  777. dest[6] = b21*id;
  778. dest[7] = (-a21*a00 + a01*a20)*id;
  779. dest[8] = (a11*a00 - a01*a10)*id;
  780. return dest;
  781. };
  782. /*
  783. * mat4.multiply
  784. * Performs a matrix multiplication
  785. *
  786. * Params:
  787. * mat - mat4, first operand
  788. * mat2 - mat4, second operand
  789. * dest - Optional, mat4 receiving operation result. If not specified result is written to mat
  790. *
  791. * Returns:
  792. * dest if specified, mat otherwise
  793. */
  794. mat4.multiply = function(mat, mat2, dest) {
  795. if(!dest) { dest = mat; }
  796. // Cache the matrix values (makes for huge speed increases!)
  797. var a00 = mat[0], a01 = mat[1], a02 = mat[2], a03 = mat[3];
  798. var a10 = mat[4], a11 = mat[5], a12 = mat[6], a13 = mat[7];
  799. var a20 = mat[8], a21 = mat[9], a22 = mat[10], a23 = mat[11];
  800. var a30 = mat[12], a31 = mat[13], a32 = mat[14], a33 = mat[15];
  801. var b00 = mat2[0], b01 = mat2[1], b02 = mat2[2], b03 = mat2[3];
  802. var b10 = mat2[4], b11 = mat2[5], b12 = mat2[6], b13 = mat2[7];
  803. var b20 = mat2[8], b21 = mat2[9], b22 = mat2[10], b23 = mat2[11];
  804. var b30 = mat2[12], b31 = mat2[13], b32 = mat2[14], b33 = mat2[15];
  805. dest[0] = b00*a00 + b01*a10 + b02*a20 + b03*a30;
  806. dest[1] = b00*a01 + b01*a11 + b02*a21 + b03*a31;
  807. dest[2] = b00*a02 + b01*a12 + b02*a22 + b03*a32;
  808. dest[3] = b00*a03 + b01*a13 + b02*a23 + b03*a33;
  809. dest[4] = b10*a00 + b11*a10 + b12*a20 + b13*a30;
  810. dest[5] = b10*a01 + b11*a11 + b12*a21 + b13*a31;
  811. dest[6] = b10*a02 + b11*a12 + b12*a22 + b13*a32;
  812. dest[7] = b10*a03 + b11*a13 + b12*a23 + b13*a33;
  813. dest[8] = b20*a00 + b21*a10 + b22*a20 + b23*a30;
  814. dest[9] = b20*a01 + b21*a11 + b22*a21 + b23*a31;
  815. dest[10] = b20*a02 + b21*a12 + b22*a22 + b23*a32;
  816. dest[11] = b20*a03 + b21*a13 + b22*a23 + b23*a33;
  817. dest[12] = b30*a00 + b31*a10 + b32*a20 + b33*a30;
  818. dest[13] = b30*a01 + b31*a11 + b32*a21 + b33*a31;
  819. dest[14] = b30*a02 + b31*a12 + b32*a22 + b33*a32;
  820. dest[15] = b30*a03 + b31*a13 + b32*a23 + b33*a33;
  821. return dest;
  822. };
  823. /*
  824. * mat4.multiplyVec3
  825. * Transforms a vec3 with the given matrix
  826. * 4th vector component is implicitly '1'
  827. *
  828. * Params:
  829. * mat - mat4 to transform the vector with
  830. * vec - vec3 to transform
  831. * dest - Optional, vec3 receiving operation result. If not specified result is written to vec
  832. *
  833. * Returns:
  834. * dest if specified, vec otherwise
  835. */
  836. mat4.multiplyVec3 = function(mat, vec, dest) {
  837. if(!dest) { dest = vec; }
  838. var x = vec[0], y = vec[1], z = vec[2];
  839. dest[0] = mat[0]*x + mat[4]*y + mat[8]*z + mat[12];
  840. dest[1] = mat[1]*x + mat[5]*y + mat[9]*z + mat[13];
  841. dest[2] = mat[2]*x + mat[6]*y + mat[10]*z + mat[14];
  842. return dest;
  843. };
  844. /*
  845. * mat4.multiplyVec4
  846. * Transforms a vec4 with the given matrix
  847. *
  848. * Params:
  849. * mat - mat4 to transform the vector with
  850. * vec - vec4 to transform
  851. * dest - Optional, vec4 receiving operation result. If not specified result is written to vec
  852. *
  853. * Returns:
  854. * dest if specified, vec otherwise
  855. */
  856. mat4.multiplyVec4 = function(mat, vec, dest) {
  857. if(!dest) { dest = vec; }
  858. var x = vec[0], y = vec[1], z = vec[2], w = vec[3];
  859. dest[0] = mat[0]*x + mat[4]*y + mat[8]*z + mat[12]*w;
  860. dest[1] = mat[1]*x + mat[5]*y + mat[9]*z + mat[13]*w;
  861. dest[2] = mat[2]*x + mat[6]*y + mat[10]*z + mat[14]*w;
  862. dest[4] = mat[4]*x + mat[7]*y + mat[11]*z + mat[15]*w;
  863. return dest;
  864. };
  865. /*
  866. * mat4.translate
  867. * Translates a matrix by the given vector
  868. *
  869. * Params:
  870. * mat - mat4 to translate
  871. * vec - vec3 specifying the translation
  872. * dest - Optional, mat4 receiving operation result. If not specified result is written to mat
  873. *
  874. * Returns:
  875. * dest if specified, mat otherwise
  876. */
  877. mat4.translate = function(mat, vec, dest) {
  878. var x = vec[0], y = vec[1], z = vec[2];
  879. if(!dest || mat == dest) {
  880. mat[12] = mat[0]*x + mat[4]*y + mat[8]*z + mat[12];
  881. mat[13] = mat[1]*x + mat[5]*y + mat[9]*z + mat[13];
  882. mat[14] = mat[2]*x + mat[6]*y + mat[10]*z + mat[14];
  883. mat[15] = mat[3]*x + mat[7]*y + mat[11]*z + mat[15];
  884. return mat;
  885. }
  886. var a00 = mat[0], a01 = mat[1], a02 = mat[2], a03 = mat[3];
  887. var a10 = mat[4], a11 = mat[5], a12 = mat[6], a13 = mat[7];
  888. var a20 = mat[8], a21 = mat[9], a22 = mat[10], a23 = mat[11];
  889. dest[0] = a00;
  890. dest[1] = a01;
  891. dest[2] = a02;
  892. dest[3] = a03;
  893. dest[4] = a10;
  894. dest[5] = a11;
  895. dest[6] = a12;
  896. dest[7] = a13;
  897. dest[8] = a20;
  898. dest[9] = a21;
  899. dest[10] = a22;
  900. dest[11] = a23;
  901. dest[12] = a00*x + a10*y + a20*z + mat[12];
  902. dest[13] = a01*x + a11*y + a21*z + mat[13];
  903. dest[14] = a02*x + a12*y + a22*z + mat[14];
  904. dest[15] = a03*x + a13*y + a23*z + mat[15];
  905. return dest;
  906. };
  907. /*
  908. * mat4.scale
  909. * Scales a matrix by the given vector
  910. *
  911. * Params:
  912. * mat - mat4 to scale
  913. * vec - vec3 specifying the scale for each axis
  914. * dest - Optional, mat4 receiving operation result. If not specified result is written to mat
  915. *
  916. * Returns:
  917. * dest if specified, mat otherwise
  918. */
  919. mat4.scale = function(mat, vec, dest) {
  920. var x = vec[0], y = vec[1], z = vec[2];
  921. if(!dest || mat == dest) {
  922. mat[0] *= x;
  923. mat[1] *= x;
  924. mat[2] *= x;
  925. mat[3] *= x;
  926. mat[4] *= y;
  927. mat[5] *= y;
  928. mat[6] *= y;
  929. mat[7] *= y;
  930. mat[8] *= z;
  931. mat[9] *= z;
  932. mat[10] *= z;
  933. mat[11] *= z;
  934. return mat;
  935. }
  936. dest[0] = mat[0]*x;
  937. dest[1] = mat[1]*x;
  938. dest[2] = mat[2]*x;
  939. dest[3] = mat[3]*x;
  940. dest[4] = mat[4]*y;
  941. dest[5] = mat[5]*y;
  942. dest[6] = mat[6]*y;
  943. dest[7] = mat[7]*y;
  944. dest[8] = mat[8]*z;
  945. dest[9] = mat[9]*z;
  946. dest[10] = mat[10]*z;
  947. dest[11] = mat[11]*z;
  948. dest[12] = mat[12];
  949. dest[13] = mat[13];
  950. dest[14] = mat[14];
  951. dest[15] = mat[15];
  952. return dest;
  953. };
  954. /*
  955. * mat4.rotate
  956. * Rotates a matrix by the given angle around the specified axis
  957. * If rotating around a primary axis (X,Y,Z) one of the specialized rotation functions should be used instead for performance
  958. *
  959. * Params:
  960. * mat - mat4 to rotate
  961. * angle - angle (in radians) to rotate
  962. * axis - vec3 representing the axis to rotate around
  963. * dest - Optional, mat4 receiving operation result. If not specified result is written to mat
  964. *
  965. * Returns:
  966. * dest if specified, mat otherwise
  967. */
  968. mat4.rotate = function(mat, angle, axis, dest) {
  969. var x = axis[0], y = axis[1], z = axis[2];
  970. var len = Math.sqrt(x*x + y*y + z*z);
  971. if (!len) { return null; }
  972. if (len != 1) {
  973. len = 1 / len;
  974. x *= len;
  975. y *= len;
  976. z *= len;
  977. }
  978. var s = Math.sin(angle);
  979. var c = Math.cos(angle);
  980. var t = 1-c;
  981. // Cache the matrix values (makes for huge speed increases!)
  982. var a00 = mat[0], a01 = mat[1], a02 = mat[2], a03 = mat[3];
  983. var a10 = mat[4], a11 = mat[5], a12 = mat[6], a13 = mat[7];
  984. var a20 = mat[8], a21 = mat[9], a22 = mat[10], a23 = mat[11];
  985. // Construct the elements of the rotation matrix
  986. var b00 = x*x*t + c, b01 = y*x*t + z*s, b02 = z*x*t - y*s;
  987. var b10 = x*y*t - z*s, b11 = y*y*t + c, b12 = z*y*t + x*s;
  988. var b20 = x*z*t + y*s, b21 = y*z*t - x*s, b22 = z*z*t + c;
  989. if(!dest) {
  990. dest = mat;
  991. } else if(mat != dest) { // If the source and destination differ, copy the unchanged last row
  992. dest[12] = mat[12];
  993. dest[13] = mat[13];
  994. dest[14] = mat[14];
  995. dest[15] = mat[15];
  996. }
  997. // Perform rotation-specific matrix multiplication
  998. dest[0] = a00*b00 + a10*b01 + a20*b02;
  999. dest[1] = a01*b00 + a11*b01 + a21*b02;
  1000. dest[2] = a02*b00 + a12*b01 + a22*b02;
  1001. dest[3] = a03*b00 + a13*b01 + a23*b02;
  1002. dest[4] = a00*b10 + a10*b11 + a20*b12;
  1003. dest[5] = a01*b10 + a11*b11 + a21*b12;
  1004. dest[6] = a02*b10 + a12*b11 + a22*b12;
  1005. dest[7] = a03*b10 + a13*b11 + a23*b12;
  1006. dest[8] = a00*b20 + a10*b21 + a20*b22;
  1007. dest[9] = a01*b20 + a11*b21 + a21*b22;
  1008. dest[10] = a02*b20 + a12*b21 + a22*b22;
  1009. dest[11] = a03*b20 + a13*b21 + a23*b22;
  1010. return dest;
  1011. };
  1012. /*
  1013. * mat4.rotateX
  1014. * Rotates a matrix by the given angle around the X axis
  1015. *
  1016. * Params:
  1017. * mat - mat4 to rotate
  1018. * angle - angle (in radians) to rotate
  1019. * dest - Optional, mat4 receiving operation result. If not specified result is written to mat
  1020. *
  1021. * Returns:
  1022. * dest if specified, mat otherwise
  1023. */
  1024. mat4.rotateX = function(mat, angle, dest) {
  1025. var s = Math.sin(angle);
  1026. var c = Math.cos(angle);
  1027. // Cache the matrix values (makes for huge speed increases!)
  1028. var a10 = mat[4], a11 = mat[5], a12 = mat[6], a13 = mat[7];
  1029. var a20 = mat[8], a21 = mat[9], a22 = mat[10], a23 = mat[11];
  1030. if(!dest) {
  1031. dest = mat;
  1032. } else if(mat != dest) { // If the source and destination differ, copy the unchanged rows
  1033. dest[0] = mat[0];
  1034. dest[1] = mat[1];
  1035. dest[2] = mat[2];
  1036. dest[3] = mat[3];
  1037. dest[12] = mat[12];
  1038. dest[13] = mat[13];
  1039. dest[14] = mat[14];
  1040. dest[15] = mat[15];
  1041. }
  1042. // Perform axis-specific matrix multiplication
  1043. dest[4] = a10*c + a20*s;
  1044. dest[5] = a11*c + a21*s;
  1045. dest[6] = a12*c + a22*s;
  1046. dest[7] = a13*c + a23*s;
  1047. dest[8] = a10*-s + a20*c;
  1048. dest[9] = a11*-s + a21*c;
  1049. dest[10] = a12*-s + a22*c;
  1050. dest[11] = a13*-s + a23*c;
  1051. return dest;
  1052. };
  1053. /*
  1054. * mat4.rotateY
  1055. * Rotates a matrix by the given angle around the Y axis
  1056. *
  1057. * Params:
  1058. * mat - mat4 to rotate
  1059. * angle - angle (in radians) to rotate
  1060. * dest - Optional, mat4 receiving operation result. If not specified result is written to mat
  1061. *
  1062. * Returns:
  1063. * dest if specified, mat otherwise
  1064. */
  1065. mat4.rotateY = function(mat, angle, dest) {
  1066. var s = Math.sin(angle);
  1067. var c = Math.cos(angle);
  1068. // Cache the matrix values (makes for huge speed increases!)
  1069. var a00 = mat[0], a01 = mat[1], a02 = mat[2], a03 = mat[3];
  1070. var a20 = mat[8], a21 = mat[9], a22 = mat[10], a23 = mat[11];
  1071. if(!dest) {
  1072. dest = mat;
  1073. } else if(mat != dest) { // If the source and destination differ, copy the unchanged rows
  1074. dest[4] = mat[4];
  1075. dest[5] = mat[5];
  1076. dest[6] = mat[6];
  1077. dest[7] = mat[7];
  1078. dest[12] = mat[12];
  1079. dest[13] = mat[13];
  1080. dest[14] = mat[14];
  1081. dest[15] = mat[15];
  1082. }
  1083. // Perform axis-specific matrix multiplication
  1084. dest[0] = a00*c + a20*-s;
  1085. dest[1] = a01*c + a21*-s;
  1086. dest[2] = a02*c + a22*-s;
  1087. dest[3] = a03*c + a23*-s;
  1088. dest[8] = a00*s + a20*c;
  1089. dest[9] = a01*s + a21*c;
  1090. dest[10] = a02*s + a22*c;
  1091. dest[11] = a03*s + a23*c;
  1092. return dest;
  1093. };
  1094. /*
  1095. * mat4.rotateZ
  1096. * Rotates a matrix by the given angle around the Z axis
  1097. *
  1098. * Params:
  1099. * mat - mat4 to rotate
  1100. * angle - angle (in radians) to rotate
  1101. * dest - Optional, mat4 receiving operation result. If not specified result is written to mat
  1102. *
  1103. * Returns:
  1104. * dest if specified, mat otherwise
  1105. */
  1106. mat4.rotateZ = function(mat, angle, dest) {
  1107. var s = Math.sin(angle);
  1108. var c = Math.cos(angle);
  1109. // Cache the matrix values (makes for huge speed increases!)
  1110. var a00 = mat[0], a01 = mat[1], a02 = mat[2], a03 = mat[3];
  1111. var a10 = mat[4], a11 = mat[5], a12 = mat[6], a13 = mat[7];
  1112. if(!dest) {
  1113. dest = mat;
  1114. } else if(mat != dest) { // If the source and destination differ, copy the unchanged last row
  1115. dest[8] = mat[8];
  1116. dest[9] = mat[9];
  1117. dest[10] = mat[10];
  1118. dest[11] = mat[11];
  1119. dest[12] = mat[12];
  1120. dest[13] = mat[13];
  1121. dest[14] = mat[14];
  1122. dest[15] = mat[15];
  1123. }
  1124. // Perform axis-specific matrix multiplication
  1125. dest[0] = a00*c + a10*s;
  1126. dest[1] = a01*c + a11*s;
  1127. dest[2] = a02*c + a12*s;
  1128. dest[3] = a03*c + a13*s;
  1129. dest[4] = a00*-s + a10*c;
  1130. dest[5] = a01*-s + a11*c;
  1131. dest[6] = a02*-s + a12*c;
  1132. dest[7] = a03*-s + a13*c;
  1133. return dest;
  1134. };
  1135. /*
  1136. * mat4.frustum
  1137. * Generates a frustum matrix with the given bounds
  1138. *
  1139. * Params:
  1140. * left, right - scalar, left and right bounds of the frustum
  1141. * bottom, top - scalar, bottom and top bounds of the frustum
  1142. * near, far - scalar, near and far bounds of the frustum
  1143. * dest - Optional, mat4 frustum matrix will be written into
  1144. *
  1145. * Returns:
  1146. * dest if specified, a new mat4 otherwise
  1147. */
  1148. mat4.frustum = function(left, right, bottom, top, near, far, dest) {
  1149. if(!dest) { dest = mat4.create(); }
  1150. var rl = (right - left);
  1151. var tb = (top - bottom);
  1152. var fn = (far - near);
  1153. dest[0] = (near*2) / rl;
  1154. dest[1] = 0;
  1155. dest[2] = 0;
  1156. dest[3] = 0;
  1157. dest[4] = 0;
  1158. dest[5] = (near*2) / tb;
  1159. dest[6] = 0;
  1160. dest[7] = 0;
  1161. dest[8] = (right + left) / rl;
  1162. dest[9] = (top + bottom) / tb;
  1163. dest[10] = -(far + near) / fn;
  1164. dest[11] = -1;
  1165. dest[12] = 0;
  1166. dest[13] = 0;
  1167. dest[14] = -(far*near*2) / fn;
  1168. dest[15] = 0;
  1169. return dest;
  1170. };
  1171. /*
  1172. * mat4.perspective
  1173. * Generates a perspective projection matrix with the given bounds
  1174. *
  1175. * Params:
  1176. * fovy - scalar, vertical field of view
  1177. * aspect - scalar, aspect ratio. typically viewport width/height
  1178. * near, far - scalar, near and far bounds of the frustum
  1179. * dest - Optional, mat4 frustum matrix will be written into
  1180. *
  1181. * Returns:
  1182. * dest if specified, a new mat4 otherwise
  1183. */
  1184. mat4.perspective = function(fovy, aspect, near, far, dest) {
  1185. var top = near*Math.tan(fovy*Math.PI / 360.0);
  1186. var right = top*aspect;
  1187. return mat4.frustum(-right, right, -top, top, near, far, dest);
  1188. };
  1189. /*
  1190. * mat4.ortho
  1191. * Generates a orthogonal projection matrix with the given bounds
  1192. *
  1193. * Params:
  1194. * left, right - scalar, left and right bounds of the frustum
  1195. * bottom, top - scalar, bottom and top bounds of the frustum
  1196. * near, far - scalar, near and far bounds of the frustum
  1197. * dest - Optional, mat4 frustum matrix will be written into
  1198. *
  1199. * Returns:
  1200. * dest if specified, a new mat4 otherwise
  1201. */
  1202. mat4.ortho = function(left, right, bottom, top, near, far, dest) {
  1203. if(!dest) { dest = mat4.create(); }
  1204. var rl = (right - left);
  1205. var tb = (top - bottom);
  1206. var fn = (far - near);
  1207. dest[0] = 2 / rl;
  1208. dest[1] = 0;
  1209. dest[2] = 0;
  1210. dest[3] = 0;
  1211. dest[4] = 0;
  1212. dest[5] = 2 / tb;
  1213. dest[6] = 0;
  1214. dest[7] = 0;
  1215. dest[8] = 0;
  1216. dest[9] = 0;
  1217. dest[10] = -2 / fn;
  1218. dest[11] = 0;
  1219. dest[12] = -(left + right) / rl;
  1220. dest[13] = -(top + bottom) / tb;
  1221. dest[14] = -(far + near) / fn;
  1222. dest[15] = 1;
  1223. return dest;
  1224. };
  1225. /*
  1226. * mat4.ortho
  1227. * Generates a look-at matrix with the given eye position, focal point, and up axis
  1228. *
  1229. * Params:
  1230. * eye - vec3, position of the viewer
  1231. * center - vec3, point the viewer is looking at
  1232. * up - vec3 pointing "up"
  1233. * dest - Optional, mat4 frustum matrix will be written into
  1234. *
  1235. * Returns:
  1236. * dest if specified, a new mat4 otherwise
  1237. */
  1238. mat4.lookAt = function(eye, center, up, dest) {
  1239. if(!dest) { dest = mat4.create(); }
  1240. var eyex = eye[0],
  1241. eyey = eye[1],
  1242. eyez = eye[2],
  1243. upx = up[0],
  1244. upy = up[1],
  1245. upz = up[2],
  1246. centerx = center[0],
  1247. centery = center[1],
  1248. centerz = center[2];
  1249. if (eyex == centerx && eyey == centery && eyez == centerz) {
  1250. return mat4.identity(dest);
  1251. }
  1252. var z0,z1,z2,x0,x1,x2,y0,y1,y2,len;
  1253. //vec3.direction(eye, center, z);
  1254. z0 = eyex - center[0];
  1255. z1 = eyey - center[1];
  1256. z2 = eyez - center[2];
  1257. // normalize (no check needed for 0 because of early return)
  1258. len = 1/Math.sqrt(z0*z0 + z1*z1 + z2*z2);
  1259. z0 *= len;
  1260. z1 *= len;
  1261. z2 *= len;
  1262. //vec3.normalize(vec3.cross(up, z, x));
  1263. x0 = upy*z2 - upz*z1;
  1264. x1 = upz*z0 - upx*z2;
  1265. x2 = upx*z1 - upy*z0;
  1266. len = Math.sqrt(x0*x0 + x1*x1 + x2*x2);
  1267. if (!len) {
  1268. x0 = 0;
  1269. x1 = 0;
  1270. x2 = 0;
  1271. } else {
  1272. len = 1/len;
  1273. x0 *= len;
  1274. x1 *= len;
  1275. x2 *= len;
  1276. };
  1277. //vec3.normalize(vec3.cross(z, x, y));
  1278. y0 = z1*x2 - z2*x1;
  1279. y1 = z2*x0 - z0*x2;
  1280. y2 = z0*x1 - z1*x0;
  1281. len = Math.sqrt(y0*y0 + y1*y1 + y2*y2);
  1282. if (!len) {
  1283. y0 = 0;
  1284. y1 = 0;
  1285. y2 = 0;
  1286. } else {
  1287. len = 1/len;
  1288. y0 *= len;
  1289. y1 *= len;
  1290. y2 *= len;
  1291. }
  1292. dest[0] = x0;
  1293. dest[1] = y0;
  1294. dest[2] = z0;
  1295. dest[3] = 0;
  1296. dest[4] = x1;
  1297. dest[5] = y1;
  1298. dest[6] = z1;
  1299. dest[7] = 0;
  1300. dest[8] = x2;
  1301. dest[9] = y2;
  1302. dest[10] = z2;
  1303. dest[11] = 0;
  1304. dest[12] = -(x0*eyex + x1*eyey + x2*eyez);
  1305. dest[13] = -(y0*eyex + y1*eyey + y2*eyez);
  1306. dest[14] = -(z0*eyex + z1*eyey + z2*eyez);
  1307. dest[15] = 1;
  1308. return dest;
  1309. };
  1310. /*
  1311. * mat4.str
  1312. * Returns a string representation of a mat4
  1313. *
  1314. * Params:
  1315. * mat - mat4 to represent as a string
  1316. *
  1317. * Returns:
  1318. * string representation of mat
  1319. */
  1320. mat4.str = function(mat) {
  1321. return '[' + mat[0] + ', ' + mat[1] + ', ' + mat[2] + ', ' + mat[3] +
  1322. ', '+ mat[4] + ', ' + mat[5] + ', ' + mat[6] + ', ' + mat[7] +
  1323. ', '+ mat[8] + ', ' + mat[9] + ', ' + mat[10] + ', ' + mat[11] +
  1324. ', '+ mat[12] + ', ' + mat[13] + ', ' + mat[14] + ', ' + mat[15] + ']';
  1325. };
  1326. /*
  1327. * quat4 - Quaternions
  1328. */
  1329. quat4 = {};
  1330. /*
  1331. * quat4.create
  1332. * Creates a new instance of a quat4 using the default array type
  1333. * Any javascript array containing at least 4 numeric elements can serve as a quat4
  1334. *
  1335. * Params:
  1336. * quat - Optional, quat4 containing values to initialize with
  1337. *
  1338. * Returns:
  1339. * New quat4
  1340. */
  1341. quat4.create = function(quat) {
  1342. var dest = new glMatrixArrayType(4);
  1343. if(quat) {
  1344. dest[0] = quat[0];
  1345. dest[1] = quat[1];
  1346. dest[2] = quat[2];
  1347. dest[3] = quat[3];
  1348. }
  1349. return dest;
  1350. };
  1351. /*
  1352. * quat4.set
  1353. * Copies the values of one quat4 to another
  1354. *
  1355. * Params:
  1356. * quat - quat4 containing values to copy
  1357. * dest - quat4 receiving copied values
  1358. *
  1359. * Returns:
  1360. * dest
  1361. */
  1362. quat4.set = function(quat, dest) {
  1363. dest[0] = quat[0];
  1364. dest[1] = quat[1];
  1365. dest[2] = quat[2];
  1366. dest[3] = quat[3];
  1367. return dest;
  1368. };
  1369. /*
  1370. * quat4.calculateW
  1371. * Calculates the W component of a quat4 from the X, Y, and Z components.
  1372. * Assumes that quaternion is 1 unit in length.
  1373. * Any existing W component will be ignored.
  1374. *
  1375. * Params:
  1376. * quat - quat4 to calculate W component of
  1377. * dest - Optional, quat4 receiving calculated values. If not specified result is written to quat
  1378. *
  1379. * Returns:
  1380. * dest if specified, quat otherwise
  1381. */
  1382. quat4.calculateW = function(quat, dest) {
  1383. var x = quat[0], y = quat[1], z = quat[2];
  1384. if(!dest || quat == dest) {
  1385. quat[3] = -Math.sqrt(Math.abs(1.0 - x*x - y*y - z*z));
  1386. return quat;
  1387. }
  1388. dest[0] = x;
  1389. dest[1] = y;
  1390. dest[2] = z;
  1391. dest[3] = -Math.sqrt(Math.abs(1.0 - x*x - y*y - z*z));
  1392. return dest;
  1393. };
  1394. /*
  1395. * quat4.inverse
  1396. * Calculates the inverse of a quat4
  1397. *
  1398. * Params:
  1399. * quat - quat4 to calculate inverse of
  1400. * dest - Optional, quat4 receiving inverse values. If not specified result is written to quat
  1401. *
  1402. * Returns:
  1403. * dest if specified, quat otherwise
  1404. */
  1405. quat4.inverse = function(quat, dest) {
  1406. if(!dest || quat == dest) {
  1407. quat[0] *= 1;
  1408. quat[1] *= 1;
  1409. quat[2] *= 1;
  1410. return quat;
  1411. }
  1412. dest[0] = -quat[0];
  1413. dest[1] = -quat[1];
  1414. dest[2] = -quat[2];
  1415. dest[3] = quat[3];
  1416. return dest;
  1417. };
  1418. /*
  1419. * quat4.length
  1420. * Calculates the length of a quat4
  1421. *
  1422. * Params:
  1423. * quat - quat4 to calculate length of
  1424. *
  1425. * Returns:
  1426. * Length of quat
  1427. */
  1428. quat4.length = function(quat) {
  1429. var x = quat[0], y = quat[1], z = quat[2], w = quat[3];
  1430. return Math.sqrt(x*x + y*y + z*z + w*w);
  1431. };
  1432. /*
  1433. * quat4.normalize
  1434. * Generates a unit quaternion of the same direction as the provided quat4
  1435. * If quaternion length is 0, returns [0, 0, 0, 0]
  1436. *
  1437. * Params:
  1438. * quat - quat4 to normalize
  1439. * dest - Optional, quat4 receiving operation result. If not specified result is written to quat
  1440. *
  1441. * Returns:
  1442. * dest if specified, quat otherwise
  1443. */
  1444. quat4.normalize = function(quat, dest) {
  1445. if(!dest) { dest = quat; }
  1446. var x = quat[0], y = quat[1], z = quat[2], w = quat[3];
  1447. var len = Math.sqrt(x*x + y*y + z*z + w*w);
  1448. if(len == 0) {
  1449. dest[0] = 0;
  1450. dest[1] = 0;
  1451. dest[2] = 0;
  1452. dest[3] = 0;
  1453. return dest;
  1454. }
  1455. len = 1/len;
  1456. dest[0] = x * len;
  1457. dest[1] = y * len;
  1458. dest[2] = z * len;
  1459. dest[3] = w * len;
  1460. return dest;
  1461. };
  1462. /*
  1463. * quat4.multiply
  1464. * Performs a quaternion multiplication
  1465. *
  1466. * Params:
  1467. * quat - quat4, first operand
  1468. * quat2 - quat4, second operand
  1469. * dest - Optional, quat4 receiving operation result. If not specified result is written to quat
  1470. *
  1471. * Returns:
  1472. * dest if specified, quat otherwise
  1473. */
  1474. quat4.multiply = function(quat, quat2, dest) {
  1475. if(!dest) { dest = quat; }
  1476. var qax = quat[0], qay = quat[1], qaz = quat[2], qaw = quat[3];
  1477. var qbx = quat2[0], qby = quat2[1], qbz = quat2[2], qbw = quat2[3];
  1478. dest[0] = qax*qbw + qaw*qbx + qay*qbz - qaz*qby;
  1479. dest[1] = qay*qbw + qaw*qby + qaz*qbx - qax*qbz;
  1480. dest[2] = qaz*qbw + qaw*qbz + qax*qby - qay*qbx;
  1481. dest[3] = qaw*qbw - qax*qbx - qay*qby - qaz*qbz;
  1482. return dest;
  1483. };
  1484. /*
  1485. * quat4.multiplyVec3
  1486. * Transforms a vec3 with the given quaternion
  1487. *
  1488. * Params:
  1489. * quat - quat4 to transform the vector with
  1490. * vec - vec3 to transform
  1491. * dest - Optional, vec3 receiving operation result. If not specified result is written to vec
  1492. *
  1493. * Returns:
  1494. * dest if specified, vec otherwise
  1495. */
  1496. quat4.multiplyVec3 = function(quat, vec, dest) {
  1497. if(!dest) { dest = vec; }
  1498. var x = vec[0], y = vec[1], z = vec[2];
  1499. var qx = quat[0], qy = quat[1], qz = quat[2], qw = quat[3];
  1500. // calculate quat * vec
  1501. var ix = qw*x + qy*z - qz*y;
  1502. var iy = qw*y + qz*x - qx*z;
  1503. var iz = qw*z + qx*y - qy*x;
  1504. var iw = -qx*x - qy*y - qz*z;
  1505. // calculate result * inverse quat
  1506. dest[0] = ix*qw + iw*-qx + iy*-qz - iz*-qy;
  1507. dest[1] = iy*qw + iw*-qy + iz*-qx - ix*-qz;
  1508. dest[2] = iz*qw + iw*-qz + ix*-qy - iy*-qx;
  1509. return dest;
  1510. };
  1511. /*
  1512. * quat4.toMat3
  1513. * Calculates a 3x3 matrix from the given quat4
  1514. *
  1515. * Params:
  1516. * quat - quat4 to create matrix from
  1517. * dest - Optional, mat3 receiving operation result
  1518. *
  1519. * Returns:
  1520. * dest if specified, a new mat3 otherwise
  1521. */
  1522. quat4.toMat3 = function(quat, dest) {
  1523. if(!dest) { dest = mat3.create(); }
  1524. var x = quat[0], y = quat[1], z = quat[2], w = quat[3];
  1525. var x2 = x + x;
  1526. var y2 = y + y;
  1527. var z2 = z + z;
  1528. var xx = x*x2;
  1529. var xy = x*y2;
  1530. var xz = x*z2;
  1531. var yy = y*y2;
  1532. var yz = y*z2;
  1533. var zz = z*z2;
  1534. var wx = w*x2;
  1535. var wy = w*y2;
  1536. var wz = w*z2;
  1537. dest[0] = 1 - (yy + zz);
  1538. dest[1] = xy - wz;
  1539. dest[2] = xz + wy;
  1540. dest[3] = xy + wz;
  1541. dest[4] = 1 - (xx + zz);
  1542. dest[5] = yz - wx;
  1543. dest[6] = xz - wy;
  1544. dest[7] = yz + wx;
  1545. dest[8] = 1 - (xx + yy);
  1546. return dest;
  1547. };
  1548. /*
  1549. * quat4.toMat4
  1550. * Calculates a 4x4 matrix from the given quat4
  1551. *
  1552. * Params:
  1553. * quat - quat4 to create matrix from
  1554. * dest - Optional, mat4 receiving operation result
  1555. *
  1556. * Returns:
  1557. * dest if specified, a new mat4 otherwise
  1558. */
  1559. quat4.toMat4 = function(quat, dest) {
  1560. if(!dest) { dest = mat4.create(); }
  1561. var x = quat[0], y = quat[1], z = quat[2], w = quat[3];
  1562. var x2 = x + x;
  1563. var y2 = y + y;
  1564. var z2 = z + z;
  1565. var xx = x*x2;
  1566. var xy = x*y2;
  1567. var xz = x*z2;
  1568. var yy = y*y2;
  1569. var yz = y*z2;
  1570. var zz = z*z2;
  1571. var wx = w*x2;
  1572. var wy = w*y2;
  1573. var wz = w*z2;
  1574. dest[0] = 1 - (yy + zz);
  1575. dest[1] = xy - wz;
  1576. dest[2] = xz + wy;
  1577. dest[3] = 0;
  1578. dest[4] = xy + wz;
  1579. dest[5] = 1 - (xx + zz);
  1580. dest[6] = yz - wx;
  1581. dest[7] = 0;
  1582. dest[8] = xz - wy;
  1583. dest[9] = yz + wx;
  1584. dest[10] = 1 - (xx + yy);
  1585. dest[11] = 0;
  1586. dest[12] = 0;
  1587. dest[13] = 0;
  1588. dest[14] = 0;
  1589. dest[15] = 1;
  1590. return dest;
  1591. };
  1592. /*
  1593. * quat4.str
  1594. * Returns a string representation of a quaternion
  1595. *
  1596. * Params:
  1597. * quat - quat4 to represent as a string
  1598. *
  1599. * Returns:
  1600. * string representation of quat
  1601. */
  1602. quat4.str = function(quat) {
  1603. return '[' + quat[0] + ', ' + quat[1] + ', ' + quat[2] + ', ' + quat[3] + ']';
  1604. };
  1605. jigLib.GLMatrix=mat4;
  1606. })(jigLib);
  1607. (function(jigLib){
  1608. /**
  1609. * @author Jim Sangwine
  1610. *
  1611. * These methods were originally in the Vector3D object ported by Paul Brunt from Flex.
  1612. *
  1613. * @name Vector3DUtil
  1614. * @class Vector3DUtil a utility class (containing only static members) for manipulation of 3D vectors expressed as arrays
  1615. * @constant {array} X_AXIS
  1616. * @constant {array} Y_AXIS
  1617. * @constant {array} Z_AXIS
  1618. * @constructor
  1619. * @throws Error on attempted instantiation
  1620. **/
  1621. var Vector3DUtil=function(){ throw new Error('Vector3DUtil is a utility class and should not be instantiated'); };
  1622. Vector3DUtil.X_AXIS=[1,0,0,0];
  1623. Vector3DUtil.Y_AXIS=[0,1,0,0];
  1624. Vector3DUtil.Z_AXIS=[0,0,1,0];
  1625. /**
  1626. * @function add returns a new 3D vector that is the sum of v1 and v2
  1627. * @static
  1628. * @param v1 {array} in the format [x,y,z,w]
  1629. * @param v2 {array} in the format [x,y,z,w]
  1630. * @type array
  1631. **/
  1632. Vector3DUtil.add=function(v1,v2){
  1633. return [v1[0]+v2[0],v1[1]+v2[1],v1[2]+v2[2],v1[3]+v2[3]];
  1634. };
  1635. /**
  1636. * @function subtract returns a new 3D vector that is the result of v2 subtracted from v1
  1637. * @param v1 {array} in the format [x,y,z,w]
  1638. * @param v2 {array} in the format [x,y,z,w]
  1639. * @type array
  1640. **/
  1641. Vector3DUtil.subtract=function(v1,v2){
  1642. return [v1[0]-v2[0],v1[1]-v2[1],v1[2]-v2[2],v1[3]-v2[3]];
  1643. };
  1644. /**
  1645. * @function decrementBy performs an in-place subtraction of v2 from v1 (v1 is modified)
  1646. * @param v1 {array} in the format [x,y,z,w]
  1647. * @param v2 {array} in the format [x,y,z,w]
  1648. * @type void
  1649. **/
  1650. Vector3DUtil.decrementBy=function(v1,v2){
  1651. v1[0]-=v2[0];
  1652. v1[1]-=v2[1];
  1653. v1[2]-=v2[2];
  1654. v1[3]-=v2[3];
  1655. };
  1656. /**
  1657. * @function IncrementBy performs an in-place addition of v2 to v1 (v1 is modified)
  1658. * @param v1 {array} in the format [x,y,z,w]
  1659. * @param v2 {array} in the format [x,y,z,w]
  1660. * @type void
  1661. **/
  1662. Vector3DUtil.IncrementBy=function(v1,v2){
  1663. v1[0]+=v2[0];
  1664. v1[1]+=v2[1];
  1665. v1[2]+=v2[2];
  1666. v1[3]+=v2[3];
  1667. };
  1668. /**
  1669. * @function distance determines the distance between vectors v1 and v2
  1670. * @param v1 {array} in the format [x,y,z,w]
  1671. * @param v2 {array} in the format [x,y,z,w]
  1672. * @type number
  1673. **/
  1674. Vector3DUtil.distance=function(v1,v2) {
  1675. var math=Math;
  1676. var pow=math.pow;
  1677. var x=pow(v1[0]-v2[0], 2);
  1678. var y=pow(v1[1]-v2[1], 2);
  1679. var z=pow(v1[2]-v2[2], 2);
  1680. return math.sqrt(x+y+z);
  1681. };
  1682. /**
  1683. * @function dotProduct determines the dot product for two vectors
  1684. * @param v1 {array} in the format [x,y,z,w]
  1685. * @param v2 {array} in the format [x,y,z,w]
  1686. * @type number
  1687. **/
  1688. Vector3DUtil.dotProduct=function(v1,v2){
  1689. return v1[0]*v2[0]+v1[1]*v2[1]+v1[2]*v2[2];
  1690. };
  1691. /**
  1692. * @function crossProduct determines the cross product for two vectors
  1693. * @param v1 {array} in the format [x,y,z,w]
  1694. * @param v2 {array} in the format [x,y,z,w]
  1695. * @type array
  1696. **/
  1697. Vector3DUtil.crossProduct=function(v1,v2){
  1698. return [v1[1]*v2[2]-v1[2]*v2[1],v1[2]*v2[0]-v1[0]*v2[2],v1[0]*v2[1]-v1[1]*v2[0],0];
  1699. };
  1700. /**
  1701. * @function get_length determines the length of a vector
  1702. * @param v {array} in the format [x,y,z,w]
  1703. * @type number
  1704. **/
  1705. Vector3DUtil.get_length=function(v){
  1706. var sq=v[0]*v[0]+v[1]*v[1]+v[2]*v[2];
  1707. return(sq>0) ? Math.pow(sq,0.5) : 0.0;
  1708. };
  1709. /**
  1710. * @function get_length_squared determines the length squared of a vector
  1711. * @param v {array} in the format [x,y,z,w]
  1712. * @type number
  1713. **/
  1714. Vector3DUtil.get_lengthSquared=function(v){
  1715. var sq=v[0]*v[0]+v[1]*v[1]+v[2]*v[2];
  1716. return sq;
  1717. };
  1718. /**
  1719. * @function normalize performs in-place normalisation of a vector
  1720. * @param v {array} in the format [x,y,z,w]
  1721. * @type number
  1722. **/
  1723. Vector3DUtil.normalize=function(v){
  1724. f=Vector3DUtil.get_length(v);
  1725. v[0]/=f;
  1726. v[1]/=f;
  1727. v[2]/=f;
  1728. return f;
  1729. };
  1730. /**
  1731. * @function negate performs in-place negation of a vector
  1732. * @param v {array} in the format [x,y,z,w]
  1733. * @type array
  1734. **/
  1735. Vector3DUtil.negate=function(v){
  1736. v[0]*=-1;
  1737. v[1]*=-1;
  1738. v[2]*=-1;
  1739. return v;
  1740. };
  1741. /**
  1742. * @function scaleBy performs in-place scaling of a vector
  1743. * @param v {array} in the format [x,y,z,w]
  1744. * @param s {number}
  1745. * @type void
  1746. **/
  1747. Vector3DUtil.scaleBy=function(v,s){
  1748. v[0]*=s;
  1749. v[1]*=s;
  1750. v[2]*=s;
  1751. };
  1752. /**
  1753. * @function getSum gets the absolute sum of each value of a given 3D vector
  1754. * useful for determining the total amount of force acting on a given body for example
  1755. * @param v {array} in the format [x,y,z,w]
  1756. * @type number
  1757. **/
  1758. Vector3DUtil.getSum=function(v){
  1759. var abs=Math.abs;
  1760. return abs(v[0])+abs(v[1])+abs(v[2]);
  1761. };
  1762. /**
  1763. * @function limitSum scales Vector3D v so that the absolute sum of x,y & z is no greater than s
  1764. * useful in situations when a force vector must be limited to some maximum total amount of force
  1765. * @param v {array} in the format [x,y,z,w]
  1766. * @param s {number} the scaling factor
  1767. * @type void
  1768. **/
  1769. Vector3DUtil.limitSum=function(v,s){
  1770. var abs=Math.abs;
  1771. c=Vector3DUtil.getSum(v);
  1772. if (s>=c) return;
  1773. f=s/c;
  1774. Vector3DUtil.scaleBy(v,f);
  1775. };
  1776. /**
  1777. * @function project performs in-place projection on a vector
  1778. * @param v {array} in the format [x,y,z,w]
  1779. * @type void
  1780. **/
  1781. Vector3DUtil.project=function(v){
  1782. v[0]/=v[3];
  1783. v[1]/=v[3];
  1784. v[2]/=v[3];
  1785. v[3]=1;
  1786. };
  1787. /**
  1788. * @function angleBetween determines the angle between two vectors
  1789. * @param v1 {array} in the format [x,y,z,w]
  1790. * @param v2 {array} in the format [x,y,z,w]
  1791. * @type number
  1792. **/
  1793. Vector3DUtil.angleBetween=function(v1,v2){
  1794. var v1n=v1.slice(0);
  1795. var v2n=v2.slice(0);
  1796. Vector3DUtil.normalize(v1n);
  1797. Vector3DUtil.normalize(v2n);
  1798. d=Vector3DUtil.dotProduct(v1n, v2n);
  1799. if (d<-1) d=-1;
  1800. else if (d>1) d=1;
  1801. return Math.acos(d);
  1802. };
  1803. /**
  1804. * @function equals tests two vectors for equality
  1805. * @param v1 {array} in the format [x,y,z,w]
  1806. * @param v2 {array} in the format [x,y,z,w]
  1807. * @param allFour {Boolean} whether to test all 4 slots [x,y,z,w] or only the 1st 3 coordinate values [x,y,z]
  1808. * @type boolean
  1809. **/
  1810. Vector3DUtil.equals=function(v1, v2, allFour){
  1811. if(!allFour)
  1812. return (v1[0]==v2[0] && v1[1]==v2[1] && v1[2]==v2[2]);
  1813. else
  1814. return (v1[0]==v2[0] && v1[1]==v2[1] && v1[2]==v2[2] && v1[3]==v2[3]);
  1815. };
  1816. /**
  1817. * @function create replacement for the Vector3D constructor - avoids NaN assignments
  1818. *
  1819. * @param x {number}
  1820. * @param y {number}
  1821. * @param z {number}
  1822. * @param w {number}
  1823. * @type array
  1824. **/
  1825. Vector3DUtil.create=function(x,y,z,w){
  1826. var v3d=[];
  1827. v3d[0] = (x) ? x : 0;
  1828. v3d[1] = (y) ? y : 0;
  1829. v3d[2] = (z) ? z : 0;
  1830. v3d[3] = (w) ? w : 0;
  1831. return v3d;
  1832. };
  1833. jigLib.Vector3DUtil=Vector3DUtil;
  1834. })(jigLib);(function(jigLib){
  1835. var Vector3DUtil=jigLib.Vector3DUtil;
  1836. var GLMatrix=jigLib.GLMatrix;
  1837. /**
  1838. * @author Paul Brunt - rewritten by Jim Sangwine to use GLMatrix (http://code.google.com/p/glmatrix/)
  1839. *
  1840. * @name Matrix3D
  1841. * @class Matrix3D a wrapper class for GLMatrix
  1842. * @requires Vector3DUtil
  1843. * @requires GLMatrix
  1844. * @property {GLMatrix} glmatrix the internal GLMatrix object
  1845. * @constructor
  1846. **/
  1847. var Matrix3D=function(v){
  1848. if(v) this.glmatrix=GLMatrix.create(v);
  1849. else this.glmatrix=GLMatrix.create([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]);
  1850. };
  1851. Matrix3D.prototype.glmatrix=null;
  1852. /**
  1853. * @function get_determinant returns the determinant for this matrix
  1854. * @type number
  1855. **/
  1856. Matrix3D.prototype.get_determinant=function() {
  1857. return GLMatrix.determinant(this.glmatrix);
  1858. };
  1859. /**
  1860. * @function prepend prepends another matrix to this one
  1861. * @param {GLMatrix} m the matrix to prepend
  1862. * @type void
  1863. **/
  1864. Matrix3D.prototype.prepend=function(m){
  1865. GLMatrix.multiply(m.glmatrix, this.glmatrix, this.glmatrix);
  1866. };
  1867. /**
  1868. * @function append appends another matrix to this one
  1869. * @param {GLMatrix} m the matrix to append
  1870. * @type void
  1871. **/
  1872. Matrix3D.prototype.append=function(m){
  1873. GLMatrix.multiply(this.glmatrix, m.glmatrix);
  1874. };
  1875. /**
  1876. * @function angleAxis
  1877. * @param {number} angle
  1878. * @param {array} axis
  1879. * @type Matrix3D
  1880. **/
  1881. Matrix3D.prototype.angleAxis=function(angle, axis) {
  1882. var xmx,ymy,zmz,xmy,ymz,zmx,xms,yms,zms;
  1883. //convert from degrees to radians
  1884. angle=angle*(3.14159/180);
  1885. var x = axis[0];
  1886. var y = axis[1];
  1887. var z = axis[2];
  1888. var cos = Math.cos(angle);
  1889. var cosi = 1.0 - cos;
  1890. var sin = Math.sin(angle);
  1891. xms = x * sin;yms = y * sin;zms = z * sin;
  1892. xmx = x * x;ymy = y * y;zmz = z * z;
  1893. xmy = x * y;ymz = y * z;zmx = z * x;
  1894. var matrix=[(cosi * xmx) + cos,(cosi * xmy) - zms,(cosi * zmx) + yms,0,
  1895. (cosi * xmy) + zms,(cosi * ymy) + cos,(cosi * ymz) - xms,0,
  1896. (cosi * zmx) - yms,(cosi * ymz) + xms,(cosi * zmz) + cos,0,
  1897. 0,0,0,1];
  1898. /*var matrix=[(cosi * xmx) + cos,(cosi * xmy) + zms,(cosi * zmx) - yms,0,
  1899. (cosi * xmy) - zms,(cosi * ymy) + cos,(cosi * ymz) + xms,0,
  1900. (cosi * zmx) + yms,(cosi * ymz) - xms,(cosi * zmz) + cos,0,
  1901. 0,0,0,1]; */
  1902. return new Matrix3D(matrix);
  1903. };
  1904. /**
  1905. * @function rotate clones and rotates this matrix
  1906. * @param {number} angle
  1907. * @param {array} axis
  1908. * @type Matrix3D
  1909. **/
  1910. Matrix3D.prototype.rotate=function(angle, axis) {
  1911. var mat=this.clone();
  1912. GLMatrix.rotate(mat.glmatrix,angle,axis);
  1913. return mat;
  1914. };
  1915. /**
  1916. * @function translateMatrix returns a translate matrix based on v
  1917. * @param {array} v translation expressed as a 3D vector
  1918. * @type Matrix3D
  1919. **/
  1920. Matrix3D.prototype.translateMatrix=function(v){
  1921. return new Matrix3D([
  1922. 1,0,0,v[0],
  1923. 0,1,0,v[1],
  1924. 0,0,1,v[2],
  1925. 0,0,0,1
  1926. ]);
  1927. /*return new Matrix3D([
  1928. 1,0,0,0,
  1929. 0,1,0,0,
  1930. 0,0,1,0,
  1931. v[0],v[1],v[2],1
  1932. ]);*/
  1933. };
  1934. /**
  1935. * @function scaleMatrix returns a scale matrix based on v
  1936. * @param {array} v scale expressed as a 3D vector
  1937. * @type Matrix3D
  1938. **/
  1939. Matrix3D.prototype.scaleMatrix=function(v){
  1940. return new Matrix3D([
  1941. v[0],0,0,0,
  1942. 0,v[1],0,0,
  1943. 0,0,v[2],0,
  1944. 0,0,0,1
  1945. ]);
  1946. };
  1947. /**
  1948. * @function appendRotation appends rotation to this matrix
  1949. * @param {number} angle the rotation angle
  1950. * @param {array} axis the rotation axis expressed as a 3D vector
  1951. * @param {array} pivot the pivot point expressed as a 3D vector
  1952. * @type void
  1953. **/
  1954. Matrix3D.prototype.appendRotation=function(angle,axis,pivot){
  1955. angle=angle*(3.14159/180);
  1956. Vector3DUtil.negate(axis);
  1957. if (pivot)
  1958. {
  1959. var npivot=Vector3DUtil.negate(pivot.slice(0));
  1960. this.appendTranslation(npivot[0], npivot[1], npivot[2]);
  1961. }
  1962. GLMatrix.rotate(this.glmatrix, angle, axis);
  1963. if (pivot)
  1964. this.appendTranslation(pivot[0], pivot[1], pivot[2]);
  1965. };
  1966. /**
  1967. * @function prependRotation prepends rotation to this matrix
  1968. * @param {number} angle the rotation angle
  1969. * @param {array} axis the rotation axis expressed as a 3D vector
  1970. * @param {array} pivot the pivot point expressed as a 3D vector
  1971. * @type void
  1972. **/
  1973. Matrix3D.prototype.prependRotation=function(angle,axis,pivot){
  1974. if(pivot)
  1975. this.prepend(this.translateMatrix(Vector3DUtil.negate(pivot.slice(0))));
  1976. this.prepend(this.angleAxis(angle,axis));
  1977. if(pivot)
  1978. this.prepend(this.translateMatrix(pivot));
  1979. };
  1980. /**
  1981. * @function appendScale appends scale to this matrix
  1982. * @param {number} x scale in the X axis
  1983. * @param {number} y scale in the Y axis
  1984. * @param {number} z scale in the Z axis
  1985. * @type void
  1986. **/
  1987. Matrix3D.prototype.appendScale=function(x,y,z){
  1988. GLMatrix.scale(this.glmatrix, [x,y,z]);
  1989. };
  1990. /**
  1991. * @function prependScale prepends scale to this matrix
  1992. * @param {number} x scale in the X axis
  1993. * @param {number} y scale in the Y axis
  1994. * @param {number} z scale in the Z axis
  1995. * @type void
  1996. **/
  1997. Matrix3D.prototype.prependScale=function(x,y,z){
  1998. this.prepend(this.scaleMatrix([x,y,z]));
  1999. };
  2000. /**
  2001. * @function appendTranslation appends translation to this matrix
  2002. * @param {number} x translation in the X axis
  2003. * @param {number} y translation in the Y axis
  2004. * @param {number} z translation in the Z axis
  2005. * @type void
  2006. **/
  2007. Matrix3D.prototype.appendTranslation=function(x,y,z){
  2008. this.append(this.translateMatrix([x,y,z]));
  2009. };
  2010. /**
  2011. * @function prependTranslation prepends translation to this matrix
  2012. * @param {number} x translation in the X axis
  2013. * @param {number} y translation in the Y axis
  2014. * @param {number} z translation in the Z axis
  2015. * @type void
  2016. **/
  2017. Matrix3D.prototype.prependTranslation=function(x,y,z){
  2018. this.prepend(this.translateMatrix([x,y,z]));
  2019. };
  2020. /**
  2021. * @function identity
  2022. * @type void
  2023. **/
  2024. Matrix3D.prototype.identity=function(){
  2025. GLMatrix.identity(this.glmatrix);
  2026. };
  2027. /**
  2028. * @function transpose transposes this matrix (making it compatible with the old Flex matrices)
  2029. * @type void
  2030. **/
  2031. Matrix3D.prototype.transpose=function(){
  2032. GLMatrix.transpose(this.glmatrix);
  2033. };
  2034. /**
  2035. * @function invert inverts this matrix
  2036. * @type void
  2037. **/
  2038. Matrix3D.prototype.invert=function(){
  2039. GLMatrix.inverse(this.glmatrix);
  2040. };
  2041. /**
  2042. * @function clone returns a clone of this matrix
  2043. * @type Matrix3D
  2044. **/
  2045. Matrix3D.prototype.clone=function(){
  2046. return new Matrix3D(this.glmatrix);
  2047. };
  2048. /**
  2049. * @function transformVector transforms (multiplies) this matrix by vector
  2050. * @param vector a 3D vector
  2051. * @returns
  2052. */
  2053. Matrix3D.prototype.transformVector=function(vector){
  2054. var x=vector[0];
  2055. var y=vector[1];
  2056. var z=vector[2];
  2057. var m=this.glmatrix;
  2058. return [m[0]*x+m[1]*y+m[2]*z+m[3],m[4]*x+m[5]*y+m[6]*z+m[7],m[8]*x+m[9]*y+m[10]*z+m[11]];
  2059. //return GLMatrix.multiplyVec3(GLMatrix.transpose(this.glmatrix), vector); for some reason this is giving a very wrong answer!!!
  2060. };
  2061. jigLib.Matrix3D=Matrix3D;
  2062. })(jigLib);(function(jigLib){
  2063. var Vector3DUtil=jigLib.Vector3DUtil;
  2064. /**
  2065. * @author Muzer(muzerly@gmail.com)
  2066. *
  2067. * @name JNumber3D
  2068. * @class JNumber3D
  2069. * @requires Vector3DUtil
  2070. * @constant {number} NUM_TINY
  2071. * @constant {number} NUM_HUGE
  2072. * @constructor
  2073. **/
  2074. var JNumber3D={};
  2075. JNumber3D.NUM_TINY = 0.00001;
  2076. JNumber3D.NUM_HUGE = 100000;
  2077. /* this method is redundant since we are already using arrays for 3D Vector storage
  2078. JNumber3D.toArray=function(v){
  2079. return v;//[v[0], v[1], v[2]];
  2080. };
  2081. */
  2082. /**
  2083. * @function getScaleVector clones a 3D vector and scales it's elements by s
  2084. * @param {array} v a 3D vector
  2085. * @param {number} s the scale to apply
  2086. * @type array
  2087. **/
  2088. JNumber3D.getScaleVector=function(v, s){
  2089. return [v[0]*s,v[1]*s,v[2]*s,v[3]];
  2090. };
  2091. /**
  2092. * @function getScaleVector clones a a 3D vector and divides it's elements by w
  2093. * @param {array} v a 3D vector
  2094. * @param {number} w the divisor
  2095. * @type array
  2096. **/
  2097. JNumber3D.getDivideVector=function(v, w){
  2098. return (w) ? [v[0] / w, v[1] / w, v[2] / w, 0] : [0, 0, 0, 0];
  2099. };
  2100. /**
  2101. * @function getNormal
  2102. * @param {array} v0 a 3D vector
  2103. * @param {array} v1 a 3D vector
  2104. * @param {array} v2 a 3D vector
  2105. * @type array
  2106. **/
  2107. JNumber3D.getNormal=function(v0, v1, v2){
  2108. // Vector3DUtil.subtract is non-destructive so we don't need to clone here...
  2109. // var E = v1.slice(0);
  2110. // var F = v2.slice(0);
  2111. // replacing with a 1 liner...
  2112. // var N = Vector3DUtil.crossProduct(Vector3DUtil.subtract(v1, v0), Vector3DUtil.subtract(v2, v1));
  2113. // Vector3DUtil.normalize(N);
  2114. // return N;
  2115. return Vector3DUtil.normalize(Vector3DUtil.crossProduct(Vector3DUtil.subtract(v1, v0), Vector3DUtil.subtract(v2, v1)));
  2116. };
  2117. /**
  2118. * @function copyFromArray copies an array into a 3D vector
  2119. * @deprecated JigLibJS uses array for 3D vector storage so this method is redundant - use array.slice(0) instead
  2120. * @param {array} v a 3D vector
  2121. * @param {array} arr the array to copy to v
  2122. * @type void
  2123. **/
  2124. JNumber3D.copyFromArray=function(v, arr){
  2125. if (arr.length >= 3) v=arr.slice(0);
  2126. };
  2127. /**
  2128. * @function getLimiteNumber ensures num falls between min and max
  2129. * @param {number} num the number to limit
  2130. * @param {number} min the minimum allowable value for num
  2131. * @param {number} max the maximum allowable value for num
  2132. * @type number
  2133. **/
  2134. JNumber3D.getLimiteNumber=function(num, min, max){
  2135. var n = num;
  2136. if (n < min) n = min;
  2137. else if (n > max) n = max;
  2138. return n;
  2139. };
  2140. jigLib.JNumber3D=JNumber3D;
  2141. })(jigLib);
  2142. (function(jigLib){
  2143. var Vector3DUtil=jigLib.Vector3DUtil;
  2144. var Matrix3D=jigLib.Matrix3D;
  2145. /**
  2146. * @author Muzer(muzerly@gmail.com)
  2147. *
  2148. * @name JMatrix3D
  2149. * @class JMatrix3D
  2150. * @requires Vector3DUtil
  2151. * @requires Matrix3D
  2152. * @constructor
  2153. **/
  2154. var JMatrix3D={};
  2155. /**
  2156. * @function getTranslationMatrix returns a translate matrix
  2157. * @param {number} x translation amount in the X axis
  2158. * @param {number} y translation amount in the Y axis
  2159. * @param {number} z translation amount in the Z axis
  2160. * @type Matrix3D
  2161. **/
  2162. JMatrix3D.getTranslationMatrix=function(x, y, z){
  2163. var matrix3D = new Matrix3D();
  2164. matrix3D.appendTranslation(x, y, z);
  2165. return matrix3D;
  2166. };
  2167. /**
  2168. * @function getScaleMatrix returns a scale matrix
  2169. * @param {number} x scale amount in the X axis
  2170. * @param {number} y scale amount in the Y axis
  2171. * @param {number} z scale amount in the Z axis
  2172. * @type Matrix3D
  2173. **/
  2174. JMatrix3D.getScaleMatrix=function(x, y, z){
  2175. var matrix3D = new Matrix3D();
  2176. matrix3D.prependScale(x, y, z);
  2177. return matrix3D;
  2178. };
  2179. /**
  2180. * @function getRotationMatrix returns a rotation matrix
  2181. * @param {number} x axis X
  2182. * @param {number} y axis Y
  2183. * @param {number} z axis Z
  2184. * @param {number} degree rotation amount in degrees
  2185. * @param {array} pivotPoint the pivot point expressed as a 3D vector
  2186. * @type Matrix3D
  2187. **/
  2188. JMatrix3D.getRotationMatrix=function(x, y, z, degree, pivotPoint){
  2189. var matrix3D = new Matrix3D();
  2190. matrix3D.appendRotation(degree, Vector3DUtil.create(x,y,z,0), pivotPoint);
  2191. return matrix3D;
  2192. };
  2193. /**
  2194. * @function getInverseMatrix returns an inverted clone of a given Matrix3D
  2195. * @param {Matrix3D} m the matrix to invert
  2196. * @type Matrix3D
  2197. **/
  2198. JMatrix3D.getInverseMatrix=function(m){
  2199. var matrix3D = m.clone();
  2200. matrix3D.invert();
  2201. return matrix3D;
  2202. };
  2203. /**
  2204. * @function getTransposeMatrix returns a transposed clone of a given Matrix3D
  2205. * @param {Matrix3D} m the matrix to transpose
  2206. * @type Matrix3D
  2207. **/
  2208. JMatrix3D.getTransposeMatrix=function(m){
  2209. var matrix3D = m.clone();
  2210. matrix3D.transpose();
  2211. return matrix3D;
  2212. };
  2213. /**
  2214. * @function getAppendMatrix3D returns the result of one matrix appended to another
  2215. * @param {Matrix3D} a the original matrix
  2216. * @param {Matrix3D} b the matrix to append to a
  2217. * @type Matrix3D
  2218. **/
  2219. JMatrix3D.getAppendMatrix3D=function(a, b){
  2220. var matrix3D = a.clone();
  2221. matrix3D.append(b);
  2222. return matrix3D;
  2223. };
  2224. /**
  2225. * @function getPrependMatrix returns the result of one matrix prepended to another
  2226. * @param {Matrix3D} a the original matrix
  2227. * @param {Matrix3D} b the matrix to prepend to a
  2228. * @type Matrix3D
  2229. **/
  2230. JMatrix3D.getPrependMatrix=function(a, b){
  2231. var matrix3D = a.clone();
  2232. matrix3D.prepend(b);
  2233. return matrix3D;
  2234. };
  2235. /**
  2236. * @function getSubMatrix returns the result of one matrix subtracted from another
  2237. * @param {Matrix3D} a the original matrix
  2238. * @param {Matrix3D} b the matrix to subtract from a
  2239. * @type Matrix3D
  2240. **/
  2241. JMatrix3D.getSubMatrix=function(a, b){
  2242. var num = [16];
  2243. for (var i = 0; i < 16; i++ ) {
  2244. num[i] = a.glmatrix[i] - b.glmatrix[i];
  2245. }
  2246. return new Matrix3D(num);
  2247. };
  2248. /**
  2249. * @function getRotationMatrixAxis generates a rotation matrix for a given axis and amount
  2250. * @param {number} degree the rotation amount in degrees
  2251. * @param {array} rotateAxis the rotation axis
  2252. * @type Matrix3D
  2253. **/
  2254. JMatrix3D.getRotationMatrixAxis=function(degree, rotateAxis){
  2255. var matrix3D = new Matrix3D();
  2256. matrix3D.appendRotation(degree, rotateAxis?rotateAxis:Vector3DUtil.X_AXIS);
  2257. return matrix3D;
  2258. };
  2259. /**
  2260. * @function getCols returns the columns Matrix3D in a multidimensional array
  2261. * @param {Matrix3D} matrix3D the Matrix3D
  2262. * @type array
  2263. **/
  2264. JMatrix3D.getCols=function(matrix3D){
  2265. var _rawData = matrix3D.glmatrix;
  2266. var cols = [];
  2267. /*
  2268. cols[0] = Vector3DUtil.create(_rawData[0], _rawData[1], _rawData[2], 0);
  2269. cols[1] = Vector3DUtil.create(_rawData[4], _rawData[5], _rawData[6], 0);
  2270. cols[2] = Vector3DUtil.create(_rawData[8], _rawData[9], _rawData[10], 0);
  2271. */
  2272. cols[0] = Vector3DUtil.create(_rawData[0], _rawData[4], _rawData[8], 0);
  2273. cols[1] = Vector3DUtil.create(_rawData[1], _rawData[5], _rawData[9], 0);
  2274. cols[2] = Vector3DUtil.create(_rawData[2], _rawData[6], _rawData[10], 0);
  2275. return cols;
  2276. };
  2277. /**
  2278. * @function multiplyVector performs in-place multiplication of a 3D vector by a given Matrix3D
  2279. * @param {Matrix3D} matrix3D the Matrix3D to use in multiplying the vector
  2280. * @param {array} v the 3D vector to multiply
  2281. * @type void
  2282. **/
  2283. JMatrix3D.multiplyVector=function(matrix3D, v){
  2284. var vx = v[0];
  2285. var vy = v[1];
  2286. var vz = v[2];
  2287. if (vx == 0 && vy == 0 && vz == 0) { return; }
  2288. var _rawData = matrix3D.glmatrix;
  2289. /*
  2290. How did this work in AS3? it looks wrong!
  2291. v[0] = vx * _rawData[0] + vy * _rawData[4] + vz * _rawData[8] + _rawData[12];
  2292. v[1] = vx * _rawData[1] + vy * _rawData[5] + vz * _rawData[9] + _rawData[13];
  2293. v[2] = vx * _rawData[2] + vy * _rawData[6] + vz * _rawData[10] + _rawData[14];
  2294. */
  2295. v[0] = vx * _rawData[0] + vy * _rawData[1] + vz * _rawData[2] + _rawData[3];
  2296. v[1] = vx * _rawData[4] + vy * _rawData[5] + vz * _rawData[6] + _rawData[7];
  2297. v[2] = vx * _rawData[8] + vy * _rawData[9] + vz * _rawData[10] + _rawData[11];
  2298. };
  2299. jigLib.JMatrix3D=JMatrix3D;
  2300. })(jigLib);
  2301. (function(jigLib){
  2302. var Vector3DUtil=jigLib.Vector3DUtil;
  2303. /**
  2304. * @author Muzer(muzerly@gmail.com)
  2305. *
  2306. * @name JMath3D
  2307. * @class JMath3D
  2308. * @requires Vector3DUtil
  2309. * @constructor
  2310. **/
  2311. var JMath3D={};
  2312. /**
  2313. * @function fromNormalAndPoint
  2314. * @param {array} normal the normal expressed as a 3D vector
  2315. * @param {array} point the point expressed as a 3D vector
  2316. * @type array
  2317. **/
  2318. JMath3D.fromNormalAndPoint=function(normal, point){
  2319. var v = Vector3DUtil.create(normal[0], normal[1], normal[2], 0);
  2320. v[3] = -(v[0]*point[0] + v[1]*point[1] + v[2]*point[2]);
  2321. return normal;
  2322. };
  2323. /**
  2324. * @function getIntersectionLine
  2325. * @param {array} v a 3D vector
  2326. * @param {array} v0 a 3D vector
  2327. * @param {array} v1 a 3D vector
  2328. * @type array
  2329. **/
  2330. JMath3D.getIntersectionLine=function(v, v0, v1){
  2331. var d0 = v[0] * v0[0] + v[1] * v0[1] + v[2] * v0[2] - v[3];
  2332. var d1 = v[0] * v1[0] + v[1] * v1[1] + v[2] * v1[2] - v[3];
  2333. var m = d1 / (d1 - d0);
  2334. return [v1[0] + (v0[0] - v1[0]) * m,
  2335. v1[1] + (v0[1] - v1[1]) * m,
  2336. v1[2] + (v0[2] - v1[2]) * m,
  2337. 0];
  2338. };
  2339. JMath3D.getLimiteNumber=function(num, min, max){
  2340. var n = num;
  2341. if (n < min){
  2342. n = min;
  2343. }else if (n > max){
  2344. n = max;
  2345. }
  2346. return n;
  2347. };
  2348. JMath3D.wrap=function(val, min, max){
  2349. var delta = max - min;
  2350. if (val > delta){
  2351. val = val / delta;
  2352. val = val - Math.floor(val);
  2353. val = val * delta;
  2354. }
  2355. return val;
  2356. };
  2357. /**
  2358. * @function unproject
  2359. * @param {Matrix3D} matrix3d
  2360. * @param {number} focus
  2361. * @param {number} zoom
  2362. * @param {number} mX
  2363. * @param {number} mY
  2364. * @type array
  2365. **/
  2366. JMath3D.unproject=function(matrix3D, focus, zoom, mX, mY){
  2367. var persp = (focus * zoom) / focus;
  2368. var vector = Vector3DUtil.create(mX / persp, -mY / persp, focus, 0);
  2369. return matrix3D.transformVector(vector);
  2370. };
  2371. jigLib.JMath3D=JMath3D;
  2372. })(jigLib);
  2373. (function(jigLib){
  2374. /**
  2375. * @author katopz
  2376. *
  2377. * @name ContactData
  2378. * @class ContactData stores information about a contact between 2 objects
  2379. * @property {BodyPair} pair
  2380. * @property {CachedImpulse} impulse
  2381. * @constructor
  2382. **/
  2383. var ContactData=function(){};
  2384. ContactData.prototype.pair=null;
  2385. ContactData.prototype.impulse=null;
  2386. jigLib.ContactData=ContactData;
  2387. })(jigLib);
  2388. (function(jigLib){
  2389. /**
  2390. * @author katopz
  2391. *
  2392. * @name EdgeData
  2393. * @class EdgeData describes an edge in terms of the numbers of it's connecting vertices - used by JBox
  2394. * @property {number} ind0 the number of the vertex at the start of the edge
  2395. * @property {number} ind1 the number of the vertex at the end of the edge
  2396. * @constructor
  2397. **/
  2398. var EdgeData=function(ind0, ind1){
  2399. this.ind0 = ind0;
  2400. this.ind1 = ind1;
  2401. };
  2402. jigLib.EdgeData=EdgeData;
  2403. })(jigLib);(function(jigLib){
  2404. var Vector3DUtil=jigLib.Vector3DUtil;
  2405. var JMath3D=jigLib.JMath3D;
  2406. /**
  2407. * @name PlaneData
  2408. * @class PlaneData stores information about a contact between 2 objects
  2409. * @requires Vector3DUtil
  2410. * @property {array} position the position of the plane expressed as a 3D vector
  2411. * @property {array} normal the normal direction of the plane expressed as a 3D vector
  2412. * @property {number} distance the dot product of position and normal
  2413. * @constructor
  2414. * @param {array} pos the position of the plane expressed as a 3D vector
  2415. * @param {nor} the normal direction of the plane expressed as a 3D vector
  2416. **/
  2417. var PlaneData=function(pos, nor){
  2418. if(!pos) pos=[0,0,0];
  2419. if(!nor) nor=[0,1,0];
  2420. this.position = pos.slice(0);
  2421. this.normal = nor.slice(0);
  2422. this.distance = Vector3DUtil.dotProduct(this.position, this.normal);
  2423. };
  2424. PlaneData.prototype.position=null;
  2425. PlaneData.prototype.normal=null;
  2426. PlaneData.prototype.distance=null;
  2427. /**
  2428. * @function pointPlaneDistance determines the distance between a given point and the plane
  2429. * @param {array} pt a 3D vector
  2430. * @type number
  2431. **/
  2432. PlaneData.prototype.pointPlaneDistance=function(pt){
  2433. return Vector3DUtil.dotProduct(this.normal, pt) - this.distance;
  2434. };
  2435. PlaneData.prototype.setWithNormal=function(pos, nor){
  2436. this.position = pos.slice(0);
  2437. this.normal = nor.slice(0);
  2438. this.distance = Vector3DUtil.dotProduct(this.position, this.normal);
  2439. };
  2440. PlaneData.prototype.setWithPoint=function(pos0, pos1, pos2){
  2441. this.position = pos0.slice(0);
  2442. var dr1 = Vector3DUtil.subtract(pos1,pos0);
  2443. var dr2 = Vector3DUtil.subtract(pos2,pos0);
  2444. this.normal = Vector3DUtil.crossProduct(dr1,dr2);
  2445. var nLen = Vector3DUtil.get_length(this.normal);
  2446. if (nLen < JMath3D.NUM_TINY) {
  2447. this.normal = new Vector3D(0, 1, 0);
  2448. this.distance = 0;
  2449. }else {
  2450. Vector3DUtil.scaleBy(this.normal,1 / nLen);
  2451. this.distance = Vector3DUtil.dotProduct(pos0,this.normal);
  2452. }
  2453. }
  2454. jigLib.PlaneData=PlaneData;
  2455. })(jigLib);
  2456. (function(jigLib){
  2457. /**
  2458. * @author katopz
  2459. *
  2460. * @name SpanData
  2461. * @class SpanData
  2462. * @property {number} min
  2463. * @property {number} max
  2464. * @property {boolean} flag
  2465. * @property {number} depth
  2466. * @constructor
  2467. **/
  2468. var SpanData=function(){};
  2469. SpanData.prototype.min=null;
  2470. SpanData.prototype.max=null;
  2471. SpanData.prototype.flag=null;
  2472. SpanData.prototype.depth=null;
  2473. jigLib.SpanData=SpanData;
  2474. })(jigLib);
  2475. (function(jigLib){
  2476. // structure used to set up the mesh
  2477. var TriangleVertexIndices=function(_i0, _i1, _i2){
  2478. this.i0 = _i0;
  2479. this.i1 = _i1;
  2480. this.i2 = _i2;
  2481. }
  2482. jigLib.TriangleVertexIndices=TriangleVertexIndices;
  2483. })(jigLib);
  2484. (function(jigLib){
  2485. var Vector3DUtil=jigLib.Vector3DUtil;
  2486. var JAABox=jigLib.JAABox;
  2487. var JNumber3D=jigLib.JNumber3D;
  2488. var OctreeCell=function(aabox){
  2489. this.childCellIndices = [-1,-1,-1,-1,-1,-1,-1,-1];
  2490. this.triangleIndices = [];
  2491. this.clear();
  2492. if(aabox){
  2493. this.AABox = aabox.clone();
  2494. }else {
  2495. this.AABox = new JAABox();
  2496. }
  2497. this._points = this.AABox.getAllPoints();
  2498. this._egdes = this.AABox.get_edges();
  2499. }
  2500. OctreeCell.NUM_CHILDREN = 8;
  2501. // indices of the children (if not leaf). Will be -1 if there is no child
  2502. OctreeCell.prototype.childCellIndices=null;
  2503. // indices of the triangles (if leaf)
  2504. OctreeCell.prototype.triangleIndices=null;
  2505. // Bounding box for the space we own
  2506. OctreeCell.prototype.AABox=null;
  2507. OctreeCell.prototype._points=null;
  2508. OctreeCell.prototype._egdes=null;
  2509. // Indicates if we contain triangles (if not then we should/might have children)
  2510. OctreeCell.prototype.isLeaf=function() {
  2511. return this.childCellIndices[0] == -1;
  2512. }
  2513. OctreeCell.prototype.clear=function(){
  2514. for (var i = 0; i < this.NUM_CHILDREN; i++ ) {
  2515. this.childCellIndices[i] = -1;
  2516. }
  2517. this.triangleIndices.splice(0, this.triangleIndices.length);
  2518. }
  2519. OctreeCell.prototype.get_points=function(){
  2520. return this._points;
  2521. }
  2522. OctreeCell.prototype.get_egdes=function(){
  2523. return this._egdes;
  2524. }
  2525. jigLib.OctreeCell=OctreeCell;
  2526. })(jigLib); (function(jigLib){
  2527. var Vector3DUtil=jigLib.Vector3DUtil;
  2528. var RigidBody=jigLib.RigidBody;
  2529. var CollOutData=function(frac, position, normal){
  2530. if(frac==undefined)frac=0;
  2531. this.frac = frac;
  2532. this.position = position ? position : [0,0,0];
  2533. this.normal = normal ? normal : [0,0,0];
  2534. };
  2535. jigLib.CollOutData=CollOutData;
  2536. })(jigLib);
  2537. (function(jigLib){
  2538. var Vector3DUtil=jigLib.Vector3DUtil;
  2539. var RigidBody=jigLib.RigidBody;
  2540. var CollOutBodyData=function(frac, position, normal, rigidBody){
  2541. if(frac==undefined) frac=0;
  2542. this.Super(frac, position, normal);
  2543. this.rigidBody = rigidBody;
  2544. };
  2545. jigLib.extend(CollOutBodyData,jigLib.CollOutData);
  2546. jigLib.CollOutBodyData=CollOutBodyData;
  2547. })(jigLib);
  2548. (function(jigLib){
  2549. /**
  2550. * @author Jim Sangwine
  2551. *
  2552. * @name JEventDispatcher
  2553. * @class JEventDispatcher The base class for event dispatchers
  2554. * @constructor
  2555. **/
  2556. var JEventDispatcher=function()
  2557. {
  2558. this._listeners={};
  2559. };
  2560. JEventDispatcher.prototype._listeners={};
  2561. /**
  2562. * @function addEventListener adds a listener to this dispatcher
  2563. * @param type {string} the type of event
  2564. * @param listener {function} the event handler
  2565. **/
  2566. JEventDispatcher.prototype.addEventListener=function(type,listener)
  2567. {
  2568. if (typeof listener != 'function')
  2569. throw new Error('Invalid argument passed to JEventDispatcher.addEventListener - listener must be a function');
  2570. if (typeof(this._listeners[type])=='undefined' || !this._listeners[type] instanceof Array)
  2571. this._listeners[type]=[];
  2572. this._listeners[type].push(listener);
  2573. };
  2574. /**
  2575. * @function removeEventListener drops a listener from this dispatcher
  2576. * @param type {string} the type of event
  2577. * @param listener {function} the event handler
  2578. **/
  2579. JEventDispatcher.prototype.removeEventListener=function(type, listener)
  2580. {
  2581. if (!this._listeners[type] instanceof Array) return;
  2582. var listeners = this._listeners[type];
  2583. for (var i=0, num=listeners.length; i<num; i++)
  2584. {
  2585. if (listener === listeners[i])
  2586. {
  2587. listeners.splice(i, 1);
  2588. break;
  2589. }
  2590. }
  2591. };
  2592. /**
  2593. * @function dispatchEvent fires an event
  2594. * @param event {JEvent} the event (should be an instance or subclass of JEvent)
  2595. **/
  2596. JEventDispatcher.prototype.dispatchEvent=function(event)
  2597. {
  2598. //remove this for now do we want to be strict?
  2599. //if (typeof event.type == 'undefined')
  2600. // throw new Error('Invalid argument passed to JEventDispatcher.dispatchEvent - use an instance or subclass of JEvent');
  2601. var listeners = this._listeners[event.type];
  2602. if (!listeners || listeners.length == 0)
  2603. return;
  2604. for (var i=0, num=listeners.length; i < num; i++)
  2605. {
  2606. listeners[i].call(this, event);
  2607. }
  2608. };
  2609. jigLib.JEventDispatcher=JEventDispatcher;
  2610. })(jigLib);(function(jigLib){
  2611. /**
  2612. * @author Jim Sangwine
  2613. *
  2614. * @name JEvent
  2615. * @class JEvent Base class for JigLib events
  2616. * @constant {string} COLLISION
  2617. * @constructor
  2618. * @param type {string}
  2619. **/
  2620. var JEvent=function(type)
  2621. {
  2622. this.type=type;
  2623. };
  2624. JEvent.prototype.type=null;
  2625. Event.EVENT='JigLibJSEvent';
  2626. jigLib.JEvent=JEvent;
  2627. })(jigLib);(function(jigLib){
  2628. /**
  2629. * @author Jim Sangwine
  2630. *
  2631. * @name JCollisionEvent
  2632. * @class JCollisionEvent An event representing a collision with another RigidBody (to be dispatched by RigidBody)
  2633. * @extends JEvent
  2634. * @constant {string} COLLISION
  2635. * @constructor
  2636. * @param body {RigidBody} The other body involved in the collision
  2637. * @param impulse {Array} A 3D vector representing the impulse applied to this RigidBody as a result of the collision
  2638. **/
  2639. var JCollisionEvent=function(body, impulse)
  2640. {
  2641. this.Super(JCollisionEvent.COLLISION);
  2642. this.collisionBody=body;
  2643. this.collisionImpulse=impulse;
  2644. };
  2645. jigLib.extend(JCollisionEvent,jigLib.JEvent);
  2646. JCollisionEvent.prototype.collisionBody=null;
  2647. JCollisionEvent.prototype.collisionImpulse=null;
  2648. JCollisionEvent.COLLISION='JigLibJSCollisionEvent';
  2649. jigLib.JCollisionEvent=JCollisionEvent;
  2650. })(jigLib);(function(jigLib){
  2651. /**
  2652. * Represents a mesh from a 3D engine inside JigLib.
  2653. * Its implementation shold allow to get and set a Matrix3D on
  2654. * the original object.
  2655. *
  2656. * In the implementation, JMatrix3D should be translated into
  2657. * the type proper for a given engine.
  2658. *
  2659. * @author bartekd
  2660. */
  2661. var Matrix3D=jigLib.Matrix3D;
  2662. /**
  2663. * @author bartekd
  2664. *
  2665. * @name ISkin3D
  2666. * @class ISkin3D an interface representing a mesh from a 3D engine inside JigLib.
  2667. * Implementations should allow getting and setting a Matrix3D on the original object.
  2668. * Matrix3D should be translated into a type compatible with the engine.
  2669. *
  2670. * @requires Matrix3D
  2671. * @property {Matrix3D} matrix
  2672. * @constructor
  2673. **/
  2674. function ISkin3D(){
  2675. this.matrix=new Matrix3D();
  2676. };
  2677. ISkin3D.prototype.matrix=null;
  2678. /**
  2679. * @function get_transform gets the transform matrix
  2680. * @type Matrix3D
  2681. **/
  2682. ISkin3D.prototype.get_transform=function(){
  2683. return this.matrix;
  2684. };
  2685. /**
  2686. * @function set_transform sets the transform matrix
  2687. * @param {Matrix3D} value
  2688. * @type void
  2689. **/
  2690. ISkin3D.prototype.set_transform=function(value){
  2691. this.matrix=value;
  2692. };
  2693. jigLib.ISkin3D=ISkin3D;
  2694. })(jigLib);/*
  2695. Copyright (c) 2007 Danny Chapman
  2696. http://www.rowlhouse.co.uk
  2697. This software is provided 'as-is', without any express or implied
  2698. warranty. In no event will the authors be held liable for any damages
  2699. arising from the use of this software.
  2700. Permission is granted to anyone to use this software for any purpose,
  2701. including commercial applications, and to alter it and redistribute it
  2702. freely, subject to the following restrictions:
  2703. 1. The origin of this software must not be misrepresented; you must not
  2704. claim that you wrote the original software. If you use this software
  2705. in a product, an acknowledgment in the product documentation would be
  2706. appreciated but is not required.
  2707. 2. Altered source versions must be plainly marked as such, and must not be
  2708. misrepresented as being the original software.
  2709. 3. This notice may not be removed or altered from any source
  2710. distribution.
  2711. */
  2712. (function(jigLib){
  2713. var Vector3DUtil=jigLib.Vector3DUtil;
  2714. var JNumber3D=jigLib.JNumber3D;
  2715. var EdgeData=jigLib.EdgeData;
  2716. var JMath3D=jigLib.JMath3D;
  2717. /**
  2718. * @author Muzer(muzerly@gmail.com)
  2719. *
  2720. * @name JAABox
  2721. * @class JAABox an axis aligned box
  2722. * @requires Vector3DUtil
  2723. * @requires JNumber3D
  2724. * @property {array} minPos a 3D vector
  2725. * @property {array} maxPos a 3D vector
  2726. * @constructor
  2727. * @param {array} minPos a 3D vector
  2728. * @param {array} maxPos a 3D vector
  2729. **/
  2730. var JAABox=function(minPos, maxPos) {
  2731. if(minPos){
  2732. this._minPos = minPos.slice(0);
  2733. this._maxPos = maxPos.slice(0);
  2734. }else{
  2735. this._minPos = [0,0,0];
  2736. this._maxPos = [0,0,0];
  2737. }
  2738. };
  2739. JAABox.prototype._minPos=null;
  2740. JAABox.prototype._maxPos=null;
  2741. /**
  2742. * @function get_minPos getter for _minPos
  2743. * @type array
  2744. **/
  2745. JAABox.prototype.get_minPos=function(){
  2746. return this._minPos;
  2747. };
  2748. /**
  2749. * @function set_minPos setter for _minPos
  2750. * @param {array} pos a 3D vector
  2751. * @type void
  2752. **/
  2753. JAABox.prototype.set_minPos=function(pos){
  2754. this._minPos = pos.slice(0);
  2755. };
  2756. /**
  2757. * @function get_minPos getter for _maxPos
  2758. * @type array
  2759. **/
  2760. JAABox.prototype.get_maxPos=function(){
  2761. return this._maxPos;
  2762. };
  2763. /**
  2764. * @function set_minPos setter for _maxPos
  2765. * @param {array} pos a 3D vector
  2766. * @type void
  2767. **/
  2768. JAABox.prototype.set_maxPos=function(pos){
  2769. this._maxPos = pos.slice(0);
  2770. };
  2771. /**
  2772. * @function get_sideLengths determines the side lengths of the JAABox
  2773. * @returns the side lengths expressed as 3D vector
  2774. * @type array
  2775. **/
  2776. JAABox.prototype.get_sideLengths=function() {
  2777. var pos = this._maxPos.slice(0);
  2778. Vector3DUtil.subtract(pos, this._minPos);
  2779. return pos;
  2780. };
  2781. /**
  2782. * @function get_centrePos determines the center point of the JAABox
  2783. * @returns the center point expressed as 3D vector
  2784. * @type array
  2785. **/
  2786. JAABox.prototype.get_centrePos=function(){
  2787. var pos = this._minPos.slice(0);
  2788. return JNumber3D.getScaleVector(Vector3DUtil.add(pos, this._maxPos), 0.5);
  2789. };
  2790. JAABox.prototype.getAllPoints=function(){
  2791. var center,halfSide;
  2792. var points;
  2793. center = this.get_centrePos();
  2794. halfSide = this.get_sideLengths().slice(0);
  2795. Vector3DUtil.scaleBy(halfSide, 0.5);
  2796. points = [];
  2797. points[0] = Vector3DUtil.add(center,[halfSide[0], -halfSide[1], halfSide[2]]);
  2798. points[1] = Vector3DUtil.add(center,[halfSide[0], halfSide[1], halfSide[2]]);
  2799. points[2] = Vector3DUtil.add(center,[-halfSide[0], -halfSide[1], halfSide[2]]);
  2800. points[3] = Vector3DUtil.add(center,[-halfSide[0], halfSide[1], halfSide[2]]);
  2801. points[4] = Vector3DUtil.add(center,[-halfSide[0], -halfSide[1], -halfSide[2]]);
  2802. points[5] = Vector3DUtil.add(center,[-halfSide[0], halfSide[1], -halfSide[2]]);
  2803. points[6] = Vector3DUtil.add(center,[halfSide[0], -halfSide[1], -halfSide[2]]);
  2804. points[7] = Vector3DUtil.add(center,[halfSide[0], halfSide[1], -halfSide[2]]);
  2805. return points;
  2806. }
  2807. JAABox.prototype.get_edges=function(){
  2808. return [
  2809. new EdgeData( 0, 1 ), new EdgeData( 0, 2 ), new EdgeData( 0, 6 ),
  2810. new EdgeData( 2, 3 ), new EdgeData( 2, 4 ), new EdgeData( 6, 7 ),
  2811. new EdgeData( 6, 4 ), new EdgeData( 1, 3 ), new EdgeData( 1, 7 ),
  2812. new EdgeData( 3, 5 ), new EdgeData( 7, 5 ), new EdgeData( 4, 5 )];
  2813. }
  2814. /**
  2815. * @function move moves the JAABox by delta
  2816. * @param {array} delta a 3D vector
  2817. * @type void
  2818. **/
  2819. JAABox.prototype.move=function(delta){
  2820. Vector3DUtil.add(this._minPos, delta);
  2821. Vector3DUtil.add(this._maxPos, delta);
  2822. };
  2823. /**
  2824. * @function clear resets the JAABox
  2825. * @type void
  2826. **/
  2827. JAABox.prototype.clear=function(){
  2828. this._minPos = Vector3DUtil.create(JNumber3D.NUM_HUGE, JNumber3D.NUM_HUGE, JNumber3D.NUM_HUGE, 0);
  2829. this._maxPos = Vector3DUtil.create(-JNumber3D.NUM_HUGE, -JNumber3D.NUM_HUGE, -JNumber3D.NUM_HUGE, 0);
  2830. };
  2831. /**
  2832. * @function clone clones the JAABox
  2833. * @returns a copy of this JAABox
  2834. * @type JAABox
  2835. **/
  2836. JAABox.prototype.clone=function(){
  2837. return new JAABox(this._minPos, this._maxPos);
  2838. };
  2839. /**
  2840. * @function addPoint
  2841. * @param {array} pos a 3D vector
  2842. * @type void
  2843. **/
  2844. JAABox.prototype.addPoint=function(pos){
  2845. var _minPos=this._minPos;
  2846. var _maxPos=this._maxPos;
  2847. if (pos[0] < _minPos[0]) _minPos[0] = pos[0] - JNumber3D.NUM_TINY;
  2848. if (pos[0] > _maxPos[0]) _maxPos[0] = pos[0] + JNumber3D.NUM_TINY;
  2849. if (pos[1] < _minPos[1]) _minPos[1] = pos[1] - JNumber3D.NUM_TINY;
  2850. if (pos[1] > _maxPos[1]) _maxPos[1] = pos[1] + JNumber3D.NUM_TINY;
  2851. if (pos[2] < _minPos[2]) _minPos[2] = pos[2] - JNumber3D.NUM_TINY;
  2852. if (pos[2] > _maxPos[2]) _maxPos[2] = pos[2] + JNumber3D.NUM_TINY;
  2853. };
  2854. /**
  2855. * @function addBox
  2856. * @param {JBox} box
  2857. * @type void
  2858. **/
  2859. JAABox.prototype.addBox=function(box){
  2860. var pts = box.getCornerPoints(box.get_currentState());
  2861. this.addPoint(pts[0]);
  2862. this.addPoint(pts[1]);
  2863. this.addPoint(pts[2]);
  2864. this.addPoint(pts[3]);
  2865. this.addPoint(pts[4]);
  2866. this.addPoint(pts[5]);
  2867. this.addPoint(pts[6]);
  2868. this.addPoint(pts[7]);
  2869. };
  2870. /**
  2871. * @function addSphere
  2872. * @param {JSphere} sphere
  2873. * @type void
  2874. **/
  2875. JAABox.prototype.addSphere=function(sphere){
  2876. var _minPos=this._minPos;
  2877. var _maxPos=this._maxPos;
  2878. if (sphere.get_currentState().position[0] - sphere.get_radius() < _minPos[0])
  2879. _minPos[0] = (sphere.get_currentState().position[0] - sphere.get_radius()) - JNumber3D.NUM_TINY;
  2880. if (sphere.get_currentState().position[0] + sphere.get_radius() > _maxPos[0])
  2881. _maxPos[0] = (sphere.get_currentState().position[0] + sphere.get_radius()) + JNumber3D.NUM_TINY;
  2882. if (sphere.get_currentState().position[1] - sphere.get_radius() < _minPos[1])
  2883. _minPos[1] = (sphere.get_currentState().position[1] - sphere.get_radius()) - JNumber3D.NUM_TINY;
  2884. if (sphere.get_currentState().position[1] + sphere.get_radius() > _maxPos[1])
  2885. _maxPos[1] = (sphere.get_currentState().position[1] + sphere.get_radius()) + JNumber3D.NUM_TINY;
  2886. if (sphere.get_currentState().position[2] - sphere.get_radius() < _minPos[2])
  2887. _minPos[2] = (sphere.get_currentState().position[2] - sphere.get_radius()) - JNumber3D.NUM_TINY;
  2888. if (sphere.get_currentState().position[2] + sphere.get_radius() > _maxPos[2])
  2889. _maxPos[2] = (sphere.get_currentState().position[2] + sphere.get_radius()) + JNumber3D.NUM_TINY;
  2890. };
  2891. /**
  2892. * @function addCapsule
  2893. * @param {JCapsule} capsule
  2894. * @type void
  2895. **/
  2896. JAABox.prototype.addCapsule=function(capsule){
  2897. var pos= capsule.getBottomPos(capsule.get_currentState());
  2898. var _minPos=this._minPos;
  2899. var _maxPos=this._maxPos;
  2900. if (pos[0] - capsule.get_radius() < _minPos[0])
  2901. _minPos[0] = (pos[0] - capsule.get_radius()) - JNumber3D.NUM_TINY;
  2902. if (pos[0] + capsule.get_radius() > _maxPos[0])
  2903. _maxPos[0] = (pos[0] + capsule.get_radius()) + JNumber3D.NUM_TINY;
  2904. if (pos[1] - capsule.get_radius() < _minPos[1])
  2905. _minPos[1] = (pos[1] - capsule.get_radius()) - JNumber3D.NUM_TINY;
  2906. if (pos[1] + capsule.get_radius() > _maxPos[1])
  2907. _maxPos[1] = (pos[1] + capsule.get_radius()) + JNumber3D.NUM_TINY;
  2908. if (pos[2] - capsule.get_radius() < _minPos[2])
  2909. _minPos[2] = (pos[2] - capsule.get_radius()) - JNumber3D.NUM_TINY;
  2910. if (pos[2] + capsule.get_radius() > _maxPos[2])
  2911. _maxPos[2] = (pos[2] + capsule.get_radius()) + JNumber3D.NUM_TINY;
  2912. pos = capsule.getEndPos(capsule.get_currentState());
  2913. if (pos[0] - capsule.get_radius() < _minPos[0])
  2914. _minPos[0] = (pos[0] - capsule.get_radius()) - JNumber3D.NUM_TINY;
  2915. if (pos[0] + capsule.get_radius() > _maxPos[0])
  2916. _maxPos[0] = (pos[0] + capsule.get_radius()) + JNumber3D.NUM_TINY;
  2917. if (pos[1] - capsule.get_radius() < _minPos[1])
  2918. _minPos[1] = (pos[1] - capsule.get_radius()) - JNumber3D.NUM_TINY;
  2919. if (pos[1] + capsule.get_radius() > _maxPos[1])
  2920. _maxPos[1] = (pos[1] + capsule.get_radius()) + JNumber3D.NUM_TINY;
  2921. if (pos[2] - capsule.get_radius() < _minPos[2])
  2922. _minPos[2] = (pos[2] - capsule.get_radius()) - JNumber3D.NUM_TINY;
  2923. if (pos[2] + capsule.get_radius() > _maxPos[2])
  2924. _maxPos[2] = (pos[2] + capsule.get_radius()) + JNumber3D.NUM_TINY;
  2925. };
  2926. /**
  2927. * @function addSegment
  2928. * @param {JSegment} seg
  2929. * @type void
  2930. **/
  2931. JAABox.prototype.addSegment=function(seg){
  2932. this.addPoint(seg.origin);
  2933. this.addPoint(seg.getEnd());
  2934. };
  2935. /**
  2936. * @function overlapTest tests for an overlap between 2 boxes
  2937. * @param {JAABox} box
  2938. * @type boolean
  2939. **/
  2940. JAABox.prototype.overlapTest=function(box){
  2941. var _minPos=this._minPos;
  2942. var _maxPos=this._maxPos;
  2943. return ((_minPos[2] >= box.get_maxPos()[2]) ||
  2944. (_maxPos[2] <= box.get_minPos()[2]) ||
  2945. (_minPos[1] >= box.get_maxPos()[1]) ||
  2946. (_maxPos[1] <= box.get_minPos()[1]) ||
  2947. (_minPos[0] >= box.get_maxPos()[0]) ||
  2948. (_maxPos[0] <= box.get_minPos()[0])) ? false : true;
  2949. };
  2950. /**
  2951. * @function isPointInside tests if a given point lies inside this JAABox
  2952. * @param {array} pos a 3D vector
  2953. * @type boolean
  2954. **/
  2955. JAABox.prototype.isPointInside=function(pos){
  2956. var _minPos=this._minPos;
  2957. var _maxPos=this._maxPos;
  2958. return ((pos[0] >= _minPos[0]) &&
  2959. (pos[0] <= _maxPos[0]) &&
  2960. (pos[1] >= _minPos[1]) &&
  2961. (pos[1] <= _maxPos[1]) &&
  2962. (pos[2] >= _minPos[2]) &&
  2963. (pos[2] <= _maxPos[2]));
  2964. };
  2965. JAABox.prototype.getRadiusAboutCentre=function(){
  2966. return 0.5 * (Vector3DUtil.get_length(Vector3DUtil.subtract(this._maxPos,this._minPos)));
  2967. }
  2968. JAABox.prototype.scaleBox=function(factor){
  2969. var center=this.get_centrePos()
  2970. var deltamin=Vector3DUtil.subtract(this._minPos,center);
  2971. Vector3DUtil.scaleBy(deltamin,factor);
  2972. this._minPos=Vector3DUtil.subtract(this._minPos,deltamin);
  2973. var deltamax=Vector3DUtil.subtract(this._maxPos,center);
  2974. Vector3DUtil.scaleBy(deltamax,factor);
  2975. this._maxPos=Vector3DUtil.subtract(this._maxPos,deltamax);
  2976. }
  2977. /**
  2978. * @function toString
  2979. * @type string
  2980. **/
  2981. JAABox.prototype.toString=function(){
  2982. var _minPos=this._minPos;
  2983. var _maxPos=this._maxPos;
  2984. return [_minPos[0],_minPos[1],_minPos[2],_maxPos[0],_maxPos[1],_maxPos[2]].toString();
  2985. };
  2986. /*
  2987. JAABox.prototype.segmentAABoxOverlap=function(seg){
  2988. pt1 = seg.origin;
  2989. pt2 = seg.getEnd();
  2990. //if either point is inside the box then it must overlap!
  2991. if(this.isPointInside(pt1) || this.isPointInside(pt2)){
  2992. return true;
  2993. }
  2994. min= this._minPos;
  2995. max = this._maxPos;
  2996. var sidesIntersected1=( (pt1[0]-min[0])*(pt2[0]-min[0])<=0 ) + ( (pt1[0]-max[0])*(pt2[0]-max[0])<=0 ) +
  2997. ( (pt1[1]-min[1])*(pt2[1]-min[1])<=0 ) + ( (pt1[1]-max[1])*(pt2[1]-max[1])<=0 );
  2998. var sidesIntersected2=( (pt1[0]-min[0])*(pt2[0]-min[0])<=0 ) + ( (pt1[0]-max[0])*(pt2[0]-max[0])<=0 ) +
  2999. ( (pt1[2]-min[2])*(pt2[2]-min[2])<=0 ) + ( (pt1[2]-max[2])*(pt2[2]-max[2])<=0 );
  3000. var sidesIntersected3=( (pt1[1]-min[1])*(pt2[1]-min[1])<=0 ) + ( (pt1[1]-max[1])*(pt2[1]-max[1])<=0 ) +
  3001. ( (pt1[2]-min[2])*(pt2[2]-min[2])<=0 ) + ( (pt1[2]-max[2])*(pt2[2]-max[2])<=0 );
  3002. if((sidesIntersected1>1) + (sidesIntersected2>1) + (sidesIntersected3>1)>1) return true;
  3003. return false;
  3004. };*/
  3005. JAABox.prototype.segmentAABoxOverlap=function(seg){
  3006. var fst = 0;
  3007. var fet = 1;
  3008. var pt1 = seg.origin;
  3009. var pt2 = seg.getEnd();
  3010. var min= this._minPos;
  3011. var max = this._maxPos;
  3012. for (var i = 0; i < 3; i++) {
  3013. var s=pt1[i];var e=pt2[i];
  3014. var amax=max[i];var amin=min[i];
  3015. if (s < e) {
  3016. if (s > amax || e < amin){
  3017. return false;
  3018. }
  3019. }else {
  3020. if (e > amax || s < amin){
  3021. return false;
  3022. }
  3023. }
  3024. var d = e - s;
  3025. var st = (s < amin) ? (amin - s) / d : 0;
  3026. var et = (e > amax) ? (amax - s) / d : 1;
  3027. if (st > fst) fst = st;
  3028. if (et < fet) fet = et;
  3029. if (fet < fst){
  3030. return false;
  3031. }
  3032. }
  3033. return true;
  3034. }
  3035. /*
  3036. JAABox.prototype.segmentAABoxOverlap=function(seg){
  3037. var jDir,kDir,i,iFace;
  3038. var frac,dist0,dist1,tiny=JNumber3D.NUM_TINY;
  3039. var pt,minPosArr,maxPosArr,p0,p1,faceOffsets;
  3040. minPosArr = this._minPos.slice(0);
  3041. maxPosArr = this._maxPos.slice(0);
  3042. p0 = seg.origin.slice(0);
  3043. p1 = seg.getEnd().slice(0);
  3044. for (i = 0; i < 3; i++ ) {
  3045. jDir = (i + 1) % 3;
  3046. kDir = (i + 2) % 3;
  3047. faceOffsets = [minPosArr[i], maxPosArr[i]];
  3048. for (iFace = 0 ; iFace < 2 ; iFace++) {
  3049. dist0 = p0[i] - faceOffsets[iFace];
  3050. dist1 = p1[i] - faceOffsets[iFace];
  3051. frac = -1;
  3052. if (dist0 * dist1 < -tiny){
  3053. frac = -dist0 / (dist1 - dist0);
  3054. }else if (Math.abs(dist0) < tiny){
  3055. frac = 0;
  3056. }else if (Math.abs(dist1) < tiny){
  3057. frac = 1;
  3058. }
  3059. if (frac >= 0) {
  3060. pt = seg.getPoint(frac).slice(0);
  3061. if((pt[jDir] > minPosArr[jDir] - tiny) &&
  3062. (pt[jDir] < maxPosArr[jDir] + tiny) &&
  3063. (pt[kDir] > minPosArr[kDir] - tiny) &&
  3064. (pt[kDir] < maxPosArr[kDir] + tiny)) {
  3065. return true;
  3066. }
  3067. }
  3068. }
  3069. }
  3070. return false;
  3071. }*/
  3072. jigLib.JAABox=JAABox;
  3073. })(jigLib);
  3074. /*
  3075. Copyright (c) 2007 Danny Chapman
  3076. http://www.rowlhouse.co.uk
  3077. This software is provided 'as-is', without any express or implied
  3078. warranty. In no event will the authors be held liable for any damages
  3079. arising from the use of this software.
  3080. Permission is granted to anyone to use this software for any purpose,
  3081. including commercial applications, and to alter it and redistribute it
  3082. freely, subject to the following restrictions:
  3083. 1. The origin of this software must not be misrepresented; you must not
  3084. claim that you wrote the original software. If you use this software
  3085. in a product, an acknowledgment in the product documentation would be
  3086. appreciated but is not required.
  3087. 2. Altered source versions must be plainly marked as such, and must not be
  3088. misrepresented as being the original software.
  3089. 3. This notice may not be removed or altered from any source
  3090. distribution.
  3091. */
  3092. (function(jigLib){
  3093. /**
  3094. * @author Muzer(muzerly@gmail.com)
  3095. *
  3096. * @name BodyPair
  3097. * @class BodyPair a container for a pair of RigidBody objects
  3098. * @property {RigidBody} body0 the first body of the constrained pair
  3099. * @property {RigidBody} body1 the second body of the constrained pair
  3100. * @property {array} r a 3D vector
  3101. * @constructor
  3102. * @param {RigidBody} _body0 the first body of the constrained pair
  3103. * @param {RigidBody} _body1 the second body of the constrained pair
  3104. * @param {array} _r0 a 3D vector
  3105. * @param {array} _r1 a 3D vector
  3106. **/
  3107. var BodyPair=function(_body0, _body1, r0, r1){
  3108. if (_body0.id > _body1.id){
  3109. this.body0 = _body0;
  3110. this.body1 = _body1;
  3111. this.r = r0;
  3112. }else{
  3113. this.body0 = _body1;
  3114. this.body1 = _body0;
  3115. this.r = r1;
  3116. }
  3117. };
  3118. BodyPair.prototype.body0=null;
  3119. BodyPair.prototype.body1=null;
  3120. BodyPair.prototype.r=null;
  3121. jigLib.BodyPair=BodyPair;
  3122. })(jigLib);/*
  3123. Copyright (c) 2007 Danny Chapman
  3124. http://www.rowlhouse.co.uk
  3125. This software is provided 'as-is', without any express or implied
  3126. warranty. In no event will the authors be held liable for any damages
  3127. arising from the use of this software.
  3128. Permission is granted to anyone to use this software for any purpose,
  3129. including commercial applications, and to alter it and redistribute it
  3130. freely, subject to the following restrictions:
  3131. 1. The origin of this software must not be misrepresented; you must not
  3132. claim that you wrote the original software. If you use this software
  3133. in a product, an acknowledgment in the product documentation would be
  3134. appreciated but is not required.
  3135. 2. Altered source versions must be plainly marked as such, and must not be
  3136. misrepresented as being the original software.
  3137. 3. This notice may not be removed or altered from any source
  3138. distribution.
  3139. */
  3140. (function(jigLib){
  3141. /**
  3142. * @author Muzer(muzerly@gmail.com)
  3143. *
  3144. * @name CachedImpulse
  3145. * @class CachedImpulse
  3146. * @property {number} normalImpulse
  3147. * @property {number} normalImpulseAux
  3148. * @property {array} frictionImpulse a 3D vector
  3149. * @constructor
  3150. * @param {number} _normalImpulse
  3151. * @param {number} _normalImpulseAux
  3152. * @param {array} _frictionImpulse a 3D vector
  3153. **/
  3154. var CachedImpulse=function(_normalImpulse, _normalImpulseAux, _frictionImpulse){
  3155. this.normalImpulse = _normalImpulse;
  3156. this.normalImpulseAux = _normalImpulseAux;
  3157. this.frictionImpulse = _frictionImpulse;
  3158. };
  3159. CachedImpulse.prototype.normalImpulse=null;
  3160. CachedImpulse.prototype.normalImpulseAux=null;
  3161. CachedImpulse.prototype.frictionImpulse=null;
  3162. jigLib.CachedImpulse=CachedImpulse;
  3163. })(jigLib);/*
  3164. Copyright (c) 2007 Danny Chapman
  3165. http://www.rowlhouse.co.uk
  3166. This software is provided 'as-is', without any express or implied
  3167. warranty. In no event will the authors be held liable for any damages
  3168. arising from the use of this software.
  3169. Permission is granted to anyone to use this software for any purpose,
  3170. including commercial applications, and to alter it and redistribute it
  3171. freely, subject to the following restrictions:
  3172. 1. The origin of this software must not be misrepresented; you must not
  3173. claim that you wrote the original software. If you use this software
  3174. in a product, an acknowledgment in the product documentation would be
  3175. appreciated but is not required.
  3176. 2. Altered source versions must be plainly marked as such, and must not be
  3177. misrepresented as being the original software.
  3178. 3. This notice may not be removed or altered from any source
  3179. distribution.
  3180. */
  3181. (function(jigLib){
  3182. /**
  3183. * @author Muzer(muzerly@gmail.com)
  3184. *
  3185. * @name MaterialProperties
  3186. * @class MaterialProperties
  3187. * @property {number} _restitution
  3188. * @property {number} _friction
  3189. * @constructor
  3190. * @param {number} restitution
  3191. * @param {number} friction
  3192. **/
  3193. var MaterialProperties=function(restitution, friction){
  3194. if(restitution==null) restitution=0.25;
  3195. if(friction==null) friction=0.25;
  3196. this._restitution = restitution;
  3197. this._friction = friction;
  3198. };
  3199. MaterialProperties.prototype._restitution=null;
  3200. MaterialProperties.prototype._friction=null;
  3201. /**
  3202. * @function get_restitution getter for _restitution
  3203. * @type number
  3204. **/
  3205. MaterialProperties.prototype.get_restitution=function(){
  3206. return this._restitution;
  3207. };
  3208. /**
  3209. * @function set_restitution setter for _restitution
  3210. * @param {number} restitution
  3211. * @type void
  3212. **/
  3213. MaterialProperties.prototype.set_restitution=function(restitution){
  3214. this._restitution = restitution;
  3215. };
  3216. /**
  3217. * @function get_restitution getter for _friction
  3218. * @type number
  3219. **/
  3220. MaterialProperties.prototype.get_friction=function(){
  3221. return this._friction;
  3222. };
  3223. /**
  3224. * @function get_restitution setter for _friction
  3225. * @param {number} friction
  3226. * @type void
  3227. **/
  3228. MaterialProperties.prototype.set_friction=function(friction){
  3229. this._friction = friction;
  3230. };
  3231. jigLib.MaterialProperties=MaterialProperties;
  3232. })(jigLib);/*
  3233. Copyright (c) 2007 Danny Chapman
  3234. http://www.rowlhouse.co.uk
  3235. This software is provided 'as-is', without any express or implied
  3236. warranty. In no event will the authors be held liable for any damages
  3237. arising from the use of this software.
  3238. Permission is granted to anyone to use this software for any purpose,
  3239. including commercial applications, and to alter it and redistribute it
  3240. freely, subject to the following restrictions:
  3241. 1. The origin of this software must not be misrepresented; you must not
  3242. claim that you wrote the original software. If you use this software
  3243. in a product, an acknowledgment in the product documentation would be
  3244. appreciated but is not required.
  3245. 2. Altered source versions must be plainly marked as such, and must not be
  3246. misrepresented as being the original software.
  3247. 3. This notice may not be removed or altered from any source
  3248. distribution.
  3249. */
  3250. (function(jigLib){
  3251. /**
  3252. * @author Muzer(muzerly@gmail.com)
  3253. *
  3254. * @name PhysicsController
  3255. * @class PhysicsController
  3256. * @property {boolean} _controllerEnabled
  3257. * @constructor
  3258. **/
  3259. var PhysicsController=function(){
  3260. this._controllerEnabled = false;
  3261. };
  3262. PhysicsController.prototype._controllerEnabled=null;
  3263. /**
  3264. * @function updateController implement this to apply whatever forces are needed to the objects this controls
  3265. * @param {number} dt a UNIX timestamp
  3266. * @type void
  3267. **/
  3268. PhysicsController.prototype.updateController=function(dt){
  3269. };
  3270. /**
  3271. * @function enableController register with the physics system
  3272. * @type void
  3273. **/
  3274. PhysicsController.prototype.enableController=function(){
  3275. if (this._controllerEnabled){
  3276. return;
  3277. }
  3278. this._controllerEnabled = true;
  3279. jigLib.PhysicsSystem.getInstance().addController(this);
  3280. };
  3281. /**
  3282. * @function disableController de-register from the physics system
  3283. * @type void
  3284. **/
  3285. PhysicsController.prototype.disableController=function(){
  3286. if (!this._controllerEnabled){
  3287. return;
  3288. }
  3289. this._controllerEnabled = false;
  3290. jigLib.PhysicsSystem.getInstance().removeController(this);
  3291. };
  3292. /**
  3293. * @function get_controllerEnabled returns true if this controller is registered with the PhysicsSystem
  3294. * @type boolean
  3295. **/
  3296. PhysicsController.prototype.get_controllerEnabled=function(){
  3297. return this._controllerEnabled;
  3298. };
  3299. jigLib.PhysicsController=PhysicsController;
  3300. })(jigLib);(function(jigLib){
  3301. var Matrix3D=jigLib.Matrix3D;
  3302. var JMatrix3D=jigLib.JMatrix3D;
  3303. /**
  3304. * @author katopz
  3305. * Devin Reimer (blog.almostlogical.com)
  3306. *
  3307. * @name PhysicsState
  3308. * @class PhysicsState
  3309. * @requires Matrix3D
  3310. * @requires JMatrix3D
  3311. * @property {array} position
  3312. * @property {Matrix3D}
  3313. * @property {array} linVelocity
  3314. * @property {array} rotVelocity
  3315. * @property {array} orientationCols
  3316. * @constructor
  3317. **/
  3318. var PhysicsState=function(){
  3319. this._orientation = new Matrix3D();
  3320. };
  3321. PhysicsState.prototype.position = [0,0,0,0];
  3322. PhysicsState.prototype._orientation;
  3323. PhysicsState.prototype.linVelocity = [0,0,0,0];
  3324. PhysicsState.prototype.rotVelocity = [0,0,0,0];
  3325. PhysicsState.prototype.orientationCols = [[0,0,0,0],[0,0,0,0],[0,0,0,0]];
  3326. /**
  3327. * @function get_orientation getter for _orientation
  3328. * @type Matrix3D
  3329. **/
  3330. PhysicsState.prototype.get_orientation=function(){ return this._orientation; };
  3331. /**
  3332. * @function set_orientation setter for _orientation
  3333. * @param {array} val
  3334. **/
  3335. PhysicsState.prototype.set_orientation=function(val){
  3336. this._orientation = val;
  3337. var _rawData = this._orientation.glmatrix;
  3338. this.orientationCols[0][0] = _rawData[0];
  3339. this.orientationCols[0][1] = _rawData[1];
  3340. this.orientationCols[0][2] = _rawData[2];
  3341. this.orientationCols[1][0] = _rawData[4];
  3342. this.orientationCols[1][1] = _rawData[5];
  3343. this.orientationCols[1][2] = _rawData[6];
  3344. this.orientationCols[2][0] = _rawData[8];
  3345. this.orientationCols[2][1] = _rawData[9];
  3346. this.orientationCols[2][2] = _rawData[10];
  3347. };
  3348. /**
  3349. * @function getOrientationCols here for backwards compatibility should use this.orientationCols unless you need a clone
  3350. * @type array
  3351. **/
  3352. PhysicsState.prototype.getOrientationCols=function(){
  3353. return JMatrix3D.getCols(this._orientation);
  3354. };
  3355. jigLib.PhysicsState=PhysicsState;
  3356. })(jigLib);/*
  3357. Copyright (c) 2007 Danny Chapman
  3358. http://www.rowlhouse.co.uk
  3359. This software is provided 'as-is', without any express or implied
  3360. warranty. In no event will the authors be held liable for any damages
  3361. arising from the use of this software.
  3362. Permission is granted to anyone to use this software for any purpose,
  3363. including commercial applications, and to alter it and redistribute it
  3364. freely, subject to the following restrictions:
  3365. 1. The origin of this software must not be misrepresented; you must not
  3366. claim that you wrote the original software. If you use this software
  3367. in a product, an acknowledgment in the product documentation would be
  3368. appreciated but is not required.
  3369. 2. Altered source versions must be plainly marked as such, and must not be
  3370. misrepresented as being the original software.
  3371. 3. This notice may not be removed or altered from any source
  3372. distribution.
  3373. */
  3374. (function(jigLib){
  3375. var Vector3DUtil=jigLib.Vector3DUtil;
  3376. var JConfig=jigLib.JConfig;
  3377. var Matrix3D=jigLib.Matrix3D;
  3378. var JMatrix3D=jigLib.JMatrix3D;
  3379. var JNumber3D=jigLib.JNumber3D;
  3380. var MaterialProperties=jigLib.MaterialProperties;
  3381. var PhysicsState=jigLib.PhysicsState;
  3382. var PhysicsSystem=jigLib.PhysicsSystem;
  3383. var JAABox=jigLib.JAABox;
  3384. var JCollisionEvent=jigLib.JCollisionEvent;
  3385. /**
  3386. * @name RigidBody
  3387. * @class RigidBody a body in the physics simulation
  3388. * @requires Vector3DUtil
  3389. * @requires JConfig
  3390. * @requires Matrix3D
  3391. * @requires JMatrix3D
  3392. * @requires JNumber3D
  3393. * @requires MaterialProperties
  3394. * @requires PhysicsState
  3395. * @requires PhysicsSystem
  3396. * @requires JAABox
  3397. * @property {number} idCounter
  3398. * @property {number} _id
  3399. * @property {ISkin3D} _skin
  3400. * @property {string} _type
  3401. * @property {number} _boundingSphere
  3402. * @property {JAABox} _boundingBox
  3403. * @property {PhysicsState} _currState
  3404. * @property {PhysicsState} _oldState
  3405. * @property {PhysicsState} _storeState
  3406. * @property {Matrix3D} _invOrientation
  3407. * @property {array} _currLinVelocityAux a 3D vector
  3408. * @property {array} _currRotVelocityAux a 3D vector
  3409. * @property {number} _mass
  3410. * @property {number} _invMass
  3411. * @property {Matrix3D} _bodyInertia
  3412. * @property {Matrix3D} _bodyInvInertia
  3413. * @property {Matrix3D} _worldInertia
  3414. * @property {Matrix3D} _worldInvInertia
  3415. * @property {array} _force a 3D vector
  3416. * @property {array} _torque a 3D vector
  3417. * @property {array} _linVelDamping a 3D vector
  3418. * @property {array} _rotVelDamping a 3D vector
  3419. * @property {number} _maxLinVelocities
  3420. * @property {number} _maxRotVelocities
  3421. * @property {boolean} _velChanged
  3422. * @property {boolean} _activity
  3423. * @property {boolean} _movable
  3424. * @property {boolean} _origMovable
  3425. * @property {number} _inactiveTime
  3426. * @property {boolean} _doShockProcessing
  3427. * @property {RigidBody} _bodiesToBeActivatedOnMovement the list of bodies that need to be activated when we move away from our stored position
  3428. * @property {array} _storedPositionForActivation a 3D vector the position stored when we need to notify other bodies
  3429. * @property {array} _lastPositionForDeactivation a 3D vector last position for when trying the deactivate
  3430. * @property {Matrix3D} _lastOrientationForDeactivation last orientation for when trying to deactivate
  3431. * @property {MaterialProperties} _material
  3432. * @property {number} _rotationX
  3433. * @property {number} _rotationY
  3434. * @property {number} _rotationZ
  3435. * @property {boolean} _useDegrees
  3436. * @property {array} _nonCollidables a collection of RigidBody objects
  3437. * @property {array} _constraints a collection of JConstraint objects
  3438. * @property {array} collisions a collection of CollisionInfo objects
  3439. * @property {boolean} isActive
  3440. * @property {number} minImpulseForCollisionEvent the minimum total absolute impulse required to trigger a collision event
  3441. * @constructor
  3442. * @param {ISkin3D} _skin
  3443. **/
  3444. var RigidBody=function(skin){
  3445. // calling "this.Super" causes recursion in inheritance chains
  3446. // because Super references this class constructor
  3447. //this.Super(skin);
  3448. jigLib.JEventDispatcher.call(this);
  3449. this._useDegrees = (JConfig.rotationType == "DEGREES") ? true : false;
  3450. this._id = RigidBody.idCounter++;
  3451. this._skin = skin;
  3452. this._material = new MaterialProperties();
  3453. this._bodyInertia = new Matrix3D();
  3454. this._bodyInvInertia = JMatrix3D.getInverseMatrix(this._bodyInertia);
  3455. this._currState = new PhysicsState();
  3456. this._oldState = new PhysicsState();
  3457. this._storeState = new PhysicsState();
  3458. this._invOrientation = JMatrix3D.getInverseMatrix(this._currState.get_orientation());
  3459. this._currLinVelocityAux = [0,0,0,0];
  3460. this._currRotVelocityAux = [0,0,0,0];
  3461. this._force = [0,0,0,0];
  3462. this._torque = [0,0,0,0];
  3463. this._linVelDamping = [0.995, 0.995, 0.995, 0];
  3464. this._rotVelDamping = [0.5, 0.5, 0.5, 0];
  3465. this._maxLinVelocities = 500;
  3466. this._maxRotVelocities = 500;
  3467. this._velChanged = false;
  3468. this._inactiveTime = 0;
  3469. this._doShockProcessing = true;
  3470. this.isActive = this._activity = true;
  3471. this._movable = true;
  3472. this._origMovable = true;
  3473. this.collisions = [];
  3474. this._constraints = [];
  3475. this._nonCollidables = [];
  3476. this._storedPositionForActivation = [0,0,0,0];
  3477. this._bodiesToBeActivatedOnMovement = [];
  3478. this._lastPositionForDeactivation = this._currState.position.slice(0);
  3479. this._lastOrientationForDeactivation = this._currState.get_orientation().clone();
  3480. this._type = "Object3D";
  3481. this._boundingSphere = 0;
  3482. this._boundingBox = new JAABox([0,0,0,0], [0,0,0,0]);
  3483. this._boundingBox.clear();
  3484. };
  3485. jigLib.extend(RigidBody,jigLib.JEventDispatcher);
  3486. RigidBody.idCounter = 0;
  3487. RigidBody.prototype._id=null;
  3488. RigidBody.prototype._skin=null;
  3489. RigidBody.prototype._type=null;
  3490. RigidBody.prototype._boundingSphere=null;
  3491. RigidBody.prototype._boundingBox=null;
  3492. RigidBody.prototype._currState=null;
  3493. RigidBody.prototype._oldState=null;
  3494. RigidBody.prototype._storeState=null;
  3495. RigidBody.prototype._invOrientation=null;
  3496. RigidBody.prototype._currLinVelocityAux=null;
  3497. RigidBody.prototype._currRotVelocityAux=null;
  3498. RigidBody.prototype._mass=null;
  3499. RigidBody.prototype._invMass=null;
  3500. RigidBody.prototype._bodyInertia=null;
  3501. RigidBody.prototype._bodyInvInertia=null;
  3502. RigidBody.prototype._worldInertia=null;
  3503. RigidBody.prototype._worldInvInertia=null;
  3504. RigidBody.prototype._force=null;
  3505. RigidBody.prototype._torque=null;
  3506. RigidBody.prototype._linVelDamping=null;
  3507. RigidBody.prototype._rotVelDamping=null;
  3508. RigidBody.prototype._maxLinVelocities=null;
  3509. RigidBody.prototype._maxRotVelocities=null;
  3510. RigidBody.prototype._velChanged=null;
  3511. RigidBody.prototype._activity=null;
  3512. RigidBody.prototype._movable=null;
  3513. RigidBody.prototype._origMovable=null;
  3514. RigidBody.prototype._inactiveTime=null;
  3515. RigidBody.prototype._doShockProcessing=null;
  3516. // The list of bodies that need to be activated when we move away from our stored position
  3517. RigidBody.prototype._bodiesToBeActivatedOnMovement=null;
  3518. RigidBody.prototype._storedPositionForActivation=null;// The position stored when we need to notify other bodies
  3519. RigidBody.prototype._lastPositionForDeactivation=null;// last position for when trying the deactivate
  3520. RigidBody.prototype._lastOrientationForDeactivation=null;// last orientation for when trying to deactivate
  3521. RigidBody.prototype._material=null;
  3522. RigidBody.prototype._rotationX = 0;
  3523. RigidBody.prototype._rotationY = 0;
  3524. RigidBody.prototype._rotationZ = 0;
  3525. RigidBody.prototype._useDegrees=null;
  3526. RigidBody.prototype._nonCollidables=null;
  3527. RigidBody.prototype._constraints=null;
  3528. RigidBody.prototype.collisions=null;
  3529. RigidBody.prototype.isActive=null;
  3530. RigidBody.prototype.minImpulseForCollisionEvent = 1;
  3531. /**
  3532. * @function dispatchCollisionEvent dispatches a JCollisionEvent
  3533. * @param {RigidBody} body the other body involved in the collision
  3534. * @param {Array} impulse a 3D vector representing the impulse applied to this body as a result of the collision
  3535. */
  3536. RigidBody.prototype.dispatchCollisionEvent=function(body, impulse)
  3537. {
  3538. if (Vector3DUtil.getSum(impulse) < this.minImpulseForCollisionEvent)
  3539. return;
  3540. this.dispatchEvent(new JCollisionEvent(body, impulse));
  3541. };
  3542. /**
  3543. * @function radiansToDegrees converts radians to degrees
  3544. * @param {number} rad
  3545. * @type number
  3546. **/
  3547. RigidBody.prototype.radiansToDegrees=function(rad){
  3548. return rad * 180 / Math.PI;
  3549. };
  3550. /**
  3551. * @function degreesToRadians converts degrees to radians
  3552. * @param {number} deg
  3553. * @type number
  3554. **/
  3555. RigidBody.prototype.degreesToRadians=function(deg){
  3556. return deg * Math.PI / 180;
  3557. };
  3558. /**
  3559. * @function get_rotationX gets rotation in the X axis
  3560. * @type number
  3561. **/
  3562. RigidBody.prototype.get_rotationX=function(){
  3563. return this._rotationX;//(_useDegrees) ? radiansToDegrees(_rotationX) : _rotationX;
  3564. };
  3565. /**
  3566. * @function get_rotationY gets rotation in the Y axis
  3567. * @type number
  3568. **/
  3569. RigidBody.prototype.get_rotationY=function(){
  3570. return this._rotationY;//(_useDegrees) ? radiansToDegrees(_rotationY) : _rotationY;
  3571. };
  3572. /**
  3573. * @function get_rotationZ gets rotation in the Z axis
  3574. * @type number
  3575. **/
  3576. RigidBody.prototype.get_rotationZ=function(){
  3577. return this._rotationZ;//(_useDegrees) ? radiansToDegrees(_rotationZ) : _rotationZ;
  3578. };
  3579. /**
  3580. * @function set_rotationX sets rotation in the X axis
  3581. * @param {number} px
  3582. * @type void
  3583. **/
  3584. RigidBody.prototype.set_rotationX=function(px){
  3585. //var rad:Number = (_useDegrees) ? degreesToRadians(px) : px;
  3586. this._rotationX = px;
  3587. this.setOrientation(this.createRotationMatrix());
  3588. };
  3589. /**
  3590. * @function set_rotationY sets rotation in the Y axis
  3591. * @param {number} py
  3592. * @type void
  3593. **/
  3594. RigidBody.prototype.set_rotationY=function(py){
  3595. //var rad:Number = (_useDegrees) ? degreesToRadians(py) : py;
  3596. this._rotationY = py;
  3597. this.setOrientation(this.createRotationMatrix());
  3598. };
  3599. /**
  3600. * @function set_rotationZ sets rotation in the Z axis
  3601. * @param {number} pz
  3602. * @type void
  3603. **/
  3604. RigidBody.prototype.set_rotationZ=function(pz){
  3605. //var rad:Number = (_useDegrees) ? degreesToRadians(pz) : pz;
  3606. this._rotationZ = pz;
  3607. this.setOrientation(this.createRotationMatrix());
  3608. };
  3609. /**
  3610. * @function setRotation sets the rotation angle
  3611. * @param {array} vect [x,y,z] rotation
  3612. * @type void
  3613. **/
  3614. RigidBody.prototype.setRotation=function(vect){
  3615. this._rotationX=vect[0];
  3616. this._rotationY=vect[1];
  3617. this._rotationZ=vect[2];
  3618. this.setOrientation(this.createRotationMatrix());
  3619. };
  3620. /**
  3621. * @function setRotation sets the pitch angle
  3622. * @param {number} rot
  3623. * @type void
  3624. **/
  3625. RigidBody.prototype.pitch=function(rot){
  3626. this.setOrientation(JMatrix3D.getAppendMatrix3D(this.get_currentState().orientation, JMatrix3D.getRotationMatrixAxis(rot, Vector3DUtil.X_AXIS)));
  3627. };
  3628. /**
  3629. * @function setRotation sets the yaw angle
  3630. * @param {number} rot
  3631. * @type void
  3632. **/
  3633. RigidBody.prototype.yaw=function(rot){
  3634. this.setOrientation(JMatrix3D.getAppendMatrix3D(this.get_currentState().orientation, JMatrix3D.getRotationMatrixAxis(rot, Vector3DUtil.Y_AXIS)));
  3635. };
  3636. /**
  3637. * @function setRotation sets the roll angle
  3638. * @param {number} rot
  3639. * @type void
  3640. **/
  3641. RigidBody.prototype.roll=function(rot){
  3642. this.setOrientation(JMatrix3D.getAppendMatrix3D(this.get_currentState().orientation, JMatrix3D.getRotationMatrixAxis(rot, Vector3DUtil.Z_AXIS)));
  3643. };
  3644. /**
  3645. * @function createRotationMatrix returns a rotation matrix based on the current angles of rotation
  3646. * @type Matrix3D
  3647. **/
  3648. RigidBody.prototype.createRotationMatrix=function(){
  3649. var matrix3D = new Matrix3D();
  3650. matrix3D.appendRotation(this._rotationX, Vector3DUtil.X_AXIS);
  3651. matrix3D.appendRotation(this._rotationY, Vector3DUtil.Y_AXIS);
  3652. matrix3D.appendRotation(this._rotationZ, Vector3DUtil.Z_AXIS);
  3653. return matrix3D;
  3654. };
  3655. /**
  3656. * @function setOrientation set orientation using a matrix
  3657. * @param orient Matrix3D
  3658. * @type void
  3659. **/
  3660. RigidBody.prototype.setOrientation=function(orient){
  3661. this._currState.set_orientation(orient.clone());
  3662. this.updateInertia();
  3663. this.updateState();
  3664. };
  3665. /**
  3666. * @function get_position gets the current position
  3667. * @returns a 3D vector
  3668. * @type array
  3669. **/
  3670. RigidBody.prototype.get_position=function(){
  3671. return this._currState.position;
  3672. };
  3673. /**
  3674. * @function get_x gets the current position in the X axis
  3675. * @type number
  3676. **/
  3677. RigidBody.prototype.get_x=function(){
  3678. return this._currState.position[0];
  3679. };
  3680. /**
  3681. * @function get_y gets the current position in the Y axis
  3682. * @type number
  3683. **/
  3684. RigidBody.prototype.get_y=function(){
  3685. return this._currState.position[1];
  3686. };
  3687. /**
  3688. * @function get_z gets the current position in the Z axis
  3689. * @type number
  3690. **/
  3691. RigidBody.prototype.get_z=function(){
  3692. return this._currState.position[2];
  3693. };
  3694. /**
  3695. * @function set_x sets the current position in the X axis
  3696. * @param {number} px
  3697. * @type void
  3698. **/
  3699. RigidBody.prototype.set_x=function(px){
  3700. this._currState.position[0] = px;
  3701. this.updateState();
  3702. };
  3703. /**
  3704. * @function set_x sets the current position in the Y axis
  3705. * @param {number} py
  3706. * @type void
  3707. **/
  3708. RigidBody.prototype.set_y=function(py){
  3709. this._currState.position[1] = py;
  3710. this.updateState();
  3711. };
  3712. /**
  3713. * @function set_x sets the current position in the Z axis
  3714. * @param {number} pz
  3715. * @type void
  3716. **/
  3717. RigidBody.prototype.set_z=function(pz){
  3718. this._currState.position[2] = pz;
  3719. this.updateState();
  3720. };
  3721. /**
  3722. * @function move_to
  3723. * @param {array} pos a 3D vector
  3724. * @type void
  3725. **/
  3726. RigidBody.prototype.moveTo=function(pos){
  3727. this._currState.position = pos.slice(0);
  3728. this.updateState();
  3729. };
  3730. /**
  3731. * @function set_Transform
  3732. * @param {array} 16 element 4x4 transform
  3733. * @type void
  3734. **/
  3735. RigidBody.prototype.set_Transform=function( mat4 ){
  3736. this._currState.position = [ mat4[12], mat4[13], mat4[14], 0 ];
  3737. var matrix3D = new Matrix3D( mat4 );
  3738. matrix3D.glmatrix[12] = 0;
  3739. matrix3D.glmatrix[13] = 0;
  3740. matrix3D.glmatrix[14] = 0;
  3741. //matrix3D.glmatrix[15] = 1;
  3742. this._currState.set_orientation( matrix3D );
  3743. this.updateState();
  3744. };
  3745. /**
  3746. * @function get_Transform
  3747. * @returns {array} 16 element 4x4 transform
  3748. * @type void
  3749. **/
  3750. RigidBody.prototype.get_Transform=function(){
  3751. var matRet = new Float32Array( this._currState.get_orientation().glmatrix );
  3752. matRet[12] = this._currState.position[0];
  3753. matRet[13] = this._currState.position[1];
  3754. matRet[14] = this._currState.position[2];
  3755. matRet[15] = 1;
  3756. return matRet;
  3757. };
  3758. /**
  3759. * @function updateState
  3760. * @type void
  3761. **/
  3762. RigidBody.prototype.updateState=function(){
  3763. this._currState.linVelocity = [0,0,0,0];
  3764. this._currState.rotVelocity = [0,0,0,0];
  3765. this.copyCurrentStateToOld();
  3766. this.updateBoundingBox();
  3767. this.setActive();
  3768. };
  3769. /**
  3770. * @function setVelocity
  3771. * @param {array} vel velocity in each axis expressed as a 3D vector
  3772. * @param {boolean} local apply velocity in local frame
  3773. * @type void
  3774. **/
  3775. RigidBody.prototype.setVelocity=function(vel,local){
  3776. if(!local){
  3777. this._currState.linVelocity = vel.slice(0);
  3778. }else{
  3779. var matrix=this._currState.get_orientation();
  3780. this._currState.linVelocity[0]=matrix.glmatrix[0]*vel[0]+matrix.glmatrix[1]*vel[1]+matrix.glmatrix[2]*vel[2];
  3781. this._currState.linVelocity[1]=matrix.glmatrix[4]*vel[0]+matrix.glmatrix[5]*vel[1]+matrix.glmatrix[6]*vel[2];
  3782. this._currState.linVelocity[2]=matrix.glmatrix[8]*vel[0]+matrix.glmatrix[9]*vel[1]+matrix.glmatrix[10]*vel[2];
  3783. }
  3784. };
  3785. /**
  3786. * @function setAngVel
  3787. * @param {array} angVel a 3D vector
  3788. * @type void
  3789. **/
  3790. RigidBody.prototype.setAngVel=function(angVel){
  3791. this._currState.rotVelocity = angVel.slice(0);
  3792. };
  3793. /**
  3794. * @function setVelocityAux
  3795. * @param {array} vel a 3D vector
  3796. * @type void
  3797. **/
  3798. RigidBody.prototype.setVelocityAux=function(vel){
  3799. this._currLinVelocityAux = vel.slice(0);
  3800. };
  3801. /**
  3802. * @function setAngVelAux
  3803. * @param {array} angVel a 3D vector
  3804. * @type void
  3805. **/
  3806. RigidBody.prototype.setAngVelAux=function(angVel){
  3807. this._currRotVelocityAux = angVel.slice(0);
  3808. };
  3809. /**
  3810. * @function addGravity
  3811. * @type void
  3812. **/
  3813. RigidBody.prototype.addGravity=function(){
  3814. if (!this._movable){
  3815. return;
  3816. }
  3817. this._force = Vector3DUtil.add(this._force, JNumber3D.getScaleVector(jigLib.PhysicsSystem.getInstance().get_gravity(), this._mass));
  3818. this._velChanged = true;
  3819. };
  3820. /**
  3821. * @function addExternalForces
  3822. * @param {number} dt a UNIX timestamp
  3823. * @type void
  3824. **/
  3825. RigidBody.prototype.addExternalForces=function(dt){
  3826. this.addGravity();
  3827. };
  3828. /**
  3829. * @function addWorldTorque
  3830. * @param {array} t torque expressed as a 3D vector
  3831. * @type void
  3832. **/
  3833. RigidBody.prototype.addWorldTorque=function(t){
  3834. if (!this._movable) return;
  3835. this._torque = Vector3DUtil.add(this._torque, t);
  3836. this._velChanged = true;
  3837. this.setActive();
  3838. };
  3839. /**
  3840. * @function addBodyTorque
  3841. * @param {array} t torque expressed as a 3D vector
  3842. * @type void
  3843. **/
  3844. RigidBody.prototype.addBodyTorque=function(t){
  3845. if (!this._movable) return;
  3846. JMatrix3D.multiplyVector(this._currState.get_orientation(), t);
  3847. this.addWorldTorque(t);
  3848. };
  3849. /**
  3850. * @function addWorldForce add forces in the world coordinate frame
  3851. * @param {array} f force expressed as a 3D vector
  3852. * @param {array} p position of origin of the force expressed as a 3D vector
  3853. * @type void
  3854. **/
  3855. RigidBody.prototype.addWorldForce=function(f, p){
  3856. if (!this._movable) return;
  3857. this._force = Vector3DUtil.add(this._force, f);
  3858. this.addWorldTorque(Vector3DUtil.crossProduct(Vector3DUtil.subtract(p, this._currState.position), f));
  3859. this._velChanged = true;
  3860. this.setActive();
  3861. };
  3862. /**
  3863. * @function addBodyForce add forces in the body coordinate frame
  3864. * @param {array} f force expressed as a 3D vector
  3865. * @param {array} p position of origin of the force expressed as a 3D vector
  3866. * @type void
  3867. **/
  3868. RigidBody.prototype.addBodyForce=function(f, p){
  3869. if (!this._movable){
  3870. return;
  3871. }
  3872. JMatrix3D.multiplyVector(this._currState.get_orientation(), f);
  3873. JMatrix3D.multiplyVector(this._currState.get_orientation(), p);
  3874. this.addWorldForce(f, Vector3DUtil.add(this._currState.position, p));
  3875. };
  3876. /**
  3877. * @function clearForces remove active force and torque
  3878. * @type void
  3879. **/
  3880. RigidBody.prototype.clearForces=function(){
  3881. this._force = [0,0,0,0];
  3882. this._torque = [0,0,0,0];
  3883. };
  3884. /**
  3885. * @function applyWorldImpulse add impulses in the world coordinate frame
  3886. * @param {array} impulse impulse expressed as a 3D vector
  3887. * @param {array} pos position of origin of the impulse expressed as a 3D vector
  3888. * @type void
  3889. **/
  3890. RigidBody.prototype.applyWorldImpulse=function(impulse, pos){
  3891. if (!this._movable) return;
  3892. this._currState.linVelocity = Vector3DUtil.add(this._currState.linVelocity, JNumber3D.getScaleVector(impulse, this._invMass));
  3893. var rotImpulse = Vector3DUtil.crossProduct(Vector3DUtil.subtract(pos, this._currState.position), impulse);
  3894. JMatrix3D.multiplyVector(this._worldInvInertia, rotImpulse);
  3895. this._currState.rotVelocity = Vector3DUtil.add(this._currState.rotVelocity, rotImpulse);
  3896. this._velChanged = true;
  3897. };
  3898. /**
  3899. * @function applyWorldImpulseAux
  3900. * @param {array} impulse impulse expressed as a 3D vector
  3901. * @param {array} pos position of origin of the impulse expressed as a 3D vector
  3902. * @type void
  3903. **/
  3904. RigidBody.prototype.applyWorldImpulseAux=function(impulse, pos){
  3905. if (!this._movable) return;
  3906. this._currLinVelocityAux = Vector3DUtil.add(this._currLinVelocityAux, JNumber3D.getScaleVector(impulse, this._invMass));
  3907. var rotImpulse = Vector3DUtil.crossProduct(Vector3DUtil.subtract(pos, this._currState.position), impulse);
  3908. JMatrix3D.multiplyVector(this._worldInvInertia, rotImpulse);
  3909. this._currRotVelocityAux = Vector3DUtil.add(this._currRotVelocityAux, rotImpulse);
  3910. this._velChanged = true;
  3911. };
  3912. /**
  3913. * @function applyBodyWorldImpulse add impulses in the body coordinate frame
  3914. * @param {array} impulse impulse expressed as a 3D vector
  3915. * @param {array} delta impulse delta expressed as a 3D vector
  3916. * @type void
  3917. **/
  3918. RigidBody.prototype.applyBodyWorldImpulse=function(impulse, delta){
  3919. if (!this._movable) return;
  3920. this._currState.linVelocity = Vector3DUtil.add(this._currState.linVelocity, JNumber3D.getScaleVector(impulse, this._invMass));
  3921. var rotImpulse = Vector3DUtil.crossProduct(delta, impulse);
  3922. JMatrix3D.multiplyVector(this._worldInvInertia, rotImpulse);
  3923. this._currState.rotVelocity = Vector3DUtil.add(this._currState.rotVelocity, rotImpulse);
  3924. this._velChanged = true;
  3925. };
  3926. /**
  3927. * @function applyBodyWorldImpulseAux
  3928. * @param {array} impulse impulse expressed as a 3D vector
  3929. * @param {array} delta impulse delta expressed as a 3D vector
  3930. * @type void
  3931. **/
  3932. RigidBody.prototype.applyBodyWorldImpulseAux=function(impulse, delta){
  3933. if (!this._movable) return;
  3934. this._currLinVelocityAux = Vector3DUtil.add(this._currLinVelocityAux, JNumber3D.getScaleVector(impulse, this._invMass));
  3935. var rotImpulse = Vector3DUtil.crossProduct(delta, impulse);
  3936. JMatrix3D.multiplyVector(this._worldInvInertia, rotImpulse);
  3937. this._currRotVelocityAux = Vector3DUtil.add(this._currRotVelocityAux, rotImpulse);
  3938. this._velChanged = true;
  3939. };
  3940. /**
  3941. * @function addConstraint add a constraint to this body
  3942. * @param {JConstraint} constraint the constraint
  3943. * @type void
  3944. **/
  3945. RigidBody.prototype.addConstraint=function(constraint){
  3946. if (!this.findConstraint(constraint)){
  3947. this._constraints.push(constraint);
  3948. }
  3949. };
  3950. /**
  3951. * @function removeConstraint remove a constraint from this body
  3952. * @param {JConstraint} constraint the constraint
  3953. * @type void
  3954. **/
  3955. RigidBody.prototype.removeConstraint=function(constraint){
  3956. if (this.findConstraint(constraint)){
  3957. this._constraints.splice(this._constraints.indexOf(constraint), 1);
  3958. }
  3959. };
  3960. /**
  3961. * @function removeAllConstraints remove all constraints from this body
  3962. * @type void
  3963. **/
  3964. RigidBody.prototype.removeAllConstraints=function(){
  3965. this._constraints = [];
  3966. };
  3967. /**
  3968. * @function findConstraint checks if a given constraint is applied to this body
  3969. * @param {JConstraint} constraint the constraint
  3970. * @type void
  3971. **/
  3972. RigidBody.prototype.findConstraint=function(constraint){
  3973. for(var i=0, cl=this._constraints.length; i<cl; i++){
  3974. if (constraint == this._constraints[i]){
  3975. return true;
  3976. }
  3977. }
  3978. return false;
  3979. };
  3980. /**
  3981. * @function updateVelocity update the velocity/angular rotation with the force/torque
  3982. * @param {number} dt a UNIX timestamp
  3983. * @type void
  3984. **/
  3985. RigidBody.prototype.updateVelocity=function(dt){
  3986. if (!this._movable || !this._activity)
  3987. return;
  3988. this._currState.linVelocity = Vector3DUtil.add(this._currState.linVelocity, JNumber3D.getScaleVector(this._force, this._invMass * dt));
  3989. var rac = JNumber3D.getScaleVector(this._torque, dt);
  3990. JMatrix3D.multiplyVector(this._worldInvInertia, rac);
  3991. this._currState.rotVelocity = Vector3DUtil.add(this._currState.rotVelocity, rac);
  3992. };
  3993. /**
  3994. * @function updateVelocity update the position with the auxiliary velocities, and zeros them
  3995. * @param {number} dt a UNIX timestamp
  3996. * @type void
  3997. **/
  3998. RigidBody.prototype.updatePositionWithAux=function(dt){
  3999. if (!this._movable || !this._activity){
  4000. this._currLinVelocityAux = [0,0,0,0];
  4001. this._currRotVelocityAux = [0,0,0,0];
  4002. return;
  4003. }
  4004. var ga = jigLib.PhysicsSystem.getInstance().get_gravityAxis();
  4005. if (ga != -1){
  4006. var arr = this._currLinVelocityAux.slice(0);
  4007. arr[(ga + 1) % 3] *= 0.1;
  4008. arr[(ga + 2) % 3] *= 0.1;
  4009. JNumber3D.copyFromArray(this._currLinVelocityAux, arr);
  4010. }
  4011. var angMomBefore = this._currState.rotVelocity.slice(0);
  4012. JMatrix3D.multiplyVector(this._worldInertia, angMomBefore);
  4013. this._currState.position = Vector3DUtil.add(this._currState.position, JNumber3D.getScaleVector(Vector3DUtil.add(this._currState.linVelocity, this._currLinVelocityAux), dt));
  4014. var dir = Vector3DUtil.add(this._currState.rotVelocity, this._currRotVelocityAux);
  4015. var ang = Vector3DUtil.get_length(dir) * 180 / Math.PI;
  4016. if (ang > 0){
  4017. Vector3DUtil.normalize(dir);
  4018. ang *= dt;
  4019. var rot = JMatrix3D.getRotationMatrix(dir[0], dir[1], dir[2], ang);
  4020. this._currState.set_orientation(JMatrix3D.getAppendMatrix3D(this._currState.get_orientation(), rot));
  4021. this.updateInertia();
  4022. }
  4023. this._currLinVelocityAux = [0,0,0,0];
  4024. this._currRotVelocityAux = [0,0,0,0];
  4025. JMatrix3D.multiplyVector(this._worldInvInertia, angMomBefore);
  4026. this._currState.rotVelocity = angMomBefore.slice(0);
  4027. this.updateBoundingBox();
  4028. };
  4029. /**
  4030. * @function postPhysics to be implemented by inheriting classes
  4031. * @param {number} dt a UNIX timestamp
  4032. * @type void
  4033. **/
  4034. RigidBody.prototype.postPhysics=function(dt){};
  4035. /**
  4036. * @function tryToFreeze provided for the use of Physics system
  4037. * @param {number} dt a UNIX timestamp
  4038. * @type void
  4039. **/
  4040. RigidBody.prototype.tryToFreeze=function(dt){
  4041. if (!this._movable || !this._activity)
  4042. return;
  4043. if (Vector3DUtil.get_length(Vector3DUtil.subtract(this._currState.position, this._lastPositionForDeactivation)) > JConfig.posThreshold){
  4044. this._lastPositionForDeactivation = this._currState.position.slice(0);
  4045. this._inactiveTime = 0;
  4046. return;
  4047. }
  4048. var ot = JConfig.orientThreshold;
  4049. var deltaMat = JMatrix3D.getSubMatrix(this._currState.get_orientation(), this._lastOrientationForDeactivation);
  4050. var cols = JMatrix3D.getCols(deltaMat);
  4051. if (Vector3DUtil.get_length(cols[0]) > ot || Vector3DUtil.get_length(cols[1]) > ot || Vector3DUtil.get_length(cols[2]) > ot){
  4052. this._lastOrientationForDeactivation = this._currState.get_orientation().clone();
  4053. this._inactiveTime = 0;
  4054. return;
  4055. }
  4056. if (this.getShouldBeActive()){
  4057. return;
  4058. }
  4059. this._inactiveTime += dt;
  4060. if (this._inactiveTime > JConfig.deactivationTime){
  4061. this._lastPositionForDeactivation = this._currState.position.slice(0);
  4062. this._lastOrientationForDeactivation = this._currState.get_orientation().clone();
  4063. this.setInactive();
  4064. }
  4065. };
  4066. /**
  4067. * @function set_mass set the mass for this body
  4068. * @param {number} m the mass
  4069. * @type void
  4070. **/
  4071. RigidBody.prototype.set_mass=function(m){
  4072. this._mass = m;
  4073. this._invMass = 1 / m;
  4074. this.setInertia(this.getInertiaProperties(m));
  4075. };
  4076. /**
  4077. * @function setInertia set the inertia for this body
  4078. * @param {Matrix3D} matrix3D the inertia expressed as a 3D matrix
  4079. * @type void
  4080. **/
  4081. RigidBody.prototype.setInertia=function(matrix3D){
  4082. this._bodyInertia = matrix3D.clone();
  4083. this._bodyInvInertia = JMatrix3D.getInverseMatrix(this._bodyInertia.clone());
  4084. this.updateInertia();
  4085. };
  4086. /**
  4087. * @function updateInertia
  4088. * @type void
  4089. **/
  4090. RigidBody.prototype.updateInertia=function(){
  4091. this._invOrientation = JMatrix3D.getTransposeMatrix(this._currState.get_orientation());
  4092. this._worldInertia = JMatrix3D.getAppendMatrix3D(
  4093. this._invOrientation,
  4094. JMatrix3D.getAppendMatrix3D(this._currState.get_orientation(), this._bodyInertia)
  4095. );
  4096. this._worldInvInertia = JMatrix3D.getAppendMatrix3D(
  4097. this._invOrientation,
  4098. JMatrix3D.getAppendMatrix3D(this._currState.get_orientation(), this._bodyInvInertia)
  4099. );
  4100. };
  4101. /**
  4102. * @function get_movable checks if this body is movable
  4103. * @type boolean
  4104. **/
  4105. RigidBody.prototype.get_movable=function(){
  4106. return this._movable;
  4107. };
  4108. /**
  4109. * @function set_movable set whether this body is movable or not - if this is a PLANE or TERRAIN this method does nothing (movable is always false)
  4110. * @param {boolean} mov
  4111. * @type void
  4112. **/
  4113. RigidBody.prototype.set_movable=function(mov){
  4114. if (this._type == "PLANE" || this._type == "TERRAIN" || this._type == "TRIANGLEMESH")
  4115. return;
  4116. this._movable = mov;
  4117. this.isActive = this._activity = mov;
  4118. this._origMovable = mov;
  4119. };
  4120. /**
  4121. * @function internalSetImmovable for internal use
  4122. * @type void
  4123. **/
  4124. RigidBody.prototype.internalSetImmovable=function(){
  4125. if (this._type == "PLANE" || this._type == "TERRAIN" || this._type == "TRIANGLEMESH")
  4126. return;
  4127. this._origMovable = this._movable;
  4128. this._movable = false;
  4129. };
  4130. /**
  4131. * @function internalRestoreImmovable for internal use
  4132. * @type void
  4133. **/
  4134. RigidBody.prototype.internalRestoreImmovable=function(){
  4135. if (this._type == "PLANE" || this._type == "TERRAIN" || this._type == "TRIANGLEMESH")
  4136. return;
  4137. this._movable = this._origMovable;
  4138. };
  4139. /**
  4140. * @function getVelChanged checks whether velocity has changed
  4141. * @type boolean
  4142. **/
  4143. RigidBody.prototype.getVelChanged=function(){
  4144. return this._velChanged;
  4145. };
  4146. /**
  4147. * @function clearVelChanged resets the velocity changed flag
  4148. * @type void
  4149. **/
  4150. RigidBody.prototype.clearVelChanged=function(){
  4151. this._velChanged = false;
  4152. };
  4153. /**
  4154. * @function setActive makes this body active
  4155. * @param {number} activityFactor
  4156. * @type void
  4157. **/
  4158. RigidBody.prototype.setActive=function(activityFactor){
  4159. if(!activityFactor) activityFactor=1;
  4160. if (this._movable){
  4161. this.isActive = this._activity = true;
  4162. this._inactiveTime = (1 - activityFactor) * JConfig.deactivationTime;
  4163. }
  4164. };
  4165. /**
  4166. * @function setInactive makes this body inactive
  4167. * @type void
  4168. **/
  4169. RigidBody.prototype.setInactive=function(){
  4170. if (this._movable){
  4171. this.isActive = this._activity = false;
  4172. }
  4173. };
  4174. /**
  4175. * @function getVelocity gets the velocity of a point at body-relative position
  4176. * @param {array} relPos the body-relative position expressed as a 3D vector
  4177. * @type array
  4178. **/
  4179. RigidBody.prototype.getVelocity=function(relPos){
  4180. return Vector3DUtil.add(this._currState.linVelocity, Vector3DUtil.crossProduct(this._currState.rotVelocity, relPos));
  4181. };
  4182. /**
  4183. * @function getVelocityAux gets the velocity of a point at body-relative position using aux velocities
  4184. * @param {array} relPos the body-relative position expressed as a 3D vector
  4185. * @type array
  4186. **/
  4187. RigidBody.prototype.getVelocityAux=function(relPos){
  4188. return Vector3DUtil.add(this._currLinVelocityAux, Vector3DUtil.crossProduct(this._currRotVelocityAux, relPos));
  4189. };
  4190. /**
  4191. * @function getShouldBeActive indicates if the velocity is above the threshold for freezing
  4192. * @type boolean
  4193. **/
  4194. RigidBody.prototype.getShouldBeActive=function(){
  4195. return ((Vector3DUtil.get_length(this._currState.linVelocity) > JConfig.velThreshold) || (Vector3DUtil.get_length(this._currState.rotVelocity) > JConfig.angVelThreshold));
  4196. };
  4197. /**
  4198. * @function getShouldBeActiveAux indicates if the aux velocity is above the threshold for freezing
  4199. * @type boolean
  4200. **/
  4201. RigidBody.prototype.getShouldBeActiveAux=function(){
  4202. return ((Vector3DUtil.get_length(this._currLinVelocityAux) > JConfig.velThreshold) || (Vector3DUtil.get_length(this._currRotVelocityAux) > JConfig.angVelThreshold));
  4203. };
  4204. /**
  4205. * @function dampForDeactivation damp movement as the body approaches deactivation
  4206. * @type void
  4207. **/
  4208. RigidBody.prototype.dampForDeactivation=function(){
  4209. this._currState.linVelocity[0] *= this._linVelDamping[0];
  4210. this._currState.linVelocity[1] *= this._linVelDamping[1];
  4211. this._currState.linVelocity[2] *= this._linVelDamping[2];
  4212. this._currState.rotVelocity[0] *= this._rotVelDamping[0];
  4213. this._currState.rotVelocity[1] *= this._rotVelDamping[1];
  4214. this._currState.rotVelocity[2] *= this._rotVelDamping[2];
  4215. this._currLinVelocityAux[0] *= this._linVelDamping[0];
  4216. this._currLinVelocityAux[1] *= this._linVelDamping[1];
  4217. this._currLinVelocityAux[2] *= this._linVelDamping[2];
  4218. this._currRotVelocityAux[0] *= this._rotVelDamping[0];
  4219. this._currRotVelocityAux[1] *= this._rotVelDamping[1];
  4220. this._currRotVelocityAux[2] *= this._rotVelDamping[2];
  4221. var r = 0.5;
  4222. var frac = this._inactiveTime / JConfig.deactivationTime;
  4223. if (frac < r){
  4224. return;
  4225. }
  4226. var scale = 1 - ((frac - r) / (1 - r));
  4227. if (scale < 0){
  4228. scale = 0;
  4229. }else if (scale > 1){
  4230. scale = 1;
  4231. }
  4232. this._currState.linVelocity = JNumber3D.getScaleVector(this._currState.linVelocity, scale);
  4233. this._currState.rotVelocity = JNumber3D.getScaleVector(this._currState.rotVelocity, scale);
  4234. };
  4235. /**
  4236. * @function doMovementActivations provided for use of physics system.
  4237. * Activates any body in its list if it's moved more than a certain distance,
  4238. * in which case it also clears its list.
  4239. * @type void
  4240. **/
  4241. RigidBody.prototype.doMovementActivations=function(){
  4242. var numBodies = this._bodiesToBeActivatedOnMovement.length;
  4243. if (numBodies == 0 || Vector3DUtil.get_length(Vector3DUtil.subtract(this._currState.position, this._storedPositionForActivation)) < JConfig.posThreshold)
  4244. return;
  4245. for (var i = 0; i<numBodies; i++){
  4246. jigLib.PhysicsSystem.getInstance().activateObject(this._bodiesToBeActivatedOnMovement[i]);
  4247. }
  4248. this._bodiesToBeActivatedOnMovement = [];
  4249. };
  4250. /**
  4251. * @function addMovementActivation adds the other body to the list of bodies to be activated if this body
  4252. * moves more than a certain distance from either a previously stored position, or the position passed in.
  4253. * in which case it also clears its list.
  4254. *
  4255. * @param {array} pos position expressed as a 3D vector
  4256. * @param {RigidBody} otherBody the other body
  4257. * @type void
  4258. **/
  4259. RigidBody.prototype.addMovementActivation=function(pos, otherBody){
  4260. var len = this._bodiesToBeActivatedOnMovement.length;
  4261. for (var i = 0; i < len; i++){
  4262. if (this._bodiesToBeActivatedOnMovement[i] == otherBody){
  4263. return;
  4264. }
  4265. }
  4266. if (this._bodiesToBeActivatedOnMovement.length == 0){
  4267. this._storedPositionForActivation = pos;
  4268. }
  4269. this._bodiesToBeActivatedOnMovement.push(otherBody);
  4270. };
  4271. /**
  4272. * @function setConstraintsAndCollisionsUnsatisfied marks all constraints/collisions as being unsatisfied
  4273. *
  4274. * @type void
  4275. **/
  4276. RigidBody.prototype.setConstraintsAndCollisionsUnsatisfied=function(){
  4277. for(var i=0, cl=this._constraints.length; i<cl; i++){
  4278. this._constraints[i].set_satisfied(false);
  4279. }
  4280. for(var i=0, cll=this.collisions.length; i<cll; i++){
  4281. this.collisions[i].satisfied = false;
  4282. }
  4283. };
  4284. /**
  4285. * @function segmentIntersect to be implemented by inheriting classes
  4286. * @param {object} out
  4287. * @param {JSegment} seg
  4288. * @param {PhysicsState} state
  4289. * @type boolean
  4290. **/
  4291. RigidBody.prototype.segmentIntersect=function(out, seg, state){
  4292. return false;
  4293. };
  4294. /**
  4295. * @function getInertiaProperties to be implemented by inheriting classes
  4296. * @param {number} m
  4297. * @type Matrix3D
  4298. **/
  4299. RigidBody.prototype.getInertiaProperties=function(m){
  4300. return new Matrix3D();
  4301. };
  4302. /**
  4303. * @function updateBoundingBox to be implemented by inheriting classes
  4304. * @type void
  4305. **/
  4306. RigidBody.prototype.updateBoundingBox=function(){
  4307. };
  4308. /**
  4309. * @function hitTestObject3D
  4310. * @param {RigidBody} obj3D
  4311. * @type boolean
  4312. **/
  4313. RigidBody.prototype.hitTestObject3D=function(obj3D){
  4314. var num1 = Vector3DUtil.get_length(Vector3DUtil.subtract(this._currState.position, obj3D.get_currentState().position));
  4315. var num2 = this._boundingSphere + obj3D.get_boundingSphere();
  4316. if (num1 <= num2){
  4317. return true;
  4318. }
  4319. return false;
  4320. };
  4321. /**
  4322. * @function findNonCollidablesBody
  4323. * @param {RigidBody} body
  4324. * @type boolean
  4325. **/
  4326. RigidBody.prototype.findNonCollidablesBody=function(body){
  4327. for(var i=0, ncl=this._nonCollidables.length; i<ncl; i++){
  4328. if (body == this._nonCollidables[i])
  4329. return true;
  4330. }
  4331. return false;
  4332. };
  4333. /**
  4334. * @function disableCollisions
  4335. * @param {RigidBody} body
  4336. * @type void
  4337. **/
  4338. RigidBody.prototype.disableCollisions=function(body){
  4339. if (!this.findNonCollidablesBody(body)){
  4340. this._nonCollidables.push(body);
  4341. }
  4342. };
  4343. /**
  4344. * @function enableCollisions
  4345. * @param {RigidBody} body
  4346. * @type void
  4347. **/
  4348. RigidBody.prototype.enableCollisions=function(body){
  4349. if (this.findNonCollidablesBody(body)){
  4350. this._nonCollidables.splice(this._nonCollidables.indexOf(body), 1);
  4351. }
  4352. };
  4353. /**
  4354. * @function copyCurrentStateToOld copies the current position etc to old - normally called only by physicsSystem.
  4355. * @type void
  4356. **/
  4357. RigidBody.prototype.copyCurrentStateToOld=function(){
  4358. this._oldState.position = this._currState.position.slice(0);
  4359. this._oldState.set_orientation(this._currState.get_orientation().clone());
  4360. this._oldState.linVelocity = this._currState.linVelocity.slice(0);
  4361. this._oldState.rotVelocity = this._currState.rotVelocity.slice(0);
  4362. };
  4363. /**
  4364. * @function storeState copy the current state into the stored state
  4365. * @type void
  4366. **/
  4367. RigidBody.prototype.storeState=function(){
  4368. this._storeState.position = this._currState.position.slice(0);
  4369. this._storeState.set_orientation(this._currState.get_orientation().clone());
  4370. this._storeState.linVelocity = this._currState.linVelocity.slice(0);
  4371. this._storeState.rotVelocity = this._currState.rotVelocity.slice(0);
  4372. };
  4373. /**
  4374. * @function restoreState restore from the stored state into the current state.
  4375. * @type void
  4376. **/
  4377. RigidBody.prototype.restoreState=function(){
  4378. this._currState.position = this._storeState.position.slice(0);
  4379. this._currState.set_orientation(this._storeState.get_orientation().clone());
  4380. this._currState.linVelocity = this._storeState.linVelocity.slice(0);
  4381. this._currState.rotVelocity = this._storeState.rotVelocity.slice(0);
  4382. };
  4383. /**
  4384. * @function get_currentState get the "working" state
  4385. * @type PhysicsState
  4386. **/
  4387. RigidBody.prototype.get_currentState=function(){
  4388. return this._currState;
  4389. };
  4390. /**
  4391. * @function get_oldState the previous state - copied explicitly using copyCurrentStateToOld
  4392. * @type PhysicsState
  4393. **/
  4394. RigidBody.prototype.get_oldState=function(){
  4395. return this._oldState;
  4396. };
  4397. /**
  4398. * @function get_id the unique ID for this body
  4399. * @type number
  4400. **/
  4401. RigidBody.prototype.get_id=function(){
  4402. return this._id;
  4403. };
  4404. /**
  4405. * @function get_id the body type (e.g. BOX, PLANE, SPHERE etc.)
  4406. * @type string
  4407. **/
  4408. RigidBody.prototype.get_type=function(){
  4409. return this._type;
  4410. };
  4411. /**
  4412. * @function get_skin the skin
  4413. * @type ISkin3D
  4414. **/
  4415. RigidBody.prototype.get_skin=function(){
  4416. return this._skin;
  4417. };
  4418. /**
  4419. * @function get_boundingSphere the bounding sphere radius
  4420. * @type number
  4421. **/
  4422. RigidBody.prototype.get_boundingSphere=function(){
  4423. return this._boundingSphere;
  4424. };
  4425. /**
  4426. * @function get_boundingSphere the bounding box dimensions
  4427. * @type JAABox
  4428. **/
  4429. RigidBody.prototype.get_boundingBox=function(){
  4430. return this._boundingBox;
  4431. };
  4432. /**
  4433. * @function get_force current force in world frame expressed as a 3D vector
  4434. * @type array
  4435. **/
  4436. RigidBody.prototype.get_force=function(){
  4437. return this._force;
  4438. };
  4439. /**
  4440. * @function get_mass the mass of this body
  4441. * @type number
  4442. **/
  4443. RigidBody.prototype.get_mass=function(){
  4444. return this._mass;
  4445. };
  4446. /**
  4447. * @function get_invMass the inverse mass of this body
  4448. * @type number
  4449. **/
  4450. RigidBody.prototype.get_invMass=function(){
  4451. return this._invMass;
  4452. };
  4453. /**
  4454. * @function get_worldInertia the inertia tensor in world space
  4455. * @type Matrix3D
  4456. **/
  4457. RigidBody.prototype.get_worldInertia=function(){
  4458. return this._worldInertia;
  4459. };
  4460. /**
  4461. * @function get_worldInvInertia the inverse inertia tensor in world space
  4462. * @type Matrix3D
  4463. **/
  4464. RigidBody.prototype.get_worldInvInertia=function(){
  4465. return this._worldInvInertia;
  4466. };
  4467. /**
  4468. * @function get_nonCollidables
  4469. * @returns a collection of RigidBody objects
  4470. * @type array
  4471. **/
  4472. RigidBody.prototype.get_nonCollidables=function(){
  4473. return this._nonCollidables;
  4474. };
  4475. /**
  4476. * @function get_doShockProcessing returns whether shock processing is being applied to this body
  4477. * @type boolean
  4478. **/
  4479. RigidBody.prototype.get_doShockProcessing=function(){
  4480. return this._doShockProcessing;
  4481. };
  4482. /**
  4483. * @function set_doShockProcessing sets whether shock processing should be applied to this body
  4484. * @param {boolean} doShock
  4485. * @type void
  4486. **/
  4487. RigidBody.prototype.set_doShockProcessing=function(doShock){
  4488. this._doShockProcessing = doShock;
  4489. };
  4490. /**
  4491. * @function set_linVelocityDamping each dimension will be limited to the range 0-1
  4492. * @param {array} vel a 3D vector
  4493. * @type void
  4494. **/
  4495. RigidBody.prototype.set_linVelocityDamping=function(vel){
  4496. this._linVelDamping[0] = JNumber3D.getLimiteNumber(vel[0], 0, 1);
  4497. this._linVelDamping[1] = JNumber3D.getLimiteNumber(vel[1], 0, 1);
  4498. this._linVelDamping[2] = JNumber3D.getLimiteNumber(vel[2], 0, 1);
  4499. };
  4500. /**
  4501. * @function get_linVelocityDamping
  4502. * @type array
  4503. **/
  4504. RigidBody.prototype.get_linVelocityDamping=function(){
  4505. return this._linVelDamping;
  4506. };
  4507. /**
  4508. * @function set_rotVelocityDamping each dimension will be limited to the range 0-1
  4509. * @param {array} vel a 3D vector
  4510. * @type void
  4511. **/
  4512. RigidBody.prototype.set_rotVelocityDamping=function(vel){
  4513. this._rotVelDamping[0] = JNumber3D.getLimiteNumber(vel[0], 0, 1);
  4514. this._rotVelDamping[1] = JNumber3D.getLimiteNumber(vel[1], 0, 1);
  4515. this._rotVelDamping[2] = JNumber3D.getLimiteNumber(vel[2], 0, 1);
  4516. };
  4517. /**
  4518. * @function get_rotVelocityDamping
  4519. * @type array
  4520. **/
  4521. RigidBody.prototype.get_rotVelocityDamping=function(){
  4522. return this._rotVelDamping;
  4523. };
  4524. /**
  4525. * @function set_maxLinVelocities limit the max value of body's line velocity
  4526. * @param {number} vel
  4527. * @type void
  4528. **/
  4529. RigidBody.prototype.set_maxLinVelocities=function(vel){
  4530. this._maxLinVelocities = JNumber3D.getLimiteNumber(Math.abs(vel), 0, 500);
  4531. };
  4532. /**
  4533. * @function get_maxLinVelocities
  4534. * @type number
  4535. **/
  4536. RigidBody.prototype.get_maxLinVelocities=function(){
  4537. return this._maxLinVelocities;
  4538. };
  4539. /**
  4540. * @function set_maxRotVelocities limit the max value of body's angle velocity
  4541. * @param {number} vel
  4542. * @type void
  4543. **/
  4544. RigidBody.prototype.set_maxRotVelocities=function(vel){
  4545. this._maxRotVelocities = JNumber3D.getLimiteNumber(Math.abs(vel), JNumber3D.NUM_TINY, 50);
  4546. };
  4547. /**
  4548. * @function get_maxRotVelocities
  4549. * @type number
  4550. **/
  4551. RigidBody.prototype.get_maxRotVelocities=function(){
  4552. return this._maxRotVelocities;
  4553. };
  4554. /**
  4555. * @function limitVel
  4556. * @type void
  4557. **/
  4558. RigidBody.prototype.limitVel=function(){
  4559. this._currState.linVelocity[0] = JNumber3D.getLimiteNumber(this._currState.linVelocity[0], -this._maxLinVelocities, this._maxLinVelocities);
  4560. this._currState.linVelocity[1] = JNumber3D.getLimiteNumber(this._currState.linVelocity[1], -this._maxLinVelocities, this._maxLinVelocities);
  4561. this._currState.linVelocity[2] = JNumber3D.getLimiteNumber(this._currState.linVelocity[2], -this._maxLinVelocities, this._maxLinVelocities);
  4562. };
  4563. /**
  4564. * @function limitAngVel
  4565. * @type void
  4566. **/
  4567. RigidBody.prototype.limitAngVel=function(){
  4568. var fx = Math.abs(this._currState.rotVelocity[0]) / this._maxRotVelocities;
  4569. var fy = Math.abs(this._currState.rotVelocity[1]) / this._maxRotVelocities;
  4570. var fz = Math.abs(this._currState.rotVelocity[2]) / this._maxRotVelocities;
  4571. var f = Math.max(fx, fy, fz);
  4572. if (f > 1)
  4573. this._currState.rotVelocity = JNumber3D.getDivideVector(this._currState.rotVelocity, f);
  4574. };
  4575. /**
  4576. * @function getTransform gets the transform matrix for the skin
  4577. * @type Matrix3D
  4578. **/
  4579. RigidBody.prototype.getTransform=function(){
  4580. if (this._skin != null){
  4581. return this._skin.get_transform();
  4582. }else{
  4583. return null;
  4584. }
  4585. };
  4586. /**
  4587. * @function updateObject3D updates the skin
  4588. * @type void
  4589. **/
  4590. RigidBody.prototype.updateObject3D=function(){
  4591. if (this._skin != null)
  4592. this._skin.set_transform(JMatrix3D.getAppendMatrix3D(this._currState.get_orientation(), JMatrix3D.getTranslationMatrix(this._currState.position[0], this._currState.position[1], this._currState.position[2])));
  4593. };
  4594. /**
  4595. * @function get_material
  4596. * @type MaterialProperties
  4597. **/
  4598. RigidBody.prototype.get_material=function(){
  4599. return this._material;
  4600. };
  4601. /**
  4602. * @function get_restitution get the coefficient of elasticity
  4603. * @type number
  4604. **/
  4605. RigidBody.prototype.get_restitution=function(){
  4606. return this._material.get_restitution();
  4607. };
  4608. /**
  4609. * @function set_restitution set the coefficient of elasticity
  4610. * @param {number} restitution
  4611. * @type void
  4612. **/
  4613. RigidBody.prototype.set_restitution=function(restitution){
  4614. this._material.set_restitution(JNumber3D.getLimiteNumber(restitution, 0, 1));
  4615. };
  4616. /**
  4617. * @function get_friction get the coefficient of friction
  4618. * @type number
  4619. **/
  4620. RigidBody.prototype.get_friction=function(){
  4621. return this._material.get_friction();
  4622. };
  4623. /**
  4624. * @function set_friction set the coefficient of friction
  4625. * @param {number} restitution
  4626. * @type void
  4627. **/
  4628. RigidBody.prototype.set_friction=function(friction){
  4629. this._material.set_friction(JNumber3D.getLimiteNumber(friction, 0, 1));
  4630. };
  4631. jigLib.RigidBody=RigidBody;
  4632. })(jigLib);/*
  4633. Copyright (c) 2007 Danny Chapman
  4634. http://www.rowlhouse.co.uk
  4635. This software is provided 'as-is', without any express or implied
  4636. warranty. In no event will the authors be held liable for any damages
  4637. arising from the use of this software.
  4638. Permission is granted to anyone to use this software for any purpose,
  4639. including commercial applications, and to alter it and redistribute it
  4640. freely, subject to the following restrictions:
  4641. 1. The origin of this software must not be misrepresented; you must not
  4642. claim that you wrote the original software. If you use this software
  4643. in a product, an acknowledgment in the product documentation would be
  4644. appreciated but is not required.
  4645. 2. Altered source versions must be plainly marked as such, and must not be
  4646. misrepresented as being the original software.
  4647. 3. This notice may not be removed or altered from any source
  4648. distribution.
  4649. */
  4650. (function(jigLib){
  4651. var Vector3DUtil=jigLib.Vector3DUtil;
  4652. var JMatrix3D=jigLib.JMatrix3D;
  4653. var JNumber3D=jigLib.JNumber3D;
  4654. var JConstraintMaxDistance=jigLib.JConstraintMaxDistance;
  4655. var JConstraintPoint=jigLib.JConstraintPoint;
  4656. /**
  4657. * @author Muzer(muzerly@gmail.com)
  4658. *
  4659. * @name HingeJoint
  4660. * @class HingeJoint hinge connector for two rigid bodies
  4661. * @extends PhysicsController
  4662. * @requires Vector3DUtil
  4663. * @requires JMatrix3D
  4664. * @requires JNumber3D
  4665. * @requires JConstraintMaxDistance
  4666. * @requires JConstraintPoint
  4667. * @constant {number} MAX_HINGE_ANGLE_LIMIT
  4668. * @property {array} _hingeAxis
  4669. * @property {array} _hingePosRel0
  4670. * @property {RigidBody} body0 the first rigid body
  4671. * @property {RigidBody} body1 the second rigid body
  4672. * @property {boolean} _usingLimit
  4673. * @property {boolean} _hingeEnabled
  4674. * @property {boolean} _broken
  4675. * @property {number} _damping
  4676. * @property {number} _extraTorque
  4677. * @property {array} sidePointConstraints used to store 2 JConstraintMaxDistance instances
  4678. * @property {JConstraintPoint} midPointConstraint
  4679. * @property {JConstraintMaxDistance} maxDistanceConstraint
  4680. * @property {array} r a 3D vector
  4681. * @constructor
  4682. * @param {RigidBody} _body0 the first body of the constrained pair
  4683. * @param {RigidBody} _body1 the second body of the constrained pair
  4684. * @param {array} _hingeAxis
  4685. * @param {array} _hingePosRel0
  4686. * @param {number} hingeHalfWidth
  4687. * @param {number} hingeFwdAngle
  4688. * @param {number} hingeBckAngle
  4689. * @param {number} sidewaysSlack
  4690. * @param {number} damping
  4691. **/
  4692. var HingeJoint=function(body0, body1, hingeAxis, hingePosRel0, hingeHalfWidth, hingeFwdAngle, hingeBckAngle, sidewaysSlack, damping){
  4693. this._body0 = body0;
  4694. this._body1 = body1;
  4695. this._hingeAxis = hingeAxis.slice(0);
  4696. this._hingePosRel0 = hingePosRel0.slice(0);
  4697. this._usingLimit = false;
  4698. this._hingeEnabled = false;
  4699. this._broken = false;
  4700. this._damping = damping;
  4701. this._extraTorque = 0;
  4702. Vector3DUtil.normalize(this._hingeAxis);
  4703. var _hingePosRel1 = Vector3DUtil.add(this._body0.get_currentState().position, Vector3DUtil.subtract(this._hingePosRel0, this._body1.get_currentState().position));
  4704. var relPos0a = Vector3DUtil.add(this._hingePosRel0, JNumber3D.getScaleVector(this._hingeAxis, hingeHalfWidth));
  4705. var relPos0b = Vector3DUtil.subtract(this._hingePosRel0, JNumber3D.getScaleVector(this._hingeAxis, hingeHalfWidth));
  4706. var relPos1a = Vector3DUtil.add(_hingePosRel1, JNumber3D.getScaleVector(this._hingeAxis, hingeHalfWidth));
  4707. var relPos1b = Vector3DUtil.subtract(_hingePosRel1, JNumber3D.getScaleVector(this._hingeAxis, hingeHalfWidth));
  4708. var timescale = 1 / 20;
  4709. var allowedDistanceMid = 0.005;
  4710. var allowedDistanceSide = sidewaysSlack * hingeHalfWidth;
  4711. this.sidePointConstraints = [];
  4712. this.sidePointConstraints[0] = new JConstraintMaxDistance(this._body0, relPos0a, this._body1, relPos1a, allowedDistanceSide);
  4713. this.sidePointConstraints[1] = new JConstraintMaxDistance(this._body0, relPos0b, this._body1, relPos1b, allowedDistanceSide);
  4714. this.midPointConstraint = new JConstraintPoint(this._body0, this._hingePosRel0, this._body1, _hingePosRel1, allowedDistanceMid, timescale);
  4715. if (hingeFwdAngle <= this.MAX_HINGE_ANGLE_LIMIT){
  4716. var perpDir = Vector3DUtil.Y_AXIS;
  4717. if (Vector3DUtil.dotProduct(perpDir, this._hingeAxis) > 0.1){
  4718. perpDir[0] = 1;
  4719. perpDir[1] = 0;
  4720. perpDir[2] = 0;
  4721. }
  4722. var sideAxis = Vector3DUtil.crossProduct(this._hingeAxis, perpDir);
  4723. perpDir = Vector3DUtil.crossProduct(sideAxis, this._hingeAxis);
  4724. Vector3DUtil.normalize(perpDir);
  4725. var len = 10 * hingeHalfWidth;
  4726. var hingeRelAnchorPos0 = JNumber3D.getScaleVector(perpDir, len);
  4727. var angleToMiddle = 0.5 * (hingeFwdAngle - hingeBckAngle);
  4728. var hingeRelAnchorPos1 = hingeRelAnchorPos0.slice(0);
  4729. JMatrix3D.multiplyVector(JMatrix3D.getRotationMatrix(this._hingeAxis[0], this._hingeAxis[1], this._hingeAxis[2], -angleToMiddle), hingeRelAnchorPos1);
  4730. var hingeHalfAngle = 0.5 * (hingeFwdAngle + hingeBckAngle);
  4731. var allowedDistance = len * 2 * Math.sin(0.5 * hingeHalfAngle * Math.PI / 180);
  4732. var hingePos = Vector3DUtil.add(this._body1.get_currentState().position, this._hingePosRel0);
  4733. var relPos0c = Vector3DUtil.add(hingePos, Vector3DUtil.subtract(hingeRelAnchorPos0, this._body0.get_currentState().position));
  4734. var relPos1c = Vector3DUtil.add(hingePos, Vector3DUtil.subtract(hingeRelAnchorPos1, this._body1.get_currentState().position));
  4735. this.maxDistanceConstraint = new JConstraintMaxDistance(this._body0, relPos0c, this._body1, relPos1c, allowedDistance);
  4736. this._usingLimit = true;
  4737. }
  4738. if (this._damping <= 0){
  4739. this._damping = -1;
  4740. }else{
  4741. this._damping = JNumber3D.getLimiteNumber(this._damping, 0, 1);
  4742. }
  4743. this.enableHinge();
  4744. };
  4745. jigLib.extend(HingeJoint, jigLib.PhysicsController);
  4746. HingeJoint.prototype.MAX_HINGE_ANGLE_LIMIT = 150;
  4747. HingeJoint.prototype._hingeAxis = null;
  4748. HingeJoint.prototype._hingePosRel0 = null;
  4749. HingeJoint.prototype._body0 = null;
  4750. HingeJoint.prototype._body1 = null;
  4751. HingeJoint.prototype._usingLimit = null;
  4752. HingeJoint.prototype._hingeEnabled = null;
  4753. HingeJoint.prototype._broken = null;
  4754. HingeJoint.prototype._damping = null;
  4755. HingeJoint.prototype._extraTorque = null;
  4756. HingeJoint.prototype.sidePointConstraints = null;
  4757. HingeJoint.prototype.midPointConstraint = null;
  4758. HingeJoint.prototype.maxDistanceConstraint = null;
  4759. /**
  4760. * @function enableHinge enable the joint
  4761. * @type void
  4762. **/
  4763. HingeJoint.prototype.enableHinge=function(){
  4764. if (this._hingeEnabled) return;
  4765. this.midPointConstraint.enableConstraint();
  4766. this.sidePointConstraints[0].enableConstraint();
  4767. this.sidePointConstraints[1].enableConstraint();
  4768. if (this._usingLimit && !this._broken)
  4769. this.maxDistanceConstraint.enableConstraint();
  4770. this.enableController();
  4771. this._hingeEnabled = true;
  4772. };
  4773. /**
  4774. * @function disableHinge disable the joint
  4775. * @type void
  4776. **/
  4777. HingeJoint.prototype.disableHinge=function(){
  4778. if (!this._hingeEnabled) return;
  4779. this.midPointConstraint.disableConstraint();
  4780. this.sidePointConstraints[0].disableConstraint();
  4781. this.sidePointConstraints[1].disableConstraint();
  4782. if (this._usingLimit && !this._broken)
  4783. this.maxDistanceConstraint.disableConstraint();
  4784. this.disableController();
  4785. this._hingeEnabled = false;
  4786. };
  4787. /**
  4788. * @function breakHinge break the joint
  4789. * @type void
  4790. **/
  4791. HingeJoint.prototype.breakHinge=function(){
  4792. if (this._broken) return;
  4793. if (this._usingLimit)
  4794. this.maxDistanceConstraint.disableConstraint();
  4795. this._broken = true;
  4796. };
  4797. /**
  4798. * @function mendHinge repair the joint
  4799. * @type void
  4800. **/
  4801. HingeJoint.prototype.mendHinge=function(){
  4802. if (!this._broken)
  4803. return;
  4804. if (this._usingLimit)
  4805. this.maxDistanceConstraint.enableConstraint();
  4806. this._broken = false;
  4807. };
  4808. /**
  4809. * @function setExtraTorque setter for _extraTorque
  4810. * @param {number} torque
  4811. * @type void
  4812. **/
  4813. HingeJoint.prototype.setExtraTorque=function(torque){
  4814. this._extraTorque = torque;
  4815. };
  4816. /**
  4817. * @function getExtraTorque getter for _extraTorque
  4818. * @type number
  4819. **/
  4820. HingeJoint.prototype.getHingeEnabled=function(){
  4821. return this._hingeEnabled;
  4822. };
  4823. /**
  4824. * @function isBroken getter for _broken
  4825. * @type boolean
  4826. **/
  4827. HingeJoint.prototype.isBroken=function(){
  4828. return this._broken;
  4829. };
  4830. /**
  4831. * @function getHingePosRel0 getter for _hingePosRel0
  4832. * @type array
  4833. **/
  4834. HingeJoint.prototype.getHingePosRel0=function(){
  4835. return this._hingePosRel0;
  4836. };
  4837. /**
  4838. * @function updateController updates this physics controller
  4839. * @see PhysicsSystem.updateController
  4840. * @param {number} dt a UNIX timestamp
  4841. * @type void
  4842. **/
  4843. HingeJoint.prototype.updateController=function(dt){
  4844. if (this._damping > 0){
  4845. var hingeAxis = Vector3DUtil.subtract(this._body1.get_currentState().rotVelocity, this._body0.get_currentState().rotVelocity);
  4846. Vector3DUtil.normalize(hingeAxis);
  4847. var angRot1 = Vector3DUtil.dotProduct(this._body0.get_currentState().rotVelocity, hingeAxis);
  4848. var angRot2 = Vector3DUtil.dotProduct(this._body1.get_currentState().rotVelocity, hingeAxis);
  4849. var avAngRot = 0.5 * (angRot1 + angRot2);
  4850. var frac = 1 - this._damping;
  4851. var newAngRot1= avAngRot + (angRot1 - avAngRot) * frac;
  4852. var newAngRot2= avAngRot + (angRot2 - avAngRot) * frac;
  4853. var newAngVel1 = Vector3DUtil.add(this._body0.get_currentState().rotVelocity, JNumber3D.getScaleVector(hingeAxis, newAngRot1 - angRot1));
  4854. var newAngVel2 = Vector3DUtil.add(this._body1.get_currentState().rotVelocity, JNumber3D.getScaleVector(hingeAxis, newAngRot2 - angRot2));
  4855. this._body0.setAngVel(newAngVel1);
  4856. this._body1.setAngVel(newAngVel2);
  4857. }
  4858. if (this._extraTorque != 0){
  4859. var torque1 = this._hingeAxis.slice(0);
  4860. JMatrix3D.multiplyVector(this._body0.get_currentState().get_orientation(), torque1);
  4861. torque1 = JNumber3D.getScaleVector(torque1, this._extraTorque);
  4862. this._body0.addWorldTorque(torque1);
  4863. this._body1.addWorldTorque(JNumber3D.getScaleVector(torque1, -1));
  4864. }
  4865. };
  4866. jigLib.HingeJoint=HingeJoint;
  4867. })(jigLib);
  4868. (function(jigLib){
  4869. /**
  4870. * @author Jim Sangwine
  4871. *
  4872. * @name JEffect
  4873. * @class JEffect the base class for effects
  4874. * @property {boolean} _effectEnabled changing this boolean registers and de-registers the effect with the physics system
  4875. * @constructor
  4876. **/
  4877. var JEffect=function(){
  4878. this._effectEnabled = true;
  4879. };
  4880. JEffect.prototype._effectEnabled=false;
  4881. JEffect.prototype.__defineGetter__('enabled',
  4882. function() { return this._effectEnabled; });
  4883. JEffect.prototype.__defineSetter__('enabled',
  4884. function(bool) {
  4885. if (bool == this._effectEnabled) return;
  4886. this._effectEnabled = bool;
  4887. if (bool) jigLib.PhysicsSystem.getInstance().addEffect(this);
  4888. else jigLib.PhysicsSystem.getInstance().removeEffect(this);
  4889. });
  4890. /**
  4891. * @function Apply this should be implemented by the effect to apply force to bodies in the physics system as appropriate.
  4892. * @see PhysicsSystem.handleAllEffects
  4893. *
  4894. * @type void
  4895. */
  4896. JEffect.prototype.Apply=function(){
  4897. return;
  4898. };
  4899. jigLib.JEffect=JEffect;
  4900. })(jigLib);(function(jigLib){
  4901. var Vector3DUtil=jigLib.Vector3DUtil;
  4902. /**
  4903. * @author Jim Sangwine
  4904. *
  4905. * @name Wind
  4906. * @class Wind a wind effect
  4907. * This effect has global influence - All objects that are movable in the scene will be affected, apart from those added to the exclusions array.
  4908. * This effect will be applied continuously as long as it is enabled
  4909. *
  4910. * @extends JEffect
  4911. * @requires Vector3DUtil
  4912. * @property {array} direction a 3D vector defining the force of the effect in each axis
  4913. * @property {array} exclusions optional - a list of bodies to be excluded from the effect
  4914. * @constructor
  4915. * @param {array} _direction a 3D vector defining the force of the effect in each axis
  4916. * @param {array} _exclusions optional - a list of bodies to be excluded from the effect
  4917. **/
  4918. var Wind=function(_direction, _exclusions) {
  4919. this.Super();
  4920. this.direction=_direction;
  4921. if (_exclusions) this.exclusions=_exclusions;
  4922. };
  4923. jigLib.extend(Wind,jigLib.JEffect);
  4924. Wind.prototype.direction = null;
  4925. Wind.prototype.exclusions = [];
  4926. /**
  4927. * @function isExcluded checks if a given body is in the exclusions list
  4928. * @param {RigidBody} body the body to check for
  4929. * @type boolean
  4930. */
  4931. Wind.prototype.isExcluded = function(body) {
  4932. var i=this.exclusions.length;
  4933. while (i--) { if (this.exclusions[i] == body) return true; }
  4934. return false;
  4935. };
  4936. /**
  4937. * @function Apply applies the effect to the relevant bodies
  4938. * @see JEffect.Apply
  4939. * @type void
  4940. **/
  4941. Wind.prototype.Apply = function() {
  4942. var system=jigLib.PhysicsSystem.getInstance();
  4943. var bodies=system.get_bodies();
  4944. var i=bodies.length;
  4945. var curBody;
  4946. this._affectedBodies=[];
  4947. while(i--) {
  4948. curBody=bodies[i];
  4949. if (!curBody.get_movable() || this.isExcluded(curBody)) continue;
  4950. system.activateObject(curBody);
  4951. curBody.applyWorldImpulse(this.direction, curBody.get_position());
  4952. }
  4953. };
  4954. jigLib.Wind=Wind;
  4955. })(jigLib);(function(jigLib){
  4956. var Vector3DUtil=jigLib.Vector3DUtil;
  4957. var JMatrix3D=jigLib.JMatrix3D;
  4958. var JNumber3D=jigLib.JNumber3D;
  4959. var RigidBody=jigLib.RigidBody;
  4960. var EdgeData=jigLib.EdgeData;
  4961. var SpanData=jigLib.SpanData;
  4962. /**
  4963. * @author Muzer(muzerly@gmail.com)
  4964. *
  4965. * @name JBox
  4966. * @class JBox a box rigid body
  4967. * @extends RigidBody
  4968. * @requires Vector3DUtil
  4969. * @requires JMatrix3D
  4970. * @requires JNumber3D
  4971. * @requires EdgeData
  4972. * @requires SpanData
  4973. * @property {array} _sideLengths the side lengths of this JBox expressed as a 3D vector
  4974. * @property {array} _points a collection of 3D vectors representing the points (vertices) of this JBox
  4975. * @property {array} _edges a collection of EdgeData objects representing the edges of this JBox
  4976. * @property {array} _faces a collection of 3D vectors representing the faces of this JBox
  4977. * @constructor
  4978. * @param {ISkin3D} skin
  4979. * @param {number} width
  4980. * @param {number} depth
  4981. * @param {number} height
  4982. **/
  4983. var JBox=function(skin, width, depth, height){
  4984. // calling "this.Super" causes recursion in inheritance chains longer than 1
  4985. //this.Super(skin);
  4986. jigLib.RigidBody.call(this);
  4987. this._edges=[new EdgeData( 0, 1 ), new EdgeData( 3, 1 ), new EdgeData( 2, 3 ),
  4988. new EdgeData( 2, 0 ), new EdgeData( 4, 5 ), new EdgeData( 5, 7 ),
  4989. new EdgeData( 6, 7 ), new EdgeData( 4, 6 ), new EdgeData( 7, 1 ),
  4990. new EdgeData( 5, 3 ), new EdgeData( 4, 2 ), new EdgeData( 6, 0 )];
  4991. this._faces=[[6, 7, 1, 0], [5, 4, 2, 3],
  4992. [3, 1, 7, 5], [4, 6, 0, 2],
  4993. [1, 3, 2, 0], [7, 6, 4, 5]];
  4994. this._type = "BOX";
  4995. this._skin = skin;
  4996. this._sideLengths = Vector3DUtil.create(width, height, depth, 0);
  4997. this._boundingSphere = 0.5 * Vector3DUtil.get_length(this._sideLengths);
  4998. this.initPoints();
  4999. this.set_mass(1);
  5000. this.updateBoundingBox();
  5001. };
  5002. jigLib.extend(JBox,jigLib.RigidBody);
  5003. JBox.prototype._sideLengths=null;
  5004. JBox.prototype._points=null;
  5005. JBox.prototype._edges=null;
  5006. JBox.prototype._faces=null;
  5007. /**
  5008. * @function initPoints determines the point (vertex) locations for this JBox
  5009. * @type void
  5010. **/
  5011. JBox.prototype.initPoints=function(){
  5012. var halfSide = this.getHalfSideLengths();
  5013. this._points = [];
  5014. this._points[0] = Vector3DUtil.create(halfSide[0], -halfSide[1], halfSide[2], 0);
  5015. this._points[1] = Vector3DUtil.create(halfSide[0], halfSide[1], halfSide[2], 0);
  5016. this._points[2] = Vector3DUtil.create(-halfSide[0], -halfSide[1], halfSide[2], 0);
  5017. this._points[3] = Vector3DUtil.create(-halfSide[0], halfSide[1], halfSide[2], 0);
  5018. this._points[4] = Vector3DUtil.create(-halfSide[0], -halfSide[1], -halfSide[2], 0);
  5019. this._points[5] = Vector3DUtil.create(-halfSide[0], halfSide[1], -halfSide[2], 0);
  5020. this._points[6] = Vector3DUtil.create(halfSide[0], -halfSide[1], -halfSide[2], 0);
  5021. this._points[7] = Vector3DUtil.create(halfSide[0], halfSide[1], -halfSide[2], 0);
  5022. };
  5023. /**
  5024. * @function set_sideLengths sets the side lengths for this JBox
  5025. * @param {array} size 3D vector specifying the side lengths i.e. [width, height, depth, 0]
  5026. * @type void
  5027. **/
  5028. JBox.prototype.set_sideLengths=function(size){
  5029. this._sideLengths = size.slice(0);
  5030. this._boundingSphere = 0.5 * Vector3DUtil.get_length(this._sideLengths);
  5031. this.initPoints();
  5032. this.setInertia(this.getInertiaProperties(this.get_mass()));
  5033. this.setActive();
  5034. this.updateBoundingBox();
  5035. };
  5036. /**
  5037. * @function get_sideLengths returns the side lengths for this JBox as a 3D vector
  5038. * @type array
  5039. **/
  5040. JBox.prototype.get_sideLengths=function(){
  5041. return this._sideLengths;
  5042. };
  5043. /**
  5044. * @function get_edges returns an array of EdgeData objects representing the edges of this JBox
  5045. * @type array
  5046. **/
  5047. JBox.prototype.get_edges=function(){
  5048. return this._edges;
  5049. };
  5050. /**
  5051. * @function getVolume returns the volume of this JBox
  5052. * @type number
  5053. **/
  5054. JBox.prototype.getVolume=function(){
  5055. return (this._sideLengths[0] * this._sideLengths[1] * this._sideLengths[2]);
  5056. };
  5057. /**
  5058. * @function getSurfaceArea returns the surface area of this JBox
  5059. * @type number
  5060. **/
  5061. JBox.prototype.getSurfaceArea=function(){
  5062. return 2 * (this._sideLengths[0] * this._sideLengths[1] + this._sideLengths[0] * this._sideLengths[2] + this._sideLengths[1] * this._sideLengths[2]);
  5063. };
  5064. /**
  5065. * @function getHalfSideLengths returns the half-side lengths of this JBox expressed as a 3D vector
  5066. * @type array
  5067. **/
  5068. JBox.prototype.getHalfSideLengths=function(){
  5069. return JNumber3D.getScaleVector(this._sideLengths, 0.5);
  5070. };
  5071. /**
  5072. * @function getSpan returns the minimum and maximum extents of the box along the axis, relative to the center of the box.
  5073. * @param {array} axis the axis expressed as a 3D vector
  5074. * @type SpanData
  5075. **/
  5076. JBox.prototype.getSpan=function(axis){
  5077. var cols= this.get_currentState().getOrientationCols();
  5078. var obj = new SpanData();
  5079. var s = Math.abs(Vector3DUtil.dotProduct(axis, cols[0])) * (0.5 * this._sideLengths[0]);
  5080. var u = Math.abs(Vector3DUtil.dotProduct(axis, cols[1])) * (0.5 * this._sideLengths[1]);
  5081. var d = Math.abs(Vector3DUtil.dotProduct(axis, cols[2])) * (0.5 * this._sideLengths[2]);
  5082. var r = s + u + d;
  5083. var p = Vector3DUtil.dotProduct(this.get_currentState().position, axis);
  5084. obj.min = p - r;
  5085. obj.max = p + r;
  5086. return obj;
  5087. };
  5088. /**
  5089. * @function getCornerPoints returns the corner points of this JBox
  5090. * @param {PhysicsState} state
  5091. * @type array
  5092. **/
  5093. JBox.prototype.getCornerPoints=function(state){
  5094. var vertex;
  5095. var arr = [];
  5096. var transform = JMatrix3D.getTranslationMatrix(state.position[0], state.position[1], state.position[2]);
  5097. transform = JMatrix3D.getAppendMatrix3D(state.get_orientation(), transform);
  5098. for(var i=0, pl=this._points.length; i<pl; i++){
  5099. var _point=this._points[i];
  5100. vertex=Vector3DUtil.create(_point[0], _point[1], _point[2], 0);
  5101. JMatrix3D.multiplyVector(transform, vertex);
  5102. arr.push(vertex);
  5103. //arr.push(transform.transformVector(new Vector3D(_point[0], _point[1], _point[2])));
  5104. }
  5105. //arr.fixed = true;
  5106. return arr;
  5107. };
  5108. /**
  5109. * @function getCornerPointsInBoxSpace returns the corner points of this JBox in another box space
  5110. * @param {PhysicsState} thisState
  5111. * @param {PhysicsState} boxState
  5112. * @type array
  5113. **/
  5114. JBox.prototype.getCornerPointsInBoxSpace=function(thisState, boxState){
  5115. var max = JMatrix3D.getTransposeMatrix(boxState.get_orientation());
  5116. var pos = Vector3DUtil.subtract(thisState.position,boxState.position);
  5117. JMatrix3D.multiplyVector(max, pos);
  5118. var orient = JMatrix3D.getAppendMatrix3D(thisState.get_orientation(), max);
  5119. var arr = [];
  5120. var transform = JMatrix3D.getTranslationMatrix(pos[0], pos[1], pos[2]);
  5121. transform = JMatrix3D.getAppendMatrix3D(orient, transform);
  5122. for(var i=0;i<this._points.length;i++){
  5123. _point=this._points[i].slice(0);
  5124. JMatrix3D.multiplyVector(transform,_point);
  5125. arr[i] = _point;
  5126. }
  5127. return arr;
  5128. };
  5129. /**
  5130. * @function getSqDistanceToPoint
  5131. * @param {PhysicsState} state
  5132. * @param {array} closestBoxPoint
  5133. * @param {array} point
  5134. * @type number
  5135. **/
  5136. JBox.prototype.getSqDistanceToPoint=function(state, closestBoxPoint, point){
  5137. closestBoxPoint.pos = Vector3DUtil.subtract(point, state.position);
  5138. JMatrix3D.multiplyVector(JMatrix3D.getTransposeMatrix(state.get_orientation()), closestBoxPoint.pos);
  5139. var delta = 0;
  5140. var sqDistance = 0;
  5141. var halfSideLengths = this.getHalfSideLengths();
  5142. if (closestBoxPoint.pos[0] < -halfSideLengths[0]){
  5143. delta = closestBoxPoint.pos[0] + halfSideLengths[0];
  5144. sqDistance += (delta * delta);
  5145. closestBoxPoint.pos[0] = -halfSideLengths[0];
  5146. }else if (closestBoxPoint.pos[0] > halfSideLengths[0]){
  5147. delta = closestBoxPoint.pos[0] - halfSideLengths[0];
  5148. sqDistance += (delta * delta);
  5149. closestBoxPoint.pos[0] = halfSideLengths[0];
  5150. }
  5151. if (closestBoxPoint.pos[1] < -halfSideLengths[1]){
  5152. delta = closestBoxPoint.pos[1] + halfSideLengths[1];
  5153. sqDistance += (delta * delta);
  5154. closestBoxPoint.pos[1] = -halfSideLengths[1];
  5155. }else if (closestBoxPoint.pos[1] > halfSideLengths[1]){
  5156. delta = closestBoxPoint.pos[1] - halfSideLengths[1];
  5157. sqDistance += (delta * delta);
  5158. closestBoxPoint.pos[1] = halfSideLengths[1];
  5159. }
  5160. if (closestBoxPoint.pos[2] < -halfSideLengths[2]){
  5161. delta = closestBoxPoint.pos[2] + halfSideLengths[2];
  5162. sqDistance += (delta * delta);
  5163. closestBoxPoint.pos[2] = -halfSideLengths[2];
  5164. }else if (closestBoxPoint.pos[2] > halfSideLengths[2]){
  5165. delta = (closestBoxPoint.pos[2] - halfSideLengths[2]);
  5166. sqDistance += (delta * delta);
  5167. closestBoxPoint.pos[2] = halfSideLengths[2];
  5168. }
  5169. JMatrix3D.multiplyVector(state.get_orientation(), closestBoxPoint.pos);
  5170. closestBoxPoint.pos = Vector3DUtil.add(state.position, closestBoxPoint.pos);
  5171. return sqDistance;
  5172. };
  5173. /**
  5174. * @function getDistanceToPoint returns the distance from the point to the box, (negative if the point is inside the box), and optionally the closest point on the box
  5175. * @param {PhysicsState} state
  5176. * @param {array} closestBoxPoint
  5177. * @param {array} point
  5178. * @type number
  5179. **/
  5180. JBox.prototype.getDistanceToPoint=function(state, closestBoxPoint, point){
  5181. return Math.sqrt(this.getSqDistanceToPoint(state, closestBoxPoint, point));
  5182. };
  5183. /**
  5184. * @function pointIntersect
  5185. * @param {array} pos
  5186. * @type boolean
  5187. **/
  5188. JBox.prototype.pointIntersect=function(pos){
  5189. var p = Vector3DUtil.subtract(pos, this.get_currentState().position);
  5190. var h = JNumber3D.getScaleVector(this._sideLengths, 0.5);
  5191. var dirVec;
  5192. var cols = this.get_currentState().getOrientationCols();
  5193. for (var dir; dir < 3; dir++){
  5194. dirVec = cols[dir].slice(0);
  5195. Vector3DUtil.normalize(dirVec);
  5196. if (Math.abs(Vector3DUtil.dotProduct(dirVec, p)) > h[dir] + JNumber3D.NUM_TINY){
  5197. return false;
  5198. }
  5199. }
  5200. return true;
  5201. };
  5202. /**
  5203. * @function getSupportVertices
  5204. * @param {array} axis
  5205. * @type array
  5206. **/
  5207. JBox.prototype.getSupportVertices=function(axis){
  5208. var vertices = [];
  5209. var d = [1,1,1];
  5210. var H;
  5211. var temp = this.get_currentState().getOrientationCols();
  5212. Vector3DUtil.normalize(temp[0]);
  5213. Vector3DUtil.normalize(temp[1]);
  5214. Vector3DUtil.normalize(temp[2]);
  5215. for (var i = 0; i < 3; i++){
  5216. d[i] = Vector3DUtil.dotProduct(axis, temp[i]);
  5217. if (Math.abs(d[i]) > 1 - 0.001){
  5218. var f = (d[i] < 0) ? (i * 2) : (i * 2) + 1;
  5219. for (var j = 0; j < 4; j++){
  5220. H = this._points[this._faces[f][j]];
  5221. var _vj = vertices[j] = this.get_currentState().position.slice(0);
  5222. _vj = Vector3DUtil.add(_vj, JNumber3D.getScaleVector(temp[0], H[0]));
  5223. _vj = Vector3DUtil.add(_vj, JNumber3D.getScaleVector(temp[1], H[1]));
  5224. _vj = Vector3DUtil.add(_vj, JNumber3D.getScaleVector(temp[2], H[2]));
  5225. }
  5226. return vertices;
  5227. }
  5228. }
  5229. for (i = 0; i < 3; i++){
  5230. if (Math.abs(d[i]) < 0.005){
  5231. var k;
  5232. var m = (i + 1) % 3;
  5233. var n = (i + 2) % 3;
  5234. H = this.get_currentState().position.slice(0);
  5235. k = (d[m] > 0) ? -1 : 1;
  5236. H = Vector3DUtil.add(H, JNumber3D.getScaleVector(temp[m], k * this._sideLengths[m] / 2));
  5237. k = (d[n] > 0) ? -1 : 1;
  5238. H = Vector3DUtil.add(H, JNumber3D.getScaleVector(temp[n], k * this._sideLengths[n] / 2));
  5239. vertices[0] = Vector3DUtil.add(H, JNumber3D.getScaleVector(temp[i], this._sideLengths[i] / 2));
  5240. vertices[1] = Vector3DUtil.add(H, JNumber3D.getScaleVector(temp[i], -this._sideLengths[i] / 2));
  5241. return vertices;
  5242. }
  5243. }
  5244. var _v0 =vertices[0] = this.get_currentState().position.slice(0);
  5245. k = (d[0] > 0) ? -1 : 1;
  5246. vertices[0] = Vector3DUtil.add(_v0, JNumber3D.getScaleVector(temp[0], k * this._sideLengths[0] / 2));
  5247. k = (d[1] > 0) ? -1 : 1;
  5248. vertices[0] = Vector3DUtil.add(_v0, JNumber3D.getScaleVector(temp[1], k * this._sideLengths[1] / 2));
  5249. k = (d[2] > 0) ? -1 : 1;
  5250. vertices[0] = Vector3DUtil.add(_v0, JNumber3D.getScaleVector(temp[2], k * this._sideLengths[2] / 2));
  5251. return vertices;
  5252. };
  5253. /**
  5254. * @function segmentIntersect
  5255. * @param {object} out
  5256. * @param {JSegment} seg
  5257. * @param {PhysicsState} state
  5258. * @type boolean
  5259. **/
  5260. JBox.prototype.segmentIntersect=function(out, seg, state){
  5261. out.frac = 0;
  5262. out.position = [0,0,0,0];
  5263. out.normal = [0,0,0,0];
  5264. var frac = JNumber3D.NUM_HUGE;
  5265. var min = -JNumber3D.NUM_HUGE;
  5266. var max = JNumber3D.NUM_HUGE;
  5267. var dirMin = 0;
  5268. var dirMax = 0;
  5269. var dir = 0;
  5270. var p = Vector3DUtil.subtract(state.position, seg.origin);
  5271. var h = JNumber3D.getScaleVector(this._sideLengths, 0.5);
  5272. //var tempV:Vector3D;
  5273. var e;
  5274. var f;
  5275. var t;
  5276. var t1;
  5277. var t2;
  5278. var orientationCol = state.getOrientationCols();
  5279. var directionVectorArray = h.slice(0);
  5280. var directionVectorNumber;
  5281. for (dir = 0; dir < 3; dir++){
  5282. directionVectorNumber = directionVectorArray[dir];
  5283. e = Vector3DUtil.dotProduct(orientationCol[dir], p);
  5284. f = Vector3DUtil.dotProduct(orientationCol[dir], seg.delta);
  5285. if (Math.abs(f) > JNumber3D.NUM_TINY){
  5286. t1 = (e + directionVectorNumber) / f;
  5287. t2 = (e - directionVectorNumber) / f;
  5288. if (t1 > t2){
  5289. t = t1;
  5290. t1 = t2;
  5291. t2 = t;
  5292. }
  5293. if (t1 > min){
  5294. min = t1;
  5295. dirMin = dir;
  5296. }
  5297. if (t2 < max){
  5298. max = t2;
  5299. dirMax = dir;
  5300. }
  5301. if (min > max) return false;
  5302. if (max < 0) return false;
  5303. }else if (-e - directionVectorNumber > 0 || -e + directionVectorNumber < 0){
  5304. return false;
  5305. }
  5306. }
  5307. if (min > 0){
  5308. dir = dirMin;
  5309. frac = min;
  5310. }else{
  5311. dir = dirMax;
  5312. frac = max;
  5313. }
  5314. if (frac < 0) frac = 0;
  5315. /*if (frac > 1)
  5316. frac = 1;*/
  5317. if (frac > 1 - JNumber3D.NUM_TINY){
  5318. return false;
  5319. }
  5320. out.frac = frac;
  5321. out.position = seg.getPoint(frac);
  5322. if (Vector3DUtil.dotProduct(orientationCol[dir], seg.delta) < 0)
  5323. out.normal = JNumber3D.getScaleVector(orientationCol[dir], -1);
  5324. else
  5325. out.normal = orientationCol[dir];
  5326. return true;
  5327. };
  5328. /**
  5329. * @function getInertiaProperties
  5330. * @param {number} m
  5331. * @type JMatrix3D
  5332. **/
  5333. JBox.prototype.getInertiaProperties=function(m){
  5334. return JMatrix3D.getScaleMatrix(
  5335. (m/12) * (this._sideLengths[1] * this._sideLengths[1] + this._sideLengths[2] * this._sideLengths[2]),
  5336. (m/12) * (this._sideLengths[0] * this._sideLengths[0] + this._sideLengths[2] * this._sideLengths[2]),
  5337. (m/12) * (this._sideLengths[0] * this._sideLengths[0] + this._sideLengths[1] * this._sideLengths[1]));
  5338. };
  5339. /**
  5340. * @function updateBoundingBox updates the bounding box for this JBox
  5341. * @type void
  5342. **/
  5343. JBox.prototype.updateBoundingBox=function(){
  5344. this._boundingBox.clear();
  5345. this._boundingBox.addBox(this);
  5346. };
  5347. jigLib.JBox=JBox;
  5348. })(jigLib);
  5349. /*
  5350. Copyright (c) 2007 Danny Chapman
  5351. http://www.rowlhouse.co.uk
  5352. This software is provided 'as-is', without any express or implied
  5353. warranty. In no event will the authors be held liable for any damages
  5354. arising from the use of this software.
  5355. Permission is granted to anyone to use this software for any purpose,
  5356. including commercial applications, and to alter it and redistribute it
  5357. freely, subject to the following restrictions:
  5358. 1. The origin of this software must not be misrepresented; you must not
  5359. claim that you wrote the original software. If you use this software
  5360. in a product, an acknowledgment in the product documentation would be
  5361. appreciated but is not required.
  5362. 2. Altered source versions must be plainly marked as such, and must not be
  5363. misrepresented as being the original software.
  5364. 3. This notice may not be removed or altered from any source
  5365. distribution.
  5366. */
  5367. (function(jigLib){
  5368. var Vector3DUtil=jigLib.Vector3DUtil;
  5369. var JMatrix3D=jigLib.JMatrix3D;
  5370. var JNumber3D=jigLib.JNumber3D;
  5371. var RigidBody=jigLib.RigidBody;
  5372. var JSegment=jigLib.JSegment;
  5373. /**
  5374. * @author Muzer(muzerly@gmail.com)
  5375. *
  5376. * @name JCapsule
  5377. * @class JCapsule
  5378. * @extends RigidBody
  5379. * @requires Vector3DUtil
  5380. * @requires JMatrix3D
  5381. * @requires JNumber3D
  5382. * @requires JSegment
  5383. * @property {number} _length the length of this JCapsule
  5384. * @property {number} _radius the radius of this JCapsule
  5385. * @constructor
  5386. * @param {ISkin3D} skin
  5387. * @param {number} r the radius
  5388. * @param {number} l the length
  5389. **/
  5390. var JCapsule=function(skin, r, l) {
  5391. this.Super(skin);
  5392. this._type = "CAPSULE";
  5393. this._radius = r;
  5394. this._length = l;
  5395. this._boundingSphere = this.getBoundingSphere(r, l);
  5396. this.set_mass(1);
  5397. this.updateBoundingBox();
  5398. };
  5399. jigLib.extend(JCapsule,jigLib.RigidBody);
  5400. JCapsule.prototype._length=null;
  5401. JCapsule.prototype._radius=null;
  5402. /**
  5403. * @function set_radius sets the radius
  5404. * @param {number} r the new radius
  5405. * @type void
  5406. **/
  5407. JCapsule.prototype.set_radius=function(r){
  5408. this._radius = r;
  5409. this._boundingSphere = getBoundingSphere(this._radius, this._length);
  5410. this.setInertia(this.getInertiaProperties(this.get_mass()));
  5411. this.updateBoundingBox();
  5412. this.setActive();
  5413. };
  5414. /**
  5415. * @function get_radius gets the radius
  5416. * @type number
  5417. **/
  5418. JCapsule.prototype.get_radius=function(){
  5419. return this._radius;
  5420. };
  5421. /**
  5422. * @function set_length sets the length
  5423. * @param {number} l the new length
  5424. * @type void
  5425. **/
  5426. JCapsule.prototype.set_length=function(l){
  5427. this._length = l;
  5428. this._boundingSphere = getBoundingSphere(this._radius, this._length);
  5429. this.setInertia(this.getInertiaProperties(this.get_mass()));
  5430. this.updateBoundingBox();
  5431. this.setActive();
  5432. };
  5433. /**
  5434. * @function get_length gets the length
  5435. * @type number
  5436. **/
  5437. JCapsule.prototype.get_length=function(){
  5438. return this._length;
  5439. };
  5440. /**
  5441. * @function getBottomPos gets the bottom position expressed as a 3D vector
  5442. * @param {PhysicsState} state
  5443. * @type array
  5444. **/
  5445. JCapsule.prototype.getBottomPos=function(state){
  5446. var temp = state.getOrientationCols()[1];
  5447. //Vector3DUtil.normalize(temp);
  5448. return Vector3DUtil.add(state.position, JNumber3D.getScaleVector(temp, -this._length / 2 - this._radius));
  5449. };
  5450. /**
  5451. * @function getEndPos gets the end position expressed as a 3D vector
  5452. * @param {PhysicsState} state
  5453. * @type array
  5454. **/
  5455. JCapsule.prototype.getEndPos=function(state){
  5456. var temp = state.getOrientationCols()[1];
  5457. //Vector3DUtil.normalize(temp);
  5458. return Vector3DUtil.add(state.position, JNumber3D.getScaleVector(temp, this._length / 2 + this._radius));
  5459. };
  5460. /**
  5461. * @function segmentIntersect tests a segment for intersection
  5462. * @param {object} out
  5463. * @param {JSegment} seg
  5464. * @param {PhysicsState} state
  5465. * @type boolean
  5466. **/
  5467. JCapsule.prototype.segmentIntersect=function(out, seg, state){
  5468. out.frac = 0;
  5469. out.position = [0,0,0,0];
  5470. out.normal = [0,0,0,0];
  5471. var Ks = seg.delta;
  5472. var kss = Vector3DUtil.dotProduct(Ks, Ks);
  5473. var radiusSq = this._radius * this._radius;
  5474. var cols = state.getOrientationCols();
  5475. var cylinderAxis = new JSegment(getBottomPos(state), cols[1]);
  5476. var Ke = cylinderAxis.delta;
  5477. var Kg = Vector3DUtil.subtract(cylinderAxis.origin, seg.origin);
  5478. var kee = Vector3DUtil.dotProduct(Ke, Ke);
  5479. if (Math.abs(kee) < JNumber3D.NUM_TINY) {
  5480. return false;
  5481. }
  5482. var kes = Vector3DUtil.dotProduct(Ke, Ks);
  5483. var kgs = Vector3DUtil.dotProduct(Kg, Ks);
  5484. var keg = Vector3DUtil.dotProduct(Ke, Kg);
  5485. var kgg = Vector3DUtil.dotProduct(Kg, Kg);
  5486. var distSq = Vector3DUtil.get_lengthSquared(Vector3DUtil.subtract(Kg, JNumber3D.getDivideVector(JNumber3D.getScaleVector(Ke, keg), kee)));
  5487. if (distSq < radiusSq) {
  5488. out.fracOut = 0;
  5489. out.posOut = seg.origin.slice(0);
  5490. out.normalOut = Vector3DUtil.subtract(out.posOut, getBottomPos(state));
  5491. out.normalOut = Vector3DUtil.subtract(out.normalOut, JNumber3D.getScaleVector(cols[1], Vector3DUtil.dotProduct(out.normalOut, cols[1])));
  5492. Vector3DUtil.normalize(out.normalOut);
  5493. return true;
  5494. }
  5495. var ar = kee * kss - (kes * kes);
  5496. if (Math.abs(a) < JNumber3D.NUM_TINY) {
  5497. return false;
  5498. }
  5499. var b = 2 * (keg * kes - kee * kgs);
  5500. var c = kee * (kgg - radiusSq) - (keg * keg);
  5501. var blah = (b * b) - 4 * a * c;
  5502. if (blah < 0) {
  5503. return false;
  5504. }
  5505. var t = ( -b - Math.sqrt(blah)) / (2 * a);
  5506. if (t < 0 || t > 1) {
  5507. return false;
  5508. }
  5509. out.frac = t;
  5510. out.position = seg.getPoint(t);
  5511. out.normal = Vector3DUtil.subtract(out.posOut, getBottomPos(state));
  5512. out.normal = Vector3DUtil.subtract(out.normal, JNumber3D.getScaleVector(cols[1], Vector3DUtil.dotProduct(out.normal, cols[1])));
  5513. Vector3DUtil.normalize(out.normal);
  5514. return true;
  5515. };
  5516. /**
  5517. * @function getInertiaProperties
  5518. * @param {number} m
  5519. * @type JMatrix3D
  5520. **/
  5521. JCapsule.prototype.getInertiaProperties=function(m){
  5522. var cylinderMass = m * Math.PI * this._radius * this._radius * this._length / this.getVolume();
  5523. var Ixx = 0.25 * cylinderMass * this._radius * this._radius + (1 / 12) * cylinderMass * this._length * this._length;
  5524. var Iyy = 0.5 * cylinderMass * this._radius * this._radius;
  5525. var Izz= Ixx;
  5526. var endMass = m - cylinderMass;
  5527. Ixx += (0.4 * endMass * this._radius * this._radius + endMass * Math.pow(0.5 * this._length, 2));
  5528. Iyy += (0.2 * endMass * this._radius * this._radius);
  5529. Izz += (0.4 * endMass * this._radius * this._radius + endMass * Math.pow(0.5 * this._length, 2));
  5530. /*
  5531. var inertiaTensor:JMatrix3D = new JMatrix3D();
  5532. inertiaTensor.n11 = Ixx;
  5533. inertiaTensor.n22 = Iyy;
  5534. inertiaTensor.n33 = Izz;
  5535. */
  5536. return JMatrix3D.getScaleMatrix(Ixx, Iyy, Izz);
  5537. };
  5538. /**
  5539. * @function updateBoundingBox updates the bounding box for this JCapsule
  5540. * @type void
  5541. **/
  5542. JCapsule.prototype.updateBoundingBox=function(){
  5543. this._boundingBox.clear();
  5544. this._boundingBox.addCapsule(this);
  5545. };
  5546. /**
  5547. * @function getBoundingSphere gets the bounding sphere for any JCapsule based on it's radius and length
  5548. * @param {number} r the radius
  5549. * @param {number} l the length
  5550. * @type number
  5551. **/
  5552. JCapsule.prototype.getBoundingSphere=function(r, l){
  5553. return Math.sqrt(Math.pow(l / 2, 2) + r * r) + r;
  5554. };
  5555. /**
  5556. * @function getVolume gets the vollume for this JCapsule
  5557. * @type number
  5558. **/
  5559. JCapsule.prototype.getVolume=function(){
  5560. return (4 / 3) * Math.PI * this._radius * this._radius * this._radius + this._length * Math.PI * this._radius * this._radius;
  5561. };
  5562. jigLib.JCapsule=JCapsule;
  5563. })(jigLib);
  5564. /*
  5565. Copyright (c) 2007 Danny Chapman
  5566. http://www.rowlhouse.co.uk
  5567. This software is provided 'as-is', without any express or implied
  5568. warranty. In no event will the authors be held liable for any damages
  5569. arising from the use of this software.
  5570. Permission is granted to anyone to use this software for any purpose,
  5571. including commercial applications, and to alter it and redistribute it
  5572. freely, subject to the following restrictions:
  5573. 1. The origin of this software must not be misrepresented; you must not
  5574. claim that you wrote the original software. If you use this software
  5575. in a product, an acknowledgment in the product documentation would be
  5576. appreciated but is not required.
  5577. 2. Altered source versions must be plainly marked as such, and must not be
  5578. misrepresented as being the original software.
  5579. 3. This notice may not be removed or altered from any source
  5580. distribution.
  5581. */
  5582. (function(jigLib){
  5583. var Vector3DUtil=jigLib.Vector3DUtil;
  5584. var JMatrix3D=jigLib.JMatrix3D;
  5585. var JNumber3D=jigLib.JNumber3D;
  5586. var RigidBody=jigLib.RigidBody;
  5587. /**
  5588. * @author Muzer(muzerly@gmail.com)
  5589. *
  5590. * @name JPlane
  5591. * @class JPlane
  5592. * @extends RigidBody
  5593. * @requires Vector3DUtil
  5594. * @requires JMatrix3D
  5595. * @requires JNumber3D
  5596. * @property {array} _initNormal the length of this JCapsule
  5597. * @property {array} _normal the radius of this JCapsule
  5598. * @property {number} _distance
  5599. * @constructor
  5600. * @param {ISkin3D} skin
  5601. * @param {array} initNormal
  5602. **/
  5603. var JPlane=function(skin, initNormal){
  5604. this.Super(skin);
  5605. if (initNormal == undefined) {
  5606. this._initNormal = [0, 0, -1, 0];
  5607. this._normal = this._initNormal.slice(0);
  5608. }else{
  5609. this._initNormal = initNormal.slice(0);
  5610. this._normal = this._initNormal.slice(0);
  5611. }
  5612. this._distance = 0;
  5613. this._type = "PLANE";
  5614. this._movable=false;
  5615. };
  5616. jigLib.extend(JPlane,jigLib.RigidBody);
  5617. JPlane.prototype._initNormal=null;
  5618. JPlane.prototype._normal=null;
  5619. JPlane.prototype._distance=null;
  5620. /**
  5621. * @function get_normal gets the normal
  5622. * @type array
  5623. **/
  5624. JPlane.prototype.get_normal=function(){
  5625. return this._normal;
  5626. };
  5627. /**
  5628. * @function get_normal gets the distance
  5629. * @type number
  5630. **/
  5631. JPlane.prototype.get_distance=function(){
  5632. return this._distance;
  5633. };
  5634. /**
  5635. * @function set_normal sets the normal
  5636. * @param {array} value The plane normal
  5637. **/
  5638. JPlane.prototype.set_normal=function(value){
  5639. this._initNormal=value;
  5640. this._normal=value;
  5641. };
  5642. /**
  5643. * @function set_normal sets the distance
  5644. * @param {number} value The plane distance
  5645. **/
  5646. JPlane.prototype.set_distance=function(value){
  5647. this._distance=value;
  5648. };
  5649. /**
  5650. * @function pointPlaneDistance gets the distance from a given point
  5651. * @param {array} pt the point expressed as a 3D vector
  5652. * @type array
  5653. **/
  5654. JPlane.prototype.pointPlaneDistance=function(pt){
  5655. return Vector3DUtil.dotProduct(this._normal, pt) - this._distance;
  5656. };
  5657. /**
  5658. * @function segmentIntersect tests for intersection with a JSegment
  5659. * @param {object} out
  5660. * @param {JSegment} seg
  5661. * @param {PhysicsState} state
  5662. * @type boolean
  5663. **/
  5664. JPlane.prototype.segmentIntersect=function(out, seg, state){
  5665. out.frac = 0;
  5666. out.position = [0,0,0,0];
  5667. out.normal = [0,0,0,0];
  5668. var frac = 0;
  5669. var t;
  5670. var denom = Vector3DUtil.dotProduct(this._normal, seg.delta);
  5671. if (Math.abs(denom) > JNumber3D.NUM_TINY){
  5672. t = -1 * (Vector3DUtil.dotProduct(this._normal, seg.origin) - this._distance) / denom;
  5673. if (t < 0 || t > 1){
  5674. return false;
  5675. }else{
  5676. frac = t;
  5677. out.frac = frac;
  5678. out.position = seg.getPoint(frac);
  5679. out.normal = this._normal.slice(0);
  5680. Vector3DUtil.normalize(out.normal);
  5681. return true;
  5682. }
  5683. }else{
  5684. return false;
  5685. }
  5686. };
  5687. /**
  5688. * @function updateState updates the current PhysicsState
  5689. * @type void
  5690. **/
  5691. JPlane.prototype.updateState=function(){
  5692. this.Super.prototype.updateState.call(this);
  5693. this._normal = this._initNormal.slice(0);
  5694. JMatrix3D.multiplyVector(this._currState._orientation, this._normal);
  5695. //_normal = _currState.orientation.transformVector(new Vector3D(0, 0, -1));
  5696. this._distance = Vector3DUtil.dotProduct(this._currState.position, this._normal);
  5697. };
  5698. jigLib.JPlane=JPlane;
  5699. })(jigLib);
  5700. /*
  5701. Copyright (c) 2007 Danny Chapman
  5702. http://www.rowlhouse.co.uk
  5703. This software is provided 'as-is', without any express or implied
  5704. warranty. In no event will the authors be held liable for any damages
  5705. arising from the use of this software.
  5706. Permission is granted to anyone to use this software for any purpose,
  5707. including commercial applications, and to alter it and redistribute it
  5708. freely, subject to the following restrictions:
  5709. 1. The origin of this software must not be misrepresented; you must not
  5710. claim that you wrote the original software. If you use this software
  5711. in a product, an acknowledgment in the product documentation would be
  5712. appreciated but is not required.
  5713. 2. Altered source versions must be plainly marked as such, and must not be
  5714. misrepresented as being the original software.
  5715. 3. This notice may not be removed or altered from any source
  5716. distribution.
  5717. */
  5718. (function(jigLib){
  5719. var Vector3DUtil=jigLib.Vector3DUtil;
  5720. var JNumber3D=jigLib.JNumber3D;
  5721. /**
  5722. * @author Muzer(muzerly@gmail.com)
  5723. *
  5724. * @name JRay
  5725. * @class JRay
  5726. * @extends RigidBody
  5727. * @requires Vector3DUtil
  5728. * @requires JNumber3D
  5729. * @property {array} origin the origin of the ray expressed as a 3D vector
  5730. * @property {array} dir the direction of the ray expressed as a 3D vector
  5731. * @constructor
  5732. * @param {array} _origin the origin of the ray expressed as a 3D vector
  5733. * @param {array} _dir the direction of the ray expressed as a 3D vector
  5734. **/
  5735. var JRay=function(_origin, _dir){
  5736. this.origin = _origin;
  5737. this.dir = _dir;
  5738. };
  5739. JRay.prototype.origin=null;
  5740. JRay.prototype.dir=null;
  5741. /**
  5742. * @function getOrigin gets the origin
  5743. * @param {number} t
  5744. * @type array
  5745. **/
  5746. JRay.prototype.getOrigin=function(t){
  5747. return Vector3DUtil.add(this.origin, JNumber3D.getScaleVector(this.dir, t));
  5748. };
  5749. jigLib.JRay=JRay;
  5750. })(jigLib);
  5751. /*
  5752. Copyright (c) 2007 Danny Chapman
  5753. http://www.rowlhouse.co.uk
  5754. This software is provided 'as-is', without any express or implied
  5755. warranty. In no event will the authors be held liable for any damages
  5756. arising from the use of this software.
  5757. Permission is granted to anyone to use this software for any purpose,
  5758. including commercial applications, and to alter it and redistribute it
  5759. freely, subject to the following restrictions:
  5760. 1. The origin of this software must not be misrepresented; you must not
  5761. claim that you wrote the original software. If you use this software
  5762. in a product, an acknowledgment in the product documentation would be
  5763. appreciated but is not required.
  5764. 2. Altered source versions must be plainly marked as such, and must not be
  5765. misrepresented as being the original software.
  5766. 3. This notice may not be removed or altered from any source
  5767. distribution.
  5768. */
  5769. (function(jigLib){
  5770. var Vector3DUtil=jigLib.Vector3DUtil;
  5771. var JNumber3D=jigLib.JNumber3D;
  5772. var JRay=jigLib.JRay;
  5773. /**
  5774. * @author Muzer(muzerly@gmail.com)
  5775. *
  5776. * @name JSegment
  5777. * @class JSegment
  5778. * @extends RigidBody
  5779. * @requires Vector3DUtil
  5780. * @requires JNumber3D
  5781. * @requires JRay
  5782. * @property {array} origin the origin of the segment expressed as a 3D vector
  5783. * @property {array} delta the delta of the segment expressed as a 3D vector
  5784. * @constructor
  5785. * @param {array} _origin the origin of the segment expressed as a 3D vector
  5786. * @param {array} _delta the delta of the segment expressed as a 3D vector
  5787. **/
  5788. var JSegment=function(_origin, _delta){
  5789. this.origin = _origin;
  5790. this.delta = _delta;
  5791. };
  5792. JSegment.prototype.origin=null;
  5793. JSegment.prototype.delta=null;
  5794. /**
  5795. * @function getPoint gets the point of the segment expressed as a 3D vector
  5796. * @param {number} t
  5797. * @type array
  5798. **/
  5799. JSegment.prototype.getPoint=function(t){
  5800. return Vector3DUtil.add(this.origin, JNumber3D.getScaleVector(this.delta, t));
  5801. };
  5802. /**
  5803. * @function getEnd gets the end of the segment expressed as a 3D vector
  5804. * @type array
  5805. **/
  5806. JSegment.prototype.getEnd=function(){
  5807. return Vector3DUtil.add(this.origin, this.delta);
  5808. };
  5809. /**
  5810. * @function clone returns a copy
  5811. * @type JSegment
  5812. **/
  5813. JSegment.prototype.clone=function(){
  5814. return new JSegment(this.origin, this.delta);
  5815. };
  5816. /**
  5817. * @function segmentSegmentDistanceSq
  5818. * @param {object} out
  5819. * @param {JSegment} seg
  5820. * @type number
  5821. **/
  5822. JSegment.prototype.segmentSegmentDistanceSq=function(out, seg){
  5823. out.t0 = 0;
  5824. out.t1 = 0;
  5825. var kDiff = Vector3DUtil.subtract(this.origin, seg.origin);
  5826. var fA00 = Vector3DUtil.get_lengthSquared(this.delta);
  5827. var fA01 = -Vector3DUtil.dotProduct(this.delta, seg.delta);
  5828. var fA11 = Vector3DUtil.get_lengthSquared(seg.delta);
  5829. var fB0 = Vector3DUtil.dotProduct(kDiff, this.delta);
  5830. var fC = Vector3DUtil.get_lengthSquared(kDiff);
  5831. var fDet = Math.abs(fA00 * fA11 - fA01 * fA01);
  5832. var fB1;
  5833. var fS;
  5834. var fT;
  5835. var fSqrDist;
  5836. var fTmp;
  5837. if (fDet >= JNumber3D.NUM_TINY){
  5838. fB1 = -Vector3DUtil.dotProduct(kDiff, seg.delta);
  5839. fS = fA01 * fB1 - fA11 * fB0;
  5840. fT = fA01 * fB0 - fA00 * fB1;
  5841. if (fS >= 0){
  5842. if (fS <= fDet){
  5843. if (fT >= 0){
  5844. if (fT <= fDet){
  5845. var fInvDet = 1 / fDet;
  5846. fS *= fInvDet;
  5847. fT *= fInvDet;
  5848. fSqrDist = fS * (fA00 * fS + fA01 * fT + 2 * fB0) + fT * (fA01 * fS + fA11 * fT + 2 * fB1) + fC;
  5849. }else{
  5850. fT = 1;
  5851. fTmp = fA01 + fB0;
  5852. if (fTmp >= 0){
  5853. fS = 0;
  5854. fSqrDist = fA11 + 2 * fB1 + fC;
  5855. }else if (-fTmp >= fA00){
  5856. fS = 1;
  5857. fSqrDist = fA00 + fA11 + fC + 2 * (fB1 + fTmp);
  5858. }else{
  5859. fS = -fTmp / fA00;
  5860. fSqrDist = fTmp * fS + fA11 + 2 * fB1 + fC;
  5861. }
  5862. }
  5863. }else{
  5864. fT = 0;
  5865. if (fB0 >= 0){
  5866. fS = 0;
  5867. fSqrDist = fC;
  5868. }else if (-fB0 >= fA00){
  5869. fS = 1;
  5870. fSqrDist = fA00 + 2 * fB0 + fC;
  5871. }else{
  5872. fS = -fB0 / fA00;
  5873. fSqrDist = fB0 * fS + fC;
  5874. }
  5875. }
  5876. }else{
  5877. if (fT >= 0){
  5878. if (fT <= fDet){
  5879. fS = 1;
  5880. fTmp = fA01 + fB1;
  5881. if (fTmp >= 0){
  5882. fT = 0;
  5883. fSqrDist = fA00 + 2 * fB0 + fC;
  5884. }else if (-fTmp >= fA11){
  5885. fT = 1;
  5886. fSqrDist = fA00 + fA11 + fC + 2 * (fB0 + fTmp);
  5887. }else{
  5888. fT = -fTmp / fA11;
  5889. fSqrDist = fTmp * fT + fA00 + 2 * fB0 + fC;
  5890. }
  5891. }else{
  5892. fTmp = fA01 + fB0;
  5893. if (-fTmp <= fA00){
  5894. fT = 1;
  5895. if (fTmp >= 0){
  5896. fS = 0;
  5897. fSqrDist = fA11 + 2 * fB1 + fC;
  5898. }else{
  5899. fS = -fTmp / fA00;
  5900. fSqrDist = fTmp * fS + fA11 + 2 * fB1 + fC;
  5901. }
  5902. }else{
  5903. fS = 1;
  5904. fTmp = fA01 + fB1;
  5905. if (fTmp >= 0){
  5906. fT = 0;
  5907. fSqrDist = fA00 + 2 * fB0 + fC;
  5908. }else if (-fTmp >= fA11){
  5909. fT = 1;
  5910. fSqrDist = fA00 + fA11 + fC + 2 * (fB0 + fTmp);
  5911. }else{
  5912. fT = -fTmp / fA11;
  5913. fSqrDist = fTmp * fT + fA00 + 2 * fB0 + fC;
  5914. }
  5915. }
  5916. }
  5917. }else{
  5918. if (-fB0 < fA00){
  5919. fT = 0;
  5920. if (fB0 >= 0){
  5921. fS = 0;
  5922. fSqrDist = fC;
  5923. }else{
  5924. fS = -fB0 / fA00;
  5925. fSqrDist = fB0 * fS + fC;
  5926. }
  5927. }else{
  5928. fS = 1;
  5929. fTmp = fA01 + fB1;
  5930. if (fTmp >= 0){
  5931. fT = 0;
  5932. fSqrDist = fA00 + 2 * fB0 + fC;
  5933. }else if (-fTmp >= fA11){
  5934. fT = 1;
  5935. fSqrDist = fA00 + fA11 + fC + 2 * (fB0 + fTmp);
  5936. }else{
  5937. fT = -fTmp / fA11;
  5938. fSqrDist = fTmp * fT + fA00 + 2 * fB0 + fC;
  5939. }
  5940. }
  5941. }
  5942. }
  5943. }else{
  5944. if (fT >= 0){
  5945. if (fT <= fDet){
  5946. fS = 0;
  5947. if (fB1 >= 0){
  5948. fT = 0;
  5949. fSqrDist = fC;
  5950. }else if (-fB1 >= fA11){
  5951. fT = 1;
  5952. fSqrDist = fA11 + 2 * fB1 + fC;
  5953. }else{
  5954. fT = -fB1 / fA11;
  5955. fSqrDist = fB1 * fT + fC;
  5956. }
  5957. }else{
  5958. fTmp = fA01 + fB0;
  5959. if (fTmp < 0){
  5960. fT = 1;
  5961. if (-fTmp >= fA00){
  5962. fS = 1;
  5963. fSqrDist = fA00 + fA11 + fC + 2 * (fB1 + fTmp);
  5964. }else{
  5965. fS = -fTmp / fA00;
  5966. fSqrDist = fTmp * fS + fA11 + 2 * fB1 + fC;
  5967. }
  5968. }else{
  5969. fS = 0;
  5970. if (fB1 >= 0){
  5971. fT = 0;
  5972. fSqrDist = fC;
  5973. }else if (-fB1 >= fA11){
  5974. fT = 1;
  5975. fSqrDist = fA11 + 2 * fB1 + fC;
  5976. }else{
  5977. fT = -fB1 / fA11;
  5978. fSqrDist = fB1 * fT + fC;
  5979. }
  5980. }
  5981. }
  5982. }else{
  5983. if (fB0 < 0){
  5984. fT = 0;
  5985. if (-fB0 >= fA00){
  5986. fS = 1;
  5987. fSqrDist = fA00 + 2 * fB0 + fC;
  5988. }else{
  5989. fS = -fB0 / fA00;
  5990. fSqrDist = fB0 * fS + fC;
  5991. }
  5992. }else{
  5993. fS = 0;
  5994. if (fB1 >= 0){
  5995. fT = 0;
  5996. fSqrDist = fC;
  5997. }else if (-fB1 >= fA11){
  5998. fT = 1;
  5999. fSqrDist = fA11 + 2 * fB1 + fC;
  6000. }else{
  6001. fT = -fB1 / fA11;
  6002. fSqrDist = fB1 * fT + fC;
  6003. }
  6004. }
  6005. }
  6006. }
  6007. }else{
  6008. if (fA01 > 0){
  6009. if (fB0 >= 0){
  6010. fS = 0;
  6011. fT = 0;
  6012. fSqrDist = fC;
  6013. }else if (-fB0 <= fA00){
  6014. fS = -fB0 / fA00;
  6015. fT = 0;
  6016. fSqrDist = fB0 * fS + fC;
  6017. }else{
  6018. fB1 = -Vector3DUtil.dotProduct(kDiff, seg.delta);
  6019. fS = 1;
  6020. fTmp = fA00 + fB0;
  6021. if (-fTmp >= fA01){
  6022. fT = 1;
  6023. fSqrDist = fA00 + fA11 + fC + 2 * (fA01 + fB0 + fB1);
  6024. }else{
  6025. fT = -fTmp / fA01;
  6026. fSqrDist = fA00 + 2 * fB0 + fC + fT * (fA11 * fT + 2 * (fA01 + fB1));
  6027. }
  6028. }
  6029. }else{
  6030. if (-fB0 >= fA00){
  6031. fS = 1;
  6032. fT = 0;
  6033. fSqrDist = fA00 + 2 * fB0 + fC;
  6034. }else if (fB0 <= 0) {
  6035. fS = -fB0 / fA00;
  6036. fT = 0;
  6037. fSqrDist = fB0 * fS + fC;
  6038. }else{
  6039. fB1 = -Vector3DUtil.dotProduct(kDiff, seg.delta);
  6040. fS = 0;
  6041. if (fB0 >= -fA01){
  6042. fT = 1;
  6043. fSqrDist = fA11 + 2 * fB1 + fC;
  6044. }else{
  6045. fT = -fB0 / fA01;
  6046. fSqrDist = fC + fT * (2 * fB1 + fA11 * fT);
  6047. }
  6048. }
  6049. }
  6050. }
  6051. out.t0 = fS;
  6052. out.t1 = fT;
  6053. return Math.abs(fSqrDist);
  6054. };
  6055. /**
  6056. * @function pointSegmentDistanceSq
  6057. * @param {object} out
  6058. * @param {array} pt
  6059. * @type number
  6060. **/
  6061. JSegment.prototype.pointSegmentDistanceSq=function(out, pt){
  6062. out.t = 0;
  6063. var kDiff = Vector3DUtil.subtract(pt, this.origin);
  6064. var fT = Vector3DUtil.dotProduct(kDiff, this.delta);
  6065. if (fT <= 0){
  6066. fT = 0;
  6067. }else{
  6068. var fSqrLen = Vector3DUtil.get_lengthSquared(this._delta);
  6069. if (fT >= fSqrLen){
  6070. fT = 1;
  6071. kDiff = Vector3DUtil.subtract(kDiff, this._delta);
  6072. }else{
  6073. fT /= fSqrLen;
  6074. kDiff = Vector3DUtil.subtract(kDiff, JNumber3D.getScaleVector(this._delta, fT));
  6075. }
  6076. }
  6077. out.t = fT;
  6078. return Vector3DUtil.get_lengthSquared(kDiff);
  6079. };
  6080. /**
  6081. * @function segmentBoxDistanceSq
  6082. * @param {object} out
  6083. * @param {JBox} rkBox
  6084. * @param {PhysicsState} boxState
  6085. * @type number
  6086. **/
  6087. JSegment.prototype.segmentBoxDistanceSq=function(out, rkBox, boxState){
  6088. out.pfLParam = 0;
  6089. out.pfLParam0 = 0;
  6090. out.pfLParam1 = 0;
  6091. out.pfLParam2 = 0;
  6092. var obj = {};
  6093. var kRay = new JRay(this.origin, this.delta);
  6094. var fSqrDistance = this.sqrDistanceLine(obj, kRay, rkBox, boxState);
  6095. if (obj.num >= 0){
  6096. if (obj.num <= 1){
  6097. out.pfLParam = obj.num;
  6098. out.pfLParam0 = obj.num0;
  6099. out.pfLParam1 = obj.num1;
  6100. out.pfLParam2 = obj.num2;
  6101. return Math.max(fSqrDistance, 0);
  6102. }else{
  6103. fSqrDistance = this.sqrDistancePoint(out, Vector3DUtil.add(this.origin, this.delta), rkBox, boxState);
  6104. out.pfLParam = 1;
  6105. return Math.max(fSqrDistance, 0);
  6106. }
  6107. }else{
  6108. fSqrDistance = this.sqrDistancePoint(out, this.origin, rkBox, boxState);
  6109. out.pfLParam = 0;
  6110. return Math.max(fSqrDistance, 0);
  6111. }
  6112. };
  6113. /**
  6114. * @function sqrDistanceLine
  6115. * @param {object} out
  6116. * @param {JRay} rkLine
  6117. * @param {JBox} rkBox
  6118. * @param {PhysicsState} boxState
  6119. * @type number
  6120. **/
  6121. JSegment.prototype.sqrDistanceLine=function(out, rkLine, rkBox, boxState){
  6122. var orientationCols = boxState.getOrientationCols();
  6123. out.num = 0;
  6124. out.num0 = 0;
  6125. out.num1 = 0;
  6126. out.num2 = 0;
  6127. var kDiff = Vector3DUtil.subtract(rkLine.origin, boxState.position);
  6128. var kPnt = Vector3DUtil.create( Vector3DUtil.dotProduct(kDiff, orientationCols[0]),
  6129. Vector3DUtil.dotProduct(kDiff, orientationCols[1]),
  6130. Vector3DUtil.dotProduct(kDiff, orientationCols[2]),
  6131. 0);
  6132. var kDir = Vector3DUtil.create( Vector3DUtil.dotProduct(rkLine.dir, orientationCols[0]),
  6133. Vector3DUtil.dotProduct(rkLine.dir, orientationCols[1]),
  6134. Vector3DUtil.dotProduct(rkLine.dir, orientationCols[2]),
  6135. 0);
  6136. var kPntArr = kPnt.slice(0);
  6137. var kDirArr = kDir.slice(0);
  6138. var bReflect = [1,1,1,0];
  6139. for (var i = 0; i < 3; i++){
  6140. if (kDirArr[i] < 0){
  6141. kPntArr[i] = -kPntArr[i];
  6142. kDirArr[i] = -kDirArr[i];
  6143. bReflect[i] = true;
  6144. }else{
  6145. bReflect[i] = false;
  6146. }
  6147. }
  6148. JNumber3D.copyFromArray(kPnt, kPntArr);
  6149. JNumber3D.copyFromArray(kDir, kDirArr);
  6150. var obj = {};
  6151. obj.rkPnt = kPnt.slice(0);
  6152. obj.pfLParam = 0;
  6153. obj.rfSqrDistance = 0;
  6154. if (kDir[0] > 0){
  6155. if (kDir[1] > 0){
  6156. if (kDir[2] > 0){
  6157. this.caseNoZeros(obj, kDir, rkBox);
  6158. out.num = obj.pfLParam;
  6159. }else{
  6160. this.case0(obj, 0, 1, 2, kDir, rkBox);
  6161. out.num = obj.pfLParam;
  6162. }
  6163. }else{
  6164. if (kDir[2] > 0){
  6165. this.case0(obj, 0, 2, 1, kDir, rkBox);
  6166. out.num = obj.pfLParam;
  6167. }else{
  6168. this.case00(obj, 0, 1, 2, kDir, rkBox);
  6169. out.num = obj.pfLParam;
  6170. }
  6171. }
  6172. }else{
  6173. if (kDir[1] > 0){
  6174. if (kDir[2] > 0){
  6175. this.case0(obj, 1, 2, 0, kDir, rkBox);
  6176. out.num = obj.pfLParam;
  6177. }else{
  6178. this.case00(obj, 1, 0, 2, kDir, rkBox);
  6179. out.num = obj.pfLParam;
  6180. }
  6181. }else{
  6182. if (kDir[2] > 0){
  6183. this.case00(obj, 2, 0, 1, kDir, rkBox);
  6184. out.num = obj.pfLParam;
  6185. }else{
  6186. this.case000(obj, rkBox);
  6187. out.num = 0;
  6188. }
  6189. }
  6190. }
  6191. kPntArr = obj.rkPnt.slice(0);
  6192. for (i = 0; i < 3; i++){
  6193. if (bReflect[i]) kPntArr[i] = -kPntArr[i];
  6194. }
  6195. JNumber3D.copyFromArray(obj.rkPnt, kPntArr);
  6196. out.num0 = obj.rkPnt[0];
  6197. out.num1 = obj.rkPnt[1];
  6198. out.num2 = obj.rkPnt[2];
  6199. return Math.max(obj.rfSqrDistance, 0);
  6200. };
  6201. /**
  6202. * @function sqrDistancePoint
  6203. * @param {object} out
  6204. * @param {array} rkPoint
  6205. * @param {JBox} rkBox
  6206. * @param {PhysicsState} boxState
  6207. * @type number
  6208. **/
  6209. JSegment.prototype.sqrDistancePoint=function(out, rkPoint, rkBox, boxState){
  6210. var orientationVector = boxState.getOrientationCols();
  6211. var kDiff = Vector3DUtil.subtract(rkPoint, boxState.position);
  6212. var kClosest = Vector3DUtil.create( Vector3DUtil.dotProduct(kDiff, orientationVector[0]),
  6213. Vector3DUtil.dotProduct(kDiff, orientationVector[1]),
  6214. Vector3DUtil.dotProduct(kDiff, orientationVector[2]),
  6215. 0);
  6216. var fSqrDistance = 0;
  6217. var fDelta;
  6218. var boxHalfSide = rkBox.getHalfSideLengths();
  6219. if (kClosest[0] < -boxHalfSide[0]){
  6220. fDelta = kClosest[0] + boxHalfSide[0];
  6221. fSqrDistance += (fDelta * fDelta);
  6222. kClosest[0] = -boxHalfSide[0];
  6223. }else if (kClosest[0] > boxHalfSide[0]){
  6224. fDelta = kClosest[0] - boxHalfSide[0];
  6225. fSqrDistance += (fDelta * fDelta);
  6226. kClosest[0] = boxHalfSide[0];
  6227. }
  6228. if (kClosest[1] < -boxHalfSide[1]){
  6229. fDelta = kClosest[1] + boxHalfSide[1];
  6230. fSqrDistance += (fDelta * fDelta);
  6231. kClosest[1] = -boxHalfSide[1];
  6232. }else if (kClosest[1] > boxHalfSide[1]){
  6233. fDelta = kClosest[1] - boxHalfSide[1];
  6234. fSqrDistance += (fDelta * fDelta);
  6235. kClosest[1] = boxHalfSide[1];
  6236. }
  6237. if (kClosest[2] < -boxHalfSide[2]){
  6238. fDelta = kClosest[2] + boxHalfSide[2];
  6239. fSqrDistance += (fDelta * fDelta);
  6240. kClosest[2] = -boxHalfSide[2];
  6241. }else if (kClosest[2] > boxHalfSide[2]){
  6242. fDelta = kClosest[2] - boxHalfSide[2];
  6243. fSqrDistance += (fDelta * fDelta);
  6244. kClosest[2] = boxHalfSide[2];
  6245. }
  6246. out.pfLParam0 = kClosest[0];
  6247. out.pfLParam1 = kClosest[1];
  6248. out.pfLParam2 = kClosest[2];
  6249. return Math.max(fSqrDistance, 0);
  6250. };
  6251. /**
  6252. * @function face
  6253. * @param {object} out
  6254. * @param {number} i0
  6255. * @param {number} i1
  6256. * @param {number} i2
  6257. * @param {array} rkDir
  6258. * @param {JBox} rkBox
  6259. * @param {array} rkPmE
  6260. * @type void
  6261. **/
  6262. JSegment.prototype.face=function(out, i0, i1, i2, rkDir, rkBox, rkPmE){
  6263. var kPpE = [0,0,0,0];
  6264. var fLSqr;
  6265. var fInv;
  6266. var fTmp;
  6267. var fParam;
  6268. var fT;
  6269. var fDelta;
  6270. var boxHalfSide = rkBox.getHalfSideLengths();
  6271. var boxHalfArr = boxHalfSide;
  6272. var rkPntArr = out.rkPnt;
  6273. var rkDirArr = rkDir;
  6274. var kPpEArr = kPpE;
  6275. var rkPmEArr = rkPmE;
  6276. kPpEArr[i1] = rkPntArr[i1] + boxHalfArr[i1];
  6277. kPpEArr[i2] = rkPntArr[i2] + boxHalfArr[i2];
  6278. JNumber3D.copyFromArray(rkPmE, kPpEArr);
  6279. if (rkDirArr[i0] * kPpEArr[i1] >= rkDirArr[i1] * rkPmEArr[i0]){
  6280. if (rkDirArr[i0] * kPpEArr[i2] >= rkDirArr[i2] * rkPmEArr[i0]){
  6281. rkPntArr[i0] = boxHalfArr[i0];
  6282. fInv = 1 / rkDirArr[i0];
  6283. rkPntArr[i1] -= (rkDirArr[i1] * rkPmEArr[i0] * fInv);
  6284. rkPntArr[i2] -= (rkDirArr[i2] * rkPmEArr[i0] * fInv);
  6285. out.pfLParam = -rkPmEArr[i0] * fInv;
  6286. JNumber3D.copyFromArray(out.rkPnt, rkPntArr);
  6287. }else{
  6288. fLSqr = rkDirArr[i0] * rkDirArr[i0] + rkDirArr[i2] * rkDirArr[i2];
  6289. fTmp = fLSqr * kPpEArr[i1] - rkDirArr[i1] * (rkDirArr[i0] * rkPmEArr[i0] + rkDirArr[i2] * kPpEArr[i2]);
  6290. if (fTmp <= 2 * fLSqr * boxHalfArr[i1]){
  6291. fT = fTmp / fLSqr;
  6292. fLSqr += (rkDirArr[i1] * rkDirArr[i1]);
  6293. fTmp = kPpEArr[i1] - fT;
  6294. fDelta = rkDirArr[i0] * rkPmEArr[i0] + rkDirArr[i1] * fTmp + rkDirArr[i2] * kPpEArr[i2];
  6295. fParam = -fDelta / fLSqr;
  6296. out.rfSqrDistance += (rkPmEArr[i0] * rkPmEArr[i0] + fTmp * fTmp + kPpEArr[i2] * kPpEArr[i2] + fDelta * fParam);
  6297. out.pfLParam = fParam;
  6298. rkPntArr[i0] = boxHalfArr[i0];
  6299. rkPntArr[i1] = fT - boxHalfArr[i1];
  6300. rkPntArr[i2] = -boxHalfArr[i2];
  6301. JNumber3D.copyFromArray(out.rkPnt, rkPntArr);
  6302. }else{
  6303. fLSqr += (rkDirArr[i1] * rkDirArr[i1]);
  6304. fDelta = rkDirArr[i0] * rkPmEArr[i0] + rkDirArr[i1] * rkPmEArr[i1] + rkDirArr[i2] * kPpEArr[i2];
  6305. fParam = -fDelta / fLSqr;
  6306. out.rfSqrDistance += (rkPmEArr[i0] * rkPmEArr[i0] + rkPmEArr[i1] * rkPmEArr[i1] + kPpEArr[i2] * kPpEArr[i2] + fDelta * fParam);
  6307. out.pfLParam = fParam;
  6308. rkPntArr[i0] = boxHalfArr[i0];
  6309. rkPntArr[i1] = boxHalfArr[i1];
  6310. rkPntArr[i2] = -boxHalfArr[i2];
  6311. JNumber3D.copyFromArray(out.rkPnt, rkPntArr);
  6312. }
  6313. }
  6314. }else{
  6315. if (rkDirArr[i0] * kPpEArr[i2] >= rkDirArr[i2] * rkPmEArr[i0])
  6316. {
  6317. fLSqr = rkDirArr[i0] * rkDirArr[i0] + rkDirArr[i1] * rkDirArr[i1];
  6318. fTmp = fLSqr * kPpEArr[i2] - rkDirArr[i2] * (rkDirArr[i0] * rkPmEArr[i0] + rkDirArr[i1] * kPpEArr[i1]);
  6319. if (fTmp <= 2 * fLSqr * boxHalfArr[i2]){
  6320. fT = fTmp / fLSqr;
  6321. fLSqr += (rkDirArr[i2] * rkDirArr[i2]);
  6322. fTmp = kPpEArr[i2] - fT;
  6323. fDelta = rkDirArr[i0] * rkPmEArr[i0] + rkDirArr[i1] * kPpEArr[i1] + rkDirArr[i2] * fTmp;
  6324. fParam = -fDelta / fLSqr;
  6325. out.rfSqrDistance += (rkPmEArr[i0] * rkPmEArr[i0] + kPpEArr[i1] * kPpEArr[i1] + fTmp * fTmp + fDelta * fParam);
  6326. out.pfLParam = fParam;
  6327. rkPntArr[i0] = boxHalfArr[i0];
  6328. rkPntArr[i1] = -boxHalfArr[i1];
  6329. rkPntArr[i2] = fT - boxHalfArr[i2];
  6330. JNumber3D.copyFromArray(out.rkPnt, rkPntArr);
  6331. }else{
  6332. fLSqr += (rkDirArr[i2] * rkDirArr[i2]);
  6333. fDelta = rkDirArr[i0] * rkPmEArr[i0] + rkDirArr[i1] * kPpEArr[i1] + rkDirArr[i2] * rkPmEArr[i2];
  6334. fParam = -fDelta / fLSqr;
  6335. out.rfSqrDistance += (rkPmEArr[i0] * rkPmEArr[i0] + kPpEArr[i1] * kPpEArr[i1] + rkPmEArr[i2] * rkPmEArr[i2] + fDelta * fParam);
  6336. out.pfLParam = fParam;
  6337. rkPntArr[i0] = boxHalfArr[i0];
  6338. rkPntArr[i1] = -boxHalfArr[i1];
  6339. rkPntArr[i2] = boxHalfArr[i2];
  6340. JNumber3D.copyFromArray(out.rkPnt, rkPntArr);
  6341. }
  6342. }else{
  6343. fLSqr = rkDirArr[i0] * rkDirArr[i0] + rkDirArr[i2] * rkDirArr[i2];
  6344. fTmp = fLSqr * kPpEArr[i1] - rkDirArr[i1] * (rkDirArr[i0] * rkPmEArr[i0] + rkDirArr[i2] * kPpEArr[i2]);
  6345. if (fTmp >= 0){
  6346. if (fTmp <= 2 * fLSqr * boxHalfArr[i1]){
  6347. fT = fTmp / fLSqr;
  6348. fLSqr += (rkDirArr[i1] * rkDirArr[i1]);
  6349. fTmp = kPpEArr[i1] - fT;
  6350. fDelta = rkDirArr[i0] * rkPmEArr[i0] + rkDirArr[i1] * fTmp + rkDirArr[i2] * kPpEArr[i2];
  6351. fParam = -fDelta / fLSqr;
  6352. out.rfSqrDistance += (rkPmEArr[i0] * rkPmEArr[i0] + fTmp * fTmp + kPpEArr[i2] * kPpEArr[i2] + fDelta * fParam);
  6353. out.pfLParam = fParam;
  6354. rkPntArr[i0] = boxHalfArr[i0];
  6355. rkPntArr[i1] = fT - boxHalfArr[i1];
  6356. rkPntArr[i2] = -boxHalfArr[i2];
  6357. JNumber3D.copyFromArray(out.rkPnt, rkPntArr);
  6358. }else{
  6359. fLSqr += (rkDirArr[i1] * rkDirArr[i1]);
  6360. fDelta = rkDirArr[i0] * rkPmEArr[i0] + rkDirArr[i1] * rkPmEArr[i1] + rkDirArr[i2] * kPpEArr[i2];
  6361. fParam = -fDelta / fLSqr;
  6362. out.rfSqrDistance += (rkPmEArr[i0] * rkPmEArr[i0] + rkPmEArr[i1] * rkPmEArr[i1] + kPpEArr[i2] * kPpEArr[i2] + fDelta * fParam);
  6363. out.pfLParam = fParam;
  6364. rkPntArr[i0] = boxHalfArr[i0];
  6365. rkPntArr[i1] = boxHalfArr[i1];
  6366. rkPntArr[i2] = -boxHalfArr[i2];
  6367. JNumber3D.copyFromArray(out.rkPnt, rkPntArr);
  6368. }
  6369. return;
  6370. }
  6371. fLSqr = rkDirArr[i0] * rkDirArr[i0] + rkDirArr[i1] * rkDirArr[i1];
  6372. fTmp = fLSqr * kPpEArr[i2] - rkDirArr[i2] * (rkDirArr[i0] * rkPmEArr[i0] + rkDirArr[i1] * kPpEArr[i1]);
  6373. if (fTmp >= 0){
  6374. if (fTmp <= 2 * fLSqr * boxHalfArr[i2]){
  6375. fT = fTmp / fLSqr;
  6376. fLSqr += (rkDirArr[i2] * rkDirArr[i2]);
  6377. fTmp = kPpEArr[i2] - fT;
  6378. fDelta = rkDirArr[i0] * rkPmEArr[i0] + rkDirArr[i1] * kPpEArr[i1] + rkDirArr[i2] * fTmp;
  6379. fParam = -fDelta / fLSqr;
  6380. out.rfSqrDistance += (rkPmEArr[i0] * rkPmEArr[i0] + kPpEArr[i1] * kPpEArr[i1] + fTmp * fTmp + fDelta * fParam);
  6381. out.pfLParam = fParam;
  6382. rkPntArr[i0] = boxHalfArr[i0];
  6383. rkPntArr[i1] = -boxHalfArr[i1];
  6384. rkPntArr[i2] = fT - boxHalfArr[i2];
  6385. JNumber3D.copyFromArray(out.rkPnt, rkPntArr);
  6386. }else{
  6387. fLSqr += (rkDirArr[i2] * rkDirArr[i2]);
  6388. fDelta = rkDirArr[i0] * rkPmEArr[i0] + rkDirArr[i1] * kPpEArr[i1] + rkDirArr[i2] * rkPmEArr[i2];
  6389. fParam = -fDelta / fLSqr;
  6390. out.rfSqrDistance += (rkPmEArr[i0] * rkPmEArr[i0] + kPpEArr[i1] * kPpEArr[i1] + rkPmEArr[i2] * rkPmEArr[i2] + fDelta * fParam);
  6391. out.pfLParam = fParam;
  6392. rkPntArr[i0] = boxHalfArr[i0];
  6393. rkPntArr[i1] = -boxHalfArr[i1];
  6394. rkPntArr[i2] = boxHalfArr[i2];
  6395. JNumber3D.copyFromArray(out.rkPnt, rkPntArr);
  6396. }
  6397. return;
  6398. }
  6399. fLSqr += (rkDirArr[i2] * rkDirArr[i2]);
  6400. fDelta = rkDirArr[i0] * rkPmEArr[i0] + rkDirArr[i1] * kPpEArr[i1] + rkDirArr[i2] * kPpEArr[i2];
  6401. fParam = -fDelta / fLSqr;
  6402. out.rfSqrDistance += (rkPmEArr[i0] * rkPmEArr[i0] + kPpEArr[i1] * kPpEArr[i1] + kPpEArr[i2] * kPpEArr[i2] + fDelta * fParam);
  6403. out.pfLParam = fParam;
  6404. rkPntArr[i0] = boxHalfArr[i0];
  6405. rkPntArr[i1] = -boxHalfArr[i1];
  6406. rkPntArr[i2] = -boxHalfArr[i2];
  6407. JNumber3D.copyFromArray(out.rkPnt, rkPntArr);
  6408. }
  6409. }
  6410. };
  6411. /**
  6412. * @function caseNoZeros
  6413. * @param {object} out
  6414. * @param {array} rkDir
  6415. * @param {JBox} rkBox
  6416. * @type void
  6417. **/
  6418. JSegment.prototype.caseNoZeros=function(out, rkDir, rkBox){
  6419. var boxHalfSide = rkBox.getHalfSideLengths();
  6420. var kPmE = Vector3DUtil.create(out.rkPnt[0] - boxHalfSide[0], out.rkPnt[1] - boxHalfSide[1], out.rkPnt[2] - boxHalfSide[2], 0);
  6421. var fProdDxPy = rkDir[0] * kPmE[1];
  6422. var fProdDyPx = rkDir[1] * kPmE[0];
  6423. var fProdDzPx;
  6424. var fProdDxPz;
  6425. var fProdDzPy;
  6426. var fProdDyPz;
  6427. if (fProdDyPx >= fProdDxPy){
  6428. fProdDzPx = rkDir[2] * kPmE[0];
  6429. fProdDxPz = rkDir[0] * kPmE[2];
  6430. if (fProdDzPx >= fProdDxPz)
  6431. this.face(out, 0, 1, 2, rkDir, rkBox, kPmE);
  6432. else
  6433. this.face(out, 2, 0, 1, rkDir, rkBox, kPmE);
  6434. }else{
  6435. fProdDzPy = rkDir[2] * kPmE[1];
  6436. fProdDyPz = rkDir[1] * kPmE[2];
  6437. if (fProdDzPy >= fProdDyPz)
  6438. this.face(out, 1, 2, 0, rkDir, rkBox, kPmE);
  6439. else
  6440. this.face(out, 2, 0, 1, rkDir, rkBox, kPmE);
  6441. }
  6442. };
  6443. /**
  6444. * @function case0
  6445. * @param {object} out
  6446. * @param {number} i0
  6447. * @param {number} i1
  6448. * @param {number} i2
  6449. * @param {array} rkDir
  6450. * @param {JBox} rkBox
  6451. * @type void
  6452. **/
  6453. JSegment.prototype.case0=function(out, i0, i1, i2, rkDir, rkBox){
  6454. var boxHalfSide = rkBox.getHalfSideLengths();
  6455. var boxHalfArr = boxHalfSide.slice(0);
  6456. var rkPntArr = out.rkPnt.slice(0);
  6457. var rkDirArr = rkDir.slice(0);
  6458. var fPmE0 = rkPntArr[i0] - boxHalfArr[i0];
  6459. var fPmE1 = rkPntArr[i1] - boxHalfArr[i1];
  6460. var fProd0 = rkDirArr[i1] * fPmE0;
  6461. var fProd1 = rkDirArr[i0] * fPmE1;
  6462. var fDelta;
  6463. var fInvLSqr;
  6464. var fInv;
  6465. if (fProd0 >= fProd1){
  6466. rkPntArr[i0] = boxHalfArr[i0];
  6467. var fPpE1 = rkPntArr[i1] + boxHalfArr[i1];
  6468. fDelta = fProd0 - rkDirArr[i0] * fPpE1;
  6469. if (fDelta >= 0){
  6470. fInvLSqr = 1 / (rkDirArr[i0] * rkDirArr[i0] + rkDirArr[i1] * rkDirArr[i1]);
  6471. out.rfSqrDistance += (fDelta * fDelta * fInvLSqr);
  6472. rkPntArr[i1] = -boxHalfArr[i1];
  6473. out.pfLParam = -(rkDirArr[i0] * fPmE0 + rkDirArr[i1] * fPpE1) * fInvLSqr;
  6474. }else{
  6475. fInv = 1 / rkDirArr[i0];
  6476. rkPntArr[i1] -= (fProd0 * fInv);
  6477. out.pfLParam = -fPmE0 * fInv;
  6478. }
  6479. JNumber3D.copyFromArray(out.rkPnt, rkPntArr);
  6480. }else{
  6481. rkPntArr[i1] = boxHalfArr[i1];
  6482. var fPpE0 = rkPntArr[i0] + boxHalfArr[i0];
  6483. fDelta = fProd1 - rkDirArr[i1] * fPpE0;
  6484. if (fDelta >= 0){
  6485. fInvLSqr = 1 / (rkDirArr[i0] * rkDirArr[i0] + rkDirArr[i1] * rkDirArr[i1]);
  6486. out.rfSqrDistance += (fDelta * fDelta * fInvLSqr);
  6487. rkPntArr[i0] = -boxHalfArr[i0];
  6488. out.pfLParam = -(rkDirArr[i0] * fPpE0 + rkDirArr[i1] * fPmE1) * fInvLSqr;
  6489. }else{
  6490. fInv = 1 / rkDirArr[i1];
  6491. rkPntArr[i0] -= (fProd1 * fInv);
  6492. out.pfLParam = -fPmE1 * fInv;
  6493. }
  6494. JNumber3D.copyFromArray(out.rkPnt, rkPntArr);
  6495. }
  6496. if (rkPntArr[i2] < -boxHalfArr[i2]){
  6497. fDelta = rkPntArr[i2] + boxHalfArr[i2];
  6498. out.rfSqrDistance += (fDelta * fDelta);
  6499. rkPntArr[i2] = -boxHalfArr[i2];
  6500. }else if (rkPntArr[i2] > boxHalfArr[i2]){
  6501. fDelta = rkPntArr[i2] - boxHalfArr[i2];
  6502. out.rfSqrDistance += (fDelta * fDelta);
  6503. rkPntArr[i2] = boxHalfArr[i2];
  6504. }
  6505. JNumber3D.copyFromArray(out.rkPnt, rkPntArr);
  6506. };
  6507. /**
  6508. * @function case00
  6509. * @param {object} out
  6510. * @param {number} i0
  6511. * @param {number} i1
  6512. * @param {number} i2
  6513. * @param {array} rkDir
  6514. * @param {JBox} rkBox
  6515. * @type void
  6516. **/
  6517. JSegment.prototype.case00=function(out, i0, i1, i2, rkDir, rkBox){
  6518. var fDelta = 0;
  6519. var boxHalfSide = rkBox.getHalfSideLengths();
  6520. var boxHalfArr = boxHalfSide.slice(0);
  6521. var rkPntArr = out.rkPnt.slice(0);
  6522. var rkDirArr = rkDir.slice(0);
  6523. out.pfLParam = (boxHalfArr[i0] - rkPntArr[i0]) / rkDirArr[i0];
  6524. rkPntArr[i0] = boxHalfArr[i0];
  6525. if (rkPntArr[i1] < -boxHalfArr[i1]){
  6526. fDelta = rkPntArr[i1] + boxHalfArr[i1];
  6527. out.rfSqrDistance += (fDelta * fDelta);
  6528. rkPntArr[i1] = -boxHalfArr[i1];
  6529. }else if (rkPntArr[i1] > boxHalfArr[i1]) {
  6530. fDelta = rkPntArr[i1] - boxHalfArr[i1];
  6531. out.rfSqrDistance += (fDelta * fDelta);
  6532. rkPntArr[i1] = boxHalfArr[i1];
  6533. }
  6534. if (rkPntArr[i2] < -boxHalfArr[i2]){
  6535. fDelta = rkPntArr[i2] + boxHalfArr[i2];
  6536. out.rfSqrDistance += (fDelta * fDelta);
  6537. rkPntArr[i2] = -boxHalfArr[i2];
  6538. }else if (rkPntArr[i2] > boxHalfArr[i2]){
  6539. fDelta = rkPntArr[i2] - boxHalfArr[i2];
  6540. out.rfSqrDistance += (fDelta * fDelta);
  6541. rkPntArr[i2] = boxHalfArr[i2];
  6542. }
  6543. JNumber3D.copyFromArray(out.rkPnt, rkPntArr);
  6544. };
  6545. /**
  6546. * @function case000
  6547. * @param {object} out
  6548. * @param {JBox} rkBox
  6549. * @type void
  6550. **/
  6551. JSegment.prototype.case000=function(out, rkBox){
  6552. var fDelta = 0;
  6553. var boxHalfSide = rkBox.getHalfSideLengths();
  6554. if (out.rkPnt[0] < -boxHalfSide[0]){
  6555. fDelta = out.rkPnt[0] + boxHalfSide[0];
  6556. out.rfSqrDistance += (fDelta * fDelta);
  6557. out.rkPnt[0] = -boxHalfSide[0];
  6558. }else if (out.rkPnt[0] > boxHalfSide[0]){
  6559. fDelta = out.rkPnt[0] - boxHalfSide[0];
  6560. out.rfSqrDistance += (fDelta * fDelta);
  6561. out.rkPnt[0] = boxHalfSide[0];
  6562. }
  6563. if (out.rkPnt[1] < -boxHalfSide[1]){
  6564. fDelta = out.rkPnt[1] + boxHalfSide[1];
  6565. out.rfSqrDistance += (fDelta * fDelta);
  6566. out.rkPnt[1] = -boxHalfSide[1];
  6567. }else if (out.rkPnt[1] > boxHalfSide[1]){
  6568. fDelta = out.rkPnt[1] - boxHalfSide[1];
  6569. out.rfSqrDistance += (fDelta * fDelta);
  6570. out.rkPnt[1] = boxHalfSide[1];
  6571. }
  6572. if (out.rkPnt[2] < -boxHalfSide[2]){
  6573. fDelta = out.rkPnt[2] + boxHalfSide[2];
  6574. out.rfSqrDistance += (fDelta * fDelta);
  6575. out.rkPnt[2] = -boxHalfSide[2];
  6576. }else if (out.rkPnt[2] > boxHalfSide[2]){
  6577. fDelta = out.rkPnt[2] - boxHalfSide[2];
  6578. out.rfSqrDistance += (fDelta * fDelta);
  6579. out.rkPnt[2] = boxHalfSide[2];
  6580. }
  6581. };
  6582. jigLib.JSegment=JSegment;
  6583. })(jigLib);
  6584. /*
  6585. Copyright (c) 2007 Danny Chapman
  6586. http://www.rowlhouse.co.uk
  6587. This software is provided 'as-is', without any express or implied
  6588. warranty. In no event will the authors be held liable for any damages
  6589. arising from the use of this software.
  6590. Permission is granted to anyone to use this software for any purpose,
  6591. including commercial applications, and to alter it and redistribute it
  6592. freely, subject to the following restrictions:
  6593. 1. The origin of this software must not be misrepresented; you must not
  6594. claim that you wrote the original software. If you use this software
  6595. in a product, an acknowledgment in the product documentation would be
  6596. appreciated but is not required.
  6597. 2. Altered source versions must be plainly marked as such, and must not be
  6598. misrepresented as being the original software.
  6599. 3. This notice may not be removed or altered from any source
  6600. distribution.
  6601. */
  6602. (function(jigLib){
  6603. var Vector3DUtil=jigLib.Vector3DUtil;
  6604. var JMatrix3D=jigLib.JMatrix3D;
  6605. var RigidBody=jigLib.RigidBody;
  6606. /**
  6607. * @author Muzer(muzerly@gmail.com)
  6608. *
  6609. * @name JSphere
  6610. * @class JSphere
  6611. * @extends RigidBody
  6612. * @requires Vector3DUtil
  6613. * @requires JMatrix3D
  6614. * @property {string} name
  6615. * @property {number} radius the radius of this JSphere
  6616. * @constructor
  6617. * @param {ISkin3D} skin
  6618. * @param {number} r the radius of the new JSphere
  6619. **/
  6620. var JSphere=function(skin, r){
  6621. this.Super(skin);
  6622. this._type = "SPHERE";
  6623. this._radius = r;
  6624. this._boundingSphere = this._radius;
  6625. this.set_mass(1);
  6626. this.updateBoundingBox();
  6627. };
  6628. jigLib.extend(JSphere,jigLib.RigidBody);
  6629. JSphere.prototype.name=null;
  6630. JSphere.prototype._radius=null;
  6631. /**
  6632. * @function set_radius gets the radius
  6633. * @param {number} r the new radius
  6634. * @type void
  6635. **/
  6636. JSphere.prototype.set_radius=function(r){
  6637. this._radius = r;
  6638. this._boundingSphere = this._radius;
  6639. this.setInertia(this.getInertiaProperties(this.get_mass()));
  6640. this.setActive();
  6641. this.updateBoundingBox();
  6642. };
  6643. /**
  6644. * @function get_radius returns the radius
  6645. * @type void
  6646. **/
  6647. JSphere.prototype.get_radius=function(){
  6648. return this._radius;
  6649. };
  6650. /**
  6651. * @function segmentIntersect
  6652. * @param {object} out
  6653. * @param {JSegment} seg
  6654. * @param {PhysicsState} state
  6655. * @type boolean
  6656. **/
  6657. JSphere.prototype.segmentIntersect=function(out, seg, state){
  6658. out.frac = 0;
  6659. out.position = [0,0,0,0];
  6660. out.normal = [0,0,0,0];
  6661. var frac = 0;
  6662. var r = seg.delta;
  6663. var s = Vector3DUtil.subtract(seg.origin, state.position);
  6664. var radiusSq = this._radius * this._radius;
  6665. var rSq = Vector3DUtil.get_lengthSquared(r);
  6666. if (rSq < radiusSq){
  6667. out.fracOut = 0;
  6668. out.posOut = seg.origin.slice(0);
  6669. out.normalOut = Vector3DUtil.subtract(out.posOut, state.position);
  6670. Vector3DUtil.normalize(out.normalOut);
  6671. return true;
  6672. }
  6673. var sDotr = Vector3DUtil.dotProduct(s, r);
  6674. var sSq = Vector3DUtil.get_lengthSquared(s);
  6675. var sigma = sDotr * sDotr - rSq * (sSq - radiusSq);
  6676. if (sigma < 0){
  6677. return false;
  6678. }
  6679. var sigmaSqrt = Math.sqrt(sigma);
  6680. var lambda1 = (-sDotr - sigmaSqrt) / rSq;
  6681. var lambda2 = (-sDotr + sigmaSqrt) / rSq;
  6682. if (lambda1 > 1 || lambda2 < 0){
  6683. return false;
  6684. }
  6685. frac = Math.max(lambda1, 0);
  6686. out.frac = frac;
  6687. out.position = seg.getPoint(frac);
  6688. out.normal = Vector3DUtil.subtract(out.position, state.position);
  6689. Vector3DUtil.normalize(out.normal);
  6690. return true;
  6691. };
  6692. /**
  6693. * @function getInertiaProperties
  6694. * @param {number} m
  6695. * @type JMatrix3D
  6696. **/
  6697. JSphere.prototype.getInertiaProperties=function(m){
  6698. var Ixx = 0.4 * m * this._radius * this._radius;
  6699. return JMatrix3D.getScaleMatrix(Ixx, Ixx, Ixx);
  6700. };
  6701. /**
  6702. * @function updateBoundingBox updates the bounding box
  6703. * @type void
  6704. **/
  6705. JSphere.prototype.updateBoundingBox=function(){
  6706. this._boundingBox.clear();
  6707. this._boundingBox.addSphere(this);
  6708. };
  6709. jigLib.JSphere=JSphere;
  6710. })(jigLib);(function(jigLib){
  6711. var Vector3DUtil=jigLib.Vector3DUtil;
  6712. var JNumber3D=jigLib.JNumber3D;
  6713. var RigidBody=jigLib.RigidBody;
  6714. /**
  6715. * @author Muzer(muzerly@gmail.com)
  6716. *
  6717. * @name JTerrain
  6718. * @class JTerrain
  6719. * @extends RigidBody
  6720. * @requires Vector3DUtil
  6721. * @requires JNumber3D
  6722. * @property {object} _terrain the terrain mesh
  6723. * @constructor
  6724. * @param {object} tr the terrain mesh
  6725. * TODO: in JigLibFlash the terrain mesh is of type ITerrain - this needs re-implementing somehow?!?
  6726. **/
  6727. var JTerrain=function(tr){
  6728. this.Super(null);
  6729. this._terrain = tr;
  6730. this.set_movable(false);
  6731. this._type = "TERRAIN";
  6732. };
  6733. jigLib.extend(JTerrain,jigLib.RigidBody);
  6734. JTerrain.prototype._terrain=null;
  6735. /**
  6736. * @function get_terrainMesh gets the mesh
  6737. * @type object
  6738. **/
  6739. JTerrain.prototype.get_terrainMesh=function(){
  6740. return this._terrain;
  6741. };
  6742. /**
  6743. * @function getHeightByIndex
  6744. * @type number
  6745. **/
  6746. JTerrain.prototype.getHeightByIndex=function(i, j){
  6747. i = this.limiteInt(i, 0, _terrain.get_sw());
  6748. j = this.limiteInt(j, 0, _terrain.get_sh());
  6749. return _terrain.get_heights(i,j);
  6750. };
  6751. /**
  6752. * @function getHeightAndNormalByPoint
  6753. * @param {array} point
  6754. * @type object
  6755. **/
  6756. JTerrain.prototype.getHeightAndNormalByPoint=function(point){
  6757. var w = this.limiteInt(point[0], this._terrain.get_minW(), this._terrain.get_maxW());
  6758. var h = this.limiteInt(point[2], this._terrain.get_minH(), this._terrain.get_maxH());
  6759. var i0 = ((w - this._terrain.get_minW()) / this._terrain.get_dw())|0;
  6760. var j0 = ((h - this._terrain.get_minH()) / this._terrain.get_dh())|0;
  6761. i0 = this.limiteInt(i0, 0, this._terrain.get_sw());
  6762. j0 = this.limiteInt(j0, 0, this._terrain.get_sh());
  6763. var i1 = i0 + 1;
  6764. var j1 = j0 + 1;
  6765. i1 = this.limiteInt(i1, 0, this._terrain.get_sw());
  6766. j1 = this.limiteInt(j1, 0, this._terrain.get_sh());
  6767. var iFrac = 1 - (w - (i0 * this._terrain.get_dw() + this._terrain.get_minW())) / this._terrain.get_dw();
  6768. var jFrac = (h - (j0 * this._terrain.get_dh() + this._terrain.get_minH())) / this._terrain.get_dh();
  6769. iFrac = JNumber3D.getLimiteNumber(iFrac, 0, 1);
  6770. jFrac = JNumber3D.getLimiteNumber(jFrac, 0, 1);
  6771. var h00 = this._terrain.get_heights(i0,j0);
  6772. var h01 = this._terrain.get_heights(i0,j1);
  6773. var h10 = this._terrain.get_heights(i1,j0);
  6774. var h11 = this._terrain.get_heights(i1,j1);
  6775. var obj = { };
  6776. obj.height = 0;
  6777. obj.normal = [0,0,0,0];
  6778. var plane;
  6779. if (iFrac < jFrac || i0==i1 || j0 == j1){
  6780. obj.normal = Vector3DUtil.crossProduct( [0, h11 - h10, this._terrain.get_dh(), 0],
  6781. [this._terrain.get_dw(), h11 - h01, 0, 0]);
  6782. Vector3DUtil.normalize(obj.normal);
  6783. plane = new PlaneData([(i1 * this._terrain.get_dw() + this._terrain.get_minW()), h11, (j1 * this._terrain.get_dh() + this._terrain.get_minH()), 0],
  6784. obj.normal);
  6785. obj.height = plane.pointPlaneDistance(point);
  6786. }else{
  6787. obj.normal = Vector3DUtil.crossProduct( [0, h01 - h00, this._terrain.get_dh(), 0],
  6788. [this._terrain.get_dw(), h10 - h00, 0, 0]);
  6789. Vector3DUtil.normalize(obj.normal);
  6790. plane = new PlaneData([(i0 * this._terrain.get_dw() + this._terrain.get_minW()), h00, (j0 * this._terrain.get_dh() + this._terrain.get_minH()), 0],
  6791. obj.normal);
  6792. obj.height = plane.pointPlaneDistance(point);
  6793. }
  6794. return obj;
  6795. };
  6796. /**
  6797. * @function getHeightByPoint
  6798. * @param {array} point
  6799. * @type number
  6800. **/
  6801. JTerrain.prototype.getHeightByPoint=function(point){
  6802. return this.getHeightAndNormalByPoint(point).height;
  6803. };
  6804. /**
  6805. * @function getNormalByPoint
  6806. * @param {array} point
  6807. * @type array
  6808. **/
  6809. JTerrain.prototype.getNormalByPoint=function(point){
  6810. return this.getHeightAndNormalByPoint(point).normal;
  6811. };
  6812. /**
  6813. * @function getSurfacePosByPoint
  6814. * @param {array} point
  6815. * @type array
  6816. **/
  6817. JTerrain.prototype.getSurfacePosByPoint=function(point){
  6818. return [point[0], this.getHeightAndNormalByPoint(point).height, point[2], 0];
  6819. };
  6820. /**
  6821. * @function segmentIntersect
  6822. * @param {object} out
  6823. * @param {JSegment} seg
  6824. * @param {PhysicsState} state
  6825. * @type array
  6826. **/
  6827. JTerrain.prototype.segmentIntersect=function(out, seg, state){
  6828. out.fracOut = 0;
  6829. out.posOut = [0,0,0,0];
  6830. out.normalOut = [0,0,0,0];
  6831. if (seg.delta[1] > -JNumber3D.NUM_TINY)
  6832. return false;
  6833. var obj1 = this.getHeightAndNormalByPoint(seg.origin);
  6834. if (obj1.height < 0)
  6835. return false;
  6836. var obj2 = getHeightAndNormalByPoint(seg.getEnd());
  6837. if (obj2.height > 0)
  6838. return false;
  6839. var depthEnd = -obj2.height;
  6840. var weightStart = 1 / (JNumber3D.NUM_TINY + obj1.height);
  6841. var weightEnd = 1 / (JNumber3D.NUM_TINY + obj2.height);
  6842. Vector3DUtil.scaleBy(obj1.normal, weightStart);
  6843. Vector3DUtil.scaleBy(obj2.normal, weightEnd);
  6844. out.normalOut = Vector3DUtil.add(obj1.normal, obj2.normal);
  6845. Vector3DUtil.scaleBy(out.normalOut, 1 / (weightStart + weightEnd));
  6846. out.fracOut = obj1.height / (obj1.height + depthEnd + JNumber3D.NUM_TINY);
  6847. out.posOut = seg.getPoint(out.fracOut);
  6848. return true;
  6849. };
  6850. /**
  6851. * @function limiteInt
  6852. * @param {number} num
  6853. * @param {number} min
  6854. * @param {number} max
  6855. * @type array
  6856. **/
  6857. JTerrain.prototype.limiteInt=function(num,min,max){
  6858. var n = num;
  6859. if (n < min){
  6860. n = min;
  6861. }else if (n > max){
  6862. n = max;
  6863. }
  6864. return n;
  6865. };
  6866. jigLib.JTerrain=JTerrain;
  6867. })(jigLib);(function(jigLib){
  6868. var Vector3DUtil=jigLib.Vector3DUtil;
  6869. var JNumber3D=jigLib.JNumber3D;
  6870. var PlaneData=jigLib.PlaneData;
  6871. var JAABox=jigLib.JAABox;
  6872. /// Support for an indexed triangle - assumes ownership by something that
  6873. /// has an array of vertices and an array of tIndexedTriangle
  6874. var JIndexedTriangle=function(){
  6875. counter = 0;
  6876. this._vertexIndices = [];
  6877. this._vertexIndices[0] = -1;
  6878. this._vertexIndices[1] = -1;
  6879. this._vertexIndices[2] = -1;
  6880. this._plane = new PlaneData();
  6881. this._boundingBox = new JAABox();
  6882. };
  6883. JIndexedTriangle.prototype.counter=0;
  6884. /// Set the indices into the relevant vertex array for this triangle. Also sets the plane and bounding box
  6885. JIndexedTriangle.prototype.setVertexIndices=function(i0, i1, i2, vertexArray){
  6886. this._vertexIndices[0] = i0;
  6887. this._vertexIndices[1] = i1;
  6888. this._vertexIndices[2] = i2;
  6889. this._plane.setWithPoint(vertexArray[i0], vertexArray[i1], vertexArray[i2]);
  6890. this._boundingBox.clear();
  6891. this._boundingBox.addPoint(vertexArray[i0]);
  6892. this._boundingBox.addPoint(vertexArray[i1]);
  6893. this._boundingBox.addPoint(vertexArray[i2]);
  6894. };
  6895. JIndexedTriangle.prototype.updateVertexIndices=function(vertexArray){
  6896. var i0,i1,i2;
  6897. i0=this._vertexIndices[0];
  6898. i1=this._vertexIndices[1];
  6899. i2=this._vertexIndices[2];
  6900. this._plane.setWithPoint(vertexArray[i0], vertexArray[i1], vertexArray[i2]);
  6901. this._boundingBox.clear();
  6902. this._boundingBox.addPoint(vertexArray[i0]);
  6903. this._boundingBox.addPoint(vertexArray[i1]);
  6904. this._boundingBox.addPoint(vertexArray[i2]);
  6905. };
  6906. // Get the indices into the relevant vertex array for this triangle.
  6907. JIndexedTriangle.prototype.get_vertexIndices=function(){
  6908. return this._vertexIndices;
  6909. };
  6910. // Get the vertex index association with iCorner (which should be 0, 1 or 2)
  6911. JIndexedTriangle.prototype.getVertexIndex=function(iCorner){
  6912. return this._vertexIndices[iCorner];
  6913. };
  6914. // Get the triangle plane
  6915. JIndexedTriangle.prototype.get_plane=function(){
  6916. return this._plane;
  6917. };
  6918. JIndexedTriangle.prototype.get_boundingBox=function(){
  6919. return this._boundingBox;
  6920. };
  6921. jigLib.JIndexedTriangle=JIndexedTriangle;
  6922. })(jigLib);
  6923. (function(jigLib){
  6924. var Vector3DUtil=jigLib.Vector3DUtil;
  6925. var JNumber3D=jigLib.JNumber3D;
  6926. var CollOutData=jigLib.CollOutData;
  6927. var PlaneData=jigLib.PlaneData;
  6928. var SpanData=jigLib.SpanData;
  6929. // Defines a 3d triangle. Each edge goes from the origin. Cross(edge0, edge1) gives the triangle normal.
  6930. // Points specified so that pt1-pt0 is edge0 and p2-pt0 is edge1
  6931. var JTriangle=function(pt0, pt1, pt2){
  6932. this.origin = pt0.slice(0);
  6933. this.edge0 = Vector3DUtil.subtract(pt1,pt0);
  6934. this.edge1 = Vector3DUtil.subtract(pt2,pt0);
  6935. };
  6936. // Edge2 goes from pt1 to pt2
  6937. JTriangle.prototype.get_edge2=function() {
  6938. return Vector3DUtil.subtract(this.edge1,this.edge0);
  6939. };
  6940. // Gets the triangle normal.
  6941. JTriangle.prototype.get_normal=function(){
  6942. var N = Vector3DUtil.crossProduct(this.edge0,this.edge1);
  6943. Vector3DUtil.normalize(N);
  6944. return N;
  6945. };
  6946. // Gets the plane containing the triangle
  6947. JTriangle.prototype.get_plane=function(){
  6948. var pl = new PlaneData();
  6949. pl.setWithNormal(this.origin, this.get_normal());
  6950. return pl;
  6951. };
  6952. // Returns the point parameterised by t0 and t1
  6953. JTriangle.prototype.getPoint=function(t0, t1) {
  6954. var d0,d1;
  6955. d0 = this.edge0.slice(0);
  6956. d1 = this.edge1.slice(0);
  6957. Vector3DUtil.scaleBy(d0,t0);
  6958. Vector3DUtil.scaleBy(d1,t1);
  6959. return Vector3DUtil.add(Vector3DUtil.add(this.origin,d0),d1);
  6960. };
  6961. JTriangle.prototype.getCentre=function() {
  6962. var result = Vector3DUtil.add(this.edge0,this.edge1);
  6963. Vector3DUtil.scaleBy(result,0.333333);
  6964. return Vector3DUtil.add(this.origin,result);
  6965. };
  6966. // Same numbering as in the constructor
  6967. JTriangle.prototype.getVertex=function(_id){
  6968. switch(_id) {
  6969. case 1:
  6970. return Vector3DUtil.add(this.origin,this.edge0);
  6971. case 2:
  6972. return Vector3DUtil.add(this.origin,this.edge1);
  6973. default:
  6974. return this.origin;
  6975. }
  6976. };
  6977. JTriangle.prototype.getSpan=function(axis) {
  6978. var d0,d1,d2;
  6979. d0 = Vector3DUtil.dotProduct(this.getVertex(0),axis);
  6980. d1 = Vector3DUtil.dotProduct(this.getVertex(1),axis);
  6981. d2 = Vector3DUtil.dotProduct(this.getVertex(2),axis);
  6982. var result = new SpanData();
  6983. result.min = Math.min(d0, d1, d2);
  6984. result.max = Math.max(d0, d1, d2);
  6985. return result;
  6986. };
  6987. JTriangle.prototype.segmentTriangleIntersection=function(out, seg){
  6988. var u,v,t,a,f;
  6989. var p,s,q;
  6990. p = Vector3DUtil.crossProduct(seg.delta,this.edge1);
  6991. a =Vector3DUtil.dotProduct(this.edge0,p);
  6992. if (a > -JNumber3D.NUM_TINY && a < JNumber3D.NUM_TINY) {
  6993. return false;
  6994. }
  6995. f = 1 / a;
  6996. s = Vector3DUtil.subtract(seg.origin,this.origin);
  6997. u = f * Vector3DUtil.dotProduct(s,p);
  6998. if (u < 0 || u > 1) return false;
  6999. q = Vector3DUtil.crossProduct(s,this.edge0);
  7000. v = f * Vector3DUtil.dotProduct(seg.delta,q);
  7001. if (v < 0 || (u + v) > 1) return false;
  7002. t = f * Vector3DUtil.dotProduct(this.edge1,q);
  7003. if (t < 0 || t > 1) return false;
  7004. if (out) out.frac = t;
  7005. return true;
  7006. }
  7007. JTriangle.prototype.pointTriangleDistanceSq=function(out, point){
  7008. var fA00,fA01,fA11,fB0,fB1,fC,fDet,fS,fT,fSqrDist;
  7009. var kDiff = Vector3DUtil.subtract(this.origin,point);
  7010. fA00 = Vector3DUtil.get_lengthSquared(this.edge0);
  7011. fA01 = Vector3DUtil.dotProduct(this.edge0,this.edge1);
  7012. fA11 = Vector3DUtil.get_lengthSquared(this.edge1);
  7013. fB0 = Vector3DUtil.dotProduct(kDiff,this.edge0);
  7014. fB1 = Vector3DUtil.dotProduct(kDiff,this.edge1);
  7015. fC = Vector3DUtil.get_lengthSquared(kDiff);
  7016. fDet = Math.abs(fA00 * fA11 - fA01 * fA01);
  7017. fS = fA01 * fB1 - fA11 * fB0;
  7018. fT = fA01 * fB0 - fA00 * fB1;
  7019. if ( fS + fT <= fDet ){
  7020. if ( fS < 0 ){
  7021. if ( fT < 0 ){ // region 4
  7022. if ( fB0 < 0 ){
  7023. fT = 0;
  7024. if ( -fB0 >= fA00 ){
  7025. fS = 1;
  7026. fSqrDist = fA00+2*fB0+fC;
  7027. }else{
  7028. fS = -fB0/fA00;
  7029. fSqrDist = fB0*fS+fC;
  7030. }
  7031. }else{
  7032. fS = 0;
  7033. if ( fB1 >= 0 ){
  7034. fT = 0;
  7035. fSqrDist = fC;
  7036. }else if ( -fB1 >= fA11 ){
  7037. fT = 1;
  7038. fSqrDist = fA11+2*fB1+fC;
  7039. }else{
  7040. fT = -fB1/fA11;
  7041. fSqrDist = fB1*fT+fC;
  7042. }
  7043. }
  7044. }else{ // region 3
  7045. fS = 0;
  7046. if ( fB1 >= 0 ){
  7047. fT = 0;
  7048. fSqrDist = fC;
  7049. }else if ( -fB1 >= fA11 ){
  7050. fT = 1;
  7051. fSqrDist = fA11+2*fB1+fC;
  7052. }else{
  7053. fT = -fB1/fA11;
  7054. fSqrDist = fB1*fT+fC;
  7055. }
  7056. }
  7057. }else if ( fT < 0 ){ // region 5
  7058. fT = 0;
  7059. if ( fB0 >= 0 ){
  7060. fS = 0;
  7061. fSqrDist = fC;
  7062. }else if ( -fB0 >= fA00 ){
  7063. fS = 1;
  7064. fSqrDist = fA00+2*fB0+fC;
  7065. }else{
  7066. fS = -fB0/fA00;
  7067. fSqrDist = fB0*fS+fC;
  7068. }
  7069. }else{ // region 0
  7070. // minimum at interior point
  7071. var fInvDet = 1/fDet;
  7072. fS *= fInvDet;
  7073. fT *= fInvDet;
  7074. fSqrDist = fS * (fA00 * fS + fA01 * fT + 2 * fB0) +fT * (fA01 * fS + fA11 * fT + 2 * fB1) + fC;
  7075. }
  7076. }else{
  7077. var fTmp0,fTmp1,fNumer,fDenom;
  7078. if ( fS < 0 ){ // region 2
  7079. fTmp0 = fA01 + fB0;
  7080. fTmp1 = fA11 + fB1;
  7081. if ( fTmp1 > fTmp0 ){
  7082. fNumer = fTmp1 - fTmp0;
  7083. fDenom = fA00-2*fA01+fA11;
  7084. if ( fNumer >= fDenom ){
  7085. fS = 1;
  7086. fT = 0;
  7087. fSqrDist = fA00+2*fB0+fC;
  7088. }else{
  7089. fS = fNumer/fDenom;
  7090. fT = 1 - fS;
  7091. fSqrDist = fS * (fA00 * fS + fA01 * fT + 2 * fB0) +fT * (fA01 * fS + fA11 * fT + 2 * fB1) + fC;
  7092. }
  7093. }else{
  7094. fS = 0;
  7095. if ( fTmp1 <= 0 ){
  7096. fT = 1;
  7097. fSqrDist = fA11+2*fB1+fC;
  7098. }else if ( fB1 >= 0 ){
  7099. fT = 0;
  7100. fSqrDist = fC;
  7101. }else {
  7102. fT = -fB1/fA11;
  7103. fSqrDist = fB1*fT+fC;
  7104. }
  7105. }
  7106. }else if ( fT < 0 ) { // region 6
  7107. fTmp0 = fA01 + fB1;
  7108. fTmp1 = fA00 + fB0;
  7109. if ( fTmp1 > fTmp0 ){
  7110. fNumer = fTmp1 - fTmp0;
  7111. fDenom = fA00-2*fA01+fA11;
  7112. if ( fNumer >= fDenom ){
  7113. fT = 1;
  7114. fS = 0;
  7115. fSqrDist = fA11+2*fB1+fC;
  7116. }else{
  7117. fT = fNumer/fDenom;
  7118. fS = 1 - fT;
  7119. fSqrDist = fS * (fA00 * fS + fA01 * fT + 2 * fB0) +fT * (fA01 * fS + fA11 * fT + 2 * fB1) + fC;
  7120. }
  7121. }else{
  7122. fT = 0;
  7123. if ( fTmp1 <= 0 ){
  7124. fS = 1;
  7125. fSqrDist = fA00+2*fB0+fC;
  7126. }else if ( fB0 >= 0 ){
  7127. fS = 0;
  7128. fSqrDist = fC;
  7129. }else{
  7130. fS = -fB0/fA00;
  7131. fSqrDist = fB0*fS+fC;
  7132. }
  7133. }
  7134. }else{ // region 1
  7135. fNumer = fA11 + fB1 - fA01 - fB0;
  7136. if ( fNumer <= 0 ){
  7137. fS = 0;
  7138. fT = 1;
  7139. fSqrDist = fA11+2*fB1+fC;
  7140. }else{
  7141. fDenom = fA00-2*fA01+fA11;
  7142. if ( fNumer >= fDenom ){
  7143. fS = 1;
  7144. fT = 0;
  7145. fSqrDist = fA00 + 2 * fB0 + fC;
  7146. }else{
  7147. fS = fNumer/fDenom;
  7148. fT = 1 - fS;
  7149. fSqrDist = fS * (fA00 * fS + fA01 * fT + 2 * fB0) +fT * (fA01 * fS + fA11 * fT + 2 * fB1) + fC;
  7150. }
  7151. }
  7152. }
  7153. }
  7154. out[0] = fS;
  7155. out[1] = fT;
  7156. return Math.abs(fSqrDist);
  7157. }
  7158. jigLib.JTriangle=JTriangle;
  7159. })(jigLib); (function(jigLib){
  7160. var Vector3DUtil=jigLib.Vector3DUtil;
  7161. var JNumber3D=jigLib.JNumber3D;
  7162. var EdgeData=jigLib.EdgeData;
  7163. var JIndexedTriangle=jigLib.JIndexedTriangle;
  7164. var JTriangle=jigLib.JTriangle;
  7165. var JSegment=jigLib.JSegment;
  7166. var OctreeCell=jigLib.OctreeCell;
  7167. var TriangleVertexIndices=jigLib.TriangleVertexIndices;
  7168. var JAABox=jigLib.JAABox;
  7169. var JOctree=function(){
  7170. this._testCounter = 0;
  7171. this._cells = [];
  7172. this._vertices = [];
  7173. this._triangles = [];
  7174. this._cellsToTest = [];
  7175. this._boundingBox = new JAABox();
  7176. };
  7177. JOctree.prototype.get_trianglesData=function(){
  7178. return this._triangles;
  7179. };
  7180. JOctree.prototype.getTriangle=function(iTriangle) {
  7181. return this._triangles[iTriangle];
  7182. };
  7183. JOctree.prototype.get_verticesData=function(){
  7184. return this._vertices;
  7185. };
  7186. JOctree.prototype.getVertex=function(iVertex){
  7187. return this._vertices[iVertex];
  7188. };
  7189. JOctree.prototype.boundingBox=function(){
  7190. return this._boundingBox;
  7191. };
  7192. JOctree.prototype.clear=function(){
  7193. this._cells=[];
  7194. this._vertices=[];
  7195. this._triangles=[];
  7196. }
  7197. // Add the triangles - doesn't actually build the octree
  7198. JOctree.prototype.addTriangles=function(vertices, numVertices, triangleVertexIndices, numTriangles){
  7199. this.clear();
  7200. this._vertices=vertices.slice(0);
  7201. var NLen,tiny=JNumber3D.NUM_TINY;
  7202. var i0,i1,i2;
  7203. var dr1,dr2,N;
  7204. var indexedTriangle;
  7205. for(var i=0;i<triangleVertexIndices.length;i++){
  7206. var tri=triangleVertexIndices[i];
  7207. var i0 = triangleVertexIndices[i][0];
  7208. var i1 = triangleVertexIndices[i][1];
  7209. var i2 = triangleVertexIndices[i][2];
  7210. dr1 = Vector3DUtil.subtract(vertices[i1],vertices[i0]);
  7211. dr2 = Vector3DUtil.subtract(vertices[i2],vertices[i0]);
  7212. N = Vector3DUtil.crossProduct(dr1,dr2);
  7213. NLen = Vector3DUtil.get_length(N);
  7214. if (NLen > tiny){
  7215. indexedTriangle = new JIndexedTriangle();
  7216. indexedTriangle.setVertexIndices(i0, i1, i2, this._vertices);
  7217. this._triangles.push(indexedTriangle);
  7218. }
  7219. }
  7220. }
  7221. /* Builds the octree from scratch (not incrementally) - deleting
  7222. any previous tree. Building the octree will involve placing
  7223. all triangles into the root cell. Then this cell gets pushed
  7224. onto a stack of cells to examine. This stack will get parsed
  7225. and every cell containing more than maxTrianglesPerCell will
  7226. get split into 8 children, and all the original triangles in
  7227. that cell will get partitioned between the children. A
  7228. triangle can end up in multiple cells (possibly a lot!) if it
  7229. straddles a boundary. Therefore when intersection tests are
  7230. done tIndexedTriangle::m_counter can be set/tested using a
  7231. counter to avoid properly testing the triangle multiple times
  7232. (the counter _might_ wrap around, so when it wraps ALL the
  7233. triangle flags should be cleared! Could do this
  7234. incrementally...).*/
  7235. JOctree.prototype.buildOctree=function(maxTrianglesPerCell, minCellSize){
  7236. this._boundingBox.clear();
  7237. for(var i=0;i<this._vertices.length;i++){
  7238. var vt=this._vertices[i];
  7239. this._boundingBox.addPoint(vt);
  7240. }
  7241. this._cells=[];
  7242. this._cells.push(new OctreeCell(this._boundingBox));
  7243. var numTriangles = this._triangles.length;
  7244. for (var i = 0; i < numTriangles; i++ ) {
  7245. this._cells[0].triangleIndices[i] = i;
  7246. }
  7247. var cellsToProcess = [];
  7248. cellsToProcess.push(0);
  7249. var iTri;
  7250. var cellIndex;
  7251. var childCell;
  7252. while (cellsToProcess.length != 0) {
  7253. cellIndex = cellsToProcess.pop();
  7254. if (this._cells[cellIndex].triangleIndices.length <= maxTrianglesPerCell || this._cells[cellIndex].AABox.getRadiusAboutCentre() < minCellSize) {
  7255. continue;
  7256. }
  7257. for (var i = 0; i < OctreeCell.NUM_CHILDREN; i++ ) {
  7258. this._cells[cellIndex].childCellIndices[i] = this._cells.length;
  7259. cellsToProcess.push(this._cells.length);
  7260. this._cells.push(new OctreeCell(this.createAABox(this._cells[cellIndex].AABox, i)));
  7261. childCell = this._cells[this._cells.length - 1];
  7262. numTriangles = this._cells[cellIndex].triangleIndices.length;
  7263. for (var j=0; j < numTriangles; j++ ) {
  7264. iTri = this._cells[cellIndex].triangleIndices[j];
  7265. if (this.doesTriangleIntersectCell(this._triangles[iTri], childCell)){
  7266. childCell.triangleIndices.push(iTri);
  7267. }
  7268. }
  7269. }
  7270. this._cells[cellIndex].triangleIndices=[];
  7271. }
  7272. }
  7273. JOctree.prototype.updateTriangles=function(vertices){
  7274. //this._vertices.concat(vertices);
  7275. this._vertices=vertices.slice(0);
  7276. for(var i=0;i<this._triangles.length;i++){
  7277. var triangle=this._triangles[i];
  7278. triangle.updateVertexIndices(this._vertices);
  7279. }
  7280. }
  7281. JOctree.prototype.getTrianglesIntersectingSegment=function(triangles, seg){
  7282. if (this._cells.length == 0) return 0;
  7283. this._cellsToTest=[];
  7284. this._cellsToTest.push(0);
  7285. var cellIndex,nTris,cell,triangle;
  7286. this.incrementTestCounter();
  7287. while (this._cellsToTest.length != 0) {
  7288. cellIndex = this._cellsToTest.pop();
  7289. cell = this._cells[cellIndex];
  7290. if (!cell.AABox.segmentAABoxOverlap(seg)) {
  7291. continue;
  7292. }
  7293. if (cell.isLeaf()) {
  7294. nTris = cell.triangleIndices.length;
  7295. for (var i = 0 ; i < nTris ; i++) {
  7296. triangle = this.getTriangle(cell.triangleIndices[i]);
  7297. if (triangle.counter != this._testCounter) {
  7298. triangle.counter = this._testCounter;
  7299. if (triangle.get_boundingBox().segmentAABoxOverlap(seg)) {
  7300. triangles.push(triangle);
  7301. }
  7302. }
  7303. }
  7304. }else {
  7305. for (var i = 0 ; i < OctreeCell.NUM_CHILDREN ; i++) {
  7306. this._cellsToTest.push(cell.childCellIndices[i]);
  7307. }
  7308. }
  7309. }
  7310. return triangles.length;
  7311. }
  7312. /* Gets a list of all triangle indices that intersect an AABox. The vector passed in resized,
  7313. so if you keep it between calls after a while it won't grow any more, and this
  7314. won't allocate more memory.
  7315. Returns the number of triangles (same as triangles.size())*/
  7316. JOctree.prototype.getTrianglesIntersectingtAABox=function(triangles, aabb){
  7317. if (this._cells.length == 0) return 0;
  7318. this._cellsToTest=[];
  7319. this._cellsToTest.push(0);
  7320. this.incrementTestCounter();
  7321. var cellIndex,nTris,cell,triangle;
  7322. while (this._cellsToTest.length != 0) {
  7323. cellIndex = this._cellsToTest.pop();
  7324. cell = this._cells[cellIndex];
  7325. if (!aabb.overlapTest(cell.AABox)) {
  7326. continue;
  7327. }
  7328. if (cell.isLeaf()) {
  7329. nTris = cell.triangleIndices.length;
  7330. for (var i = 0 ; i < nTris ; i++) {
  7331. triangle = this.getTriangle(cell.triangleIndices[i]);
  7332. if (triangle.counter != this._testCounter) {
  7333. triangle.counter = this._testCounter;
  7334. if (aabb.overlapTest(triangle.get_boundingBox())) {
  7335. triangles.push(cell.triangleIndices[i]);
  7336. }
  7337. }
  7338. }
  7339. }else {
  7340. for (var i = 0 ; i < OctreeCell.NUM_CHILDREN ; i++) {
  7341. this._cellsToTest.push(cell.childCellIndices[i]);
  7342. }
  7343. }
  7344. }
  7345. return triangles.length;
  7346. }
  7347. JOctree.prototype.dumpStats=function(){
  7348. var maxTris = 0,numTris,cellIndex,cell;
  7349. var cellsToProcess = [];
  7350. cellsToProcess.push(0);
  7351. while (cellsToProcess.length != 0) {
  7352. cellIndex = cellsToProcess.pop();
  7353. cell = cell[cellIndex];
  7354. if (cell.isLeaf()) {
  7355. numTris = cell.triangleIndices.length;
  7356. if (numTris > maxTris) {
  7357. maxTris = numTris;
  7358. }
  7359. }else {
  7360. for (var i = 0 ; i < OctreeCell.NUM_CHILDREN ; i++) {
  7361. if ((cell.childCellIndices[i] >= 0) && (cell.childCellIndices[i] < this._cells.length)) {
  7362. cellsToProcess.push(cell.childCellIndices[i]);
  7363. }
  7364. }
  7365. }
  7366. }
  7367. }
  7368. // Create a bounding box appropriate for a child, based on a parents AABox
  7369. JOctree.prototype.createAABox=function(aabb, _id){
  7370. var dims = JNumber3D.getScaleVector(Vector3DUtil.subtract(aabb.get_maxPos(),aabb.get_minPos()), 0.5);
  7371. var offset;
  7372. switch(_id) {
  7373. case 0:
  7374. offset = [1, 1, 1];
  7375. break;
  7376. case 1:
  7377. offset = [1, 1, 0];
  7378. break;
  7379. case 2:
  7380. offset = [1, 0, 1];
  7381. break;
  7382. case 3:
  7383. offset = [1, 0, 0];
  7384. break;
  7385. case 4:
  7386. offset = [0, 1, 1];
  7387. break;
  7388. case 5:
  7389. offset = [0, 1, 0];
  7390. break;
  7391. case 6:
  7392. offset = [0, 0, 1];
  7393. break;
  7394. case 7:
  7395. offset = [0, 0, 0];
  7396. break;
  7397. default:
  7398. offset = [0, 0, 0];
  7399. break;
  7400. }
  7401. var result = new JAABox();
  7402. result.set_minPos(Vector3DUtil.add(aabb.get_minPos(),[offset[0] * dims[0], offset[1] * dims[1], offset[2] * dims[2]]));
  7403. result.set_maxPos(Vector3DUtil.add(result.get_minPos(),dims));
  7404. Vector3DUtil.scaleBy(dims,0.00001);
  7405. result.set_minPos(Vector3DUtil.subtract(result.get_minPos(),dims));
  7406. result.set_maxPos(Vector3DUtil.add(result.get_maxPos(),dims));
  7407. return result;
  7408. }
  7409. // Returns true if the triangle intersects or is contained by a cell
  7410. JOctree.prototype.doesTriangleIntersectCell=function(triangle, cell){
  7411. if (!triangle.get_boundingBox().overlapTest(cell.AABox)) {
  7412. return false;
  7413. }
  7414. if (cell.AABox.isPointInside(this.getVertex(triangle.getVertexIndex(0))) ||
  7415. cell.AABox.isPointInside(this.getVertex(triangle.getVertexIndex(1))) ||
  7416. cell.AABox.isPointInside(this.getVertex(triangle.getVertexIndex(2)))) {
  7417. return true;
  7418. }
  7419. var tri = new JTriangle(this.getVertex(triangle.getVertexIndex(0)), this.getVertex(triangle.getVertexIndex(1)), this.getVertex(triangle.getVertexIndex(2)));
  7420. var edge;
  7421. var seg;
  7422. var edges = cell.get_egdes();
  7423. var pts = cell.get_points();
  7424. for (var i = 0; i < 12; i++ ) {
  7425. edge = edges[i];
  7426. seg = new JSegment(pts[edge.ind0], Vector3DUtil.subtract(pts[edge.ind1],pts[edge.ind0]));
  7427. if (tri.segmentTriangleIntersection({}, seg)) {
  7428. return true;
  7429. }
  7430. }
  7431. var pt0;
  7432. var pt1;
  7433. for (i = 0; i < 3; i++ ) {
  7434. pt0 = tri.getVertex(i);
  7435. pt1 = tri.getVertex((i + 1) % 3);
  7436. if (cell.AABox.segmentAABoxOverlap(new JSegment(pt0, Vector3DUtil.subtract(pt1,pt0)))) {
  7437. return true;
  7438. }
  7439. }
  7440. return false;
  7441. }
  7442. /* Increment our test counter, wrapping around if necessary and zapping the triangle counters.
  7443. Const because we only modify mutable members.*/
  7444. JOctree.prototype.incrementTestCounter=function(){
  7445. ++this._testCounter;
  7446. if (this._testCounter == 0) {
  7447. var numTriangles = this._triangles.length;
  7448. for (var i = 0; i < numTriangles; i++) {
  7449. this._triangles[i].counter = 0;
  7450. }
  7451. this._testCounter = 1;
  7452. }
  7453. }
  7454. jigLib.JOctree=JOctree;
  7455. })(jigLib);
  7456. (function(jigLib){
  7457. var Vector3DUtil=jigLib.Vector3DUtil;
  7458. var JNumber3D=jigLib.JNumber3D;
  7459. var JMatrix3D=jigLib.JMatrix3D;
  7460. var JOctree=jigLib.JOctree;
  7461. var CollOutData=jigLib.CollOutData;
  7462. var TriangleVertexIndices=jigLib.TriangleVertexIndices;
  7463. var PhysicsState=jigLib.PhysicsState;
  7464. var RigidBody=jigLib.RigidBody;
  7465. var ISkin3D=jigLib.ISkin3D;
  7466. var JTriangle=jigLib.JTriangle;
  7467. //removed init position and init orientation seems weird to have on trimesh but no other geom types
  7468. var JTriangleMesh=function(skin, maxTrianglesPerCell, minCellSize){
  7469. this.Super(skin);
  7470. if(maxTrianglesPerCell==undefined) maxTrianglesPerCell=20;
  7471. if(minCellSize==undefined) minCellSize=1;
  7472. this._maxTrianglesPerCell = maxTrianglesPerCell;
  7473. this._minCellSize = minCellSize;
  7474. this.set_movable(false);
  7475. if(skin){
  7476. this._skinVertices=skin.vertices;
  7477. this.createMesh(this._skinVertices,skin.indices);
  7478. this._boundingBox=this._octree.boundingBox().clone();
  7479. this._boundingSphere=this._boundingBox.getRadiusAboutCentre();
  7480. }
  7481. this._type = "TRIANGLEMESH";
  7482. };
  7483. jigLib.extend(JTriangleMesh,jigLib.RigidBody);
  7484. /*Internally set up and preprocess all numTriangles. Each index
  7485. should, of course, be from 0 to numVertices-1. Vertices and
  7486. triangles are copied and stored internally.*/
  7487. JTriangleMesh.prototype.createMesh=function(vertices, triangleVertexIndices){
  7488. this._skinVertices=vertices;
  7489. var len=vertices.length;
  7490. var vts=[];
  7491. var transform = JMatrix3D.getTranslationMatrix(this.get_currentState().position[0], this.get_currentState().position[1], this.get_currentState().position[2]);
  7492. transform = JMatrix3D.getAppendMatrix3D(this.get_currentState().get_orientation(), transform);
  7493. var i = 0;
  7494. for(var j=0;j<vertices.length;j++){
  7495. var _point=vertices[j].slice(0);
  7496. vts[i++] = transform.transformVector(_point);
  7497. }
  7498. this._octree = new JOctree();
  7499. this._octree.addTriangles(vts, vts.length, triangleVertexIndices, triangleVertexIndices.length);
  7500. this._octree.buildOctree(this._maxTrianglesPerCell, this._minCellSize);
  7501. }
  7502. JTriangleMesh.prototype.get_octree=function(){
  7503. return this._octree;
  7504. }
  7505. /*JTriangleMesh.prototype.segmentIntersect=function(out, seg, state){
  7506. var segBox = new jigLib.JAABox();
  7507. segBox.addSegment(seg);
  7508. var potentialTriangles = [];
  7509. var numTriangles = this._octree.getTrianglesIntersectingtAABox(potentialTriangles, segBox);
  7510. var bestFrac = JNumber3D.NUM_HUGE;
  7511. var tri;
  7512. var meshTriangle;
  7513. for (var iTriangle = 0 ; iTriangle < numTriangles ; iTriangle++) {
  7514. meshTriangle = this._octree.getTriangle(potentialTriangles[iTriangle]);
  7515. tri = new JTriangle(this._octree.getVertex(meshTriangle.getVertexIndex(0)), this._octree.getVertex(meshTriangle.getVertexIndex(1)), this._octree.getVertex(meshTriangle.getVertexIndex(2)));
  7516. if (tri.segmentTriangleIntersection(out, seg)) {
  7517. if (out.frac < bestFrac) {
  7518. bestFrac = out.frac;
  7519. out.position = seg.getPoint(bestFrac);
  7520. out.normal = meshTriangle.get_plane().normal;
  7521. }
  7522. }
  7523. }
  7524. out.frac = bestFrac;
  7525. if (bestFrac < JNumber3D.NUM_HUGE) {
  7526. return true;
  7527. }else {
  7528. return false;
  7529. }
  7530. }*/
  7531. JTriangleMesh.prototype.segmentIntersect=function(out, seg, state){
  7532. var potentialTriangles = [];
  7533. var numTriangles = this._octree.getTrianglesIntersectingSegment(potentialTriangles, seg);
  7534. var bestFrac = JNumber3D.NUM_HUGE;
  7535. for (var iTriangle = 0 ; iTriangle < numTriangles ; iTriangle++) {
  7536. var meshTriangle = potentialTriangles[iTriangle];
  7537. var tri = new JTriangle(this._octree.getVertex(meshTriangle.getVertexIndex(0)), this._octree.getVertex(meshTriangle.getVertexIndex(1)), this._octree.getVertex(meshTriangle.getVertexIndex(2)));
  7538. if (tri.segmentTriangleIntersection(out, seg)) {
  7539. if (out.frac < bestFrac) {
  7540. bestFrac = out.frac;
  7541. out.position = seg.getPoint(bestFrac);
  7542. out.normal = meshTriangle.get_plane().normal;
  7543. }
  7544. }
  7545. }
  7546. out.frac = bestFrac;
  7547. if (bestFrac < JNumber3D.NUM_HUGE) {
  7548. return true;
  7549. }else {
  7550. return false;
  7551. }
  7552. }
  7553. JTriangleMesh.prototype.updateState=function(){
  7554. this.Super.prototype.updateState.call(this);
  7555. var len=this._skinVertices.length;
  7556. var vts=[];
  7557. var transform = JMatrix3D.getTranslationMatrix(this.get_currentState().position[0], this.get_currentState().position[1], this.get_currentState().position[2]);
  7558. transform = JMatrix3D.getAppendMatrix3D(this.get_currentState().get_orientation(), transform);
  7559. var i = 0;
  7560. for(j=0;j<this._skinVertices.length;j++){
  7561. var _point=this._skinVertices[j].slice(0);
  7562. vts[i++] = transform.transformVector(_point);
  7563. }
  7564. this._octree.updateTriangles(vts);
  7565. this._octree.buildOctree(this._maxTrianglesPerCell, this._minCellSize);
  7566. this._boundingBox=this._octree.boundingBox().clone();
  7567. }
  7568. /*
  7569. override public function getInertiaProperties(m:Number):Matrix3D
  7570. {
  7571. return new Matrix3D();
  7572. }
  7573. override protected function updateBoundingBox():void {
  7574. }*/
  7575. jigLib.JTriangleMesh=JTriangleMesh;
  7576. })(jigLib); /*
  7577. Copyright (c) 2007 Danny Chapman
  7578. http://www.rowlhouse.co.uk
  7579. This software is provided 'as-is', without any express or implied
  7580. warranty. In no event will the authors be held liable for any damages
  7581. arising from the use of this software.
  7582. Permission is granted to anyone to use this software for any purpose,
  7583. including commercial applications, and to alter it and redistribute it
  7584. freely, subject to the following restrictions:
  7585. 1. The origin of this software must not be misrepresented; you must not
  7586. claim that you wrote the original software. If you use this software
  7587. in a product, an acknowledgment in the product documentation would be
  7588. appreciated but is not required.
  7589. 2. Altered source versions must be plainly marked as such, and must not be
  7590. misrepresented as being the original software.
  7591. 3. This notice may not be removed or altered from any source
  7592. distribution.
  7593. */
  7594. (function(jigLib){
  7595. /**
  7596. * @author Muzer(muzerly@gmail.com)
  7597. *
  7598. * @name CollPointInfo
  7599. * @class CollPointInfo
  7600. * @property {number} initialPenetration
  7601. * @property {array} r0 a 3D vector
  7602. * @property {array} r1 a 3D vector
  7603. * @property {array} position a 3D vector
  7604. * @property {number} minSeparationVel
  7605. * @property {number} denominator
  7606. * @property {number} accumulatedNormalImpulse
  7607. * @property {number} accumulatedNormalImpulseAux
  7608. * @property {array} accumulatedFrictionImpulse a 3D vector
  7609. * @constructor
  7610. **/
  7611. var CollPointInfo=function(){
  7612. this.accumulatedFrictionImpulse=[0,0,0,0];
  7613. };
  7614. CollPointInfo.prototype.initialPenetration=null;
  7615. CollPointInfo.prototype.r0;
  7616. CollPointInfo.prototype.r1;
  7617. CollPointInfo.prototype.position;
  7618. CollPointInfo.prototype.minSeparationVel = 0;
  7619. CollPointInfo.prototype.denominator = 0;
  7620. CollPointInfo.prototype.accumulatedNormalImpulse = 0;
  7621. CollPointInfo.prototype.accumulatedNormalImpulseAux = 0;
  7622. CollPointInfo.prototype.accumulatedFrictionImpulse = null;
  7623. jigLib.CollPointInfo=CollPointInfo;
  7624. })(jigLib);/*
  7625. Copyright (c) 2007 Danny Chapman
  7626. http://www.rowlhouse.co.uk
  7627. This software is provided 'as-is', without any express or implied
  7628. warranty. In no event will the authors be held liable for any damages
  7629. arising from the use of this software.
  7630. Permission is granted to anyone to use this software for any purpose,
  7631. including commercial applications, and to alter it and redistribute it
  7632. freely, subject to the following restrictions:
  7633. 1. The origin of this software must not be misrepresented; you must not
  7634. claim that you wrote the original software. If you use this software
  7635. in a product, an acknowledgment in the product documentation would be
  7636. appreciated but is not required.
  7637. 2. Altered source versions must be plainly marked as such, and must not be
  7638. misrepresented as being the original software.
  7639. 3. This notice may not be removed or altered from any source
  7640. distribution.
  7641. */
  7642. (function(jigLib){
  7643. var MaterialProperties=jigLib.MaterialProperties;
  7644. /**
  7645. * @author Muzer(muzerly@gmail.com)
  7646. *
  7647. * @name CollisionInfo
  7648. * @class CollisionInfo stores information about a collision
  7649. * @requires MaterialProperties
  7650. * @property {MaterialProperties} mat
  7651. * @property {CollDetectInfo} objInfo
  7652. * @property {array} pointInfo a collection of points expressed as 3D vectors
  7653. * @property {boolean} satisfied whether the collision has been satisfied
  7654. * @constructor
  7655. **/
  7656. var CollisionInfo=function(){
  7657. this.mat=new MaterialProperties();
  7658. this.pointInfo=[];
  7659. };
  7660. CollisionInfo.prototype.mat=null;
  7661. CollisionInfo.prototype.objInfo=null;
  7662. CollisionInfo.prototype.dirToBody=null;
  7663. CollisionInfo.prototype.pointInfo=null;
  7664. CollisionInfo.prototype.satisfied=null;
  7665. jigLib.CollisionInfo=CollisionInfo;
  7666. })(jigLib);
  7667. /*
  7668. Copyright (c) 2007 Danny Chapman
  7669. http://www.rowlhouse.co.uk
  7670. This software is provided 'as-is', without any express or implied
  7671. warranty. In no event will the authors be held liable for any damages
  7672. arising from the use of this software.
  7673. Permission is granted to anyone to use this software for any purpose,
  7674. including commercial applications, and to alter it and redistribute it
  7675. freely, subject to the following restrictions:
  7676. 1. The origin of this software must not be misrepresented; you must not
  7677. claim that you wrote the original software. If you use this software
  7678. in a product, an acknowledgment in the product documentation would be
  7679. appreciated but is not required.
  7680. 2. Altered source versions must be plainly marked as such, and must not be
  7681. misrepresented as being the original software.
  7682. 3. This notice may not be removed or altered from any source
  7683. distribution.
  7684. */
  7685. (function(jigLib){
  7686. /**
  7687. * @author Muzer(muzerly@gmail.com)
  7688. *
  7689. * @name CollDetectInfo
  7690. * @class CollDetectInfo stores 2 rigid bodies and is used by collision detection classes
  7691. * @property {RigidBody} body0
  7692. * @property {RigidBody} body1
  7693. * @constructor
  7694. */
  7695. var CollDetectInfo=function(){
  7696. };
  7697. CollDetectInfo.prototype.body0=null;
  7698. CollDetectInfo.prototype.body1=null;
  7699. jigLib.CollDetectInfo=CollDetectInfo;
  7700. })(jigLib);/*
  7701. Copyright (c) 2007 Danny Chapman
  7702. http://www.rowlhouse.co.uk
  7703. This software is provided 'as-is', without any express or implied
  7704. warranty. In no event will the authors be held liable for any damages
  7705. arising from the use of this software.
  7706. Permission is granted to anyone to use this software for any purpose,
  7707. including commercial applications, and to alter it and redistribute it
  7708. freely, subject to the following restrictions:
  7709. 1. The origin of this software must not be misrepresented; you must not
  7710. claim that you wrote the original software. If you use this software
  7711. in a product, an acknowledgment in the product documentation would be
  7712. appreciated but is not required.
  7713. 2. Altered source versions must be plainly marked as such, and must not be
  7714. misrepresented as being the original software.
  7715. 3. This notice may not be removed or altered from any source
  7716. distribution.
  7717. */
  7718. (function(jigLib){
  7719. /**
  7720. * @author Muzer(muzerly@gmail.com)
  7721. *
  7722. * @name CollDetectFunctor
  7723. * @class CollDetectFunctor base class for collision detection classes
  7724. * @property {string} name the inheriting class's collision type e.g. BoxPlane
  7725. * @property {string} type0 the first geometry type in the collisions supported by the inheritng class e.g. Box
  7726. * @property {string} type1 the second geometry type in the collisions supported by the inheritng class e.g. Plane
  7727. * @constructor
  7728. **/
  7729. var CollDetectFunctor=function(){
  7730. };
  7731. CollDetectFunctor.prototype.name=null;
  7732. CollDetectFunctor.prototype.type0=null;
  7733. CollDetectFunctor.prototype.type1=null;
  7734. /**
  7735. * @function collDetect detects a collision and updates the info parameter - must be implemented by the inheriting class
  7736. * @param {CollDetectInfo} info
  7737. * @param {array} collArray
  7738. * @type void
  7739. **/
  7740. CollDetectFunctor.prototype.collDetect=function(info,collArr){
  7741. };
  7742. jigLib.CollDetectFunctor=CollDetectFunctor;
  7743. })(jigLib);/*
  7744. Copyright (c) 2007 Danny Chapman
  7745. http://www.rowlhouse.co.uk
  7746. This software is provided 'as-is', without any express or implied
  7747. warranty. In no event will the authors be held liable for any damages
  7748. arising from the use of this software.
  7749. Permission is granted to anyone to use this software for any purpose,
  7750. including commercial applications, and to alter it and redistribute it
  7751. freely, subject to the following restrictions:
  7752. 1. The origin of this software must not be misrepresented; you must not
  7753. claim that you wrote the original software. If you use this software
  7754. in a product, an acknowledgment in the product documentation would be
  7755. appreciated but is not required.
  7756. 2. Altered source versions must be plainly marked as such, and must not be
  7757. misrepresented as being the original software.
  7758. 3. This notice may not be removed or altered from any source
  7759. distribution.
  7760. */
  7761. (function(jigLib){
  7762. var Vector3DUtil=jigLib.Vector3DUtil;
  7763. var JNumber3D=jigLib.JNumber3D;
  7764. var JMatrix3D=jigLib.JMatrix3D;
  7765. var JConstraint=jigLib.JConstraint;
  7766. var JSegment=jigLib.JSegment;
  7767. var JConfig=jigLib.JConfig;
  7768. var JSphere=jigLib.JSphere;
  7769. var MaterialProperties=jigLib.MaterialProperties;
  7770. var PhysicsState=jigLib.PhysicsState;
  7771. var EdgeData=jigLib.EdgeData;
  7772. var SpanData=jigLib.SpanData;
  7773. var CollPointInfo=jigLib.CollPointInfo;
  7774. var CollisionInfo=jigLib.CollisionInfo;
  7775. /**
  7776. * @author Muzer(muzerly@gmail.com)
  7777. *
  7778. * @name CollDetectBoxBox
  7779. * @class CollDetectBoxBox handles collisions between boxes
  7780. * @extends CollDetectFunctor
  7781. * @property {number} combinationDist the combination distance
  7782. * @requires CollDetectInfo
  7783. * @requires Vector3DUtil
  7784. * @requires JNumber3D
  7785. * @requires JBox
  7786. * @requires PhysicsState
  7787. * @constructor
  7788. **/
  7789. var CollDetectBoxBox=function(){
  7790. this.name = "BoxBox";
  7791. this.type0 = "BOX";
  7792. this.type1 = "BOX";
  7793. };
  7794. jigLib.extend(CollDetectBoxBox,jigLib.CollDetectFunctor);
  7795. CollDetectBoxBox.prototype.combinationDist=null;
  7796. // I can't find any other reference to the MAX_SUPPORT_VERTS property anywhere!
  7797. // CollDetectBoxBox.prototype.MAX_SUPPORT_VERTS = 10;
  7798. /**
  7799. * @function disjoint tests for disjoint or intersection
  7800. * @param {SpanData} out the SpanData object to apply test results to
  7801. * @param {array} axis the axis expressed as a 3D vector
  7802. * @param {JBox} box0 the first box to use for testing
  7803. * @param {JBox} box1 the second box to use for testing
  7804. * @returns true if disjoint, false if intersecting
  7805. * @type boolean
  7806. **/
  7807. CollDetectBoxBox.prototype.disjoint=function(out, axis, box0, box1){
  7808. var obj0 = box0.getSpan(axis);
  7809. var obj1 = box1.getSpan(axis);
  7810. var obj0Min = obj0.min;
  7811. var obj0Max = obj0.max;
  7812. var obj1Min = obj1.min;
  7813. var obj1Max = obj1.max;
  7814. var mmin = Math.min;
  7815. if (obj0Min > (obj1Max + JConfig.collToll + JNumber3D.NUM_TINY) || obj1Min > (obj0Max + JConfig.collToll + JNumber3D.NUM_TINY)){
  7816. out.flag = true;
  7817. return true;
  7818. }
  7819. if ((obj0Max > obj1Max) && (obj1Min > obj0Min)){
  7820. out.depth = mmin(obj0Max - obj1Min, obj1Max - obj0Min);
  7821. }else if ((obj1Max > obj0Max) && (obj0Min > obj1Min)){
  7822. out.depth = mmin(obj1Max - obj0Min, obj0Max - obj1Min);
  7823. }else{
  7824. out.depth = (obj0Max < obj1Max) ? obj0Max : obj1Max;
  7825. out.depth -= (obj0Min > obj1Min) ? obj0Min : obj1Min;
  7826. }
  7827. out.flag = false;
  7828. return false;
  7829. };
  7830. /**
  7831. * @function addPoint conditionally adds one 3D vector to a collection of other 3D vectors
  7832. * @param {array} contactPoints a collection of points (3D vectors)
  7833. * @param {array} pt the point to add expressed as a 3D vector
  7834. * @param {number} combinationDistanceSq the maximum length squared allowed between pt and any of contactPoints
  7835. * @returns true if pt was added to contactPoints, false if combinationDistanceSq was ever exceeded
  7836. * @type boolean
  7837. **/
  7838. CollDetectBoxBox.prototype.addPoint=function(contactPoints, pt, combinationDistanceSq){
  7839. for(var i=0,cpsl=contactPoints.length;i<cpsl;i++){
  7840. var contactPoint=contactPoints[i];
  7841. if (Vector3DUtil.get_lengthSquared(Vector3DUtil.subtract(contactPoint, pt)) < combinationDistanceSq){
  7842. contactPoint = JNumber3D.getDivideVector(Vector3DUtil.add(contactPoint, pt), 2);
  7843. return false;
  7844. }
  7845. }
  7846. contactPoints.push(pt);
  7847. return true;
  7848. };
  7849. /**
  7850. * @function getSupportPoint
  7851. * @param {JBox} box
  7852. * @param {array} axis the axis expressed as a 3D vector
  7853. * @returns the point expressed as a 3D Vector
  7854. * @type {array}
  7855. **/
  7856. CollDetectBoxBox.prototype.getSupportPoint=function(box, axis) {
  7857. var orientationCol = box.get_currentState().getOrientationCols();
  7858. var _as = Vector3DUtil.dotProduct(axis,orientationCol[0]);
  7859. var _au = Vector3DUtil.dotProduct(axis,orientationCol[1]);
  7860. var _ad = Vector3DUtil.dotProduct(axis,orientationCol[2]);
  7861. var p = box.get_currentState().position.slice(0);
  7862. var sideLengths=box.get_sideLengths();
  7863. if (_as < -JNumber3D.NUM_TINY) {
  7864. p = Vector3DUtil.add(p,JNumber3D.getScaleVector(orientationCol[0], 0.5 * sideLengths[0]));
  7865. }else if (_as >= JNumber3D.NUM_TINY) {
  7866. p = Vector3DUtil.subtract(p,JNumber3D.getScaleVector(orientationCol[0], 0.5 * sideLengths[0]));
  7867. }
  7868. if (_au < -JNumber3D.NUM_TINY) {
  7869. p = Vector3DUtil.add(p,JNumber3D.getScaleVector(orientationCol[1], 0.5 * sideLengths[1]));
  7870. }else if (_au > JNumber3D.NUM_TINY) {
  7871. p = Vector3DUtil.subtract(p,JNumber3D.getScaleVector(orientationCol[1], 0.5 * sideLengths[1]));
  7872. }
  7873. if (_ad < -JNumber3D.NUM_TINY) {
  7874. p = Vector3DUtil.add(p,JNumber3D.getScaleVector(orientationCol[2], 0.5 * sideLengths[2]));
  7875. }else if (_ad > JNumber3D.NUM_TINY) {
  7876. p = Vector3DUtil.subtract(p,JNumber3D.getScaleVector(orientationCol[2], 0.5 * sideLengths[2]));
  7877. }
  7878. return p;
  7879. };
  7880. /**
  7881. * @function getAABox2EdgeIntersectionPoints
  7882. * @param {array} contactPoint a 3D vector
  7883. * @param {array} origBoxSides a 3D vector
  7884. * @param {PhysicsState} origBoxState
  7885. * @param {array} edgePt0 a 3D vector
  7886. * @param {array} edgePt1 a 3D vector
  7887. * @type {number}
  7888. **/
  7889. CollDetectBoxBox.prototype.getAABox2EdgeIntersectionPoints=function(contactPoint, origBoxSides, origBoxState, edgePt0, edgePt1){
  7890. var jDir;
  7891. var kDir;
  7892. var dist0;
  7893. var dist1;
  7894. var frac;
  7895. var num=0;
  7896. var pt;
  7897. var edgeDir = Vector3DUtil.subtract(edgePt1, edgePt0);
  7898. Vector3DUtil.normalize(edgeDir);
  7899. var ptArr=[];
  7900. var faceOffsets=[];
  7901. var edgePt0Arr = edgePt0;
  7902. var edgePt1Arr = edgePt1;
  7903. var edgeDirArr = edgeDir;
  7904. var sidesArr = JNumber3D.getScaleVector(origBoxSides, 0.5);
  7905. for (var iDir= 2; iDir >= 0; iDir--) {
  7906. if (Math.abs(edgeDirArr[iDir]) < 0.1) {
  7907. continue;
  7908. }
  7909. jDir = (iDir + 1) % 3;
  7910. kDir = (iDir + 2) % 3;
  7911. faceOffsets = [ -sidesArr[iDir], sidesArr[iDir]];
  7912. for (var iFace= 1; iFace >= 0; iFace-- ) {
  7913. dist0 = edgePt0Arr[iDir] - faceOffsets[iFace];
  7914. dist1 = edgePt1Arr[iDir] - faceOffsets[iFace];
  7915. frac = -1;
  7916. if (dist0 * dist1 < -JNumber3D.NUM_TINY) {
  7917. frac = -dist0 / (dist1 - dist0);
  7918. }else if (Math.abs(dist0) < JNumber3D.NUM_TINY) {
  7919. frac = 0;
  7920. }else if (Math.abs(dist1) < JNumber3D.NUM_TINY) {
  7921. frac = 1;
  7922. }
  7923. if (frac >= 0) {
  7924. pt = Vector3DUtil.add(JNumber3D.getScaleVector(edgePt0, 1 - frac),JNumber3D.getScaleVector(edgePt1, frac));
  7925. ptArr = pt;
  7926. if ((ptArr[jDir] > -sidesArr[jDir] - JNumber3D.NUM_TINY) && (ptArr[jDir] < sidesArr[jDir] + JNumber3D.NUM_TINY) && (ptArr[kDir] > -sidesArr[kDir] - JNumber3D.NUM_TINY) && (ptArr[kDir] < sidesArr[kDir] + JNumber3D.NUM_TINY) ) {
  7927. pt=pt.splice(0);
  7928. JMatrix3D.multiplyVector(origBoxState.get_orientation(),pt);
  7929. pt = Vector3DUtil.add(pt,origBoxState.position);
  7930. this.addPoint(contactPoint, pt, combinationDist);
  7931. if (++num == 2) {
  7932. return num;
  7933. }
  7934. }
  7935. }
  7936. }
  7937. }
  7938. return num;
  7939. };
  7940. /**
  7941. * @function getBox2BoxEdgesIntersectionPoints
  7942. * @param {array} contactPoint a 3D vector
  7943. * @param {JBox} box0
  7944. * @param {JBox} box1
  7945. * @param {PhysicsState} newState
  7946. * @type {number}
  7947. **/
  7948. CollDetectBoxBox.prototype.getBox2BoxEdgesIntersectionPoints=function(contactPoint, box0, box1, newState){
  7949. var num = 0;
  7950. var seg;
  7951. var box0State = (newState) ? box0.get_currentState() : box0.get_oldState();
  7952. var box1State= (newState) ? box1.get_currentState() : box1.get_oldState();
  7953. var boxPts = box1.getCornerPointsInBoxSpace(box1State, box0State);
  7954. var boxEdges = box1.get_edges();
  7955. var edgePt0;
  7956. var edgePt1;
  7957. for(var i=0;i<boxEdges.length;i++){
  7958. var boxEdge=boxEdges[i];
  7959. edgePt0 = boxPts[boxEdge.ind0];
  7960. edgePt1 = boxPts[boxEdge.ind1];
  7961. num += this.getAABox2EdgeIntersectionPoints(contactPoint, box0.get_sideLengths(), box0State, edgePt0, edgePt1);
  7962. if (num >= 8) {
  7963. return num;
  7964. }
  7965. }
  7966. return num;
  7967. };
  7968. /**
  7969. * @function getBoxBoxIntersectionPoints
  7970. * @param {array} contactPoint a 3D vector
  7971. * @param {JBox} box0
  7972. * @param {JBox} box1
  7973. * @param {PhysicsState} newState
  7974. * @type {number}
  7975. **/
  7976. CollDetectBoxBox.prototype.getBoxBoxIntersectionPoints=function(contactPoint, box0, box1, newState){
  7977. this.getBox2BoxEdgesIntersectionPoints(contactPoint, box0, box1, newState);
  7978. this.getBox2BoxEdgesIntersectionPoints(contactPoint, box1, box0, newState);
  7979. return Vector3DUtil.get_length(contactPoint);
  7980. };
  7981. /**
  7982. * @function collDetect detects a collision and updates the info parameter
  7983. * @param {CollDetectInfo} info
  7984. * @param {array} collArray
  7985. * @param {PhysicsState} newState
  7986. * @type {void}
  7987. **/
  7988. CollDetectBoxBox.prototype.collDetect=function(info, collArr){
  7989. var box0 = info.body0;
  7990. var box1 = info.body1;
  7991. if (!box0.hitTestObject3D(box1)) return;
  7992. if (JConfig.aabbDetection && !box0.get_boundingBox().overlapTest(box1.get_boundingBox())) return;
  7993. var numTiny= JNumber3D.NUM_TINY;
  7994. var numHuge= JNumber3D.NUM_HUGE;
  7995. var dirs0Arr = box0.get_currentState().getOrientationCols();
  7996. var dirs1Arr = box1.get_currentState().getOrientationCols();
  7997. // the 15 potential separating axes
  7998. var axes = [dirs0Arr[0], dirs0Arr[1], dirs0Arr[2],
  7999. dirs1Arr[0], dirs1Arr[1], dirs1Arr[2],
  8000. Vector3DUtil.crossProduct(dirs0Arr[0],dirs1Arr[0]),
  8001. Vector3DUtil.crossProduct(dirs0Arr[1],dirs1Arr[0]),
  8002. Vector3DUtil.crossProduct(dirs0Arr[2],dirs1Arr[0]),
  8003. Vector3DUtil.crossProduct(dirs0Arr[0],dirs1Arr[1]),
  8004. Vector3DUtil.crossProduct(dirs0Arr[1],dirs1Arr[1]),
  8005. Vector3DUtil.crossProduct(dirs0Arr[2],dirs1Arr[1]),
  8006. Vector3DUtil.crossProduct(dirs0Arr[0],dirs1Arr[2]),
  8007. Vector3DUtil.crossProduct(dirs0Arr[1],dirs1Arr[2]),
  8008. Vector3DUtil.crossProduct(dirs0Arr[2],dirs1Arr[2])];
  8009. var l2;
  8010. // the overlap depths along each axis
  8011. var overlapDepths = [];
  8012. var i= 0;
  8013. var axesLength = axes.length;
  8014. // see if the boxes are separate along any axis, and if not keep a
  8015. // record of the depths along each axis
  8016. for (i = 0; i < axesLength; i++){
  8017. var _overlapDepth = overlapDepths[i] = new SpanData();
  8018. _overlapDepth.depth = numHuge;
  8019. l2 = Vector3DUtil.get_lengthSquared(axes[i]);
  8020. if (l2 < numTiny) continue;
  8021. var ax = axes[i].slice(0);
  8022. Vector3DUtil.normalize(ax);
  8023. if (this.disjoint(overlapDepths[i], ax, box0, box1)) return;
  8024. }
  8025. // The box overlap, find the separation depth closest to 0.
  8026. var minDepth = numHuge;
  8027. var minAxis = -1;
  8028. axesLength = axes.length;
  8029. for (i = 0; i < axesLength; i++){
  8030. l2 = Vector3DUtil.get_lengthSquared(axes[i]);
  8031. if (l2 < numTiny) continue;
  8032. // If this axis is the minimum, select it
  8033. if (overlapDepths[i].depth < minDepth){
  8034. minDepth = overlapDepths[i].depth;
  8035. minAxis =i;
  8036. }
  8037. }
  8038. if (minAxis == -1) return;
  8039. // Make sure the axis is facing towards the box0. if not, invert it
  8040. var N= axes[minAxis].splice(0);
  8041. if (Vector3DUtil.dotProduct(Vector3DUtil.subtract(box1.get_currentState().position,box0.get_currentState().position),N) > 0)
  8042. N = JNumber3D.getScaleVector(N, -1);
  8043. var contactPointsFromOld = true;
  8044. var contactPoints = [];
  8045. var box0lengths=box0.get_sideLengths();
  8046. var box1lengths=box1.get_sideLengths();
  8047. combinationDist = 0.05 * Math.min(Math.min(box0lengths[0], box0lengths[1], box0lengths[2]), Math.min(box1lengths[0], box1lengths[1], box1lengths[2]));
  8048. combinationDist += (JConfig.collToll * 3.464);
  8049. combinationDist *= combinationDist;
  8050. if (minDepth > -JNumber3D.NUM_TINY)
  8051. this.getBoxBoxIntersectionPoints(contactPoints, box0, box1, false);
  8052. if (contactPoints.length == 0){
  8053. contactPointsFromOld = false;
  8054. this.getBoxBoxIntersectionPoints(contactPoints, box0, box1, true);
  8055. }
  8056. var bodyDelta = Vector3DUtil.subtract(Vector3DUtil.subtract(box0.get_currentState().position,box0.get_oldState().position),Vector3DUtil.subtract(box1.get_currentState().position,box1.get_oldState().position));
  8057. var bodyDeltaLen = Vector3DUtil.dotProduct(bodyDelta,N);
  8058. var oldDepth = minDepth + bodyDeltaLen;
  8059. var SATPoint = [];
  8060. switch(minAxis){
  8061. //-----------------------------------------------------------------
  8062. // Box0 face, Box1 Corner collision
  8063. //-----------------------------------------------------------------
  8064. case 0:
  8065. case 1:
  8066. case 2:
  8067. //-----------------------------------------------------------------
  8068. // Get the lowest point on the box1 along box1 normal
  8069. //-----------------------------------------------------------------
  8070. SATPoint = this.getSupportPoint(box1, JNumber3D.getScaleVector(N, -1));
  8071. break;
  8072. //-----------------------------------------------------------------
  8073. // We have a Box2 corner/Box1 face collision
  8074. //-----------------------------------------------------------------
  8075. case 3:
  8076. case 4:
  8077. case 5:
  8078. //-----------------------------------------------------------------
  8079. // Find with vertex on the triangle collided
  8080. //-----------------------------------------------------------------
  8081. SATPoint = this.getSupportPoint(box0, N);
  8082. break;
  8083. //-----------------------------------------------------------------
  8084. // We have an edge/edge colliiosn
  8085. //-----------------------------------------------------------------
  8086. case 6:
  8087. case 7:
  8088. case 8:
  8089. case 9:
  8090. case 10:
  8091. case 11:
  8092. case 12:
  8093. case 13:
  8094. case 14:
  8095. //-----------------------------------------------------------------
  8096. // Retrieve which edges collided.
  8097. //-----------------------------------------------------------------
  8098. i = minAxis - 6;
  8099. var ia = (i / 3)|0;
  8100. var ib= i - ia * 3;
  8101. //-----------------------------------------------------------------
  8102. // find two P0, P1 point on both edges.
  8103. //-----------------------------------------------------------------
  8104. var P0 = this.getSupportPoint(box0, N);
  8105. var P1 = this.getSupportPoint(box1, JNumber3D.getScaleVector(N, -1));
  8106. //-----------------------------------------------------------------
  8107. // Find the edge intersection.
  8108. //-----------------------------------------------------------------
  8109. //-----------------------------------------------------------------
  8110. // plane along N and F, and passing through PB
  8111. //-----------------------------------------------------------------
  8112. var planeNormal = Vector3DUtil.crossProduct(N,dirs1Arr[ib]);
  8113. var planeD = Vector3DUtil.dotProduct(planeNormal,P1);
  8114. //-----------------------------------------------------------------
  8115. // find the intersection t, where Pintersection = P0 + t*box edge dir
  8116. //-----------------------------------------------------------------
  8117. var div = Vector3DUtil.dotProduct(dirs0Arr[ia],planeNormal);
  8118. //-----------------------------------------------------------------
  8119. // plane and ray colinear, skip the intersection.
  8120. //-----------------------------------------------------------------
  8121. if (Math.abs(div) < JNumber3D.NUM_TINY) return;
  8122. var t = (planeD - Vector3DUtil.dotProduct(P0,planeNormal)) / div;
  8123. //-----------------------------------------------------------------
  8124. // point on edge of box0
  8125. //-----------------------------------------------------------------
  8126. P0 = Vector3DUtil.add(P0,JNumber3D.getScaleVector(dirs0Arr[ia], t));
  8127. SATPoint =Vector3DUtil.add(P0,JNumber3D.getScaleVector(N, 0.5 * minDepth));
  8128. break;
  8129. }
  8130. var collPts;
  8131. if (contactPoints.length > 0){
  8132. collPts = [];
  8133. var minDist = JNumber3D.NUM_HUGE;
  8134. var maxDist = -JNumber3D.NUM_HUGE;
  8135. var dist;
  8136. var depth;
  8137. var depthScale;
  8138. var cpInfo;
  8139. var contactPoint;
  8140. for(var j=0;j<contactPoints.length;j++){
  8141. contactPoint=contactPoints[j];
  8142. dist = Vector3DUtil.get_length(Vector3DUtil.subtract(contactPoint,SATPoint));
  8143. if (dist < minDist) minDist = dist;
  8144. if (dist > maxDist) maxDist = dist;
  8145. }
  8146. if (maxDist < minDist + JNumber3D.NUM_TINY) maxDist = minDist + JNumber3D.NUM_TINY;
  8147. i = 0;
  8148. for(var j=0;j<contactPoints.length;j++){
  8149. contactPoint=contactPoints[j];
  8150. dist = Vector3DUtil.get_length(Vector3DUtil.subtract(contactPoint,SATPoint));
  8151. depthScale = (dist - minDist) / (maxDist - minDist);
  8152. depth = (1 - depthScale) * oldDepth;
  8153. cpInfo = new CollPointInfo();
  8154. if (contactPointsFromOld) {
  8155. cpInfo.r0 = Vector3DUtil.subtract(contactPoint,box0.get_oldState().position);
  8156. cpInfo.r1 = Vector3DUtil.subtract(contactPoint,box1.get_oldState().position);
  8157. } else {
  8158. cpInfo.r0 = Vector3DUtil.subtract(contactPoint,box0.get_currentState().position);
  8159. cpInfo.r1 = Vector3DUtil.subtract(contactPoint,box1.get_currentState().position);
  8160. }
  8161. cpInfo.initialPenetration = depth;
  8162. collPts[i++] = cpInfo;
  8163. }
  8164. }else{
  8165. cpInfo = new CollPointInfo();
  8166. cpInfo.r0 = Vector3DUtil.subtract(SATPoint,box0.get_currentState().position);
  8167. cpInfo.r1 = Vector3DUtil.subtract(SATPoint,box1.get_currentState().position);
  8168. cpInfo.initialPenetration = oldDepth;
  8169. collPts = [];
  8170. collPts[0] = cpInfo;
  8171. }
  8172. var collInfo = new CollisionInfo();
  8173. collInfo.objInfo = info;
  8174. collInfo.dirToBody = N;
  8175. collInfo.pointInfo = collPts;
  8176. var mat = new MaterialProperties();
  8177. mat.set_restitution(Math.sqrt(box0.get_material().get_restitution() * box1.get_material().get_restitution()));
  8178. mat.set_friction(Math.sqrt(box0.get_material().get_friction() * box1.get_material().get_friction()));
  8179. collInfo.mat = mat;
  8180. collArr.push(collInfo);
  8181. info.body0.collisions.push(collInfo);
  8182. info.body1.collisions.push(collInfo);
  8183. };
  8184. jigLib.CollDetectBoxBox=CollDetectBoxBox;
  8185. })(jigLib);
  8186. /*
  8187. Copyright (c) 2007 Danny Chapman
  8188. http://www.rowlhouse.co.uk
  8189. This software is provided 'as-is', without any express or implied
  8190. warranty. In no event will the authors be held liable for any damages
  8191. arising from the use of this software.
  8192. Permission is granted to anyone to use this software for any purpose,
  8193. including commercial applications, and to alter it and redistribute it
  8194. freely, subject to the following restrictions:
  8195. 1. The origin of this software must not be misrepresented; you must not
  8196. claim that you wrote the original software. If you use this software
  8197. in a product, an acknowledgment in the product documentation would be
  8198. appreciated but is not required.
  8199. 2. Altered source versions must be plainly marked as such, and must not be
  8200. misrepresented as being the original software.
  8201. 3. This notice may not be removed or altered from any source
  8202. distribution.
  8203. */
  8204. (function(jigLib){
  8205. var Vector3DUtil=jigLib.Vector3DUtil;
  8206. var JNumber3D=jigLib.JNumber3D;
  8207. var JConstraint=jigLib.JConstraint;
  8208. var JConfig=jigLib.JConfig;
  8209. var JPlane=jigLib.JPlane;
  8210. var JSegment=jigLib.JSegment;
  8211. var JBox=jigLib.JBox;
  8212. var MaterialProperties=jigLib.MaterialProperties;
  8213. var RigidBody=jigLib.RigidBody;
  8214. var CollPointInfo=jigLib.CollPointInfo;
  8215. var CollisionInfo=jigLib.CollisionInfo;
  8216. /**
  8217. * @author Muzer(muzerly@gmail.com)
  8218. *
  8219. * @name CollDetectBoxPlane
  8220. * @class CollDetectBoxPlane handles collisions between boxes and planes
  8221. * @extends CollDetectFunctor
  8222. * @requires CollDetectInfo
  8223. * @requires Vector3DUtil
  8224. * @constructor
  8225. **/
  8226. var CollDetectBoxPlane=function(){
  8227. this.name = "BoxPlane";
  8228. this.type0 = "BOX";
  8229. this.type1 = "PLANE";
  8230. };
  8231. jigLib.extend(CollDetectBoxPlane,jigLib.CollDetectFunctor);
  8232. /**
  8233. * @function collDetect detects a collision and updates the info parameter
  8234. * @param {CollDetectInfo} info
  8235. * @param {array} collArray
  8236. * @type void
  8237. **/
  8238. CollDetectBoxPlane.prototype.collDetect=function(info, collArr){
  8239. var tempBody;
  8240. if (info.body0.get_type() == "PLANE"){
  8241. tempBody = info.body0;
  8242. info.body0 = info.body1;
  8243. info.body1 = tempBody;
  8244. }
  8245. var box = info.body0;
  8246. var plane = info.body1;
  8247. var centreDist= plane.pointPlaneDistance(box.get_currentState().position);
  8248. if (centreDist > box.get_boundingSphere() + JConfig.collToll)
  8249. return;
  8250. var newPts = box.getCornerPoints(box.get_currentState());
  8251. var oldPts = box.getCornerPoints(box.get_oldState());
  8252. var collPts = [];
  8253. var cpInfo;
  8254. var newPt;
  8255. var oldPt;
  8256. var newDepth;
  8257. var oldDepth;
  8258. for (var i=0; i<8; i++){
  8259. newPt = newPts[i];
  8260. oldPt = oldPts[i];
  8261. newDepth = -1 * plane.pointPlaneDistance(newPt);
  8262. oldDepth = -1 * plane.pointPlaneDistance(oldPt);
  8263. if (Math.max(newDepth, oldDepth) > -JConfig.collToll){
  8264. cpInfo = new CollPointInfo();
  8265. cpInfo.r0 = Vector3DUtil.subtract(oldPt, box.get_oldState().position);
  8266. cpInfo.r1 = Vector3DUtil.subtract(oldPt, plane.get_oldState().position);
  8267. cpInfo.initialPenetration = oldDepth;
  8268. collPts.push(cpInfo);
  8269. }
  8270. }
  8271. if (collPts.length > 0){
  8272. var collInfo = new CollisionInfo();
  8273. collInfo.objInfo = info;
  8274. collInfo.dirToBody = plane.get_normal();
  8275. collInfo.pointInfo = collPts;
  8276. var mat = new MaterialProperties();
  8277. mat.set_restitution(Math.sqrt(box.get_material().get_restitution() * plane.get_material().get_restitution()));
  8278. mat.set_friction(Math.sqrt(box.get_material().get_friction() * plane.get_material().get_friction()));
  8279. collInfo.mat = mat;
  8280. collArr.push(collInfo);
  8281. info.body0.collisions.push(collInfo);
  8282. info.body1.collisions.push(collInfo);
  8283. }
  8284. };
  8285. jigLib.CollDetectBoxPlane=CollDetectBoxPlane;
  8286. })(jigLib);/*
  8287. Copyright (c) 2007 Danny Chapman
  8288. http://www.rowlhouse.co.uk
  8289. This software is provided 'as-is', without any express or implied
  8290. warranty. In no event will the authors be held liable for any damages
  8291. arising from the use of this software.
  8292. Permission is granted to anyone to use this software for any purpose,
  8293. including commercial applications, and to alter it and redistribute it
  8294. freely, subject to the following restrictions:
  8295. 1. The origin of this software must not be misrepresented; you must not
  8296. claim that you wrote the original software. If you use this software
  8297. in a product, an acknowledgment in the product documentation would be
  8298. appreciated but is not required.
  8299. 2. Altered source versions must be plainly marked as such, and must not be
  8300. misrepresented as being the original software.
  8301. 3. This notice may not be removed or altered from any source
  8302. distribution.
  8303. */
  8304. (function(jigLib){
  8305. var Vector3DUtil=jigLib.Vector3DUtil;
  8306. var JNumber3D=jigLib.JNumber3D;
  8307. var JConstraint=jigLib.JConstraint;
  8308. var JConfig=jigLib.JConfig;
  8309. var JTerrain=jigLib.JTerrain;
  8310. var JBox=jigLib.JBox;
  8311. var MaterialProperties=jigLib.MaterialProperties;
  8312. var RigidBody=jigLib.RigidBody;
  8313. /**
  8314. * @author Muzer(muzerly@gmail.com)
  8315. *
  8316. * @name CollDetectBoxTerrain
  8317. * @class CollDetectBoxTerrain handles collisions between boxes and terrain
  8318. * @extends CollDetectFunctor
  8319. * @requires CollDetectInfo
  8320. * @requires CollPointInfo
  8321. * @requires Vector3DUtil
  8322. * @requires MaterialProperties
  8323. * @constructor
  8324. **/
  8325. var CollDetectBoxTerrain=function(){
  8326. this.name = "BoxTerrain";
  8327. this.type0 = "BOX";
  8328. this.type1 = "TERRAIN";
  8329. };
  8330. jigLib.extend(CollDetectBoxTerrain,jigLib.CollDetectFunctor);
  8331. /**
  8332. * @function collDetect detects a collision and updates the info parameter
  8333. * @param {CollDetectInfo} info
  8334. * @param {array} collArray
  8335. * @type void
  8336. **/
  8337. CollDetectBoxTerrain.prototype.collDetect=function(info, collArr){
  8338. var tempBody;
  8339. if (info.body0.type == "TERRAIN"){
  8340. tempBody = info.body0;
  8341. info.body0 = info.body1;
  8342. info.body1 = tempBody;
  8343. }
  8344. var box = info.body0;
  8345. var terrain = info.body1;
  8346. var oldPts = box.getCornerPoints(box.oldState);
  8347. var newPts = box.getCornerPoints(box.currentState);
  8348. var collNormal = [0,0,0,0];
  8349. var obj;
  8350. var dist;
  8351. var newPt;
  8352. var oldPt;
  8353. var collPts = [];
  8354. var cpInfo;
  8355. for (var i = 0; i < 8; i++ ) {
  8356. newPt = newPts[i];
  8357. obj = terrain.getHeightAndNormalByPoint(newPt);
  8358. if (obj.height < JConfig.collToll) {
  8359. oldPt = oldPts[i];
  8360. dist = terrain.getHeightByPoint(oldPt);
  8361. collNormal = Vector3DUtil.add(collNormal, obj.normal);
  8362. cpInfo = new CollPointInfo();
  8363. cpInfo.r0 = Vector3DUtil.subtract(oldPt, box.oldState.position);
  8364. cpInfo.r1 = Vector3DUtil.subtract(oldPt, terrain.oldState.position);
  8365. cpInfo.initialPenetration = -dist;
  8366. collPts.push(cpInfo);
  8367. }
  8368. }
  8369. if (collPts.length > 0) {
  8370. Vector3DUtil.normalize(collNormal);
  8371. var collInfo = new CollisionInfo();
  8372. collInfo.objInfo = info;
  8373. collInfo.dirToBody = collNormal;
  8374. collInfo.pointInfo = collPts;
  8375. var mat = new MaterialProperties();
  8376. mat.restitution = Math.sqrt(box.material.restitution * terrain.material.restitution);
  8377. mat.friction = Math.sqrt(box.material.friction * terrain.material.friction);
  8378. collInfo.mat = mat;
  8379. collArr.push(collInfo);
  8380. info.body0.collisions.push(collInfo);
  8381. info.body1.collisions.push(collInfo);
  8382. };
  8383. };
  8384. jigLib.CollDetectBoxTerrain=CollDetectBoxTerrain;
  8385. })(jigLib);/*
  8386. Copyright (c) 2007 Danny Chapman
  8387. http://www.rowlhouse.co.uk
  8388. This software is provided 'as-is', without any express or implied
  8389. warranty. In no event will the authors be held liable for any damages
  8390. arising from the use of this software.
  8391. Permission is granted to anyone to use this software for any purpose,
  8392. including commercial applications, and to alter it and redistribute it
  8393. freely, subject to the following restrictions:
  8394. 1. The origin of this software must not be misrepresented; you must not
  8395. claim that you wrote the original software. If you use this software
  8396. in a product, an acknowledgment in the product documentation would be
  8397. appreciated but is not required.
  8398. 2. Altered source versions must be plainly marked as such, and must not be
  8399. misrepresented as being the original software.
  8400. 3. This notice may not be removed or altered from any source
  8401. distribution.
  8402. */
  8403. (function(jigLib){
  8404. var Vector3DUtil=jigLib.Vector3DUtil;
  8405. var JMatrix3D=jigLib.JMatrix3D;
  8406. var JNumber3D=jigLib.JNumber3D;
  8407. var JConstraint=jigLib.JConstraint;
  8408. var JConfig=jigLib.JConfig;
  8409. var JCapsule=jigLib.JCapsule;
  8410. var JSegment=jigLib.JSegment;
  8411. var JBox=jigLib.JBox;
  8412. var MaterialProperties=jigLib.MaterialProperties;
  8413. var RigidBody=jigLib.RigidBody;
  8414. var CollPointInfo=jigLib.CollPointInfo;
  8415. var CollisionInfo=jigLib.CollisionInfo;
  8416. /**
  8417. * @author Muzer(muzerly@gmail.com)
  8418. *
  8419. * @name CollDetectCapsuleBox
  8420. * @class CollDetectCapsuleBox handles collisions between capsules and boxes
  8421. * @extends CollDetectFunctor
  8422. * @requires CollDetectInfo
  8423. * @requires CollPointInfo
  8424. * @requires Vector3DUtil
  8425. * @requires JNumber3D
  8426. * @requires JSegment
  8427. * @requires MaterialProperties
  8428. * @constructor
  8429. **/
  8430. var CollDetectCapsuleBox=function(){
  8431. this.name = "CapsuleBox";
  8432. this.type0 = "CAPSULE";
  8433. this.type1 = "BOX";
  8434. };
  8435. jigLib.extend(CollDetectCapsuleBox,jigLib.CollDetectFunctor);
  8436. /**
  8437. * @function collDetect detects a collision and updates the info parameter
  8438. * @param {CollDetectInfo} info
  8439. * @param {array} collArray
  8440. * @type void
  8441. **/
  8442. CollDetectCapsuleBox.prototype.collDetect=function(info, collArr){
  8443. var tempBody;
  8444. if (info.body0.get_type() == "BOX"){
  8445. tempBody = info.body0;
  8446. info.body0 = info.body1;
  8447. info.body1 = tempBody;
  8448. }
  8449. var capsule = info.body0;
  8450. var box = info.body1;
  8451. if (!capsule.hitTestObject3D(box)){
  8452. return;
  8453. }
  8454. if (JConfig.aabbDetection && !capsule.get_boundingBox().overlapTest(box.get_boundingBox())) {
  8455. return;
  8456. }
  8457. var collPts = [];
  8458. var cpInfo;
  8459. var averageNormal = [0,0,0,0];
  8460. var oldSeg = new JSegment(capsule.getEndPos(capsule.get_oldState()), JNumber3D.getScaleVector(capsule.get_oldState().getOrientationCols()[1], -Vector3DUtil.get_length(capsule)));
  8461. var newSeg = new JSegment(capsule.getEndPos(capsule.get_currentState()), JNumber3D.getScaleVector(capsule.get_currentState().getOrientationCols()[1], -Vector3DUtil.get_length(capsule)));
  8462. var radius = capsule.get_radius();
  8463. var oldObj = {};
  8464. var oldDistSq= oldSeg.segmentBoxDistanceSq(oldObj, box, box.get_oldState());
  8465. var newObj = {};
  8466. var newDistSq = newSeg.segmentBoxDistanceSq(newObj, box, box.get_currentState());
  8467. var arr = box.get_oldState().getOrientationCols();
  8468. if (Math.min(oldDistSq, newDistSq) < Math.pow(radius + JConfig.collToll, 2)){
  8469. var segPos = oldSeg.getPoint(Number(oldObj.pfLParam));
  8470. var boxPos = box.get_oldState().position.slice(0);
  8471. boxPos = Vector3DUtil.add(boxPos, JNumber3D.getScaleVector(arr[0], oldObj.pfLParam0));
  8472. boxPos = Vector3DUtil.add(boxPos, JNumber3D.getScaleVector(arr[1], oldObj.pfLParam1));
  8473. boxPos = Vector3DUtil.add(boxPos, JNumber3D.getScaleVector(arr[2], oldObj.pfLParam2));
  8474. var dist = Math.sqrt(oldDistSq);
  8475. var depth = radius - dist;
  8476. var dir;
  8477. if (dist > JNumber3D.NUM_TINY){
  8478. dir = Vector3DUtil.subtract(segPos, boxPos);
  8479. Vector3DUtil.normalize(dir);
  8480. }else if (Vector3DUtil.get_length(Vector3DUtil.subtract(segPos, box.get_oldState().position)) > JNumber3D.NUM_TINY){
  8481. dir = Vector3DUtil.subtract(segPos, box.get_oldState().position);
  8482. Vector3DUtil.normalize(dir);
  8483. }else{
  8484. dir = Vector3DUtil.Y_AXIS;
  8485. JMatrix3D.multiplyVector(JMatrix3D.getRotationMatrix(0, 0, 1, 360 * Math.random()), dir);
  8486. }
  8487. averageNormal = Vector3DUtil.add(averageNormal, dir);
  8488. cpInfo = new CollPointInfo();
  8489. cpInfo.r0 = Vector3DUtil.subtract(boxPos, capsule.get_oldState().position);
  8490. cpInfo.r1 = Vector3DUtil.subtract(boxPos, box.get_oldState().position);
  8491. cpInfo.initialPenetration = depth;
  8492. collPts.push(cpInfo);
  8493. }
  8494. oldSeg = new JSegment(capsule.getBottomPos(capsule.get_oldState()), JNumber3D.getScaleVector(capsule.get_oldState().getOrientationCols()[1], Vector3DUtil.get_length(capsule)));
  8495. newSeg = new JSegment(capsule.getBottomPos(capsule.get_currentState()), JNumber3D.getScaleVector(capsule.get_currentState().getOrientationCols()[1], Vector3DUtil.get_length(capsule)));
  8496. oldObj = {};
  8497. oldDistSq = oldSeg.segmentBoxDistanceSq(oldObj, box, box.get_oldState());
  8498. newObj = {};
  8499. newDistSq = newSeg.segmentBoxDistanceSq(newObj, box, box.get_currentState());
  8500. if (Math.min(oldDistSq, newDistSq) < Math.pow(radius + JConfig.collToll, 2)){
  8501. segPos = oldSeg.getPoint(Number(oldObj.pfLParam));
  8502. boxPos = box.get_oldState().position.slice(0);
  8503. boxPos = Vector3DUtil.add(boxPos, JNumber3D.getScaleVector(arr[0], oldObj.pfLParam0));
  8504. boxPos = Vector3DUtil.add(boxPos, JNumber3D.getScaleVector(arr[1], oldObj.pfLParam1));
  8505. boxPos = Vector3DUtil.add(boxPos, JNumber3D.getScaleVector(arr[2], oldObj.pfLParam2));
  8506. dist = Math.sqrt(oldDistSq);
  8507. depth = radius - dist;
  8508. if (dist > JNumber3D.NUM_TINY){
  8509. dir = Vector3DUtil.subtract(segPos, boxPos);
  8510. Vector3DUtil.normalize(dir);
  8511. }else if (Vector3DUtil.get_length(Vector3DUtil.subtract(segPos, box.get_oldState().position)) > JNumber3D.NUM_TINY){
  8512. dir = Vector3DUtil.subtract(segPos, box.get_oldState().position);
  8513. Vector3DUtil.normalize(dir);
  8514. }else{
  8515. dir = Vector3DUtil.Y_AXIS;
  8516. JMatrix3D.multiplyVector(JMatrix3D.getRotationMatrix(0, 0, 1, 360 * Math.random()), dir);
  8517. }
  8518. averageNormal = Vector3DUtil.add(averageNormal, dir);
  8519. cpInfo = new CollPointInfo();
  8520. cpInfo.r0 = Vector3DUtil.subtract(boxPos, capsule.get_oldState().position);
  8521. cpInfo.r1 = Vector3DUtil.subtract(boxPos, box.get_oldState().position);
  8522. cpInfo.initialPenetration = depth;
  8523. collPts.push(cpInfo);
  8524. }
  8525. if (collPts.length > 0){
  8526. averageNormal.normalize();
  8527. var collInfo = new CollisionInfo();
  8528. collInfo.objInfo = info;
  8529. collInfo.dirToBody = averageNormal;
  8530. collInfo.pointInfo = collPts;
  8531. var mat = new MaterialProperties();
  8532. mat.set_restitution(Math.sqrt(capsule.get_material().get_restitution() * box.get_material().get_restitution()));
  8533. mat.set_friction(Math.sqrt(capsule.get_material().get_friction() * box.get_material().get_friction()));
  8534. collInfo.mat = mat;
  8535. collArr.push(collInfo);
  8536. info.body0.collisions.push(collInfo);
  8537. info.body1.collisions.push(collInfo);
  8538. }
  8539. };
  8540. jigLib.CollDetectCapsuleBox=CollDetectCapsuleBox;
  8541. })(jigLib);
  8542. /*
  8543. Copyright (c) 2007 Danny Chapman
  8544. http://www.rowlhouse.co.uk
  8545. This software is provided 'as-is', without any express or implied
  8546. warranty. In no event will the authors be held liable for any damages
  8547. arising from the use of this software.
  8548. Permission is granted to anyone to use this software for any purpose,
  8549. including commercial applications, and to alter it and redistribute it
  8550. freely, subject to the following restrictions:
  8551. 1. The origin of this software must not be misrepresented; you must not
  8552. claim that you wrote the original software. If you use this software
  8553. in a product, an acknowledgment in the product documentation would be
  8554. appreciated but is not required.
  8555. 2. Altered source versions must be plainly marked as such, and must not be
  8556. misrepresented as being the original software.
  8557. 3. This notice may not be removed or altered from any source
  8558. distribution.
  8559. */
  8560. (function(jigLib){
  8561. var Vector3DUtil=jigLib.Vector3DUtil;
  8562. var JMatrix3D=jigLib.JMatrix3D;
  8563. var JNumber3D=jigLib.JNumber3D;
  8564. var JConstraint=jigLib.JConstraint;
  8565. var JConfig=jigLib.JConfig;
  8566. var JCapsule=jigLib.JCapsule;
  8567. var JSegment=jigLib.JSegment;
  8568. var MaterialProperties=jigLib.MaterialProperties;
  8569. var RigidBody=jigLib.RigidBody;
  8570. var CollPointInfo=jigLib.CollPointInfo;
  8571. var CollisionInfo=jigLib.CollisionInfo;
  8572. /**
  8573. * @author Muzer(muzerly@gmail.com)
  8574. *
  8575. * @name CollDetectCapsuleCapsule
  8576. * @class CollDetectCapsuleCapsule handles collisions between capsules
  8577. * @extends CollDetectFunctor
  8578. * @requires CollDetectInfo
  8579. * @requires CollPointInfo
  8580. * @requires Vector3DUtil
  8581. * @requires JNumber3D
  8582. * @requires JMatrix3D
  8583. * @requires JSegment
  8584. * @requires MaterialProperties
  8585. * @constructor
  8586. **/
  8587. var CollDetectCapsuleCapsule=function(){
  8588. this.name = "CapsuleCapsule";
  8589. this.type0 = "CAPSULE";
  8590. this.type1 = "CAPSULE";
  8591. };
  8592. jigLib.extend(CollDetectCapsuleCapsule,jigLib.CollDetectFunctor);
  8593. /**
  8594. * @function collDetect detects a collision and updates the info parameter
  8595. * @param {CollDetectInfo} info
  8596. * @param {array} collArray
  8597. * @type void
  8598. **/
  8599. CollDetectCapsuleCapsule.prototype.collDetect=function(info, collArr){
  8600. var capsule0 = info.body0;
  8601. var capsule1 = info.body1;
  8602. if (!capsule0.hitTestObject3D(capsule1)) {
  8603. return;
  8604. }
  8605. if (JConfig.aabbDetection && !capsule0.get_boundingBox().overlapTest(capsule1.get_boundingBox())) {
  8606. return;
  8607. }
  8608. var collPts = [];
  8609. var cpInfo;
  8610. var averageNormal = [0,0,0,0];
  8611. var oldSeg0= new JSegment(capsule0.getEndPos(capsule0.get_oldState()), JNumber3D.getScaleVector(capsule0.get_oldState().getOrientationCols()[1], -Vector3DUtil.get_length(capsule0)));
  8612. var newSeg0= new JSegment(capsule0.getEndPos(capsule0.get_currentState()), JNumber3D.getScaleVector(capsule0.get_currentState().getOrientationCols()[1], -Vector3DUtil.get_length(capsule0)));
  8613. var oldSeg1= new JSegment(capsule1.getEndPos(capsule1.get_oldState()), JNumber3D.getScaleVector(capsule1.get_oldState().getOrientationCols()[1], -Vector3DUtil.get_length(capsule1)));
  8614. var newSeg1 = new JSegment(capsule1.getEndPos(capsule1.get_currentState()), JNumber3D.getScaleVector(capsule1.get_currentState().getOrientationCols()[1], -Vector3DUtil.get_length(capsule1)));
  8615. var radSum = capsule0.get_radius() + capsule1.get_radius();
  8616. var oldObj = {};
  8617. var oldDistSq = oldSeg0.segmentSegmentDistanceSq(oldObj, oldSeg1);
  8618. var newObj = {};
  8619. var newDistSq = newSeg0.segmentSegmentDistanceSq(oldObj, newSeg1);
  8620. if (Math.min(oldDistSq, newDistSq) < Math.pow(radSum + JConfig.collToll, 2)){
  8621. var pos0 = oldSeg0.getPoint(oldObj.t0);
  8622. var pos1 = oldSeg1.getPoint(oldObj.t1);
  8623. var delta = Vector3DUtil.subtract(pos0, pos1);
  8624. var dist = Math.sqrt(oldDistSq);
  8625. var depth = radSum - dist;
  8626. if (dist > JNumber3D.NUM_TINY){
  8627. delta = JNumber3D.getDivideVector(delta, dist);
  8628. }else{
  8629. delta = Vector3DUtil.Y_AXIS;
  8630. JMatrix3D.multiplyVector(JMatrix3D.getRotationMatrix(0, 0, 1, 360 * Math.random()), delta);
  8631. }
  8632. var worldPos = Vector3DUtil.add(pos1, JNumber3D.getScaleVector(delta, capsule1.get_radius() - 0.5 * depth));
  8633. averageNormal = Vector3DUtil.add(averageNormal, delta);
  8634. cpInfo = new CollPointInfo();
  8635. cpInfo.r0 = Vector3DUtil.subtract(worldPos, capsule0.get_oldState().position);
  8636. cpInfo.r1 = Vector3DUtil.subtract(worldPos, capsule1.get_oldState().position);
  8637. cpInfo.initialPenetration = depth;
  8638. collPts.push(cpInfo);
  8639. }
  8640. oldSeg0 = new JSegment(capsule0.getBottomPos(capsule0.get_oldState()), JNumber3D.getScaleVector(capsule0.get_oldState().getOrientationCols()[1], Vector3DUtil.get_length(capsule0)));
  8641. newSeg0 = new JSegment(capsule0.getBottomPos(capsule0.get_currentState()), JNumber3D.getScaleVector(capsule0.get_currentState().getOrientationCols()[1], Vector3DUtil.get_length(capsule0)));
  8642. oldSeg1 = new JSegment(capsule1.getBottomPos(capsule1.get_oldState()), JNumber3D.getScaleVector(capsule1.get_oldState().getOrientationCols()[1], Vector3DUtil.get_length(capsule1)));
  8643. newSeg1 = new JSegment(capsule1.getBottomPos(capsule1.get_currentState()), JNumber3D.getScaleVector(capsule1.get_currentState().getOrientationCols()[1], Vector3DUtil.get_length(capsule1)));
  8644. oldObj = {};
  8645. oldDistSq = oldSeg0.segmentSegmentDistanceSq(oldObj, oldSeg1);
  8646. newObj = {};
  8647. newDistSq = newSeg0.segmentSegmentDistanceSq(oldObj, newSeg1);
  8648. if (Math.min(oldDistSq, newDistSq) < Math.pow(radSum + JConfig.collToll, 2)){
  8649. pos0 = oldSeg0.getPoint(oldObj.t0);
  8650. pos1 = oldSeg1.getPoint(oldObj.t1);
  8651. delta = Vector3DUtil.subtract(pos0, pos1);
  8652. dist = Math.sqrt(oldDistSq);
  8653. depth = radSum - dist;
  8654. if (dist > JNumber3D.NUM_TINY){
  8655. delta = JNumber3D.getDivideVector(delta, dist);
  8656. }else{
  8657. delta = Vector3DUtil.Y_AXIS;
  8658. JMatrix3D.multiplyVector(JMatrix3D.getRotationMatrix(0, 0, 1, 360 * Math.random()), delta);
  8659. }
  8660. worldPos = Vector3DUtil.add(pos1, JNumber3D.getScaleVector(delta, capsule1.get_radius() - 0.5 * depth));
  8661. averageNormal = Vector3DUtil.add(averageNormal, delta);
  8662. cpInfo = new CollPointInfo();
  8663. cpInfo.r0 = Vector3DUtil.subtract(worldPos, capsule0.get_oldState().position);
  8664. cpInfo.r1 = Vector3DUtil.subtract(worldPos, capsule1.get_oldState().position);
  8665. cpInfo.initialPenetration = depth;
  8666. collPts.push(cpInfo);
  8667. }
  8668. if (collPts.length > 0){
  8669. Vector3DUtil.normalize(averageNormal);
  8670. var collInfo = new CollisionInfo();
  8671. collInfo.objInfo = info;
  8672. collInfo.dirToBody = averageNormal;
  8673. collInfo.pointInfo = collPts;
  8674. var mat = new MaterialProperties();
  8675. mat.set_restitution(Math.sqrt(capsule0.get_material().get_restitution() * capsule1.get_material().get_restitution()));
  8676. mat.set_friction(Math.sqrt(capsule0.get_material().get_friction() * capsule1.get_material().get_friction()));
  8677. collInfo.mat = mat;
  8678. collArr.push(collInfo);
  8679. info.body0.collisions.push(collInfo);
  8680. info.body1.collisions.push(collInfo);
  8681. }
  8682. };
  8683. jigLib.CollDetectCapsuleCapsule=CollDetectCapsuleCapsule;
  8684. })(jigLib);
  8685. /*
  8686. Copyright (c) 2007 Danny Chapman
  8687. http://www.rowlhouse.co.uk
  8688. This software is provided 'as-is', without any express or implied
  8689. warranty. In no event will the authors be held liable for any damages
  8690. arising from the use of this software.
  8691. Permission is granted to anyone to use this software for any purpose,
  8692. including commercial applications, and to alter it and redistribute it
  8693. freely, subject to the following restrictions:
  8694. 1. The origin of this software must not be misrepresented; you must not
  8695. claim that you wrote the original software. If you use this software
  8696. in a product, an acknowledgment in the product documentation would be
  8697. appreciated but is not required.
  8698. 2. Altered source versions must be plainly marked as such, and must not be
  8699. misrepresented as being the original software.
  8700. 3. This notice may not be removed or altered from any source
  8701. distribution.
  8702. */
  8703. (function(jigLib){
  8704. var Vector3DUtil=jigLib.Vector3DUtil;
  8705. var JNumber3D=jigLib.JNumber3D;
  8706. var JConstraint=jigLib.JConstraint;
  8707. var JConfig=jigLib.JConfig;
  8708. var JCapsule=jigLib.JCapsule;
  8709. var JTerrain=jigLib.JPlane;
  8710. var MaterialProperties=jigLib.MaterialProperties;
  8711. var RigidBody=jigLib.RigidBody;
  8712. var CollPointInfo=jigLib.CollPointInfo;
  8713. var CollisionInfo=jigLib.CollisionInfo;
  8714. /**
  8715. * @author Muzer(muzerly@gmail.com)
  8716. *
  8717. * @name CollDetectCapsulePlane
  8718. * @class CollDetectCapsulePlane handles collisions between capsules and planes
  8719. * @extends CollDetectFunctor
  8720. * @requires CollDetectInfo
  8721. * @requires Vector3DUtil
  8722. * @requires JNumber3D
  8723. * @requires MaterialProperties
  8724. * @constructor
  8725. **/
  8726. var CollDetectCapsulePlane=function(){
  8727. this.name = "CapsulePlane";
  8728. this.type0 = "CAPSULE";
  8729. this.type1 = "PLANE";
  8730. };
  8731. jigLib.extend(CollDetectCapsulePlane,jigLib.CollDetectFunctor);
  8732. /**
  8733. * @function collDetect detects a collision and updates the info parameter
  8734. * @param {CollDetectInfo} info
  8735. * @param {array} collArray
  8736. * @type void
  8737. **/
  8738. CollDetectCapsulePlane.prototype.collDetect=function(info, collArr){
  8739. var tempBody;
  8740. if (info.body0.get_type() == "PLANE"){
  8741. tempBody = info.body0;
  8742. info.body0 = info.body1;
  8743. info.body1 = tempBody;
  8744. }
  8745. var capsule = info.body0;
  8746. var plane = info.body1;
  8747. var collPts = [];
  8748. var cpInfo;
  8749. var oldPos = capsule.getBottomPos(capsule.get_oldState());
  8750. var oldDist = plane.pointPlaneDistance(oldPos);
  8751. var newPos = capsule.getBottomPos(capsule.get_currentState());
  8752. var newDist = plane.pointPlaneDistance(newPos);
  8753. if (Math.min(oldDist, newDist) < capsule.get_radius() + JConfig.collToll){
  8754. var oldDepth= capsule.get_radius() - oldDist;
  8755. var worldPos= Vector3DUtil.subtract(oldPos, JNumber3D.getScaleVector(plane.get_normal(), capsule.get_radius()));
  8756. cpInfo = new CollPointInfo();
  8757. cpInfo.r0 = Vector3DUtil.subtract(worldPos, capsule.get_oldState().position);
  8758. cpInfo.r1 = Vector3DUtil.subtract(worldPos, plane.get_oldState().position);
  8759. cpInfo.initialPenetration = oldDepth;
  8760. collPts.push(cpInfo);
  8761. }
  8762. oldPos = capsule.getEndPos(capsule.get_oldState());
  8763. newPos = capsule.getEndPos(capsule.get_currentState());
  8764. oldDist = plane.pointPlaneDistance(oldPos);
  8765. newDist = plane.pointPlaneDistance(newPos);
  8766. if (Math.min(oldDist, newDist) < capsule.get_radius() + JConfig.collToll){
  8767. oldDepth = capsule.get_radius() - oldDist;
  8768. worldPos = Vector3DUtil.subtract(oldPos, JNumber3D.getScaleVector(plane.get_normal(), capsule.get_radius()));
  8769. cpInfo = new CollPointInfo();
  8770. cpInfo.r0 = Vector3DUtil.subtract(worldPos, capsule.get_oldState().position);
  8771. cpInfo.r1 = Vector3DUtil.subtract(worldPos, plane.get_oldState().position);
  8772. cpInfo.initialPenetration = oldDepth;
  8773. collPts.push(cpInfo);
  8774. }
  8775. if (collPts.length > 0){
  8776. var collInfo= new CollisionInfo();
  8777. collInfo.objInfo = info;
  8778. collInfo.dirToBody = plane.get_normal();
  8779. collInfo.pointInfo = collPts;
  8780. var mat = new MaterialProperties();
  8781. mat.set_restitution(Math.sqrt(capsule.get_material().get_restitution() * plane.get_material().get_restitution()));
  8782. mat.set_friction(Math.sqrt(capsule.get_material().get_friction() * plane.get_material().get_friction()));
  8783. collInfo.mat = mat;
  8784. collArr.push(collInfo);
  8785. info.body0.collisions.push(collInfo);
  8786. info.body1.collisions.push(collInfo);
  8787. }
  8788. };
  8789. jigLib.CollDetectCapsulePlane=CollDetectCapsulePlane;
  8790. })(jigLib);/*
  8791. Copyright (c) 2007 Danny Chapman
  8792. http://www.rowlhouse.co.uk
  8793. This software is provided 'as-is', without any express or implied
  8794. warranty. In no event will the authors be held liable for any damages
  8795. arising from the use of this software.
  8796. Permission is granted to anyone to use this software for any purpose,
  8797. including commercial applications, and to alter it and redistribute it
  8798. freely, subject to the following restrictions:
  8799. 1. The origin of this software must not be misrepresented; you must not
  8800. claim that you wrote the original software. If you use this software
  8801. in a product, an acknowledgment in the product documentation would be
  8802. appreciated but is not required.
  8803. 2. Altered source versions must be plainly marked as such, and must not be
  8804. misrepresented as being the original software.
  8805. 3. This notice may not be removed or altered from any source
  8806. distribution.
  8807. */
  8808. (function(jigLib){
  8809. var Vector3DUtil=jigLib.Vector3DUtil;
  8810. var JNumber3D=jigLib.JNumber3D;
  8811. var JConstraint=jigLib.JConstraint;
  8812. var JConfig=jigLib.JConfig;
  8813. var JCapsule=jigLib.JCapsule;
  8814. var JTerrain=jigLib.JTerrain;
  8815. var MaterialProperties=jigLib.MaterialProperties;
  8816. var RigidBody=jigLib.RigidBody;
  8817. /**
  8818. * @author Muzer(muzerly@gmail.com)
  8819. *
  8820. * @name CollDetectCapsuleTerrain
  8821. * @class CollDetectCapsuleTerrain handles collisions between capsules and terrain
  8822. * @extends CollDetectFunctor
  8823. * @requires CollDetectInfo
  8824. * @requires CollPointInfo
  8825. * @requires Vector3DUtil
  8826. * @requires JNumber3D
  8827. * @requires CollisionInfo
  8828. * @requires MaterialProperties
  8829. * @constructor
  8830. **/
  8831. var CollDetectCapsuleTerrain=function(){
  8832. this.name = "BoxTerrain";
  8833. this.type0 = "CAPSULE";
  8834. this.type1 = "TERRAIN";
  8835. };
  8836. jigLib.extend(CollDetectCapsuleTerrain,jigLib.CollDetectFunctor);
  8837. /**
  8838. * @function collDetect detects a collision and updates the info parameter
  8839. * @param {CollDetectInfo} info
  8840. * @param {array} collArray
  8841. * @type void
  8842. **/
  8843. CollDetectCapsuleTerrain.prototype.collDetect=function(info, collArr){
  8844. var tempBody;
  8845. if (info.body0.type == "TERRAIN"){
  8846. tempBody = info.body0;
  8847. info.body0 = info.body1;
  8848. info.body1 = tempBody;
  8849. }
  8850. var capsule = info.body0;
  8851. var terrain = info.body1;
  8852. var collPts = [];
  8853. var cpInfo;
  8854. var averageNormal= [0,0,0,0];
  8855. var pos1 = capsule.getBottomPos(capsule.oldState);
  8856. var pos2 = capsule.getBottomPos(capsule.currentState);
  8857. var obj1= terrain.getHeightAndNormalByPoint(pos1);
  8858. var obj2 = terrain.getHeightAndNormalByPoint(pos2);
  8859. if (Math.min(obj1.height, obj2.height) < JConfig.collToll + capsule.radius) {
  8860. var oldDepth = capsule.radius - obj1.height;
  8861. var worldPos = Vector3DUtil.subtract(pos1, JNumber3D.getScaleVector(obj2.normal, capsule.radius));
  8862. cpInfo = new CollPointInfo();
  8863. cpInfo.r0 = Vector3DUtil.subtract(worldPos, capsule.oldState.position);
  8864. cpInfo.r1 = Vector3DUtil.subtract(worldPos, terrain.oldState.position);
  8865. cpInfo.initialPenetration = oldDepth;
  8866. collPts.push(cpInfo);
  8867. averageNormal = Vector3DUtil.add(averageNormal, obj2.normal);
  8868. }
  8869. pos1 = capsule.getEndPos(capsule.oldState);
  8870. pos2 = capsule.getEndPos(capsule.currentState);
  8871. obj1 = terrain.getHeightAndNormalByPoint(pos1);
  8872. obj2 = terrain.getHeightAndNormalByPoint(pos2);
  8873. if (Math.min(obj1.height, obj2.height) < JConfig.collToll + capsule.radius) {
  8874. oldDepth = capsule.radius - obj1.height;
  8875. worldPos = Vector3DUtil.subtract(pos1, JNumber3D.getScaleVector(obj2.normal, capsule.radius));
  8876. cpInfo = new CollPointInfo();
  8877. cpInfo.r0 = Vector3DUtil.subtract(worldPos, capsule.oldState.position);
  8878. cpInfo.r1 = Vector3DUtil.subtract(worldPos, terrain.oldState.position);
  8879. cpInfo.initialPenetration = oldDepth;
  8880. collPts.push(cpInfo);
  8881. averageNormal = Vector3DUtil.add(averageNormal, obj2.normal);
  8882. }
  8883. if (collPts.length > 0){
  8884. Vector3DUtil.normalize(averageNormal);
  8885. var collInfo = new CollisionInfo();
  8886. collInfo.objInfo = info;
  8887. collInfo.dirToBody = averageNormal;
  8888. collInfo.pointInfo = collPts;
  8889. var mat = new MaterialProperties();
  8890. mat.restitution = Math.sqrt(capsule.material.restitution * terrain.material.restitution);
  8891. mat.friction = Math.sqrt(capsule.material.friction * terrain.material.friction);
  8892. collInfo.mat = mat;
  8893. collArr.push(collInfo);
  8894. info.body0.collisions.push(collInfo);
  8895. info.body1.collisions.push(collInfo);
  8896. }
  8897. };
  8898. jigLib.CollDetectCapsuleTerrain=CollDetectCapsuleTerrain;
  8899. })(jigLib);/*
  8900. Copyright (c) 2007 Danny Chapman
  8901. http://www.rowlhouse.co.uk
  8902. This software is provided 'as-is', without any express or implied
  8903. warranty. In no event will the authors be held liable for any damages
  8904. arising from the use of this software.
  8905. Permission is granted to anyone to use this software for any purpose,
  8906. including commercial applications, and to alter it and redistribute it
  8907. freely, subject to the following restrictions:
  8908. 1. The origin of this software must not be misrepresented; you must not
  8909. claim that you wrote the original software. If you use this software
  8910. in a product, an acknowledgment in the product documentation would be
  8911. appreciated but is not required.
  8912. 2. Altered source versions must be plainly marked as such, and must not be
  8913. misrepresented as being the original software.
  8914. 3. This notice may not be removed or altered from any source
  8915. distribution.
  8916. */
  8917. (function(jigLib){
  8918. var Vector3DUtil=jigLib.Vector3DUtil;
  8919. var JNumber3D=jigLib.JNumber3D;
  8920. var JConfig=jigLib.JConfig;
  8921. var MaterialProperties=jigLib.MaterialProperties;
  8922. var CollPointInfo=jigLib.CollPointInfo;
  8923. var CollisionInfo=jigLib.CollisionInfo;
  8924. /**
  8925. * @author Muzer(muzerly@gmail.com)
  8926. *
  8927. * @name CollDetectSphereBox
  8928. * @class CollDetectSphereBox handles collisions between spheres and boxes
  8929. * @extends CollDetectFunctor
  8930. * @requires CollDetectInfo
  8931. * @requires CollPointInfo
  8932. * @requires CollisionInfo
  8933. * @requires Vector3DUtil
  8934. * @requires JNumber3D
  8935. * @requires JConfig
  8936. * @requires MaterialProperties
  8937. * @constructor
  8938. **/
  8939. var CollDetectSphereBox=function(){
  8940. this.name = "SphereBox";
  8941. this.type0 = "SPHERE";
  8942. this.type1 = "BOX";
  8943. };
  8944. jigLib.extend(CollDetectSphereBox,jigLib.CollDetectFunctor);
  8945. /**
  8946. * @function collDetect detects a collision and updates the info parameter
  8947. * @param {CollDetectInfo} info
  8948. * @param {array} collArray
  8949. * @type void
  8950. **/
  8951. CollDetectSphereBox.prototype.collDetect=function(info, collArr){
  8952. var tempBody;
  8953. if(info.body0.get_type()=="BOX") {
  8954. tempBody=info.body0;
  8955. info.body0=info.body1;
  8956. info.body1=tempBody;
  8957. }
  8958. var sphere = info.body0;
  8959. var box = info.body1;
  8960. if (!sphere.hitTestObject3D(box))
  8961. return;
  8962. if (JConfig.aabbDetection && !sphere.get_boundingBox().overlapTest(box.get_boundingBox()))
  8963. return;
  8964. //var spherePos:Vector3D = sphere.get_oldState().position;
  8965. //var boxPos:Vector3D = box.get_oldState().position;
  8966. var oldBoxPoint={};
  8967. var newBoxPoint={};
  8968. var oldDist = box.getDistanceToPoint(box.get_oldState(), oldBoxPoint, sphere.get_oldState().position);
  8969. var newDist = box.getDistanceToPoint(box.get_currentState(), newBoxPoint, sphere.get_currentState().position);
  8970. var oldDepth = sphere.get_radius() - oldDist;
  8971. var newDepth = sphere.get_radius() - newDist;
  8972. if (Math.max(oldDepth, newDepth) > -JConfig.collToll) {
  8973. var dir;
  8974. var collPts = [];
  8975. if (oldDist < -JNumber3D.NUM_TINY) {
  8976. dir = Vector3DUtil.subtract(Vector3DUtil.subtract(oldBoxPoint.pos,
  8977. sphere.get_oldState().position),
  8978. oldBoxPoint.pos);
  8979. Vector3DUtil.normalize(dir);
  8980. }else if (oldDist > JNumber3D.NUM_TINY) {
  8981. dir = Vector3DUtil.subtract(sphere.get_oldState().position, oldBoxPoint.pos);
  8982. Vector3DUtil.normalize(dir);
  8983. }else{
  8984. dir = Vector3DUtil.subtract(sphere.get_oldState().position, box.get_oldState().position);
  8985. Vector3DUtil.normalize(dir);
  8986. }
  8987. var cpInfo = new CollPointInfo();
  8988. cpInfo.r0 = Vector3DUtil.subtract(oldBoxPoint.pos, sphere.get_oldState().position);
  8989. cpInfo.r1 = Vector3DUtil.subtract(oldBoxPoint.pos, box.get_oldState().position);
  8990. cpInfo.initialPenetration = oldDepth;
  8991. collPts.push(cpInfo);
  8992. var collInfo=new CollisionInfo();
  8993. collInfo.objInfo=info;
  8994. collInfo.dirToBody = dir;
  8995. collInfo.pointInfo = collPts;
  8996. var mat = new MaterialProperties();
  8997. mat.set_restitution(Math.sqrt(sphere.get_material().get_restitution() * box.get_material().get_restitution()));
  8998. mat.set_friction(Math.sqrt(sphere.get_material().get_friction() * box.get_material().get_friction()));
  8999. collInfo.mat = mat;
  9000. collArr.push(collInfo);
  9001. info.body0.collisions.push(collInfo);
  9002. info.body1.collisions.push(collInfo);
  9003. }
  9004. };
  9005. jigLib.CollDetectSphereBox=CollDetectSphereBox;
  9006. })(jigLib);/*
  9007. Copyright (c) 2007 Danny Chapman
  9008. http://www.rowlhouse.co.uk
  9009. This software is provided 'as-is', without any express or implied
  9010. warranty. In no event will the authors be held liable for any damages
  9011. arising from the use of this software.
  9012. Permission is granted to anyone to use this software for any purpose,
  9013. including commercial applications, and to alter it and redistribute it
  9014. freely, subject to the following restrictions:
  9015. 1. The origin of this software must not be misrepresented; you must not
  9016. claim that you wrote the original software. If you use this software
  9017. in a product, an acknowledgment in the product documentation would be
  9018. appreciated but is not required.
  9019. 2. Altered source versions must be plainly marked as such, and must not be
  9020. misrepresented as being the original software.
  9021. 3. This notice may not be removed or altered from any source
  9022. distribution.
  9023. */
  9024. (function(jigLib){
  9025. var Vector3DUtil=jigLib.Vector3DUtil;
  9026. var JMatrix3D=jigLib.JMatrix3D;
  9027. var JNumber3D=jigLib.JNumber3D;
  9028. var JConstraint=jigLib.JConstraint;
  9029. var JConfig=jigLib.JConfig;
  9030. var JSphere=jigLib.JSphere;
  9031. var JSegment=jigLib.JSegment;
  9032. var MaterialProperties=jigLib.MaterialProperties;
  9033. var RigidBody=jigLib.RigidBody;
  9034. var CollPointInfo=jigLib.CollPointInfo;
  9035. var CollisionInfo=jigLib.CollisionInfo;
  9036. /**
  9037. * @author Muzer(muzerly@gmail.com)
  9038. *
  9039. * @name CollDetectSphereCapsule
  9040. * @class CollDetectSphereCapsule handles collisions between spheres and capsules
  9041. * @extends CollDetectFunctor
  9042. * @requires CollDetectInfo
  9043. * @requires CollPointInfo
  9044. * @requires CollisionInfo
  9045. * @requires Vector3DUtil
  9046. * @requires JNumber3D
  9047. * @requires JMatrix3D
  9048. * @requires JSegment
  9049. * @requires MaterialProperties
  9050. * @constructor
  9051. **/
  9052. var CollDetectSphereCapsule=function(){
  9053. this.name = "SphereCapsule";
  9054. this.type0 = "SPHERE";
  9055. this.type1 = "CAPSULE";
  9056. };
  9057. jigLib.extend(CollDetectSphereCapsule,jigLib.CollDetectFunctor);
  9058. /**
  9059. * @function collDetect detects a collision and updates the info parameter
  9060. * @param {CollDetectInfo} info
  9061. * @param {array} collArray
  9062. * @type void
  9063. **/
  9064. CollDetectSphereCapsule.prototype.collDetect=function(info, collArr){
  9065. var tempBody;
  9066. if (info.body0.get_type() == "CAPSULE"){
  9067. tempBody = info.body0;
  9068. info.body0 = info.body1;
  9069. info.body1 = tempBody;
  9070. }
  9071. var sphere = info.body0;
  9072. var capsule= info.body1;
  9073. if (!sphere.hitTestObject3D(capsule)){
  9074. return;
  9075. }
  9076. if (JConfig.aabbDetection && !sphere.get_boundingBox().overlapTest(capsule.get_boundingBox())) {
  9077. return;
  9078. }
  9079. var oldSeg = new JSegment(capsule.getBottomPos(capsule.get_oldState()), JNumber3D.getScaleVector(capsule.get_oldState().getOrientationCols()[1], Vector3DUtil.get_length(capsule) + 2 * capsule.get_radius()));
  9080. var newSeg = new JSegment(capsule.getBottomPos(capsule.get_currentState()), JNumber3D.getScaleVector(capsule.get_currentState().getOrientationCols()[1], Vector3DUtil.get_length(capsule) + 2 * capsule.get_radius()));
  9081. var radSum = sphere.get_radius() + capsule.get_radius();
  9082. var oldObj = {};
  9083. var oldDistSq = oldSeg.pointSegmentDistanceSq(oldObj, sphere.get_oldState().position);
  9084. var newObj = {};
  9085. var newDistSq = newSeg.pointSegmentDistanceSq(newObj, sphere.get_currentState().position);
  9086. if (Math.min(oldDistSq, newDistSq) < Math.pow(radSum + JConfig.collToll, 2)){
  9087. var segPos = oldSeg.getPoint(oldObj.t);
  9088. var delta = Vector3DUtil.subtract(sphere.get_oldState().position, segPos);
  9089. var dist = Math.sqrt(oldDistSq);
  9090. var depth = radSum - dist;
  9091. if (dist > JNumber3D.NUM_TINY){
  9092. delta = JNumber3D.getDivideVector(delta, dist);
  9093. }else{
  9094. delta = Vector3DUtil.Y_AXIS;
  9095. JMatrix3D.multiplyVector(JMatrix3D.getRotationMatrix(0, 0, 1, 360 * Math.random()), delta);
  9096. }
  9097. var worldPos = Vector3DUtil.add(segPos, JNumber3D.getScaleVector(delta, capsule.get_radius() - 0.5 * depth));
  9098. var collPts = [];
  9099. var cpInfo = new CollPointInfo();
  9100. cpInfo.r0 = Vector3DUtil.subtract(worldPos, sphere.get_oldState().position);
  9101. cpInfo.r1 = Vector3DUtil.subtract(worldPos, capsule.get_oldState().position);
  9102. cpInfo.initialPenetration = depth;
  9103. collPts.push(cpInfo);
  9104. var collInfo = new CollisionInfo();
  9105. collInfo.objInfo = info;
  9106. collInfo.dirToBody = delta;
  9107. collInfo.pointInfo = collPts;
  9108. var mat = new MaterialProperties();
  9109. mat.set_restitution(Math.sqrt(sphere.get_material().get_restitution() * capsule.get_material().get_restitution()));
  9110. mat.set_friction(Math.sqrt(sphere.get_material().get_friction() * capsule.get_material().get_friction()));
  9111. collInfo.mat = mat;
  9112. collArr.push(collInfo);
  9113. info.body0.collisions.push(collInfo);
  9114. info.body1.collisions.push(collInfo);
  9115. }
  9116. };
  9117. jigLib.CollDetectSphereCapsule=CollDetectSphereCapsule;
  9118. })(jigLib);
  9119. /*
  9120. Copyright (c) 2007 Danny Chapman
  9121. http://www.rowlhouse.co.uk
  9122. This software is provided 'as-is', without any express or implied
  9123. warranty. In no event will the authors be held liable for any damages
  9124. arising from the use of this software.
  9125. Permission is granted to anyone to use this software for any purpose,
  9126. including commercial applications, and to alter it and redistribute it
  9127. freely, subject to the following restrictions:
  9128. 1. The origin of this software must not be misrepresented; you must not
  9129. claim that you wrote the original software. If you use this software
  9130. in a product, an acknowledgment in the product documentation would be
  9131. appreciated but is not required.
  9132. 2. Altered source versions must be plainly marked as such, and must not be
  9133. misrepresented as being the original software.
  9134. 3. This notice may not be removed or altered from any source
  9135. distribution.
  9136. */
  9137. (function(jigLib){
  9138. var Vector3DUtil=jigLib.Vector3DUtil;
  9139. var JNumber3D=jigLib.JNumber3D;
  9140. var JConstraint=jigLib.JConstraint;
  9141. var JConfig=jigLib.JConfig;
  9142. var JSphere=jigLib.JSphere;
  9143. var MaterialProperties=jigLib.MaterialProperties;
  9144. var RigidBody=jigLib.RigidBody;
  9145. var CollPointInfo=jigLib.CollPointInfo;
  9146. var CollisionInfo=jigLib.CollisionInfo;
  9147. /**
  9148. * @author Muzer(muzerly@gmail.com)
  9149. *
  9150. * @name CollDetectSpherePlane
  9151. * @class CollDetectSpherePlane handles collisions between spheres and planes
  9152. * @extends CollDetectFunctor
  9153. * @requires CollDetectInfo
  9154. * @requires CollisionInfo
  9155. * @requires Vector3DUtil
  9156. * @requires JNumber3D
  9157. * @requires MaterialProperties
  9158. * @constructor
  9159. **/
  9160. var CollDetectSpherePlane=function(){
  9161. this.name = "SpherePlane";
  9162. this.type0 = "SPHERE";
  9163. this.type1 = "PLANE";
  9164. };
  9165. jigLib.extend(CollDetectSpherePlane,jigLib.CollDetectFunctor);
  9166. /**
  9167. * @function collDetect detects a collision and updates the info parameter
  9168. * @param {CollDetectInfo} info
  9169. * @param {array} collArray
  9170. * @type void
  9171. **/
  9172. CollDetectSpherePlane.prototype.collDetect=function(info, collArr){
  9173. var tempBody;
  9174. if (info.body0.get_type() == "PLANE"){
  9175. tempBody = info.body0;
  9176. info.body0 = info.body1;
  9177. info.body1 = tempBody;
  9178. }
  9179. var sphere = info.body0;
  9180. var plane = info.body1;
  9181. var oldDist = plane.pointPlaneDistance(sphere.get_oldState().position);
  9182. var newDist = plane.pointPlaneDistance(sphere.get_currentState().position);
  9183. if (Math.min(newDist, oldDist) > sphere.get_boundingSphere() + JConfig.collToll){
  9184. return;
  9185. }
  9186. var collPts = [];
  9187. var cpInfo;
  9188. var depth = sphere.get_radius() - oldDist;
  9189. var worldPos = Vector3DUtil.subtract(sphere.get_oldState().position, JNumber3D.getScaleVector(plane.get_normal(), sphere.get_radius()));
  9190. cpInfo = new CollPointInfo();
  9191. cpInfo.r0 = Vector3DUtil.subtract(worldPos, sphere.get_oldState().position);
  9192. cpInfo.r1 = Vector3DUtil.subtract(worldPos, plane.get_oldState().position);
  9193. cpInfo.initialPenetration = depth;
  9194. collPts.push(cpInfo);
  9195. var collInfo = new CollisionInfo();
  9196. collInfo.objInfo = info;
  9197. collInfo.dirToBody = plane.get_normal();
  9198. collInfo.pointInfo = collPts;
  9199. var mat = new MaterialProperties();
  9200. mat.set_restitution(Math.sqrt(sphere.get_material().get_restitution() * plane.get_material().get_restitution()));
  9201. mat.set_friction(Math.sqrt(sphere.get_material().get_friction() * plane.get_material().get_friction()));
  9202. collInfo.mat = mat;
  9203. collArr.push(collInfo);
  9204. info.body0.collisions.push(collInfo);
  9205. info.body1.collisions.push(collInfo);
  9206. };
  9207. jigLib.CollDetectSpherePlane=CollDetectSpherePlane;
  9208. })(jigLib);/*
  9209. Copyright (c) 2007 Danny Chapman
  9210. http://www.rowlhouse.co.uk
  9211. This software is provided 'as-is', without any express or implied
  9212. warranty. In no event will the authors be held liable for any damages
  9213. arising from the use of this software.
  9214. Permission is granted to anyone to use this software for any purpose,
  9215. including commercial applications, and to alter it and redistribute it
  9216. freely, subject to the following restrictions:
  9217. 1. The origin of this software must not be misrepresented; you must not
  9218. claim that you wrote the original software. If you use this software
  9219. in a product, an acknowledgment in the product documentation would be
  9220. appreciated but is not required.
  9221. 2. Altered source versions must be plainly marked as such, and must not be
  9222. misrepresented as being the original software.
  9223. 3. This notice may not be removed or altered from any source
  9224. distribution.
  9225. */
  9226. (function(jigLib){
  9227. var Vector3DUtil=jigLib.Vector3DUtil;
  9228. var JMatrix3D=jigLib.JMatrix3D;
  9229. var JNumber3D=jigLib.JNumber3D;
  9230. var JConstraint=jigLib.JConstraint;
  9231. var JConfig=jigLib.JConfig;
  9232. var JSphere=jigLib.JSphere;
  9233. var MaterialProperties=jigLib.MaterialProperties;
  9234. var CollPointInfo=jigLib.CollPointInfo;
  9235. var CollisionInfo=jigLib.CollisionInfo;
  9236. /**
  9237. * @author Muzer(muzerly@gmail.com)
  9238. *
  9239. * @name CollDetectSphereSphere
  9240. * @class CollDetectSphereSphere handles collisions between spheres
  9241. * @extends CollDetectFunctor
  9242. * @requires CollDetectInfo
  9243. * @requires CollPointInfo
  9244. * @requires CollisionInfo
  9245. * @requires Vector3DUtil
  9246. * @requires JNumber3D
  9247. * @requires JMatrix3D
  9248. * @requires MaterialProperties
  9249. * @constructor
  9250. **/
  9251. var CollDetectSphereSphere=function(){
  9252. this.name = "SphereSphere";
  9253. this.type0 = "SPHERE";
  9254. this.type1 = "SPHERE";
  9255. };
  9256. jigLib.extend(CollDetectSphereSphere,jigLib.CollDetectFunctor);
  9257. /**
  9258. * @function collDetect detects a collision and updates the info parameter
  9259. * @param {CollDetectInfo} info
  9260. * @param {array} collArray
  9261. * @type void
  9262. **/
  9263. CollDetectSphereSphere.prototype.collDetect=function(info, collArr){
  9264. var sphere0 = info.body0;
  9265. var sphere1 = info.body1;
  9266. var oldDelta = Vector3DUtil.subtract(sphere0.get_oldState().position, sphere1.get_oldState().position);
  9267. var newDelta = Vector3DUtil.subtract(sphere0.get_currentState().position, sphere1.get_currentState().position);
  9268. var oldDistSq = Vector3DUtil.get_lengthSquared(oldDelta);
  9269. var newDistSq = Vector3DUtil.get_lengthSquared(newDelta);
  9270. var radSum = sphere0.get_radius() + sphere1.get_radius();
  9271. if (Math.min(oldDistSq, newDistSq) < Math.pow(radSum + JConfig.collToll, 2)){
  9272. var oldDist = Math.sqrt(oldDistSq);
  9273. var depth = radSum - oldDist;
  9274. if (oldDist > JNumber3D.NUM_TINY){
  9275. oldDelta = JNumber3D.getDivideVector(oldDelta, oldDist);
  9276. }else{
  9277. oldDelta = Vector3DUtil.Y_AXIS;
  9278. JMatrix3D.multiplyVector(JMatrix3D.getRotationMatrix(0, 0, 1, 360 * Math.random()), oldDelta);
  9279. }
  9280. var worldPos = Vector3DUtil.add(sphere1.get_oldState().position, JNumber3D.getScaleVector(oldDelta, sphere1.get_radius() - 0.5 * depth));
  9281. var collPts = [];
  9282. var cpInfo = new CollPointInfo();
  9283. cpInfo.r0 = Vector3DUtil.subtract(worldPos, sphere0.get_oldState().position);
  9284. cpInfo.r1 = Vector3DUtil.subtract(worldPos, sphere1.get_oldState().position);
  9285. cpInfo.initialPenetration = depth;
  9286. collPts.push(cpInfo);
  9287. var collInfo = new CollisionInfo();
  9288. collInfo.objInfo = info;
  9289. collInfo.dirToBody = oldDelta;
  9290. collInfo.pointInfo = collPts;
  9291. var mat = new MaterialProperties();
  9292. mat.set_restitution(Math.sqrt(sphere0.get_material().get_restitution() * sphere1.get_material().get_restitution()));
  9293. mat.set_friction(Math.sqrt(sphere0.get_material().get_friction() * sphere1.get_material().get_friction()));
  9294. collInfo.mat = mat;
  9295. collArr.push(collInfo);
  9296. info.body0.collisions.push(collInfo);
  9297. info.body1.collisions.push(collInfo);
  9298. }
  9299. };
  9300. jigLib.CollDetectSphereSphere=CollDetectSphereSphere;
  9301. })(jigLib);/*
  9302. Copyright (c) 2007 Danny Chapman
  9303. http://www.rowlhouse.co.uk
  9304. This software is provided 'as-is', without any express or implied
  9305. warranty. In no event will the authors be held liable for any damages
  9306. arising from the use of this software.
  9307. Permission is granted to anyone to use this software for any purpose,
  9308. including commercial applications, and to alter it and redistribute it
  9309. freely, subject to the following restrictions:
  9310. 1. The origin of this software must not be misrepresented; you must not
  9311. claim that you wrote the original software. If you use this software
  9312. in a product, an acknowledgment in the product documentation would be
  9313. appreciated but is not required.
  9314. 2. Altered source versions must be plainly marked as such, and must not be
  9315. misrepresented as being the original software.
  9316. 3. This notice may not be removed or altered from any source
  9317. distribution.
  9318. */
  9319. (function(jigLib){
  9320. var Vector3DUtil=jigLib.Vector3DUtil;
  9321. var JNumber3D=jigLib.JNumber3D;
  9322. var JConstraint=jigLib.JConstraint;
  9323. var JConfig=jigLib.JConfig;
  9324. var JSphere=jigLib.JSphere;
  9325. var JTerrain=jigLib.JTerrain;
  9326. var MaterialProperties=jigLib.MaterialProperties;
  9327. var RigidBody=jigLib.RigidBody;
  9328. /**
  9329. * @author Muzer(muzerly@gmail.com)
  9330. *
  9331. * @name CollDetectSphereTerrain
  9332. * @class CollDetectSphereTerrain handles collisions between spheres and terrain
  9333. * @extends CollDetectFunctor
  9334. * @requires CollDetectInfo
  9335. * @requires CollPointInfo
  9336. * @requires CollisionInfo
  9337. * @requires Vector3DUtil
  9338. * @requires JNumber3D
  9339. * @requires MaterialProperties
  9340. * @constructor
  9341. **/
  9342. var CollDetectSphereTerrain=function(){
  9343. this.name = "SphereTerrain";
  9344. this.type0 = "SPHERE";
  9345. this.type1 = "TERRAIN";
  9346. };
  9347. jigLib.extend(CollDetectSphereTerrain,jigLib.CollDetectFunctor);
  9348. /**
  9349. * @function collDetect detects a collision and updates the info parameter
  9350. * @param {CollDetectInfo} info
  9351. * @param {array} collArray
  9352. * @type void
  9353. **/
  9354. CollDetectSphereTerrain.prototype.collDetect=function(info, collArr){
  9355. var tempBody;
  9356. if (info.body0.type == "TERRAIN"){
  9357. tempBody = info.body0;
  9358. info.body0 = info.body1;
  9359. info.body1 = tempBody;
  9360. }
  9361. var sphere = info.body0;
  9362. var terrain = info.body1;
  9363. var obj = terrain.getHeightAndNormalByPoint(sphere.currentState.position);
  9364. if (obj.height < JConfig.collToll + sphere.radius) {
  9365. var dist = terrain.getHeightByPoint(sphere.oldState.position);
  9366. var depth = sphere.radius - dist;
  9367. var Pt = Vector3DUtil.subtract(sphere.oldState.position, JNumber3D.getScaleVector(obj.normal, sphere.radius));
  9368. var collPts = [];
  9369. var cpInfo = new CollPointInfo();
  9370. cpInfo.r0 = Vector3DUtil.subtract(Pt, sphere.oldState.position);
  9371. cpInfo.r1 = Vector3DUtil.subtract(Pt, terrain.oldState.position);
  9372. cpInfo.initialPenetration = depth;
  9373. collPts.push(cpInfo);
  9374. var collInfo = new CollisionInfo();
  9375. collInfo.objInfo = info;
  9376. collInfo.dirToBody = obj.normal;
  9377. collInfo.pointInfo = collPts;
  9378. var mat = new MaterialProperties();
  9379. mat.restitution = Math.sqrt(sphere.material.restitution * terrain.material.restitution);
  9380. mat.friction = Math.sqrt(sphere.material.friction * terrain.material.friction);
  9381. collInfo.mat = mat;
  9382. collArr.push(collInfo);
  9383. info.body0.collisions.push(collInfo);
  9384. info.body1.collisions.push(collInfo);
  9385. }
  9386. };
  9387. jigLib.CollDetectSphereTerrain=CollDetectSphereTerrain;
  9388. })(jigLib);(function(jigLib){
  9389. var Vector3DUtil=jigLib.Vector3DUtil;
  9390. var JNumber3D=jigLib.JNumber3D;
  9391. var JConstraint=jigLib.JConstraint;
  9392. var JConfig=jigLib.JConfig;
  9393. var JSphere=jigLib.JSphere;
  9394. var MaterialProperties=jigLib.MaterialProperties;
  9395. var RigidBody=jigLib.RigidBody;
  9396. var CollPointInfo=jigLib.CollPointInfo;
  9397. var CollisionInfo=jigLib.CollisionInfo;
  9398. var JBox=jigLib.JBox;
  9399. var JIndexedTriangle=jigLib.JIndexedTriangle;
  9400. var JSegment=jigLib.JSegment;
  9401. var JTriangle=jigLib.JTriangle;
  9402. var JTriangleMesh=jigLib.JTriangleMesh;
  9403. var CollOutData=jigLib.CollOutData;
  9404. var EdgeData=jigLib.EdgeData;
  9405. var SpanData=jigLib.SpanDatadot
  9406. ;
  9407. var SpanData=jigLib.SpanData;
  9408. var CollDetectBoxMesh=function(){
  9409. this.name = "BoxMesh";
  9410. this.type0 = "BOX";
  9411. this.type1 = "TRIANGLEMESH";
  9412. };
  9413. jigLib.extend(CollDetectBoxMesh,jigLib.CollDetectFunctor);
  9414. CollDetectBoxMesh.prototype.disjoint=function(out, axis, box, triangle){
  9415. var obj0 = box.getSpan(axis);
  9416. var obj1 = triangle.getSpan(axis);
  9417. var obj0Min=obj0.min,obj0Max=obj0.max,obj1Min=obj1.min,obj1Max=obj1.max,tiny=JNumber3D.NUM_TINY;
  9418. if (obj0Min > (obj1Max + JConfig.collToll + tiny) || obj1Min > (obj0Max + JConfig.collToll + tiny)){
  9419. out.flag = true;
  9420. return true;
  9421. }
  9422. if ((obj0Max > obj1Max) && (obj1Min > obj0Min)){
  9423. out.depth = Math.min(obj0Max - obj1Min, obj1Max - obj0Min);
  9424. }else if ((obj1Max > obj0Max) && (obj0Min > obj1Min)){
  9425. out.depth = Math.min(obj1Max - obj0Min, obj0Max - obj1Min);
  9426. }else{
  9427. out.depth = Math.min(obj0Max, obj1Max);
  9428. out.depth -= Math.max(obj0Min, obj1Min);
  9429. }
  9430. out.flag = false;
  9431. return false;
  9432. };
  9433. CollDetectBoxMesh.prototype.addPoint=function(contactPoints, pt, combinationDistanceSq){
  9434. for(var i=0; i<contactPoints.length;i++){
  9435. var contactPoint=contactPoints[i];
  9436. if (Vector3DUtil.get_lengthSquared(Vector3DUtil.subtract(contactPoint,pt))< combinationDistanceSq){
  9437. contactPoint = Vector3DUtil.add(contactPoint,pt);
  9438. Vector3DUtil.scaleBy(contactPoint,0.5);
  9439. return false;
  9440. }
  9441. }
  9442. contactPoints.push(pt);
  9443. return true;
  9444. };
  9445. CollDetectBoxMesh.prototype.getBoxTriangleIntersectionPoints=function(pts,box,triangle,combinationDistanceSq){
  9446. var edges=box.get_edges();
  9447. var boxPts=box.getCornerPoints(box.get_currentState());
  9448. var data;
  9449. var edge;
  9450. var seg;
  9451. for(var i=0;i<12;i++){
  9452. edge=edges[i];
  9453. data=new CollOutData();
  9454. seg=new JSegment(boxPts[edge.ind0],Vector3DUtil.subtract(boxPts[edge.ind1],boxPts[edge.ind0]));
  9455. if(triangle.segmentTriangleIntersection(data,seg)){
  9456. this.addPoint(pts,seg.getPoint(data.frac),combinationDistanceSq);
  9457. if(pts.length>8) return pts.length;
  9458. }
  9459. }
  9460. var pt0,pt1;
  9461. for(i=0;i<3;i++){
  9462. pt0=triangle.getVertex(i);
  9463. pt1=triangle.getVertex((i+1)%3);
  9464. data=new CollOutData();
  9465. if(box.segmentIntersect(data,new JSegment(pt0,Vector3DUtil.subtract(pt1,pt0)),box.get_currentState())){
  9466. this.addPoint(pts,data.position,combinationDistanceSq);
  9467. if(pts.length>8) return pts.length;
  9468. }
  9469. if(box.segmentIntersect(data,new JSegment(pt1,Vector3DUtil.subtract(pt0,pt1)),box.get_currentState())){
  9470. this.addPoint(pts,data.position,combinationDistanceSq);
  9471. if(pts.length>8) return pts.length;
  9472. }
  9473. }
  9474. return pts.length;
  9475. };
  9476. CollDetectBoxMesh.prototype.doOverlapBoxTriangleTest=function(box,triangle,mesh,info,collArr){
  9477. var triEdge0,triEdge1,triEdge2,triNormal,D,N,boxOldPos,boxNewPos,meshPos,delta;
  9478. var dirs0=box.get_currentState().getOrientationCols();
  9479. var tri=new JTriangle(mesh.get_octree().getVertex(triangle.getVertexIndex(0)),mesh.get_octree().getVertex(triangle.getVertexIndex(1)),mesh.get_octree().getVertex(triangle.getVertexIndex(2)));
  9480. triEdge0=Vector3DUtil.subtract(tri.getVertex(1),tri.getVertex(0));
  9481. Vector3DUtil.normalize(triEdge0);
  9482. triEdge1=Vector3DUtil.subtract(tri.getVertex(2),tri.getVertex(1));
  9483. Vector3DUtil.normalize(triEdge1);
  9484. triEdge2=Vector3DUtil.subtract(tri.getVertex(0),tri.getVertex(2));
  9485. Vector3DUtil.normalize(triEdge2);
  9486. var triNormal=triangle.get_plane().normal.slice(0);
  9487. var numAxes=13;
  9488. var axes = [triNormal,dirs0[0],dirs0[1],dirs0[2],
  9489. Vector3DUtil.crossProduct(dirs0[0],triEdge0),
  9490. Vector3DUtil.crossProduct(dirs0[0],triEdge1),
  9491. Vector3DUtil.crossProduct(dirs0[0],triEdge2),
  9492. Vector3DUtil.crossProduct(dirs0[1],triEdge0),
  9493. Vector3DUtil.crossProduct(dirs0[1],triEdge1),
  9494. Vector3DUtil.crossProduct(dirs0[1],triEdge2),
  9495. Vector3DUtil.crossProduct(dirs0[2],triEdge0),
  9496. Vector3DUtil.crossProduct(dirs0[2],triEdge1),
  9497. Vector3DUtil.crossProduct(dirs0[2],triEdge2)];
  9498. var overlapDepths=[];
  9499. for(var i=0;i<numAxes;i++){
  9500. overlapDepths[i]=new SpanData();
  9501. if(this.disjoint(overlapDepths[i],axes[i],box,tri)){
  9502. return false;
  9503. }
  9504. }
  9505. var minAxis=-1;
  9506. var tiny=JNumber3D.NUM_TINY,minDepth=JNumber3D.NUM_HUGE,l2,invl,depth,combinationDist,oldDepth;
  9507. for(i = 0; i < numAxes; i++){
  9508. l2=Vector3DUtil.get_lengthSquared(axes[i]);
  9509. if (l2 < tiny){
  9510. continue;
  9511. }
  9512. invl=1/Math.sqrt(l2);
  9513. Vector3DUtil.scaleBy(axes[i],invl);
  9514. overlapDepths[i].depth*=invl;
  9515. if (overlapDepths[i].depth < minDepth){
  9516. minDepth = overlapDepths[i].depth;
  9517. minAxis=i;
  9518. }
  9519. }
  9520. if (minAxis == -1) return false;
  9521. D=Vector3DUtil.subtract(box.get_currentState().position,tri.getCentre());
  9522. N=axes[minAxis];
  9523. depth=overlapDepths[minAxis].depth;
  9524. if(Vector3DUtil.dotProduct(D,N)<0){
  9525. Vector3DUtil.negate(N);
  9526. }
  9527. boxOldPos=box.get_oldState().position;
  9528. boxNewPos=box.get_currentState().position;
  9529. meshPos=mesh.get_currentState().position;
  9530. var pts=[];
  9531. combinationDist=depth+0.05;
  9532. this.getBoxTriangleIntersectionPoints(pts,box,tri,combinationDist*combinationDist);
  9533. delta=Vector3DUtil.subtract(boxNewPos,boxOldPos);
  9534. oldDepth=depth+Vector3DUtil.dotProduct(delta,N);
  9535. var numPts=pts.length;
  9536. var collPts = [];
  9537. if(numPts>0){
  9538. var cpInfo;
  9539. for (i=0; i<numPts; i++){
  9540. cpInfo = new CollPointInfo();
  9541. cpInfo.r0=Vector3DUtil.subtract(pts[i],boxNewPos);
  9542. cpInfo.r1=Vector3DUtil.subtract(pts[i],meshPos);
  9543. cpInfo.initialPenetration=oldDepth;
  9544. collPts[i]=cpInfo;
  9545. }
  9546. var collInfo = new CollisionInfo();
  9547. collInfo.objInfo = info;
  9548. collInfo.dirToBody = N;
  9549. collInfo.pointInfo = collPts;
  9550. var mat = new MaterialProperties();
  9551. mat.set_restitution(0.5*(box.get_material().get_restitution() + mesh.get_material().get_restitution()));
  9552. mat.set_friction(0.5*(box.get_material().get_friction() + mesh.get_material().get_friction()));
  9553. collInfo.mat = mat;
  9554. collArr.push(collInfo);
  9555. info.body0.collisions.push(collInfo);
  9556. info.body1.collisions.push(collInfo);
  9557. return true;
  9558. }else{
  9559. return false;
  9560. }
  9561. };
  9562. CollDetectBoxMesh.prototype.collDetectBoxStaticMeshOverlap=function(box,mesh,info,collArr){
  9563. var boxRadius=box.get_boundingSphere();
  9564. var boxCentre=box.get_currentState().position;
  9565. var potentialTriangles = [];
  9566. var numTriangles=mesh.get_octree().getTrianglesIntersectingtAABox(potentialTriangles,box.get_boundingBox());
  9567. var collision=false;
  9568. var dist;
  9569. var meshTriangle;
  9570. for (var iTriangle = 0 ; iTriangle < numTriangles ; ++iTriangle) {
  9571. meshTriangle=mesh.get_octree().getTriangle(potentialTriangles[iTriangle]);
  9572. dist=meshTriangle.get_plane().pointPlaneDistance(boxCentre);
  9573. if (dist > boxRadius || dist < 0){
  9574. continue;
  9575. }
  9576. if(this.doOverlapBoxTriangleTest(box,meshTriangle,mesh,info,collArr)){
  9577. collision = true;
  9578. }
  9579. }
  9580. return collision;
  9581. };
  9582. CollDetectBoxMesh.prototype.collDetect=function(info, collArr){
  9583. var tempBody;
  9584. if (info.body0.type == "TRIANGLEMESH"){
  9585. tempBody = info.body0;
  9586. info.body0 = info.body1;
  9587. info.body1 = tempBody;
  9588. }
  9589. var box = info.body0;
  9590. var mesh = info.body1;
  9591. this.collDetectBoxStaticMeshOverlap(box,mesh,info,collArr);
  9592. };
  9593. jigLib.CollDetectBoxMesh=CollDetectBoxMesh;
  9594. })(jigLib);
  9595. (function(jigLib){
  9596. var Vector3DUtil=jigLib.Vector3DUtil;
  9597. var JConfig=jigLib.JConfig;
  9598. var JIndexedTriangle=jigLib.JIndexedTriangle;
  9599. var JSphere=jigLib.JSphere;
  9600. var JTriangle=jigLib.JTriangle;
  9601. var JTriangleMesh=jigLib.JTriangleMesh;
  9602. var JNumber3D=jigLib.JNumber3D;
  9603. var MaterialProperties=jigLib.MaterialProperties;
  9604. var RigidBody=jigLib.RigidBody;
  9605. var CollPointInfo=jigLib.CollPointInfo;
  9606. var CollDetectSphereMesh=function() {
  9607. this.name = "SphereMesh";
  9608. this.type0 = "SPHERE";
  9609. this.type1 = "TRIANGLEMESH";
  9610. }
  9611. jigLib.extend(CollDetectSphereMesh,jigLib.CollDetectFunctor);
  9612. CollDetectSphereMesh.prototype.collDetectSphereStaticMeshOverlap=function(sphere, mesh, info, collTolerance, collArr){
  9613. var body0Pos = info.body0.get_oldState().position;
  9614. var body1Pos = info.body1.get_oldState().position;
  9615. var sphereTolR = collTolerance + sphere.get_radius();
  9616. var sphereTolR2 = sphereTolR * sphereTolR;
  9617. var collNormal = [0,0,0];
  9618. var collPts = []
  9619. var potentialTriangles = [];
  9620. var numTriangles = mesh.get_octree().getTrianglesIntersectingtAABox(potentialTriangles, sphere.get_boundingBox());
  9621. if(!numTriangles) return;
  9622. var newD2,distToCentre,oldD2,dist,depth,tiny=JNumber3D.NUM_TINY;
  9623. var meshTriangle;
  9624. var vertexIndices;
  9625. var arr;
  9626. var triangle;
  9627. for (var iTriangle = 0 ; iTriangle < numTriangles ; ++iTriangle) {
  9628. meshTriangle = mesh.get_octree().getTriangle(potentialTriangles[iTriangle]);
  9629. distToCentre = meshTriangle.get_plane().pointPlaneDistance(sphere.get_currentState().position);
  9630. if (distToCentre <= 0) continue;
  9631. if (distToCentre >= sphereTolR) continue;
  9632. vertexIndices = meshTriangle.get_vertexIndices();
  9633. triangle = new JTriangle(mesh.get_octree().getVertex(vertexIndices[0]), mesh.get_octree().getVertex(vertexIndices[1]), mesh.get_octree().getVertex(vertexIndices[2]));
  9634. arr = [];
  9635. newD2 = triangle.pointTriangleDistanceSq(arr, sphere.get_currentState().position);
  9636. if (newD2 < sphereTolR2) {
  9637. // have overlap - but actually report the old intersection
  9638. oldD2 = triangle.pointTriangleDistanceSq(arr, sphere.get_oldState().position);
  9639. dist = Math.sqrt(oldD2);
  9640. depth = sphere.get_radius() - dist;
  9641. var collisionN = (dist > tiny) ? (Vector3DUtil.subtract(sphere.get_oldState().position,triangle.getPoint(arr[0], arr[1]))) : triangle.get_normal().slice(0);
  9642. Vector3DUtil.normalize(collisionN);
  9643. // since impulse get applied at the old position
  9644. var pt = Vector3DUtil.subtract(sphere.get_oldState().position,JNumber3D.getScaleVector(collisionN, sphere.get_radius()));
  9645. var cpInfo = new CollPointInfo();
  9646. cpInfo.r0 = Vector3DUtil.subtract(pt,body0Pos);
  9647. cpInfo.r1 = Vector3DUtil.subtract(pt,body1Pos);
  9648. cpInfo.initialPenetration = depth;
  9649. collPts.push(cpInfo);
  9650. collNormal = Vector3DUtil.add(collNormal,collisionN);
  9651. Vector3DUtil.normalize(collNormal);
  9652. }
  9653. }
  9654. var collInfo = new jigLib.CollisionInfo();
  9655. collInfo.objInfo = info;
  9656. collInfo.dirToBody = collNormal;
  9657. collInfo.pointInfo = collPts;
  9658. var mat = new MaterialProperties();
  9659. mat.set_restitution(0.5*(sphere.get_material().get_restitution() + mesh.get_material().get_restitution()));
  9660. mat.set_friction(0.5*(sphere.get_material().get_friction() + mesh.get_material().get_friction()));
  9661. collInfo.mat = mat;
  9662. collArr.push(collInfo);
  9663. info.body0.collisions.push(collInfo);
  9664. info.body1.collisions.push(collInfo);
  9665. };
  9666. CollDetectSphereMesh.prototype.collDetect=function(info, collArr){
  9667. var tempBody;
  9668. if (info.body0._type == "TRIANGLEMESH"){
  9669. tempBody = info.body0;
  9670. info.body0 = info.body1;
  9671. info.body1 = tempBody;
  9672. }
  9673. var sphere = info.body0;
  9674. var mesh = info.body1;
  9675. this.collDetectSphereStaticMeshOverlap(sphere, mesh, info, JConfig.collToll, collArr);
  9676. }
  9677. jigLib.CollDetectSphereMesh=CollDetectSphereMesh;
  9678. })(jigLib);
  9679. (function(jigLib){
  9680. var Vector3DUtil=jigLib.Vector3DUtil;
  9681. var CollOutBodyData=jigLib.CollOutBodyData;
  9682. var JSegment=jigLib.JSegment;
  9683. var JNumber3D=jigLib.JNumber3D;
  9684. var RigidBody=jigLib.RigidBody;
  9685. var CollDetectInfo=jigLib.CollDetectInfo;
  9686. var CollisionSystemAbstract=function(){
  9687. this.collBody = [];
  9688. this.detectionFunctors = {};
  9689. this.detectionFunctors["BOX_BOX"] = new jigLib.CollDetectBoxBox();
  9690. this.detectionFunctors["BOX_SPHERE"] = new jigLib.CollDetectSphereBox();
  9691. this.detectionFunctors["BOX_CAPSULE"] = new jigLib.CollDetectCapsuleBox();
  9692. this.detectionFunctors["BOX_PLANE"] = new jigLib.CollDetectBoxPlane();
  9693. this.detectionFunctors["BOX_TERRAIN"] = new jigLib.CollDetectBoxTerrain();
  9694. this.detectionFunctors["BOX_TRIANGLEMESH"] = new jigLib.CollDetectBoxMesh();
  9695. this.detectionFunctors["SPHERE_BOX"] = new jigLib.CollDetectSphereBox();
  9696. this.detectionFunctors["SPHERE_SPHERE"] = new jigLib.CollDetectSphereSphere();
  9697. this.detectionFunctors["SPHERE_CAPSULE"] = new jigLib.CollDetectSphereCapsule();
  9698. this.detectionFunctors["SPHERE_PLANE"] = new jigLib.CollDetectSpherePlane();
  9699. this.detectionFunctors["SPHERE_TERRAIN"] = new jigLib.CollDetectSphereTerrain();
  9700. this.detectionFunctors["SPHERE_TRIANGLEMESH"] = new jigLib.CollDetectSphereMesh();
  9701. this.detectionFunctors["CAPSULE_CAPSULE"] = new jigLib.CollDetectCapsuleCapsule();
  9702. this.detectionFunctors["CAPSULE_BOX"] = new jigLib.CollDetectCapsuleBox();
  9703. this.detectionFunctors["CAPSULE_SPHERE"] = new jigLib.CollDetectSphereCapsule();
  9704. this.detectionFunctors["CAPSULE_PLANE"] = new jigLib.CollDetectCapsulePlane();
  9705. this.detectionFunctors["CAPSULE_TERRAIN"] = new jigLib.CollDetectCapsuleTerrain();
  9706. this.detectionFunctors["PLANE_BOX"] = new jigLib.CollDetectBoxPlane();
  9707. this.detectionFunctors["PLANE_SPHERE"] = new jigLib.CollDetectSpherePlane();
  9708. this.detectionFunctors["PLANE_CAPSULE"] = new jigLib.CollDetectCapsulePlane();
  9709. this.detectionFunctors["TERRAIN_SPHERE"] = new jigLib.CollDetectSphereTerrain();
  9710. this.detectionFunctors["TERRAIN_BOX"] = new jigLib.CollDetectBoxTerrain();
  9711. this.detectionFunctors["TERRAIN_CAPSULE"] = new jigLib.CollDetectCapsuleTerrain();
  9712. this.detectionFunctors["TRIANGLEMESH_SPHERE"] = new jigLib.CollDetectSphereMesh();
  9713. this.detectionFunctors["TRIANGLEMESH_BOX"] = new jigLib.CollDetectBoxMesh();
  9714. };
  9715. CollisionSystemAbstract.prototype.detectionFunctors={};
  9716. CollisionSystemAbstract.prototype.collBody=null;
  9717. CollisionSystemAbstract.prototype._numCollisionsChecks = 0;
  9718. CollisionSystemAbstract.prototype.addCollisionBody=function(body){
  9719. if (!this.findBody(body)) this.collBody.push(body);
  9720. };
  9721. CollisionSystemAbstract.prototype.removeCollisionBody=function(body){
  9722. if (this.findBody(body)) this.collBody.splice(this.collBody.indexOf(body), 1);
  9723. };
  9724. CollisionSystemAbstract.prototype.removeAllCollisionBodies=function(){
  9725. this.collBody=[];
  9726. };
  9727. // Detects collisions between the body and all the registered collision bodies
  9728. CollisionSystemAbstract.prototype.detectCollisions=function(body, collArr){
  9729. if (!body.isActive) return;
  9730. var info;
  9731. var fu;
  9732. for(var j=0;j<this.collBody.length;j++){
  9733. var _collBody=this.collBody[j];
  9734. if (body == _collBody){
  9735. continue;
  9736. }
  9737. if (this.checkCollidables(body, _collBody) && this.detectionFunctors[body.get_type() + "_" + _collBody.get_type()] != undefined){
  9738. info = new CollDetectInfo();
  9739. info.body0 = body;
  9740. info.body1 = _collBody;
  9741. fu = this.detectionFunctors[info.body0.get_type() + "_" + info.body1.get_type()];
  9742. fu.collDetect(info, collArr);
  9743. }
  9744. }
  9745. };
  9746. // Detects collisions between the all bodies
  9747. CollisionSystemAbstract.prototype.detectAllCollisions=function(bodies, collArr){
  9748. };
  9749. CollisionSystemAbstract.prototype.collisionSkinMoved=function(colBody){
  9750. // used for grid
  9751. };
  9752. CollisionSystemAbstract.prototype.segmentIntersect=function(out, seg, ownerBody){
  9753. out.frac = JNumber3D.NUM_HUGE;
  9754. out.position = [];
  9755. out.normal = [];
  9756. var obj = new CollOutBodyData();
  9757. for(j=0;j<this.collBody.length;j++){
  9758. var _collBody=this.collBody[j];
  9759. if (_collBody != ownerBody && this.segmentBounding(seg, _collBody)){
  9760. if (_collBody.segmentIntersect(obj, seg, _collBody.get_currentState())){
  9761. if (obj.frac < out.frac){
  9762. out.position = obj.position;
  9763. out.normal = obj.normal;
  9764. out.frac = obj.frac;
  9765. out.rigidBody = _collBody;
  9766. }
  9767. }
  9768. }
  9769. }
  9770. if (out.frac > 1) return false;
  9771. if (out.frac < 0){
  9772. out.frac = 0;
  9773. }else if (out.frac > 1) {
  9774. out.frac = 1;
  9775. }
  9776. return true;
  9777. };
  9778. CollisionSystemAbstract.prototype.segmentBounding=function(seg, obj){
  9779. var pos = seg.getPoint(0.5);
  9780. var r = Vector3DUtil.get_length(seg.delta) / 2;
  9781. if (obj.get_type() != "PLANE" && obj.get_type() != "TERRAIN" && obj.get_type() != "TRIANGLEMESH"){
  9782. var num1 = Vector3DUtil.get_length(Vector3DUtil.subtract(pos, obj.get_currentState().position));
  9783. var num2 = r + obj.get_boundingSphere();
  9784. if (num1 <= num2){
  9785. return true;
  9786. }else{
  9787. return false;
  9788. }
  9789. }else{
  9790. return true;
  9791. }
  9792. };
  9793. /*CollisionSystemAbstract.prototype.segmentBounding=function(seg, obj){
  9794. var pos = seg.getPoint(0.5);
  9795. var r = Vector3DUtil.get_length(seg.delta) / 2;
  9796. var num1 = Vector3DUtil.get_length(Vector3DUtil.subtract(pos,obj.get_currentState().position));
  9797. var num2 = r + obj.get_boundingSphere();
  9798. if (num1 <= num2) return true;
  9799. else return false;
  9800. };*/
  9801. CollisionSystemAbstract.prototype.get_numCollisionsChecks=function(){
  9802. return this._numCollisionsChecks;
  9803. };
  9804. CollisionSystemAbstract.prototype.findBody=function(body){
  9805. return this.collBody.indexOf(body) > -1;
  9806. };
  9807. CollisionSystemAbstract.prototype.checkCollidables=function(body0, body1){
  9808. if (body0.get_nonCollidables().length == 0 && body1.get_nonCollidables().length == 0) return true;
  9809. if(body0.get_nonCollidables().indexOf(body1) > -1) return false;
  9810. if(body1.get_nonCollidables().indexOf(body0) > -1) return false;
  9811. return true;
  9812. }
  9813. jigLib.CollisionSystemAbstract=CollisionSystemAbstract;
  9814. })(jigLib); (function(jigLib){
  9815. var Vector3DUtil=jigLib.Vector3DUtil;
  9816. var RigidBody=jigLib.RigidBody;
  9817. var CollDetectInfo=jigLib.CollDetectInfo;
  9818. var CollisionSystemBrute=function(){
  9819. this.Super();
  9820. };
  9821. jigLib.extend(CollisionSystemBrute,jigLib.CollisionSystemAbstract);
  9822. // Detects collisions between the all bodies
  9823. CollisionSystemBrute.prototype.detectAllCollisions=function(bodies, collArr){
  9824. var info;
  9825. var fu;
  9826. var bodyID;
  9827. var bodyType;
  9828. this._numCollisionsChecks = 0;
  9829. for(j=0;j<bodies.length;j++){
  9830. var _body=bodies[j];
  9831. if(!_body.isActive) continue;
  9832. bodyID = _body.id;
  9833. bodyType = _body.get_type();
  9834. for(k=0;k<this.collBody.length;k++){
  9835. var _collBody=this.collBody[k];
  9836. if (_body == _collBody){
  9837. continue;
  9838. }
  9839. if (_collBody && _collBody.isActive && bodyID > _collBody.id){
  9840. continue;
  9841. }
  9842. if (this.checkCollidables(_body, _collBody) && this.detectionFunctors[bodyType + "_" + _collBody.get_type()] != undefined){
  9843. info = new CollDetectInfo();
  9844. info.body0 = _body;
  9845. info.body1 = _collBody;
  9846. fu = this.detectionFunctors[info.body0.get_type() + "_" + info.body1.get_type()];
  9847. fu.collDetect(info, collArr);
  9848. this._numCollisionsChecks += 1;
  9849. }
  9850. }
  9851. }
  9852. }
  9853. jigLib.CollisionSystemBrute=CollisionSystemBrute;
  9854. })(jigLib);
  9855. (function(jigLib){
  9856. var Vector3DUtil=jigLib.Vector3DUtil;
  9857. var RigidBody=jigLib.RigidBody;
  9858. var CollisionSystemGridEntry=function(collisionBody) {
  9859. this.collisionBody = collisionBody;
  9860. this.previous = this.next = null;
  9861. };
  9862. CollisionSystemGridEntry.prototype.collisionBody=null;
  9863. CollisionSystemGridEntry.prototype.previous=null;
  9864. CollisionSystemGridEntry.prototype.next=null;
  9865. CollisionSystemGridEntry.prototype.gridIndex=0;
  9866. /*
  9867. * Removes the entry by updating its neighbours. Also zaps the prev/next
  9868. * pointers in the entry, to help debugging
  9869. */
  9870. CollisionSystemGridEntry.removeGridEntry=function(entry){
  9871. // link the previous to the next (may be 0)
  9872. entry.previous.next = entry.next;
  9873. // link the next (if it exists) to the previous.
  9874. if (entry.next != null)
  9875. entry.next.previous = entry.previous;
  9876. // tidy up this entry
  9877. entry.previous = entry.next = null;
  9878. entry.gridIndex = -2;
  9879. };
  9880. /*
  9881. * Inserts an entry after prev, updating all links
  9882. * @param entry prev
  9883. */
  9884. CollisionSystemGridEntry.insertGridEntryAfter=function(entry, prev){
  9885. var next = prev.next;
  9886. prev.next = entry;
  9887. entry.previous = prev;
  9888. entry.next = next;
  9889. if (next != null)
  9890. next.previous = entry;
  9891. entry.gridIndex = prev.gridIndex;
  9892. }
  9893. jigLib.CollisionSystemGridEntry=CollisionSystemGridEntry;
  9894. })(jigLib);
  9895. (function(jigLib){
  9896. var Vector3DUtil=jigLib.Vector3DUtil;
  9897. var CollOutBodyData=jigLib.CollOutBodyData;
  9898. var JAABox=jigLib.JAABox;
  9899. var JSegment=jigLib.JSegment;
  9900. var JMath3D=jigLib.JMath3D;
  9901. var JNumber3D=jigLib.JNumber3D;
  9902. var RigidBody=jigLib.RigidBody;
  9903. var CollisionSystemGridEntry=jigLib.CollisionSystemGridEntry;
  9904. var CollDetectInfo=jigLib.CollDetectInfo;
  9905. /*
  9906. * Initializes a new CollisionSystem which uses a grid to speed up collision detection.
  9907. * Use this system for larger scenes with many objects.
  9908. * @param sx start point of grid in X axis.
  9909. * @param sy start point of grid in Y axis.
  9910. * @param sz start point of grid in Z axis.
  9911. * @param nx Number of GridEntries in X Direction.
  9912. * @param ny Number of GridEntries in Y Direction.
  9913. * @param nz Number of GridEntries in Z Direction.
  9914. * @param dx Size of a single GridEntry in X Direction.
  9915. * @param dy Size of a single GridEntry in Y Direction.
  9916. * @param dz Size of a single GridEntry in Z Direction.
  9917. */
  9918. var CollisionSystemGrid=function(sx, sy, sz, nx, ny, nz, dx, dy, dz){
  9919. this.Super();
  9920. if(sx==undefined) sx=0;
  9921. if(sy==undefined) sy=0;
  9922. if(sz==undefined) sz=0;
  9923. if(nx==undefined) nx=20;
  9924. if(ny==undefined) ny=20;
  9925. if(nz==undefined) nz=20;
  9926. if(dx==undefined) dx=200;
  9927. if(dy==undefined) dy=200;
  9928. if(dz==undefined) dz=200;
  9929. this.nx = nx; this.ny = ny; this.nz = nz;
  9930. this.dx = dx; this.dy = dy; this.dz = dz;
  9931. this.sizeX = nx * dx;
  9932. this.sizeY = ny * dy;
  9933. this.sizeZ = nz * dz;
  9934. this.minDelta = Math.min(dx, dy, dz);
  9935. this.startpoint = [sx, sy, sz];
  9936. this.gridEntries = [];
  9937. //gridBoxes = new Vector.<JAABox>(nx*ny*nz,true);
  9938. var len=this.gridEntries.length;
  9939. for (var j = 0; j < len; ++j){
  9940. var gridEntry = new CollisionSystemGridEntry(null);
  9941. gridEntry.gridIndex = j;
  9942. this.gridEntries[j]=gridEntry;
  9943. }
  9944. this.overflowEntries = new CollisionSystemGridEntry(null);
  9945. this.overflowEntries.gridIndex = -1;
  9946. }
  9947. jigLib.extend(CollisionSystemGrid,jigLib.CollisionSystemAbstract);
  9948. CollisionSystemGrid.prototype.gridEntries=null;
  9949. //private var gridBoxes:Vector.<JAABox>;
  9950. CollisionSystemGrid.prototype.overflowEntries=null;
  9951. CollisionSystemGrid.prototype.nx=0;
  9952. CollisionSystemGrid.prototype.ny=0;
  9953. CollisionSystemGrid.prototype.nz=0;
  9954. CollisionSystemGrid.prototype.dx=0;
  9955. CollisionSystemGrid.prototype.dy=0;
  9956. CollisionSystemGrid.prototype.dz=0;
  9957. CollisionSystemGrid.prototype.sizeX=0;
  9958. CollisionSystemGrid.prototype.sizeY=0;
  9959. CollisionSystemGrid.prototype.sizeZ=0;
  9960. CollisionSystemGrid.prototype.minDelta=0;
  9961. CollisionSystemGrid.prototype.calcIndex=function(i, j, k){
  9962. var _i = i % this.nx;
  9963. var _j = j % this.ny;
  9964. var _k = k % this.nz;
  9965. return (_i + this.nx * _j + (this.nx + this.ny) * _k);
  9966. };
  9967. CollisionSystemGrid.prototype.calcGridForSkin3=function(colBody){
  9968. var i;var j;var k;
  9969. var sides = colBody.get_boundingBox().get_sideLengths();
  9970. if ((sides[0] > this.dx) || (sides[1] > this.dy) || (sides[2] > this.dz)){
  9971. //trace("calcGridForSkin3 -- Rigidbody to big for gridsystem - putting it into overflow list (lengths,type,id):", sides.x,sides.y,sides.z,colBody.type,colBody.id,colBody.boundingBox.minPos,colBody.boundingBox.maxPos);
  9972. i = j = k = -1;
  9973. return [i,j,k];
  9974. }
  9975. //trace(sides.x,sides.y,sides.z);
  9976. var min = colBody.get_boundingBox().get_minPos();
  9977. min[0] = JMath3D.wrap(min[0], this.startpoint[0], this.startpoint[0]+this.sizeX);
  9978. min[1] = JMath3D.wrap(min[1], this.startpoint[1], this.startpoint[1]+this.sizeY);
  9979. min[2] = JMath3D.wrap(min[2], this.startpoint[2], this.startpoint[2]+this.sizeZ);
  9980. i = ( ((min[0]-this.startpoint[0]) / this.dx) % this.nx)|0;
  9981. j = ( ((min[1]-this.startpoint[1]) / this.dy) % this.ny)|0;
  9982. k = ( ((min[2]-this.startpoint[2]) / this.dz) % this.nz)|0;
  9983. return [i,j,k];
  9984. };
  9985. CollisionSystemGrid.prototype.calcGridForSkin6=function(colBody){
  9986. var tempStoreObject = {};
  9987. var i;var j;var k;
  9988. var fi;var fj;var fk;
  9989. var sides = colBody.get_boundingBox().get_sideLengths();
  9990. if ((sides[0] > this.dx) || (sides[1] > this.dy) || (sides[2] > this.dz)){
  9991. //trace("calcGridForSkin6 -- Rigidbody to big for gridsystem - putting it into overflow list (lengths,type,id):", sides.x,sides.y,sides.z,colBody.type,colBody.id,colBody.boundingBox.minPos,colBody.boundingBox.maxPos);
  9992. i = j = k = -1;
  9993. fi = fj = fk = 0.0;
  9994. tempStoreObject.i = i; tempStoreObject.j = j; tempStoreObject.k = k; tempStoreObject.fi = fi; tempStoreObject.fj = fj; tempStoreObject.fk = fk;
  9995. return tempStoreObject;
  9996. }
  9997. var min = colBody.get_boundingBox().get_minPos();
  9998. min[0] = JMath3D.getLimiteNumber(min[0], this.startpoint[0], this.startpoint[0] + this.sizeX);
  9999. min[1] = JMath3D.getLimiteNumber(min[1], this.startpoint[1], this.startpoint[1] + this.sizeY);
  10000. min[2] = JMath3D.getLimiteNumber(min[2], this.startpoint[2], this.startpoint[2] + this.sizeZ);
  10001. fi = (min[0] - this.startpoint[0]) / this.dx;
  10002. fj = (min[1] - this.startpoint[1]) / this.dy;
  10003. fk = (min[2] - this.startpoint[2]) / this.dz;
  10004. i = fi;
  10005. j = fj;
  10006. k = fk;
  10007. if (i < 0) { i = 0; fi = 0.0; }
  10008. else if (i >= this.nx) { i = 0; fi = 0.0; }
  10009. else fi -= i;
  10010. if (j < 0) { j = 0; fj = 0.0; }
  10011. else if (j >= this.ny) { j = 0; fj = 0.0; }
  10012. else fj -= j;
  10013. if (k < 0) { k = 0; fk = 0.0; }
  10014. else if (k >= this.nz) { k = 0; fk = 0.0; }
  10015. else fk -= k;
  10016. tempStoreObject.i = i; tempStoreObject.j = j; tempStoreObject.k = k; tempStoreObject.fi = fi; tempStoreObject.fj = fj; tempStoreObject.fk = fk;
  10017. //trace(i,j,k,fi,fj,fk);
  10018. //trace(colBody.x,colBody.y,colBody.z);
  10019. return tempStoreObject;
  10020. };
  10021. CollisionSystemGrid.prototype.calcGridIndexForBody=function(colBody){
  10022. var tempStoreVector = this.calcGridForSkin3(colBody);
  10023. //trace(tempStoreVector.x,tempStoreVector.y,tempStoreVector.z);
  10024. if (tempStoreVector.x == -1) return -1;
  10025. return this.calcIndex(tempStoreVector[0], tempStoreVector[1], tempStoreVector[2]);
  10026. };
  10027. CollisionSystemGrid.prototype.addCollisionBody=function(body){
  10028. if (!this.findBody(body)) this.collBody.push(body);
  10029. body.collisionSystem = this;
  10030. // also do the grid stuff - for now put it on the overflow list
  10031. var entry = new CollisionSystemGridEntry(body);
  10032. body.externalData = entry;
  10033. // add entry to the start of the list
  10034. CollisionSystemGridEntry.insertGridEntryAfter(entry, this.overflowEntries);
  10035. this.collisionSkinMoved(body);
  10036. };
  10037. CollisionSystemGrid.prototype.removeCollisionBody=function(body){
  10038. if (body.externalData != null){
  10039. body.externalData.collisionBody = null;
  10040. CollisionSystemGridEntry.removeGridEntry(body.externalData);
  10041. body.externalData = null;
  10042. }
  10043. if (this.findBody(body))
  10044. this.collBody.splice(this.collBody.indexOf(body), 1);
  10045. };
  10046. CollisionSystemGrid.prototype.removeAllCollisionBodies=function(){
  10047. for(var i=0;i<this.collBody.length;i++){
  10048. var body=this.collBody[i];
  10049. if (body.externalData != null){
  10050. body.externalData.collisionBody = null;
  10051. CollisionSystemGridEntry.removeGridEntry(body.externalData);
  10052. }
  10053. }
  10054. collBody=[];
  10055. };
  10056. // todo: only call when really moved, make it override public add into abstract ?
  10057. CollisionSystemGrid.prototype.collisionSkinMoved=function(colBody){
  10058. var entry = colBody.externalData;
  10059. if (entry == null){
  10060. //trace("Warning rigidbody has grid entry null!");
  10061. return;
  10062. }
  10063. var gridIndex = this.calcGridIndexForBody(colBody);
  10064. // see if it's moved grid
  10065. if (gridIndex == entry.gridIndex)
  10066. return;
  10067. //trace(gridIndex);
  10068. var start;
  10069. var gridEntries=this.gridEntries;
  10070. //if (gridIndex >= 0**)
  10071. if (gridEntries.length-1 > gridIndex && gridIndex >=0) // check if it's outside the gridspace, if so add to overflow
  10072. start = gridEntries[gridIndex];
  10073. else
  10074. start = this.overflowEntries;
  10075. CollisionSystemGridEntry.removeGridEntry(entry);
  10076. CollisionSystemGridEntry.insertGridEntryAfter(entry, start);
  10077. };
  10078. CollisionSystemGrid.prototype.getListsToCheck=function(colBody){
  10079. var entries = [];
  10080. var entry = colBody.externalData;
  10081. if (entry == null){
  10082. //trace("Warning skin has grid entry null!");
  10083. return entries;
  10084. }
  10085. // todo - work back from the mGridIndex rather than calculating it again...
  10086. var i; var j; var k;
  10087. var fi; var fj; var fk;
  10088. var tempStoreObject = this.calcGridForSkin6(colBody);
  10089. i = tempStoreObject.i; j = tempStoreObject.j; k = tempStoreObject.k; fi = tempStoreObject.fi; fj = tempStoreObject.fj; fk = tempStoreObject.fk;
  10090. if (i == -1){
  10091. //trace("ADD ALL!");
  10092. entries=this.gridEntries.concat();
  10093. entries.push(this.overflowEntries);
  10094. return entries;
  10095. }
  10096. // always add the overflow
  10097. entries.push(this.overflowEntries);
  10098. var delta = colBody.get_boundingBox().get_sideLengths(); // skin.WorldBoundingBox.Max - skin.WorldBoundingBox.Min;
  10099. var maxI = 1, maxJ = 1, maxK = 1;
  10100. if (fi + (delta[0] / this.dx) < 1)
  10101. maxI = 0;
  10102. if (fj + (delta[1] / this.dy) < 1)
  10103. maxJ = 0;
  10104. if (fk + (delta[2]/ this.dz) < 1)
  10105. maxK = 0;
  10106. // now add the contents of all grid boxes - their contents may extend beyond the bounds
  10107. for (var di = -1; di <= maxI; ++di){
  10108. for (var dj = -1; dj <= maxJ; ++dj){
  10109. for (var dk = -1; dk <= maxK; ++dk){
  10110. var thisIndex = this.calcIndex(this.nx + i + di, this.ny + j + dj, this.nz + k + dk); // + ((nx*ny*nz)*0.5);
  10111. //trace("ge", gridEntries.length);
  10112. if (this.gridEntries.length-1 > thisIndex && thisIndex >=0) {
  10113. var start = this.gridEntries[thisIndex];
  10114. //trace(thisIndex,gridEntries.length);
  10115. if (start != null && start.next != null){
  10116. entries.push(start);
  10117. }
  10118. }
  10119. }
  10120. }
  10121. }
  10122. return entries;
  10123. }
  10124. CollisionSystemGrid.prototype.detectAllCollisions=function(bodies, collArr) {
  10125. var info;
  10126. var fu;
  10127. var bodyID;
  10128. var bodyType;
  10129. this._numCollisionsChecks = 0;
  10130. for(var j=0;j<bodies.length;j++){
  10131. var body=bodies[j];
  10132. if (!body.isActive) continue;
  10133. bodyID = body.get_id();
  10134. bodyType = body.get_type();
  10135. var lists=this.getListsToCheck(body);
  10136. for(var k=0;k<lists.length;k++){
  10137. var entry=lists[k];
  10138. for (entry = entry.next; entry != null; entry = entry.next){
  10139. if (body == entry.collisionBody) continue;
  10140. if (entry.collisionBody && entry.collisionBody.isActive && bodyID > entry.collisionBody.get_id())
  10141. continue;
  10142. if (this.checkCollidables(body, entry.collisionBody) && this.detectionFunctors[bodyType + "_" + entry.collisionBody.get_type()] != undefined){
  10143. info = new CollDetectInfo();
  10144. info.body0 = body;
  10145. info.body1 = entry.collisionBody;
  10146. fu = this.detectionFunctors[info.body0.get_type() + "_" + info.body1.get_type()];
  10147. fu.collDetect(info, collArr);
  10148. this._numCollisionsChecks += 1;
  10149. } //check collidables
  10150. }// loop over entries
  10151. } // loop over lists
  10152. } // loop over bodies
  10153. }
  10154. jigLib.CollisionSystemGrid=CollisionSystemGrid;
  10155. })(jigLib); /*
  10156. Copyright (c) 2007 Danny Chapman
  10157. http://www.rowlhouse.co.uk
  10158. This software is provided 'as-is', without any express or implied
  10159. warranty. In no event will the authors be held liable for any damages
  10160. arising from the use of this software.
  10161. Permission is granted to anyone to use this software for any purpose,
  10162. including commercial applications, and to alter it and redistribute it
  10163. freely, subject to the following restrictions:
  10164. 1. The origin of this software must not be misrepresented; you must not
  10165. claim that you wrote the original software. If you use this software
  10166. in a product, an acknowledgment in the product documentation would be
  10167. appreciated but is not required.
  10168. 2. Altered source versions must be plainly marked as such, and must not be
  10169. misrepresented as being the original software.
  10170. 3. This notice may not be removed or altered from any source
  10171. distribution.
  10172. */
  10173. (function(jigLib){
  10174. /**
  10175. * @author Muzer(muzerly@gmail.com)
  10176. *
  10177. * @name JConstraint
  10178. * @class JConstraint the base class for constraints
  10179. * @property {boolean} _satisfied flag indicating whether this constraint has been satisfied
  10180. * @property {boolean} _constraintEnabled flag indicating whether this constraint is registered with the physics system
  10181. * @constructor
  10182. **/
  10183. var JConstraint=function(){
  10184. this._constraintEnabled = false;
  10185. this.enableConstraint();
  10186. };
  10187. JConstraint.prototype._satisfied=null;
  10188. JConstraint.prototype._constraintEnabled=null;
  10189. /**
  10190. * @function set_satisfied setter for the _satisfied flag
  10191. * @param {boolean} s
  10192. * @type void
  10193. **/
  10194. JConstraint.prototype.set_satisfied=function(s){
  10195. this._satisfied = s;
  10196. };
  10197. /**
  10198. * @function get_satisfied getter for the _satisfied flag
  10199. * @type boolean
  10200. **/
  10201. JConstraint.prototype.get_satisfied=function(){
  10202. return this._satisfied;
  10203. };
  10204. /**
  10205. * @function preApply prepare for applying constraints - subsequent calls to
  10206. * apply will all occur with a constant position i.e. precalculate everything possible
  10207. * @param {number} dt a UNIX timestamp
  10208. * @type void
  10209. **/
  10210. JConstraint.prototype.preApply=function(dt){
  10211. this._satisfied = false;
  10212. };
  10213. /**
  10214. * @function apply enforces the constraint using impulses. Return value
  10215. * indicates if any impulses were applied. If impulses were applied
  10216. * the derived class should call SetConstraintsUnsatisfied() on each
  10217. * body that is involved.
  10218. * @param {number} dt a UNIX timestamp
  10219. * @type boolean
  10220. **/
  10221. JConstraint.prototype.apply=function(dt){
  10222. return false;
  10223. };
  10224. /**
  10225. * @function enableConstraint registers this constraint with the physics system
  10226. * @type void
  10227. **/
  10228. JConstraint.prototype.enableConstraint=function(){
  10229. if (this._constraintEnabled)
  10230. return;
  10231. this._constraintEnabled = true;
  10232. jigLib.PhysicsSystem.getInstance().addConstraint(this);
  10233. };
  10234. /**
  10235. * @function disableConstraint de-registers this constraint from the physics system
  10236. * @type void
  10237. **/
  10238. JConstraint.prototype.disableConstraint=function(){
  10239. if (!this._constraintEnabled)
  10240. return;
  10241. this._constraintEnabled = false;
  10242. jigLib.PhysicsSystem.getInstance().removeConstraint(this);
  10243. };
  10244. /**
  10245. * @function get_constraintEnabled determines whether this constraint is registered with the physics system
  10246. * @type boolean
  10247. **/
  10248. JConstraint.prototype.get_constraintEnabled=function(){
  10249. return this._constraintEnabled;
  10250. };
  10251. jigLib.JConstraint=JConstraint;
  10252. })(jigLib);/*
  10253. Copyright (c) 2007 Danny Chapman
  10254. http://www.rowlhouse.co.uk
  10255. This software is provided 'as-is', without any express or implied
  10256. warranty. In no event will the authors be held liable for any damages
  10257. arising from the use of this software.
  10258. Permission is granted to anyone to use this software for any purpose,
  10259. including commercial applications, and to alter it and redistribute it
  10260. freely, subject to the following restrictions:
  10261. 1. The origin of this software must not be misrepresented; you must not
  10262. claim that you wrote the original software. If you use this software
  10263. in a product, an acknowledgment in the product documentation would be
  10264. appreciated but is not required.
  10265. 2. Altered source versions must be plainly marked as such, and must not be
  10266. misrepresented as being the original software.
  10267. 3. This notice may not be removed or altered from any source
  10268. distribution.
  10269. */
  10270. (function(jigLib){
  10271. var Vector3DUtil=jigLib.Vector3DUtil;
  10272. var JMatrix3D=jigLib.JMatrix3D;
  10273. var JNumber3D=jigLib.JNumber3D;
  10274. /**
  10275. * @author Muzer(muzerly@gmail.com)
  10276. *
  10277. * @name JConstraintMaxDistance
  10278. * @class JConstraintMaxDistance a maximum distance constraint
  10279. * @extends JConstraint
  10280. * @requires Vector3DUtil
  10281. * @requires JMatrix3D
  10282. * @requires JNumber3D
  10283. * @property {number} _maxVelMag limits the velocity of the constrained bodies
  10284. * @property {number} _minVelForProcessing the lower velocity threshold below which the constraint is not processed
  10285. * @property {RigidBody} _body0 the first body of the constrained pair
  10286. * @property {RigidBody} _body1 the second body of the constrained pair
  10287. * @property {array} _body0Pos the position of the first body
  10288. * @property {array} _body1Pos the position of the second body
  10289. * @property {number} _maxDistance the maximum allowed distance
  10290. * @property {array} r0 for internal use
  10291. * @property {array} r1 for internal use
  10292. * @property {array} _worldPos for internal use
  10293. * @property {array} _currentRelPos0 for internal use
  10294. * @constructor
  10295. * @param {RigidBody} body0 the first body of the constrained pair
  10296. * @param {array} body0Pos the position of the first body expressed as a 3D vector
  10297. * @param {RigidBody} body1 the second body of the constrained pair
  10298. * @param {array} body1Pos the position of the second body expressed as a 3D vector
  10299. * @param {number} maxDistance the maximum allowed distance between body0 and body1
  10300. **/
  10301. var JConstraintMaxDistance=function(body0, body0Pos, body1, body1Pos, maxDistance){
  10302. if(!maxDistance) maxDistance=1;
  10303. this.Super();
  10304. this._body0 = body0;
  10305. this._body0Pos = body0Pos;
  10306. this._body1 = body1;
  10307. this._body1Pos = body1Pos;
  10308. this._maxDistance = maxDistance;
  10309. body0.addConstraint(this);
  10310. body1.addConstraint(this);
  10311. };
  10312. jigLib.extend(JConstraintMaxDistance,jigLib.JConstraint);
  10313. JConstraintMaxDistance.prototype._maxVelMag = 20;
  10314. JConstraintMaxDistance.prototype._minVelForProcessing = 0.01;
  10315. JConstraintMaxDistance.prototype._body0=null;
  10316. JConstraintMaxDistance.prototype._body1=null;
  10317. JConstraintMaxDistance.prototype._body0Pos=null;
  10318. JConstraintMaxDistance.prototype._body1Pos=null;
  10319. JConstraintMaxDistance.prototype._maxDistance=null;
  10320. JConstraintMaxDistance.prototype.r0=null;
  10321. JConstraintMaxDistance.prototype.r1=null;
  10322. JConstraintMaxDistance.prototype._worldPos=null;
  10323. JConstraintMaxDistance.prototype._currentRelPos0=null;
  10324. /**
  10325. * @function preApply prepare for applying the constraint
  10326. * @param {number} dt a UNIX timestamp
  10327. * @type void
  10328. **/
  10329. JConstraintMaxDistance.prototype.preApply=function(dt){
  10330. this.set_satisfied(false);
  10331. this.r0 = this._body0Pos.slice(0);
  10332. this.r1 = this._body1Pos.slice(0);
  10333. JMatrix3D.multiplyVector(this._body0.get_currentState().get_orientation(), this.r0);
  10334. JMatrix3D.multiplyVector(this._body1.get_currentState().get_orientation(), this.r1);
  10335. //this.r0 = this._body0.get_currentState().get_orientation().transformVector(this._body0Pos.slice(0));
  10336. //this.r1 = this._body1.get_currentState().get_orientation().transformVector(this._body1Pos.slice(0));
  10337. var worldPos0 = Vector3DUtil.add(this._body0.get_currentState().position, this.r0);
  10338. var worldPos1 = Vector3DUtil.add(this._body1.get_currentState().position, this.r1);
  10339. this._worldPos = JNumber3D.getScaleVector(Vector3DUtil.add(worldPos0, worldPos1), 0.5);
  10340. this._currentRelPos0 = Vector3DUtil.subtract(worldPos0, worldPos1);
  10341. };
  10342. /**
  10343. * @function apply enforce the constraint
  10344. * @param {number} dt a UNIX timestamp
  10345. * @type boolean
  10346. **/
  10347. JConstraintMaxDistance.prototype.apply=function(dt){
  10348. this.set_satisfied(true);
  10349. if (!this._body0.isActive && !this._body1.isActive)
  10350. return false;
  10351. var currentVel0 = this._body0.getVelocity(this.r0);
  10352. var currentVel1 = this._body1.getVelocity(this.r1);
  10353. var predRelPos0 = Vector3DUtil.add(this._currentRelPos0, JNumber3D.getScaleVector(Vector3DUtil.subtract(currentVel0, currentVel1), dt));
  10354. var clampedRelPos0 = predRelPos0.slice(0);
  10355. var clampedRelPos0Mag = Vector3DUtil.get_length(clampedRelPos0);
  10356. if (clampedRelPos0Mag <= JNumber3D.NUM_TINY)
  10357. return false;
  10358. if (clampedRelPos0Mag > this._maxDistance)
  10359. clampedRelPos0 = JNumber3D.getScaleVector(clampedRelPos0, this._maxDistance / clampedRelPos0Mag);
  10360. var desiredRelVel0 = JNumber3D.getDivideVector(Vector3DUtil.subtract(clampedRelPos0, this._currentRelPos0), dt);
  10361. var Vr = Vector3DUtil.subtract(Vector3DUtil.subtract(currentVel0, currentVel1), desiredRelVel0);
  10362. var normalVel = Vector3DUtil.get_length(Vr);
  10363. if (normalVel > this._maxVelMag){
  10364. Vr = JNumber3D.getScaleVector(Vr, this._maxVelMag / normalVel);
  10365. normalVel = this._maxVelMag;
  10366. }else if (normalVel < this._minVelForProcessing){
  10367. return false;
  10368. }
  10369. var N = JNumber3D.getDivideVector(Vr, normalVel);
  10370. var tempVec1 = Vector3DUtil.crossProduct(this.r0, N);
  10371. JMatrix3D.multiplyVector(this._body0.get_worldInvInertia(), tempVec1);
  10372. var tempVec2 = Vector3DUtil.crossProduct(this.r1, N);
  10373. JMatrix3D.multiplyVector(this._body1.get_worldInvInertia(), tempVec2);
  10374. var denominator = this._body0.get_invMass()
  10375. + this._body1.get_invMass()
  10376. + Vector3DUtil.dotProduct(N, Vector3DUtil.crossProduct(tempVec1, this.r0))
  10377. + Vector3DUtil.dotProduct(N, Vector3DUtil.crossProduct(tempVec2, this.r1));
  10378. if (denominator < JNumber3D.NUM_TINY)
  10379. return false;
  10380. var normalImpulse = JNumber3D.getScaleVector(N, -normalVel / denominator);
  10381. this._body0.applyWorldImpulse(normalImpulse, this._worldPos);
  10382. this._body1.applyWorldImpulse(JNumber3D.getScaleVector(normalImpulse, -1), this._worldPos);
  10383. this._body0.setConstraintsAndCollisionsUnsatisfied();
  10384. this._body1.setConstraintsAndCollisionsUnsatisfied();
  10385. this.set_satisfied(true);
  10386. return true;
  10387. };
  10388. jigLib.JConstraintMaxDistance=JConstraintMaxDistance;
  10389. })(jigLib);/*
  10390. Copyright (c) 2007 Danny Chapman
  10391. http://www.rowlhouse.co.uk
  10392. This software is provided 'as-is', without any express or implied
  10393. warranty. In no event will the authors be held liable for any damages
  10394. arising from the use of this software.
  10395. Permission is granted to anyone to use this software for any purpose,
  10396. including commercial applications, and to alter it and redistribute it
  10397. freely, subject to the following restrictions:
  10398. 1. The origin of this software must not be misrepresented; you must not
  10399. claim that you wrote the original software. If you use this software
  10400. in a product, an acknowledgment in the product documentation would be
  10401. appreciated but is not required.
  10402. 2. Altered source versions must be plainly marked as such, and must not be
  10403. misrepresented as being the original software.
  10404. 3. This notice may not be removed or altered from any source
  10405. distribution.
  10406. */
  10407. (function(jigLib){
  10408. var Vector3DUtil=jigLib.Vector3DUtil;
  10409. var JMatrix3D=jigLib.JMatrix3D;
  10410. var JNumber3D=jigLib.JNumber3D;
  10411. /**
  10412. * @author Muzer(muzerly@gmail.com)
  10413. *
  10414. * @name JConstraintPoint
  10415. * @class JConstraintPoint a constraint that links a point on one body to a point on another body
  10416. * @extends JConstraint
  10417. * @requires Vector3DUtil
  10418. * @requires JMatrix3D
  10419. * @requires JNumber3D
  10420. * @property {number} _maxVelMag limits the velocity of the constrained bodies
  10421. * @property {number} _minVelForProcessing the lower velocity threshold below which the constraint is not processed
  10422. * @property {RigidBody} _body0 the first body of the constrained pair
  10423. * @property {RigidBody} _body1 the second body of the constrained pair
  10424. * @property {array} _body0Pos the position of the first body
  10425. * @property {array} _body1Pos the position of the second body
  10426. * @property {number} _allowedDistance the maximum allowed distance
  10427. * @property {array} r0 for internal use
  10428. * @property {array} r1 for internal use
  10429. * @property {array} _worldPos for internal use
  10430. * @property {array} _vrExtra for internal use
  10431. * @constructor
  10432. * @param {RigidBody} body0 the first body of the constrained pair
  10433. * @param {array} body0Pos the position of the first body expressed as a 3D vector
  10434. * @param {RigidBody} body1 the second body of the constrained pair
  10435. * @param {array} body1Pos the position of the second body expressed as a 3D vector
  10436. * @param {number} allowedDistance how much the points are allowed to deviate
  10437. * @param timescale the timescale over which deviation is eliminated (suggest a few times dt - be careful if there's a variable timestep!). If timescale < 0 then the value indicates the number of dts
  10438. **/
  10439. var JConstraintPoint=function(body0, body0Pos, body1, body1Pos, allowedDistance, timescale)
  10440. {
  10441. this.Super();
  10442. this._body0 = body0;
  10443. this._body0Pos = body0Pos;
  10444. this._body1 = body1;
  10445. this._body1Pos = body1Pos;
  10446. this._allowedDistance = (allowedDistance) ? allowedDistance : 1;
  10447. this._timescale = (timescale) ? timescale : 1;
  10448. if (this._timescale < JNumber3D.NUM_TINY) _timescale = JNumber3D.NUM_TINY;
  10449. body0.addConstraint(this);
  10450. body1.addConstraint(this);
  10451. };
  10452. jigLib.extend(JConstraintPoint,jigLib.JConstraint);
  10453. JConstraintPoint.prototype._maxVelMag = 20;
  10454. JConstraintPoint.prototype._minVelForProcessing = 0.01;
  10455. JConstraintPoint.prototype._body0=null;
  10456. JConstraintPoint.prototype._body1=null;
  10457. JConstraintPoint.prototype._body0Pos=null;
  10458. JConstraintPoint.prototype._body1Pos=null;
  10459. JConstraintPoint.prototype._timescale=null;
  10460. JConstraintPoint.prototype._allowedDistance=null;
  10461. JConstraintPoint.prototype.r0=null;
  10462. JConstraintPoint.prototype.r1=null;
  10463. JConstraintPoint.prototype._worldPos=null;
  10464. JConstraintPoint.prototype._vrExtra=null;
  10465. /**
  10466. * @function preApply prepare for applying the constraint
  10467. * @param {number} dt a UNIX timestamp
  10468. * @type void
  10469. **/
  10470. JConstraintPoint.prototype.preApply=function(dt)
  10471. {
  10472. this.set_satisfied(false);
  10473. this.r0 = this._body0Pos.slice(0);
  10474. JMatrix3D.multiplyVector(this._body0.get_currentState().get_orientation(), this.r0);
  10475. this.r1 = this._body1Pos.slice(0);
  10476. JMatrix3D.multiplyVector(this._body1.get_currentState().get_orientation(), this.r1);
  10477. //this.r0 = this._body0.get_currentState().get_orientation().transformVector(this._body0Pos);
  10478. //this.r1 = this._body1.get_currentState().get_orientation().transformVector(this._body1Pos);
  10479. var worldPos0 = Vector3DUtil.add(this._body0.get_currentState().position, this.r0);
  10480. var worldPos1 = Vector3DUtil.add(this._body1.get_currentState().position, this.r1);
  10481. this._worldPos = JNumber3D.getScaleVector(Vector3DUtil.add(worldPos0, worldPos1), 0.5);
  10482. var deviation = Vector3DUtil.subtract(worldPos0, worldPos1);
  10483. var deviationAmount = Vector3DUtil.get_length(deviation);
  10484. /*
  10485. if (deviationAmount <= this._allowedDistance){
  10486. this.set_satisfied(true);
  10487. this._vrExtra = [0,0,0,0];
  10488. return;
  10489. }
  10490. */
  10491. if (deviationAmount > this._allowedDistance)
  10492. this._vrExtra = JNumber3D.getScaleVector(deviation, (deviationAmount - this._allowedDistance) / (deviationAmount * Math.max(this._timescale, dt)));
  10493. else
  10494. this._vrExtra = [0,0,0,0];
  10495. };
  10496. /**
  10497. * @function apply enforce the constraint
  10498. * @param {number} dt a UNIX timestamp
  10499. * @type boolean
  10500. **/
  10501. JConstraintPoint.prototype.apply=function(dt)
  10502. {
  10503. //if (this._satisfied) return;
  10504. this.set_satisfied(true);
  10505. if (!this._body0.isActive && !this._body1.isActive)
  10506. return false;
  10507. var currentVel0 = this._body0.getVelocity(this.r0);
  10508. var currentVel1 = this._body1.getVelocity(this.r1);
  10509. var Vr = Vector3DUtil.add(this._vrExtra, Vector3DUtil.subtract(currentVel0, currentVel1));
  10510. var normalVel = Vector3DUtil.get_length(Vr);
  10511. if (normalVel < this._minVelForProcessing)
  10512. return false;
  10513. if (normalVel > this._maxVelMag){
  10514. Vr = JNumber3D.getScaleVector(Vr, this._maxVelMag / normalVel);
  10515. normalVel = this._maxVelMag;
  10516. }
  10517. var N = JNumber3D.getDivideVector(Vr, normalVel);
  10518. var tempVec1 = Vector3DUtil.crossProduct(this.r0, N);
  10519. JMatrix3D.multiplyVector(this._body0.get_worldInvInertia(), tempVec1);
  10520. //tempVec1 = this._body0.get_worldInvInertia().transformVector(tempVec1);
  10521. var tempVec2 = Vector3DUtil.crossProduct(this.r1, N);
  10522. JMatrix3D.multiplyVector(this._body1.get_worldInvInertia(), tempVec2);
  10523. //tempVec2 = this._body1.get_worldInvInertia().transformVector(tempVec2);
  10524. var denominator = this._body0.get_invMass()
  10525. + this._body1.get_invMass()
  10526. + Vector3DUtil.dotProduct(N, Vector3DUtil.crossProduct(tempVec1, this.r0))
  10527. + Vector3DUtil.dotProduct(N, Vector3DUtil.crossProduct(tempVec2, this.r1));
  10528. if (denominator < JNumber3D.NUM_TINY)
  10529. return false;
  10530. var normalImpulse0=JNumber3D.getScaleVector(N, -normalVel / denominator);
  10531. //Vector3DUtil.scaleBy(normalImpulse0, 0.5);
  10532. var normalImpulse1=JNumber3D.getScaleVector(normalImpulse0, -1);
  10533. /*limit the impulse applied to body1 so it does not exceed the velocity of body0
  10534. var vel1toAdd=JNumber3D.getScaleVector(normalImpulse1, this._body1._invMass);
  10535. var newVel1=Vector3DUtil.add(this._body1._currState.linVelocity, vel1toAdd);
  10536. var vel0Sum=Vector3DUtil.getSum(currentVel0);
  10537. var newVel1Sum=Vector3DUtil.getSum(newVel1);
  10538. if (newVel1Sum > vel0Sum){
  10539. var diff=newVel1Sum-vel0Sum;
  10540. Vector3DUtil.limitSum(normalImpulse1,newVel1Sum-diff);
  10541. }
  10542. //limit the impulse applied to body1 so it does not exceed the velocity of body0
  10543. var vel0toAdd=JNumber3D.getScaleVector(normalImpulse0, this._body1._invMass);
  10544. var newVel0=Vector3DUtil.add(this._body0._currState.linVelocity, vel0toAdd);
  10545. //var vel0Sum=Vector3DUtil.getSum(currentVel0);
  10546. var newVel0Sum=Vector3DUtil.getSum(newVel0);
  10547. if (newVel0Sum > vel0Sum){
  10548. var diff=newVel0Sum-vel0Sum;
  10549. Vector3DUtil.limitSum(normalImpulse0,newVel0Sum-diff);
  10550. }
  10551. */
  10552. this._body0.applyWorldImpulse(normalImpulse0, this._worldPos);
  10553. this._body1.applyWorldImpulse(normalImpulse1, this._worldPos);
  10554. this._body0.setConstraintsAndCollisionsUnsatisfied();
  10555. this._body1.setConstraintsAndCollisionsUnsatisfied();
  10556. this.set_satisfied(true);
  10557. return true;
  10558. };
  10559. jigLib.JConstraintPoint=JConstraintPoint;
  10560. })(jigLib);/*
  10561. Copyright (c) 2007 Danny Chapman
  10562. http://www.rowlhouse.co.uk
  10563. This software is provided 'as-is', without any express or implied
  10564. warranty. In no event will the authors be held liable for any damages
  10565. arising from the use of this software.
  10566. Permission is granted to anyone to use this software for any purpose,
  10567. including commercial applications, and to alter it and redistribute it
  10568. freely, subject to the following restrictions:
  10569. 1. The origin of this software must not be misrepresented; you must not
  10570. claim that you wrote the original software. If you use this software
  10571. in a product, an acknowledgment in the product documentation would be
  10572. appreciated but is not required.
  10573. 2. Altered source versions must be plainly marked as such, and must not be
  10574. misrepresented as being the original software.
  10575. 3. This notice may not be removed or altered from any source
  10576. distribution.
  10577. */
  10578. (function(jigLib){
  10579. var Vector3DUtil=jigLib.Vector3DUtil;
  10580. var JMatrix3D=jigLib.JMatrix3D;
  10581. var JNumber3D=jigLib.JNumber3D;
  10582. var JConstraintMaxDistance=jigLib.JConstraintMaxDistance;
  10583. var JConstraintPoint=jigLib.JConstraintPoint;
  10584. /**
  10585. * @author Muzer(muzerly@gmail.com)
  10586. *
  10587. * @name HingeJoint
  10588. * @class HingeJoint hinge connector for two rigid bodies
  10589. * @extends PhysicsController
  10590. * @requires Vector3DUtil
  10591. * @requires JMatrix3D
  10592. * @requires JNumber3D
  10593. * @requires JConstraintMaxDistance
  10594. * @requires JConstraintPoint
  10595. * @constant {number} MAX_HINGE_ANGLE_LIMIT
  10596. * @property {array} _hingeAxis
  10597. * @property {array} _hingePosRel0
  10598. * @property {RigidBody} body0 the first rigid body
  10599. * @property {RigidBody} body1 the second rigid body
  10600. * @property {boolean} _usingLimit
  10601. * @property {boolean} _hingeEnabled
  10602. * @property {boolean} _broken
  10603. * @property {number} _damping
  10604. * @property {number} _extraTorque
  10605. * @property {array} sidePointConstraints used to store 2 JConstraintMaxDistance instances
  10606. * @property {JConstraintPoint} midPointConstraint
  10607. * @property {JConstraintMaxDistance} maxDistanceConstraint
  10608. * @property {array} r a 3D vector
  10609. * @constructor
  10610. * @param {RigidBody} _body0 the first body of the constrained pair
  10611. * @param {RigidBody} _body1 the second body of the constrained pair
  10612. * @param {array} _hingeAxis
  10613. * @param {array} _hingePosRel0
  10614. * @param {number} hingeHalfWidth
  10615. * @param {number} hingeFwdAngle
  10616. * @param {number} hingeBckAngle
  10617. * @param {number} sidewaysSlack
  10618. * @param {number} damping
  10619. **/
  10620. var HingeJoint=function(body0, body1, hingeAxis, hingePosRel0, hingeHalfWidth, hingeFwdAngle, hingeBckAngle, sidewaysSlack, damping){
  10621. this._body0 = body0;
  10622. this._body1 = body1;
  10623. this._hingeAxis = hingeAxis.slice(0);
  10624. this._hingePosRel0 = hingePosRel0.slice(0);
  10625. this._usingLimit = false;
  10626. this._hingeEnabled = false;
  10627. this._broken = false;
  10628. this._damping = damping;
  10629. this._extraTorque = 0;
  10630. Vector3DUtil.normalize(this._hingeAxis);
  10631. var _hingePosRel1 = Vector3DUtil.add(this._body0.get_currentState().position, Vector3DUtil.subtract(this._hingePosRel0, this._body1.get_currentState().position));
  10632. var relPos0a = Vector3DUtil.add(this._hingePosRel0, JNumber3D.getScaleVector(this._hingeAxis, hingeHalfWidth));
  10633. var relPos0b = Vector3DUtil.subtract(this._hingePosRel0, JNumber3D.getScaleVector(this._hingeAxis, hingeHalfWidth));
  10634. var relPos1a = Vector3DUtil.add(_hingePosRel1, JNumber3D.getScaleVector(this._hingeAxis, hingeHalfWidth));
  10635. var relPos1b = Vector3DUtil.subtract(_hingePosRel1, JNumber3D.getScaleVector(this._hingeAxis, hingeHalfWidth));
  10636. var timescale = 1 / 20;
  10637. var allowedDistanceMid = 0.005;
  10638. var allowedDistanceSide = sidewaysSlack * hingeHalfWidth;
  10639. this.sidePointConstraints = [];
  10640. this.sidePointConstraints[0] = new JConstraintMaxDistance(this._body0, relPos0a, this._body1, relPos1a, allowedDistanceSide);
  10641. this.sidePointConstraints[1] = new JConstraintMaxDistance(this._body0, relPos0b, this._body1, relPos1b, allowedDistanceSide);
  10642. this.midPointConstraint = new JConstraintPoint(this._body0, this._hingePosRel0, this._body1, _hingePosRel1, allowedDistanceMid, timescale);
  10643. if (hingeFwdAngle <= this.MAX_HINGE_ANGLE_LIMIT){
  10644. var perpDir = Vector3DUtil.Y_AXIS;
  10645. if (Vector3DUtil.dotProduct(perpDir, this._hingeAxis) > 0.1){
  10646. perpDir[0] = 1;
  10647. perpDir[1] = 0;
  10648. perpDir[2] = 0;
  10649. }
  10650. var sideAxis = Vector3DUtil.crossProduct(this._hingeAxis, perpDir);
  10651. perpDir = Vector3DUtil.crossProduct(sideAxis, this._hingeAxis);
  10652. Vector3DUtil.normalize(perpDir);
  10653. var len = 10 * hingeHalfWidth;
  10654. var hingeRelAnchorPos0 = JNumber3D.getScaleVector(perpDir, len);
  10655. var angleToMiddle = 0.5 * (hingeFwdAngle - hingeBckAngle);
  10656. var hingeRelAnchorPos1 = hingeRelAnchorPos0.slice(0);
  10657. JMatrix3D.multiplyVector(JMatrix3D.getRotationMatrix(this._hingeAxis[0], this._hingeAxis[1], this._hingeAxis[2], -angleToMiddle), hingeRelAnchorPos1);
  10658. var hingeHalfAngle = 0.5 * (hingeFwdAngle + hingeBckAngle);
  10659. var allowedDistance = len * 2 * Math.sin(0.5 * hingeHalfAngle * Math.PI / 180);
  10660. var hingePos = Vector3DUtil.add(this._body1.get_currentState().position, this._hingePosRel0);
  10661. var relPos0c = Vector3DUtil.add(hingePos, Vector3DUtil.subtract(hingeRelAnchorPos0, this._body0.get_currentState().position));
  10662. var relPos1c = Vector3DUtil.add(hingePos, Vector3DUtil.subtract(hingeRelAnchorPos1, this._body1.get_currentState().position));
  10663. this.maxDistanceConstraint = new JConstraintMaxDistance(this._body0, relPos0c, this._body1, relPos1c, allowedDistance);
  10664. this._usingLimit = true;
  10665. }
  10666. if (this._damping <= 0){
  10667. this._damping = -1;
  10668. }else{
  10669. this._damping = JNumber3D.getLimiteNumber(this._damping, 0, 1);
  10670. }
  10671. this.enableHinge();
  10672. };
  10673. jigLib.extend(HingeJoint, jigLib.PhysicsController);
  10674. HingeJoint.prototype.MAX_HINGE_ANGLE_LIMIT = 150;
  10675. HingeJoint.prototype._hingeAxis = null;
  10676. HingeJoint.prototype._hingePosRel0 = null;
  10677. HingeJoint.prototype._body0 = null;
  10678. HingeJoint.prototype._body1 = null;
  10679. HingeJoint.prototype._usingLimit = null;
  10680. HingeJoint.prototype._hingeEnabled = null;
  10681. HingeJoint.prototype._broken = null;
  10682. HingeJoint.prototype._damping = null;
  10683. HingeJoint.prototype._extraTorque = null;
  10684. HingeJoint.prototype.sidePointConstraints = null;
  10685. HingeJoint.prototype.midPointConstraint = null;
  10686. HingeJoint.prototype.maxDistanceConstraint = null;
  10687. /**
  10688. * @function enableHinge enable the joint
  10689. * @type void
  10690. **/
  10691. HingeJoint.prototype.enableHinge=function(){
  10692. if (this._hingeEnabled) return;
  10693. this.midPointConstraint.enableConstraint();
  10694. this.sidePointConstraints[0].enableConstraint();
  10695. this.sidePointConstraints[1].enableConstraint();
  10696. if (this._usingLimit && !this._broken)
  10697. this.maxDistanceConstraint.enableConstraint();
  10698. this.enableController();
  10699. this._hingeEnabled = true;
  10700. };
  10701. /**
  10702. * @function disableHinge disable the joint
  10703. * @type void
  10704. **/
  10705. HingeJoint.prototype.disableHinge=function(){
  10706. if (!this._hingeEnabled) return;
  10707. this.midPointConstraint.disableConstraint();
  10708. this.sidePointConstraints[0].disableConstraint();
  10709. this.sidePointConstraints[1].disableConstraint();
  10710. if (this._usingLimit && !this._broken)
  10711. this.maxDistanceConstraint.disableConstraint();
  10712. this.disableController();
  10713. this._hingeEnabled = false;
  10714. };
  10715. /**
  10716. * @function breakHinge break the joint
  10717. * @type void
  10718. **/
  10719. HingeJoint.prototype.breakHinge=function(){
  10720. if (this._broken) return;
  10721. if (this._usingLimit)
  10722. this.maxDistanceConstraint.disableConstraint();
  10723. this._broken = true;
  10724. };
  10725. /**
  10726. * @function mendHinge repair the joint
  10727. * @type void
  10728. **/
  10729. HingeJoint.prototype.mendHinge=function(){
  10730. if (!this._broken)
  10731. return;
  10732. if (this._usingLimit)
  10733. this.maxDistanceConstraint.enableConstraint();
  10734. this._broken = false;
  10735. };
  10736. /**
  10737. * @function setExtraTorque setter for _extraTorque
  10738. * @param {number} torque
  10739. * @type void
  10740. **/
  10741. HingeJoint.prototype.setExtraTorque=function(torque){
  10742. this._extraTorque = torque;
  10743. };
  10744. /**
  10745. * @function getExtraTorque getter for _extraTorque
  10746. * @type number
  10747. **/
  10748. HingeJoint.prototype.getHingeEnabled=function(){
  10749. return this._hingeEnabled;
  10750. };
  10751. /**
  10752. * @function isBroken getter for _broken
  10753. * @type boolean
  10754. **/
  10755. HingeJoint.prototype.isBroken=function(){
  10756. return this._broken;
  10757. };
  10758. /**
  10759. * @function getHingePosRel0 getter for _hingePosRel0
  10760. * @type array
  10761. **/
  10762. HingeJoint.prototype.getHingePosRel0=function(){
  10763. return this._hingePosRel0;
  10764. };
  10765. /**
  10766. * @function updateController updates this physics controller
  10767. * @see PhysicsSystem.updateController
  10768. * @param {number} dt a UNIX timestamp
  10769. * @type void
  10770. **/
  10771. HingeJoint.prototype.updateController=function(dt){
  10772. if (this._damping > 0){
  10773. var hingeAxis = Vector3DUtil.subtract(this._body1.get_currentState().rotVelocity, this._body0.get_currentState().rotVelocity);
  10774. Vector3DUtil.normalize(hingeAxis);
  10775. var angRot1 = Vector3DUtil.dotProduct(this._body0.get_currentState().rotVelocity, hingeAxis);
  10776. var angRot2 = Vector3DUtil.dotProduct(this._body1.get_currentState().rotVelocity, hingeAxis);
  10777. var avAngRot = 0.5 * (angRot1 + angRot2);
  10778. var frac = 1 - this._damping;
  10779. var newAngRot1= avAngRot + (angRot1 - avAngRot) * frac;
  10780. var newAngRot2= avAngRot + (angRot2 - avAngRot) * frac;
  10781. var newAngVel1 = Vector3DUtil.add(this._body0.get_currentState().rotVelocity, JNumber3D.getScaleVector(hingeAxis, newAngRot1 - angRot1));
  10782. var newAngVel2 = Vector3DUtil.add(this._body1.get_currentState().rotVelocity, JNumber3D.getScaleVector(hingeAxis, newAngRot2 - angRot2));
  10783. this._body0.setAngVel(newAngVel1);
  10784. this._body1.setAngVel(newAngVel2);
  10785. }
  10786. if (this._extraTorque != 0){
  10787. var torque1 = this._hingeAxis.slice(0);
  10788. JMatrix3D.multiplyVector(this._body0.get_currentState().get_orientation(), torque1);
  10789. torque1 = JNumber3D.getScaleVector(torque1, this._extraTorque);
  10790. this._body0.addWorldTorque(torque1);
  10791. this._body1.addWorldTorque(JNumber3D.getScaleVector(torque1, -1));
  10792. }
  10793. };
  10794. jigLib.HingeJoint=HingeJoint;
  10795. })(jigLib);
  10796. /*
  10797. Copyright (c) 2007 Danny Chapman
  10798. http://www.rowlhouse.co.uk
  10799. This software is provided 'as-is', without any express or implied
  10800. warranty. In no event will the authors be held liable for any damages
  10801. arising from the use of this software.
  10802. Permission is granted to anyone to use this software for any purpose,
  10803. including commercial applications, and to alter it and redistribute it
  10804. freely, subject to the following restrictions:
  10805. 1. The origin of this software must not be misrepresented; you must not
  10806. claim that you wrote the original software. If you use this software
  10807. in a product, an acknowledgment in the product documentation would be
  10808. appreciated but is not required.
  10809. 2. Altered source versions must be plainly marked as such, and must not be
  10810. misrepresented as being the original software.
  10811. 3. This notice may not be removed or altered from any source
  10812. distribution.
  10813. */
  10814. (function(jigLib){
  10815. var Vector3DUtil=jigLib.Vector3DUtil;
  10816. var JConfig=jigLib.JConfig;
  10817. var CollPointInfo=jigLib.CollPointInfo;
  10818. var CollisionSystemBrute=jigLib.CollisionSystemBrute;
  10819. var CollisionSystemGrid=jigLib.CollisionSystemGrid;
  10820. var ContactData=jigLib.ContactData;
  10821. var JMatrix3D=jigLib.JMatrix3D;
  10822. var JNumber3D=jigLib.JNumber3D;
  10823. var BodyPair=jigLib.BodyPair;
  10824. var CachedImpulse=jigLib.CachedImpulse;
  10825. var JCollisionEvent=jigLib.JCollisionEvent;
  10826. /**
  10827. * @name PhysicsSystem
  10828. * @class PhysicsSystem a singleton representing the physics system
  10829. * @requires Vector3DUtil
  10830. * @requires JConfig
  10831. * @requires CollPointInfo
  10832. * @requires CollisionSystem
  10833. * @requires ContactData
  10834. * @requires JMatrix3D
  10835. * @requires JNumber3D
  10836. * @requires BodyPair
  10837. * @requires CachedImpulse
  10838. * @property {PhysicsSystem} _currentPhysicsSystem
  10839. * @property {number} _maxVelMag
  10840. * @property {number} _minVelForProcessing
  10841. * @property {array} _bodies a collection of RigidBody objects
  10842. * @property {array} _activeBodies a collection of RigidBody objects
  10843. * @property {array} _collisions a collection of CollisionInfo objects
  10844. * @property {array} _constraints a collection of JConstraint objects
  10845. * @property {array} _controllers a collection of PhysicsController objects
  10846. * @property {array} _effects a collection of JEffect objects
  10847. * @property {number} _gravityAxis
  10848. * @property {array} _gravity a 3D vector
  10849. * @property {boolean} _doingIntegration
  10850. * @property {function} preProcessCollisionFn
  10851. * @property {function} preProcessContactFn
  10852. * @property {function} processCollisionFn
  10853. * @property {function} processContactFn
  10854. * @property {array} _cachedContacts a collection of ContactData objects
  10855. * @property {CollisionSystem} _collisionSystem
  10856. * @constructor
  10857. **/
  10858. var PhysicsSystem=function(){
  10859. this.setSolverType(JConfig.solverType);
  10860. this._doingIntegration = false;
  10861. this._bodies = [];
  10862. this._collisions = [];
  10863. this._effects=[];
  10864. this._activeBodies = [];
  10865. this._constraints = [];
  10866. this._controllers = [];
  10867. this._cachedContacts = [];
  10868. this._collisionSystem = new CollisionSystemBrute();
  10869. this.setGravity(JNumber3D.getScaleVector(Vector3DUtil.Y_AXIS, -10));
  10870. };
  10871. PhysicsSystem.prototype._currentPhysicsSystem=null;
  10872. PhysicsSystem.prototype._maxVelMag = 0.5;
  10873. PhysicsSystem.prototype._minVelForProcessing = 0.001;
  10874. PhysicsSystem.prototype._bodies = null;
  10875. PhysicsSystem.prototype._activeBodies=null;
  10876. PhysicsSystem.prototype._collisions=null;
  10877. PhysicsSystem.prototype._constraints=null;
  10878. PhysicsSystem.prototype._controllers=null;
  10879. PhysicsSystem.prototype._effects=null;
  10880. PhysicsSystem.prototype._gravityAxis=null;
  10881. PhysicsSystem.prototype._gravity=null;
  10882. PhysicsSystem.prototype._doingIntegration=null;
  10883. PhysicsSystem.prototype.preProcessCollisionFn=function(){};
  10884. PhysicsSystem.prototype.preProcessContactFn=function(){};
  10885. PhysicsSystem.prototype.processCollisionFn=function(){};
  10886. PhysicsSystem.prototype.processContactFn=function(){};
  10887. PhysicsSystem.prototype._cachedContacts=null;
  10888. PhysicsSystem.prototype._collisionSystem=null;
  10889. /**
  10890. * @function getInstance returns the singleton instance
  10891. * @type PhysicsSystem
  10892. **/
  10893. PhysicsSystem.getInstance=function(){
  10894. if (!PhysicsSystem._currentPhysicsSystem){
  10895. PhysicsSystem._currentPhysicsSystem = new PhysicsSystem();
  10896. }
  10897. return PhysicsSystem._currentPhysicsSystem;
  10898. };
  10899. /**
  10900. * @function getAllExternalForces
  10901. * @type void
  10902. **/
  10903. PhysicsSystem.prototype.getAllExternalForces=function(dt){
  10904. for(var i=0, bl=this._bodies.length; i<bl; i++){
  10905. this._bodies[i].addExternalForces(dt);
  10906. }
  10907. for(var i=0, cl=this._controllers.length; i<cl; i++){
  10908. this._controllers[i].updateController(dt);
  10909. }
  10910. };
  10911. //TODO document here
  10912. PhysicsSystem.prototype.setCollisionSystem=function(collisionSystemGrid, sx, sy, sz, nx, ny, nz, dx, dy, dz){
  10913. if(sx==undefined) sx=0;
  10914. if(sy==undefined) sy=0;
  10915. if(sz==undefined) sz=0;
  10916. if(nx==undefined) nx=20;
  10917. if(ny==undefined) ny=20;
  10918. if(nz==undefined) nz=20;
  10919. if(dx==undefined) dx=200;
  10920. if(dy==undefined) dy=200;
  10921. if(dz==undefined) dz=200;
  10922. // which collisionsystem to use grid / brute
  10923. if (collisionSystemGrid){
  10924. this._collisionSystem = new CollisionSystemGrid(sx, sy, sz, nx, ny, nz, dx, dy, dz);
  10925. }else{
  10926. this._collisionSystem = new CollisionSystemBrute(); // brute by default
  10927. }
  10928. };
  10929. /**
  10930. * @function getCollisionSystem getter for _collisionSystem
  10931. * @type CollisionSystem
  10932. **/
  10933. PhysicsSystem.prototype.getCollisionSystem=function(){
  10934. return this._collisionSystem;
  10935. };
  10936. /**
  10937. * @function setGravity
  10938. * @param {array} gravity a 3D vector
  10939. * @type void
  10940. **/
  10941. PhysicsSystem.prototype.setGravity=function(gravity){
  10942. this._gravity = gravity;
  10943. if (this._gravity[0] == this._gravity[1] && this._gravity[1] == this._gravity[2])
  10944. this._gravityAxis = -1;
  10945. this._gravityAxis = 0;
  10946. if (Math.abs(this._gravity[1]) > Math.abs(this._gravity[2]))
  10947. this._gravityAxis = 1;
  10948. if (Math.abs(this._gravity[2]) > Math.abs(this._gravity[this._gravityAxis]))
  10949. this._gravityAxis = 2;
  10950. };
  10951. /**
  10952. * @function get_gravity global gravity acceleration
  10953. * @type array
  10954. **/
  10955. PhysicsSystem.prototype.get_gravity=function(){
  10956. return this._gravity;
  10957. };
  10958. /**
  10959. * @function get_gravityAxis getter for _gravityAxis
  10960. * @type number
  10961. **/
  10962. PhysicsSystem.prototype.get_gravityAxis=function(){
  10963. return this._gravityAxis;
  10964. };
  10965. /**
  10966. * @function get_bodies getter for _bodies
  10967. * @type array
  10968. **/
  10969. PhysicsSystem.prototype.get_bodies=function(){
  10970. return this._bodies;
  10971. };
  10972. /**
  10973. * @function addBody add a RigidBody to the simulation
  10974. * @param {RigidBody} body
  10975. * @type void
  10976. **/
  10977. PhysicsSystem.prototype.addBody=function(body){
  10978. if (!this.findBody(body)){
  10979. this._bodies.push(body);
  10980. this._collisionSystem.addCollisionBody(body);
  10981. }
  10982. };
  10983. /**
  10984. * @function removeBody remove a RigidBody from the simulation
  10985. * @param {RigidBody} body
  10986. * @type void
  10987. **/
  10988. PhysicsSystem.prototype.removeBody=function(body){
  10989. if (this.findBody(body)){
  10990. this._bodies.splice(this._bodies.indexOf(body), 1);
  10991. this._collisionSystem.removeCollisionBody(body);
  10992. }
  10993. };
  10994. /**
  10995. * @function removeAllBodies remove all bodies from the simulation
  10996. * @type void
  10997. **/
  10998. PhysicsSystem.prototype.removeAllBodies=function(){
  10999. this._bodies = [];
  11000. this._collisionSystem.removeAllCollisionBodies();
  11001. };
  11002. /**
  11003. * @function addConstraint add a constraint to the simulation
  11004. * @param {JConstraint} constraint
  11005. * @type void
  11006. **/
  11007. PhysicsSystem.prototype.addConstraint=function(constraint){
  11008. if (!this.findConstraint(constraint))
  11009. this._constraints.push(constraint);
  11010. };
  11011. /**
  11012. * @function removeConstraint remove a constraint from the simulation
  11013. * @param {JConstraint} constraint
  11014. * @type void
  11015. **/
  11016. PhysicsSystem.prototype.removeConstraint=function(constraint){
  11017. if (this.findConstraint(constraint))
  11018. this._constraints.splice(this._constraints.indexOf(constraint), 1);
  11019. };
  11020. /**
  11021. * @function removeAllConstraints remove all constraints from the simulation
  11022. * @type void
  11023. **/
  11024. PhysicsSystem.prototype.removeAllConstraints=function(){
  11025. this._constraints = [];
  11026. };
  11027. /**
  11028. * @function addEffect add an effect to the simulation
  11029. * @param {JEffect} effect
  11030. * @type void
  11031. **/
  11032. PhysicsSystem.prototype.addEffect=function(effect){
  11033. if (!this.findEffect(effect))
  11034. this._effects.push(effect);
  11035. };
  11036. /**
  11037. * @function removeEffect remove an effect from the simulation
  11038. * @param {JEffect} effect
  11039. * @type void
  11040. **/
  11041. PhysicsSystem.prototype.removeEffect=function(effect){
  11042. if (this.findEffect(effect))
  11043. this._effects.splice(this._effects.indexOf(effect), 1);
  11044. };
  11045. /**
  11046. * @function removeAllEffects remove all effects from the simulation
  11047. * @type void
  11048. **/
  11049. PhysicsSystem.prototype.removeAllEffects=function(){
  11050. this._effects = [];
  11051. };
  11052. /**
  11053. * @function addController add a physics controller to the simulation
  11054. * @param {PhysicsController} controller
  11055. * @type void
  11056. **/
  11057. PhysicsSystem.prototype.addController=function(controller){
  11058. if (!this.findController(controller))
  11059. this._controllers.push(controller);
  11060. };
  11061. /**
  11062. * @function removeController remove a physics controller from the simulation
  11063. * @param {PhysicsController} controller
  11064. * @type void
  11065. **/
  11066. PhysicsSystem.prototype.removeController=function(controller){
  11067. if (this.findController(controller))
  11068. this._controllers.splice(this._controllers.indexOf(controller), 1);
  11069. };
  11070. /**
  11071. * @function removeAllControllers remove all physics controllers from the simulation
  11072. * @type void
  11073. **/
  11074. PhysicsSystem.prototype.removeAllControllers=function(){
  11075. this._controllers = [];
  11076. };
  11077. /**
  11078. * @function setSolverType select which solver type should be used for the simulation
  11079. * @see JConfig.solverType
  11080. * @param {string} type
  11081. * @type void
  11082. **/
  11083. PhysicsSystem.prototype.setSolverType=function(type){
  11084. switch (type)
  11085. {
  11086. case "FAST":
  11087. this.preProcessCollisionFn = this.preProcessCollisionFast;
  11088. this.preProcessContactFn = this.preProcessCollisionFast;
  11089. this.processCollisionFn = this.processCollision;
  11090. this.processContactFn = this.processCollision;
  11091. return;
  11092. case "NORMAL":
  11093. this.preProcessCollisionFn = this.preProcessCollisionNormal;
  11094. this.preProcessContactFn = this.preProcessCollisionNormal;
  11095. this.processCollisionFn = this.processCollision;
  11096. this.processContactFn = this.processCollision;
  11097. return;
  11098. case "ACCUMULATED":
  11099. this.preProcessCollisionFn = this.preProcessCollisionAccumulated;
  11100. this.preProcessContactFn = this.preProcessCollisionAccumulated;
  11101. this.processCollisionFn = this.processCollision;
  11102. this.processContactFn = this.processCollisionAccumulated;
  11103. return;
  11104. default:
  11105. this.preProcessCollisionFn = this.preProcessCollisionNormal;
  11106. this.preProcessContactFn = this.preProcessCollisionNormal;
  11107. this.processCollisionFn = this.processCollision;
  11108. this.processContactFn = this.processCollision;
  11109. return;
  11110. }
  11111. };
  11112. /**
  11113. * @function findBody find a body in _bodies
  11114. * @param {RigidBody} body
  11115. * @returns true if the body is found, otherwise false
  11116. * @type boolean
  11117. **/
  11118. PhysicsSystem.prototype.findBody=function(body){
  11119. return (this._bodies.indexOf(body)>-1);
  11120. };
  11121. /**
  11122. * @function findConstraint find a constraint in _constraints
  11123. * @param {JConstraint} constraint
  11124. * @returns true if the constraint is found, otherwise false
  11125. * @type boolean
  11126. **/
  11127. PhysicsSystem.prototype.findConstraint=function(constraint){
  11128. var i=this._constraints.length-1;
  11129. if (i > 0) do { if(constraint==this._constraints[i]) return true; } while (i--);
  11130. return false;
  11131. };
  11132. /**
  11133. * @function findEffect find an effect in _effects
  11134. * @param {JEffect} effect
  11135. * @returns true if the effect is found, otherwise false
  11136. * @type boolean
  11137. **/
  11138. PhysicsSystem.prototype.findEffect=function(effect){
  11139. var i=this._effects.length-1;
  11140. if (i > 0) do { if(effect==this._effects[i]) return true; } while (i--);
  11141. return false;
  11142. };
  11143. /**
  11144. * @function findController find a controller in _controllers
  11145. * @param {PhysicsController} controller
  11146. * @returns true if the controller is found, otherwise false
  11147. * @type boolean
  11148. **/
  11149. PhysicsSystem.prototype.findController=function(controller){
  11150. var i=this._controllers.length-1;
  11151. if (i > 0) do { if(controller==this._controllers[i]) return true; } while (i--);
  11152. return false;
  11153. };
  11154. /**
  11155. * @function preProcessCollisionFast a fast-but-inaccurate pre-processor
  11156. * @param {CollisionInfo} collision
  11157. * @param {number} dt a UNIX timestamp
  11158. * @type void
  11159. **/
  11160. PhysicsSystem.prototype.preProcessCollisionFast=function(collision, dt){
  11161. collision.satisfied=false;
  11162. var body0 = collision.objInfo.body0;
  11163. var body1 = collision.objInfo.body1;
  11164. var N = collision.dirToBody;
  11165. var timescale = JConfig.numPenetrationRelaxationTimesteps * dt;
  11166. var approachScale = 0;
  11167. var ptInfo;
  11168. var tempV;
  11169. var ptNum = collision.pointInfo.length;
  11170. var numTiny = JNumber3D.NUM_TINY;
  11171. if (ptNum > 1){
  11172. var avR0 = [0,0,0,0];
  11173. var avR1 = [0,0,0,0];
  11174. var avDepth = 0;
  11175. for (var i = 0; i < ptNum; i++){
  11176. ptInfo = collision.pointInfo[i];
  11177. avR0 = Vector3DUtil.add(avR0, ptInfo.r0);
  11178. avR1 = Vector3DUtil.add(avR1, ptInfo.r1);
  11179. avDepth += ptInfo.initialPenetration;
  11180. }
  11181. avR0 = JNumber3D.getDivideVector(avR0, ptNum);
  11182. avR1 = JNumber3D.getDivideVector(avR1, ptNum);
  11183. avDepth /= ptNum;
  11184. var colPI = new CollPointInfo();
  11185. colPI.r0 = avR0;
  11186. colPI.r1 = avR1;
  11187. colPI.initialPenetration = avDepth;
  11188. collision.pointInfo = [colPI];
  11189. }
  11190. // removed loop because collision.pointInfo.length can only ever be 1 - Jim Sangwine
  11191. ptInfo = collision.pointInfo[0];
  11192. if (!body0.get_movable()){
  11193. ptInfo.denominator = 0;
  11194. }else{
  11195. tempV = Vector3DUtil.crossProduct(ptInfo.r0, N);
  11196. JMatrix3D.multiplyVector(body0.get_worldInvInertia(), tempV);
  11197. ptInfo.denominator = body0.get_invMass() + Vector3DUtil.dotProduct(N, Vector3DUtil.crossProduct(tempV, ptInfo.r0));
  11198. }
  11199. if (body1.get_movable()){
  11200. tempV = Vector3DUtil.crossProduct(ptInfo.r1, N);
  11201. JMatrix3D.multiplyVector(body1.get_worldInvInertia(), tempV);
  11202. ptInfo.denominator += (body1.get_invMass() + Vector3DUtil.dotProduct(N, Vector3DUtil.crossProduct(tempV, ptInfo.r1)));
  11203. }
  11204. if (ptInfo.denominator < numTiny)
  11205. ptInfo.denominator = numTiny;
  11206. if (ptInfo.initialPenetration > JConfig.allowedPenetration){
  11207. ptInfo.minSeparationVel = (ptInfo.initialPenetration - JConfig.allowedPenetration) / timescale;
  11208. }else{
  11209. approachScale = -0.1 * (ptInfo.initialPenetration - JConfig.allowedPenetration) / JConfig.allowedPenetration;
  11210. if (approachScale < numTiny)
  11211. approachScale = numTiny;
  11212. else if (approachScale > 1)
  11213. approachScale = 1;
  11214. var max = (dt > numTiny) ? dt : numTiny; // ~7x quicker than Math.max in Chromium, ~4x quicker in WebKit and marginally slower in Minefield
  11215. ptInfo.minSeparationVel = approachScale * (ptInfo.initialPenetration - JConfig.allowedPenetration) / max;
  11216. }
  11217. if (ptInfo.minSeparationVel > this._maxVelMag)
  11218. ptInfo.minSeparationVel = this._maxVelMag;
  11219. };
  11220. /**
  11221. * @function preProcessCollisionNormal a special pre-processor for the normal solver
  11222. * @param {CollisionInfo} collision
  11223. * @param {number} dt a UNIX timestamp
  11224. * @type void
  11225. **/
  11226. PhysicsSystem.prototype.preProcessCollisionNormal=function(collision, dt){
  11227. collision.satisfied = false;
  11228. var body0 = collision.objInfo.body0;
  11229. var body1 = collision.objInfo.body1;
  11230. var N = collision.dirToBody;
  11231. var timescale= JConfig.numPenetrationRelaxationTimesteps * dt;
  11232. var approachScale = 0;
  11233. var ptInfo;
  11234. var tempV;
  11235. var len= collision.pointInfo.length;
  11236. for (var i = 0; i < len; i++){
  11237. ptInfo = collision.pointInfo[i];
  11238. if (!body0.get_movable()){
  11239. ptInfo.denominator = 0;
  11240. }else{
  11241. tempV = Vector3DUtil.crossProduct(ptInfo.r0, N);
  11242. JMatrix3D.multiplyVector(body0.get_worldInvInertia(), tempV);
  11243. ptInfo.denominator = body0.get_invMass() + Vector3DUtil.dotProduct(N, Vector3DUtil.crossProduct(tempV, ptInfo.r0));
  11244. }
  11245. if (body1.get_movable()){
  11246. tempV = Vector3DUtil.crossProduct(ptInfo.r1, N);
  11247. JMatrix3D.multiplyVector(body1.get_worldInvInertia(), tempV);
  11248. ptInfo.denominator += (body1.get_invMass() + Vector3DUtil.dotProduct(N, Vector3DUtil.crossProduct(tempV, ptInfo.r1)));
  11249. }
  11250. if (ptInfo.denominator < JNumber3D.NUM_TINY)
  11251. ptInfo.denominator = JNumber3D.NUM_TINY;
  11252. if (ptInfo.initialPenetration > JConfig.allowedPenetration){
  11253. ptInfo.minSeparationVel = (ptInfo.initialPenetration - JConfig.allowedPenetration) / timescale;
  11254. }else{
  11255. approachScale = -0.1 * (ptInfo.initialPenetration - JConfig.allowedPenetration) / JConfig.allowedPenetration;
  11256. if (approachScale < JNumber3D.NUM_TINY)
  11257. approachScale = JNumber3D.NUM_TINY;
  11258. else if (approachScale > 1)
  11259. approachScale = 1;
  11260. var max=(dt > JNumber3D.NUM_TINY) ? dt : JNumber3D.NUM_TINY;
  11261. ptInfo.minSeparationVel = approachScale * (ptInfo.initialPenetration - JConfig.allowedPenetration) / max;
  11262. }
  11263. if (ptInfo.minSeparationVel > this._maxVelMag)
  11264. ptInfo.minSeparationVel = this._maxVelMag;
  11265. }
  11266. };
  11267. /**
  11268. * @function preProcessCollisionAccumulated a special pre-processor for the accumulated solver
  11269. * @param {CollisionInfo} collision
  11270. * @param {number} dt a UNIX timestamp
  11271. * @type void
  11272. **/
  11273. PhysicsSystem.prototype.preProcessCollisionAccumulated=function(collision, dt){
  11274. collision.satisfied = false;
  11275. var body0 = collision.objInfo.body0;
  11276. var body1 = collision.objInfo.body1;
  11277. var N = collision.dirToBody;
  11278. var timescale = JConfig.numPenetrationRelaxationTimesteps * dt;
  11279. var tempV;
  11280. var ptInfo;
  11281. var initMinAllowedPen;
  11282. var approachScale = 0;
  11283. var numTiny = JNumber3D.NUM_TINY;
  11284. var allowedPenetration = JConfig.allowedPenetration;
  11285. var len = collision.pointInfo.length;
  11286. for (var i = 0; i < len; i++){
  11287. ptInfo = collision.pointInfo[i];
  11288. initMinAllowedPen = ptInfo.initialPenetration - allowedPenetration;
  11289. if (!body0.get_movable()){
  11290. ptInfo.denominator = 0;
  11291. }else{
  11292. tempV = Vector3DUtil.crossProduct(ptInfo.r0, N);
  11293. JMatrix3D.multiplyVector(body0.get_worldInvInertia(), tempV);
  11294. ptInfo.denominator = body0.get_invMass() + Vector3DUtil.dotProduct(N, Vector3DUtil.crossProduct(tempV, ptInfo.r0));
  11295. }
  11296. if (body1.get_movable()){
  11297. tempV = Vector3DUtil.crossProduct(ptInfo.r1, N);
  11298. JMatrix3D.multiplyVector(body1.get_worldInvInertia(), tempV);
  11299. ptInfo.denominator += (body1.get_invMass() + Vector3DUtil.dotProduct(N, Vector3DUtil.crossProduct(tempV, ptInfo.r1)));
  11300. }
  11301. if (ptInfo.denominator < numTiny) ptInfo.denominator = numTiny;
  11302. if (ptInfo.initialPenetration > allowedPenetration){
  11303. ptInfo.minSeparationVel = initMinAllowedPen / timescale;
  11304. }else{
  11305. approachScale = -0.1 * initMinAllowedPen / allowedPenetration;
  11306. if (approachScale < numTiny) approachScale = numTiny;
  11307. else if (approachScale > 1) approachScale = 1;
  11308. var max=(dt>numTiny) ? dt : numTiny;
  11309. ptInfo.minSeparationVel = approachScale * initMinAllowedPen / max;
  11310. }
  11311. ptInfo.accumulatedNormalImpulse = 0;
  11312. ptInfo.accumulatedNormalImpulseAux = 0;
  11313. ptInfo.accumulatedFrictionImpulse = [0,0,0,0];
  11314. var bestDistSq = 0.04;
  11315. var bp = new BodyPair(body0, body1, [0,0,0,0], [0,0,0,0]);
  11316. for(var j=0, ccl=this._cachedContacts.length; j<ccl; j++){
  11317. var cont=this._cachedContacts[j];
  11318. var cpair=cont.pair;
  11319. if (bp.body0 != cpair.body0 || bp.body1 == cpair.body1)
  11320. continue;
  11321. var distSq = (cpair.body0 == body0) ? Vector3DUtil.get_lengthSquared(Vector3DUtil.subtract(cpair.r, ptInfo.r0))
  11322. : Vector3DUtil.get_lengthSquared(Vector3DUtil.subtract(cpair.r, ptInfo.r1));
  11323. if (distSq < bestDistSq){
  11324. bestDistSq = distSq;
  11325. ptInfo.accumulatedNormalImpulse = this._cachedContacts[j].impulse.normalImpulse;
  11326. ptInfo.accumulatedNormalImpulseAux = this._cachedContacts[j].impulse.normalImpulseAux;
  11327. ptInfo.accumulatedFrictionImpulse = this._cachedContacts[j].impulse.frictionImpulse;
  11328. if (this._cachedContacts[j].pair.body0 != body0){
  11329. ptInfo.accumulatedFrictionImpulse = JNumber3D.getScaleVector(ptInfo.accumulatedFrictionImpulse, -1);
  11330. }
  11331. }
  11332. }
  11333. var impulse;
  11334. if (ptInfo.accumulatedNormalImpulse != 0){
  11335. impulse = JNumber3D.getScaleVector(N, ptInfo.accumulatedNormalImpulse);
  11336. impulse = Vector3DUtil.add(impulse, ptInfo.accumulatedFrictionImpulse);
  11337. body0.applyBodyWorldImpulse(impulse, ptInfo.r0);
  11338. body1.applyBodyWorldImpulse(JNumber3D.getScaleVector(impulse, -1), ptInfo.r1);
  11339. }
  11340. if (ptInfo.accumulatedNormalImpulseAux != 0){
  11341. impulse = JNumber3D.getScaleVector(N, ptInfo.accumulatedNormalImpulseAux);
  11342. body0.applyBodyWorldImpulseAux(impulse, ptInfo.r0);
  11343. body1.applyBodyWorldImpulseAux(JNumber3D.getScaleVector(impulse, -1), ptInfo.r1);
  11344. }
  11345. }
  11346. };
  11347. /**
  11348. * @function processCollision handle an individual collision by classifying it, calculating
  11349. * impulse, applying impulse and updating the velocities of the objects. Allows over-riding of the elasticity.
  11350. *
  11351. * @param {CollisionInfo} collision
  11352. * @param {number} dt a UNIX timestamp
  11353. * @returns true if an impulse was applied, otherwise false
  11354. * @type boolean
  11355. **/
  11356. PhysicsSystem.prototype.processCollision=function(collision, dt){
  11357. collision.satisfied = true;
  11358. var body0 = collision.objInfo.body0;
  11359. var body1 = collision.objInfo.body1;
  11360. var gotOne = false;
  11361. var N = collision.dirToBody;
  11362. var deltaVel = 0;
  11363. var normalVel = 0;
  11364. var finalNormalVel = 0;
  11365. var normalImpulse= 0;
  11366. var impulse;
  11367. var Vr0;
  11368. var Vr1;
  11369. var ptInfo;
  11370. // tracking var for the collision event
  11371. var appliedImpulse = [0,0,0,0];
  11372. var len = collision.pointInfo.length;
  11373. for (var i = 0; i < len; i++){
  11374. ptInfo = collision.pointInfo[i];
  11375. Vr0 = body0.getVelocity(ptInfo.r0);
  11376. Vr1 = body1.getVelocity(ptInfo.r1);
  11377. normalVel = Vector3DUtil.dotProduct(Vector3DUtil.subtract(Vr0, Vr1), N);
  11378. if (normalVel > ptInfo.minSeparationVel)
  11379. continue;
  11380. finalNormalVel = -1 * collision.mat.get_restitution() * normalVel;
  11381. if (finalNormalVel < this._minVelForProcessing)
  11382. finalNormalVel = ptInfo.minSeparationVel;
  11383. deltaVel = finalNormalVel - normalVel;
  11384. if (deltaVel <= this._minVelForProcessing)
  11385. continue;
  11386. normalImpulse = deltaVel / ptInfo.denominator;
  11387. gotOne = true;
  11388. impulse = JNumber3D.getScaleVector(N, normalImpulse);
  11389. appliedImpulse = Vector3DUtil.add(appliedImpulse, impulse); // keep track of the total impulse applied
  11390. body0.applyBodyWorldImpulse(impulse, ptInfo.r0);
  11391. body1.applyBodyWorldImpulse(JNumber3D.getScaleVector(impulse, -1), ptInfo.r1);
  11392. Vr0 = body0.getVelocity(ptInfo.r0);
  11393. Vr1 = body1.getVelocity(ptInfo.r1);
  11394. var tempV;
  11395. var VR = Vr0.slice(0);
  11396. if(body1.get_movable()) VR = Vector3DUtil.subtract(Vr0, Vr1);
  11397. var tangent_vel = Vector3DUtil.subtract(VR, JNumber3D.getScaleVector(N, Vector3DUtil.dotProduct(VR, N)));
  11398. var tangent_speed = Vector3DUtil.get_length(tangent_vel);
  11399. if (tangent_speed > this._minVelForProcessing){
  11400. var T = JNumber3D.getDivideVector(tangent_vel, -tangent_speed);
  11401. var denominator = 0;
  11402. if (body0.get_movable()){
  11403. tempV = Vector3DUtil.crossProduct(ptInfo.r0, T);
  11404. JMatrix3D.multiplyVector(body0.get_worldInvInertia(), tempV);
  11405. denominator = body0.get_invMass() + Vector3DUtil.dotProduct(T, Vector3DUtil.crossProduct(tempV, ptInfo.r0));
  11406. }
  11407. if (body1.get_movable()){
  11408. tempV = Vector3DUtil.crossProduct(ptInfo.r1, T);
  11409. JMatrix3D.multiplyVector(body1.get_worldInvInertia(), tempV);
  11410. denominator += (body1.get_invMass() + Vector3DUtil.dotProduct(T, Vector3DUtil.crossProduct(tempV, ptInfo.r1)));
  11411. }
  11412. if (denominator > JNumber3D.NUM_TINY){
  11413. var impulseToReverse = tangent_speed / denominator;
  11414. T = JNumber3D.getScaleVector(T, impulseToReverse);
  11415. body0.applyBodyWorldImpulse(T, ptInfo.r0);
  11416. body1.applyBodyWorldImpulse(JNumber3D.getScaleVector(T, -1), ptInfo.r1);
  11417. }
  11418. }
  11419. }
  11420. if (gotOne){
  11421. body0.setConstraintsAndCollisionsUnsatisfied();
  11422. body1.setConstraintsAndCollisionsUnsatisfied();
  11423. // dispatch collision events
  11424. if(Vector3DUtil.get_length(appliedImpulse)>0){ //only fire event if the impulse size is greater then zero
  11425. body0.dispatchEvent(new JCollisionEvent(body1, appliedImpulse));
  11426. body1.dispatchEvent(new JCollisionEvent(body0, JNumber3D.getScaleVector(appliedImpulse, -1)));
  11427. }
  11428. }
  11429. return gotOne;
  11430. };
  11431. /**
  11432. * @function processCollisionAccumulated accumulated and clamp impulses
  11433. *
  11434. * @param {CollisionInfo} collision
  11435. * @param {number} dt a UNIX timestamp
  11436. * @returns true if an impulse was applied, otherwise false
  11437. * @type boolean
  11438. **/
  11439. PhysicsSystem.prototype.processCollisionAccumulated=function(collision, dt){
  11440. collision.satisfied = true;
  11441. var gotOne = false;
  11442. var N = collision.dirToBody;
  11443. var body0 = collision.objInfo.body0;
  11444. var body1 = collision.objInfo.body1;
  11445. var deltaVel = 0;
  11446. var normalVel = 0;
  11447. var normalImpulse = 0;
  11448. var impulse;
  11449. var Vr0;
  11450. var Vr1;
  11451. var ptInfo;
  11452. // tracking var for the collision event
  11453. var appliedImpulse = [0,0,0,0];
  11454. var len = collision.pointInfo.length;
  11455. for (var i = 0; i < len; i++){
  11456. ptInfo = collision.pointInfo[i];
  11457. Vr0 = body0.getVelocity(ptInfo.r0);
  11458. Vr1 = body1.getVelocity(ptInfo.r1);
  11459. normalVel = Vector3DUtil.dotProduct(Vector3DUtil.subtract(Vr0, Vr1), N);
  11460. deltaVel = -normalVel;
  11461. if (ptInfo.minSeparationVel < 0)
  11462. deltaVel += ptInfo.minSeparationVel;
  11463. if (Math.abs(deltaVel) > this._minVelForProcessing){
  11464. normalImpulse = deltaVel / ptInfo.denominator;
  11465. var origAccumulatedNormalImpulse = ptInfo.accumulatedNormalImpulse;
  11466. var accImpulse=(origAccumulatedNormalImpulse + normalImpulse);
  11467. if (accImpulse<0) accImpulse = 0;
  11468. ptInfo.accumulatedNormalImpulse = accImpulse;
  11469. var actualImpulse = accImpulse - origAccumulatedNormalImpulse;
  11470. impulse = JNumber3D.getScaleVector(N, actualImpulse);
  11471. appliedImpulse = Vector3DUtil.add(appliedImpulse, impulse); // keep track of the total impulse applied
  11472. body0.applyBodyWorldImpulse(impulse, ptInfo.r0);
  11473. body1.applyBodyWorldImpulse(JNumber3D.getScaleVector(impulse, -1), ptInfo.r1);
  11474. gotOne = true;
  11475. }
  11476. Vr0 = body0.getVelocityAux(ptInfo.r0);
  11477. Vr1 = body1.getVelocityAux(ptInfo.r1);
  11478. normalVel = Vector3DUtil.dotProduct(Vector3DUtil.subtract(Vr0, Vr1), N);
  11479. deltaVel = -normalVel;
  11480. if (ptInfo.minSeparationVel > 0)
  11481. deltaVel += ptInfo.minSeparationVel;
  11482. if (Math.abs(deltaVel) > this._minVelForProcessing){
  11483. normalImpulse = deltaVel / ptInfo.denominator;
  11484. origAccumulatedNormalImpulse = ptInfo.accumulatedNormalImpulseAux;
  11485. var accImpulseAux=ptInfo.accumulatedNormalImpulseAux + normalImpulse;
  11486. if (accImpulseAux < 0) accImpulseAux = 0;
  11487. ptInfo.accumulatedNormalImpulseAux = accImpulseAux;
  11488. actualImpulse = accImpulseAux - origAccumulatedNormalImpulse;
  11489. impulse = JNumber3D.getScaleVector(N, actualImpulse);
  11490. body0.applyBodyWorldImpulseAux(impulse, ptInfo.r0);
  11491. body1.applyBodyWorldImpulseAux(JNumber3D.getScaleVector(impulse, -1), ptInfo.r1);
  11492. gotOne = true;
  11493. }
  11494. if (ptInfo.accumulatedNormalImpulse > 0){
  11495. Vr0 = body0.getVelocity(ptInfo.r0);
  11496. Vr1 = body1.getVelocity(ptInfo.r1);
  11497. var tempV;
  11498. var VR = Vector3DUtil.subtract(Vr0, Vr1);
  11499. var tangent_vel = Vector3DUtil.subtract(VR, JNumber3D.getScaleVector(N, Vector3DUtil.dotProduct(VR, N)));
  11500. var tangent_speed = Vector3DUtil.get_length(tangent_vel);
  11501. if (tangent_speed > this._minVelForProcessing){
  11502. var T= JNumber3D.getScaleVector(JNumber3D.getDivideVector(tangent_vel, tangent_speed), -1);
  11503. var denominator = 0;
  11504. if (body0.get_movable()){
  11505. tempV = Vector3DUtil.crossProduct(ptInfo.r0, T);
  11506. JMatrix3D.multiplyVector(body0.get_worldInvInertia(), tempV);
  11507. denominator = body0.invMass + Vector3DUtil.dotProduct(T, Vector3DUtil.crossProduct(tempV, ptInfo.r0));
  11508. }
  11509. if (body1.get_movable()){
  11510. tempV = Vector3DUtil.crossProduct(ptInfo.r1, T);
  11511. JMatrix3D.multiplyVector(body1.get_worldInvInertia(), tempV);
  11512. denominator += (body1.invMass + Vector3DUtil.dotProduct(T, Vector3DUtil.crossProduct(tempV, ptInfo.r1)));
  11513. }
  11514. if (denominator > JNumber3D.NUM_TINY){
  11515. var impulseToReverse = tangent_speed / denominator;
  11516. var frictionImpulseVec = JNumber3D.getScaleVector(T, impulseToReverse);
  11517. var origAccumulatedFrictionImpulse = ptInfo.accumulatedFrictionImpulse.slice(0);
  11518. ptInfo.accumulatedFrictionImpulse = Vector3DUtil.add(ptInfo.accumulatedFrictionImpulse, frictionImpulseVec);
  11519. var AFIMag = Vector3DUtil.get_length(ptInfo.accumulatedFrictionImpulse);
  11520. var maxAllowedAFIMag = collision.mat.friction * ptInfo.accumulatedNormalImpulse;
  11521. if (AFIMag > JNumber3D.NUM_TINY && AFIMag > maxAllowedAFIMag)
  11522. ptInfo.accumulatedFrictionImpulse = JNumber3D.getScaleVector(ptInfo.accumulatedFrictionImpulse, maxAllowedAFIMag / AFIMag);
  11523. var actualFrictionImpulse = Vector3DUtil.subtract(ptInfo.accumulatedFrictionImpulse, origAccumulatedFrictionImpulse);
  11524. body0.applyBodyWorldImpulse(actualFrictionImpulse, ptInfo.r0);
  11525. body1.applyBodyWorldImpulse(JNumber3D.getScaleVector(actualFrictionImpulse, -1), ptInfo.r1);
  11526. }
  11527. }
  11528. }
  11529. }
  11530. if (gotOne)
  11531. {
  11532. body0.setConstraintsAndCollisionsUnsatisfied();
  11533. body1.setConstraintsAndCollisionsUnsatisfied();
  11534. // dispatch collision events
  11535. if(Vector3DUtil.get_length(appliedImpulse)>0){ //only fire event if the impulse size is greater then zero
  11536. body0.dispatchEvent(new JCollisionEvent(body1, appliedImpulse));
  11537. body1.dispatchEvent(new JCollisionEvent(body0, JNumber3D.getScaleVector(appliedImpulse, -1)));
  11538. }
  11539. }
  11540. return gotOne;
  11541. };
  11542. /**
  11543. * @function sortPositionX
  11544. *
  11545. * @param {RigidBody} body0
  11546. * @param {RigidBody} body1
  11547. * @type number
  11548. **/
  11549. PhysicsSystem.prototype.sortPositionX=function(body0, body1){
  11550. if (body0.get_currentState().position[0] < body1.get_currentState().position[0])
  11551. return -1;
  11552. else if (body0.get_currentState().position[0] > body1.get_currentState().position[0])
  11553. return 1;
  11554. else
  11555. return 0;
  11556. };
  11557. /**
  11558. * @function sortPositionY
  11559. *
  11560. * @param {RigidBody} body0
  11561. * @param {RigidBody} body1
  11562. * @type number
  11563. **/
  11564. PhysicsSystem.prototype.sortPositionY=function(body0, body1){
  11565. if (body0.get_currentState().position[1] < body1.get_currentState().position[1])
  11566. return -1;
  11567. else if (body0.get_currentState().position[1] > body1.get_currentState().position[1])
  11568. return 1;
  11569. else
  11570. return 0;
  11571. };
  11572. /**
  11573. * @function sortPositionZ
  11574. *
  11575. * @param {RigidBody} body0
  11576. * @param {RigidBody} body1
  11577. * @type number
  11578. **/
  11579. PhysicsSystem.prototype.sortPositionZ=function(body0, body1){
  11580. if (body0.get_currentState().position[2] < body1.get_currentState().position[2])
  11581. return -1;
  11582. else if (body0.get_currentState().position[2] > body1.get_currentState().position[2])
  11583. return 1;
  11584. else
  11585. return 0;
  11586. };
  11587. /**
  11588. * @function doShockStep the shock step helps with stacking
  11589. * @see JConfig.doShockStep
  11590. * @param {RigidBody} body0
  11591. * @param {RigidBody} body1
  11592. * @type void
  11593. **/
  11594. PhysicsSystem.prototype.doShockStep=function(dt){
  11595. if (Math.abs(this._gravity[0]) > Math.abs(this._gravity[1]) && Math.abs(this._gravity[0]) > Math.abs(this._gravity[2])){
  11596. this._bodies = this._bodies.sort(this.sortPositionX);
  11597. this._collisionSystem.collBody = this._collisionSystem.collBody.sort(this.sortPositionX);
  11598. }else if (Math.abs(this._gravity[1]) > Math.abs(this._gravity[2]) && Math.abs(this._gravity[1]) > Math.abs(this._gravity[0])){
  11599. this._bodies = this._bodies.sort(this.sortPositionY);
  11600. this._collisionSystem.collBody = this._collisionSystem.collBody.sort(this.sortPositionY);
  11601. }else if (Math.abs(this._gravity[2]) > Math.abs(this._gravity[0]) && Math.abs(this._gravity[2]) > Math.abs(this._gravity[1])){
  11602. this._bodies = this._bodies.sort(this.sortPositionZ);
  11603. this._collisionSystem.collBody = this._collisionSystem.collBody.sort(this.sortPositionZ);
  11604. }
  11605. var info;
  11606. var setImmovable;
  11607. var gotOne = true;
  11608. var body_collisions=[];
  11609. var body0;
  11610. var body1;
  11611. while (gotOne){
  11612. gotOne = false;
  11613. for(var i=0;i<this._bodies.length;i++){
  11614. var body=this._bodies[i];
  11615. if (body.get_movable() && body.get_doShockProcessing()){
  11616. if (body.collisions.length == 0 || !body.isActive){
  11617. body.internalSetImmovable();
  11618. }else{
  11619. setImmovable = false;
  11620. body_collisions = body.collisions;
  11621. for(var j=0;j<body_collisions.length;j++){
  11622. info=body_collisions[j];
  11623. body0 = info.objInfo.body0;
  11624. body1 = info.objInfo.body1;
  11625. if ((body0 == body && !body1.get_movable()) || (body1 == body && !body0.get_movable())){
  11626. this.preProcessCollisionFast(info, dt);
  11627. this.processCollision(info, dt);
  11628. setImmovable = true;
  11629. }
  11630. }
  11631. if (setImmovable){
  11632. body.internalSetImmovable();
  11633. gotOne = true;
  11634. }
  11635. }
  11636. }
  11637. }
  11638. }
  11639. for(var i=0;i<this._bodies.length;i++){
  11640. body=this._bodies[i];
  11641. body.internalRestoreImmovable();
  11642. body_collisions = body.collisions;
  11643. for(var j=0;j<body_collisions.length;j++){
  11644. info=body_collisions[j];
  11645. this.preProcessCollisionFn(info, dt);
  11646. this.processCollisionFn(info, dt);
  11647. }
  11648. }
  11649. };
  11650. /**
  11651. * @function updateContactCache
  11652. * @type void
  11653. **/
  11654. PhysicsSystem.prototype.updateContactCache=function(){
  11655. this._cachedContacts = [];
  11656. var ptInfo;
  11657. var fricImpulse;
  11658. var contact;
  11659. for(var i=0, cl=this._collisions.length; i<cl; i++){
  11660. var collInfo=this._collisions[i];
  11661. for (var j=0, pilen=collInfo.pointInfo.length; j<pilen; j++){
  11662. ptInfo = collInfo.pointInfo[j];
  11663. fricImpulse = (collInfo.objInfo.body0.id > collInfo.objInfo.body1.id) ? ptInfo.accumulatedFrictionImpulse : JNumber3D.getScaleVector(ptInfo.accumulatedFrictionImpulse, -1);
  11664. contact = new ContactData();
  11665. contact.pair = new BodyPair(collInfo.objInfo.body0, collInfo.objInfo.body1, ptInfo.r0, ptInfo.r1);
  11666. contact.impulse = new CachedImpulse(ptInfo.accumulatedNormalImpulse, ptInfo.accumulatedNormalImpulseAux, ptInfo.accumulatedFrictionImpulse);
  11667. this._cachedContacts.push(contact);
  11668. }
  11669. }
  11670. };
  11671. /**
  11672. * @function handleAllConstraints applies all constraints registered with the PhysicsSystem
  11673. * @param {number} dt a UNIX timestamp
  11674. * @param {number} iter
  11675. * @param {boolean} forceInelastic
  11676. * @type void
  11677. **/
  11678. PhysicsSystem.prototype.handleAllConstraints=function(dt, iter, forceInelastic){
  11679. var origNumCollisions = this._collisions.length;
  11680. var collInfo;
  11681. var _constraint;
  11682. for(var i=0, cl=this._constraints.length; i<cl; i++){
  11683. this._constraints[i].preApply(dt);
  11684. }
  11685. if (forceInelastic){
  11686. for(var i=0, cl=this._collisions.length; i<cl; i++){
  11687. this.preProcessContactFn(this._collisions[i], dt);
  11688. this._collisions[i].mat.set_restitution(0);
  11689. this._collisions[i].satisfied=false;
  11690. }
  11691. }else{
  11692. for(var i=0, cl=this._collisions.length; i<cl;i++){
  11693. this.preProcessCollisionFn(this._collisions[i], dt);
  11694. }
  11695. }
  11696. var flag;
  11697. var gotOne;
  11698. var len;
  11699. for (var step = 0; step < iter; step++){
  11700. gotOne = false;
  11701. for(var i=0, cl=this._collisions.length; i<cl;i++){
  11702. collInfo=this._collisions[i];
  11703. if (!collInfo.satisfied){
  11704. if (forceInelastic){
  11705. flag = this.processContactFn(collInfo, dt);
  11706. gotOne = gotOne || flag;
  11707. }else{
  11708. flag = this.processCollisionFn(collInfo, dt);
  11709. gotOne = gotOne || flag;
  11710. }
  11711. }
  11712. }
  11713. for(var i=0, cl=this._constraints.length; i<cl; i++){
  11714. var _constraint=this._constraints[i];
  11715. if (!_constraint.get_satisfied()){
  11716. flag = _constraint.apply(dt);
  11717. gotOne = gotOne || flag;
  11718. }
  11719. }
  11720. this.tryToActivateAllFrozenObjects();
  11721. if (forceInelastic){
  11722. len = this._collisions.length;
  11723. for (var j = origNumCollisions; j < len; j++){
  11724. this._collisions[j].mat.set_restitution(0);
  11725. this._collisions[j].satisfied=false;
  11726. this.preProcessContactFn(this._collisions[j], dt);
  11727. }
  11728. }else{
  11729. len = this._collisions.length;
  11730. for (j = origNumCollisions; j < len; j++){
  11731. this.preProcessCollisionFn(this._collisions[j], dt);
  11732. }
  11733. }
  11734. origNumCollisions = this._collisions.length;
  11735. if (!gotOne) break;
  11736. }
  11737. };
  11738. /**
  11739. * @function handleAllEffects applies all effects registered with the PhysicsSystem
  11740. * @type void
  11741. **/
  11742. PhysicsSystem.prototype.handleAllEffects=function(){
  11743. var effect;
  11744. var i=this._effects.length-1;
  11745. if (i < 0) return;
  11746. do {
  11747. effect=this._effects[i];
  11748. if (effect.enabled) effect.Apply();
  11749. } while(i--);
  11750. };
  11751. /**
  11752. * @function activateObject
  11753. * @param {RigidBody} body
  11754. * @type void
  11755. **/
  11756. PhysicsSystem.prototype.activateObject=function(body){
  11757. if (!body.get_movable() || body.isActive)
  11758. return;
  11759. body.setActive();
  11760. this._activeBodies.push(body);
  11761. var orig_num = this._collisions.length;
  11762. this._collisionSystem.detectCollisions(body, this._collisions);
  11763. var other_body;
  11764. var thisBody_normal;
  11765. for (var i=orig_num, len=this._collisions.length; i<len; i++){
  11766. other_body = this._collisions[i].objInfo.body0;
  11767. thisBody_normal = this._collisions[i].dirToBody;
  11768. if (other_body == body){
  11769. other_body = this._collisions[i].objInfo.body1;
  11770. thisBody_normal = JNumber3D.getScaleVector(this._collisions[i].dirToBody, -1);
  11771. }
  11772. if (!other_body.isActive && Vector3DUtil.dotProduct(other_body.get_force(), thisBody_normal) < -JNumber3D.NUM_TINY)
  11773. this.activateObject(other_body);
  11774. }
  11775. };
  11776. /**
  11777. * @function dampAllActiveBodies
  11778. * @type void
  11779. **/
  11780. PhysicsSystem.prototype.dampAllActiveBodies=function(){
  11781. for(var i=0, abl=this._activeBodies.length; i<abl; i++){
  11782. _activeBody=this._activeBodies[i];
  11783. _activeBody.dampForDeactivation();
  11784. }
  11785. };
  11786. /**
  11787. * @function tryToActivateAllFrozenObjects
  11788. * @type void
  11789. **/
  11790. PhysicsSystem.prototype.tryToActivateAllFrozenObjects=function(){
  11791. for(var i=0, bl=this._bodies.length; i<bl; i++){
  11792. var _body=this._bodies[i];
  11793. if (!_body.isActive){
  11794. if (_body.getShouldBeActive()){
  11795. this.activateObject(_body);
  11796. }else{
  11797. if (_body.getVelChanged()){
  11798. _body.setVelocity([0,0,0,0]);
  11799. _body.setAngVel([0,0,0,0]);
  11800. _body.clearVelChanged();
  11801. }
  11802. }
  11803. }
  11804. }
  11805. };
  11806. /**
  11807. * @function activateAllFrozenObjectsLeftHanging
  11808. * @type void
  11809. **/
  11810. PhysicsSystem.prototype.activateAllFrozenObjectsLeftHanging=function(){
  11811. var other_body;
  11812. for(var i=0, bl=this._bodies.length; i<bl; i++){
  11813. var _body=this._bodies[i];
  11814. if (_body.isActive){
  11815. _body.doMovementActivations();
  11816. if (_body.collisions.length > 0){
  11817. for (var j=0, bcl=_body.collisions.length; j<bcl; j++){
  11818. other_body = _body.collisions[j].objInfo.body0;
  11819. if (other_body == _body)
  11820. other_body = _body.collisions[j].objInfo.body1;
  11821. if (!other_body.isActive)
  11822. _body.addMovementActivation(_body.get_currentState().position, other_body);
  11823. }
  11824. }
  11825. }
  11826. }
  11827. };
  11828. /**
  11829. * @function updateAllVelocities
  11830. * @param {number} dt a UNIX timestamp
  11831. * @type void
  11832. **/
  11833. PhysicsSystem.prototype.updateAllVelocities=function(dt){
  11834. for(var i=0, abl=this._activeBodies.length; i<abl; i++){
  11835. _activeBody=this._activeBodies[i];
  11836. _activeBody.updateVelocity(dt);
  11837. }
  11838. };
  11839. /**
  11840. * @function updateAllPositions
  11841. * @param {number} dt a UNIX timestamp
  11842. * @type void
  11843. **/
  11844. PhysicsSystem.prototype.updateAllPositions=function(dt){
  11845. for(var i=0, abl=this._activeBodies.length; i<abl; i++){
  11846. _activeBody=this._activeBodies[i];
  11847. _activeBody.updatePositionWithAux(dt);
  11848. }
  11849. };
  11850. /**
  11851. * @function notifyAllPostPhysics
  11852. * @param {number} dt a UNIX timestamp
  11853. * @type void
  11854. **/
  11855. PhysicsSystem.prototype.notifyAllPostPhysics=function(dt){
  11856. for(var i=0, abl=this._bodies.length; i<abl; i++){
  11857. _body=this._bodies[i];
  11858. _body.postPhysics(dt);
  11859. }
  11860. };
  11861. /**
  11862. * @function updateAllObject3D
  11863. * @type void
  11864. **/
  11865. PhysicsSystem.prototype.updateAllObject3D=function(){
  11866. for(var i=0, abl=this._bodies.length; i<abl; i++){
  11867. _body=this._bodies[i];
  11868. _body.updateObject3D();
  11869. }
  11870. };
  11871. /**
  11872. * @function limitAllVelocities
  11873. * @type void
  11874. **/
  11875. PhysicsSystem.prototype.limitAllVelocities=function(){
  11876. for(var i=0, abl=this._activeBodies.length; i<abl; i++){
  11877. _activeBody=this._activeBodies[i];
  11878. _activeBody.limitVel();
  11879. _activeBody.limitAngVel();
  11880. }
  11881. };
  11882. /**
  11883. * @function tryToFreezeAllObjects
  11884. * @param {number} dt a UNIX timestamp
  11885. * @type void
  11886. **/
  11887. PhysicsSystem.prototype.tryToFreezeAllObjects=function(dt){
  11888. for(var i=0, abl=this._activeBodies.length; i<abl; i++){
  11889. _activeBody=this._activeBodies[i];
  11890. _activeBody.tryToFreeze(dt);
  11891. }
  11892. };
  11893. /**
  11894. * @function detectAllCollisions
  11895. * @param {number} dt a UNIX timestamp
  11896. * @type void
  11897. **/
  11898. PhysicsSystem.prototype.detectAllCollisions=function(dt){
  11899. for (var i=0, abl=this._activeBodies.length; i<abl; i++)
  11900. {
  11901. _activeBody=this._activeBodies[i];
  11902. _activeBody.storeState();
  11903. }
  11904. this.updateAllVelocities(dt);
  11905. this.updateAllPositions(dt);
  11906. for (var i=0, bl=this._bodies.length; i<bl; i++)
  11907. {
  11908. _body=this._bodies[i];
  11909. _body.collisions = [];
  11910. }
  11911. this._collisions = [];
  11912. this._collisionSystem.detectAllCollisions(this._activeBodies, this._collisions);
  11913. for (var i=0, abl=this._activeBodies.length; i<abl; i++)
  11914. {
  11915. _activeBody=this._activeBodies[i];
  11916. _activeBody.restoreState();
  11917. }
  11918. };
  11919. /**
  11920. * @function copyAllCurrentStatesToOld
  11921. * @type void
  11922. **/
  11923. PhysicsSystem.prototype.copyAllCurrentStatesToOld=function(){
  11924. for(var i=0, bl=this._bodies.length; i<bl; i++){
  11925. _body=this._bodies[i];
  11926. if (_body.isActive || _body.getVelChanged())
  11927. _body.copyCurrentStateToOld();
  11928. }
  11929. };
  11930. /**
  11931. * @function findAllActiveBodies
  11932. * @type void
  11933. **/
  11934. PhysicsSystem.prototype.findAllActiveBodies=function(){
  11935. this._activeBodies = [];
  11936. for(var i=0, bl=this._bodies.length; i<bl; i++){
  11937. var _body=this._bodies[i];
  11938. if (_body.isActive)
  11939. this._activeBodies.push(_body);
  11940. }
  11941. };
  11942. /**
  11943. * @function integrate integrates the system forwards by dt
  11944. * the caller is responsible for making sure that repeated calls to this use the same dt (if desired)
  11945. * @param {number} dt a UNIX timestamp
  11946. * @type void
  11947. **/
  11948. PhysicsSystem.prototype.integrate=function(dt){
  11949. this._doingIntegration = true;
  11950. this.findAllActiveBodies();
  11951. this.copyAllCurrentStatesToOld();
  11952. this.getAllExternalForces(dt);
  11953. this.handleAllEffects();
  11954. this.detectAllCollisions(dt);
  11955. this.handleAllConstraints(dt, JConfig.numCollisionIterations, false);
  11956. this.updateAllVelocities(dt);
  11957. this.handleAllConstraints(dt, JConfig.numContactIterations, true);
  11958. if (JConfig.doShockStep) {
  11959. this.doShockStep(dt);
  11960. }
  11961. this.dampAllActiveBodies();
  11962. this.tryToFreezeAllObjects(dt);
  11963. this.activateAllFrozenObjectsLeftHanging();
  11964. this.limitAllVelocities();
  11965. this.updateAllPositions(dt);
  11966. this.notifyAllPostPhysics(dt);
  11967. this.updateAllObject3D();
  11968. if (JConfig.solverType == "ACCUMULATED")
  11969. this.updateContactCache();
  11970. for(var i=0, bl=this._bodies.length; i<bl; i++){
  11971. _body=this._bodies[i];
  11972. _body.clearForces();
  11973. }
  11974. this._doingIntegration = false;
  11975. };
  11976. jigLib.PhysicsSystem=PhysicsSystem;
  11977. })(jigLib);(function(jigLib){
  11978. var Vector3DUtil=jigLib.Vector3DUtil;
  11979. /**
  11980. * @author Jim Sangwine
  11981. *
  11982. * This effect has a radius within which it will repel bodies depending on the defined force
  11983. * and their distance (the closer the object, the stronger the effect).
  11984. *
  11985. * This effect will only be applied during a single cycle of the PhysicsSystem, imparting a sudden impulse.
  11986. *
  11987. * This effect can either be placed at an arbitrary location in the scene, or it can be attached to a parent object.
  11988. *
  11989. **/
  11990. /**
  11991. * @author Jim Sangwine
  11992. *
  11993. * @name Explosion
  11994. * @class Explosion an explosive force effect
  11995. * This effect has a radius within which it will repel bodies depending on the defined force
  11996. * and their distance (the closer the object, the stronger the effect).
  11997. * This effect will only be applied during a single cycle of the PhysicsSystem, imparting a sudden impulse.
  11998. * This effect can either be placed at an arbitrary location in the scene, or it can be attached to a parent object.
  11999. *
  12000. * @extends JEffect
  12001. * @requires Vector3DUtil
  12002. * @property {array} location initial location of the effect expressed as a 3D vector
  12003. * @property {number} radius radius of effect - the distance at which the effect's influence will drop to zero
  12004. * @property {number} force the force of the effect at 0 distance (impulse will be force/distance)
  12005. * @property {RigidBody} parent optional - a RigidBody that the gravitational field will follow - excluded from the main effect force, but optionally receives relative force
  12006. * @property {boolean} relativity optional - toggle whether or not the parent receives a reactive impulse relative to that delivered to bodies falling within the effect radius
  12007. * @constructor
  12008. * @param {array} _location initial location of the effect expressed as a 3D vector
  12009. * @param {number} _radius radius of effect
  12010. * @param {number} _force the force of the effect at 0 distance
  12011. * @param {RigidBody} _parent optional parent body
  12012. * @param {boolean} _relativity optional toggle whether or not the parent receives a reactive impulse
  12013. **/
  12014. var Explosion=function(_location, _radius, _force, _parent, _relativity) {
  12015. this.Super();
  12016. this.location=_location;
  12017. this.radius=_radius;
  12018. this.force=_force;
  12019. if (_parent) this.parent=_parent;
  12020. if (_parent && _relativity) this.relativity=true;
  12021. // set to NOT fire instantly...
  12022. this.enabled = false;
  12023. };
  12024. jigLib.extend(Explosion,jigLib.JEffect);
  12025. Explosion.prototype.location = null;
  12026. Explosion.prototype.radius = null;
  12027. Explosion.prototype.force = null;
  12028. Explosion.prototype.parent = null;
  12029. Explosion.prototype.relativity = false;
  12030. /**
  12031. * @function explode triggers the effect (sets the effect to fire the next time Apply() is called)
  12032. *
  12033. * @type void
  12034. **/
  12035. Explosion.prototype.explode = function() {
  12036. this.enabled = true;
  12037. };
  12038. /**
  12039. * @function Apply applies the effect to the relevant bodies
  12040. * @see JEffect.Apply
  12041. * @type void
  12042. **/
  12043. Explosion.prototype.Apply = function() {
  12044. this.enabled = false;
  12045. var system=jigLib.PhysicsSystem.getInstance();
  12046. var bodies=system.get_bodies();
  12047. var i=bodies.length;
  12048. var curBody, distance, force, forceV;
  12049. var forceVP=[0,0,0,0];
  12050. if (this.parent)
  12051. this.location = this.parent.get_position();
  12052. this._affectedBodies=[];
  12053. while(i--) {
  12054. curBody=bodies[i];
  12055. if (this.parent && curBody == this.parent) continue;
  12056. // handle normal bodies first
  12057. if (curBody._type!="PLANE")
  12058. {
  12059. distance=Vector3DUtil.distance(curBody.get_position(), this.location);
  12060. if (distance < this.radius)
  12061. {
  12062. forceV=Vector3DUtil.subtract(curBody.get_position(), this.location);
  12063. force=(1-(distance / this.radius)) * this.force;
  12064. Vector3DUtil.scaleBy(forceV, force);
  12065. if(this.relativity) forceVP = Vector3DUtil.add(forceV,forceVP);
  12066. if(curBody.get_movable())
  12067. {
  12068. system.activateObject(curBody);
  12069. curBody.addWorldForce(forceV, this.location);
  12070. }
  12071. }
  12072. }
  12073. else if (this.relativity)
  12074. {
  12075. // allow ground and wall type immovable bodies to impart relative force to the exploding body
  12076. distance=curBody.pointPlaneDistance(this.location);
  12077. if (distance<this.radius)
  12078. {
  12079. forceV=Vector3DUtil.negate(curBody.get_normal().slice(0));
  12080. force=(1-(distance / this.radius)) * (this.force*2);
  12081. Vector3DUtil.scaleBy(forceV, force);
  12082. forceVP = Vector3DUtil.add(forceV,forceVP);
  12083. }
  12084. }
  12085. }
  12086. if(this.relativity) {
  12087. Vector3DUtil.limitSum(forceVP,this.force);
  12088. Vector3DUtil.negate(forceVP);
  12089. system.activateObject(this.parent);
  12090. this.parent.applyWorldImpulse(forceVP, this.location);
  12091. }
  12092. };
  12093. jigLib.Explosion=Explosion;
  12094. })(jigLib);/*
  12095. Copyright (c) 2007 Danny Chapman
  12096. http://www.rowlhouse.co.uk
  12097. This software is provided 'as-is', without any express or implied
  12098. warranty. In no event will the authors be held liable for any damages
  12099. arising from the use of this software.
  12100. Permission is granted to anyone to use this software for any purpose,
  12101. including commercial applications, and to alter it and redistribute it
  12102. freely, subject to the following restrictions:
  12103. 1. The origin of this software must not be misrepresented; you must not
  12104. claim that you wrote the original software. If you use this software
  12105. in a product, an acknowledgment in the product documentation would be
  12106. appreciated but is not required.
  12107. 2. Altered source versions must be plainly marked as such, and must not be
  12108. misrepresented as being the original software.
  12109. 3. This notice may not be removed or altered from any source
  12110. distribution.
  12111. */
  12112. (function(jigLib){
  12113. var JBox=jigLib.JBox;
  12114. /**
  12115. * @author Muzer(muzerly@gmail.com)
  12116. *
  12117. * @name JChassis
  12118. * @class JChassis represents vehicle chassis
  12119. * @extends JBox
  12120. * @property {JCar} _car the vehicle this chassis belongs to
  12121. * @constructor
  12122. * @param {JCar} car the vehicle this chassis belongs to
  12123. * @param {ISkin3D} skin the mesh
  12124. * @param {number} width the required chassis width
  12125. * @param {number} depth the required chassis depth
  12126. * @param {number} height the required chassis height
  12127. **/
  12128. var JChassis=function(car, skin, width, depth, height){
  12129. if(width==null) width=40;
  12130. if(depth==null) depth=70;
  12131. if(height==null) height=30;
  12132. this.Super(skin, width, depth, height);
  12133. this._car = car;
  12134. };
  12135. jigLib.extend(JChassis, jigLib.JBox);
  12136. JChassis.prototype._car=null;
  12137. /**
  12138. * @function addExternalForces applies wheel forces to the vehicle
  12139. * @param {number} dt a UNIX timestamp
  12140. * @type void
  12141. **/
  12142. JChassis.prototype.addExternalForces=function(dt){
  12143. this.clearForces();
  12144. this.addGravity();
  12145. this._car.addExternalForces(dt);
  12146. };
  12147. /**
  12148. * @function postPhysics runs after the PhysicsSystem has been applied
  12149. * @param {number} dt a UNIX timestamp
  12150. * @type void
  12151. **/
  12152. JChassis.prototype.postPhysics=function(dt){
  12153. this._car.postPhysics(dt);
  12154. };
  12155. jigLib.JChassis=JChassis;
  12156. })(jigLib);/*
  12157. Copyright (c) 2007 Danny Chapman
  12158. http://www.rowlhouse.co.uk
  12159. This software is provided 'as-is', without any express or implied
  12160. warranty. In no event will the authors be held liable for any damages
  12161. arising from the use of this software.
  12162. Permission is granted to anyone to use this software for any purpose,
  12163. including commercial applications, and to alter it and redistribute it
  12164. freely, subject to the following restrictions:
  12165. 1. The origin of this software must not be misrepresented; you must not
  12166. claim that you wrote the original software. If you use this software
  12167. in a product, an acknowledgment in the product documentation would be
  12168. appreciated but is not required.
  12169. 2. Altered source versions must be plainly marked as such, and must not be
  12170. misrepresented as being the original software.
  12171. 3. This notice may not be removed or altered from any source
  12172. distribution.
  12173. */
  12174. (function(jigLib){
  12175. var Vector3DUtil=jigLib.Vector3DUtil;
  12176. var JMatrix3D=jigLib.JMatrix3D;
  12177. var JNumber3D=jigLib.JNumber3D;
  12178. var JSegment=jigLib.JSegment;
  12179. var JConfig=jigLib.JConfig;
  12180. var PhysicsSystem=jigLib.PhysicsSystem;
  12181. // get local refs to Math methods to improve performance
  12182. var mr=Math, mrPI=mr.PI, mrMin=mr.min, mrMax=mr.max, mrCos=mr.cos, mrAbs=mr.abs, mrSqrt=mr.sqrt;
  12183. /**
  12184. * @author Muzer(muzerly@gmail.com)
  12185. *
  12186. * @name JWheel
  12187. * @class JWheel represents a wheel
  12188. * @constant {number} noslipVel
  12189. * @constant {number} slipVel
  12190. * @constant {number} slipFactor
  12191. * @constant {number} smallVel
  12192. * @property {string} name a unique name by which to identify the wheel (e.g. FrontRight, RearLeft etc.)
  12193. * @property {JCar} _car the car this wheel belongs to
  12194. * @property {array} _pos position of the wheel relative to the car's center as a 3D vector
  12195. * @property {array} _axisUp the inverse of the gravity axis as a 3D vector
  12196. * @property {number} _spring amount of suspension spring
  12197. * @property {number} _travel vertical suspension travel
  12198. * @property {number} _inertia the wheel inertia
  12199. * @property {number} _radius the wheel radius
  12200. * @property {number} _sideFriction side friction
  12201. * @property {number} _fwdFriction forward friction
  12202. * @property {number} _damping suspension damping
  12203. * @property {number} _numRays
  12204. * @property {number} _angVel
  12205. * @property {number} _steerAngle the steering angle
  12206. * @property {number} _torque amount of torque
  12207. * @property {number} _driveTorque
  12208. * @property {number} _axisAngle
  12209. * @property {number} _displacement current suspension travel
  12210. * @property {number} _upSpeed
  12211. * @property {number} _rotDamping
  12212. * @property {number} _normalForce
  12213. * @property {boolean} _locked whether the wheel is locked
  12214. * @property {number} _lastDisplacement previous suspension travel
  12215. * @property {boolean} _lastOnFloor whether the wheel was previously on the floor
  12216. * @property {number} _angVelForGrip
  12217. * @property {array} worldPos a 3D vector
  12218. * @property {array} worldAxis a 3D vector
  12219. * @property {array} wheelFwd a 3D vector
  12220. * @property {array} wheelUp a 3D vector
  12221. * @property {array} wheelLeft a 3D vector
  12222. * @property {array} wheelRayEnd a 3D vector
  12223. * @property {JSegment} wheelRay
  12224. * @property {array} groundUp a 3D vector
  12225. * @property {array} groundLeft a 3D vector
  12226. * @property {array} groundFwd a 3D vector
  12227. * @property {array} wheelPointVel a 3D vector
  12228. * @property {array} rimVel a 3D vector
  12229. * @property {array} worldVel a 3D vector
  12230. * @property {array} wheelCentreVel a 3D vector
  12231. * @property {CollisionSystem} _collSystem the collision system
  12232. * @constructor
  12233. * @param {JCar} car the vehicle this wheel belongs to
  12234. **/
  12235. var JWheel=function(car){
  12236. this._car = car;
  12237. };
  12238. JWheel.prototype.name = null;
  12239. JWheel.prototype.noslipVel = 0.2;
  12240. JWheel.prototype.slipVel = 0.4;
  12241. JWheel.prototype.slipFactor = 0.7;
  12242. JWheel.prototype.smallVel = 3;
  12243. JWheel.prototype._car=null;
  12244. JWheel.prototype._pos=null;
  12245. JWheel.prototype._axisUp=null;
  12246. JWheel.prototype._spring=null;
  12247. JWheel.prototype._travel=null;
  12248. JWheel.prototype._inertia=null;
  12249. JWheel.prototype._radius=null;
  12250. JWheel.prototype._sideFriction=null;
  12251. JWheel.prototype._fwdFriction=null;
  12252. JWheel.prototype._damping=null;
  12253. JWheel.prototype._numRays=null;
  12254. JWheel.prototype._angVel=null;
  12255. JWheel.prototype._steerAngle=null;
  12256. JWheel.prototype._torque=null;
  12257. JWheel.prototype._driveTorque=null;
  12258. JWheel.prototype._axisAngle=null;
  12259. JWheel.prototype._displacement=null;
  12260. JWheel.prototype._upSpeed=null;
  12261. JWheel.prototype._rotDamping=null;
  12262. JWheel.prototype._normalForce=null;
  12263. JWheel.prototype._locked=null;
  12264. JWheel.prototype._lastDisplacement=null;
  12265. JWheel.prototype._lastOnFloor=null;
  12266. JWheel.prototype._angVelForGrip=null;
  12267. JWheel.prototype.worldPos=null;
  12268. JWheel.prototype.worldAxis=null;
  12269. JWheel.prototype.wheelFwd=null;
  12270. JWheel.prototype.wheelUp=null;
  12271. JWheel.prototype.wheelLeft=null;
  12272. JWheel.prototype.wheelRayEnd=null;
  12273. JWheel.prototype.wheelRay=null;
  12274. JWheel.prototype.groundUp=null;
  12275. JWheel.prototype.groundLeft=null;
  12276. JWheel.prototype.groundFwd=null;
  12277. JWheel.prototype.wheelPointVel=null;
  12278. JWheel.prototype.rimVel=null;
  12279. JWheel.prototype.worldVel=null;
  12280. JWheel.prototype.wheelCentreVel=null;
  12281. JWheel.prototype._collSystem=null;
  12282. /**
  12283. * @function setup setup the wheel
  12284. * @param {array} pos position relative to car, in car's space
  12285. * @param {array} axisUp in car's space
  12286. * @param {number} spring force per suspension offset
  12287. * @param {number} travel suspension travel upwards
  12288. * @param {number} inertia inertia about the axle
  12289. * @param {number} radius wheel radius
  12290. * @param {number} sideFriction side friction
  12291. * @param {number} fwdFriction forward friction
  12292. * @param {number} damping suspension damping
  12293. * @param {number} numRays
  12294. * @param {number} drive
  12295. * @param {number} normalForce
  12296. * @type void
  12297. **/
  12298. JWheel.prototype.setup=function(pos, axisUp, spring, travel, inertia, radius, sideFriction, fwdFriction, damping, numRays, drive, normalForce){
  12299. if(spring==null) spring=0;
  12300. if(travel==null) travel=0;
  12301. if(inertia==null) inertia=0;
  12302. if(radius==null) radius=0;
  12303. if(sideFriction==null) sideFriction=0;
  12304. if(fwdFriction==null) fwdFriction=0;
  12305. if(damping==null) damping=0;
  12306. if(numRays==null) numRays=0;
  12307. if(drive==null) drive=0;
  12308. if(normalForce==null) normalForce=0;
  12309. this._pos = pos;
  12310. this._axisUp = axisUp;
  12311. this._spring = spring;
  12312. this._travel = travel;
  12313. this._inertia = inertia;
  12314. this._radius = radius;
  12315. this._sideFriction = sideFriction;
  12316. this._fwdFriction = fwdFriction;
  12317. this._damping = damping;
  12318. this._numRays = numRays;
  12319. this._drive = drive;
  12320. this._normalForce = normalForce;
  12321. this._torque = 0;
  12322. this.reset();
  12323. };
  12324. /**
  12325. * @function addTorque add torque to the wheel
  12326. * @param {number} torque the amount of torque to add
  12327. * @type void
  12328. **/
  12329. JWheel.prototype.addTorque=function(torque){
  12330. this._driveTorque += torque;
  12331. };
  12332. /**
  12333. * @function setLock lock/unlock the wheel
  12334. * @param {boolean} lock
  12335. * @type void
  12336. **/
  12337. JWheel.prototype.setLock=function(lock){
  12338. this._locked = lock;
  12339. };
  12340. /**
  12341. * @function setSteerAngle set the target steering angle
  12342. * @param {number} steer
  12343. * @type void
  12344. **/
  12345. JWheel.prototype.setSteerAngle=function(steer){
  12346. this._steerAngle = steer;
  12347. };
  12348. /**
  12349. * @function setSteerAngle get the steering angle in degrees
  12350. * @type number
  12351. **/
  12352. JWheel.prototype.getSteerAngle=function(){
  12353. return this._steerAngle;
  12354. };
  12355. /**
  12356. * @function getPos get the base wheel position as a 3D vector
  12357. * @type array
  12358. **/
  12359. JWheel.prototype.getPos=function(){
  12360. return this._pos;
  12361. };
  12362. /**
  12363. * @function getLocalAxisUp get the suspension axis in the car's frame as a 3D vector
  12364. * @type array
  12365. **/
  12366. JWheel.prototype.getLocalAxisUp=function(){
  12367. return this._axisUp;
  12368. };
  12369. /**
  12370. * @function getActualPos get the real position of the wheel taking into account current suspension travel
  12371. * @type array
  12372. **/
  12373. JWheel.prototype.getActualPos=function(){
  12374. return Vector3DUtil.add(this._pos, JNumber3D.getScaleVector(this._axisUp, this._displacement));
  12375. };
  12376. /**
  12377. * @function getRadius get the wheel radius
  12378. * @type number
  12379. **/
  12380. JWheel.prototype.getRadius=function(){
  12381. return this._radius;
  12382. };
  12383. /**
  12384. * @function getDisplacement get the current suspension travel
  12385. * @type number
  12386. **/
  12387. JWheel.prototype.getDisplacement=function(){
  12388. return this._displacement;
  12389. };
  12390. /**
  12391. * @function getAxisAngle
  12392. * @type array
  12393. **/
  12394. JWheel.prototype.getAxisAngle=function(){
  12395. return this._axisAngle;
  12396. };
  12397. /**
  12398. * @function getRollAngle get the current rotation around the axle axis
  12399. * @type number
  12400. **/
  12401. JWheel.prototype.getRollAngle=function(){
  12402. return 0.1 * this._angVel * 180 / mrPI;
  12403. };
  12404. /**
  12405. * @function setRotationDamping set the rotation damping
  12406. * @param {number} vel
  12407. * @type void
  12408. **/
  12409. JWheel.prototype.setRotationDamping=function(vel){
  12410. this._rotDamping = vel;
  12411. };
  12412. /**
  12413. * @function getRotationDamping get the rotation damping value
  12414. * @type number
  12415. **/
  12416. JWheel.prototype.getRotationDamping=function(){
  12417. return this._rotDamping;
  12418. };
  12419. /**
  12420. * @function getOnFloor tests whether the wheel is on the ground or not
  12421. * @returns true if on the ground, else false
  12422. * @type boolean
  12423. **/
  12424. JWheel.prototype.getOnFloor=function(){
  12425. return this._lastOnFloor;
  12426. };
  12427. /**
  12428. * @function addForcesToCar adds the forces from this wheel to the parent vehicle.
  12429. * @returns true if the wheel is on the ground, else false
  12430. * @type boolean
  12431. **/
  12432. JWheel.prototype.addForcesToCar=function(dt){
  12433. var force = [0,0,0,0];
  12434. this._lastDisplacement = this._displacement;
  12435. this._displacement = 0;
  12436. var carBody = this._car._chassis;
  12437. worldPos = this._pos.slice(0);
  12438. JMatrix3D.multiplyVector(carBody.get_currentState().get_orientation(), worldPos);
  12439. worldPos = Vector3DUtil.add(carBody.get_currentState().position, worldPos);
  12440. worldAxis = this._axisUp.slice(0);
  12441. JMatrix3D.multiplyVector(carBody.get_currentState().get_orientation(), worldAxis);
  12442. wheelFwd = carBody.get_currentState().getOrientationCols()[2].slice(0);
  12443. JMatrix3D.multiplyVector(JMatrix3D.getRotationMatrix(worldAxis[0], worldAxis[1], worldAxis[2], this._steerAngle/180*2*Math.PI), wheelFwd);
  12444. wheelUp = worldAxis;
  12445. wheelLeft = Vector3DUtil.crossProduct(wheelUp, wheelFwd);
  12446. Vector3DUtil.normalize(wheelLeft);
  12447. var rayLen = 2 * this._radius + this._travel;
  12448. wheelRayEnd = Vector3DUtil.subtract(worldPos, JNumber3D.getScaleVector(worldAxis, this._radius));
  12449. wheelRay = new JSegment(Vector3DUtil.add(wheelRayEnd, JNumber3D.getScaleVector(worldAxis, rayLen)), JNumber3D.getScaleVector(worldAxis, -rayLen));
  12450. if (this._collSystem == null)
  12451. this._collSystem = PhysicsSystem.getInstance().getCollisionSystem();
  12452. var maxNumRays = 10;
  12453. var numRays = mrMin(this._numRays, maxNumRays);
  12454. var objArr = [];
  12455. var segments = [];
  12456. var deltaFwd = (2 * this._radius) / (numRays +1);
  12457. var deltaFwdStart = deltaFwd;
  12458. this._lastOnFloor = false;
  12459. var distFwd;
  12460. var yOffset;
  12461. var bestIRay = 0;
  12462. var iRay = 0;
  12463. var segment = null;
  12464. for (iRay = 0; iRay < numRays; iRay++){
  12465. objArr[iRay] = {};
  12466. distFwd = (deltaFwdStart + iRay * deltaFwd) - this._radius;
  12467. yOffset = this._radius * (1 - mrCos(90 * (distFwd / this._radius) * mrPI / 180));
  12468. segment = wheelRay.clone();
  12469. segment.origin = Vector3DUtil.add(segment.origin, Vector3DUtil.add(JNumber3D.getScaleVector(wheelFwd, distFwd), JNumber3D.getScaleVector(wheelUp, yOffset)));
  12470. if (this._collSystem.segmentIntersect(objArr[iRay], segment, carBody)) {
  12471. this._lastOnFloor = true;
  12472. if (objArr[iRay].frac < objArr[bestIRay].frac){
  12473. bestIRay = iRay;
  12474. }
  12475. }
  12476. segments[iRay] = segment;
  12477. }
  12478. if (!this._lastOnFloor) return false;
  12479. var frac= objArr[bestIRay].frac;
  12480. var groundPos = objArr[bestIRay].position;
  12481. var otherBody = objArr[bestIRay].rigidBody;
  12482. var groundNormal = worldAxis.slice(0);
  12483. if (numRays > 1){
  12484. for (iRay = 0; iRay < numRays; iRay++){
  12485. var rayFracOut=objArr[iRay].fracOut;
  12486. if (rayFracOut <= 1)
  12487. groundNormal = Vector3DUtil.add(groundNormal, JNumber3D.getScaleVector(Vector3DUtil.subtract(worldPos, segments[iRay].getEnd()), 1 - rayFracOut));
  12488. }
  12489. Vector3DUtil.normalize(groundNormal);
  12490. }else groundNormal = objArr[bestIRay].normalOut;
  12491. wheelFwd=Vector3DUtil.crossProduct(wheelLeft,groundNormal);
  12492. this._displacement = rayLen * (1 - frac);
  12493. if (this._displacement < 0) this._displacement = 0;
  12494. var mass = carBody.get_mass();
  12495. var mass4 = mass/4;
  12496. var otherFriction=otherBody.get_friction();
  12497. var wheelCenterVel=carBody.getVelocity(this._pos);
  12498. //hit floor hard
  12499. var origDisplacement=this._displacement;
  12500. if (this._displacement > this._travel){
  12501. this._displacement=this._travel;
  12502. var cv=Vector3DUtil.dotProduct(wheelCenterVel,groundNormal)/dt*mass4;
  12503. cv=cv*2*otherBody.get_restitution()/10;
  12504. extraForce = JNumber3D.getScaleVector(groundNormal, -cv);
  12505. force = Vector3DUtil.add(force, extraForce);
  12506. }
  12507. //suspension spring force
  12508. extraForce = JNumber3D.getScaleVector(this._axisUp, this._spring*this._displacement+this._upSpeed*this._damping);
  12509. force = Vector3DUtil.add(force, extraForce);
  12510. groundUp = groundNormal;
  12511. groundLeft = Vector3DUtil.crossProduct(groundNormal, wheelFwd);
  12512. Vector3DUtil.normalize(groundLeft);
  12513. groundFwd = Vector3DUtil.crossProduct(groundLeft, groundUp);
  12514. var rimVel = JNumber3D.getScaleVector(Vector3DUtil.crossProduct(groundLeft, Vector3DUtil.subtract(groundPos, worldPos)), -this._angVel);
  12515. var centerVel = JNumber3D.getScaleVector(groundFwd, Vector3DUtil.dotProduct(wheelCenterVel,groundFwd));
  12516. var friction=this._fwdFriction*otherFriction;
  12517. var extraForce = JNumber3D.getScaleVector(Vector3DUtil.subtract(rimVel,centerVel), mass4/dt/this._radius*friction);
  12518. var forceSize=Vector3DUtil.get_length(extraForce);
  12519. if(forceSize>this._normalForce*friction) extraForce = JNumber3D.getScaleVector(extraForce,this._normalForce*friction/forceSize);
  12520. force = Vector3DUtil.add(force, extraForce);
  12521. this._torque-=Vector3DUtil.dotProduct(Vector3DUtil.subtract(rimVel,centerVel),groundFwd)/this._radius*mass4/dt;
  12522. this._angVelForGrip = Vector3DUtil.dotProduct(wheelCenterVel, groundFwd) / this._radius;
  12523. //sideways friction
  12524. var sideVel = Vector3DUtil.dotProduct(wheelCenterVel,groundLeft);
  12525. var friction=this._sideFriction*otherFriction;
  12526. var leftVel = JNumber3D.getScaleVector(groundLeft, -sideVel*friction);
  12527. var extraForce = JNumber3D.getScaleVector(leftVel, mass4/dt/this._radius);
  12528. var forceSize=Vector3DUtil.get_length(extraForce);
  12529. if(forceSize>this._normalForce*friction) extraForce = JNumber3D.getScaleVector(extraForce,this._normalForce*friction/forceSize);
  12530. force = Vector3DUtil.add(force, extraForce);
  12531. carBody.addWorldForce(force, groundPos);
  12532. if (otherBody.get_movable()){
  12533. var maxOtherBodyAcc = 500;
  12534. var maxOtherBodyForce = maxOtherBodyAcc * otherBody.get_mass();
  12535. if (Vector3DUtil.get_lengthSquared(force) > (maxOtherBodyForce * maxOtherBodyForce))
  12536. force = JNumber3D.getScaleVector(force, maxOtherBodyForce / Vector3DUtil.get_length(force));
  12537. otherBody.addWorldForce(JNumber3D.getScaleVector(force, -1), groundPos);
  12538. }
  12539. return true;
  12540. };
  12541. /**
  12542. * @function update updates the rotational state etc
  12543. * @type void
  12544. **/
  12545. JWheel.prototype.update=function(dt){
  12546. if (dt <= 0) return;
  12547. var origAngVel = this._angVel;
  12548. this._upSpeed = (this._displacement - this._lastDisplacement) / mrMax(dt, JNumber3D.NUM_TINY);
  12549. if (this._locked){
  12550. this._angVel = 0;
  12551. this._torque = 0;
  12552. }else{
  12553. this._angVel += (this._torque * dt / this._inertia);
  12554. this._torque = 0;
  12555. if (((origAngVel > this._angVelForGrip) && (this._angVel < this._angVelForGrip)) || ((origAngVel < this._angVelForGrip) && (this._angVel > this._angVelForGrip)))
  12556. this._angVel = this._angVelForGrip;
  12557. this._angVel += this._driveTorque * dt / this._inertia * this._drive;
  12558. this._driveTorque = 0;
  12559. if (this._angVel < -100) this._angVel = -100;
  12560. else if (this._angVel > 100) this._angVel = 100;
  12561. this._angVel *= this._rotDamping;
  12562. this._axisAngle += (this._angVel * dt * 180 / mrPI);
  12563. }
  12564. };
  12565. /**
  12566. * @function reset resets everything
  12567. * @type void
  12568. **/
  12569. JWheel.prototype.reset=function(){
  12570. this._angVel = 0;
  12571. this._steerAngle = 0;
  12572. this._torque = 0;
  12573. this._driveTorque = 0;
  12574. this._axisAngle = 0;
  12575. this._displacement = 0;
  12576. this._upSpeed = 0;
  12577. this._locked = false;
  12578. this._lastDisplacement = 0;
  12579. this._lastOnFloor = false;
  12580. this._angVelForGrip = 0;
  12581. this._rotDamping = 0.99;
  12582. };
  12583. jigLib.JWheel=JWheel;
  12584. })(jigLib);/*
  12585. Copyright (c) 2007 Danny Chapman
  12586. http://www.rowlhouse.co.uk
  12587. This software is provided 'as-is', without any express or implied
  12588. warranty. In no event will the authors be held liable for any damages
  12589. arising from the use of this software.
  12590. Permission is granted to anyone to use this software for any purpose,
  12591. including commercial applications, and to alter it and redistribute it
  12592. freely, subject to the following restrictions:
  12593. 1. The origin of this software must not be misrepresented; you must not
  12594. claim that you wrote the original software. If you use this software
  12595. in a product, an acknowledgment in the product documentation would be
  12596. appreciated but is not required.
  12597. 2. Altered source versions must be plainly marked as such, and must not be
  12598. misrepresented as being the original software.
  12599. 3. This notice may not be removed or altered from any source
  12600. distribution.
  12601. */
  12602. (function(jigLib){
  12603. var Vector3DUtil=jigLib.Vector3DUtil;
  12604. var JNumber3D=jigLib.JNumber3D;
  12605. var JChassis=jigLib.JChassis;
  12606. var JWheel=jigLib.JWheel;
  12607. var PhysicsSystem=jigLib.PhysicsSystem;
  12608. // get local refs to Math methods to improve performance
  12609. var mr=Math, mrAbs=mr.abs, mrSqrt=mr.sqrt;
  12610. /**
  12611. * @author Muzer(muzerly@gmail.com)
  12612. *
  12613. * @name JCar
  12614. * @class JCar represents a wheeled vehicle
  12615. * @requires Vector3DUtil
  12616. * @requires JNumber3D
  12617. * @requires JChassis
  12618. * @requires JWheel
  12619. * @requires PhysicsSystem
  12620. * @property {number} _maxSteerAngle the maximum steering angle
  12621. * @property {number} _steerRate the rate of steering angle change
  12622. * @property {number} _driveTorque the maximum torque of a wheel
  12623. * @property {number} _destSteering the target steering angle
  12624. * @property {number} _destAccelerate the target acceleration
  12625. * @property {number} _steering the current steering angle
  12626. * @property {number} _accelerate the current acceleration
  12627. * @property {number} _HBrake whether the handbrake is on (1) or off (0)
  12628. * @property {JChassis} _chassis the vehicle chassis
  12629. * @property {array} _wheels the wheels (a collection of Wheel objects)
  12630. * @property {array} _steerWheels the wheels used for steering (a collection of Wheel objects)
  12631. * @constructor
  12632. * @param {ISkin3D} skin
  12633. **/
  12634. var JCar=function(skin){
  12635. this._chassis = new JChassis(this, skin);
  12636. this._wheels = [];
  12637. this._steerWheels = [];
  12638. this._destSteering = this._destAccelerate = this._steering = this._accelerate = this._HBrake = 0;
  12639. this.setCar();
  12640. };
  12641. JCar.prototype._maxSteerAngle=null;
  12642. JCar.prototype._steerRate=null;
  12643. JCar.prototype._driveTorque=null;
  12644. JCar.prototype._destSteering=null;
  12645. JCar.prototype._destAccelerate=null;
  12646. JCar.prototype._steering=null;
  12647. JCar.prototype._accelerate=null;
  12648. JCar.prototype._HBrake=null;
  12649. JCar.prototype._chassis=null;
  12650. JCar.prototype._wheels=null;
  12651. JCar.prototype._steerWheels=null;
  12652. /**
  12653. * @function setCar sets up the vehicle
  12654. * @param {number} maxSteerAngle the maximum steering angle
  12655. * @param {number} steerRate the rate of steering angle change
  12656. * @param {number} driveTorque the maximum torque of a wheel
  12657. * @type void
  12658. **/
  12659. JCar.prototype.setCar=function(maxSteerAngle, steerRate, driveTorque){
  12660. if(maxSteerAngle==null) maxSteerAngle=45;
  12661. if(steerRate==null) steerRate=4;
  12662. if(driveTorque==null) driveTorque=500;
  12663. this._maxSteerAngle = maxSteerAngle;
  12664. this._steerRate = steerRate;
  12665. this._driveTorque = driveTorque;
  12666. };
  12667. /**
  12668. * @function setupWheel add a wheel to the vehicle
  12669. * @param {string} _name a unique name by which to identify the wheel (e.g. FrontRight, RearLeft etc.)
  12670. * @param {array} pos position of the wheel relative to the car's center
  12671. * @param {number} wheelSideFriction side friction
  12672. * @param {number} wheelFwdFriction forward friction
  12673. * @param {number} wheelTravel vertical suspension travel
  12674. * @param {number} wheelRadius wheel radius
  12675. * @param {number} wheelRestingFrac elasticity coefficient
  12676. * @param {number} wheelDampingFrac suspension damping
  12677. * @param {number} wheelNumRays
  12678. * @param {number} drive
  12679. * @type void
  12680. **/
  12681. JCar.prototype.setupWheel=function(_name, pos, wheelSideFriction, wheelFwdFriction, wheelTravel, wheelRadius, wheelRestingFrac, wheelDampingFrac, wheelNumRays, drive){
  12682. if(wheelSideFriction==null) wheelSideFriction=2;
  12683. if(wheelFwdFriction==null) wheelFwdFriction=2;
  12684. if(wheelTravel==null) wheelTravel=3;
  12685. if(wheelRadius==null) wheelRadius=10;
  12686. if(wheelRestingFrac==null) wheelRestingFrac=0.5;
  12687. if(wheelDampingFrac==null) wheelDampingFrac=0.5;
  12688. if(wheelNumRays==null) wheelNumRays=1;
  12689. if(drive==null) drive=1;
  12690. var gravity = PhysicsSystem.getInstance().get_gravity().slice(0);
  12691. var mass = this._chassis.get_mass();
  12692. var mass4 = 0.25 * mass;
  12693. var gravityLen = Vector3DUtil.get_length(gravity);
  12694. Vector3DUtil.normalize(gravity);
  12695. var axis = JNumber3D.getScaleVector(gravity,-1);
  12696. var spring = mass4 * gravityLen / (wheelRestingFrac * wheelTravel);
  12697. var inertia = 0.015 * wheelRadius * wheelRadius * mass;
  12698. var damping = wheelDampingFrac/2;
  12699. var normalForce = gravityLen*mass4;
  12700. //var damping = 2 * mrSqrt(spring * mass);
  12701. //damping *= (0.25 * wheelDampingFrac);
  12702. //damping /= this._steerRate;
  12703. //damping *= wheelDampingFrac;
  12704. var wheel = new JWheel(this);
  12705. wheel.name = _name;
  12706. wheel.setup(pos, axis, spring, wheelTravel, inertia, wheelRadius, wheelSideFriction, wheelFwdFriction, damping, wheelNumRays, drive, normalForce);
  12707. this._wheels.push(wheel);
  12708. };
  12709. /**
  12710. * @function setAccelerate set the target acceleration
  12711. * @param {number} val the target acceleration
  12712. * @type void
  12713. **/
  12714. JCar.prototype.setAccelerate=function(val){
  12715. this._destAccelerate = val;
  12716. };
  12717. /**
  12718. * @function setSteer set the target steering angle and define which wheels should turn
  12719. * @param {array} wheels a collection of Wheel objects
  12720. * @param {number} val the target acceleration
  12721. * @type void
  12722. **/
  12723. JCar.prototype.setSteer=function(wheels, val){
  12724. this._destSteering = val;
  12725. this._steerWheels = [];
  12726. var wheel=null;
  12727. for (var i=0, l=wheels.length; i<l; i++){
  12728. wheel=this.getWheel(wheels[i]);
  12729. if (wheel)
  12730. this._steerWheels.push(wheel);
  12731. }
  12732. };
  12733. /**
  12734. * @function findWheel checks if a wheel exists matching a given name
  12735. * @param {string} name the name of the wheel to find
  12736. * @type boolean
  12737. **/
  12738. JCar.prototype.findWheel=function(_name){
  12739. for (var i=0, l=this._wheels.length; i<l; i++){
  12740. if (this._wheels[i].name == _name) return true;
  12741. }
  12742. return false;
  12743. };
  12744. /**
  12745. * @function getWheel get a wheel by name
  12746. * @param {string} name the name of the wheel to get
  12747. * @type Wheel
  12748. **/
  12749. JCar.prototype.getWheel=function(_name){
  12750. for (var i=0; i<this._wheels.length; i++){
  12751. if (this._wheels[i].name == _name) return this._wheels[i];
  12752. }
  12753. return null;
  12754. };
  12755. /**
  12756. * @function setHBrake sets the handbrake off or on
  12757. * @param {number} val 0 to set the handbrake off, and 1 to set it on
  12758. * @type void
  12759. **/
  12760. JCar.prototype.setHBrake=function(val){
  12761. this._HBrake = val;
  12762. };
  12763. /**
  12764. * @function addExternalForces applies wheel forces to the vehicle
  12765. * @param {number} dt a UNIX timestamp
  12766. * @type void
  12767. **/
  12768. JCar.prototype.addExternalForces=function(dt){
  12769. for(var i=0, wl=this._wheels.length; i<wl; i++){
  12770. this._wheels[i].addForcesToCar(dt);
  12771. }
  12772. };
  12773. /**
  12774. * @function postPhysics runs after the PhysicsSystem has been applied
  12775. * @param {number} dt a UNIX timestamp
  12776. * @type void
  12777. **/
  12778. JCar.prototype.postPhysics=function(dt){
  12779. for(var i=0, wl=this._wheels.length; i<wl; i++){
  12780. this._wheels[i].update(dt);
  12781. }
  12782. var deltaAccelerate = dt;
  12783. var deltaSteering = dt * this._steerRate;
  12784. var dAccelerate = this._destAccelerate - this._accelerate;
  12785. if (dAccelerate < -deltaAccelerate) dAccelerate = -deltaAccelerate;
  12786. else if (dAccelerate > deltaAccelerate) dAccelerate = deltaAccelerate;
  12787. this._accelerate += dAccelerate;
  12788. var dSteering = this._destSteering - this._steering;
  12789. if (dSteering < -deltaSteering) dSteering = -deltaSteering;
  12790. else if (dSteering > deltaSteering) dSteering = deltaSteering;
  12791. this._steering += dSteering;
  12792. for(var i=0;i<this._wheels.length;i++){
  12793. this._wheels[i].addTorque(this._driveTorque * this._accelerate);
  12794. this._wheels[i].setLock(this._HBrake > 0.5);
  12795. }
  12796. var alpha = mrAbs(this._maxSteerAngle * this._steering);
  12797. var angleSgn = (this._steering > 0) ? 1 : -1;
  12798. for(var i=0, swl=this._steerWheels.length; i<swl; i++){
  12799. this._steerWheels[i].setSteerAngle(angleSgn * alpha);
  12800. }
  12801. };
  12802. /**
  12803. * @function getNumWheelsOnFloor returns the number of wheels in contact with the ground
  12804. * @param {number} dt a UNIX timestamp
  12805. * @type number
  12806. **/
  12807. JCar.prototype.getNumWheelsOnFloor=function(dt){
  12808. var count = 0;
  12809. for(var i=0, wl=this._wheels.length; i<wl; i++){
  12810. //this._wheels[i].update(dt);
  12811. if (this._wheels[i].getOnFloor()) count++;
  12812. }
  12813. return count;
  12814. };
  12815. jigLib.JCar=JCar;
  12816. })(jigLib);