Oimo.js 414 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407114081140911410114111141211413114141141511416114171141811419114201142111422114231142411425114261142711428114291143011431114321143311434114351143611437114381143911440114411144211443114441144511446114471144811449114501145111452114531145411455114561145711458114591146011461114621146311464114651146611467114681146911470114711147211473114741147511476114771147811479114801148111482114831148411485114861148711488114891149011491114921149311494114951149611497114981149911500115011150211503115041150511506115071150811509115101151111512115131151411515115161151711518115191152011521115221152311524115251152611527115281152911530115311153211533115341153511536115371153811539115401154111542115431154411545115461154711548115491155011551115521155311554115551155611557115581155911560115611156211563115641156511566115671156811569115701157111572115731157411575115761157711578115791158011581115821158311584115851158611587115881158911590115911159211593115941159511596115971159811599116001160111602116031160411605116061160711608116091161011611116121161311614116151161611617116181161911620116211162211623116241162511626116271162811629116301163111632116331163411635116361163711638116391164011641116421164311644116451164611647116481164911650116511165211653116541165511656116571165811659116601166111662116631166411665116661166711668116691167011671116721167311674116751167611677116781167911680116811168211683116841168511686116871168811689116901169111692116931169411695116961169711698116991170011701117021170311704117051170611707117081170911710117111171211713117141171511716117171171811719117201172111722117231172411725117261172711728117291173011731117321173311734117351173611737117381173911740117411174211743117441174511746117471174811749117501175111752117531175411755117561175711758117591176011761117621176311764117651176611767117681176911770117711177211773117741177511776117771177811779117801178111782117831178411785117861178711788117891179011791117921179311794117951179611797117981179911800118011180211803118041180511806118071180811809118101181111812118131181411815118161181711818118191182011821118221182311824118251182611827118281182911830118311183211833118341183511836118371183811839118401184111842118431184411845118461184711848118491185011851118521185311854118551185611857118581185911860118611186211863118641186511866118671186811869118701187111872118731187411875118761187711878118791188011881118821188311884118851188611887118881188911890118911189211893118941189511896118971189811899119001190111902119031190411905119061190711908119091191011911119121191311914119151191611917119181191911920119211192211923119241192511926119271192811929119301193111932119331193411935119361193711938119391194011941119421194311944119451194611947119481194911950119511195211953119541195511956119571195811959119601196111962119631196411965119661196711968119691197011971119721197311974119751197611977119781197911980119811198211983119841198511986119871198811989119901199111992119931199411995119961199711998119991200012001120021200312004120051200612007120081200912010120111201212013120141201512016120171201812019120201202112022120231202412025120261202712028120291203012031120321203312034120351203612037120381203912040120411204212043120441204512046120471204812049120501205112052120531205412055120561205712058120591206012061120621206312064120651206612067120681206912070120711207212073120741207512076120771207812079120801208112082120831208412085120861208712088120891209012091120921209312094120951209612097120981209912100121011210212103121041210512106121071210812109121101211112112121131211412115121161211712118121191212012121121221212312124121251212612127121281212912130121311213212133121341213512136121371213812139121401214112142121431214412145121461214712148121491215012151121521215312154121551215612157121581215912160121611216212163121641216512166121671216812169121701217112172121731217412175121761217712178121791218012181121821218312184121851218612187121881218912190121911219212193121941219512196121971219812199122001220112202122031220412205122061220712208122091221012211122121221312214122151221612217122181221912220122211222212223122241222512226122271222812229122301223112232122331223412235122361223712238122391224012241122421224312244122451224612247122481224912250122511225212253122541225512256122571225812259122601226112262122631226412265122661226712268122691227012271122721227312274122751227612277122781227912280122811228212283122841228512286122871228812289122901229112292122931229412295122961229712298122991230012301123021230312304123051230612307123081230912310123111231212313123141231512316123171231812319123201232112322123231232412325123261232712328123291233012331123321233312334123351233612337123381233912340123411234212343123441234512346123471234812349123501235112352123531235412355123561235712358123591236012361123621236312364123651236612367123681236912370123711237212373123741237512376123771237812379123801238112382123831238412385123861238712388123891239012391123921239312394123951239612397123981239912400124011240212403124041240512406124071240812409124101241112412124131241412415124161241712418124191242012421124221242312424124251242612427124281242912430124311243212433124341243512436124371243812439124401244112442124431244412445124461244712448124491245012451124521245312454124551245612457124581245912460124611246212463124641246512466124671246812469124701247112472124731247412475124761247712478124791248012481124821248312484124851248612487124881248912490124911249212493124941249512496124971249812499125001250112502125031250412505125061250712508125091251012511125121251312514125151251612517125181251912520125211252212523125241252512526125271252812529
  1. /**
  2. * from OimoPhysics DEV 1.1.0a AS3
  3. * @author Saharan / http://el-ement.com/
  4. *
  5. * to Oimo.js 2015 JAVASCRIPT
  6. * @author LoTh / http://lo-th.github.io/labs/
  7. */
  8. var OIMO = {
  9. REVISION: "1.2",
  10. // Global identification of next shape.
  11. // This will be incremented every time a shape is created.
  12. nextID: 0,
  13. proxyID: 0,
  14. // BroadPhase
  15. BR_NULL: 0,
  16. BR_BRUTE_FORCE: 1,
  17. BR_SWEEP_AND_PRUNE: 2,
  18. BR_BOUNDING_VOLUME_TREE: 3,
  19. // body type
  20. BODY_NULL: 0,
  21. BODY_DYNAMIC: 1,
  22. BODY_STATIC: 2,
  23. // shape type
  24. SHAPE_NULL: 0,
  25. SHAPE_SPHERE: 1,
  26. SHAPE_BOX: 2,
  27. SHAPE_CYLINDER: 3,
  28. SHAPE_TETRA: 4,
  29. // joint type
  30. JOINT_NULL: 0,
  31. JOINT_DISTANCE: 1,
  32. JOINT_BALL_AND_SOCKET: 2,
  33. JOINT_HINGE: 3,
  34. JOINT_WHEEL: 4,
  35. JOINT_SLIDER: 5,
  36. JOINT_PRISMATIC: 6,
  37. // this world scale defaut is 0.1 to 10 meters max for dynamique body
  38. // scale all by 100 so object is between 10 to 10000 three unit.
  39. WORLD_SCALE: 100,
  40. INV_SCALE: 0.01,
  41. // AABB aproximation
  42. AABB_PROX: 0.005,
  43. // Math function
  44. sqrt: Math.sqrt,
  45. abs: Math.abs,
  46. floor: Math.floor,
  47. cos: Math.cos,
  48. sin: Math.sin,
  49. acos: Math.acos,
  50. asin: Math.asin,
  51. atan2: Math.atan2,
  52. round: Math.round,
  53. pow: Math.pow,
  54. max: Math.max,
  55. min: Math.min,
  56. random: Math.random,
  57. lerp: function (a, b, percent) { return a + (b - a) * percent; },
  58. rand: function (a, b) { return OIMO.lerp(a, b, OIMO.random()); },
  59. randInt: function (a, b, n) { return OIMO.lerp(a, b, OIMO.random()).toFixed(n || 0) * 1; },
  60. int: function (x) { return ~~x; },
  61. fix: function (x, n) { return x.toFixed(n || 3, 10); },
  62. clamp: function (value, min, max) { return OIMO.max(min, OIMO.min(max, value)); },
  63. degtorad: 0.0174532925199432957,
  64. radtodeg: 57.295779513082320876,
  65. PI: 3.141592653589793,
  66. TwoPI: 6.283185307179586,
  67. PI90: 1.570796326794896,
  68. PI270: 4.712388980384689,
  69. CustomError: null,
  70. Error: function (Class, Msg) {
  71. if (OIMO.CustomError == null) console.error(Class, Msg);
  72. else OIMO.CustomError.innerHTML += Class + " - " + Msg + '<br>';
  73. }
  74. };
  75. var OIMO_ARRAY_TYPE;
  76. if (!OIMO_ARRAY_TYPE) { OIMO_ARRAY_TYPE = typeof Float32Array !== 'undefined' ? Float32Array : Array; }
  77. try {
  78. (function (w) {
  79. var perfNow;
  80. var perfNowNames = ['now', 'webkitNow', 'msNow', 'mozNow'];
  81. if (!!w['performance']) for (var i = 0; i < perfNowNames.length; ++i) {
  82. var n = perfNowNames[i];
  83. if (!!w['performance'][n]) {
  84. perfNow = function () { return w['performance'][n]() };
  85. break;
  86. }
  87. }
  88. if (!perfNow) perfNow = Date.now;
  89. //w.perfNow = perfNow;
  90. OIMO.now = perfNow;
  91. })(window);
  92. } catch (e) { OIMO.now = function () { return 0; }; }
  93. /**
  94. * The class of physical computing world.
  95. * You must be added to the world physical all computing objects
  96. * @author saharan
  97. * @author lo-th
  98. */
  99. OIMO.World = function (TimeStep, BroadPhaseType, Iterations, NoStat) {
  100. // The time between each step
  101. this.timeStep = TimeStep || 0.01666; // 1/60;
  102. // The number of iterations for constraint solvers.
  103. this.numIterations = Iterations || 8;
  104. // It is a wide-area collision judgment that is used in order to reduce as much as possible a detailed collision judgment.
  105. switch (BroadPhaseType || 2) {
  106. case 1: this.broadPhase = new OIMO.BruteForceBroadPhase(); break;
  107. case 2: default: this.broadPhase = new OIMO.SAPBroadPhase(); break;
  108. case 3: this.broadPhase = new OIMO.DBVTBroadPhase(); break;
  109. }
  110. // This is the detailed information of the performance.
  111. this.performance = null;
  112. this.isNoStat = NoStat || false;
  113. if (!this.isNoStat) this.performance = new OIMO.Performance(this);
  114. // Whether the constraints randomizer is enabled or not.
  115. this.enableRandomizer = true;
  116. // The rigid body list
  117. this.rigidBodies = null;
  118. // number of rigid body
  119. this.numRigidBodies = 0;
  120. // The contact list
  121. this.contacts = null;
  122. this.unusedContacts = null;
  123. // The number of contact
  124. this.numContacts = 0;
  125. // The number of contact points
  126. this.numContactPoints = 0;
  127. // The joint list
  128. this.joints = null;
  129. // The number of joints.
  130. this.numJoints = 0;
  131. // The number of simulation islands.
  132. this.numIslands = 0;
  133. // The gravity in the world.
  134. this.gravity = new OIMO.Vec3(0, -9.80665, 0);
  135. var numShapeTypes = 5;//4;//3;
  136. this.detectors = [];
  137. this.detectors.length = numShapeTypes;
  138. var i = numShapeTypes;
  139. while (i--) {
  140. this.detectors[i] = [];
  141. this.detectors[i].length = numShapeTypes;
  142. }
  143. this.detectors[OIMO.SHAPE_SPHERE][OIMO.SHAPE_SPHERE] = new OIMO.SphereSphereCollisionDetector();
  144. this.detectors[OIMO.SHAPE_SPHERE][OIMO.SHAPE_BOX] = new OIMO.SphereBoxCollisionDetector(false);
  145. this.detectors[OIMO.SHAPE_BOX][OIMO.SHAPE_SPHERE] = new OIMO.SphereBoxCollisionDetector(true);
  146. this.detectors[OIMO.SHAPE_BOX][OIMO.SHAPE_BOX] = new OIMO.BoxBoxCollisionDetector();
  147. // CYLINDER add
  148. this.detectors[OIMO.SHAPE_CYLINDER][OIMO.SHAPE_CYLINDER] = new OIMO.CylinderCylinderCollisionDetector();
  149. this.detectors[OIMO.SHAPE_CYLINDER][OIMO.SHAPE_BOX] = new OIMO.BoxCylinderCollisionDetector(true);
  150. this.detectors[OIMO.SHAPE_BOX][OIMO.SHAPE_CYLINDER] = new OIMO.BoxCylinderCollisionDetector(false);
  151. this.detectors[OIMO.SHAPE_CYLINDER][OIMO.SHAPE_SPHERE] = new OIMO.SphereCylinderCollisionDetector(true);
  152. this.detectors[OIMO.SHAPE_SPHERE][OIMO.SHAPE_CYLINDER] = new OIMO.SphereCylinderCollisionDetector(false);
  153. // TETRA add
  154. this.detectors[OIMO.SHAPE_TETRA][OIMO.SHAPE_TETRA] = new OIMO.TetraTetraCollisionDetector();
  155. this.randX = 65535;
  156. this.randA = 98765;
  157. this.randB = 123456789;
  158. //this.maxIslandRigidBodies = 64;
  159. this.islandRigidBodies = [];
  160. //this.islandRigidBodies.length = this.maxIslandRigidBodies;
  161. this.islandStack = [];
  162. //this.islandStack.length = this.maxIslandRigidBodies;
  163. //this.maxIslandConstraints = 128;
  164. this.islandConstraints = [];
  165. //this.islandConstraints.length = this.maxIslandConstraints;
  166. };
  167. OIMO.World.prototype = {
  168. constructor: OIMO.World,
  169. /**
  170. * Reset the randomizer and remove all rigid bodies, shapes, joints and any object from the world.
  171. */
  172. clear: function () {
  173. this.randX = 65535;
  174. while (this.joints !== null) {
  175. this.removeJoint(this.joints);
  176. }
  177. while (this.contacts !== null) {
  178. this.removeContact(this.contacts);
  179. }
  180. while (this.rigidBodies !== null) {
  181. this.removeRigidBody(this.rigidBodies);
  182. }
  183. OIMO.nextID = 0;
  184. OIMO.proxyID = 0;
  185. },
  186. /**
  187. * I'll add a rigid body to the world.
  188. * Rigid body that has been added will be the operands of each step.
  189. * @param rigidBody Rigid body that you want to add
  190. */
  191. addRigidBody: function (rigidBody) {
  192. if (rigidBody.parent) {
  193. OIMO.Error("World", "It is not possible to be added to more than one world one of the rigid body");
  194. }
  195. rigidBody.parent = this;
  196. rigidBody.awake();
  197. for (var shape = rigidBody.shapes; shape !== null; shape = shape.next) {
  198. this.addShape(shape);
  199. }
  200. if (this.rigidBodies !== null) (this.rigidBodies.prev = rigidBody).next = this.rigidBodies;
  201. this.rigidBodies = rigidBody;
  202. this.numRigidBodies++;
  203. },
  204. /**
  205. * I will remove the rigid body from the world.
  206. * Rigid body that has been deleted is excluded from the calculation on a step-by-step basis.
  207. * @param rigidBody Rigid body to be removed
  208. */
  209. removeRigidBody: function (rigidBody) {
  210. var remove = rigidBody;
  211. if (remove.parent !== this) return;
  212. remove.awake();
  213. var js = remove.jointLink;
  214. while (js != null) {
  215. var joint = js.joint;
  216. js = js.next;
  217. this.removeJoint(joint);
  218. }
  219. for (var shape = rigidBody.shapes; shape !== null; shape = shape.next) {
  220. this.removeShape(shape);
  221. }
  222. var prev = remove.prev;
  223. var next = remove.next;
  224. if (prev !== null) prev.next = next;
  225. if (next !== null) next.prev = prev;
  226. if (this.rigidBodies == remove) this.rigidBodies = next;
  227. remove.prev = null;
  228. remove.next = null;
  229. remove.parent = null;
  230. this.numRigidBodies--;
  231. },
  232. getByName: function (name) {
  233. var result = null;
  234. var body = this.rigidBodies;
  235. while (body !== null) {
  236. if (body.name !== " " && body.name === name) result = body;
  237. body = body.next;
  238. }
  239. var joint = this.joints;
  240. while (joint !== null) {
  241. if (joint.name !== "" && joint.name === name) result = joint;
  242. joint = joint.next;
  243. }
  244. return result;
  245. },
  246. /**
  247. * I'll add a shape to the world..
  248. * Add to the rigid world, and if you add a shape to a rigid body that has been added to the world,
  249. * Shape will be added to the world automatically, please do not call from outside this method.
  250. * @param shape Shape you want to add
  251. */
  252. addShape: function (shape) {
  253. if (!shape.parent || !shape.parent.parent) {
  254. OIMO.Error("World", "It is not possible to be added alone to shape world");
  255. }
  256. shape.proxy = this.broadPhase.createProxy(shape);
  257. shape.updateProxy();
  258. this.broadPhase.addProxy(shape.proxy);
  259. },
  260. /**
  261. * I will remove the shape from the world.
  262. * Add to the rigid world, and if you add a shape to a rigid body that has been added to the world,
  263. * Shape will be added to the world automatically, please do not call from outside this method.
  264. * @param shape Shape you want to delete
  265. */
  266. removeShape: function (shape) {
  267. this.broadPhase.removeProxy(shape.proxy);
  268. shape.proxy = null;
  269. },
  270. /**
  271. * I'll add a joint to the world.
  272. * Joint that has been added will be the operands of each step.
  273. * @param shape Joint to be added
  274. */
  275. addJoint: function (joint) {
  276. if (joint.parent) {
  277. OIMO.Error("World", "It is not possible to be added to more than one world one of the joint");
  278. }
  279. if (this.joints != null) (this.joints.prev = joint).next = this.joints;
  280. this.joints = joint;
  281. joint.parent = this;
  282. this.numJoints++;
  283. joint.awake();
  284. joint.attach();
  285. },
  286. /**
  287. * I will remove the joint from the world.
  288. * Joint that has been added will be the operands of each step.
  289. * @param shape Joint to be deleted
  290. */
  291. removeJoint: function (joint) {
  292. var remove = joint;
  293. var prev = remove.prev;
  294. var next = remove.next;
  295. if (prev !== null) prev.next = next;
  296. if (next !== null) next.prev = prev;
  297. if (this.joints == remove) this.joints = next;
  298. remove.prev = null;
  299. remove.next = null;
  300. this.numJoints--;
  301. remove.awake();
  302. remove.detach();
  303. remove.parent = null;
  304. },
  305. worldscale: function (scale) {
  306. OIMO.WORLD_SCALE = scale || 100;
  307. OIMO.INV_SCALE = 1 / OIMO.WORLD_SCALE;
  308. },
  309. addContact: function (s1, s2) {
  310. var newContact;
  311. if (this.unusedContacts !== null) {
  312. newContact = this.unusedContacts;
  313. this.unusedContacts = this.unusedContacts.next;
  314. } else {
  315. newContact = new OIMO.Contact();
  316. }
  317. newContact.attach(s1, s2);
  318. newContact.detector = this.detectors[s1.type][s2.type];
  319. if (this.contacts) (this.contacts.prev = newContact).next = this.contacts;
  320. this.contacts = newContact;
  321. this.numContacts++;
  322. },
  323. removeContact: function (contact) {
  324. var prev = contact.prev;
  325. var next = contact.next;
  326. if (next) next.prev = prev;
  327. if (prev) prev.next = next;
  328. if (this.contacts == contact) this.contacts = next;
  329. contact.prev = null;
  330. contact.next = null;
  331. contact.detach();
  332. contact.next = this.unusedContacts;
  333. this.unusedContacts = contact;
  334. this.numContacts--;
  335. },
  336. checkContact: function (name1, name2) {
  337. var n1, n2;
  338. var contact = this.contacts;
  339. while (contact !== null) {
  340. n1 = contact.body1.name || ' ';
  341. n2 = contact.body2.name || ' ';
  342. if ((n1 == name1 && n2 == name2) || (n2 == name1 && n1 == name2)) { if (contact.touching) return true; else return false; }
  343. else contact = contact.next;
  344. }
  345. return false;
  346. },
  347. callSleep: function (body) {
  348. if (!body.allowSleep) return false;
  349. if (body.linearVelocity.lengthSq() > 0.04) return false;
  350. if (body.angularVelocity.lengthSq() > 0.25) return false;
  351. return true;
  352. },
  353. /**
  354. * I will proceed only time step seconds time of World.
  355. */
  356. step: function () {
  357. var time0, time1, time2, time3;
  358. var stat = !this.isNoStat ? true : false;
  359. if (stat) time0 = OIMO.now();
  360. var body = this.rigidBodies;
  361. while (body !== null) {
  362. body.addedToIsland = false;
  363. if (body.sleeping) {
  364. if (
  365. body.linearVelocity.testZero() ||
  366. body.angularVelocity.testZero() ||
  367. body.position.testDiff(body.sleepPosition) ||
  368. body.orientation.testDiff(body.sleepOrientation)
  369. ) body.awake(); // awake the body
  370. }
  371. body = body.next;
  372. }
  373. //------------------------------------------------------
  374. // UPDATE CONTACT
  375. //------------------------------------------------------
  376. // broad phase
  377. if (stat) time1 = OIMO.now();
  378. this.broadPhase.detectPairs();
  379. var pairs = this.broadPhase.pairs;
  380. var i = this.broadPhase.numPairs;
  381. //do{
  382. while (i--) {
  383. //for(var i=0, l=numPairs; i<l; i++){
  384. var pair = pairs[i];
  385. var s1;
  386. var s2;
  387. if (pair.shape1.id < pair.shape2.id) {
  388. s1 = pair.shape1;
  389. s2 = pair.shape2;
  390. } else {
  391. s1 = pair.shape2;
  392. s2 = pair.shape1;
  393. }
  394. var link;
  395. if (s1.numContacts < s2.numContacts) link = s1.contactLink;
  396. else link = s2.contactLink;
  397. var exists = false;
  398. while (link) {
  399. var contact = link.contact;
  400. if (contact.shape1 == s1 && contact.shape2 == s2) {
  401. contact.persisting = true;
  402. exists = true;// contact already exists
  403. break;
  404. }
  405. link = link.next;
  406. }
  407. if (!exists) {
  408. this.addContact(s1, s2);
  409. }
  410. }// while(i-- >0);
  411. if (stat) {
  412. time2 = OIMO.now();
  413. this.performance.broadPhaseTime = time2 - time1;
  414. }
  415. // update & narrow phase
  416. this.numContactPoints = 0;
  417. contact = this.contacts;
  418. while (contact !== null) {
  419. if (!contact.persisting) {
  420. if (contact.shape1.aabb.intersectTest(contact.shape2.aabb)) {
  421. /*var aabb1=contact.shape1.aabb;
  422. var aabb2=contact.shape2.aabb;
  423. if(
  424. aabb1.minX>aabb2.maxX || aabb1.maxX<aabb2.minX ||
  425. aabb1.minY>aabb2.maxY || aabb1.maxY<aabb2.minY ||
  426. aabb1.minZ>aabb2.maxZ || aabb1.maxZ<aabb2.minZ
  427. ){*/
  428. var next = contact.next;
  429. this.removeContact(contact);
  430. contact = next;
  431. continue;
  432. }
  433. }
  434. var b1 = contact.body1;
  435. var b2 = contact.body2;
  436. if (b1.isDynamic && !b1.sleeping || b2.isDynamic && !b2.sleeping) {
  437. contact.updateManifold();
  438. }
  439. this.numContactPoints += contact.manifold.numPoints;
  440. contact.persisting = false;
  441. contact.constraint.addedToIsland = false;
  442. contact = contact.next;
  443. }
  444. if (stat) {
  445. time3 = OIMO.now();
  446. this.performance.narrowPhaseTime = time3 - time2;
  447. }
  448. //------------------------------------------------------
  449. // SOLVE ISLANDS
  450. //------------------------------------------------------
  451. var invTimeStep = 1 / this.timeStep;
  452. //var body;
  453. var joint;
  454. var constraint;
  455. //var num;
  456. for (joint = this.joints; joint !== null; joint = joint.next) {
  457. joint.addedToIsland = false;
  458. }
  459. // clear old island array
  460. this.islandRigidBodies = [];
  461. this.islandConstraints = [];
  462. this.islandStack = [];
  463. // expand island buffers
  464. /*if(this.maxIslandRigidBodies<this.numRigidBodies){
  465. this.maxIslandRigidBodies=this.numRigidBodies<<1;
  466. //this.maxIslandRigidBodies=this.numRigidBodies*2;
  467. this.islandRigidBodies=[];
  468. this.islandStack=[];
  469. this.islandRigidBodies.length = this.maxIslandRigidBodies;
  470. this.islandStack.length = this.maxIslandRigidBodies;
  471. }
  472. var numConstraints=this.numJoints+this.numContacts;
  473. if(this.maxIslandConstraints<numConstraints){
  474. this.maxIslandConstraints=numConstraints<<1;
  475. //this.maxIslandConstraints=numConstraints*2;
  476. this.islandConstraints=[];
  477. this.islandConstraints.length = this.maxIslandConstraints;
  478. }*/
  479. time1 = OIMO.now();
  480. this.numIslands = 0;
  481. // build and solve simulation islands
  482. for (var base = this.rigidBodies; base !== null; base = base.next) {
  483. if (base.addedToIsland || base.isStatic || base.sleeping) continue;// ignore
  484. if (base.isLonely()) {// update single body
  485. if (base.isDynamic) {
  486. base.linearVelocity.addTime(this.gravity, this.timeStep);
  487. /*base.linearVelocity.x+=this.gravity.x*this.timeStep;
  488. base.linearVelocity.y+=this.gravity.y*this.timeStep;
  489. base.linearVelocity.z+=this.gravity.z*this.timeStep;*/
  490. }
  491. if (this.callSleep(base)) {
  492. base.sleepTime += this.timeStep;
  493. if (base.sleepTime > 0.5) base.sleep();
  494. else base.updatePosition(this.timeStep);
  495. } else {
  496. base.sleepTime = 0;
  497. base.updatePosition(this.timeStep);
  498. }
  499. this.numIslands++;
  500. continue;
  501. }
  502. var islandNumRigidBodies = 0;
  503. var islandNumConstraints = 0;
  504. var stackCount = 1;
  505. // add rigid body to stack
  506. this.islandStack[0] = base;
  507. base.addedToIsland = true;
  508. // build an island
  509. do {
  510. // get rigid body from stack
  511. body = this.islandStack[--stackCount];
  512. this.islandStack[stackCount] = null;
  513. body.sleeping = false;
  514. // add rigid body to the island
  515. this.islandRigidBodies[islandNumRigidBodies++] = body;
  516. if (body.isStatic) continue;
  517. // search connections
  518. for (var cs = body.contactLink; cs !== null; cs = cs.next) {
  519. var contact = cs.contact;
  520. constraint = contact.constraint;
  521. if (constraint.addedToIsland || !contact.touching) continue;// ignore
  522. // add constraint to the island
  523. this.islandConstraints[islandNumConstraints++] = constraint;
  524. constraint.addedToIsland = true;
  525. var next = cs.body;
  526. if (next.addedToIsland) continue;
  527. // add rigid body to stack
  528. this.islandStack[stackCount++] = next;
  529. next.addedToIsland = true;
  530. }
  531. for (var js = body.jointLink; js !== null; js = js.next) {
  532. constraint = js.joint;
  533. if (constraint.addedToIsland) continue;// ignore
  534. // add constraint to the island
  535. this.islandConstraints[islandNumConstraints++] = constraint;
  536. constraint.addedToIsland = true;
  537. next = js.body;
  538. if (next.addedToIsland || !next.isDynamic) continue;
  539. // add rigid body to stack
  540. this.islandStack[stackCount++] = next;
  541. next.addedToIsland = true;
  542. }
  543. } while (stackCount != 0);
  544. // update velocities
  545. var gVel = new OIMO.Vec3().addTime(this.gravity, this.timeStep);
  546. /*var gx=this.gravity.x*this.timeStep;
  547. var gy=this.gravity.y*this.timeStep;
  548. var gz=this.gravity.z*this.timeStep;*/
  549. var j = islandNumRigidBodies;
  550. while (j--) {
  551. //or(var j=0, l=islandNumRigidBodies; j<l; j++){
  552. body = this.islandRigidBodies[j];
  553. if (body.isDynamic) {
  554. body.linearVelocity.addEqual(gVel);
  555. /*body.linearVelocity.x+=gx;
  556. body.linearVelocity.y+=gy;
  557. body.linearVelocity.z+=gz;*/
  558. }
  559. }
  560. // randomizing order
  561. if (this.enableRandomizer) {
  562. //for(var j=1, l=islandNumConstraints; j<l; j++){
  563. j = islandNumConstraints;
  564. while (j--) {
  565. if (j !== 0) {
  566. var swap = (this.randX = (this.randX * this.randA + this.randB & 0x7fffffff)) / 2147483648.0 * j | 0;
  567. constraint = this.islandConstraints[j];
  568. this.islandConstraints[j] = this.islandConstraints[swap];
  569. this.islandConstraints[swap] = constraint;
  570. }
  571. }
  572. }
  573. // solve contraints
  574. j = islandNumConstraints;
  575. while (j--) {
  576. //for(j=0, l=islandNumConstraints; j<l; j++){
  577. this.islandConstraints[j].preSolve(this.timeStep, invTimeStep);// pre-solve
  578. }
  579. var k = this.numIterations;
  580. while (k--) {
  581. //for(var k=0, l=this.numIterations; k<l; k++){
  582. j = islandNumConstraints;
  583. while (j--) {
  584. //for(j=0, m=islandNumConstraints; j<m; j++){
  585. this.islandConstraints[j].solve();// main-solve
  586. }
  587. }
  588. j = islandNumConstraints;
  589. while (j--) {
  590. //for(j=0, l=islandNumConstraints; j<l; j++){
  591. this.islandConstraints[j].postSolve();// post-solve
  592. this.islandConstraints[j] = null;// gc
  593. }
  594. // sleeping check
  595. var sleepTime = 10;
  596. j = islandNumRigidBodies;
  597. while (j--) {
  598. //for(j=0, l=islandNumRigidBodies;j<l;j++){
  599. body = this.islandRigidBodies[j];
  600. if (this.callSleep(body)) {
  601. body.sleepTime += this.timeStep;
  602. if (body.sleepTime < sleepTime) sleepTime = body.sleepTime;
  603. } else {
  604. body.sleepTime = 0;
  605. sleepTime = 0;
  606. continue;
  607. }
  608. }
  609. if (sleepTime > 0.5) {
  610. // sleep the island
  611. j = islandNumRigidBodies;
  612. while (j--) {
  613. //for(j=0, l=islandNumRigidBodies;j<l;j++){
  614. this.islandRigidBodies[j].sleep();
  615. this.islandRigidBodies[j] = null;// gc
  616. }
  617. } else {
  618. // update positions
  619. j = islandNumRigidBodies;
  620. while (j--) {
  621. //for(j=0, l=islandNumRigidBodies;j<l;j++){
  622. this.islandRigidBodies[j].updatePosition(this.timeStep);
  623. this.islandRigidBodies[j] = null;// gc
  624. }
  625. }
  626. this.numIslands++;
  627. }
  628. if (stat) {
  629. time2 = OIMO.now();
  630. this.performance.solvingTime = time2 - time1;
  631. //------------------------------------------------------
  632. // END SIMULATION
  633. //------------------------------------------------------
  634. time2 = OIMO.now();
  635. // fps update
  636. this.performance.upfps();
  637. this.performance.totalTime = time2 - time0;
  638. }
  639. }
  640. }
  641. /**
  642. * The class of rigid body.
  643. * Rigid body has the shape of a single or multiple collision processing,
  644. * I can set the parameters individually.
  645. * @author saharan
  646. */
  647. OIMO.RigidBody = function (x, y, z, rad, ax, ay, az) {
  648. this.name = " ";
  649. // The maximum number of shapes that can be added to a one rigid.
  650. this.MAX_SHAPES = 64;//64;
  651. this.prev = null;
  652. this.next = null;
  653. // I represent the kind of rigid body.
  654. // Please do not change from the outside this variable.
  655. // If you want to change the type of rigid body, always
  656. // Please specify the type you want to set the arguments of setupMass method.
  657. this.type = OIMO.BODY_NULL;
  658. this.massInfo = new OIMO.MassInfo();
  659. // It is the world coordinate of the center of gravity.
  660. this.position = new OIMO.Vec3(x, y, z);
  661. this.orientation = this.rotationAxisToQuad(rad || 0, ax || 0, ay || 0, az || 0);
  662. this.newPosition = new OIMO.Vec3();
  663. this.controlPos = false;
  664. this.newOrientation = new OIMO.Quat();
  665. this.newRotation = new OIMO.Vec3();
  666. this.currentRotation = new OIMO.Vec3();
  667. this.controlRot = false;
  668. this.controlRotInTime = false;
  669. // Is the translational velocity.
  670. this.linearVelocity = new OIMO.Vec3();
  671. // Is the angular velocity.
  672. this.angularVelocity = new OIMO.Vec3();
  673. // return matrix for three.js
  674. this.matrix = new OIMO.Mat44();
  675. //--------------------------------------------
  676. // Please do not change from the outside this variables.
  677. //--------------------------------------------
  678. // It is a world that rigid body has been added.
  679. this.parent = null;
  680. this.contactLink = null;
  681. this.numContacts = 0;
  682. // An array of shapes that are included in the rigid body.
  683. this.shapes = null;
  684. // The number of shapes that are included in the rigid body.
  685. this.numShapes = 0;
  686. // It is the link array of joint that is connected to the rigid body.
  687. this.jointLink = null;
  688. // The number of joints that are connected to the rigid body.
  689. this.numJoints = 0;
  690. // It is the world coordinate of the center of gravity in the sleep just before.
  691. this.sleepPosition = new OIMO.Vec3();
  692. // It is a quaternion that represents the attitude of sleep just before.
  693. this.sleepOrientation = new OIMO.Quat();
  694. // I will show this rigid body to determine whether it is a rigid body static.
  695. this.isStatic = false;
  696. // I indicates that this rigid body to determine whether it is a rigid body dynamic.
  697. this.isDynamic = false;
  698. // It is a rotation matrix representing the orientation.
  699. this.rotation = new OIMO.Mat33();
  700. //--------------------------------------------
  701. // It will be recalculated automatically from the shape, which is included.
  702. //--------------------------------------------
  703. // This is the weight.
  704. this.mass = NaN;
  705. // It is the reciprocal of the mass.
  706. this.inverseMass = NaN;
  707. // It is the inverse of the inertia tensor in the world system.
  708. this.inverseInertia = new OIMO.Mat33();
  709. // It is the inertia tensor in the initial state.
  710. this.localInertia = new OIMO.Mat33();
  711. // It is the inverse of the inertia tensor in the initial state.
  712. this.inverseLocalInertia = new OIMO.Mat33();
  713. // I indicates rigid body whether it has been added to the simulation Island.
  714. this.addedToIsland = false;
  715. // It shows how to sleep rigid body.
  716. this.allowSleep = true;
  717. // This is the time from when the rigid body at rest.
  718. this.sleepTime = 0;
  719. // I shows rigid body to determine whether it is a sleep state.
  720. this.sleeping = false;
  721. };
  722. OIMO.RigidBody.prototype = {
  723. constructor: OIMO.RigidBody,
  724. /**
  725. * I'll add a shape to rigid body.
  726. * If you add a shape, please call the setupMass method to step up to the start of the next.
  727. * @param shape shape to Add
  728. */
  729. addShape: function (shape) {
  730. if (shape.parent) OIMO.Error("RigidBody", "It is not possible that you add to the multi-rigid body the shape of one");
  731. if (this.shapes != null) (this.shapes.prev = shape).next = this.shapes;
  732. this.shapes = shape;
  733. shape.parent = this;
  734. if (this.parent) this.parent.addShape(shape);
  735. this.numShapes++;
  736. },
  737. /**
  738. * I will delete the shape from the rigid body.
  739. * If you delete a shape, please call the setupMass method to step up to the start of the next.
  740. * @param shape shape to Delete
  741. */
  742. removeShape: function (shape) {
  743. var remove = shape;
  744. if (remove.parent != this) return;
  745. var prev = remove.prev;
  746. var next = remove.next;
  747. if (prev != null) prev.next = next;
  748. if (next != null) next.prev = prev;
  749. if (this.shapes == remove) this.shapes = next;
  750. remove.prev = null;
  751. remove.next = null;
  752. remove.parent = null;
  753. if (this.parent) this.parent.removeShape(remove);
  754. this.numShapes--;
  755. },
  756. remove: function () {
  757. this.dispose();
  758. },
  759. dispose: function () {
  760. this.parent.removeRigidBody(this);
  761. },
  762. checkContact: function (name) {
  763. this.parent.checkContact(this.name, name);
  764. },
  765. /**
  766. * Calulates mass datas(center of gravity, mass, moment inertia, etc...).
  767. * If the parameter type is set to BODY_STATIC, the rigid body will be fixed to the space.
  768. * If the parameter adjustPosition is set to true, the shapes' relative positions and
  769. * the rigid body's position will be adjusted to the center of gravity.
  770. * @param type
  771. * @param adjustPosition
  772. */
  773. setupMass: function (type, AdjustPosition) {
  774. var adjustPosition = (AdjustPosition !== undefined) ? AdjustPosition : true;
  775. this.type = type || OIMO.BODY_DYNAMIC;
  776. this.isDynamic = this.type == OIMO.BODY_DYNAMIC;
  777. this.isStatic = this.type == OIMO.BODY_STATIC;
  778. this.mass = 0;
  779. this.localInertia.set(0, 0, 0, 0, 0, 0, 0, 0, 0);
  780. var te = this.localInertia.elements;
  781. //
  782. var tmpM = new OIMO.Mat33();
  783. var tmpV = new OIMO.Vec3();
  784. for (var shape = this.shapes; shape != null; shape = shape.next) {
  785. shape.calculateMassInfo(this.massInfo);
  786. var shapeMass = this.massInfo.mass;
  787. var relX = shape.relativePosition.x;
  788. var relY = shape.relativePosition.y;
  789. var relZ = shape.relativePosition.z;
  790. /*tmpV.x+=relX*shapeMass;
  791. tmpV.y+=relY*shapeMass;
  792. tmpV.z+=relZ*shapeMass;*/
  793. tmpV.addScale(shape.relativePosition, shapeMass);
  794. this.mass += shapeMass;
  795. this.rotateInertia(shape.relativeRotation, this.massInfo.inertia, tmpM);
  796. this.localInertia.addEqual(tmpM);
  797. // add offset inertia
  798. te[0] += shapeMass * (relY * relY + relZ * relZ);
  799. te[4] += shapeMass * (relX * relX + relZ * relZ);
  800. te[8] += shapeMass * (relX * relX + relY * relY);
  801. var xy = shapeMass * relX * relY;
  802. var yz = shapeMass * relY * relZ;
  803. var zx = shapeMass * relZ * relX;
  804. te[1] -= xy;
  805. te[3] -= xy;
  806. te[2] -= yz;
  807. te[6] -= yz;
  808. te[5] -= zx;
  809. te[7] -= zx;
  810. }
  811. this.inverseMass = 1 / this.mass;
  812. tmpV.scaleEqual(this.inverseMass);
  813. if (adjustPosition) {
  814. this.position.addEqual(tmpV);
  815. for (shape = this.shapes; shape != null; shape = shape.next) {
  816. shape.relativePosition.subEqual(tmpV);
  817. }
  818. // subtract offset inertia
  819. relX = tmpV.x;
  820. relY = tmpV.y;
  821. relZ = tmpV.z;
  822. //var te = this.localInertia.elements;
  823. te[0] -= this.mass * (relY * relY + relZ * relZ);
  824. te[4] -= this.mass * (relX * relX + relZ * relZ);
  825. te[8] -= this.mass * (relX * relX + relY * relY);
  826. xy = this.mass * relX * relY;
  827. yz = this.mass * relY * relZ;
  828. zx = this.mass * relZ * relX;
  829. te[1] += xy;
  830. te[3] += xy;
  831. te[2] += yz;
  832. te[6] += yz;
  833. te[5] += zx;
  834. te[7] += zx;
  835. }
  836. this.inverseLocalInertia.invert(this.localInertia);
  837. if (this.type == OIMO.BODY_STATIC) {
  838. this.inverseMass = 0;
  839. this.inverseLocalInertia.set(0, 0, 0, 0, 0, 0, 0, 0, 0);
  840. }
  841. this.syncShapes();
  842. this.awake();
  843. },
  844. /**
  845. * Awake the rigid body.
  846. */
  847. awake: function () {
  848. if (!this.allowSleep || !this.sleeping) return;
  849. this.sleeping = false;
  850. this.sleepTime = 0;
  851. // awake connected constraints
  852. var cs = this.contactLink;
  853. while (cs != null) {
  854. cs.body.sleepTime = 0;
  855. cs.body.sleeping = false;
  856. cs = cs.next;
  857. }
  858. var js = this.jointLink;
  859. while (js != null) {
  860. js.body.sleepTime = 0;
  861. js.body.sleeping = false;
  862. js = js.next;
  863. }
  864. for (var shape = this.shapes; shape != null; shape = shape.next) {
  865. shape.updateProxy();
  866. }
  867. },
  868. /**
  869. * Sleep the rigid body.
  870. */
  871. sleep: function () {
  872. if (!this.allowSleep || this.sleeping) return;
  873. this.linearVelocity.set(0, 0, 0);
  874. this.angularVelocity.set(0, 0, 0);
  875. this.sleepPosition.copy(this.position);
  876. this.sleepOrientation.copy(this.orientation);
  877. /*this.linearVelocity.x=0;
  878. this.linearVelocity.y=0;
  879. this.linearVelocity.z=0;
  880. this.angularVelocity.x=0;
  881. this.angularVelocity.y=0;
  882. this.angularVelocity.z=0;
  883. this.sleepPosition.x=this.position.x;
  884. this.sleepPosition.y=this.position.y;
  885. this.sleepPosition.z=this.position.z;*/
  886. /*this.sleepOrientation.s=this.orientation.s;
  887. this.sleepOrientation.x=this.orientation.x;
  888. this.sleepOrientation.y=this.orientation.y;
  889. this.sleepOrientation.z=this.orientation.z;*/
  890. this.sleepTime = 0;
  891. this.sleeping = true;
  892. for (var shape = this.shapes; shape != null; shape = shape.next) {
  893. shape.updateProxy();
  894. }
  895. },
  896. /**
  897. * Get whether the rigid body has not any connection with others.
  898. * @return
  899. */
  900. isLonely: function () {
  901. return this.numJoints == 0 && this.numContacts == 0;
  902. },
  903. /**
  904. * The time integration of the motion of a rigid body, you can update the information such as the shape.
  905. * This method is invoked automatically when calling the step of the World,
  906. * There is no need to call from outside usually.
  907. * @param timeStep time
  908. */
  909. updatePosition: function (timeStep) {
  910. switch (this.type) {
  911. case OIMO.BODY_STATIC:
  912. this.linearVelocity.set(0, 0, 0);
  913. this.angularVelocity.set(0, 0, 0);
  914. // ONLY FOR TEST
  915. if (this.controlPos) {
  916. this.position.copy(this.newPosition);
  917. this.controlPos = false;
  918. }
  919. if (this.controlRot) {
  920. this.orientation.copy(this.newOrientation);
  921. this.controlRot = false;
  922. }
  923. /*this.linearVelocity.x=0;
  924. this.linearVelocity.y=0;
  925. this.linearVelocity.z=0;
  926. this.angularVelocity.x=0;
  927. this.angularVelocity.y=0;
  928. this.angularVelocity.z=0;*/
  929. break;
  930. case OIMO.BODY_DYNAMIC:
  931. if (this.controlPos) {
  932. this.angularVelocity.set(0, 0, 0);
  933. this.linearVelocity.set(0, 0, 0);
  934. this.linearVelocity.x = (this.newPosition.x - this.position.x) / timeStep;
  935. this.linearVelocity.y = (this.newPosition.y - this.position.y) / timeStep;
  936. this.linearVelocity.z = (this.newPosition.z - this.position.z) / timeStep;
  937. this.controlPos = false;
  938. }
  939. if (this.controlRot) {
  940. this.angularVelocity.set(0, 0, 0);
  941. this.orientation.copy(this.newOrientation);
  942. //var t=timeStep//*0.5;
  943. //var q = new OIMO.Quat();
  944. //q.sub(this.newOrientation, this.orientation);
  945. //q.normalize(q);
  946. /*q.s = (this.newOrientation.s - this.orientation.s)/t;
  947. q.x = (this.newOrientation.x - this.orientation.x)/t;
  948. q.y = (this.newOrientation.y - this.orientation.y)/t;
  949. q.z = (this.newOrientation.z - this.orientation.z)/t;*/
  950. //this.angularVelocity.applyQuaternion(q);
  951. //this.angularVelocity.x = this.angularVelocity.x/t;
  952. //this.angularVelocity.y = this.angularVelocity.y/t;
  953. //this.angularVelocity.z = this.angularVelocity.z/t;
  954. this.controlRot = false;
  955. }
  956. this.position.addTime(this.linearVelocity, timeStep);
  957. this.orientation.addTime(this.angularVelocity, timeStep);
  958. break;
  959. default: OIMO.Error("RigidBody", "Invalid type.");
  960. }
  961. this.syncShapes();
  962. },
  963. rotateInertia: function (rot, inertia, out) {
  964. var tm1 = rot.elements;
  965. var tm2 = inertia.elements;
  966. var a0 = tm1[0], a3 = tm1[3], a6 = tm1[6];
  967. var a1 = tm1[1], a4 = tm1[4], a7 = tm1[7];
  968. var a2 = tm1[2], a5 = tm1[5], a8 = tm1[8];
  969. var b0 = tm2[0], b3 = tm2[3], b6 = tm2[6];
  970. var b1 = tm2[1], b4 = tm2[4], b7 = tm2[7];
  971. var b2 = tm2[2], b5 = tm2[5], b8 = tm2[8];
  972. var e00 = a0 * b0 + a1 * b3 + a2 * b6;
  973. var e01 = a0 * b1 + a1 * b4 + a2 * b7;
  974. var e02 = a0 * b2 + a1 * b5 + a2 * b8;
  975. var e10 = a3 * b0 + a4 * b3 + a5 * b6;
  976. var e11 = a3 * b1 + a4 * b4 + a5 * b7;
  977. var e12 = a3 * b2 + a4 * b5 + a5 * b8;
  978. var e20 = a6 * b0 + a7 * b3 + a8 * b6;
  979. var e21 = a6 * b1 + a7 * b4 + a8 * b7;
  980. var e22 = a6 * b2 + a7 * b5 + a8 * b8;
  981. var oe = out.elements;
  982. oe[0] = e00 * a0 + e01 * a1 + e02 * a2;
  983. oe[1] = e00 * a3 + e01 * a4 + e02 * a5;
  984. oe[2] = e00 * a6 + e01 * a7 + e02 * a8;
  985. oe[3] = e10 * a0 + e11 * a1 + e12 * a2;
  986. oe[4] = e10 * a3 + e11 * a4 + e12 * a5;
  987. oe[5] = e10 * a6 + e11 * a7 + e12 * a8;
  988. oe[6] = e20 * a0 + e21 * a1 + e22 * a2;
  989. oe[7] = e20 * a3 + e21 * a4 + e22 * a5;
  990. oe[8] = e20 * a6 + e21 * a7 + e22 * a8;
  991. },
  992. syncShapes: function () {
  993. var s = this.orientation.s;
  994. var x = this.orientation.x;
  995. var y = this.orientation.y;
  996. var z = this.orientation.z;
  997. var x2 = 2 * x;
  998. var y2 = 2 * y;
  999. var z2 = 2 * z;
  1000. var xx = x * x2;
  1001. var yy = y * y2;
  1002. var zz = z * z2;
  1003. var xy = x * y2;
  1004. var yz = y * z2;
  1005. var xz = x * z2;
  1006. var sx = s * x2;
  1007. var sy = s * y2;
  1008. var sz = s * z2;
  1009. var tr = this.rotation.elements;
  1010. tr[0] = 1 - yy - zz;
  1011. tr[1] = xy - sz;
  1012. tr[2] = xz + sy;
  1013. tr[3] = xy + sz;
  1014. tr[4] = 1 - xx - zz;
  1015. tr[5] = yz - sx;
  1016. tr[6] = xz - sy;
  1017. tr[7] = yz + sx;
  1018. tr[8] = 1 - xx - yy;
  1019. this.rotateInertia(this.rotation, this.inverseLocalInertia, this.inverseInertia);
  1020. for (var shape = this.shapes; shape != null; shape = shape.next) {
  1021. //var relPos=shape.relativePosition;
  1022. //var relRot=shape.relativeRotation;
  1023. //var rot=shape.rotation;
  1024. /*var lx=relPos.x;
  1025. var ly=relPos.y;
  1026. var lz=relPos.z;
  1027. shape.position.x=this.position.x+lx*tr[0]+ly*tr[1]+lz*tr[2];
  1028. shape.position.y=this.position.y+lx*tr[3]+ly*tr[4]+lz*tr[5];
  1029. shape.position.z=this.position.z+lx*tr[6]+ly*tr[7]+lz*tr[8];*/
  1030. shape.position.mul(this.position, shape.relativePosition, this.rotation);
  1031. //shape.rotation.mul(shape.relativeRotation,this.rotation);
  1032. // add by QuaziKb
  1033. shape.rotation.mul(this.rotation, shape.relativeRotation);
  1034. shape.updateProxy();
  1035. }
  1036. },
  1037. applyImpulse: function (position, force) {
  1038. this.linearVelocity.addScale(force, this.inverseMass);
  1039. /*this.linearVelocity.x+=force.x*this.inverseMass;
  1040. this.linearVelocity.y+=force.y*this.inverseMass;
  1041. this.linearVelocity.z+=force.z*this.inverseMass;*/
  1042. var rel = new OIMO.Vec3();
  1043. rel.sub(position, this.position).cross(rel, force).mulMat(this.inverseInertia, rel);
  1044. this.angularVelocity.addEqual(rel);
  1045. /*this.angularVelocity.x+=rel.x;
  1046. this.angularVelocity.y+=rel.y;
  1047. this.angularVelocity.z+=rel.z;*/
  1048. },
  1049. //---------------------------------------------
  1050. //
  1051. // FOR THREE JS
  1052. //
  1053. //---------------------------------------------
  1054. rotationVectToQuad: function (rot) {
  1055. var r = OIMO.EulerToAxis(rot.x * OIMO.degtorad, rot.y * OIMO.degtorad, rot.z * OIMO.degtorad);
  1056. return this.rotationAxisToQuad(r[0], r[1], r[2], r[3]);
  1057. },
  1058. rotationAxisToQuad: function (rad, ax, ay, az) { // in radian
  1059. var len = ax * ax + ay * ay + az * az;
  1060. if (len > 0) {
  1061. len = 1 / OIMO.sqrt(len);
  1062. ax *= len;
  1063. ay *= len;
  1064. az *= len;
  1065. }
  1066. var sin = OIMO.sin(rad * 0.5);
  1067. var cos = OIMO.cos(rad * 0.5);
  1068. return new OIMO.Quat(cos, sin * ax, sin * ay, sin * az);
  1069. },
  1070. //---------------------------------------------
  1071. // SET DYNAMIQUE POSITION AND ROTATION
  1072. //---------------------------------------------
  1073. setPosition: function (pos) {
  1074. this.newPosition.copy(pos).multiplyScalar(OIMO.INV_SCALE);
  1075. //this.newPosition.set(pos.x*OIMO.INV_SCALE,pos.y*OIMO.INV_SCALE,pos.z*OIMO.INV_SCALE);
  1076. this.controlPos = true;
  1077. },
  1078. setQuaternion: function (q) {
  1079. //if(this.type == this.BODY_STATIC)this.orientation.init(q.w,q.x,q.y,q.z);
  1080. this.newOrientation.set(q.x, q.y, q.z, q.w);
  1081. this.controlRot = true;
  1082. },
  1083. setRotation: function (rot) {
  1084. this.newOrientation = this.rotationVectToQuad(rot);
  1085. this.controlRot = true;
  1086. },
  1087. //---------------------------------------------
  1088. // RESET DYNAMIQUE POSITION AND ROTATION
  1089. //---------------------------------------------
  1090. resetPosition: function (x, y, z) {
  1091. this.linearVelocity.set(0, 0, 0);
  1092. this.angularVelocity.set(0, 0, 0);
  1093. this.position.set(x, y, z).multiplyScalar(OIMO.INV_SCALE);
  1094. //this.position.set( x*OIMO.INV_SCALE, y*OIMO.INV_SCALE, z*OIMO.INV_SCALE );
  1095. this.awake();
  1096. },
  1097. resetQuaternion: function (q) {
  1098. this.angularVelocity.set(0, 0, 0);
  1099. this.orientation = new OIMO.Quat(q.w, q.x, q.y, q.z);
  1100. this.awake();
  1101. },
  1102. resetRotation: function (x, y, z) {
  1103. this.angularVelocity.set(0, 0, 0);
  1104. this.orientation = this.rotationVectToQuad(new OIMO.Vec3(x, y, z));
  1105. this.awake();
  1106. },
  1107. //---------------------------------------------
  1108. // GET POSITION AND ROTATION
  1109. //---------------------------------------------
  1110. getPosition: function () {
  1111. return new OIMO.Vec3().scale(this.position, OIMO.WORLD_SCALE);
  1112. },
  1113. getRotation: function () {
  1114. return new OIMO.Euler().setFromRotationMatrix(this.rotation);
  1115. },
  1116. getQuaternion: function () {
  1117. return new OIMO.Quaternion().setFromRotationMatrix(this.rotation);
  1118. },
  1119. getMatrix: function () {
  1120. var m = this.matrix.elements;
  1121. var r, p;
  1122. if (!this.sleeping) {
  1123. // rotation matrix
  1124. r = this.rotation.elements;
  1125. m[0] = r[0]; m[1] = r[3]; m[2] = r[6]; m[3] = 0;
  1126. m[4] = r[1]; m[5] = r[4]; m[6] = r[7]; m[7] = 0;
  1127. m[8] = r[2]; m[9] = r[5]; m[10] = r[8]; m[11] = 0;
  1128. // position matrix
  1129. p = this.position;
  1130. m[12] = p.x * OIMO.WORLD_SCALE;
  1131. m[13] = p.y * OIMO.WORLD_SCALE;
  1132. m[14] = p.z * OIMO.WORLD_SCALE;
  1133. // sleep or not ?
  1134. m[15] = 0;
  1135. } else {
  1136. m[15] = 1;
  1137. }
  1138. return m;
  1139. }
  1140. };
  1141. /**
  1142. * The main class of body.
  1143. * is for simplify creation process and data access of rigidRody
  1144. * Rigid body has the shape of a single or multiple collision processing,
  1145. * all setting in object
  1146. *
  1147. * @author loth
  1148. */
  1149. OIMO.Body = function (Obj) {
  1150. var obj = Obj || {};
  1151. if (!obj.world) return;
  1152. if (obj.type === undefined) obj.type = "box";
  1153. this.name = obj.name || '';
  1154. // obsolete use world.add(obj)
  1155. this.body = obj.world.add(obj);
  1156. /*
  1157. // the world where i am
  1158. this.parent = obj.world;
  1159. // Yep my name
  1160. this.name = obj.name || '';
  1161. // I'm dynamique or not
  1162. var move = obj.move || false;
  1163. // I can sleep or not
  1164. var noSleep = obj.noSleep || false;
  1165. // My start position
  1166. var p = obj.pos || [0,0,0];
  1167. p = p.map(function(x) { return x * OIMO.INV_SCALE; });
  1168. // My size
  1169. var s = obj.size || [1,1,1];
  1170. s = s.map(function(x) { return x * OIMO.INV_SCALE; });
  1171. // My rotation in degre
  1172. var rot = obj.rot || [0,0,0];
  1173. rot = rot.map(function(x) { return x * OIMO.TO_RAD; });
  1174. var r = [];
  1175. for (var i=0; i<rot.length/3; i++){
  1176. var tmp = OIMO.EulerToAxis(rot[i+0], rot[i+1], rot[i+2]);
  1177. r.push(tmp[0]); r.push(tmp[1]); r.push(tmp[2]); r.push(tmp[3]);
  1178. }
  1179. // My physics setting
  1180. var sc = obj.sc || new OIMO.ShapeConfig();
  1181. if(obj.config){
  1182. // The density of the shape.
  1183. sc.density = obj.config[0] || 1;
  1184. // The coefficient of friction of the shape.
  1185. sc.friction = obj.config[1] || 0.4;
  1186. // The coefficient of restitution of the shape.
  1187. sc.restitution = obj.config[2] || 0.2;
  1188. // The bits of the collision groups to which the shape belongs.
  1189. sc.belongsTo = obj.config[3] || 1;
  1190. // The bits of the collision groups with which the shape collides.
  1191. sc.collidesWith = obj.config[4] || 0xffffffff;
  1192. }
  1193. if(obj.massPos){
  1194. obj.massPos = obj.massPos.map(function(x) { return x * OIMO.INV_SCALE; });
  1195. sc.relativePosition.init(obj.massPos[0], obj.massPos[1], obj.massPos[2]);
  1196. }
  1197. if(obj.massRot){
  1198. obj.massRot = obj.massRot.map(function(x) { return x * OIMO.TO_RAD; });
  1199. sc.relativeRotation = OIMO.EulerToMatrix(obj.massRot[0], obj.massRot[1], obj.massRot[2]);
  1200. }
  1201. // My rigidbody
  1202. this.body = new OIMO.RigidBody(p[0], p[1], p[2], r[0], r[1], r[2], r[3]);
  1203. // My shapes
  1204. var shapes = [];
  1205. var type = obj.type || "box";
  1206. if( typeof type === 'string' ) type = [type];// single shape
  1207. var n, n2;
  1208. for(var i=0; i<type.length; i++){
  1209. n = i*3;
  1210. n2 = i*4;
  1211. switch(type[i]){
  1212. case "sphere": shapes[i] = new OIMO.SphereShape(sc, s[n+0]); break;
  1213. case "cylinder": shapes[i] = new OIMO.BoxShape(sc, s[n+0], s[n+1], s[n+2]); break; // fake cylinder
  1214. case "box": shapes[i] = new OIMO.BoxShape(sc, s[n+0], s[n+1], s[n+2]); break;
  1215. }
  1216. this.body.addShape(shapes[i]);
  1217. if(i>0){
  1218. //shapes[i].position.init(p[0]+p[n+0], p[1]+p[n+1], p[2]+p[n+2] );
  1219. shapes[i].relativePosition = new OIMO.Vec3( p[n+0], p[n+1], p[n+2] );
  1220. if(r[n2+0]) shapes[i].relativeRotation = [ r[n2+0], r[n2+1], r[n2+2], r[n2+3] ];
  1221. }
  1222. }
  1223. // I'm static or i move
  1224. if(move){
  1225. if(obj.massPos || obj.massRot)this.body.setupMass(0x1, false);
  1226. else this.body.setupMass(0x1, true);
  1227. if(noSleep) this.body.allowSleep = false;
  1228. else this.body.allowSleep = true;
  1229. } else {
  1230. this.body.setupMass(0x2);
  1231. }
  1232. this.body.name = this.name;
  1233. this.sleeping = this.body.sleeping;
  1234. // finaly add to physics world
  1235. this.parent.addRigidBody(this.body);*/
  1236. }
  1237. OIMO.Body.prototype = {
  1238. constructor: OIMO.Body,
  1239. // SET
  1240. setPosition: function (pos) {
  1241. this.body.setPosition(pos);
  1242. },
  1243. setQuaternion: function (q) {
  1244. this.body.setQuaternion(q);
  1245. },
  1246. setRotation: function (rot) {
  1247. this.body.setRotation(rot);
  1248. },
  1249. // GET
  1250. getPosition: function () {
  1251. return this.body.getPosition();
  1252. },
  1253. getRotation: function () {
  1254. return this.body.getRotation();
  1255. },
  1256. getQuaternion: function () {
  1257. return this.body.getQuaternion();
  1258. },
  1259. getMatrix: function () {
  1260. return this.body.getMatrix();
  1261. },
  1262. getSleep: function () {
  1263. return this.body.sleeping;
  1264. },
  1265. // RESET
  1266. resetPosition: function (x, y, z) {
  1267. this.body.resetPosition(x, y, z);
  1268. },
  1269. resetRotation: function (x, y, z) {
  1270. this.body.resetRotation(x, y, z);
  1271. },
  1272. // force wakeup
  1273. awake: function () {
  1274. this.body.awake();
  1275. },
  1276. // remove rigidbody
  1277. remove: function () {
  1278. this.body.dispose();
  1279. //this.parent.removeRigidBody(this.body);
  1280. },
  1281. // test if this object hit another
  1282. checkContact: function (name) {
  1283. this.body.checkContact(name);
  1284. //this.parent.checkContact(this.name, name);
  1285. }
  1286. }
  1287. /**
  1288. * The main class of link.
  1289. * is for simplify creation process and data access of Joint
  1290. * all setting in object
  1291. *
  1292. * @author loth
  1293. */
  1294. OIMO.Link = function (Obj) {
  1295. var obj = Obj || {};
  1296. if (!obj.world) return;
  1297. if (obj.type === undefined) obj.type = "jointHinge";
  1298. this.name = obj.name || '';
  1299. // obsolete use world.add(obj)
  1300. this.joint = obj.world.add(obj);
  1301. // the world where i am
  1302. /*this.parent = obj.world;
  1303. this.name = obj.name || '';
  1304. var type = obj.type || "jointHinge";
  1305. var axe1 = obj.axe1 || [1,0,0];
  1306. var axe2 = obj.axe2 || [1,0,0];
  1307. var pos1 = obj.pos1 || [0,0,0];
  1308. var pos2 = obj.pos2 || [0,0,0];
  1309. pos1 = pos1.map(function(x){ return x * OIMO.INV_SCALE; });
  1310. pos2 = pos2.map(function(x){ return x * OIMO.INV_SCALE; });
  1311. var min, max;
  1312. if(type==="jointDistance"){
  1313. min = obj.min || 0;
  1314. max = obj.max || 10;
  1315. min = min*OIMO.INV_SCALE;
  1316. max = max*OIMO.INV_SCALE;
  1317. }else{
  1318. min = obj.min || 57.29578;
  1319. max = obj.max || 0;
  1320. min = min*OIMO.TO_RAD;
  1321. max = max*OIMO.TO_RAD;
  1322. }
  1323. var limit = obj.limit || null;
  1324. var spring = obj.spring || null;
  1325. var motor = obj.motor || null;
  1326. // joint setting
  1327. var jc = new OIMO.JointConfig();
  1328. jc.allowCollision = obj.collision || false;;
  1329. jc.localAxis1.init(axe1[0], axe1[1], axe1[2]);
  1330. jc.localAxis2.init(axe2[0], axe2[1], axe2[2]);
  1331. jc.localAnchorPoint1.init(pos1[0], pos1[1], pos1[2]);
  1332. jc.localAnchorPoint2.init(pos2[0], pos2[1], pos2[2]);
  1333. if (typeof obj.body1 == 'string' || obj.body1 instanceof String) obj.body1 = obj.world.getByName(obj.body1);
  1334. if (typeof obj.body2 == 'string' || obj.body2 instanceof String) obj.body2 = obj.world.getByName(obj.body2);
  1335. jc.body1 = obj.body1;
  1336. jc.body2 = obj.body2;
  1337. switch(type){
  1338. case "jointDistance": this.joint = new OIMO.DistanceJoint(jc, min, max);
  1339. if(spring !== null) this.joint.limitMotor.setSpring(spring[0], spring[1]);
  1340. if(motor !== null) this.joint.limitMotor.setSpring(motor[0], motor[1]);
  1341. break;
  1342. case "jointHinge": this.joint = new OIMO.HingeJoint(jc, min, max);
  1343. if(spring !== null) this.joint.limitMotor.setSpring(spring[0], spring[1]);// soften the joint ex: 100, 0.2
  1344. if(motor !== null) this.joint.limitMotor.setSpring(motor[0], motor[1]);
  1345. break;
  1346. case "jointPrisme": this.joint = new OIMO.PrismaticJoint(jc, min, max); break;
  1347. case "jointSlide": this.joint = new OIMO.SliderJoint(jc, min, max); break;
  1348. case "jointBall": this.joint = new OIMO.BallAndSocketJoint(jc); break;
  1349. case "jointWheel": this.joint = new OIMO.WheelJoint(jc);
  1350. if(limit !== null) this.joint.rotationalLimitMotor1.setLimit(limit[0], limit[1]);
  1351. if(spring !== null) this.joint.rotationalLimitMotor1.setSpring(spring[0], spring[1]);
  1352. if(motor !== null) this.joint.rotationalLimitMotor1.setSpring(motor[0], motor[1]);
  1353. break;
  1354. }
  1355. this.joint.name = this.name;
  1356. // finaly add to physics world
  1357. this.parent.addJoint(this.joint);*/
  1358. }
  1359. OIMO.Link.prototype = {
  1360. constructor: OIMO.Link,
  1361. getPosition: function () {
  1362. // array of two vect3 [point1, point2]
  1363. return this.joint.getPosition();
  1364. },
  1365. getMatrix: function () {
  1366. return this.joint.getMatrix();
  1367. },
  1368. // remove joint
  1369. remove: function () {
  1370. this.joint.dispose();
  1371. //this.parent.removeJoint(this.joint);
  1372. },
  1373. // force wakeup linked body
  1374. awake: function () {
  1375. this.joint.awake();
  1376. }
  1377. }
  1378. /**
  1379. * The Dictionary class for testing
  1380. * @author lo-th
  1381. */
  1382. OIMO.Dictionary = function () {
  1383. this.data = {};
  1384. this.keys = [];
  1385. };
  1386. OIMO.Dictionary.prototype = {
  1387. constructor: OIMO.Dictionary,
  1388. set: function (value) {
  1389. var key = value.id;
  1390. if (!this.get[key]) this.keys.push(key);
  1391. this.data[key] = value;
  1392. },
  1393. get: function (id) {
  1394. return this.data[id];
  1395. },
  1396. del: function (value) {
  1397. var k = this.keys;
  1398. var n = k.indexOf(value.id);
  1399. if (n > -1) {
  1400. delete this.data[k[n]];
  1401. k.splice(n, 1);
  1402. }
  1403. },
  1404. reset: function () {
  1405. var data = this.data, keys = this.keys, key;
  1406. while (keys.length > 0) {
  1407. key = keys.pop();
  1408. delete data[key];
  1409. }
  1410. }
  1411. };
  1412. OIMO.Performance = function (world) {
  1413. this.parent = world;
  1414. this.infos = new OIMO_ARRAY_TYPE(13);
  1415. this.f = [0, 0, 0];
  1416. this.types = ['None', 'BruteForce', 'Sweep & Prune', 'Bounding Volume Tree'];
  1417. this.broadPhase = this.types[this.parent.broadPhase.types];
  1418. this.version = OIMO.REVISION;
  1419. this.fps = 0;
  1420. this.broadPhaseTime = 0;
  1421. this.narrowPhaseTime = 0;
  1422. this.solvingTime = 0;
  1423. //this.updatingTime = 0;
  1424. this.totalTime = 0;
  1425. };
  1426. OIMO.Performance.prototype = {
  1427. upfps: function () {
  1428. this.f[1] = Date.now();
  1429. if (this.f[1] - 1000 > this.f[0]) { this.f[0] = this.f[1]; this.fps = this.f[2]; this.f[2] = 0; } this.f[2]++;
  1430. },
  1431. updatingTime: function () {
  1432. return OIMO.fix(this.totalTime - (this.broadPhaseTime + this.narrowPhaseTime + this.solvingTime));
  1433. },
  1434. show: function () {
  1435. var info = [
  1436. "Oimo.js " + this.version + "<br>",
  1437. this.broadPhase + "<br><br>",
  1438. "FPS: " + this.fps + " fps<br><br>",
  1439. "rigidbody " + this.parent.numRigidBodies + "<br>",
  1440. "contact &nbsp;&nbsp;" + this.parent.numContacts + "<br>",
  1441. "ct-point &nbsp;" + this.parent.numContactPoints + "<br>",
  1442. "paircheck " + this.parent.broadPhase.numPairChecks + "<br>",
  1443. "island &nbsp;&nbsp;&nbsp;" + this.parent.numIslands + "<br><br>",
  1444. "Time in milliseconde<br><br>",
  1445. "broad-phase &nbsp;" + OIMO.fix(this.broadPhaseTime) + "<br>",
  1446. "narrow-phase " + OIMO.fix(this.narrowPhaseTime) + "<br>",
  1447. "solving &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;" + OIMO.fix(this.solvingTime) + "<br>",
  1448. "total &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;" + OIMO.fix(this.totalTime) + "<br>",
  1449. "updating &nbsp;&nbsp;&nbsp;&nbsp;" + this.updatingTime() + "<br>"
  1450. ].join("\n");
  1451. return info;
  1452. },
  1453. toArray: function () {
  1454. this.infos[0] = this.parent.broadPhase.types;
  1455. this.infos[1] = this.parent.numRigidBodies;
  1456. this.infos[2] = this.parent.numContacts;
  1457. this.infos[3] = this.parent.broadPhase.numPairChecks;
  1458. this.infos[4] = this.parent.numContactPoints;
  1459. this.infos[5] = this.parent.numIslands;
  1460. this.infos[6] = this.broadPhaseTime;
  1461. this.infos[7] = this.narrowPhaseTime;
  1462. this.infos[8] = this.solvingTime;
  1463. this.infos[9] = this.updatingTime();
  1464. this.infos[10] = this.totalTime;
  1465. this.infos[11] = this.fps;
  1466. return this.infos;
  1467. }
  1468. };
  1469. OIMO.Mat44 = function (n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44) {
  1470. this.elements = new OIMO_ARRAY_TYPE(16);
  1471. var te = this.elements;
  1472. te[0] = (n11 !== undefined) ? n11 : 1; te[4] = n12 || 0; te[8] = n13 || 0; te[12] = n14 || 0;
  1473. te[1] = n21 || 0; te[5] = (n22 !== undefined) ? n22 : 1; te[9] = n23 || 0; te[13] = n24 || 0;
  1474. te[2] = n31 || 0; te[6] = n32 || 0; te[10] = (n33 !== undefined) ? n33 : 1; te[14] = n34 || 0;
  1475. te[3] = n41 || 0; te[7] = n42 || 0; te[11] = n43 || 0; te[15] = (n44 !== undefined) ? n44 : 1;
  1476. };
  1477. OIMO.Mat44.prototype = {
  1478. constructor: OIMO.Mat44,
  1479. set: function (n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44) {
  1480. var te = this.elements;
  1481. te[0] = n11; te[4] = n12; te[8] = n13; te[12] = n14;
  1482. te[1] = n21; te[5] = n22; te[9] = n23; te[13] = n24;
  1483. te[2] = n31; te[6] = n32; te[10] = n33; te[14] = n34;
  1484. te[3] = n41; te[7] = n42; te[11] = n43; te[15] = n44;
  1485. return this;
  1486. }/*,
  1487. extractRotation: function () {
  1488. var v1 = new THREE.Vector3();
  1489. return function ( m ) {
  1490. var te = this.elements;
  1491. var me = m.elements;
  1492. var scaleX = 1 / v1.set( me[ 0 ], me[ 1 ], me[ 2 ] ).length();
  1493. var scaleY = 1 / v1.set( me[ 4 ], me[ 5 ], me[ 6 ] ).length();
  1494. var scaleZ = 1 / v1.set( me[ 8 ], me[ 9 ], me[ 10 ] ).length();
  1495. te[ 0 ] = me[ 0 ] * scaleX;
  1496. te[ 1 ] = me[ 1 ] * scaleX;
  1497. te[ 2 ] = me[ 2 ] * scaleX;
  1498. te[ 4 ] = me[ 4 ] * scaleY;
  1499. te[ 5 ] = me[ 5 ] * scaleY;
  1500. te[ 6 ] = me[ 6 ] * scaleY;
  1501. te[ 8 ] = me[ 8 ] * scaleZ;
  1502. te[ 9 ] = me[ 9 ] * scaleZ;
  1503. te[ 10 ] = me[ 10 ] * scaleZ;
  1504. return this;
  1505. };
  1506. }() */
  1507. }
  1508. OIMO.Mat33 = function (e00, e01, e02, e10, e11, e12, e20, e21, e22) {
  1509. this.elements = new OIMO_ARRAY_TYPE(9);
  1510. var te = this.elements;
  1511. this.init(
  1512. (e00 !== undefined) ? e00 : 1, e01 || 0, e02 || 0,
  1513. e10 || 0, (e11 !== undefined) ? e11 : 1, e12 || 0,
  1514. e20 || 0, e21 || 0, (e22 !== undefined) ? e22 : 1
  1515. );
  1516. };
  1517. OIMO.Mat33.prototype = {
  1518. constructor: OIMO.Mat33,
  1519. set: function (e00, e01, e02, e10, e11, e12, e20, e21, e22) {
  1520. var te = this.elements;
  1521. te[0] = e00; te[1] = e01; te[2] = e02;
  1522. te[3] = e10; te[4] = e11; te[5] = e12;
  1523. te[6] = e20; te[7] = e21; te[8] = e22;
  1524. return this;
  1525. },
  1526. init: function (e00, e01, e02, e10, e11, e12, e20, e21, e22) {
  1527. var te = this.elements;
  1528. te[0] = e00; te[1] = e01; te[2] = e02;
  1529. te[3] = e10; te[4] = e11; te[5] = e12;
  1530. te[6] = e20; te[7] = e21; te[8] = e22;
  1531. return this;
  1532. },
  1533. multiply: function (s) {
  1534. var te = this.elements;
  1535. te[0] *= s; te[1] *= s; te[2] *= s;
  1536. te[3] *= s; te[4] *= s; te[5] *= s;
  1537. te[6] *= s; te[7] *= s; te[8] *= s;
  1538. return this;
  1539. },
  1540. add: function (m1, m2) {
  1541. var te = this.elements, tem1 = m1.elements, tem2 = m2.elements;
  1542. te[0] = tem1[0] + tem2[0]; te[1] = tem1[1] + tem2[1]; te[2] = tem1[2] + tem2[2];
  1543. te[3] = tem1[3] + tem2[3]; te[4] = tem1[4] + tem2[4]; te[5] = tem1[5] + tem2[5];
  1544. te[6] = tem1[6] + tem2[6]; te[7] = tem1[7] + tem2[7]; te[8] = tem1[8] + tem2[8];
  1545. return this;
  1546. },
  1547. addEqual: function (m) {
  1548. var te = this.elements, tem = m.elements;
  1549. te[0] += tem[0]; te[1] += tem[1]; te[2] += tem[2];
  1550. te[3] += tem[3]; te[4] += tem[4]; te[5] += tem[5];
  1551. te[6] += tem[6]; te[7] += tem[7]; te[8] += tem[8];
  1552. return this;
  1553. },
  1554. sub: function (m1, m2) {
  1555. var te = this.elements, tem1 = m1.elements, tem2 = m2.elements;
  1556. te[0] = tem1[0] - tem2[0]; te[1] = tem1[1] - tem2[1]; te[2] = tem1[2] - tem2[2];
  1557. te[3] = tem1[3] - tem2[3]; te[4] = tem1[4] - tem2[4]; te[5] = tem1[5] - tem2[5];
  1558. te[6] = tem1[6] - tem2[6]; te[7] = tem1[7] - tem2[7]; te[8] = tem1[8] - tem2[8];
  1559. return this;
  1560. },
  1561. subEqual: function (m) {
  1562. var te = this.elements, tem = m.elements;
  1563. te[0] -= tem[0]; te[1] -= tem[1]; te[2] -= tem[2];
  1564. te[3] -= tem[3]; te[4] -= tem[4]; te[5] -= tem[5];
  1565. te[6] -= tem[6]; te[7] -= tem[7]; te[8] -= tem[8];
  1566. return this;
  1567. },
  1568. scale: function (m, s) {
  1569. var te = this.elements, tm = m.elements;
  1570. te[0] = tm[0] * s; te[1] = tm[1] * s; te[2] = tm[2] * s;
  1571. te[3] = tm[3] * s; te[4] = tm[4] * s; te[5] = tm[5] * s;
  1572. te[6] = tm[6] * s; te[7] = tm[7] * s; te[8] = tm[8] * s;
  1573. return this;
  1574. },
  1575. scaleEqual: function (s) {
  1576. var te = this.elements;
  1577. te[0] *= s; te[1] *= s; te[2] *= s;
  1578. te[3] *= s; te[4] *= s; te[5] *= s;
  1579. te[6] *= s; te[7] *= s; te[8] *= s;
  1580. return this;
  1581. },
  1582. mul: function (m1, m2) {
  1583. var te = this.elements, tm1 = m1.elements, tm2 = m2.elements,
  1584. a0 = tm1[0], a3 = tm1[3], a6 = tm1[6],
  1585. a1 = tm1[1], a4 = tm1[4], a7 = tm1[7],
  1586. a2 = tm1[2], a5 = tm1[5], a8 = tm1[8],
  1587. b0 = tm2[0], b3 = tm2[3], b6 = tm2[6],
  1588. b1 = tm2[1], b4 = tm2[4], b7 = tm2[7],
  1589. b2 = tm2[2], b5 = tm2[5], b8 = tm2[8];
  1590. te[0] = a0 * b0 + a1 * b3 + a2 * b6;
  1591. te[1] = a0 * b1 + a1 * b4 + a2 * b7;
  1592. te[2] = a0 * b2 + a1 * b5 + a2 * b8;
  1593. te[3] = a3 * b0 + a4 * b3 + a5 * b6;
  1594. te[4] = a3 * b1 + a4 * b4 + a5 * b7;
  1595. te[5] = a3 * b2 + a4 * b5 + a5 * b8;
  1596. te[6] = a6 * b0 + a7 * b3 + a8 * b6;
  1597. te[7] = a6 * b1 + a7 * b4 + a8 * b7;
  1598. te[8] = a6 * b2 + a7 * b5 + a8 * b8;
  1599. return this;
  1600. },
  1601. mulScale: function (m, sx, sy, sz, Prepend) {
  1602. var prepend = Prepend || false;
  1603. var te = this.elements, tm = m.elements;
  1604. if (prepend) {
  1605. te[0] = sx * tm[0]; te[1] = sx * tm[1]; te[2] = sx * tm[2];
  1606. te[3] = sy * tm[3]; te[4] = sy * tm[4]; te[5] = sy * tm[5];
  1607. te[6] = sz * tm[6]; te[7] = sz * tm[7]; te[8] = sz * tm[8];
  1608. } else {
  1609. te[0] = tm[0] * sx; te[1] = tm[1] * sy; te[2] = tm[2] * sz;
  1610. te[3] = tm[3] * sx; te[4] = tm[4] * sy; te[5] = tm[5] * sz;
  1611. te[6] = tm[6] * sx; te[7] = tm[7] * sy; te[8] = tm[8] * sz;
  1612. }
  1613. return this;
  1614. },
  1615. mulRotate: function (m, rad, ax, ay, az, Prepend) {
  1616. var prepend = Prepend || false;
  1617. var s = OIMO.sin(rad);
  1618. var c = OIMO.cos(rad);
  1619. var c1 = 1 - c;
  1620. var r00 = ax * ax * c1 + c;
  1621. var r01 = ax * ay * c1 - az * s;
  1622. var r02 = ax * az * c1 + ay * s;
  1623. var r10 = ay * ax * c1 + az * s;
  1624. var r11 = ay * ay * c1 + c;
  1625. var r12 = ay * az * c1 - ax * s;
  1626. var r20 = az * ax * c1 - ay * s;
  1627. var r21 = az * ay * c1 + ax * s;
  1628. var r22 = az * az * c1 + c;
  1629. var tm = m.elements;
  1630. var a0 = tm[0], a3 = tm[3], a6 = tm[6];
  1631. var a1 = tm[1], a4 = tm[4], a7 = tm[7];
  1632. var a2 = tm[2], a5 = tm[5], a8 = tm[8];
  1633. var te = this.elements;
  1634. if (prepend) {
  1635. te[0] = r00 * a0 + r01 * a3 + r02 * a6;
  1636. te[1] = r00 * a1 + r01 * a4 + r02 * a7;
  1637. te[2] = r00 * a2 + r01 * a5 + r02 * a8;
  1638. te[3] = r10 * a0 + r11 * a3 + r12 * a6;
  1639. te[4] = r10 * a1 + r11 * a4 + r12 * a7;
  1640. te[5] = r10 * a2 + r11 * a5 + r12 * a8;
  1641. te[6] = r20 * a0 + r21 * a3 + r22 * a6;
  1642. te[7] = r20 * a1 + r21 * a4 + r22 * a7;
  1643. te[8] = r20 * a2 + r21 * a5 + r22 * a8;
  1644. } else {
  1645. te[0] = a0 * r00 + a1 * r10 + a2 * r20;
  1646. te[1] = a0 * r01 + a1 * r11 + a2 * r21;
  1647. te[2] = a0 * r02 + a1 * r12 + a2 * r22;
  1648. te[3] = a3 * r00 + a4 * r10 + a5 * r20;
  1649. te[4] = a3 * r01 + a4 * r11 + a5 * r21;
  1650. te[5] = a3 * r02 + a4 * r12 + a5 * r22;
  1651. te[6] = a6 * r00 + a7 * r10 + a8 * r20;
  1652. te[7] = a6 * r01 + a7 * r11 + a8 * r21;
  1653. te[8] = a6 * r02 + a7 * r12 + a8 * r22;
  1654. }
  1655. return this;
  1656. },
  1657. transpose: function (m) {
  1658. var te = this.elements, tm = m.elements;
  1659. te[0] = tm[0]; te[1] = tm[3]; te[2] = tm[6];
  1660. te[3] = tm[1]; te[4] = tm[4]; te[5] = tm[7];
  1661. te[6] = tm[2]; te[7] = tm[5]; te[8] = tm[8];
  1662. return this;
  1663. },
  1664. setQuat: function (q) {
  1665. var te = this.elements,
  1666. x2 = 2 * q.x, y2 = 2 * q.y, z2 = 2 * q.z,
  1667. xx = q.x * x2, yy = q.y * y2, zz = q.z * z2,
  1668. xy = q.x * y2, yz = q.y * z2, xz = q.x * z2,
  1669. sx = q.s * x2, sy = q.s * y2, sz = q.s * z2;
  1670. te[0] = 1 - yy - zz;
  1671. te[1] = xy - sz;
  1672. te[2] = xz + sy;
  1673. te[3] = xy + sz;
  1674. te[4] = 1 - xx - zz;
  1675. te[5] = yz - sx;
  1676. te[6] = xz - sy;
  1677. te[7] = yz + sx;
  1678. te[8] = 1 - xx - yy;
  1679. return this;
  1680. },
  1681. invert: function (m) {
  1682. var te = this.elements, tm = m.elements,
  1683. a0 = tm[0], a3 = tm[3], a6 = tm[6],
  1684. a1 = tm[1], a4 = tm[4], a7 = tm[7],
  1685. a2 = tm[2], a5 = tm[5], a8 = tm[8],
  1686. b01 = a4 * a8 - a7 * a5,
  1687. b11 = a7 * a2 - a1 * a8,
  1688. b21 = a1 * a5 - a4 * a2,
  1689. dt = a0 * (b01) + a3 * (b11) + a6 * (b21);
  1690. if (dt != 0) { dt = 1.0 / dt; }
  1691. te[0] = dt * b01;//(a4*a8 - a5*a7);
  1692. te[1] = dt * b11;//(a2*a7 - a1*a8);
  1693. te[2] = dt * b21;//(a1*a5 - a2*a4);
  1694. te[3] = dt * (a5 * a6 - a3 * a8);
  1695. te[4] = dt * (a0 * a8 - a2 * a6);
  1696. te[5] = dt * (a2 * a3 - a0 * a5);
  1697. te[6] = dt * (a3 * a7 - a4 * a6);
  1698. te[7] = dt * (a1 * a6 - a0 * a7);
  1699. te[8] = dt * (a0 * a4 - a1 * a3);
  1700. return this;
  1701. },
  1702. /*copy: function(m){
  1703. var te = this.elements, tem = m.elements;
  1704. te[0] = tem[0]; te[1] = tem[1]; te[2] = tem[2];
  1705. te[3] = tem[3]; te[4] = tem[4]; te[5] = tem[5];
  1706. te[6] = tem[6]; te[7] = tem[7]; te[8] = tem[8];
  1707. return this;
  1708. },*/
  1709. toEuler: function () { // not work !!
  1710. function clamp(x) {
  1711. return OIMO.min(OIMO.max(x, -1), 1);
  1712. }
  1713. var te = this.elements;
  1714. var m11 = te[0], m12 = te[3], m13 = te[6];
  1715. var m21 = te[1], m22 = te[4], m23 = te[7];
  1716. var m31 = te[2], m32 = te[5], m33 = te[8];
  1717. var p = new OIMO.Vec3();
  1718. var d = new OIMO.Quat();
  1719. var s;
  1720. p.y = OIMO.asin(clamp(m13));
  1721. if (OIMO.abs(m13) < 0.99999) {
  1722. p.x = OIMO.atan2(-m23, m33);
  1723. p.z = OIMO.atan2(-m12, m11);
  1724. } else {
  1725. p.x = OIMO.atan2(m32, m22);
  1726. p.z = 0;
  1727. }
  1728. return p;
  1729. },
  1730. /*clone: function(){
  1731. var te = this.elements;
  1732. return new OIMO.Mat33(
  1733. te[0], te[1], te[2],
  1734. te[3], te[4], te[5],
  1735. te[6], te[7], te[8]
  1736. );
  1737. },*/
  1738. toString: function () {
  1739. var te = this.elements;
  1740. var text =
  1741. "Mat33|" + te[0].toFixed(4) + ", " + te[1].toFixed(4) + ", " + te[2].toFixed(4) + "|\n" +
  1742. " |" + te[3].toFixed(4) + ", " + te[4].toFixed(4) + ", " + te[5].toFixed(4) + "|\n" +
  1743. " |" + te[6].toFixed(4) + ", " + te[7].toFixed(4) + ", " + te[8].toFixed(4) + "|";
  1744. return text;
  1745. },
  1746. // OK
  1747. multiplyScalar: function (s) {
  1748. var te = this.elements;
  1749. te[0] *= s; te[3] *= s; te[6] *= s;
  1750. te[1] *= s; te[4] *= s; te[7] *= s;
  1751. te[2] *= s; te[5] *= s; te[8] *= s;
  1752. return this;
  1753. },
  1754. identity: function () {
  1755. this.set(1, 0, 0, 0, 1, 0, 0, 0, 1);
  1756. return this;
  1757. },
  1758. clone: function () {
  1759. return new this.constructor().fromArray(this.elements);
  1760. },
  1761. copy: function (m) {
  1762. var me = m.elements;
  1763. this.set(
  1764. me[0], me[3], me[6],
  1765. me[1], me[4], me[7],
  1766. me[2], me[5], me[8]
  1767. );
  1768. return this;
  1769. },
  1770. fromArray: function (array) {
  1771. this.elements.set(array);
  1772. return this;
  1773. },
  1774. toArray: function () {
  1775. var te = this.elements;
  1776. return [
  1777. te[0], te[1], te[2],
  1778. te[3], te[4], te[5],
  1779. te[6], te[7], te[8]
  1780. ];
  1781. }
  1782. };
  1783. OIMO.Quat = function (s, x, y, z) {
  1784. this.s = (s !== undefined) ? s : 1;
  1785. this.x = x || 0;
  1786. this.y = y || 0;
  1787. this.z = z || 0;
  1788. };
  1789. OIMO.Quat.prototype = {
  1790. constructor: OIMO.Quat,
  1791. set: function (x, y, z, w) {
  1792. this.x = x;
  1793. this.y = y;
  1794. this.z = z;
  1795. this.s = w;
  1796. return this;
  1797. },
  1798. init: function (s, x, y, z) {
  1799. this.s = (s !== undefined) ? s : 1;
  1800. this.x = x || 0;
  1801. this.y = y || 0;
  1802. this.z = z || 0;
  1803. return this;
  1804. },
  1805. add: function (q1, q2) {
  1806. this.s = q1.s + q2.s;
  1807. this.x = q1.x + q2.x;
  1808. this.y = q1.y + q2.y;
  1809. this.z = q1.z + q2.z;
  1810. return this;
  1811. },
  1812. addTime: function (v, t) {
  1813. var x = v.x;
  1814. var y = v.y;
  1815. var z = v.z;
  1816. var qs = this.s;
  1817. var qx = this.x;
  1818. var qy = this.y;
  1819. var qz = this.z;
  1820. t *= 0.5;
  1821. var ns = (-x * qx - y * qy - z * qz) * t;
  1822. var nx = (x * qs + y * qz - z * qy) * t;
  1823. var ny = (-x * qz + y * qs + z * qx) * t;
  1824. var nz = (x * qy - y * qx + z * qs) * t;
  1825. qs += ns;
  1826. qx += nx;
  1827. qy += ny;
  1828. qz += nz;
  1829. var s = 1 / OIMO.sqrt(qs * qs + qx * qx + qy * qy + qz * qz);
  1830. this.s = qs * s;
  1831. this.x = qx * s;
  1832. this.y = qy * s;
  1833. this.z = qz * s;
  1834. return this;
  1835. },
  1836. sub: function (q1, q2) {
  1837. this.s = q1.s - q2.s;
  1838. this.x = q1.x - q2.x;
  1839. this.y = q1.y - q2.y;
  1840. this.z = q1.z - q2.z;
  1841. return this;
  1842. },
  1843. scale: function (q, s) {
  1844. this.s = q.s * s;
  1845. this.x = q.x * s;
  1846. this.y = q.y * s;
  1847. this.z = q.z * s;
  1848. return this;
  1849. },
  1850. mul: function (q1, q2) {
  1851. var ax = q1.x, ay = q1.y, az = q1.z, as = q1.s,
  1852. bx = q2.x, by = q2.y, bz = q2.z, bs = q2.s;
  1853. this.x = ax * bs + as * bx + ay * bz - az * by;
  1854. this.y = ay * bs + as * by + az * bx - ax * bz;
  1855. this.z = az * bs + as * bz + ax * by - ay * bx;
  1856. this.s = as * bs - ax * bx - ay * by - az * bz;
  1857. return this;
  1858. },
  1859. arc: function (v1, v2) {
  1860. var x1 = v1.x;
  1861. var y1 = v1.y;
  1862. var z1 = v1.z;
  1863. var x2 = v2.x;
  1864. var y2 = v2.y;
  1865. var z2 = v2.z;
  1866. var d = x1 * x2 + y1 * y2 + z1 * z2;
  1867. if (d == -1) {
  1868. x2 = y1 * x1 - z1 * z1;
  1869. y2 = -z1 * y1 - x1 * x1;
  1870. z2 = x1 * z1 + y1 * y1;
  1871. d = 1 / OIMO.sqrt(x2 * x2 + y2 * y2 + z2 * z2);
  1872. this.s = 0;
  1873. this.x = x2 * d;
  1874. this.y = y2 * d;
  1875. this.z = z2 * d;
  1876. return this;
  1877. }
  1878. var cx = y1 * z2 - z1 * y2;
  1879. var cy = z1 * x2 - x1 * z2;
  1880. var cz = x1 * y2 - y1 * x2;
  1881. this.s = OIMO.sqrt((1 + d) * 0.5);
  1882. d = 0.5 / this.s;
  1883. this.x = cx * d;
  1884. this.y = cy * d;
  1885. this.z = cz * d;
  1886. return this;
  1887. },
  1888. normalize: function (q) {
  1889. var len = OIMO.sqrt(q.s * q.s + q.x * q.x + q.y * q.y + q.z * q.z);
  1890. if (len > 0) { len = 1 / len; }
  1891. this.s = q.s * len;
  1892. this.x = q.x * len;
  1893. this.y = q.y * len;
  1894. this.z = q.z * len;
  1895. return this;
  1896. },
  1897. invert: function (q) {
  1898. this.s = q.s;
  1899. this.x = -q.x;
  1900. this.y = -q.y;
  1901. this.z = -q.z;
  1902. return this;
  1903. },
  1904. length: function () {
  1905. return OIMO.sqrt(this.s * this.s + this.x * this.x + this.y * this.y + this.z * this.z);
  1906. },
  1907. copy: function (q) {
  1908. this.s = q.s;
  1909. this.x = q.x;
  1910. this.y = q.y;
  1911. this.z = q.z;
  1912. return this;
  1913. },
  1914. testDiff: function (q) {
  1915. if (this.s !== q.s || this.x !== q.x || this.y !== q.y || this.z !== q.z) return true;
  1916. else return false;
  1917. },
  1918. clone: function (q) {
  1919. return new OIMO.Quat(this.s, this.x, this.y, this.z);
  1920. },
  1921. toString: function () {
  1922. return "Quat[" + this.s.toFixed(4) + ", (" + this.x.toFixed(4) + ", " + this.y.toFixed(4) + ", " + this.z.toFixed(4) + ")]";
  1923. }
  1924. }
  1925. // for three easy export
  1926. OIMO.Quaternion = function (x, y, z, w) {
  1927. this.x = x || 0;
  1928. this.y = y || 0;
  1929. this.z = z || 0;
  1930. this.w = (w !== undefined) ? w : 1;
  1931. };
  1932. OIMO.Quaternion.prototype = {
  1933. constructor: OIMO.Quaternion,
  1934. setFromRotationMatrix: function (m) {
  1935. // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm
  1936. // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)
  1937. var te = m.elements,
  1938. m11 = te[0], m12 = te[1], m13 = te[2],
  1939. m21 = te[3], m22 = te[4], m23 = te[5],
  1940. m31 = te[6], m32 = te[7], m33 = te[8],
  1941. trace = m11 + m22 + m33,
  1942. s;
  1943. if (trace > 0) {
  1944. s = 0.5 / OIMO.sqrt(trace + 1.0);
  1945. this.w = 0.25 / s;
  1946. this.x = (m32 - m23) * s;
  1947. this.y = (m13 - m31) * s;
  1948. this.z = (m21 - m12) * s;
  1949. } else if (m11 > m22 && m11 > m33) {
  1950. s = 2.0 * OIMO.sqrt(1.0 + m11 - m22 - m33);
  1951. this.w = (m32 - m23) / s;
  1952. this.x = 0.25 * s;
  1953. this.y = (m12 + m21) / s;
  1954. this.z = (m13 + m31) / s;
  1955. } else if (m22 > m33) {
  1956. s = 2.0 * OIMO.sqrt(1.0 + m22 - m11 - m33);
  1957. this.w = (m13 - m31) / s;
  1958. this.x = (m12 + m21) / s;
  1959. this.y = 0.25 * s;
  1960. this.z = (m23 + m32) / s;
  1961. } else {
  1962. s = 2.0 * OIMO.sqrt(1.0 + m33 - m11 - m22);
  1963. this.w = (m21 - m12) / s;
  1964. this.x = (m13 + m31) / s;
  1965. this.y = (m23 + m32) / s;
  1966. this.z = 0.25 * s;
  1967. }
  1968. //this.onChangeCallback();
  1969. return this;
  1970. }
  1971. }
  1972. OIMO.Vec3 = function (x, y, z) {
  1973. this.x = x || 0;
  1974. this.y = y || 0;
  1975. this.z = z || 0;
  1976. };
  1977. OIMO.Vec3.prototype = {
  1978. constructor: OIMO.Vec3,
  1979. init: function (x, y, z) {
  1980. this.x = x || 0;
  1981. this.y = y || 0;
  1982. this.z = z || 0;
  1983. return this;
  1984. },
  1985. set: function (x, y, z) {
  1986. this.x = x;
  1987. this.y = y;
  1988. this.z = z;
  1989. return this;
  1990. },
  1991. add: function (v1, v2) {
  1992. this.x = v1.x + v2.x;
  1993. this.y = v1.y + v2.y;
  1994. this.z = v1.z + v2.z;
  1995. return this;
  1996. },
  1997. addEqual: function (v) {
  1998. this.x += v.x;
  1999. this.y += v.y;
  2000. this.z += v.z;
  2001. return this;
  2002. },
  2003. addTime: function (v, t) {
  2004. this.x += v.x * t;
  2005. this.y += v.y * t;
  2006. this.z += v.z * t;
  2007. return this;
  2008. },
  2009. sub: function (v1, v2) {
  2010. this.x = v1.x - v2.x;
  2011. this.y = v1.y - v2.y;
  2012. this.z = v1.z - v2.z;
  2013. return this;
  2014. },
  2015. subEqual: function (v) {
  2016. this.x -= v.x;
  2017. this.y -= v.y;
  2018. this.z -= v.z;
  2019. return this;
  2020. },
  2021. addScale: function (v, s) {
  2022. this.x += v.x * s;
  2023. this.y += v.y * s;
  2024. this.z += v.z * s;
  2025. return this;
  2026. },
  2027. scale: function (v, s) {
  2028. this.x = v.x * s;
  2029. this.y = v.y * s;
  2030. this.z = v.z * s;
  2031. return this;
  2032. },
  2033. scaleEqual: function (s) {
  2034. this.x *= s;
  2035. this.y *= s;
  2036. this.z *= s;
  2037. return this;
  2038. },
  2039. /*dot: function(v){
  2040. return this.x*v.x+this.y*v.y+this.z*v.z;
  2041. },*/
  2042. cross: function (v1, v2) {
  2043. var ax = v1.x, ay = v1.y, az = v1.z,
  2044. bx = v2.x, by = v2.y, bz = v2.z;
  2045. this.x = ay * bz - az * by;
  2046. this.y = az * bx - ax * bz;
  2047. this.z = ax * by - ay * bx;
  2048. return this;
  2049. },
  2050. mul: function (o, v, m) {
  2051. var te = m.elements;
  2052. this.x = o.x + v.x * te[0] + v.y * te[1] + v.z * te[2];
  2053. this.y = o.y + v.x * te[3] + v.y * te[4] + v.z * te[5];
  2054. this.z = o.z + v.x * te[6] + v.y * te[7] + v.z * te[8];
  2055. return this;
  2056. },
  2057. mulMat: function (m, v) {
  2058. var te = m.elements;
  2059. this.x = te[0] * v.x + te[1] * v.y + te[2] * v.z;
  2060. this.y = te[3] * v.x + te[4] * v.y + te[5] * v.z;
  2061. this.z = te[6] * v.x + te[7] * v.y + te[8] * v.z;
  2062. return this;
  2063. },
  2064. normalize: function (v) {
  2065. var x = v.x, y = v.y, z = v.z;
  2066. var l = x * x + y * y + z * z;
  2067. if (l > 0) {
  2068. l = 1 / OIMO.sqrt(l);
  2069. this.x = x * l;
  2070. this.y = y * l;
  2071. this.z = z * l;
  2072. }
  2073. return this;
  2074. },
  2075. /*norm: function(){
  2076. var x = this.x, y = this.y, z = this.z;
  2077. var l = x*x + y*y + z*z;
  2078. if (l > 0) {
  2079. l = 1 / OIMO.sqrt(l);
  2080. this.x = x*l;
  2081. this.y = y*l;
  2082. this.z = z*l;
  2083. }
  2084. return this;
  2085. },*/
  2086. invert: function (v) {
  2087. this.x = -v.x;
  2088. this.y = -v.y;
  2089. this.z = -v.z;
  2090. return this;
  2091. },
  2092. /*length: function(){
  2093. var x = this.x, y = this.y, z = this.z;
  2094. return OIMO.sqrt(x*x + y*y + z*z);
  2095. },*/
  2096. negate: function () {
  2097. this.x = -this.x;
  2098. this.y = -this.y;
  2099. this.z = -this.z;
  2100. return this;
  2101. },
  2102. dot: function (v) {
  2103. return this.x * v.x + this.y * v.y + this.z * v.z;
  2104. },
  2105. lengthSq: function () {
  2106. return this.x * this.x + this.y * this.y + this.z * this.z;
  2107. },
  2108. length: function () {
  2109. return OIMO.sqrt(this.x * this.x + this.y * this.y + this.z * this.z);
  2110. },
  2111. /*len: function(){
  2112. var x = this.x, y = this.y, z = this.z;
  2113. return x*x + y*y + z*z;
  2114. },*/
  2115. copy: function (v) {
  2116. this.x = v.x;
  2117. this.y = v.y;
  2118. this.z = v.z;
  2119. return this;
  2120. },
  2121. applyQuaternion: function (q) {
  2122. var x = this.x;
  2123. var y = this.y;
  2124. var z = this.z;
  2125. var qx = q.x;
  2126. var qy = q.y;
  2127. var qz = q.z;
  2128. var qs = q.s;
  2129. // calculate quat * vector
  2130. var ix = qs * x + qy * z - qz * y;
  2131. var iy = qs * y + qz * x - qx * z;
  2132. var iz = qs * z + qx * y - qy * x;
  2133. var iw = -qx * x - qy * y - qz * z;
  2134. // calculate result * inverse quat
  2135. this.x = ix * qs + iw * -qx + iy * -qz - iz * -qy;
  2136. this.y = iy * qs + iw * -qy + iz * -qx - ix * -qz;
  2137. this.z = iz * qs + iw * -qz + ix * -qy - iy * -qx;
  2138. return this;
  2139. },
  2140. testZero: function () {
  2141. if (this.x !== 0 || this.y !== 0 || this.z !== 0) return true;
  2142. else return false;
  2143. },
  2144. testDiff: function (v) {
  2145. return ((v.x !== this.x) || (v.y !== this.y) || (v.z !== this.z));
  2146. //if(this.x!==v.x || this.y!==v.y || this.z!==v.z) return true;
  2147. //else return false;
  2148. },
  2149. equals: function (v) {
  2150. return ((v.x === this.x) && (v.y === this.y) && (v.z === this.z));
  2151. },
  2152. clone: function () {
  2153. return new this.constructor(this.x, this.y, this.z);
  2154. },
  2155. toString: function () {
  2156. return "Vec3[" + this.x.toFixed(4) + ", " + this.y.toFixed(4) + ", " + this.z.toFixed(4) + "]";
  2157. },
  2158. multiplyScalar: function (scalar) {
  2159. if (isFinite(scalar)) {
  2160. this.x *= scalar;
  2161. this.y *= scalar;
  2162. this.z *= scalar;
  2163. } else {
  2164. this.x = 0;
  2165. this.y = 0;
  2166. this.z = 0;
  2167. }
  2168. return this;
  2169. },
  2170. divideScalar: function (scalar) {
  2171. return this.multiplyScalar(1 / scalar);
  2172. },
  2173. // TODO rename to normalize
  2174. norm: function () {
  2175. return this.divideScalar(this.length());
  2176. },
  2177. }
  2178. OIMO.Euler = function (x, y, z, order) {
  2179. this._x = x || 0;
  2180. this._y = y || 0;
  2181. this._z = z || 0;
  2182. this._order = order || OIMO.Euler.DefaultOrder;
  2183. };
  2184. OIMO.Euler.RotationOrders = ['XYZ', 'YZX', 'ZXY', 'XZY', 'YXZ', 'ZYX'];
  2185. OIMO.Euler.DefaultOrder = 'XYZ';
  2186. OIMO.clamp = function (x, a, b) {
  2187. return (x < a) ? a : ((x > b) ? b : x);
  2188. }
  2189. OIMO.Euler.prototype = {
  2190. constructor: OIMO.Euler,
  2191. _x: 0, _y: 0, _z: 0, _order: OIMO.Euler.DefaultOrder,
  2192. get x() {
  2193. return this._x;
  2194. },
  2195. set x(value) {
  2196. this._x = value;
  2197. this.onChangeCallback();
  2198. },
  2199. get y() {
  2200. return this._y;
  2201. },
  2202. set y(value) {
  2203. this._y = value;
  2204. this.onChangeCallback();
  2205. },
  2206. get z() {
  2207. return this._z;
  2208. },
  2209. set z(value) {
  2210. this._z = value;
  2211. this.onChangeCallback();
  2212. },
  2213. get order() {
  2214. return this._order;
  2215. },
  2216. set order(value) {
  2217. this._order = value;
  2218. this.onChangeCallback();
  2219. },
  2220. set: function (x, y, z, order) {
  2221. this._x = x;
  2222. this._y = y;
  2223. this._z = z;
  2224. this._order = order || this._order;
  2225. this.onChangeCallback();
  2226. return this;
  2227. },
  2228. copy: function (euler) {
  2229. this._x = euler._x;
  2230. this._y = euler._y;
  2231. this._z = euler._z;
  2232. this._order = euler._order;
  2233. this.onChangeCallback();
  2234. return this;
  2235. },
  2236. setFromRotationMatrix: function (m, order) {
  2237. var clamp = OIMO.clamp;
  2238. // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)
  2239. var te = m.elements;
  2240. /*var m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ];
  2241. var m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ];
  2242. var m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ];*/
  2243. var m11 = te[0], m12 = te[1], m13 = te[2],
  2244. m21 = te[3], m22 = te[4], m23 = te[5],
  2245. m31 = te[6], m32 = te[7], m33 = te[8];
  2246. order = order || this._order;
  2247. if (order === 'XYZ') {
  2248. this._y = OIMO.asin(clamp(m13, -1, 1));
  2249. if (OIMO.abs(m13) < 0.99999) {
  2250. this._x = OIMO.atan2(-m23, m33);
  2251. this._z = OIMO.atan2(-m12, m11);
  2252. } else {
  2253. this._x = OIMO.atan2(m32, m22);
  2254. this._z = 0;
  2255. }
  2256. } else if (order === 'YXZ') {
  2257. this._x = OIMO.asin(-clamp(m23, -1, 1));
  2258. if (OIMO.abs(m23) < 0.99999) {
  2259. this._y = OIMO.atan2(m13, m33);
  2260. this._z = OIMO.atan2(m21, m22);
  2261. } else {
  2262. this._y = OIMO.atan2(-m31, m11);
  2263. this._z = 0;
  2264. }
  2265. } else if (order === 'ZXY') {
  2266. this._x = OIMO.asin(clamp(m32, -1, 1));
  2267. if (OIMO.abs(m32) < 0.99999) {
  2268. this._y = OIMO.atan2(-m31, m33);
  2269. this._z = OIMO.atan2(-m12, m22);
  2270. } else {
  2271. this._y = 0;
  2272. this._z = OIMO.atan2(m21, m11);
  2273. }
  2274. } else if (order === 'ZYX') {
  2275. this._y = OIMO.asin(-clamp(m31, -1, 1));
  2276. if (OIMO.abs(m31) < 0.99999) {
  2277. this._x = OIMO.atan2(m32, m33);
  2278. this._z = OIMO.atan2(m21, m11);
  2279. } else {
  2280. this._x = 0;
  2281. this._z = OIMO.atan2(-m12, m22);
  2282. }
  2283. } else if (order === 'YZX') {
  2284. this._z = OIMO.asin(clamp(m21, -1, 1));
  2285. if (OIMO.abs(m21) < 0.99999) {
  2286. this._x = OIMO.atan2(-m23, m22);
  2287. this._y = OIMO.atan2(-m31, m11);
  2288. } else {
  2289. this._x = 0;
  2290. this._y = OIMO.atan2(m13, m33);
  2291. }
  2292. } else if (order === 'XZY') {
  2293. this._z = OIMO.asin(-clamp(m12, -1, 1));
  2294. if (OIMO.abs(m12) < 0.99999) {
  2295. this._x = OIMO.atan2(m32, m22);
  2296. this._y = OIMO.atan2(m13, m11);
  2297. } else {
  2298. this._x = OIMO.atan2(-m23, m33);
  2299. this._y = 0;
  2300. }
  2301. } else {
  2302. console.warn('THREE.Euler: .setFromRotationMatrix() given unsupported order: ' + order)
  2303. }
  2304. this._order = order;
  2305. this.onChangeCallback();
  2306. return this;
  2307. },
  2308. setFromQuaternion: function (q, order, update) {
  2309. var clamp = OIMO.clamp;
  2310. // q is assumed to be normalized
  2311. // http://www.mathworks.com/matlabcentral/fileexchange/20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/content/SpinCalc.m
  2312. var sqx = q.x * q.x;
  2313. var sqy = q.y * q.y;
  2314. var sqz = q.z * q.z;
  2315. var sqw = q.s * q.s;
  2316. order = order || this._order;
  2317. if (order === 'XYZ') {
  2318. this._x = OIMO.atan2(2 * (q.x * q.s - q.y * q.z), (sqw - sqx - sqy + sqz));
  2319. this._y = OIMO.asin(clamp(2 * (q.x * q.z + q.y * q.s), -1, 1));
  2320. this._z = OIMO.atan2(2 * (q.z * q.s - q.x * q.y), (sqw + sqx - sqy - sqz));
  2321. } else if (order === 'YXZ') {
  2322. this._x = OIMO.asin(clamp(2 * (q.x * q.s - q.y * q.z), -1, 1));
  2323. this._y = OIMO.atan2(2 * (q.x * q.z + q.y * q.s), (sqw - sqx - sqy + sqz));
  2324. this._z = OIMO.atan2(2 * (q.x * q.y + q.z * q.s), (sqw - sqx + sqy - sqz));
  2325. } else if (order === 'ZXY') {
  2326. this._x = OIMO.asin(clamp(2 * (q.x * q.s + q.y * q.z), -1, 1));
  2327. this._y = OIMO.atan2(2 * (q.y * q.s - q.z * q.x), (sqw - sqx - sqy + sqz));
  2328. this._z = OIMO.atan2(2 * (q.z * q.s - q.x * q.y), (sqw - sqx + sqy - sqz));
  2329. } else if (order === 'ZYX') {
  2330. this._x = OIMO.atan2(2 * (q.x * q.s + q.z * q.y), (sqw - sqx - sqy + sqz));
  2331. this._y = OIMO.asin(clamp(2 * (q.y * q.s - q.x * q.z), -1, 1));
  2332. this._z = OIMO.atan2(2 * (q.x * q.y + q.z * q.s), (sqw + sqx - sqy - sqz));
  2333. } else if (order === 'YZX') {
  2334. this._x = OIMO.atan2(2 * (q.x * q.s - q.z * q.y), (sqw - sqx + sqy - sqz));
  2335. this._y = OIMO.atan2(2 * (q.y * q.s - q.x * q.z), (sqw + sqx - sqy - sqz));
  2336. this._z = OIMO.asin(clamp(2 * (q.x * q.y + q.z * q.s), -1, 1));
  2337. } else if (order === 'XZY') {
  2338. this._x = OIMO.atan2(2 * (q.x * q.s + q.y * q.z), (sqw - sqx + sqy - sqz));
  2339. this._y = OIMO.atan2(2 * (q.x * q.z + q.y * q.s), (sqw + sqx - sqy - sqz));
  2340. this._z = OIMO.asin(clamp(2 * (q.z * q.s - q.x * q.y), -1, 1));
  2341. } else {
  2342. console.warn('OIMO.Euler: .setFromQuaternion() given unsupported order: ' + order)
  2343. }
  2344. this._order = order;
  2345. if (update !== false) this.onChangeCallback();
  2346. return this;
  2347. },
  2348. reorder: function () {
  2349. // WARNING: this discards revolution information -bhouston
  2350. var q = new OIMO.Quat();
  2351. return function (newOrder) {
  2352. q.setFromEuler(this);
  2353. this.setFromQuaternion(q, newOrder);
  2354. };
  2355. }(),
  2356. equals: function (euler) {
  2357. return (euler._x === this._x) && (euler._y === this._y) && (euler._z === this._z) && (euler._order === this._order);
  2358. },
  2359. fromArray: function (array) {
  2360. this._x = array[0];
  2361. this._y = array[1];
  2362. this._z = array[2];
  2363. if (array[3] !== undefined) this._order = array[3];
  2364. this.onChangeCallback();
  2365. return this;
  2366. },
  2367. toArray: function () {
  2368. return [this._x, this._y, this._z, this._order];
  2369. },
  2370. onChange: function (callback) {
  2371. this.onChangeCallback = callback;
  2372. return this;
  2373. },
  2374. onChangeCallback: function () { },
  2375. clone: function () {
  2376. return new OIMO.Euler(this._x, this._y, this._z, this._order);
  2377. }
  2378. };
  2379. OIMO.EulerToAxis = function (ox, oy, oz) {// angles in radians
  2380. var c1 = OIMO.cos(oy * 0.5);//heading
  2381. var s1 = OIMO.sin(oy * 0.5);
  2382. var c2 = OIMO.cos(oz * 0.5);//altitude
  2383. var s2 = OIMO.sin(oz * 0.5);
  2384. var c3 = OIMO.cos(ox * 0.5);//bank
  2385. var s3 = OIMO.sin(ox * 0.5);
  2386. var c1c2 = c1 * c2;
  2387. var s1s2 = s1 * s2;
  2388. var w = c1c2 * c3 - s1s2 * s3;
  2389. var x = c1c2 * s3 + s1s2 * c3;
  2390. var y = s1 * c2 * c3 + c1 * s2 * s3;
  2391. var z = c1 * s2 * c3 - s1 * c2 * s3;
  2392. var angle = 2 * OIMO.acos(w);
  2393. var norm = x * x + y * y + z * z;
  2394. if (norm < 0.001) {
  2395. x = 1;
  2396. y = z = 0;
  2397. } else {
  2398. norm = OIMO.sqrt(norm);
  2399. x /= norm;
  2400. y /= norm;
  2401. z /= norm;
  2402. }
  2403. return [angle, x, y, z];
  2404. }
  2405. OIMO.EulerToMatrix = function (ox, oy, oz) {// angles in radians
  2406. var ch = OIMO.cos(oy);//heading
  2407. var sh = OIMO.sin(oy);
  2408. var ca = OIMO.cos(oz);//altitude
  2409. var sa = OIMO.sin(oz);
  2410. var cb = OIMO.cos(ox);//bank
  2411. var sb = OIMO.sin(ox);
  2412. var mtx = new OIMO.Mat33();
  2413. var te = mtx.elements;
  2414. te[0] = ch * ca;
  2415. te[1] = sh * sb - ch * sa * cb;
  2416. te[2] = ch * sa * sb + sh * cb;
  2417. te[3] = sa;
  2418. te[4] = ca * cb;
  2419. te[5] = -ca * sb;
  2420. te[6] = -sh * ca;
  2421. te[7] = sh * sa * cb + ch * sb;
  2422. te[8] = -sh * sa * sb + ch * cb;
  2423. return mtx;
  2424. }
  2425. OIMO.MatrixToEuler = function (mtx) {// angles in radians
  2426. var te = mtx.elements;
  2427. var x, y, z;
  2428. if (te[3] > 0.998) { // singularity at north pole
  2429. y = OIMO.atan2(te[2], te[8]);
  2430. z = OIMO.PI / 2;
  2431. x = 0;
  2432. } else if (te[3] < -0.998) { // singularity at south pole
  2433. y = OIMO.atan2(te[2], te[8]);
  2434. z = -OIMO.PI / 2;
  2435. x = 0;
  2436. } else {
  2437. y = OIMO.atan2(-te[6], te[0]);
  2438. x = OIMO.atan2(-te[5], te[4]);
  2439. z = OIMO.asin(te[3]);
  2440. }
  2441. return [x, y, z];
  2442. }
  2443. OIMO.unwrapDegrees = function (r) {
  2444. r = r % 360;
  2445. if (r > 180) r -= 360;
  2446. if (r < -180) r += 360;
  2447. return r;
  2448. }
  2449. OIMO.unwrapRadian = function (r) {
  2450. r = r % OIMO.TwoPI;
  2451. if (r > OIMO.PI) r -= OIMO.TwoPI;
  2452. if (r < -OIMO.PI) r += OIMO.TwoPI;
  2453. return r;
  2454. }
  2455. OIMO.Distance3d = function (p1, p2) {
  2456. var xd = p2[0] - p1[0];
  2457. var yd = p2[1] - p1[1];
  2458. var zd = p2[2] - p1[2];
  2459. return OIMO.sqrt(xd * xd + yd * yd + zd * zd);
  2460. }
  2461. /**
  2462. * The base class of all type of the constraints.
  2463. * @author saharan
  2464. */
  2465. OIMO.Constraint = function () {
  2466. // The parent world of the constraint.
  2467. this.parent = null;
  2468. // The first body of the constraint.
  2469. this.body1 = null;
  2470. // The second body of the constraint.
  2471. this.body2 = null;
  2472. // Internal
  2473. this.addedToIsland = false;
  2474. }
  2475. OIMO.Constraint.prototype = {
  2476. constructor: OIMO.Constraint,
  2477. /**
  2478. * Prepare for solving the constraint.
  2479. * @param timeStep
  2480. * @param invTimeStep
  2481. */
  2482. preSolve: function (timeStep, invTimeStep) {
  2483. OIMO.Error("Constraint", "Inheritance error.");
  2484. },
  2485. /**
  2486. * Solve the constraint.
  2487. * This is usually called iteratively.
  2488. */
  2489. solve: function () {
  2490. OIMO.Error("Constraint", "Inheritance error.");
  2491. },
  2492. /**
  2493. * Do the post-processing.
  2494. */
  2495. postSolve: function () {
  2496. OIMO.Error("Constraint", "Inheritance error.");
  2497. }
  2498. }
  2499. /**
  2500. * Joints are used to constrain the motion between two rigid bodies.
  2501. * @author saharan
  2502. * @author lo-th
  2503. */
  2504. OIMO.Joint = function (config) {
  2505. OIMO.Constraint.call(this);
  2506. // joint name
  2507. this.name = "";
  2508. // The type of the joint.
  2509. this.type = OIMO.JOINT_NULL;
  2510. // The previous joint in the world.
  2511. this.prev = null;
  2512. // The next joint in the world.
  2513. this.next = null;
  2514. this.body1 = config.body1;
  2515. this.body2 = config.body2;
  2516. // The anchor point on the first rigid body in local coordinate system.
  2517. this.localAnchorPoint1 = new OIMO.Vec3().copy(config.localAnchorPoint1);
  2518. // The anchor point on the second rigid body in local coordinate system.
  2519. this.localAnchorPoint2 = new OIMO.Vec3().copy(config.localAnchorPoint2);
  2520. // The anchor point on the first rigid body in world coordinate system relative to the body's origin.
  2521. this.relativeAnchorPoint1 = new OIMO.Vec3();
  2522. // The anchor point on the second rigid body in world coordinate system relative to the body's origin.
  2523. this.relativeAnchorPoint2 = new OIMO.Vec3();
  2524. // The anchor point on the first rigid body in world coordinate system.
  2525. this.anchorPoint1 = new OIMO.Vec3();
  2526. // The anchor point on the second rigid body in world coordinate system.
  2527. this.anchorPoint2 = new OIMO.Vec3();
  2528. // Whether allow collision between connected rigid bodies or not.
  2529. this.allowCollision = config.allowCollision;
  2530. this.b1Link = new OIMO.JointLink(this);
  2531. this.b2Link = new OIMO.JointLink(this);
  2532. this.matrix = new OIMO.Mat44();
  2533. };
  2534. OIMO.Joint.prototype = Object.create(OIMO.Constraint.prototype);
  2535. OIMO.Joint.prototype.constructor = OIMO.Joint;
  2536. // Update all the anchor points.
  2537. OIMO.Joint.prototype.updateAnchorPoints = function () {
  2538. this.relativeAnchorPoint1.mulMat(this.body1.rotation, this.localAnchorPoint1);
  2539. this.relativeAnchorPoint2.mulMat(this.body2.rotation, this.localAnchorPoint2);
  2540. this.anchorPoint1.add(this.relativeAnchorPoint1, this.body1.position);
  2541. this.anchorPoint2.add(this.relativeAnchorPoint2, this.body2.position);
  2542. };
  2543. // Attach the joint from the bodies.
  2544. OIMO.Joint.prototype.attach = function () {
  2545. this.b1Link.body = this.body2;
  2546. this.b2Link.body = this.body1;
  2547. if (this.body1.jointLink != null) (this.b1Link.next = this.body1.jointLink).prev = this.b1Link;
  2548. else this.b1Link.next = null;
  2549. this.body1.jointLink = this.b1Link;
  2550. this.body1.numJoints++;
  2551. if (this.body2.jointLink != null) (this.b2Link.next = this.body2.jointLink).prev = this.b2Link;
  2552. else this.b2Link.next = null;
  2553. this.body2.jointLink = this.b2Link;
  2554. this.body2.numJoints++;
  2555. };
  2556. // Detach the joint from the bodies.
  2557. OIMO.Joint.prototype.detach = function () {
  2558. var prev = this.b1Link.prev;
  2559. var next = this.b1Link.next;
  2560. if (prev != null) prev.next = next;
  2561. if (next != null) next.prev = prev;
  2562. if (this.body1.jointLink == this.b1Link) this.body1.jointLink = next;
  2563. this.b1Link.prev = null;
  2564. this.b1Link.next = null;
  2565. this.b1Link.body = null;
  2566. this.body1.numJoints--;
  2567. prev = this.b2Link.prev;
  2568. next = this.b2Link.next;
  2569. if (prev != null) prev.next = next;
  2570. if (next != null) next.prev = prev;
  2571. if (this.body2.jointLink == this.b2Link) this.body2.jointLink = next;
  2572. this.b2Link.prev = null;
  2573. this.b2Link.next = null;
  2574. this.b2Link.body = null;
  2575. this.body2.numJoints--;
  2576. this.b1Link.body = null;
  2577. this.b2Link.body = null;
  2578. };
  2579. // Awake the bodies.
  2580. OIMO.Joint.prototype.awake = function () {
  2581. this.body1.awake();
  2582. this.body2.awake();
  2583. };
  2584. // calculation function
  2585. OIMO.Joint.prototype.preSolve = function (timeStep, invTimeStep) {
  2586. };
  2587. OIMO.Joint.prototype.solve = function () {
  2588. };
  2589. OIMO.Joint.prototype.postSolve = function () {
  2590. };
  2591. // Delete process
  2592. OIMO.Joint.prototype.remove = function () {
  2593. this.dispose();
  2594. };
  2595. OIMO.Joint.prototype.dispose = function () {
  2596. this.parent.removeJoint(this);
  2597. };
  2598. // Three js add
  2599. OIMO.Joint.prototype.getPosition = function () {
  2600. var p1 = new OIMO.Vec3().scale(this.anchorPoint1, OIMO.WORLD_SCALE);
  2601. var p2 = new OIMO.Vec3().scale(this.anchorPoint2, OIMO.WORLD_SCALE);
  2602. return [p1, p2];
  2603. };
  2604. OIMO.Joint.prototype.getMatrix = function () {
  2605. var m = this.matrix.elements;
  2606. var p1 = this.anchorPoint1;
  2607. var p2 = this.anchorPoint2;
  2608. m[0] = p1.x * OIMO.WORLD_SCALE;
  2609. m[1] = p1.y * OIMO.WORLD_SCALE;
  2610. m[2] = p1.z * OIMO.WORLD_SCALE;
  2611. m[3] = 0;
  2612. m[4] = p2.x * OIMO.WORLD_SCALE;
  2613. m[5] = p2.y * OIMO.WORLD_SCALE;
  2614. m[6] = p2.z * OIMO.WORLD_SCALE;
  2615. m[7] = 0;
  2616. return m;
  2617. };
  2618. /**
  2619. * A joint configuration holds all configuration data for constructing a joint.
  2620. * Joint configurations can be reused safely.
  2621. * @author saharan
  2622. */
  2623. OIMO.JointConfig = function () {
  2624. // The first rigid body of the joint.
  2625. this.body1 = null;
  2626. // The second rigid body of the joint.
  2627. this.body2 = null;
  2628. // The anchor point on the first rigid body in local coordinate system.
  2629. this.localAnchorPoint1 = new OIMO.Vec3();
  2630. // The anchor point on the second rigid body in local coordinate system.
  2631. this.localAnchorPoint2 = new OIMO.Vec3();
  2632. // The axis in the first body's coordinate system.
  2633. // his property is available in some joints.
  2634. this.localAxis1 = new OIMO.Vec3();
  2635. // The axis in the second body's coordinate system.
  2636. // This property is available in some joints.
  2637. this.localAxis2 = new OIMO.Vec3();
  2638. // Whether allow collision between connected rigid bodies or not.
  2639. this.allowCollision = false;
  2640. };
  2641. /**
  2642. * A link list of joints.
  2643. * @author saharan
  2644. */
  2645. OIMO.JointLink = function (joint) {
  2646. // The previous joint link.
  2647. this.prev = null;
  2648. // The next joint link.
  2649. this.next = null;
  2650. // The other rigid body connected to the joint.
  2651. this.body = null;
  2652. // The joint of the link.
  2653. this.joint = joint;
  2654. };
  2655. /**
  2656. * An information of limit and motor.
  2657. * @author saharan
  2658. */
  2659. OIMO.LimitMotor = function (axis, fixed) {
  2660. fixed = fixed || false;
  2661. // The axis of the constraint.
  2662. this.axis = axis;
  2663. // The current angle for rotational constraints.
  2664. this.angle = 0;
  2665. // The lower limit. Set lower > upper to disable
  2666. this.lowerLimit = fixed ? 0 : 1;
  2667. //if(fixed)this.lowerLimit = 0;
  2668. //else this.lowerLimit = 1;
  2669. // The upper limit. Set lower > upper to disable.
  2670. this.upperLimit = 0;
  2671. // The target motor speed.
  2672. this.motorSpeed = 0;
  2673. // The maximum motor force or torque. Set 0 to disable.
  2674. this.maxMotorForce = 0;
  2675. // The frequency of the spring. Set 0 to disable.
  2676. this.frequency = 0;
  2677. // The damping ratio of the spring. Set 0 for no damping, 1 for critical damping.
  2678. this.dampingRatio = 0;
  2679. };
  2680. OIMO.LimitMotor.prototype = {
  2681. constructor: OIMO.LimitMotor,
  2682. /**
  2683. * Set limit data into this constraint.
  2684. * @param lowerLimit
  2685. * @param upperLimit
  2686. */
  2687. setLimit: function (lowerLimit, upperLimit) {
  2688. this.lowerLimit = lowerLimit;
  2689. this.upperLimit = upperLimit;
  2690. },
  2691. /**
  2692. * Set motor data into this constraint.
  2693. * @param motorSpeed
  2694. * @param maxMotorForce
  2695. */
  2696. setMotor: function (motorSpeed, maxMotorForce) {
  2697. this.motorSpeed = motorSpeed;
  2698. this.maxMotorForce = maxMotorForce;
  2699. },
  2700. /**
  2701. * Set spring data into this constraint.
  2702. * @param frequency
  2703. * @param dampingRatio
  2704. */
  2705. setSpring: function (frequency, dampingRatio) {
  2706. this.frequency = frequency;
  2707. this.dampingRatio = dampingRatio;
  2708. }
  2709. };
  2710. /**
  2711. * A ball-and-socket joint limits relative translation on two anchor points on rigid bodies.
  2712. * @author saharan
  2713. * @author lo-th
  2714. */
  2715. OIMO.BallAndSocketJoint = function (config) {
  2716. OIMO.Joint.call(this, config);
  2717. this.type = OIMO.JOINT_BALL_AND_SOCKET;
  2718. this.lc = new OIMO.LinearConstraint(this);
  2719. };
  2720. OIMO.BallAndSocketJoint.prototype = Object.create(OIMO.Joint.prototype);
  2721. OIMO.BallAndSocketJoint.prototype.constructor = OIMO.BallAndSocketJoint;
  2722. OIMO.BallAndSocketJoint.prototype.preSolve = function (timeStep, invTimeStep) {
  2723. this.updateAnchorPoints();
  2724. this.lc.preSolve(timeStep, invTimeStep);
  2725. };
  2726. OIMO.BallAndSocketJoint.prototype.solve = function () {
  2727. this.lc.solve();
  2728. };
  2729. OIMO.BallAndSocketJoint.prototype.postSolve = function () {
  2730. };
  2731. /**
  2732. * A distance joint limits the distance between two anchor points on rigid bodies.
  2733. * @author saharan
  2734. * @author lo-th
  2735. */
  2736. OIMO.DistanceJoint = function (config, minDistance, maxDistance) {
  2737. OIMO.Joint.call(this, config);
  2738. this.type = OIMO.JOINT_DISTANCE;
  2739. this.normal = new OIMO.Vec3();
  2740. this.nr = new OIMO.Vec3();
  2741. // The limit and motor information of the joint.
  2742. this.limitMotor = new OIMO.LimitMotor(this.normal, true);
  2743. this.limitMotor.lowerLimit = minDistance;
  2744. this.limitMotor.upperLimit = maxDistance;
  2745. this.t = new OIMO.TranslationalConstraint(this, this.limitMotor);
  2746. };
  2747. OIMO.DistanceJoint.prototype = Object.create(OIMO.Joint.prototype);
  2748. OIMO.DistanceJoint.prototype.constructor = OIMO.DistanceJoint;
  2749. OIMO.DistanceJoint.prototype.preSolve = function (timeStep, invTimeStep) {
  2750. this.updateAnchorPoints();
  2751. //var nr = this.nr;
  2752. this.nr.sub(this.anchorPoint2, this.anchorPoint1);
  2753. //var len = OIMO.sqrt( nr.x*nr.x + nr.y*nr.y + nr.z*nr.z );
  2754. //if(len>0) len = 1/len;
  2755. //this.normal.scale( nr, len );
  2756. this.normal.normalize(this.nr);
  2757. this.t.preSolve(timeStep, invTimeStep);
  2758. };
  2759. OIMO.DistanceJoint.prototype.solve = function () {
  2760. this.t.solve();
  2761. };
  2762. OIMO.DistanceJoint.prototype.postSolve = function () {
  2763. };
  2764. /**
  2765. * A hinge joint allows only for relative rotation of rigid bodies along the axis.
  2766. * @author saharan
  2767. * @author lo-th
  2768. */
  2769. OIMO.HingeJoint = function (config, lowerAngleLimit, upperAngleLimit) {
  2770. OIMO.Joint.call(this, config);
  2771. this.type = OIMO.JOINT_HINGE;
  2772. // The axis in the first body's coordinate system.
  2773. this.localAxis1 = config.localAxis1.clone().norm();
  2774. // The axis in the second body's coordinate system.
  2775. this.localAxis2 = config.localAxis2.clone().norm();
  2776. // make angle axis 1
  2777. this.localAngle1 = new OIMO.Vec3(
  2778. this.localAxis1.y * this.localAxis1.x - this.localAxis1.z * this.localAxis1.z,
  2779. -this.localAxis1.z * this.localAxis1.y - this.localAxis1.x * this.localAxis1.x,
  2780. this.localAxis1.x * this.localAxis1.z + this.localAxis1.y * this.localAxis1.y
  2781. ).norm();
  2782. // make angle axis 2
  2783. var arc = new OIMO.Mat33().setQuat(new OIMO.Quat().arc(this.localAxis1, this.localAxis2));
  2784. this.localAngle2 = new OIMO.Vec3().mulMat(arc, this.localAngle1);
  2785. this.nor = new OIMO.Vec3();
  2786. this.tan = new OIMO.Vec3();
  2787. this.bin = new OIMO.Vec3();
  2788. this.ax1 = new OIMO.Vec3();
  2789. this.ax2 = new OIMO.Vec3();
  2790. this.an1 = new OIMO.Vec3();
  2791. this.an2 = new OIMO.Vec3();
  2792. // The rotational limit and motor information of the joint.
  2793. this.limitMotor = new OIMO.LimitMotor(this.nor, false);
  2794. this.limitMotor.lowerLimit = lowerAngleLimit;
  2795. this.limitMotor.upperLimit = upperAngleLimit;
  2796. this.lc = new OIMO.LinearConstraint(this);
  2797. this.r3 = new OIMO.Rotational3Constraint(this, this.limitMotor, new OIMO.LimitMotor(this.tan, true), new OIMO.LimitMotor(this.bin, true));
  2798. };
  2799. OIMO.HingeJoint.prototype = Object.create(OIMO.Joint.prototype);
  2800. OIMO.HingeJoint.prototype.constructor = OIMO.HingeJoint;
  2801. OIMO.HingeJoint.prototype.preSolve = function (timeStep, invTimeStep) {
  2802. var tmp1X, tmp1Y, tmp1Z, limite;//, nx, ny, nz, tx, ty, tz, bx, by, bz;
  2803. this.updateAnchorPoints();
  2804. this.ax1.mulMat(this.body1.rotation, this.localAxis1);
  2805. this.ax2.mulMat(this.body2.rotation, this.localAxis2);
  2806. this.an1.mulMat(this.body1.rotation, this.localAngle1);
  2807. this.an2.mulMat(this.body2.rotation, this.localAngle2);
  2808. this.nor.set(
  2809. this.ax1.x * this.body2.inverseMass + this.ax2.x * this.body1.inverseMass,
  2810. this.ax1.y * this.body2.inverseMass + this.ax2.y * this.body1.inverseMass,
  2811. this.ax1.z * this.body2.inverseMass + this.ax2.z * this.body1.inverseMass
  2812. ).norm();
  2813. this.tan.set(
  2814. this.nor.y * this.nor.x - this.nor.z * this.nor.z,
  2815. -this.nor.z * this.nor.y - this.nor.x * this.nor.x,
  2816. this.nor.x * this.nor.z + this.nor.y * this.nor.y
  2817. ).norm();
  2818. this.bin.set(
  2819. this.nor.y * this.tan.z - this.nor.z * this.tan.y,
  2820. this.nor.z * this.tan.x - this.nor.x * this.tan.z,
  2821. this.nor.x * this.tan.y - this.nor.y * this.tan.x
  2822. );
  2823. // calculate hinge angle
  2824. limite = this.acosClamp(this.an1.x * this.an2.x + this.an1.y * this.an2.y + this.an1.z * this.an2.z)
  2825. if (
  2826. this.nor.x * (this.an1.y * this.an2.z - this.an1.z * this.an2.y) +
  2827. this.nor.y * (this.an1.z * this.an2.x - this.an1.x * this.an2.z) +
  2828. this.nor.z * (this.an1.x * this.an2.y - this.an1.y * this.an2.x) < 0
  2829. ) {
  2830. this.limitMotor.angle = -limite;
  2831. } else {
  2832. this.limitMotor.angle = limite;
  2833. }
  2834. tmp1X = this.ax1.y * this.ax2.z - this.ax1.z * this.ax2.y;
  2835. tmp1Y = this.ax1.z * this.ax2.x - this.ax1.x * this.ax2.z;
  2836. tmp1Z = this.ax1.x * this.ax2.y - this.ax1.y * this.ax2.x;
  2837. this.r3.limitMotor2.angle = this.tan.x * tmp1X + this.tan.y * tmp1Y + this.tan.z * tmp1Z;
  2838. this.r3.limitMotor3.angle = this.bin.x * tmp1X + this.bin.y * tmp1Y + this.bin.z * tmp1Z;
  2839. this.r3.preSolve(timeStep, invTimeStep);
  2840. this.lc.preSolve(timeStep, invTimeStep);
  2841. };
  2842. OIMO.HingeJoint.prototype.solve = function () {
  2843. this.r3.solve();
  2844. this.lc.solve();
  2845. };
  2846. OIMO.HingeJoint.prototype.postSolve = function () {
  2847. };
  2848. OIMO.HingeJoint.prototype.acosClamp = function (cos) {
  2849. if (cos > 1) return 0;
  2850. else if (cos < -1) return OIMO.PI;
  2851. else return OIMO.acos(cos);
  2852. };
  2853. /**
  2854. * A prismatic joint allows only for relative translation of rigid bodies along the axis.
  2855. * @author saharan
  2856. * @author lo-th
  2857. */
  2858. OIMO.PrismaticJoint = function (config, lowerTranslation, upperTranslation) {
  2859. OIMO.Joint.call(this, config);
  2860. this.type = OIMO.JOINT_PRISMATIC;
  2861. // The axis in the first body's coordinate system.
  2862. this.localAxis1 = new OIMO.Vec3().normalize(config.localAxis1);
  2863. // The axis in the second body's coordinate system.
  2864. this.localAxis2 = new OIMO.Vec3().normalize(config.localAxis2);
  2865. this.localAxis1X = this.localAxis1.x;
  2866. this.localAxis1Y = this.localAxis1.y;
  2867. this.localAxis1Z = this.localAxis1.z;
  2868. this.localAxis2X = this.localAxis2.x;
  2869. this.localAxis2Y = this.localAxis2.y;
  2870. this.localAxis2Z = this.localAxis2.z;
  2871. this.nor = new OIMO.Vec3();
  2872. this.tan = new OIMO.Vec3();
  2873. this.bin = new OIMO.Vec3();
  2874. this.ac = new OIMO.AngularConstraint(this, new OIMO.Quat().arc(this.localAxis1, this.localAxis2));
  2875. // The translational limit and motor information of the joint.
  2876. this.limitMotor = new OIMO.LimitMotor(this.nor, true);
  2877. this.limitMotor.lowerLimit = lowerTranslation;
  2878. this.limitMotor.upperLimit = upperTranslation;
  2879. this.t3 = new OIMO.Translational3Constraint(this, this.limitMotor, new OIMO.LimitMotor(this.tan, true), new OIMO.LimitMotor(this.bin, true));
  2880. };
  2881. OIMO.PrismaticJoint.prototype = Object.create(OIMO.Joint.prototype);
  2882. OIMO.PrismaticJoint.prototype.constructor = OIMO.PrismaticJoint;
  2883. OIMO.PrismaticJoint.prototype.preSolve = function (timeStep, invTimeStep) {
  2884. var tmpM;
  2885. var tmp1X;
  2886. var tmp1Y;
  2887. var tmp1Z;
  2888. this.updateAnchorPoints();
  2889. tmpM = this.body1.rotation.elements;
  2890. var axis1X = this.localAxis1X * tmpM[0] + this.localAxis1Y * tmpM[1] + this.localAxis1Z * tmpM[2];
  2891. var axis1Y = this.localAxis1X * tmpM[3] + this.localAxis1Y * tmpM[4] + this.localAxis1Z * tmpM[5];
  2892. var axis1Z = this.localAxis1X * tmpM[6] + this.localAxis1Y * tmpM[7] + this.localAxis1Z * tmpM[8];
  2893. tmpM = this.body2.rotation.elements;
  2894. var axis2X = this.localAxis2X * tmpM[0] + this.localAxis2Y * tmpM[1] + this.localAxis2Z * tmpM[2];
  2895. var axis2Y = this.localAxis2X * tmpM[3] + this.localAxis2Y * tmpM[4] + this.localAxis2Z * tmpM[5];
  2896. var axis2Z = this.localAxis2X * tmpM[6] + this.localAxis2Y * tmpM[7] + this.localAxis2Z * tmpM[8];
  2897. var nx = axis1X * this.body2.inverseMass + axis2X * this.body1.inverseMass;
  2898. var ny = axis1Y * this.body2.inverseMass + axis2Y * this.body1.inverseMass;
  2899. var nz = axis1Z * this.body2.inverseMass + axis2Z * this.body1.inverseMass;
  2900. tmp1X = OIMO.sqrt(nx * nx + ny * ny + nz * nz);
  2901. if (tmp1X > 0) tmp1X = 1 / tmp1X;
  2902. nx *= tmp1X;
  2903. ny *= tmp1X;
  2904. nz *= tmp1X;
  2905. var tx = ny * nx - nz * nz;
  2906. var ty = -nz * ny - nx * nx;
  2907. var tz = nx * nz + ny * ny;
  2908. tmp1X = 1 / OIMO.sqrt(tx * tx + ty * ty + tz * tz);
  2909. tx *= tmp1X;
  2910. ty *= tmp1X;
  2911. tz *= tmp1X;
  2912. var bx = ny * tz - nz * ty;
  2913. var by = nz * tx - nx * tz;
  2914. var bz = nx * ty - ny * tx;
  2915. this.nor.init(nx, ny, nz);
  2916. this.tan.init(tx, ty, tz);
  2917. this.bin.init(bx, by, bz);
  2918. this.ac.preSolve(timeStep, invTimeStep);
  2919. this.t3.preSolve(timeStep, invTimeStep);
  2920. };
  2921. OIMO.PrismaticJoint.prototype.solve = function () {
  2922. this.ac.solve();
  2923. this.t3.solve();
  2924. };
  2925. OIMO.PrismaticJoint.prototype.postSolve = function () {
  2926. };
  2927. /**
  2928. * A slider joint allows for relative translation and relative rotation between two rigid bodies along the axis.
  2929. * @author saharan
  2930. * @author lo-th
  2931. */
  2932. OIMO.SliderJoint = function (config, lowerTranslation, upperTranslation) {
  2933. OIMO.Joint.call(this, config);
  2934. this.type = OIMO.JOINT_SLIDER;
  2935. // The first axis in local coordinate system.
  2936. this.localAxis1 = new OIMO.Vec3().normalize(config.localAxis1);
  2937. // The second axis in local coordinate system.
  2938. this.localAxis2 = new OIMO.Vec3().normalize(config.localAxis2);
  2939. var len;
  2940. this.localAxis1X = this.localAxis1.x;
  2941. this.localAxis1Y = this.localAxis1.y;
  2942. this.localAxis1Z = this.localAxis1.z;
  2943. this.localAngAxis1X = this.localAxis1Y * this.localAxis1X - this.localAxis1Z * this.localAxis1Z;
  2944. this.localAngAxis1Y = -this.localAxis1Z * this.localAxis1Y - this.localAxis1X * this.localAxis1X;
  2945. this.localAngAxis1Z = this.localAxis1X * this.localAxis1Z + this.localAxis1Y * this.localAxis1Y;
  2946. len = 1 / OIMO.sqrt(this.localAngAxis1X * this.localAngAxis1X + this.localAngAxis1Y * this.localAngAxis1Y + this.localAngAxis1Z * this.localAngAxis1Z);
  2947. this.localAngAxis1X *= len;
  2948. this.localAngAxis1Y *= len;
  2949. this.localAngAxis1Z *= len;
  2950. this.localAxis2X = this.localAxis2.x;
  2951. this.localAxis2Y = this.localAxis2.y;
  2952. this.localAxis2Z = this.localAxis2.z;
  2953. // make angle axis 2
  2954. var arc = new OIMO.Mat33().setQuat(new OIMO.Quat().arc(this.localAxis1, this.localAxis2));
  2955. var tarc = arc.elements;
  2956. this.localAngAxis2X = this.localAngAxis1X * tarc[0] + this.localAngAxis1Y * tarc[1] + this.localAngAxis1Z * tarc[2];
  2957. this.localAngAxis2Y = this.localAngAxis1X * tarc[3] + this.localAngAxis1Y * tarc[4] + this.localAngAxis1Z * tarc[5];
  2958. this.localAngAxis2Z = this.localAngAxis1X * tarc[6] + this.localAngAxis1Y * tarc[7] + this.localAngAxis1Z * tarc[8];
  2959. this.nor = new OIMO.Vec3();
  2960. this.tan = new OIMO.Vec3();
  2961. this.bin = new OIMO.Vec3();
  2962. // The limit and motor for the rotation
  2963. this.rotationalLimitMotor = new OIMO.LimitMotor(this.nor, false);
  2964. this.r3 = new OIMO.Rotational3Constraint(this, this.rotationalLimitMotor, new OIMO.LimitMotor(this.tan, true), new OIMO.LimitMotor(this.bin, true));
  2965. // The limit and motor for the translation.
  2966. this.translationalLimitMotor = new OIMO.LimitMotor(this.nor, true);
  2967. this.translationalLimitMotor.lowerLimit = lowerTranslation;
  2968. this.translationalLimitMotor.upperLimit = upperTranslation;
  2969. this.t3 = new OIMO.Translational3Constraint(this, this.translationalLimitMotor, new OIMO.LimitMotor(this.tan, true), new OIMO.LimitMotor(this.bin, true));
  2970. };
  2971. OIMO.SliderJoint.prototype = Object.create(OIMO.Joint.prototype);
  2972. OIMO.SliderJoint.prototype.constructor = OIMO.SliderJoint;
  2973. OIMO.SliderJoint.prototype.preSolve = function (timeStep, invTimeStep) {
  2974. var tmpM;
  2975. var tmp1X;
  2976. var tmp1Y;
  2977. var tmp1Z;
  2978. this.updateAnchorPoints();
  2979. tmpM = this.body1.rotation.elements;
  2980. var axis1X = this.localAxis1X * tmpM[0] + this.localAxis1Y * tmpM[1] + this.localAxis1Z * tmpM[2];
  2981. var axis1Y = this.localAxis1X * tmpM[3] + this.localAxis1Y * tmpM[4] + this.localAxis1Z * tmpM[5];
  2982. var axis1Z = this.localAxis1X * tmpM[6] + this.localAxis1Y * tmpM[7] + this.localAxis1Z * tmpM[8];
  2983. var angAxis1X = this.localAngAxis1X * tmpM[0] + this.localAngAxis1Y * tmpM[1] + this.localAngAxis1Z * tmpM[2];
  2984. var angAxis1Y = this.localAngAxis1X * tmpM[3] + this.localAngAxis1Y * tmpM[4] + this.localAngAxis1Z * tmpM[5];
  2985. var angAxis1Z = this.localAngAxis1X * tmpM[6] + this.localAngAxis1Y * tmpM[7] + this.localAngAxis1Z * tmpM[8];
  2986. tmpM = this.body2.rotation.elements;
  2987. var axis2X = this.localAxis2X * tmpM[0] + this.localAxis2Y * tmpM[1] + this.localAxis2Z * tmpM[2];
  2988. var axis2Y = this.localAxis2X * tmpM[3] + this.localAxis2Y * tmpM[4] + this.localAxis2Z * tmpM[5];
  2989. var axis2Z = this.localAxis2X * tmpM[6] + this.localAxis2Y * tmpM[7] + this.localAxis2Z * tmpM[8];
  2990. var angAxis2X = this.localAngAxis2X * tmpM[0] + this.localAngAxis2Y * tmpM[1] + this.localAngAxis2Z * tmpM[2];
  2991. var angAxis2Y = this.localAngAxis2X * tmpM[3] + this.localAngAxis2Y * tmpM[4] + this.localAngAxis2Z * tmpM[5];
  2992. var angAxis2Z = this.localAngAxis2X * tmpM[6] + this.localAngAxis2Y * tmpM[7] + this.localAngAxis2Z * tmpM[8];
  2993. var nx = axis1X * this.body2.inverseMass + axis2X * this.body1.inverseMass;
  2994. var ny = axis1Y * this.body2.inverseMass + axis2Y * this.body1.inverseMass;
  2995. var nz = axis1Z * this.body2.inverseMass + axis2Z * this.body1.inverseMass;
  2996. tmp1X = OIMO.sqrt(nx * nx + ny * ny + nz * nz);
  2997. if (tmp1X > 0) tmp1X = 1 / tmp1X;
  2998. nx *= tmp1X;
  2999. ny *= tmp1X;
  3000. nz *= tmp1X;
  3001. var tx = ny * nx - nz * nz;
  3002. var ty = -nz * ny - nx * nx;
  3003. var tz = nx * nz + ny * ny;
  3004. tmp1X = 1 / OIMO.sqrt(tx * tx + ty * ty + tz * tz);
  3005. tx *= tmp1X;
  3006. ty *= tmp1X;
  3007. tz *= tmp1X;
  3008. var bx = ny * tz - nz * ty;
  3009. var by = nz * tx - nx * tz;
  3010. var bz = nx * ty - ny * tx;
  3011. this.nor.init(nx, ny, nz);
  3012. this.tan.init(tx, ty, tz);
  3013. this.bin.init(bx, by, bz);
  3014. // ----------------------------------------------
  3015. // calculate hinge angle
  3016. // ----------------------------------------------
  3017. if (
  3018. nx * (angAxis1Y * angAxis2Z - angAxis1Z * angAxis2Y) +
  3019. ny * (angAxis1Z * angAxis2X - angAxis1X * angAxis2Z) +
  3020. nz * (angAxis1X * angAxis2Y - angAxis1Y * angAxis2X) < 0
  3021. ) {
  3022. this.rotationalLimitMotor.angle = -this.acosClamp(angAxis1X * angAxis2X + angAxis1Y * angAxis2Y + angAxis1Z * angAxis2Z);
  3023. } else {
  3024. this.rotationalLimitMotor.angle = this.acosClamp(angAxis1X * angAxis2X + angAxis1Y * angAxis2Y + angAxis1Z * angAxis2Z);
  3025. }
  3026. // angular error
  3027. tmp1X = axis1Y * axis2Z - axis1Z * axis2Y;
  3028. tmp1Y = axis1Z * axis2X - axis1X * axis2Z;
  3029. tmp1Z = axis1X * axis2Y - axis1Y * axis2X;
  3030. this.r3.limitMotor2.angle = tx * tmp1X + ty * tmp1Y + tz * tmp1Z;
  3031. this.r3.limitMotor3.angle = bx * tmp1X + by * tmp1Y + bz * tmp1Z;
  3032. this.r3.preSolve(timeStep, invTimeStep);
  3033. this.t3.preSolve(timeStep, invTimeStep);
  3034. };
  3035. OIMO.SliderJoint.prototype.solve = function () {
  3036. this.r3.solve();
  3037. this.t3.solve();
  3038. };
  3039. OIMO.SliderJoint.prototype.postSolve = function () {
  3040. };
  3041. OIMO.SliderJoint.prototype.acosClamp = function (cos) {
  3042. if (cos > 1) return 0;
  3043. else if (cos < -1) return OIMO.PI;
  3044. else return OIMO.acos(cos);
  3045. };
  3046. /**
  3047. * A wheel joint allows for relative rotation between two rigid bodies along two axes.
  3048. * The wheel joint also allows for relative translation for the suspension.
  3049. * @author saharan
  3050. * @author lo-th
  3051. */
  3052. OIMO.WheelJoint = function (config) {
  3053. OIMO.Joint.call(this, config);
  3054. this.type = OIMO.JOINT_WHEEL;
  3055. // The first axis in local coordinate system.
  3056. this.localAxis1 = new OIMO.Vec3().normalize(config.localAxis1);
  3057. // The second axis in local coordinate system.
  3058. this.localAxis2 = new OIMO.Vec3().normalize(config.localAxis2);
  3059. var len;
  3060. this.localAxis1X = this.localAxis1.x;
  3061. this.localAxis1Y = this.localAxis1.y;
  3062. this.localAxis1Z = this.localAxis1.z;
  3063. this.localAxis2X = this.localAxis2.x;
  3064. this.localAxis2Y = this.localAxis2.y;
  3065. this.localAxis2Z = this.localAxis2.z;
  3066. var dot = this.localAxis1X * this.localAxis2X + this.localAxis1Y * this.localAxis2Y + this.localAxis1Z * this.localAxis2Z;
  3067. if (dot > -1 && dot < 1) {
  3068. this.localAngAxis1X = this.localAxis2X - dot * this.localAxis1X;
  3069. this.localAngAxis1Y = this.localAxis2Y - dot * this.localAxis1Y;
  3070. this.localAngAxis1Z = this.localAxis2Z - dot * this.localAxis1Z;
  3071. this.localAngAxis2X = this.localAxis1X - dot * this.localAxis2X;
  3072. this.localAngAxis2Y = this.localAxis1Y - dot * this.localAxis2Y;
  3073. this.localAngAxis2Z = this.localAxis1Z - dot * this.localAxis2Z;
  3074. len = 1 / OIMO.sqrt(this.localAngAxis1X * this.localAngAxis1X + this.localAngAxis1Y * this.localAngAxis1Y + this.localAngAxis1Z * this.localAngAxis1Z);
  3075. this.localAngAxis1X *= len;
  3076. this.localAngAxis1Y *= len;
  3077. this.localAngAxis1Z *= len;
  3078. len = 1 / OIMO.sqrt(this.localAngAxis2X * this.localAngAxis2X + this.localAngAxis2Y * this.localAngAxis2Y + this.localAngAxis2Z * this.localAngAxis2Z);
  3079. this.localAngAxis2X *= len;
  3080. this.localAngAxis2Y *= len;
  3081. this.localAngAxis2Z *= len;
  3082. } else {
  3083. this.localAngAxis1X = this.localAxis1Y * this.localAxis1X - this.localAxis1Z * this.localAxis1Z;
  3084. this.localAngAxis1Y = -this.localAxis1Z * this.localAxis1Y - this.localAxis1X * this.localAxis1X;
  3085. this.localAngAxis1Z = this.localAxis1X * this.localAxis1Z + this.localAxis1Y * this.localAxis1Y;
  3086. len = 1 / OIMO.sqrt(this.localAngAxis1X * this.localAngAxis1X + this.localAngAxis1Y * this.localAngAxis1Y + this.localAngAxis1Z * this.localAngAxis1Z);
  3087. this.localAngAxis1X *= len;
  3088. this.localAngAxis1Y *= len;
  3089. this.localAngAxis1Z *= len;
  3090. var arc = new OIMO.Mat33().setQuat(new OIMO.Quat().arc(this.localAxis1, this.localAxis2));
  3091. var tarc = arc.elements;
  3092. this.localAngAxis2X = this.localAngAxis1X * tarc[0] + this.localAngAxis1Y * tarc[1] + this.localAngAxis1Z * tarc[2];
  3093. this.localAngAxis2Y = this.localAngAxis1X * tarc[3] + this.localAngAxis1Y * tarc[4] + this.localAngAxis1Z * tarc[5];
  3094. this.localAngAxis2Z = this.localAngAxis1X * tarc[6] + this.localAngAxis1Y * tarc[7] + this.localAngAxis1Z * tarc[8];
  3095. }
  3096. this.nor = new OIMO.Vec3();
  3097. this.tan = new OIMO.Vec3();
  3098. this.bin = new OIMO.Vec3();
  3099. // The translational limit and motor information of the joint.
  3100. this.translationalLimitMotor = new OIMO.LimitMotor(this.tan, true);
  3101. this.translationalLimitMotor.frequency = 8;
  3102. this.translationalLimitMotor.dampingRatio = 1;
  3103. // The first rotational limit and motor information of the joint.
  3104. this.rotationalLimitMotor1 = new OIMO.LimitMotor(this.tan, false);
  3105. // The second rotational limit and motor information of the joint.
  3106. this.rotationalLimitMotor2 = new OIMO.LimitMotor(this.bin, false);
  3107. this.t3 = new OIMO.Translational3Constraint(this, new OIMO.LimitMotor(this.nor, true), this.translationalLimitMotor, new OIMO.LimitMotor(this.bin, true));
  3108. this.t3.weight = 1;
  3109. this.r3 = new OIMO.Rotational3Constraint(this, new OIMO.LimitMotor(this.nor, true), this.rotationalLimitMotor1, this.rotationalLimitMotor2);
  3110. };
  3111. OIMO.WheelJoint.prototype = Object.create(OIMO.Joint.prototype);
  3112. OIMO.WheelJoint.prototype.constructor = OIMO.WheelJoint;
  3113. OIMO.WheelJoint.prototype.preSolve = function (timeStep, invTimeStep) {
  3114. var tmpM;
  3115. var tmp1X;
  3116. var tmp1Y;
  3117. var tmp1Z;
  3118. this.updateAnchorPoints();
  3119. tmpM = this.body1.rotation.elements;
  3120. var x1 = this.localAxis1X * tmpM[0] + this.localAxis1Y * tmpM[1] + this.localAxis1Z * tmpM[2];
  3121. var y1 = this.localAxis1X * tmpM[3] + this.localAxis1Y * tmpM[4] + this.localAxis1Z * tmpM[5];
  3122. var z1 = this.localAxis1X * tmpM[6] + this.localAxis1Y * tmpM[7] + this.localAxis1Z * tmpM[8];
  3123. var angAxis1X = this.localAngAxis1X * tmpM[0] + this.localAngAxis1Y * tmpM[1] + this.localAngAxis1Z * tmpM[2];
  3124. var angAxis1Y = this.localAngAxis1X * tmpM[3] + this.localAngAxis1Y * tmpM[4] + this.localAngAxis1Z * tmpM[5];
  3125. var angAxis1Z = this.localAngAxis1X * tmpM[6] + this.localAngAxis1Y * tmpM[7] + this.localAngAxis1Z * tmpM[8];
  3126. tmpM = this.body2.rotation.elements;
  3127. var x2 = this.localAxis2X * tmpM[0] + this.localAxis2Y * tmpM[1] + this.localAxis2Z * tmpM[2];
  3128. var y2 = this.localAxis2X * tmpM[3] + this.localAxis2Y * tmpM[4] + this.localAxis2Z * tmpM[5];
  3129. var z2 = this.localAxis2X * tmpM[6] + this.localAxis2Y * tmpM[7] + this.localAxis2Z * tmpM[8];
  3130. var angAxis2X = this.localAngAxis2X * tmpM[0] + this.localAngAxis2Y * tmpM[1] + this.localAngAxis2Z * tmpM[2];
  3131. var angAxis2Y = this.localAngAxis2X * tmpM[3] + this.localAngAxis2Y * tmpM[4] + this.localAngAxis2Z * tmpM[5];
  3132. var angAxis2Z = this.localAngAxis2X * tmpM[6] + this.localAngAxis2Y * tmpM[7] + this.localAngAxis2Z * tmpM[8];
  3133. this.r3.limitMotor1.angle = x1 * x2 + y1 * y2 + z1 * z2;
  3134. if (x1 * (angAxis1Y * z2 - angAxis1Z * y2) + y1 * (angAxis1Z * x2 - angAxis1X * z2) + z1 * (angAxis1X * y2 - angAxis1Y * x2) < 0) {
  3135. this.rotationalLimitMotor1.angle = -this.acosClamp(angAxis1X * x2 + angAxis1Y * y2 + angAxis1Z * z2);
  3136. } else {
  3137. this.rotationalLimitMotor1.angle = this.acosClamp(angAxis1X * x2 + angAxis1Y * y2 + angAxis1Z * z2);
  3138. }
  3139. if (x2 * (angAxis2Y * z1 - angAxis2Z * y1) + y2 * (angAxis2Z * x1 - angAxis2X * z1) + z2 * (angAxis2X * y1 - angAxis2Y * x1) < 0) {
  3140. this.rotationalLimitMotor2.angle = this.acosClamp(angAxis2X * x1 + angAxis2Y * y1 + angAxis2Z * z1);
  3141. } else {
  3142. this.rotationalLimitMotor2.angle = -this.acosClamp(angAxis2X * x1 + angAxis2Y * y1 + angAxis2Z * z1);
  3143. }
  3144. var nx = y2 * z1 - z2 * y1;
  3145. var ny = z2 * x1 - x2 * z1;
  3146. var nz = x2 * y1 - y2 * x1;
  3147. tmp1X = OIMO.sqrt(nx * nx + ny * ny + nz * nz);
  3148. if (tmp1X > 0) tmp1X = 1 / tmp1X;
  3149. nx *= tmp1X;
  3150. ny *= tmp1X;
  3151. nz *= tmp1X;
  3152. var tx = ny * z2 - nz * y2;
  3153. var ty = nz * x2 - nx * z2;
  3154. var tz = nx * y2 - ny * x2;
  3155. tmp1X = OIMO.sqrt(tx * tx + ty * ty + tz * tz);
  3156. if (tmp1X > 0) tmp1X = 1 / tmp1X;
  3157. tx *= tmp1X;
  3158. ty *= tmp1X;
  3159. tz *= tmp1X;
  3160. var bx = y1 * nz - z1 * ny;
  3161. var by = z1 * nx - x1 * nz;
  3162. var bz = x1 * ny - y1 * nx;
  3163. tmp1X = OIMO.sqrt(bx * bx + by * by + bz * bz);
  3164. if (tmp1X > 0) tmp1X = 1 / tmp1X;
  3165. bx *= tmp1X;
  3166. by *= tmp1X;
  3167. bz *= tmp1X;
  3168. this.nor.init(nx, ny, nz);
  3169. this.tan.init(tx, ty, tz);
  3170. this.bin.init(bx, by, bz);
  3171. this.r3.preSolve(timeStep, invTimeStep);
  3172. this.t3.preSolve(timeStep, invTimeStep);
  3173. };
  3174. OIMO.WheelJoint.prototype.solve = function () {
  3175. this.r3.solve();
  3176. this.t3.solve();
  3177. };
  3178. OIMO.WheelJoint.prototype.postSolve = function () {
  3179. };
  3180. OIMO.WheelJoint.prototype.acosClamp = function (cos) {
  3181. if (cos > 1) return 0;
  3182. else if (cos < -1) return OIMO.PI;
  3183. else return OIMO.acos(cos);
  3184. };
  3185. /**
  3186. * An angular constraint for all axes for various joints.
  3187. * @author saharan
  3188. */
  3189. OIMO.AngularConstraint = function (joint, targetOrientation) {
  3190. this.joint = joint;
  3191. this.targetOrientation = new OIMO.Quat().invert(targetOrientation);
  3192. this.relativeOrientation = new OIMO.Quat();
  3193. this.ii1 = null;
  3194. this.ii2 = null;
  3195. this.dd = null;
  3196. this.vel = new OIMO.Vec3();
  3197. this.imp = new OIMO.Vec3();
  3198. this.rn0 = new OIMO.Vec3();
  3199. this.rn1 = new OIMO.Vec3();
  3200. this.rn2 = new OIMO.Vec3();
  3201. this.b1 = joint.body1;
  3202. this.b2 = joint.body2;
  3203. this.a1 = this.b1.angularVelocity;
  3204. this.a2 = this.b2.angularVelocity;
  3205. this.i1 = this.b1.inverseInertia;
  3206. this.i2 = this.b2.inverseInertia;
  3207. };
  3208. OIMO.AngularConstraint.prototype = {
  3209. constructor: OIMO.AngularConstraint,
  3210. preSolve: function (timeStep, invTimeStep) {
  3211. var inv, len, v, vv;
  3212. this.ii1 = this.i1.clone();
  3213. this.ii2 = this.i2.clone();
  3214. v = new OIMO.Mat33().add(this.ii1, this.ii2).elements;
  3215. inv = 1 / (v[0] * (v[4] * v[8] - v[7] * v[5]) + v[3] * (v[7] * v[2] - v[1] * v[8]) + v[6] * (v[1] * v[5] - v[4] * v[2]));
  3216. this.dd = new OIMO.Mat33(
  3217. v[4] * v[8] - v[5] * v[7], v[2] * v[7] - v[1] * v[8], v[1] * v[5] - v[2] * v[4],
  3218. v[5] * v[6] - v[3] * v[8], v[0] * v[8] - v[2] * v[6], v[2] * v[3] - v[0] * v[5],
  3219. v[3] * v[7] - v[4] * v[6], v[1] * v[6] - v[0] * v[7], v[0] * v[4] - v[1] * v[3]
  3220. ).multiply(inv);
  3221. this.relativeOrientation.invert(this.b1.orientation);
  3222. this.relativeOrientation.mul(this.targetOrientation, this.relativeOrientation);
  3223. this.relativeOrientation.mul(this.b2.orientation, this.relativeOrientation);
  3224. inv = this.relativeOrientation.s * 2;
  3225. this.vel.scale(this.relativeOrientation, inv);
  3226. len = this.vel.length();
  3227. if (len > 0.02) {
  3228. len = (0.02 - len) / len * invTimeStep * 0.05;
  3229. this.vel.scaleEqual(len);
  3230. } else {
  3231. this.vel.init();
  3232. }
  3233. this.rn1.mulMat(this.ii1, this.imp);
  3234. this.rn2.mulMat(this.ii2, this.imp);
  3235. this.a1.addEqual(this.rn1);
  3236. this.a2.subEqual(this.rn2);
  3237. },
  3238. solve: function () {
  3239. var r = this.a2.clone().subEqual(this.a1).subEqual(this.vel);
  3240. this.rn0.mulMat(this.dd, r);
  3241. this.rn1.mulMat(this.ii1, this.rn0);
  3242. this.rn2.mulMat(this.ii2, this.rn0);
  3243. this.imp.addEqual(this.rn0);
  3244. this.a1.addEqual(this.rn1);
  3245. this.a2.subEqual(this.rn2);
  3246. }
  3247. };
  3248. /**
  3249. * A linear constraint for all axes for various joints.
  3250. * @author saharan
  3251. */
  3252. OIMO.LinearConstraint = function (joint) {
  3253. this.m1 = NaN;
  3254. this.m2 = NaN;
  3255. this.ii1 = null;
  3256. this.ii2 = null;
  3257. this.dd = null;
  3258. this.r1x = NaN;
  3259. this.r1y = NaN;
  3260. this.r1z = NaN;
  3261. this.r2x = NaN;
  3262. this.r2y = NaN;
  3263. this.r2z = NaN;
  3264. this.ax1x = NaN;
  3265. this.ax1y = NaN;
  3266. this.ax1z = NaN;
  3267. this.ay1x = NaN;
  3268. this.ay1y = NaN;
  3269. this.ay1z = NaN;
  3270. this.az1x = NaN;
  3271. this.az1y = NaN;
  3272. this.az1z = NaN;
  3273. this.ax2x = NaN;
  3274. this.ax2y = NaN;
  3275. this.ax2z = NaN;
  3276. this.ay2x = NaN;
  3277. this.ay2y = NaN;
  3278. this.ay2z = NaN;
  3279. this.az2x = NaN;
  3280. this.az2y = NaN;
  3281. this.az2z = NaN;
  3282. this.vel = NaN;
  3283. this.velx = NaN;
  3284. this.vely = NaN;
  3285. this.velz = NaN;
  3286. this.joint = joint;
  3287. this.r1 = joint.relativeAnchorPoint1;
  3288. this.r2 = joint.relativeAnchorPoint2;
  3289. this.p1 = joint.anchorPoint1;
  3290. this.p2 = joint.anchorPoint2;
  3291. this.b1 = joint.body1;
  3292. this.b2 = joint.body2;
  3293. this.l1 = this.b1.linearVelocity;
  3294. this.l2 = this.b2.linearVelocity;
  3295. this.a1 = this.b1.angularVelocity;
  3296. this.a2 = this.b2.angularVelocity;
  3297. this.i1 = this.b1.inverseInertia;
  3298. this.i2 = this.b2.inverseInertia;
  3299. this.impx = 0;
  3300. this.impy = 0;
  3301. this.impz = 0;
  3302. }
  3303. OIMO.LinearConstraint.prototype = {
  3304. constructor: OIMO.LinearConstraint,
  3305. preSolve: function (timeStep, invTimeStep) {
  3306. this.r1x = this.r1.x;
  3307. this.r1y = this.r1.y;
  3308. this.r1z = this.r1.z;
  3309. this.r2x = this.r2.x;
  3310. this.r2y = this.r2.y;
  3311. this.r2z = this.r2.z;
  3312. this.m1 = this.b1.inverseMass;
  3313. this.m2 = this.b2.inverseMass;
  3314. this.ii1 = this.i1.clone();
  3315. this.ii2 = this.i2.clone();
  3316. var ii1 = this.ii1.elements;
  3317. var ii2 = this.ii2.elements;
  3318. this.ax1x = this.r1z * ii1[1] + -this.r1y * ii1[2];
  3319. this.ax1y = this.r1z * ii1[4] + -this.r1y * ii1[5];
  3320. this.ax1z = this.r1z * ii1[7] + -this.r1y * ii1[8];
  3321. this.ay1x = -this.r1z * ii1[0] + this.r1x * ii1[2];
  3322. this.ay1y = -this.r1z * ii1[3] + this.r1x * ii1[5];
  3323. this.ay1z = -this.r1z * ii1[6] + this.r1x * ii1[8];
  3324. this.az1x = this.r1y * ii1[0] + -this.r1x * ii1[1];
  3325. this.az1y = this.r1y * ii1[3] + -this.r1x * ii1[4];
  3326. this.az1z = this.r1y * ii1[6] + -this.r1x * ii1[7];
  3327. this.ax2x = this.r2z * ii2[1] + -this.r2y * ii2[2];
  3328. this.ax2y = this.r2z * ii2[4] + -this.r2y * ii2[5];
  3329. this.ax2z = this.r2z * ii2[7] + -this.r2y * ii2[8];
  3330. this.ay2x = -this.r2z * ii2[0] + this.r2x * ii2[2];
  3331. this.ay2y = -this.r2z * ii2[3] + this.r2x * ii2[5];
  3332. this.ay2z = -this.r2z * ii2[6] + this.r2x * ii2[8];
  3333. this.az2x = this.r2y * ii2[0] + -this.r2x * ii2[1];
  3334. this.az2y = this.r2y * ii2[3] + -this.r2x * ii2[4];
  3335. this.az2z = this.r2y * ii2[6] + -this.r2x * ii2[7];
  3336. // calculate point-to-point mass matrix
  3337. // from impulse equation
  3338. //
  3339. // M = ([/m] - [r^][/I][r^]) ^ -1
  3340. //
  3341. // where
  3342. //
  3343. // [/m] = |1/m, 0, 0|
  3344. // |0, 1/m, 0|
  3345. // |0, 0, 1/m|
  3346. //
  3347. // [r^] = |0, -rz, ry|
  3348. // |rz, 0, -rx|
  3349. // |-ry, rx, 0|
  3350. //
  3351. // [/I] = Inverted moment inertia
  3352. var rxx = this.m1 + this.m2;
  3353. var kk = new OIMO.Mat33(rxx, 0, 0, 0, rxx, 0, 0, 0, rxx);
  3354. var k = kk.elements;
  3355. k[0] += ii1[4] * this.r1z * this.r1z - (ii1[7] + ii1[5]) * this.r1y * this.r1z + ii1[8] * this.r1y * this.r1y;
  3356. k[1] += (ii1[6] * this.r1y + ii1[5] * this.r1x) * this.r1z - ii1[3] * this.r1z * this.r1z - ii1[8] * this.r1x * this.r1y;
  3357. k[2] += (ii1[3] * this.r1y - ii1[4] * this.r1x) * this.r1z - ii1[6] * this.r1y * this.r1y + ii1[7] * this.r1x * this.r1y;
  3358. k[3] += (ii1[2] * this.r1y + ii1[7] * this.r1x) * this.r1z - ii1[1] * this.r1z * this.r1z - ii1[8] * this.r1x * this.r1y;
  3359. k[4] += ii1[0] * this.r1z * this.r1z - (ii1[6] + ii1[2]) * this.r1x * this.r1z + ii1[8] * this.r1x * this.r1x;
  3360. k[5] += (ii1[1] * this.r1x - ii1[0] * this.r1y) * this.r1z - ii1[7] * this.r1x * this.r1x + ii1[6] * this.r1x * this.r1y;
  3361. k[6] += (ii1[1] * this.r1y - ii1[4] * this.r1x) * this.r1z - ii1[2] * this.r1y * this.r1y + ii1[5] * this.r1x * this.r1y;
  3362. k[7] += (ii1[3] * this.r1x - ii1[0] * this.r1y) * this.r1z - ii1[5] * this.r1x * this.r1x + ii1[2] * this.r1x * this.r1y;
  3363. k[8] += ii1[0] * this.r1y * this.r1y - (ii1[3] + ii1[1]) * this.r1x * this.r1y + ii1[4] * this.r1x * this.r1x;
  3364. k[0] += ii2[4] * this.r2z * this.r2z - (ii2[7] + ii2[5]) * this.r2y * this.r2z + ii2[8] * this.r2y * this.r2y;
  3365. k[1] += (ii2[6] * this.r2y + ii2[5] * this.r2x) * this.r2z - ii2[3] * this.r2z * this.r2z - ii2[8] * this.r2x * this.r2y;
  3366. k[2] += (ii2[3] * this.r2y - ii2[4] * this.r2x) * this.r2z - ii2[6] * this.r2y * this.r2y + ii2[7] * this.r2x * this.r2y;
  3367. k[3] += (ii2[2] * this.r2y + ii2[7] * this.r2x) * this.r2z - ii2[1] * this.r2z * this.r2z - ii2[8] * this.r2x * this.r2y;
  3368. k[4] += ii2[0] * this.r2z * this.r2z - (ii2[6] + ii2[2]) * this.r2x * this.r2z + ii2[8] * this.r2x * this.r2x;
  3369. k[5] += (ii2[1] * this.r2x - ii2[0] * this.r2y) * this.r2z - ii2[7] * this.r2x * this.r2x + ii2[6] * this.r2x * this.r2y;
  3370. k[6] += (ii2[1] * this.r2y - ii2[4] * this.r2x) * this.r2z - ii2[2] * this.r2y * this.r2y + ii2[5] * this.r2x * this.r2y;
  3371. k[7] += (ii2[3] * this.r2x - ii2[0] * this.r2y) * this.r2z - ii2[5] * this.r2x * this.r2x + ii2[2] * this.r2x * this.r2y;
  3372. k[8] += ii2[0] * this.r2y * this.r2y - (ii2[3] + ii2[1]) * this.r2x * this.r2y + ii2[4] * this.r2x * this.r2x;
  3373. var inv = 1 / (k[0] * (k[4] * k[8] - k[7] * k[5]) + k[3] * (k[7] * k[2] - k[1] * k[8]) + k[6] * (k[1] * k[5] - k[4] * k[2]));
  3374. this.dd = new OIMO.Mat33(
  3375. k[4] * k[8] - k[5] * k[7], k[2] * k[7] - k[1] * k[8], k[1] * k[5] - k[2] * k[4],
  3376. k[5] * k[6] - k[3] * k[8], k[0] * k[8] - k[2] * k[6], k[2] * k[3] - k[0] * k[5],
  3377. k[3] * k[7] - k[4] * k[6], k[1] * k[6] - k[0] * k[7], k[0] * k[4] - k[1] * k[3]
  3378. ).multiply(inv);
  3379. this.velx = this.p2.x - this.p1.x;
  3380. this.vely = this.p2.y - this.p1.y;
  3381. this.velz = this.p2.z - this.p1.z;
  3382. var len = OIMO.sqrt(this.velx * this.velx + this.vely * this.vely + this.velz * this.velz);
  3383. if (len > 0.005) {
  3384. len = (0.005 - len) / len * invTimeStep * 0.05;
  3385. this.velx *= len;
  3386. this.vely *= len;
  3387. this.velz *= len;
  3388. } else {
  3389. this.velx = 0;
  3390. this.vely = 0;
  3391. this.velz = 0;
  3392. }
  3393. this.impx *= 0.95;
  3394. this.impy *= 0.95;
  3395. this.impz *= 0.95;
  3396. this.l1.x += this.impx * this.m1;
  3397. this.l1.y += this.impy * this.m1;
  3398. this.l1.z += this.impz * this.m1;
  3399. this.a1.x += this.impx * this.ax1x + this.impy * this.ay1x + this.impz * this.az1x;
  3400. this.a1.y += this.impx * this.ax1y + this.impy * this.ay1y + this.impz * this.az1y;
  3401. this.a1.z += this.impx * this.ax1z + this.impy * this.ay1z + this.impz * this.az1z;
  3402. this.l2.x -= this.impx * this.m2;
  3403. this.l2.y -= this.impy * this.m2;
  3404. this.l2.z -= this.impz * this.m2;
  3405. this.a2.x -= this.impx * this.ax2x + this.impy * this.ay2x + this.impz * this.az2x;
  3406. this.a2.y -= this.impx * this.ax2y + this.impy * this.ay2y + this.impz * this.az2y;
  3407. this.a2.z -= this.impx * this.ax2z + this.impy * this.ay2z + this.impz * this.az2z;
  3408. },
  3409. solve: function () {
  3410. var d = this.dd.elements;
  3411. var rvx = this.l2.x - this.l1.x + this.a2.y * this.r2z - this.a2.z * this.r2y - this.a1.y * this.r1z + this.a1.z * this.r1y - this.velx;
  3412. var rvy = this.l2.y - this.l1.y + this.a2.z * this.r2x - this.a2.x * this.r2z - this.a1.z * this.r1x + this.a1.x * this.r1z - this.vely;
  3413. var rvz = this.l2.z - this.l1.z + this.a2.x * this.r2y - this.a2.y * this.r2x - this.a1.x * this.r1y + this.a1.y * this.r1x - this.velz;
  3414. var nimpx = rvx * d[0] + rvy * d[1] + rvz * d[2];
  3415. var nimpy = rvx * d[3] + rvy * d[4] + rvz * d[5];
  3416. var nimpz = rvx * d[6] + rvy * d[7] + rvz * d[8];
  3417. this.impx += nimpx;
  3418. this.impy += nimpy;
  3419. this.impz += nimpz;
  3420. this.l1.x += nimpx * this.m1;
  3421. this.l1.y += nimpy * this.m1;
  3422. this.l1.z += nimpz * this.m1;
  3423. this.a1.x += nimpx * this.ax1x + nimpy * this.ay1x + nimpz * this.az1x;
  3424. this.a1.y += nimpx * this.ax1y + nimpy * this.ay1y + nimpz * this.az1y;
  3425. this.a1.z += nimpx * this.ax1z + nimpy * this.ay1z + nimpz * this.az1z;
  3426. this.l2.x -= nimpx * this.m2;
  3427. this.l2.y -= nimpy * this.m2;
  3428. this.l2.z -= nimpz * this.m2;
  3429. this.a2.x -= nimpx * this.ax2x + nimpy * this.ay2x + nimpz * this.az2x;
  3430. this.a2.y -= nimpx * this.ax2y + nimpy * this.ay2y + nimpz * this.az2y;
  3431. this.a2.z -= nimpx * this.ax2z + nimpy * this.ay2z + nimpz * this.az2z;
  3432. }
  3433. }
  3434. /**
  3435. * A three-axis rotational constraint for various joints.
  3436. * @author saharan
  3437. */
  3438. OIMO.Rotational3Constraint = function (joint, limitMotor1, limitMotor2, limitMotor3) {
  3439. this.cfm1 = NaN;
  3440. this.cfm2 = NaN;
  3441. this.cfm3 = NaN;
  3442. this.i1e00 = NaN;
  3443. this.i1e01 = NaN;
  3444. this.i1e02 = NaN;
  3445. this.i1e10 = NaN;
  3446. this.i1e11 = NaN;
  3447. this.i1e12 = NaN;
  3448. this.i1e20 = NaN;
  3449. this.i1e21 = NaN;
  3450. this.i1e22 = NaN;
  3451. this.i2e00 = NaN;
  3452. this.i2e01 = NaN;
  3453. this.i2e02 = NaN;
  3454. this.i2e10 = NaN;
  3455. this.i2e11 = NaN;
  3456. this.i2e12 = NaN;
  3457. this.i2e20 = NaN;
  3458. this.i2e21 = NaN;
  3459. this.i2e22 = NaN;
  3460. this.ax1 = NaN;
  3461. this.ay1 = NaN;
  3462. this.az1 = NaN;
  3463. this.ax2 = NaN;
  3464. this.ay2 = NaN;
  3465. this.az2 = NaN;
  3466. this.ax3 = NaN;
  3467. this.ay3 = NaN;
  3468. this.az3 = NaN;
  3469. this.a1x1 = NaN; // jacoians
  3470. this.a1y1 = NaN;
  3471. this.a1z1 = NaN;
  3472. this.a2x1 = NaN;
  3473. this.a2y1 = NaN;
  3474. this.a2z1 = NaN;
  3475. this.a1x2 = NaN;
  3476. this.a1y2 = NaN;
  3477. this.a1z2 = NaN;
  3478. this.a2x2 = NaN;
  3479. this.a2y2 = NaN;
  3480. this.a2z2 = NaN;
  3481. this.a1x3 = NaN;
  3482. this.a1y3 = NaN;
  3483. this.a1z3 = NaN;
  3484. this.a2x3 = NaN;
  3485. this.a2y3 = NaN;
  3486. this.a2z3 = NaN;
  3487. this.lowerLimit1 = NaN;
  3488. this.upperLimit1 = NaN;
  3489. this.limitVelocity1 = NaN;
  3490. this.limitState1 = 0; // -1: at lower, 0: locked, 1: at upper, 2: free
  3491. this.enableMotor1 = false;
  3492. this.motorSpeed1 = NaN;
  3493. this.maxMotorForce1 = NaN;
  3494. this.maxMotorImpulse1 = NaN;
  3495. this.lowerLimit2 = NaN;
  3496. this.upperLimit2 = NaN;
  3497. this.limitVelocity2 = NaN;
  3498. this.limitState2 = 0; // -1: at lower, 0: locked, 1: at upper, 2: free
  3499. this.enableMotor2 = false;
  3500. this.motorSpeed2 = NaN;
  3501. this.maxMotorForce2 = NaN;
  3502. this.maxMotorImpulse2 = NaN;
  3503. this.lowerLimit3 = NaN;
  3504. this.upperLimit3 = NaN;
  3505. this.limitVelocity3 = NaN;
  3506. this.limitState3 = 0; // -1: at lower, 0: locked, 1: at upper, 2: free
  3507. this.enableMotor3 = false;
  3508. this.motorSpeed3 = NaN;
  3509. this.maxMotorForce3 = NaN;
  3510. this.maxMotorImpulse3 = NaN;
  3511. this.k00 = NaN; // K = J*M*JT
  3512. this.k01 = NaN;
  3513. this.k02 = NaN;
  3514. this.k10 = NaN;
  3515. this.k11 = NaN;
  3516. this.k12 = NaN;
  3517. this.k20 = NaN;
  3518. this.k21 = NaN;
  3519. this.k22 = NaN;
  3520. this.kv00 = NaN; // diagonals without CFMs
  3521. this.kv11 = NaN;
  3522. this.kv22 = NaN;
  3523. this.dv00 = NaN; // ...inverted
  3524. this.dv11 = NaN;
  3525. this.dv22 = NaN;
  3526. this.d00 = NaN; // K^-1
  3527. this.d01 = NaN;
  3528. this.d02 = NaN;
  3529. this.d10 = NaN;
  3530. this.d11 = NaN;
  3531. this.d12 = NaN;
  3532. this.d20 = NaN;
  3533. this.d21 = NaN;
  3534. this.d22 = NaN;
  3535. this.limitMotor1 = limitMotor1;
  3536. this.limitMotor2 = limitMotor2;
  3537. this.limitMotor3 = limitMotor3;
  3538. this.b1 = joint.body1;
  3539. this.b2 = joint.body2;
  3540. this.a1 = this.b1.angularVelocity;
  3541. this.a2 = this.b2.angularVelocity;
  3542. this.i1 = this.b1.inverseInertia;
  3543. this.i2 = this.b2.inverseInertia;
  3544. this.limitImpulse1 = 0;
  3545. this.motorImpulse1 = 0;
  3546. this.limitImpulse2 = 0;
  3547. this.motorImpulse2 = 0;
  3548. this.limitImpulse3 = 0;
  3549. this.motorImpulse3 = 0;
  3550. }
  3551. OIMO.Rotational3Constraint.prototype = {
  3552. constructor: OIMO.Rotational3Constraint,
  3553. preSolve: function (timeStep, invTimeStep) {
  3554. this.ax1 = this.limitMotor1.axis.x;
  3555. this.ay1 = this.limitMotor1.axis.y;
  3556. this.az1 = this.limitMotor1.axis.z;
  3557. this.ax2 = this.limitMotor2.axis.x;
  3558. this.ay2 = this.limitMotor2.axis.y;
  3559. this.az2 = this.limitMotor2.axis.z;
  3560. this.ax3 = this.limitMotor3.axis.x;
  3561. this.ay3 = this.limitMotor3.axis.y;
  3562. this.az3 = this.limitMotor3.axis.z;
  3563. this.lowerLimit1 = this.limitMotor1.lowerLimit;
  3564. this.upperLimit1 = this.limitMotor1.upperLimit;
  3565. this.motorSpeed1 = this.limitMotor1.motorSpeed;
  3566. this.maxMotorForce1 = this.limitMotor1.maxMotorForce;
  3567. this.enableMotor1 = this.maxMotorForce1 > 0;
  3568. this.lowerLimit2 = this.limitMotor2.lowerLimit;
  3569. this.upperLimit2 = this.limitMotor2.upperLimit;
  3570. this.motorSpeed2 = this.limitMotor2.motorSpeed;
  3571. this.maxMotorForce2 = this.limitMotor2.maxMotorForce;
  3572. this.enableMotor2 = this.maxMotorForce2 > 0;
  3573. this.lowerLimit3 = this.limitMotor3.lowerLimit;
  3574. this.upperLimit3 = this.limitMotor3.upperLimit;
  3575. this.motorSpeed3 = this.limitMotor3.motorSpeed;
  3576. this.maxMotorForce3 = this.limitMotor3.maxMotorForce;
  3577. this.enableMotor3 = this.maxMotorForce3 > 0;
  3578. var ti1 = this.i1.elements;
  3579. var ti2 = this.i2.elements;
  3580. this.i1e00 = ti1[0];
  3581. this.i1e01 = ti1[1];
  3582. this.i1e02 = ti1[2];
  3583. this.i1e10 = ti1[3];
  3584. this.i1e11 = ti1[4];
  3585. this.i1e12 = ti1[5];
  3586. this.i1e20 = ti1[6];
  3587. this.i1e21 = ti1[7];
  3588. this.i1e22 = ti1[8];
  3589. this.i2e00 = ti2[0];
  3590. this.i2e01 = ti2[1];
  3591. this.i2e02 = ti2[2];
  3592. this.i2e10 = ti2[3];
  3593. this.i2e11 = ti2[4];
  3594. this.i2e12 = ti2[5];
  3595. this.i2e20 = ti2[6];
  3596. this.i2e21 = ti2[7];
  3597. this.i2e22 = ti2[8];
  3598. var frequency1 = this.limitMotor1.frequency;
  3599. var frequency2 = this.limitMotor2.frequency;
  3600. var frequency3 = this.limitMotor3.frequency;
  3601. var enableSpring1 = frequency1 > 0;
  3602. var enableSpring2 = frequency2 > 0;
  3603. var enableSpring3 = frequency3 > 0;
  3604. var enableLimit1 = this.lowerLimit1 <= this.upperLimit1;
  3605. var enableLimit2 = this.lowerLimit2 <= this.upperLimit2;
  3606. var enableLimit3 = this.lowerLimit3 <= this.upperLimit3;
  3607. var angle1 = this.limitMotor1.angle;
  3608. if (enableLimit1) {
  3609. if (this.lowerLimit1 == this.upperLimit1) {
  3610. if (this.limitState1 != 0) {
  3611. this.limitState1 = 0;
  3612. this.limitImpulse1 = 0;
  3613. }
  3614. this.limitVelocity1 = this.lowerLimit1 - angle1;
  3615. } else if (angle1 < this.lowerLimit1) {
  3616. if (this.limitState1 != -1) {
  3617. this.limitState1 = -1;
  3618. this.limitImpulse1 = 0;
  3619. }
  3620. this.limitVelocity1 = this.lowerLimit1 - angle1;
  3621. } else if (angle1 > this.upperLimit1) {
  3622. if (this.limitState1 != 1) {
  3623. this.limitState1 = 1;
  3624. this.limitImpulse1 = 0;
  3625. }
  3626. this.limitVelocity1 = this.upperLimit1 - angle1;
  3627. } else {
  3628. this.limitState1 = 2;
  3629. this.limitImpulse1 = 0;
  3630. this.limitVelocity1 = 0;
  3631. }
  3632. if (!enableSpring1) {
  3633. if (this.limitVelocity1 > 0.02) this.limitVelocity1 -= 0.02;
  3634. else if (this.limitVelocity1 < -0.02) this.limitVelocity1 += 0.02;
  3635. else this.limitVelocity1 = 0;
  3636. }
  3637. } else {
  3638. this.limitState1 = 2;
  3639. this.limitImpulse1 = 0;
  3640. }
  3641. var angle2 = this.limitMotor2.angle;
  3642. if (enableLimit2) {
  3643. if (this.lowerLimit2 == this.upperLimit2) {
  3644. if (this.limitState2 != 0) {
  3645. this.limitState2 = 0;
  3646. this.limitImpulse2 = 0;
  3647. }
  3648. this.limitVelocity2 = this.lowerLimit2 - angle2;
  3649. } else if (angle2 < this.lowerLimit2) {
  3650. if (this.limitState2 != -1) {
  3651. this.limitState2 = -1;
  3652. this.limitImpulse2 = 0;
  3653. }
  3654. this.limitVelocity2 = this.lowerLimit2 - angle2;
  3655. } else if (angle2 > this.upperLimit2) {
  3656. if (this.limitState2 != 1) {
  3657. this.limitState2 = 1;
  3658. this.limitImpulse2 = 0;
  3659. }
  3660. this.limitVelocity2 = this.upperLimit2 - angle2;
  3661. } else {
  3662. this.limitState2 = 2;
  3663. this.limitImpulse2 = 0;
  3664. this.limitVelocity2 = 0;
  3665. }
  3666. if (!enableSpring2) {
  3667. if (this.limitVelocity2 > 0.02) this.limitVelocity2 -= 0.02;
  3668. else if (this.limitVelocity2 < -0.02) this.limitVelocity2 += 0.02;
  3669. else this.limitVelocity2 = 0;
  3670. }
  3671. } else {
  3672. this.limitState2 = 2;
  3673. this.limitImpulse2 = 0;
  3674. }
  3675. var angle3 = this.limitMotor3.angle;
  3676. if (enableLimit3) {
  3677. if (this.lowerLimit3 == this.upperLimit3) {
  3678. if (this.limitState3 != 0) {
  3679. this.limitState3 = 0;
  3680. this.limitImpulse3 = 0;
  3681. }
  3682. this.limitVelocity3 = this.lowerLimit3 - angle3;
  3683. } else if (angle3 < this.lowerLimit3) {
  3684. if (this.limitState3 != -1) {
  3685. this.limitState3 = -1;
  3686. this.limitImpulse3 = 0;
  3687. }
  3688. this.limitVelocity3 = this.lowerLimit3 - angle3;
  3689. } else if (angle3 > this.upperLimit3) {
  3690. if (this.limitState3 != 1) {
  3691. this.limitState3 = 1;
  3692. this.limitImpulse3 = 0;
  3693. }
  3694. this.limitVelocity3 = this.upperLimit3 - angle3;
  3695. } else {
  3696. this.limitState3 = 2;
  3697. this.limitImpulse3 = 0;
  3698. this.limitVelocity3 = 0;
  3699. }
  3700. if (!enableSpring3) {
  3701. if (this.limitVelocity3 > 0.02) this.limitVelocity3 -= 0.02;
  3702. else if (this.limitVelocity3 < -0.02) this.limitVelocity3 += 0.02;
  3703. else this.limitVelocity3 = 0;
  3704. }
  3705. } else {
  3706. this.limitState3 = 2;
  3707. this.limitImpulse3 = 0;
  3708. }
  3709. if (this.enableMotor1 && (this.limitState1 != 0 || enableSpring1)) {
  3710. this.maxMotorImpulse1 = this.maxMotorForce1 * timeStep;
  3711. } else {
  3712. this.motorImpulse1 = 0;
  3713. this.maxMotorImpulse1 = 0;
  3714. }
  3715. if (this.enableMotor2 && (this.limitState2 != 0 || enableSpring2)) {
  3716. this.maxMotorImpulse2 = this.maxMotorForce2 * timeStep;
  3717. } else {
  3718. this.motorImpulse2 = 0;
  3719. this.maxMotorImpulse2 = 0;
  3720. }
  3721. if (this.enableMotor3 && (this.limitState3 != 0 || enableSpring3)) {
  3722. this.maxMotorImpulse3 = this.maxMotorForce3 * timeStep;
  3723. } else {
  3724. this.motorImpulse3 = 0;
  3725. this.maxMotorImpulse3 = 0;
  3726. }
  3727. // build jacobians
  3728. this.a1x1 = this.ax1 * this.i1e00 + this.ay1 * this.i1e01 + this.az1 * this.i1e02;
  3729. this.a1y1 = this.ax1 * this.i1e10 + this.ay1 * this.i1e11 + this.az1 * this.i1e12;
  3730. this.a1z1 = this.ax1 * this.i1e20 + this.ay1 * this.i1e21 + this.az1 * this.i1e22;
  3731. this.a2x1 = this.ax1 * this.i2e00 + this.ay1 * this.i2e01 + this.az1 * this.i2e02;
  3732. this.a2y1 = this.ax1 * this.i2e10 + this.ay1 * this.i2e11 + this.az1 * this.i2e12;
  3733. this.a2z1 = this.ax1 * this.i2e20 + this.ay1 * this.i2e21 + this.az1 * this.i2e22;
  3734. this.a1x2 = this.ax2 * this.i1e00 + this.ay2 * this.i1e01 + this.az2 * this.i1e02;
  3735. this.a1y2 = this.ax2 * this.i1e10 + this.ay2 * this.i1e11 + this.az2 * this.i1e12;
  3736. this.a1z2 = this.ax2 * this.i1e20 + this.ay2 * this.i1e21 + this.az2 * this.i1e22;
  3737. this.a2x2 = this.ax2 * this.i2e00 + this.ay2 * this.i2e01 + this.az2 * this.i2e02;
  3738. this.a2y2 = this.ax2 * this.i2e10 + this.ay2 * this.i2e11 + this.az2 * this.i2e12;
  3739. this.a2z2 = this.ax2 * this.i2e20 + this.ay2 * this.i2e21 + this.az2 * this.i2e22;
  3740. this.a1x3 = this.ax3 * this.i1e00 + this.ay3 * this.i1e01 + this.az3 * this.i1e02;
  3741. this.a1y3 = this.ax3 * this.i1e10 + this.ay3 * this.i1e11 + this.az3 * this.i1e12;
  3742. this.a1z3 = this.ax3 * this.i1e20 + this.ay3 * this.i1e21 + this.az3 * this.i1e22;
  3743. this.a2x3 = this.ax3 * this.i2e00 + this.ay3 * this.i2e01 + this.az3 * this.i2e02;
  3744. this.a2y3 = this.ax3 * this.i2e10 + this.ay3 * this.i2e11 + this.az3 * this.i2e12;
  3745. this.a2z3 = this.ax3 * this.i2e20 + this.ay3 * this.i2e21 + this.az3 * this.i2e22;
  3746. // build an impulse matrix
  3747. this.k00 = this.ax1 * (this.a1x1 + this.a2x1) + this.ay1 * (this.a1y1 + this.a2y1) + this.az1 * (this.a1z1 + this.a2z1);
  3748. this.k01 = this.ax1 * (this.a1x2 + this.a2x2) + this.ay1 * (this.a1y2 + this.a2y2) + this.az1 * (this.a1z2 + this.a2z2);
  3749. this.k02 = this.ax1 * (this.a1x3 + this.a2x3) + this.ay1 * (this.a1y3 + this.a2y3) + this.az1 * (this.a1z3 + this.a2z3);
  3750. this.k10 = this.ax2 * (this.a1x1 + this.a2x1) + this.ay2 * (this.a1y1 + this.a2y1) + this.az2 * (this.a1z1 + this.a2z1);
  3751. this.k11 = this.ax2 * (this.a1x2 + this.a2x2) + this.ay2 * (this.a1y2 + this.a2y2) + this.az2 * (this.a1z2 + this.a2z2);
  3752. this.k12 = this.ax2 * (this.a1x3 + this.a2x3) + this.ay2 * (this.a1y3 + this.a2y3) + this.az2 * (this.a1z3 + this.a2z3);
  3753. this.k20 = this.ax3 * (this.a1x1 + this.a2x1) + this.ay3 * (this.a1y1 + this.a2y1) + this.az3 * (this.a1z1 + this.a2z1);
  3754. this.k21 = this.ax3 * (this.a1x2 + this.a2x2) + this.ay3 * (this.a1y2 + this.a2y2) + this.az3 * (this.a1z2 + this.a2z2);
  3755. this.k22 = this.ax3 * (this.a1x3 + this.a2x3) + this.ay3 * (this.a1y3 + this.a2y3) + this.az3 * (this.a1z3 + this.a2z3);
  3756. this.kv00 = this.k00;
  3757. this.kv11 = this.k11;
  3758. this.kv22 = this.k22;
  3759. this.dv00 = 1 / this.kv00;
  3760. this.dv11 = 1 / this.kv11;
  3761. this.dv22 = 1 / this.kv22;
  3762. if (enableSpring1 && this.limitState1 != 2) {
  3763. var omega = 6.2831853 * frequency1;
  3764. var k = omega * omega * timeStep;
  3765. var dmp = invTimeStep / (k + 2 * this.limitMotor1.dampingRatio * omega);
  3766. this.cfm1 = this.kv00 * dmp;
  3767. this.limitVelocity1 *= k * dmp;
  3768. } else {
  3769. this.cfm1 = 0;
  3770. this.limitVelocity1 *= invTimeStep * 0.05;
  3771. }
  3772. if (enableSpring2 && this.limitState2 != 2) {
  3773. omega = 6.2831853 * frequency2;
  3774. k = omega * omega * timeStep;
  3775. dmp = invTimeStep / (k + 2 * this.limitMotor2.dampingRatio * omega);
  3776. this.cfm2 = this.kv11 * dmp;
  3777. this.limitVelocity2 *= k * dmp;
  3778. } else {
  3779. this.cfm2 = 0;
  3780. this.limitVelocity2 *= invTimeStep * 0.05;
  3781. }
  3782. if (enableSpring3 && this.limitState3 != 2) {
  3783. omega = 6.2831853 * frequency3;
  3784. k = omega * omega * timeStep;
  3785. dmp = invTimeStep / (k + 2 * this.limitMotor3.dampingRatio * omega);
  3786. this.cfm3 = this.kv22 * dmp;
  3787. this.limitVelocity3 *= k * dmp;
  3788. } else {
  3789. this.cfm3 = 0;
  3790. this.limitVelocity3 *= invTimeStep * 0.05;
  3791. }
  3792. this.k00 += this.cfm1;
  3793. this.k11 += this.cfm2;
  3794. this.k22 += this.cfm3;
  3795. var inv = 1 / (
  3796. this.k00 * (this.k11 * this.k22 - this.k21 * this.k12) +
  3797. this.k10 * (this.k21 * this.k02 - this.k01 * this.k22) +
  3798. this.k20 * (this.k01 * this.k12 - this.k11 * this.k02)
  3799. );
  3800. this.d00 = (this.k11 * this.k22 - this.k12 * this.k21) * inv;
  3801. this.d01 = (this.k02 * this.k21 - this.k01 * this.k22) * inv;
  3802. this.d02 = (this.k01 * this.k12 - this.k02 * this.k11) * inv;
  3803. this.d10 = (this.k12 * this.k20 - this.k10 * this.k22) * inv;
  3804. this.d11 = (this.k00 * this.k22 - this.k02 * this.k20) * inv;
  3805. this.d12 = (this.k02 * this.k10 - this.k00 * this.k12) * inv;
  3806. this.d20 = (this.k10 * this.k21 - this.k11 * this.k20) * inv;
  3807. this.d21 = (this.k01 * this.k20 - this.k00 * this.k21) * inv;
  3808. this.d22 = (this.k00 * this.k11 - this.k01 * this.k10) * inv;
  3809. this.limitImpulse1 *= 0.95;
  3810. this.motorImpulse1 *= 0.95;
  3811. this.limitImpulse2 *= 0.95;
  3812. this.motorImpulse2 *= 0.95;
  3813. this.limitImpulse3 *= 0.95;
  3814. this.motorImpulse3 *= 0.95;
  3815. var totalImpulse1 = this.limitImpulse1 + this.motorImpulse1;
  3816. var totalImpulse2 = this.limitImpulse2 + this.motorImpulse2;
  3817. var totalImpulse3 = this.limitImpulse3 + this.motorImpulse3;
  3818. this.a1.x += totalImpulse1 * this.a1x1 + totalImpulse2 * this.a1x2 + totalImpulse3 * this.a1x3;
  3819. this.a1.y += totalImpulse1 * this.a1y1 + totalImpulse2 * this.a1y2 + totalImpulse3 * this.a1y3;
  3820. this.a1.z += totalImpulse1 * this.a1z1 + totalImpulse2 * this.a1z2 + totalImpulse3 * this.a1z3;
  3821. this.a2.x -= totalImpulse1 * this.a2x1 + totalImpulse2 * this.a2x2 + totalImpulse3 * this.a2x3;
  3822. this.a2.y -= totalImpulse1 * this.a2y1 + totalImpulse2 * this.a2y2 + totalImpulse3 * this.a2y3;
  3823. this.a2.z -= totalImpulse1 * this.a2z1 + totalImpulse2 * this.a2z2 + totalImpulse3 * this.a2z3;
  3824. },
  3825. solve_: function () {
  3826. var rvx = this.a2.x - this.a1.x;
  3827. var rvy = this.a2.y - this.a1.y;
  3828. var rvz = this.a2.z - this.a1.z;
  3829. this.limitVelocity3 = 30;
  3830. var rvn1 = rvx * this.ax1 + rvy * this.ay1 + rvz * this.az1 - this.limitVelocity1;
  3831. var rvn2 = rvx * this.ax2 + rvy * this.ay2 + rvz * this.az2 - this.limitVelocity2;
  3832. var rvn3 = rvx * this.ax3 + rvy * this.ay3 + rvz * this.az3 - this.limitVelocity3;
  3833. var dLimitImpulse1 = rvn1 * this.d00 + rvn2 * this.d01 + rvn3 * this.d02;
  3834. var dLimitImpulse2 = rvn1 * this.d10 + rvn2 * this.d11 + rvn3 * this.d12;
  3835. var dLimitImpulse3 = rvn1 * this.d20 + rvn2 * this.d21 + rvn3 * this.d22;
  3836. this.limitImpulse1 += dLimitImpulse1;
  3837. this.limitImpulse2 += dLimitImpulse2;
  3838. this.limitImpulse3 += dLimitImpulse3;
  3839. this.a1.x += dLimitImpulse1 * this.a1x1 + dLimitImpulse2 * this.a1x2 + dLimitImpulse3 * this.a1x3;
  3840. this.a1.y += dLimitImpulse1 * this.a1y1 + dLimitImpulse2 * this.a1y2 + dLimitImpulse3 * this.a1y3;
  3841. this.a1.z += dLimitImpulse1 * this.a1z1 + dLimitImpulse2 * this.a1z2 + dLimitImpulse3 * this.a1z3;
  3842. this.a2.x -= dLimitImpulse1 * this.a2x1 + dLimitImpulse2 * this.a2x2 + dLimitImpulse3 * this.a2x3;
  3843. this.a2.y -= dLimitImpulse1 * this.a2y1 + dLimitImpulse2 * this.a2y2 + dLimitImpulse3 * this.a2y3;
  3844. this.a2.z -= dLimitImpulse1 * this.a2z1 + dLimitImpulse2 * this.a2z2 + dLimitImpulse3 * this.a2z3;
  3845. },
  3846. solve: function () {
  3847. var rvx = this.a2.x - this.a1.x;
  3848. var rvy = this.a2.y - this.a1.y;
  3849. var rvz = this.a2.z - this.a1.z;
  3850. var rvn1 = rvx * this.ax1 + rvy * this.ay1 + rvz * this.az1;
  3851. var rvn2 = rvx * this.ax2 + rvy * this.ay2 + rvz * this.az2;
  3852. var rvn3 = rvx * this.ax3 + rvy * this.ay3 + rvz * this.az3;
  3853. var oldMotorImpulse1 = this.motorImpulse1;
  3854. var oldMotorImpulse2 = this.motorImpulse2;
  3855. var oldMotorImpulse3 = this.motorImpulse3;
  3856. var dMotorImpulse1 = 0;
  3857. var dMotorImpulse2 = 0;
  3858. var dMotorImpulse3 = 0;
  3859. if (this.enableMotor1) {
  3860. dMotorImpulse1 = (rvn1 - this.motorSpeed1) * this.dv00;
  3861. this.motorImpulse1 += dMotorImpulse1;
  3862. if (this.motorImpulse1 > this.maxMotorImpulse1) { // clamp motor impulse
  3863. this.motorImpulse1 = this.maxMotorImpulse1;
  3864. } else if (this.motorImpulse1 < -this.maxMotorImpulse1) {
  3865. this.motorImpulse1 = -this.maxMotorImpulse1;
  3866. }
  3867. dMotorImpulse1 = this.motorImpulse1 - oldMotorImpulse1;
  3868. }
  3869. if (this.enableMotor2) {
  3870. dMotorImpulse2 = (rvn2 - this.motorSpeed2) * this.dv11;
  3871. this.motorImpulse2 += dMotorImpulse2;
  3872. if (this.motorImpulse2 > this.maxMotorImpulse2) { // clamp motor impulse
  3873. this.motorImpulse2 = this.maxMotorImpulse2;
  3874. } else if (this.motorImpulse2 < -this.maxMotorImpulse2) {
  3875. this.motorImpulse2 = -this.maxMotorImpulse2;
  3876. }
  3877. dMotorImpulse2 = this.motorImpulse2 - oldMotorImpulse2;
  3878. }
  3879. if (this.enableMotor3) {
  3880. dMotorImpulse3 = (rvn3 - this.motorSpeed3) * this.dv22;
  3881. this.motorImpulse3 += dMotorImpulse3;
  3882. if (this.motorImpulse3 > this.maxMotorImpulse3) { // clamp motor impulse
  3883. this.motorImpulse3 = this.maxMotorImpulse3;
  3884. } else if (this.motorImpulse3 < -this.maxMotorImpulse3) {
  3885. this.motorImpulse3 = -this.maxMotorImpulse3;
  3886. }
  3887. dMotorImpulse3 = this.motorImpulse3 - oldMotorImpulse3;
  3888. }
  3889. // apply motor impulse to relative velocity
  3890. rvn1 += dMotorImpulse1 * this.kv00 + dMotorImpulse2 * this.k01 + dMotorImpulse3 * this.k02;
  3891. rvn2 += dMotorImpulse1 * this.k10 + dMotorImpulse2 * this.kv11 + dMotorImpulse3 * this.k12;
  3892. rvn3 += dMotorImpulse1 * this.k20 + dMotorImpulse2 * this.k21 + dMotorImpulse3 * this.kv22;
  3893. // subtract target velocity and applied impulse
  3894. rvn1 -= this.limitVelocity1 + this.limitImpulse1 * this.cfm1;
  3895. rvn2 -= this.limitVelocity2 + this.limitImpulse2 * this.cfm2;
  3896. rvn3 -= this.limitVelocity3 + this.limitImpulse3 * this.cfm3;
  3897. var oldLimitImpulse1 = this.limitImpulse1;
  3898. var oldLimitImpulse2 = this.limitImpulse2;
  3899. var oldLimitImpulse3 = this.limitImpulse3;
  3900. var dLimitImpulse1 = rvn1 * this.d00 + rvn2 * this.d01 + rvn3 * this.d02;
  3901. var dLimitImpulse2 = rvn1 * this.d10 + rvn2 * this.d11 + rvn3 * this.d12;
  3902. var dLimitImpulse3 = rvn1 * this.d20 + rvn2 * this.d21 + rvn3 * this.d22;
  3903. this.limitImpulse1 += dLimitImpulse1;
  3904. this.limitImpulse2 += dLimitImpulse2;
  3905. this.limitImpulse3 += dLimitImpulse3;
  3906. // clamp
  3907. var clampState = 0;
  3908. if (this.limitState1 == 2 || this.limitImpulse1 * this.limitState1 < 0) {
  3909. dLimitImpulse1 = -oldLimitImpulse1;
  3910. rvn2 += dLimitImpulse1 * this.k10;
  3911. rvn3 += dLimitImpulse1 * this.k20;
  3912. clampState |= 1;
  3913. }
  3914. if (this.limitState2 == 2 || this.limitImpulse2 * this.limitState2 < 0) {
  3915. dLimitImpulse2 = -oldLimitImpulse2;
  3916. rvn1 += dLimitImpulse2 * this.k01;
  3917. rvn3 += dLimitImpulse2 * this.k21;
  3918. clampState |= 2;
  3919. }
  3920. if (this.limitState3 == 2 || this.limitImpulse3 * this.limitState3 < 0) {
  3921. dLimitImpulse3 = -oldLimitImpulse3;
  3922. rvn1 += dLimitImpulse3 * this.k02;
  3923. rvn2 += dLimitImpulse3 * this.k12;
  3924. clampState |= 4;
  3925. }
  3926. // update un-clamped impulse
  3927. // TODO: isolate division
  3928. var det;
  3929. switch (clampState) {
  3930. case 1: // update 2 3
  3931. det = 1 / (this.k11 * this.k22 - this.k12 * this.k21);
  3932. dLimitImpulse2 = (this.k22 * rvn2 + -this.k12 * rvn3) * det;
  3933. dLimitImpulse3 = (-this.k21 * rvn2 + this.k11 * rvn3) * det;
  3934. break;
  3935. case 2: // update 1 3
  3936. det = 1 / (this.k00 * this.k22 - this.k02 * this.k20);
  3937. dLimitImpulse1 = (this.k22 * rvn1 + -this.k02 * rvn3) * det;
  3938. dLimitImpulse3 = (-this.k20 * rvn1 + this.k00 * rvn3) * det;
  3939. break;
  3940. case 3: // update 3
  3941. dLimitImpulse3 = rvn3 / this.k22;
  3942. break;
  3943. case 4: // update 1 2
  3944. det = 1 / (this.k00 * this.k11 - this.k01 * this.k10);
  3945. dLimitImpulse1 = (this.k11 * rvn1 + -this.k01 * rvn2) * det;
  3946. dLimitImpulse2 = (-this.k10 * rvn1 + this.k00 * rvn2) * det;
  3947. break;
  3948. case 5: // update 2
  3949. dLimitImpulse2 = rvn2 / this.k11;
  3950. break;
  3951. case 6: // update 1
  3952. dLimitImpulse1 = rvn1 / this.k00;
  3953. break;
  3954. }
  3955. this.limitImpulse1 = dLimitImpulse1 + oldLimitImpulse1;
  3956. this.limitImpulse2 = dLimitImpulse2 + oldLimitImpulse2;
  3957. this.limitImpulse3 = dLimitImpulse3 + oldLimitImpulse3;
  3958. var dImpulse1 = dMotorImpulse1 + dLimitImpulse1;
  3959. var dImpulse2 = dMotorImpulse2 + dLimitImpulse2;
  3960. var dImpulse3 = dMotorImpulse3 + dLimitImpulse3;
  3961. // apply impulse
  3962. this.a1.x += dImpulse1 * this.a1x1 + dImpulse2 * this.a1x2 + dImpulse3 * this.a1x3;
  3963. this.a1.y += dImpulse1 * this.a1y1 + dImpulse2 * this.a1y2 + dImpulse3 * this.a1y3;
  3964. this.a1.z += dImpulse1 * this.a1z1 + dImpulse2 * this.a1z2 + dImpulse3 * this.a1z3;
  3965. this.a2.x -= dImpulse1 * this.a2x1 + dImpulse2 * this.a2x2 + dImpulse3 * this.a2x3;
  3966. this.a2.y -= dImpulse1 * this.a2y1 + dImpulse2 * this.a2y2 + dImpulse3 * this.a2y3;
  3967. this.a2.z -= dImpulse1 * this.a2z1 + dImpulse2 * this.a2z2 + dImpulse3 * this.a2z3;
  3968. rvx = this.a2.x - this.a1.x;
  3969. rvy = this.a2.y - this.a1.y;
  3970. rvz = this.a2.z - this.a1.z;
  3971. rvn2 = rvx * this.ax2 + rvy * this.ay2 + rvz * this.az2;
  3972. }
  3973. }
  3974. /**
  3975. * A rotational constraint for various joints.
  3976. * @author saharan
  3977. */
  3978. OIMO.RotationalConstraint = function (joint, limitMotor) {
  3979. this.cfm = NaN;
  3980. this.i1e00 = NaN;
  3981. this.i1e01 = NaN;
  3982. this.i1e02 = NaN;
  3983. this.i1e10 = NaN;
  3984. this.i1e11 = NaN;
  3985. this.i1e12 = NaN;
  3986. this.i1e20 = NaN;
  3987. this.i1e21 = NaN;
  3988. this.i1e22 = NaN;
  3989. this.i2e00 = NaN;
  3990. this.i2e01 = NaN;
  3991. this.i2e02 = NaN;
  3992. this.i2e10 = NaN;
  3993. this.i2e11 = NaN;
  3994. this.i2e12 = NaN;
  3995. this.i2e20 = NaN;
  3996. this.i2e21 = NaN;
  3997. this.i2e22 = NaN;
  3998. this.motorDenom = NaN;
  3999. this.invMotorDenom = NaN;
  4000. this.invDenom = NaN;
  4001. this.ax = NaN;
  4002. this.ay = NaN;
  4003. this.az = NaN;
  4004. this.a1x = NaN;
  4005. this.a1y = NaN;
  4006. this.a1z = NaN;
  4007. this.a2x = NaN;
  4008. this.a2y = NaN;
  4009. this.a2z = NaN;
  4010. this.enableLimit = false;
  4011. this.lowerLimit = NaN;
  4012. this.upperLimit = NaN;
  4013. this.limitVelocity = NaN;
  4014. this.limitState = 0; // -1: at lower, 0: locked, 1: at upper, 2: free
  4015. this.enableMotor = false;
  4016. this.motorSpeed = NaN;
  4017. this.maxMotorForce = NaN;
  4018. this.maxMotorImpulse = NaN;
  4019. this.limitMotor = limitMotor;
  4020. this.b1 = joint.body1;
  4021. this.b2 = joint.body2;
  4022. this.a1 = this.b1.angularVelocity;
  4023. this.a2 = this.b2.angularVelocity;
  4024. this.i1 = this.b1.inverseInertia;
  4025. this.i2 = this.b2.inverseInertia;
  4026. this.limitImpulse = 0;
  4027. this.motorImpulse = 0;
  4028. }
  4029. OIMO.RotationalConstraint.prototype = {
  4030. constructor: OIMO.RotationalConstraint,
  4031. preSolve: function (timeStep, invTimeStep) {
  4032. this.ax = this.limitMotor.axis.x;
  4033. this.ay = this.limitMotor.axis.y;
  4034. this.az = this.limitMotor.axis.z;
  4035. this.lowerLimit = this.limitMotor.lowerLimit;
  4036. this.upperLimit = this.limitMotor.upperLimit;
  4037. this.motorSpeed = this.limitMotor.motorSpeed;
  4038. this.maxMotorForce = this.limitMotor.maxMotorForce;
  4039. this.enableMotor = this.maxMotorForce > 0;
  4040. var ti1 = this.i1.elements;
  4041. var ti2 = this.i2.elements;
  4042. this.i1e00 = ti1[0];
  4043. this.i1e01 = ti1[1];
  4044. this.i1e02 = ti1[2];
  4045. this.i1e10 = ti1[3];
  4046. this.i1e11 = ti1[4];
  4047. this.i1e12 = ti1[5];
  4048. this.i1e20 = ti1[6];
  4049. this.i1e21 = ti1[7];
  4050. this.i1e22 = ti1[8];
  4051. this.i2e00 = ti2[0];
  4052. this.i2e01 = ti2[1];
  4053. this.i2e02 = ti2[2];
  4054. this.i2e10 = ti2[3];
  4055. this.i2e11 = ti2[4];
  4056. this.i2e12 = ti2[5];
  4057. this.i2e20 = ti2[6];
  4058. this.i2e21 = ti2[7];
  4059. this.i2e22 = ti2[8];
  4060. var frequency = this.limitMotor.frequency;
  4061. var enableSpring = frequency > 0;
  4062. var enableLimit = this.lowerLimit <= this.upperLimit;
  4063. var angle = this.limitMotor.angle;
  4064. if (enableLimit) {
  4065. if (this.lowerLimit == this.upperLimit) {
  4066. if (this.limitState != 0) {
  4067. this.limitState = 0;
  4068. this.limitImpulse = 0;
  4069. }
  4070. this.limitVelocity = this.lowerLimit - angle;
  4071. } else if (angle < this.lowerLimit) {
  4072. if (this.limitState != -1) {
  4073. this.limitState = -1;
  4074. this.limitImpulse = 0;
  4075. }
  4076. this.limitVelocity = this.lowerLimit - angle;
  4077. } else if (angle > this.upperLimit) {
  4078. if (this.limitState != 1) {
  4079. this.limitState = 1;
  4080. this.limitImpulse = 0;
  4081. }
  4082. this.limitVelocity = this.upperLimit - angle;
  4083. } else {
  4084. this.limitState = 2;
  4085. this.limitImpulse = 0;
  4086. this.limitVelocity = 0;
  4087. }
  4088. if (!enableSpring) {
  4089. if (this.limitVelocity > 0.02) this.limitVelocity -= 0.02;
  4090. else if (this.limitVelocity < -0.02) this.limitVelocity += 0.02;
  4091. else this.limitVelocity = 0;
  4092. }
  4093. } else {
  4094. this.limitState = 2;
  4095. this.limitImpulse = 0;
  4096. }
  4097. if (this.enableMotor && (this.limitState != 0 || enableSpring)) {
  4098. this.maxMotorImpulse = this.maxMotorForce * timeStep;
  4099. } else {
  4100. this.motorImpulse = 0;
  4101. this.maxMotorImpulse = 0;
  4102. }
  4103. this.a1x = this.ax * this.i1e00 + this.ay * this.i1e01 + this.az * this.i1e02;
  4104. this.a1y = this.ax * this.i1e10 + this.ay * this.i1e11 + this.az * this.i1e12;
  4105. this.a1z = this.ax * this.i1e20 + this.ay * this.i1e21 + this.az * this.i1e22;
  4106. this.a2x = this.ax * this.i2e00 + this.ay * this.i2e01 + this.az * this.i2e02;
  4107. this.a2y = this.ax * this.i2e10 + this.ay * this.i2e11 + this.az * this.i2e12;
  4108. this.a2z = this.ax * this.i2e20 + this.ay * this.i2e21 + this.az * this.i2e22;
  4109. this.motorDenom = this.ax * (this.a1x + this.a2x) + this.ay * (this.a1y + this.a2y) + this.az * (this.a1z + this.a2z);
  4110. this.invMotorDenom = 1 / this.motorDenom;
  4111. if (enableSpring && this.limitState != 2) {
  4112. var omega = 6.2831853 * frequency;
  4113. var k = omega * omega * timeStep;
  4114. var dmp = invTimeStep / (k + 2 * this.limitMotor.dampingRatio * omega);
  4115. this.cfm = this.motorDenom * dmp;
  4116. this.limitVelocity *= k * dmp;
  4117. } else {
  4118. this.cfm = 0;
  4119. this.limitVelocity *= invTimeStep * 0.05;
  4120. }
  4121. this.invDenom = 1 / (this.motorDenom + this.cfm);
  4122. this.limitImpulse *= 0.95;
  4123. this.motorImpulse *= 0.95;
  4124. var totalImpulse = this.limitImpulse + this.motorImpulse;
  4125. this.a1.x += totalImpulse * this.a1x;
  4126. this.a1.y += totalImpulse * this.a1y;
  4127. this.a1.z += totalImpulse * this.a1z;
  4128. this.a2.x -= totalImpulse * this.a2x;
  4129. this.a2.y -= totalImpulse * this.a2y;
  4130. this.a2.z -= totalImpulse * this.a2z;
  4131. },
  4132. solve: function () {
  4133. var rvn = this.ax * (this.a2.x - this.a1.x) + this.ay * (this.a2.y - this.a1.y) + this.az * (this.a2.z - this.a1.z);
  4134. // motor part
  4135. var newMotorImpulse;
  4136. if (this.enableMotor) {
  4137. newMotorImpulse = (rvn - this.motorSpeed) * this.invMotorDenom;
  4138. var oldMotorImpulse = this.motorImpulse;
  4139. this.motorImpulse += newMotorImpulse;
  4140. if (this.motorImpulse > this.maxMotorImpulse) this.motorImpulse = this.maxMotorImpulse;
  4141. else if (this.motorImpulse < -this.maxMotorImpulse) this.motorImpulse = -this.maxMotorImpulse;
  4142. newMotorImpulse = this.motorImpulse - oldMotorImpulse;
  4143. rvn -= newMotorImpulse * this.motorDenom;
  4144. } else newMotorImpulse = 0;
  4145. // limit part
  4146. var newLimitImpulse;
  4147. if (this.limitState != 2) {
  4148. newLimitImpulse = (rvn - this.limitVelocity - this.limitImpulse * this.cfm) * this.invDenom;
  4149. var oldLimitImpulse = this.limitImpulse;
  4150. this.limitImpulse += newLimitImpulse;
  4151. if (this.limitImpulse * this.limitState < 0) this.limitImpulse = 0;
  4152. newLimitImpulse = this.limitImpulse - oldLimitImpulse;
  4153. } else newLimitImpulse = 0;
  4154. var totalImpulse = newLimitImpulse + newMotorImpulse;
  4155. this.a1.x += totalImpulse * this.a1x;
  4156. this.a1.y += totalImpulse * this.a1y;
  4157. this.a1.z += totalImpulse * this.a1z;
  4158. this.a2.x -= totalImpulse * this.a2x;
  4159. this.a2.y -= totalImpulse * this.a2y;
  4160. this.a2.z -= totalImpulse * this.a2z;
  4161. }
  4162. }
  4163. /**
  4164. * A three-axis translational constraint for various joints.
  4165. * @author saharan
  4166. */
  4167. OIMO.Translational3Constraint = function (joint, limitMotor1, limitMotor2, limitMotor3) {
  4168. this.m1 = NaN;
  4169. this.m2 = NaN;
  4170. this.i1e00 = NaN;
  4171. this.i1e01 = NaN;
  4172. this.i1e02 = NaN;
  4173. this.i1e10 = NaN;
  4174. this.i1e11 = NaN;
  4175. this.i1e12 = NaN;
  4176. this.i1e20 = NaN;
  4177. this.i1e21 = NaN;
  4178. this.i1e22 = NaN;
  4179. this.i2e00 = NaN;
  4180. this.i2e01 = NaN;
  4181. this.i2e02 = NaN;
  4182. this.i2e10 = NaN;
  4183. this.i2e11 = NaN;
  4184. this.i2e12 = NaN;
  4185. this.i2e20 = NaN;
  4186. this.i2e21 = NaN;
  4187. this.i2e22 = NaN;
  4188. this.ax1 = NaN;
  4189. this.ay1 = NaN;
  4190. this.az1 = NaN;
  4191. this.ax2 = NaN;
  4192. this.ay2 = NaN;
  4193. this.az2 = NaN;
  4194. this.ax3 = NaN;
  4195. this.ay3 = NaN;
  4196. this.az3 = NaN;
  4197. this.r1x = NaN;
  4198. this.r1y = NaN;
  4199. this.r1z = NaN;
  4200. this.r2x = NaN;
  4201. this.r2y = NaN;
  4202. this.r2z = NaN;
  4203. this.t1x1 = NaN;// jacobians
  4204. this.t1y1 = NaN;
  4205. this.t1z1 = NaN;
  4206. this.t2x1 = NaN;
  4207. this.t2y1 = NaN;
  4208. this.t2z1 = NaN;
  4209. this.l1x1 = NaN;
  4210. this.l1y1 = NaN;
  4211. this.l1z1 = NaN;
  4212. this.l2x1 = NaN;
  4213. this.l2y1 = NaN;
  4214. this.l2z1 = NaN;
  4215. this.a1x1 = NaN;
  4216. this.a1y1 = NaN;
  4217. this.a1z1 = NaN;
  4218. this.a2x1 = NaN;
  4219. this.a2y1 = NaN;
  4220. this.a2z1 = NaN;
  4221. this.t1x2 = NaN;
  4222. this.t1y2 = NaN;
  4223. this.t1z2 = NaN;
  4224. this.t2x2 = NaN;
  4225. this.t2y2 = NaN;
  4226. this.t2z2 = NaN;
  4227. this.l1x2 = NaN;
  4228. this.l1y2 = NaN;
  4229. this.l1z2 = NaN;
  4230. this.l2x2 = NaN;
  4231. this.l2y2 = NaN;
  4232. this.l2z2 = NaN;
  4233. this.a1x2 = NaN;
  4234. this.a1y2 = NaN;
  4235. this.a1z2 = NaN;
  4236. this.a2x2 = NaN;
  4237. this.a2y2 = NaN;
  4238. this.a2z2 = NaN;
  4239. this.t1x3 = NaN;
  4240. this.t1y3 = NaN;
  4241. this.t1z3 = NaN;
  4242. this.t2x3 = NaN;
  4243. this.t2y3 = NaN;
  4244. this.t2z3 = NaN;
  4245. this.l1x3 = NaN;
  4246. this.l1y3 = NaN;
  4247. this.l1z3 = NaN;
  4248. this.l2x3 = NaN;
  4249. this.l2y3 = NaN;
  4250. this.l2z3 = NaN;
  4251. this.a1x3 = NaN;
  4252. this.a1y3 = NaN;
  4253. this.a1z3 = NaN;
  4254. this.a2x3 = NaN;
  4255. this.a2y3 = NaN;
  4256. this.a2z3 = NaN;
  4257. this.lowerLimit1 = NaN;
  4258. this.upperLimit1 = NaN;
  4259. this.limitVelocity1 = NaN;
  4260. this.limitState1 = 0; // -1: at lower, 0: locked, 1: at upper, 2: unlimited
  4261. this.enableMotor1 = false;
  4262. this.motorSpeed1 = NaN;
  4263. this.maxMotorForce1 = NaN;
  4264. this.maxMotorImpulse1 = NaN;
  4265. this.lowerLimit2 = NaN;
  4266. this.upperLimit2 = NaN;
  4267. this.limitVelocity2 = NaN;
  4268. this.limitState2 = 0; // -1: at lower, 0: locked, 1: at upper, 2: unlimited
  4269. this.enableMotor2 = false;
  4270. this.motorSpeed2 = NaN;
  4271. this.maxMotorForce2 = NaN;
  4272. this.maxMotorImpulse2 = NaN;
  4273. this.lowerLimit3 = NaN;
  4274. this.upperLimit3 = NaN;
  4275. this.limitVelocity3 = NaN;
  4276. this.limitState3 = 0; // -1: at lower, 0: locked, 1: at upper, 2: unlimited
  4277. this.enableMotor3 = false;
  4278. this.motorSpeed3 = NaN;
  4279. this.maxMotorForce3 = NaN;
  4280. this.maxMotorImpulse3 = NaN;
  4281. this.k00 = NaN; // K = J*M*JT
  4282. this.k01 = NaN;
  4283. this.k02 = NaN;
  4284. this.k10 = NaN;
  4285. this.k11 = NaN;
  4286. this.k12 = NaN;
  4287. this.k20 = NaN;
  4288. this.k21 = NaN;
  4289. this.k22 = NaN;
  4290. this.kv00 = NaN; // diagonals without CFMs
  4291. this.kv11 = NaN;
  4292. this.kv22 = NaN;
  4293. this.dv00 = NaN; // ...inverted
  4294. this.dv11 = NaN;
  4295. this.dv22 = NaN;
  4296. this.d00 = NaN; // K^-1
  4297. this.d01 = NaN;
  4298. this.d02 = NaN;
  4299. this.d10 = NaN;
  4300. this.d11 = NaN;
  4301. this.d12 = NaN;
  4302. this.d20 = NaN;
  4303. this.d21 = NaN;
  4304. this.d22 = NaN;
  4305. this.limitMotor1 = limitMotor1;
  4306. this.limitMotor2 = limitMotor2;
  4307. this.limitMotor3 = limitMotor3;
  4308. this.b1 = joint.body1;
  4309. this.b2 = joint.body2;
  4310. this.p1 = joint.anchorPoint1;
  4311. this.p2 = joint.anchorPoint2;
  4312. this.r1 = joint.relativeAnchorPoint1;
  4313. this.r2 = joint.relativeAnchorPoint2;
  4314. this.l1 = this.b1.linearVelocity;
  4315. this.l2 = this.b2.linearVelocity;
  4316. this.a1 = this.b1.angularVelocity;
  4317. this.a2 = this.b2.angularVelocity;
  4318. this.i1 = this.b1.inverseInertia;
  4319. this.i2 = this.b2.inverseInertia;
  4320. this.limitImpulse1 = 0;
  4321. this.motorImpulse1 = 0;
  4322. this.limitImpulse2 = 0;
  4323. this.motorImpulse2 = 0;
  4324. this.limitImpulse3 = 0;
  4325. this.motorImpulse3 = 0;
  4326. this.cfm1 = 0;// Constraint Force Mixing
  4327. this.cfm2 = 0;
  4328. this.cfm3 = 0;
  4329. this.weight = -1;
  4330. }
  4331. OIMO.Translational3Constraint.prototype = {
  4332. constructor: OIMO.Translational3Constraint,
  4333. preSolve: function (timeStep, invTimeStep) {
  4334. this.ax1 = this.limitMotor1.axis.x;
  4335. this.ay1 = this.limitMotor1.axis.y;
  4336. this.az1 = this.limitMotor1.axis.z;
  4337. this.ax2 = this.limitMotor2.axis.x;
  4338. this.ay2 = this.limitMotor2.axis.y;
  4339. this.az2 = this.limitMotor2.axis.z;
  4340. this.ax3 = this.limitMotor3.axis.x;
  4341. this.ay3 = this.limitMotor3.axis.y;
  4342. this.az3 = this.limitMotor3.axis.z;
  4343. this.lowerLimit1 = this.limitMotor1.lowerLimit;
  4344. this.upperLimit1 = this.limitMotor1.upperLimit;
  4345. this.motorSpeed1 = this.limitMotor1.motorSpeed;
  4346. this.maxMotorForce1 = this.limitMotor1.maxMotorForce;
  4347. this.enableMotor1 = this.maxMotorForce1 > 0;
  4348. this.lowerLimit2 = this.limitMotor2.lowerLimit;
  4349. this.upperLimit2 = this.limitMotor2.upperLimit;
  4350. this.motorSpeed2 = this.limitMotor2.motorSpeed;
  4351. this.maxMotorForce2 = this.limitMotor2.maxMotorForce;
  4352. this.enableMotor2 = this.maxMotorForce2 > 0;
  4353. this.lowerLimit3 = this.limitMotor3.lowerLimit;
  4354. this.upperLimit3 = this.limitMotor3.upperLimit;
  4355. this.motorSpeed3 = this.limitMotor3.motorSpeed;
  4356. this.maxMotorForce3 = this.limitMotor3.maxMotorForce;
  4357. this.enableMotor3 = this.maxMotorForce3 > 0;
  4358. this.m1 = this.b1.inverseMass;
  4359. this.m2 = this.b2.inverseMass;
  4360. var ti1 = this.i1.elements;
  4361. var ti2 = this.i2.elements;
  4362. this.i1e00 = ti1[0];
  4363. this.i1e01 = ti1[1];
  4364. this.i1e02 = ti1[2];
  4365. this.i1e10 = ti1[3];
  4366. this.i1e11 = ti1[4];
  4367. this.i1e12 = ti1[5];
  4368. this.i1e20 = ti1[6];
  4369. this.i1e21 = ti1[7];
  4370. this.i1e22 = ti1[8];
  4371. this.i2e00 = ti2[0];
  4372. this.i2e01 = ti2[1];
  4373. this.i2e02 = ti2[2];
  4374. this.i2e10 = ti2[3];
  4375. this.i2e11 = ti2[4];
  4376. this.i2e12 = ti2[5];
  4377. this.i2e20 = ti2[6];
  4378. this.i2e21 = ti2[7];
  4379. this.i2e22 = ti2[8];
  4380. var dx = this.p2.x - this.p1.x;
  4381. var dy = this.p2.y - this.p1.y;
  4382. var dz = this.p2.z - this.p1.z;
  4383. var d1 = dx * this.ax1 + dy * this.ay1 + dz * this.az1;
  4384. var d2 = dx * this.ax2 + dy * this.ay2 + dz * this.az2;
  4385. var d3 = dx * this.ax3 + dy * this.ay3 + dz * this.az3;
  4386. var frequency1 = this.limitMotor1.frequency;
  4387. var frequency2 = this.limitMotor2.frequency;
  4388. var frequency3 = this.limitMotor3.frequency;
  4389. var enableSpring1 = frequency1 > 0;
  4390. var enableSpring2 = frequency2 > 0;
  4391. var enableSpring3 = frequency3 > 0;
  4392. var enableLimit1 = this.lowerLimit1 <= this.upperLimit1;
  4393. var enableLimit2 = this.lowerLimit2 <= this.upperLimit2;
  4394. var enableLimit3 = this.lowerLimit3 <= this.upperLimit3;
  4395. // for stability
  4396. if (enableSpring1 && d1 > 20 || d1 < -20) {
  4397. enableSpring1 = false;
  4398. }
  4399. if (enableSpring2 && d2 > 20 || d2 < -20) {
  4400. enableSpring2 = false;
  4401. }
  4402. if (enableSpring3 && d3 > 20 || d3 < -20) {
  4403. enableSpring3 = false;
  4404. }
  4405. if (enableLimit1) {
  4406. if (this.lowerLimit1 == this.upperLimit1) {
  4407. if (this.limitState1 != 0) {
  4408. this.limitState1 = 0;
  4409. this.limitImpulse1 = 0;
  4410. }
  4411. this.limitVelocity1 = this.lowerLimit1 - d1;
  4412. if (!enableSpring1) d1 = this.lowerLimit1;
  4413. } else if (d1 < this.lowerLimit1) {
  4414. if (this.limitState1 != -1) {
  4415. this.limitState1 = -1;
  4416. this.limitImpulse1 = 0;
  4417. }
  4418. this.limitVelocity1 = this.lowerLimit1 - d1;
  4419. if (!enableSpring1) d1 = this.lowerLimit1;
  4420. } else if (d1 > this.upperLimit1) {
  4421. if (this.limitState1 != 1) {
  4422. this.limitState1 = 1;
  4423. this.limitImpulse1 = 0;
  4424. }
  4425. this.limitVelocity1 = this.upperLimit1 - d1;
  4426. if (!enableSpring1) d1 = this.upperLimit1;
  4427. } else {
  4428. this.limitState1 = 2;
  4429. this.limitImpulse1 = 0;
  4430. this.limitVelocity1 = 0;
  4431. }
  4432. if (!enableSpring1) {
  4433. if (this.limitVelocity1 > 0.005) this.limitVelocity1 -= 0.005;
  4434. else if (this.limitVelocity1 < -0.005) this.limitVelocity1 += 0.005;
  4435. else this.limitVelocity1 = 0;
  4436. }
  4437. } else {
  4438. this.limitState1 = 2;
  4439. this.limitImpulse1 = 0;
  4440. }
  4441. if (enableLimit2) {
  4442. if (this.lowerLimit2 == this.upperLimit2) {
  4443. if (this.limitState2 != 0) {
  4444. this.limitState2 = 0;
  4445. this.limitImpulse2 = 0;
  4446. }
  4447. this.limitVelocity2 = this.lowerLimit2 - d2;
  4448. if (!enableSpring2) d2 = this.lowerLimit2;
  4449. } else if (d2 < this.lowerLimit2) {
  4450. if (this.limitState2 != -1) {
  4451. this.limitState2 = -1;
  4452. this.limitImpulse2 = 0;
  4453. }
  4454. this.limitVelocity2 = this.lowerLimit2 - d2;
  4455. if (!enableSpring2) d2 = this.lowerLimit2;
  4456. } else if (d2 > this.upperLimit2) {
  4457. if (this.limitState2 != 1) {
  4458. this.limitState2 = 1;
  4459. this.limitImpulse2 = 0;
  4460. }
  4461. this.limitVelocity2 = this.upperLimit2 - d2;
  4462. if (!enableSpring2) d2 = this.upperLimit2;
  4463. } else {
  4464. this.limitState2 = 2;
  4465. this.limitImpulse2 = 0;
  4466. this.limitVelocity2 = 0;
  4467. }
  4468. if (!enableSpring2) {
  4469. if (this.limitVelocity2 > 0.005) this.limitVelocity2 -= 0.005;
  4470. else if (this.limitVelocity2 < -0.005) this.limitVelocity2 += 0.005;
  4471. else this.limitVelocity2 = 0;
  4472. }
  4473. } else {
  4474. this.limitState2 = 2;
  4475. this.limitImpulse2 = 0;
  4476. }
  4477. if (enableLimit3) {
  4478. if (this.lowerLimit3 == this.upperLimit3) {
  4479. if (this.limitState3 != 0) {
  4480. this.limitState3 = 0;
  4481. this.limitImpulse3 = 0;
  4482. }
  4483. this.limitVelocity3 = this.lowerLimit3 - d3;
  4484. if (!enableSpring3) d3 = this.lowerLimit3;
  4485. } else if (d3 < this.lowerLimit3) {
  4486. if (this.limitState3 != -1) {
  4487. this.limitState3 = -1;
  4488. this.limitImpulse3 = 0;
  4489. }
  4490. this.limitVelocity3 = this.lowerLimit3 - d3;
  4491. if (!enableSpring3) d3 = this.lowerLimit3;
  4492. } else if (d3 > this.upperLimit3) {
  4493. if (this.limitState3 != 1) {
  4494. this.limitState3 = 1;
  4495. this.limitImpulse3 = 0;
  4496. }
  4497. this.limitVelocity3 = this.upperLimit3 - d3;
  4498. if (!enableSpring3) d3 = this.upperLimit3;
  4499. } else {
  4500. this.limitState3 = 2;
  4501. this.limitImpulse3 = 0;
  4502. this.limitVelocity3 = 0;
  4503. }
  4504. if (!enableSpring3) {
  4505. if (this.limitVelocity3 > 0.005) this.limitVelocity3 -= 0.005;
  4506. else if (this.limitVelocity3 < -0.005) this.limitVelocity3 += 0.005;
  4507. else this.limitVelocity3 = 0;
  4508. }
  4509. } else {
  4510. this.limitState3 = 2;
  4511. this.limitImpulse3 = 0;
  4512. }
  4513. if (this.enableMotor1 && (this.limitState1 != 0 || enableSpring1)) {
  4514. this.maxMotorImpulse1 = this.maxMotorForce1 * timeStep;
  4515. } else {
  4516. this.motorImpulse1 = 0;
  4517. this.maxMotorImpulse1 = 0;
  4518. }
  4519. if (this.enableMotor2 && (this.limitState2 != 0 || enableSpring2)) {
  4520. this.maxMotorImpulse2 = this.maxMotorForce2 * timeStep;
  4521. } else {
  4522. this.motorImpulse2 = 0;
  4523. this.maxMotorImpulse2 = 0;
  4524. }
  4525. if (this.enableMotor3 && (this.limitState3 != 0 || enableSpring3)) {
  4526. this.maxMotorImpulse3 = this.maxMotorForce3 * timeStep;
  4527. } else {
  4528. this.motorImpulse3 = 0;
  4529. this.maxMotorImpulse3 = 0;
  4530. }
  4531. var rdx = d1 * this.ax1 + d2 * this.ax2 + d3 * this.ax2;
  4532. var rdy = d1 * this.ay1 + d2 * this.ay2 + d3 * this.ay2;
  4533. var rdz = d1 * this.az1 + d2 * this.az2 + d3 * this.az2;
  4534. var w1 = this.m2 / (this.m1 + this.m2);
  4535. if (this.weight >= 0) w1 = this.weight; // use given weight
  4536. var w2 = 1 - w1;
  4537. this.r1x = this.r1.x + rdx * w1;
  4538. this.r1y = this.r1.y + rdy * w1;
  4539. this.r1z = this.r1.z + rdz * w1;
  4540. this.r2x = this.r2.x - rdx * w2;
  4541. this.r2y = this.r2.y - rdy * w2;
  4542. this.r2z = this.r2.z - rdz * w2;
  4543. // build jacobians
  4544. this.t1x1 = this.r1y * this.az1 - this.r1z * this.ay1;
  4545. this.t1y1 = this.r1z * this.ax1 - this.r1x * this.az1;
  4546. this.t1z1 = this.r1x * this.ay1 - this.r1y * this.ax1;
  4547. this.t2x1 = this.r2y * this.az1 - this.r2z * this.ay1;
  4548. this.t2y1 = this.r2z * this.ax1 - this.r2x * this.az1;
  4549. this.t2z1 = this.r2x * this.ay1 - this.r2y * this.ax1;
  4550. this.l1x1 = this.ax1 * this.m1;
  4551. this.l1y1 = this.ay1 * this.m1;
  4552. this.l1z1 = this.az1 * this.m1;
  4553. this.l2x1 = this.ax1 * this.m2;
  4554. this.l2y1 = this.ay1 * this.m2;
  4555. this.l2z1 = this.az1 * this.m2;
  4556. this.a1x1 = this.t1x1 * this.i1e00 + this.t1y1 * this.i1e01 + this.t1z1 * this.i1e02;
  4557. this.a1y1 = this.t1x1 * this.i1e10 + this.t1y1 * this.i1e11 + this.t1z1 * this.i1e12;
  4558. this.a1z1 = this.t1x1 * this.i1e20 + this.t1y1 * this.i1e21 + this.t1z1 * this.i1e22;
  4559. this.a2x1 = this.t2x1 * this.i2e00 + this.t2y1 * this.i2e01 + this.t2z1 * this.i2e02;
  4560. this.a2y1 = this.t2x1 * this.i2e10 + this.t2y1 * this.i2e11 + this.t2z1 * this.i2e12;
  4561. this.a2z1 = this.t2x1 * this.i2e20 + this.t2y1 * this.i2e21 + this.t2z1 * this.i2e22;
  4562. this.t1x2 = this.r1y * this.az2 - this.r1z * this.ay2;
  4563. this.t1y2 = this.r1z * this.ax2 - this.r1x * this.az2;
  4564. this.t1z2 = this.r1x * this.ay2 - this.r1y * this.ax2;
  4565. this.t2x2 = this.r2y * this.az2 - this.r2z * this.ay2;
  4566. this.t2y2 = this.r2z * this.ax2 - this.r2x * this.az2;
  4567. this.t2z2 = this.r2x * this.ay2 - this.r2y * this.ax2;
  4568. this.l1x2 = this.ax2 * this.m1;
  4569. this.l1y2 = this.ay2 * this.m1;
  4570. this.l1z2 = this.az2 * this.m1;
  4571. this.l2x2 = this.ax2 * this.m2;
  4572. this.l2y2 = this.ay2 * this.m2;
  4573. this.l2z2 = this.az2 * this.m2;
  4574. this.a1x2 = this.t1x2 * this.i1e00 + this.t1y2 * this.i1e01 + this.t1z2 * this.i1e02;
  4575. this.a1y2 = this.t1x2 * this.i1e10 + this.t1y2 * this.i1e11 + this.t1z2 * this.i1e12;
  4576. this.a1z2 = this.t1x2 * this.i1e20 + this.t1y2 * this.i1e21 + this.t1z2 * this.i1e22;
  4577. this.a2x2 = this.t2x2 * this.i2e00 + this.t2y2 * this.i2e01 + this.t2z2 * this.i2e02;
  4578. this.a2y2 = this.t2x2 * this.i2e10 + this.t2y2 * this.i2e11 + this.t2z2 * this.i2e12;
  4579. this.a2z2 = this.t2x2 * this.i2e20 + this.t2y2 * this.i2e21 + this.t2z2 * this.i2e22;
  4580. this.t1x3 = this.r1y * this.az3 - this.r1z * this.ay3;
  4581. this.t1y3 = this.r1z * this.ax3 - this.r1x * this.az3;
  4582. this.t1z3 = this.r1x * this.ay3 - this.r1y * this.ax3;
  4583. this.t2x3 = this.r2y * this.az3 - this.r2z * this.ay3;
  4584. this.t2y3 = this.r2z * this.ax3 - this.r2x * this.az3;
  4585. this.t2z3 = this.r2x * this.ay3 - this.r2y * this.ax3;
  4586. this.l1x3 = this.ax3 * this.m1;
  4587. this.l1y3 = this.ay3 * this.m1;
  4588. this.l1z3 = this.az3 * this.m1;
  4589. this.l2x3 = this.ax3 * this.m2;
  4590. this.l2y3 = this.ay3 * this.m2;
  4591. this.l2z3 = this.az3 * this.m2;
  4592. this.a1x3 = this.t1x3 * this.i1e00 + this.t1y3 * this.i1e01 + this.t1z3 * this.i1e02;
  4593. this.a1y3 = this.t1x3 * this.i1e10 + this.t1y3 * this.i1e11 + this.t1z3 * this.i1e12;
  4594. this.a1z3 = this.t1x3 * this.i1e20 + this.t1y3 * this.i1e21 + this.t1z3 * this.i1e22;
  4595. this.a2x3 = this.t2x3 * this.i2e00 + this.t2y3 * this.i2e01 + this.t2z3 * this.i2e02;
  4596. this.a2y3 = this.t2x3 * this.i2e10 + this.t2y3 * this.i2e11 + this.t2z3 * this.i2e12;
  4597. this.a2z3 = this.t2x3 * this.i2e20 + this.t2y3 * this.i2e21 + this.t2z3 * this.i2e22;
  4598. // build an impulse matrix
  4599. var m12 = this.m1 + this.m2;
  4600. this.k00 = (this.ax1 * this.ax1 + this.ay1 * this.ay1 + this.az1 * this.az1) * m12;
  4601. this.k01 = (this.ax1 * this.ax2 + this.ay1 * this.ay2 + this.az1 * this.az2) * m12;
  4602. this.k02 = (this.ax1 * this.ax3 + this.ay1 * this.ay3 + this.az1 * this.az3) * m12;
  4603. this.k10 = (this.ax2 * this.ax1 + this.ay2 * this.ay1 + this.az2 * this.az1) * m12;
  4604. this.k11 = (this.ax2 * this.ax2 + this.ay2 * this.ay2 + this.az2 * this.az2) * m12;
  4605. this.k12 = (this.ax2 * this.ax3 + this.ay2 * this.ay3 + this.az2 * this.az3) * m12;
  4606. this.k20 = (this.ax3 * this.ax1 + this.ay3 * this.ay1 + this.az3 * this.az1) * m12;
  4607. this.k21 = (this.ax3 * this.ax2 + this.ay3 * this.ay2 + this.az3 * this.az2) * m12;
  4608. this.k22 = (this.ax3 * this.ax3 + this.ay3 * this.ay3 + this.az3 * this.az3) * m12;
  4609. this.k00 += this.t1x1 * this.a1x1 + this.t1y1 * this.a1y1 + this.t1z1 * this.a1z1;
  4610. this.k01 += this.t1x1 * this.a1x2 + this.t1y1 * this.a1y2 + this.t1z1 * this.a1z2;
  4611. this.k02 += this.t1x1 * this.a1x3 + this.t1y1 * this.a1y3 + this.t1z1 * this.a1z3;
  4612. this.k10 += this.t1x2 * this.a1x1 + this.t1y2 * this.a1y1 + this.t1z2 * this.a1z1;
  4613. this.k11 += this.t1x2 * this.a1x2 + this.t1y2 * this.a1y2 + this.t1z2 * this.a1z2;
  4614. this.k12 += this.t1x2 * this.a1x3 + this.t1y2 * this.a1y3 + this.t1z2 * this.a1z3;
  4615. this.k20 += this.t1x3 * this.a1x1 + this.t1y3 * this.a1y1 + this.t1z3 * this.a1z1;
  4616. this.k21 += this.t1x3 * this.a1x2 + this.t1y3 * this.a1y2 + this.t1z3 * this.a1z2;
  4617. this.k22 += this.t1x3 * this.a1x3 + this.t1y3 * this.a1y3 + this.t1z3 * this.a1z3;
  4618. this.k00 += this.t2x1 * this.a2x1 + this.t2y1 * this.a2y1 + this.t2z1 * this.a2z1;
  4619. this.k01 += this.t2x1 * this.a2x2 + this.t2y1 * this.a2y2 + this.t2z1 * this.a2z2;
  4620. this.k02 += this.t2x1 * this.a2x3 + this.t2y1 * this.a2y3 + this.t2z1 * this.a2z3;
  4621. this.k10 += this.t2x2 * this.a2x1 + this.t2y2 * this.a2y1 + this.t2z2 * this.a2z1;
  4622. this.k11 += this.t2x2 * this.a2x2 + this.t2y2 * this.a2y2 + this.t2z2 * this.a2z2;
  4623. this.k12 += this.t2x2 * this.a2x3 + this.t2y2 * this.a2y3 + this.t2z2 * this.a2z3;
  4624. this.k20 += this.t2x3 * this.a2x1 + this.t2y3 * this.a2y1 + this.t2z3 * this.a2z1;
  4625. this.k21 += this.t2x3 * this.a2x2 + this.t2y3 * this.a2y2 + this.t2z3 * this.a2z2;
  4626. this.k22 += this.t2x3 * this.a2x3 + this.t2y3 * this.a2y3 + this.t2z3 * this.a2z3;
  4627. this.kv00 = this.k00;
  4628. this.kv11 = this.k11;
  4629. this.kv22 = this.k22;
  4630. this.dv00 = 1 / this.kv00;
  4631. this.dv11 = 1 / this.kv11;
  4632. this.dv22 = 1 / this.kv22;
  4633. if (enableSpring1 && this.limitState1 != 2) {
  4634. var omega = 6.2831853 * frequency1;
  4635. var k = omega * omega * timeStep;
  4636. var dmp = invTimeStep / (k + 2 * this.limitMotor1.dampingRatio * omega);
  4637. this.cfm1 = this.kv00 * dmp;
  4638. this.limitVelocity1 *= k * dmp;
  4639. } else {
  4640. this.cfm1 = 0;
  4641. this.limitVelocity1 *= invTimeStep * 0.05;
  4642. }
  4643. if (enableSpring2 && this.limitState2 != 2) {
  4644. omega = 6.2831853 * frequency2;
  4645. k = omega * omega * timeStep;
  4646. dmp = invTimeStep / (k + 2 * this.limitMotor2.dampingRatio * omega);
  4647. this.cfm2 = this.kv11 * dmp;
  4648. this.limitVelocity2 *= k * dmp;
  4649. } else {
  4650. this.cfm2 = 0;
  4651. this.limitVelocity2 *= invTimeStep * 0.05;
  4652. }
  4653. if (enableSpring3 && this.limitState3 != 2) {
  4654. omega = 6.2831853 * frequency3;
  4655. k = omega * omega * timeStep;
  4656. dmp = invTimeStep / (k + 2 * this.limitMotor3.dampingRatio * omega);
  4657. this.cfm3 = this.kv22 * dmp;
  4658. this.limitVelocity3 *= k * dmp;
  4659. } else {
  4660. this.cfm3 = 0;
  4661. this.limitVelocity3 *= invTimeStep * 0.05;
  4662. }
  4663. this.k00 += this.cfm1;
  4664. this.k11 += this.cfm2;
  4665. this.k22 += this.cfm3;
  4666. var inv = 1 / (
  4667. this.k00 * (this.k11 * this.k22 - this.k21 * this.k12) +
  4668. this.k10 * (this.k21 * this.k02 - this.k01 * this.k22) +
  4669. this.k20 * (this.k01 * this.k12 - this.k11 * this.k02)
  4670. );
  4671. this.d00 = (this.k11 * this.k22 - this.k12 * this.k21) * inv;
  4672. this.d01 = (this.k02 * this.k21 - this.k01 * this.k22) * inv;
  4673. this.d02 = (this.k01 * this.k12 - this.k02 * this.k11) * inv;
  4674. this.d10 = (this.k12 * this.k20 - this.k10 * this.k22) * inv;
  4675. this.d11 = (this.k00 * this.k22 - this.k02 * this.k20) * inv;
  4676. this.d12 = (this.k02 * this.k10 - this.k00 * this.k12) * inv;
  4677. this.d20 = (this.k10 * this.k21 - this.k11 * this.k20) * inv;
  4678. this.d21 = (this.k01 * this.k20 - this.k00 * this.k21) * inv;
  4679. this.d22 = (this.k00 * this.k11 - this.k01 * this.k10) * inv;
  4680. // warm starting
  4681. var totalImpulse1 = this.limitImpulse1 + this.motorImpulse1;
  4682. var totalImpulse2 = this.limitImpulse2 + this.motorImpulse2;
  4683. var totalImpulse3 = this.limitImpulse3 + this.motorImpulse3;
  4684. this.l1.x += totalImpulse1 * this.l1x1 + totalImpulse2 * this.l1x2 + totalImpulse3 * this.l1x3;
  4685. this.l1.y += totalImpulse1 * this.l1y1 + totalImpulse2 * this.l1y2 + totalImpulse3 * this.l1y3;
  4686. this.l1.z += totalImpulse1 * this.l1z1 + totalImpulse2 * this.l1z2 + totalImpulse3 * this.l1z3;
  4687. this.a1.x += totalImpulse1 * this.a1x1 + totalImpulse2 * this.a1x2 + totalImpulse3 * this.a1x3;
  4688. this.a1.y += totalImpulse1 * this.a1y1 + totalImpulse2 * this.a1y2 + totalImpulse3 * this.a1y3;
  4689. this.a1.z += totalImpulse1 * this.a1z1 + totalImpulse2 * this.a1z2 + totalImpulse3 * this.a1z3;
  4690. this.l2.x -= totalImpulse1 * this.l2x1 + totalImpulse2 * this.l2x2 + totalImpulse3 * this.l2x3;
  4691. this.l2.y -= totalImpulse1 * this.l2y1 + totalImpulse2 * this.l2y2 + totalImpulse3 * this.l2y3;
  4692. this.l2.z -= totalImpulse1 * this.l2z1 + totalImpulse2 * this.l2z2 + totalImpulse3 * this.l2z3;
  4693. this.a2.x -= totalImpulse1 * this.a2x1 + totalImpulse2 * this.a2x2 + totalImpulse3 * this.a2x3;
  4694. this.a2.y -= totalImpulse1 * this.a2y1 + totalImpulse2 * this.a2y2 + totalImpulse3 * this.a2y3;
  4695. this.a2.z -= totalImpulse1 * this.a2z1 + totalImpulse2 * this.a2z2 + totalImpulse3 * this.a2z3;
  4696. },
  4697. solve: function () {
  4698. var rvx = this.l2.x - this.l1.x + this.a2.y * this.r2z - this.a2.z * this.r2y - this.a1.y * this.r1z + this.a1.z * this.r1y;
  4699. var rvy = this.l2.y - this.l1.y + this.a2.z * this.r2x - this.a2.x * this.r2z - this.a1.z * this.r1x + this.a1.x * this.r1z;
  4700. var rvz = this.l2.z - this.l1.z + this.a2.x * this.r2y - this.a2.y * this.r2x - this.a1.x * this.r1y + this.a1.y * this.r1x;
  4701. var rvn1 = rvx * this.ax1 + rvy * this.ay1 + rvz * this.az1;
  4702. var rvn2 = rvx * this.ax2 + rvy * this.ay2 + rvz * this.az2;
  4703. var rvn3 = rvx * this.ax3 + rvy * this.ay3 + rvz * this.az3;
  4704. var oldMotorImpulse1 = this.motorImpulse1;
  4705. var oldMotorImpulse2 = this.motorImpulse2;
  4706. var oldMotorImpulse3 = this.motorImpulse3;
  4707. var dMotorImpulse1 = 0;
  4708. var dMotorImpulse2 = 0;
  4709. var dMotorImpulse3 = 0;
  4710. if (this.enableMotor1) {
  4711. dMotorImpulse1 = (rvn1 - this.motorSpeed1) * this.dv00;
  4712. this.motorImpulse1 += dMotorImpulse1;
  4713. if (this.motorImpulse1 > this.maxMotorImpulse1) { // clamp motor impulse
  4714. this.motorImpulse1 = this.maxMotorImpulse1;
  4715. } else if (this.motorImpulse1 < -this.maxMotorImpulse1) {
  4716. this.motorImpulse1 = -this.maxMotorImpulse1;
  4717. }
  4718. dMotorImpulse1 = this.motorImpulse1 - oldMotorImpulse1;
  4719. }
  4720. if (this.enableMotor2) {
  4721. dMotorImpulse2 = (rvn2 - this.motorSpeed2) * this.dv11;
  4722. this.motorImpulse2 += dMotorImpulse2;
  4723. if (this.motorImpulse2 > this.maxMotorImpulse2) { // clamp motor impulse
  4724. this.motorImpulse2 = this.maxMotorImpulse2;
  4725. } else if (this.motorImpulse2 < -this.maxMotorImpulse2) {
  4726. this.motorImpulse2 = -this.maxMotorImpulse2;
  4727. }
  4728. dMotorImpulse2 = this.motorImpulse2 - oldMotorImpulse2;
  4729. }
  4730. if (this.enableMotor3) {
  4731. dMotorImpulse3 = (rvn3 - this.motorSpeed3) * this.dv22;
  4732. this.motorImpulse3 += dMotorImpulse3;
  4733. if (this.motorImpulse3 > this.maxMotorImpulse3) { // clamp motor impulse
  4734. this.motorImpulse3 = this.maxMotorImpulse3;
  4735. } else if (this.motorImpulse3 < -this.maxMotorImpulse3) {
  4736. this.motorImpulse3 = -this.maxMotorImpulse3;
  4737. }
  4738. dMotorImpulse3 = this.motorImpulse3 - oldMotorImpulse3;
  4739. }
  4740. // apply motor impulse to relative velocity
  4741. rvn1 += dMotorImpulse1 * this.kv00 + dMotorImpulse2 * this.k01 + dMotorImpulse3 * this.k02;
  4742. rvn2 += dMotorImpulse1 * this.k10 + dMotorImpulse2 * this.kv11 + dMotorImpulse3 * this.k12;
  4743. rvn3 += dMotorImpulse1 * this.k20 + dMotorImpulse2 * this.k21 + dMotorImpulse3 * this.kv22;
  4744. // subtract target velocity and applied impulse
  4745. rvn1 -= this.limitVelocity1 + this.limitImpulse1 * this.cfm1;
  4746. rvn2 -= this.limitVelocity2 + this.limitImpulse2 * this.cfm2;
  4747. rvn3 -= this.limitVelocity3 + this.limitImpulse3 * this.cfm3;
  4748. var oldLimitImpulse1 = this.limitImpulse1;
  4749. var oldLimitImpulse2 = this.limitImpulse2;
  4750. var oldLimitImpulse3 = this.limitImpulse3;
  4751. var dLimitImpulse1 = rvn1 * this.d00 + rvn2 * this.d01 + rvn3 * this.d02;
  4752. var dLimitImpulse2 = rvn1 * this.d10 + rvn2 * this.d11 + rvn3 * this.d12;
  4753. var dLimitImpulse3 = rvn1 * this.d20 + rvn2 * this.d21 + rvn3 * this.d22;
  4754. this.limitImpulse1 += dLimitImpulse1;
  4755. this.limitImpulse2 += dLimitImpulse2;
  4756. this.limitImpulse3 += dLimitImpulse3;
  4757. // clamp
  4758. var clampState = 0;
  4759. if (this.limitState1 == 2 || this.limitImpulse1 * this.limitState1 < 0) {
  4760. dLimitImpulse1 = -oldLimitImpulse1;
  4761. rvn2 += dLimitImpulse1 * this.k10;
  4762. rvn3 += dLimitImpulse1 * this.k20;
  4763. clampState |= 1;
  4764. }
  4765. if (this.limitState2 == 2 || this.limitImpulse2 * this.limitState2 < 0) {
  4766. dLimitImpulse2 = -oldLimitImpulse2;
  4767. rvn1 += dLimitImpulse2 * this.k01;
  4768. rvn3 += dLimitImpulse2 * this.k21;
  4769. clampState |= 2;
  4770. }
  4771. if (this.limitState3 == 2 || this.limitImpulse3 * this.limitState3 < 0) {
  4772. dLimitImpulse3 = -oldLimitImpulse3;
  4773. rvn1 += dLimitImpulse3 * this.k02;
  4774. rvn2 += dLimitImpulse3 * this.k12;
  4775. clampState |= 4;
  4776. }
  4777. // update un-clamped impulse
  4778. // TODO: isolate division
  4779. var det;
  4780. switch (clampState) {
  4781. case 1:// update 2 3
  4782. det = 1 / (this.k11 * this.k22 - this.k12 * this.k21);
  4783. dLimitImpulse2 = (this.k22 * rvn2 + -this.k12 * rvn3) * det;
  4784. dLimitImpulse3 = (-this.k21 * rvn2 + this.k11 * rvn3) * det;
  4785. break;
  4786. case 2:// update 1 3
  4787. det = 1 / (this.k00 * this.k22 - this.k02 * this.k20);
  4788. dLimitImpulse1 = (this.k22 * rvn1 + -this.k02 * rvn3) * det;
  4789. dLimitImpulse3 = (-this.k20 * rvn1 + this.k00 * rvn3) * det;
  4790. break;
  4791. case 3:// update 3
  4792. dLimitImpulse3 = rvn3 / this.k22;
  4793. break;
  4794. case 4:// update 1 2
  4795. det = 1 / (this.k00 * this.k11 - this.k01 * this.k10);
  4796. dLimitImpulse1 = (this.k11 * rvn1 + -this.k01 * rvn2) * det;
  4797. dLimitImpulse2 = (-this.k10 * rvn1 + this.k00 * rvn2) * det;
  4798. break;
  4799. case 5:// update 2
  4800. dLimitImpulse2 = rvn2 / this.k11;
  4801. break;
  4802. case 6:// update 1
  4803. dLimitImpulse1 = rvn1 / this.k00;
  4804. break;
  4805. }
  4806. this.limitImpulse1 = oldLimitImpulse1 + dLimitImpulse1;
  4807. this.limitImpulse2 = oldLimitImpulse2 + dLimitImpulse2;
  4808. this.limitImpulse3 = oldLimitImpulse3 + dLimitImpulse3;
  4809. var dImpulse1 = dMotorImpulse1 + dLimitImpulse1;
  4810. var dImpulse2 = dMotorImpulse2 + dLimitImpulse2;
  4811. var dImpulse3 = dMotorImpulse3 + dLimitImpulse3;
  4812. // apply impulse
  4813. this.l1.x += dImpulse1 * this.l1x1 + dImpulse2 * this.l1x2 + dImpulse3 * this.l1x3;
  4814. this.l1.y += dImpulse1 * this.l1y1 + dImpulse2 * this.l1y2 + dImpulse3 * this.l1y3;
  4815. this.l1.z += dImpulse1 * this.l1z1 + dImpulse2 * this.l1z2 + dImpulse3 * this.l1z3;
  4816. this.a1.x += dImpulse1 * this.a1x1 + dImpulse2 * this.a1x2 + dImpulse3 * this.a1x3;
  4817. this.a1.y += dImpulse1 * this.a1y1 + dImpulse2 * this.a1y2 + dImpulse3 * this.a1y3;
  4818. this.a1.z += dImpulse1 * this.a1z1 + dImpulse2 * this.a1z2 + dImpulse3 * this.a1z3;
  4819. this.l2.x -= dImpulse1 * this.l2x1 + dImpulse2 * this.l2x2 + dImpulse3 * this.l2x3;
  4820. this.l2.y -= dImpulse1 * this.l2y1 + dImpulse2 * this.l2y2 + dImpulse3 * this.l2y3;
  4821. this.l2.z -= dImpulse1 * this.l2z1 + dImpulse2 * this.l2z2 + dImpulse3 * this.l2z3;
  4822. this.a2.x -= dImpulse1 * this.a2x1 + dImpulse2 * this.a2x2 + dImpulse3 * this.a2x3;
  4823. this.a2.y -= dImpulse1 * this.a2y1 + dImpulse2 * this.a2y2 + dImpulse3 * this.a2y3;
  4824. this.a2.z -= dImpulse1 * this.a2z1 + dImpulse2 * this.a2z2 + dImpulse3 * this.a2z3;
  4825. }
  4826. }
  4827. /**
  4828. * A translational constraint for various joints.
  4829. * @author saharan
  4830. */
  4831. OIMO.TranslationalConstraint = function (joint, limitMotor) {
  4832. this.cfm = NaN;
  4833. this.m1 = NaN;
  4834. this.m2 = NaN;
  4835. this.i1e00 = NaN;
  4836. this.i1e01 = NaN;
  4837. this.i1e02 = NaN;
  4838. this.i1e10 = NaN;
  4839. this.i1e11 = NaN;
  4840. this.i1e12 = NaN;
  4841. this.i1e20 = NaN;
  4842. this.i1e21 = NaN;
  4843. this.i1e22 = NaN;
  4844. this.i2e00 = NaN;
  4845. this.i2e01 = NaN;
  4846. this.i2e02 = NaN;
  4847. this.i2e10 = NaN;
  4848. this.i2e11 = NaN;
  4849. this.i2e12 = NaN;
  4850. this.i2e20 = NaN;
  4851. this.i2e21 = NaN;
  4852. this.i2e22 = NaN;
  4853. this.motorDenom = NaN;
  4854. this.invMotorDenom = NaN;
  4855. this.invDenom = NaN;
  4856. this.ax = NaN;
  4857. this.ay = NaN;
  4858. this.az = NaN;
  4859. this.r1x = NaN;
  4860. this.r1y = NaN;
  4861. this.r1z = NaN;
  4862. this.r2x = NaN;
  4863. this.r2y = NaN;
  4864. this.r2z = NaN;
  4865. this.t1x = NaN;
  4866. this.t1y = NaN;
  4867. this.t1z = NaN;
  4868. this.t2x = NaN;
  4869. this.t2y = NaN;
  4870. this.t2z = NaN;
  4871. this.l1x = NaN;
  4872. this.l1y = NaN;
  4873. this.l1z = NaN;
  4874. this.l2x = NaN;
  4875. this.l2y = NaN;
  4876. this.l2z = NaN;
  4877. this.a1x = NaN;
  4878. this.a1y = NaN;
  4879. this.a1z = NaN;
  4880. this.a2x = NaN;
  4881. this.a2y = NaN;
  4882. this.a2z = NaN;
  4883. this.lowerLimit = NaN;
  4884. this.upperLimit = NaN;
  4885. this.limitVelocity = NaN;
  4886. this.limitState = 0; // -1: at lower, 0: locked, 1: at upper, 2: free
  4887. this.enableMotor = false;
  4888. this.motorSpeed = NaN;
  4889. this.maxMotorForce = NaN;
  4890. this.maxMotorImpulse = NaN;
  4891. this.limitMotor = limitMotor;
  4892. this.b1 = joint.body1;
  4893. this.b2 = joint.body2;
  4894. this.p1 = joint.anchorPoint1;
  4895. this.p2 = joint.anchorPoint2;
  4896. this.r1 = joint.relativeAnchorPoint1;
  4897. this.r2 = joint.relativeAnchorPoint2;
  4898. this.l1 = this.b1.linearVelocity;
  4899. this.l2 = this.b2.linearVelocity;
  4900. this.a1 = this.b1.angularVelocity;
  4901. this.a2 = this.b2.angularVelocity;
  4902. this.i1 = this.b1.inverseInertia;
  4903. this.i2 = this.b2.inverseInertia;
  4904. this.limitImpulse = 0;
  4905. this.motorImpulse = 0;
  4906. }
  4907. OIMO.TranslationalConstraint.prototype = {
  4908. constructor: OIMO.TranslationalConstraint,
  4909. preSolve: function (timeStep, invTimeStep) {
  4910. this.ax = this.limitMotor.axis.x;
  4911. this.ay = this.limitMotor.axis.y;
  4912. this.az = this.limitMotor.axis.z;
  4913. this.lowerLimit = this.limitMotor.lowerLimit;
  4914. this.upperLimit = this.limitMotor.upperLimit;
  4915. this.motorSpeed = this.limitMotor.motorSpeed;
  4916. this.maxMotorForce = this.limitMotor.maxMotorForce;
  4917. this.enableMotor = this.maxMotorForce > 0;
  4918. this.m1 = this.b1.inverseMass;
  4919. this.m2 = this.b2.inverseMass;
  4920. var ti1 = this.i1.elements;
  4921. var ti2 = this.i2.elements;
  4922. this.i1e00 = ti1[0];
  4923. this.i1e01 = ti1[1];
  4924. this.i1e02 = ti1[2];
  4925. this.i1e10 = ti1[3];
  4926. this.i1e11 = ti1[4];
  4927. this.i1e12 = ti1[5];
  4928. this.i1e20 = ti1[6];
  4929. this.i1e21 = ti1[7];
  4930. this.i1e22 = ti1[8];
  4931. this.i2e00 = ti2[0];
  4932. this.i2e01 = ti2[1];
  4933. this.i2e02 = ti2[2];
  4934. this.i2e10 = ti2[3];
  4935. this.i2e11 = ti2[4];
  4936. this.i2e12 = ti2[5];
  4937. this.i2e20 = ti2[6];
  4938. this.i2e21 = ti2[7];
  4939. this.i2e22 = ti2[8];
  4940. var dx = this.p2.x - this.p1.x;
  4941. var dy = this.p2.y - this.p1.y;
  4942. var dz = this.p2.z - this.p1.z;
  4943. var d = dx * this.ax + dy * this.ay + dz * this.az;
  4944. var frequency = this.limitMotor.frequency;
  4945. var enableSpring = frequency > 0;
  4946. var enableLimit = this.lowerLimit <= this.upperLimit;
  4947. if (enableSpring && d > 20 || d < -20) {
  4948. enableSpring = false;
  4949. }
  4950. if (enableLimit) {
  4951. if (this.lowerLimit == this.upperLimit) {
  4952. if (this.limitState != 0) {
  4953. this.limitState = 0;
  4954. this.limitImpulse = 0;
  4955. }
  4956. this.limitVelocity = this.lowerLimit - d;
  4957. if (!enableSpring) d = this.lowerLimit;
  4958. } else if (d < this.lowerLimit) {
  4959. if (this.limitState != -1) {
  4960. this.limitState = -1;
  4961. this.limitImpulse = 0;
  4962. }
  4963. this.limitVelocity = this.lowerLimit - d;
  4964. if (!enableSpring) d = this.lowerLimit;
  4965. } else if (d > this.upperLimit) {
  4966. if (this.limitState != 1) {
  4967. this.limitState = 1;
  4968. this.limitImpulse = 0;
  4969. }
  4970. this.limitVelocity = this.upperLimit - d;
  4971. if (!enableSpring) d = this.upperLimit;
  4972. } else {
  4973. this.limitState = 2;
  4974. this.limitImpulse = 0;
  4975. this.limitVelocity = 0;
  4976. }
  4977. if (!enableSpring) {
  4978. if (this.limitVelocity > 0.005) this.limitVelocity -= 0.005;
  4979. else if (this.limitVelocity < -0.005) this.limitVelocity += 0.005;
  4980. else this.limitVelocity = 0;
  4981. }
  4982. } else {
  4983. this.limitState = 2;
  4984. this.limitImpulse = 0;
  4985. }
  4986. if (this.enableMotor && (this.limitState != 0 || enableSpring)) {
  4987. this.maxMotorImpulse = this.maxMotorForce * timeStep;
  4988. } else {
  4989. this.motorImpulse = 0;
  4990. this.maxMotorImpulse = 0;
  4991. }
  4992. var rdx = d * this.ax;
  4993. var rdy = d * this.ay;
  4994. var rdz = d * this.az;
  4995. var w1 = this.m1 / (this.m1 + this.m2);
  4996. var w2 = 1 - w1;
  4997. this.r1x = this.r1.x + rdx * w1;
  4998. this.r1y = this.r1.y + rdy * w1;
  4999. this.r1z = this.r1.z + rdz * w1;
  5000. this.r2x = this.r2.x - rdx * w2;
  5001. this.r2y = this.r2.y - rdy * w2;
  5002. this.r2z = this.r2.z - rdz * w2;
  5003. this.t1x = this.r1y * this.az - this.r1z * this.ay;
  5004. this.t1y = this.r1z * this.ax - this.r1x * this.az;
  5005. this.t1z = this.r1x * this.ay - this.r1y * this.ax;
  5006. this.t2x = this.r2y * this.az - this.r2z * this.ay;
  5007. this.t2y = this.r2z * this.ax - this.r2x * this.az;
  5008. this.t2z = this.r2x * this.ay - this.r2y * this.ax;
  5009. this.l1x = this.ax * this.m1;
  5010. this.l1y = this.ay * this.m1;
  5011. this.l1z = this.az * this.m1;
  5012. this.l2x = this.ax * this.m2;
  5013. this.l2y = this.ay * this.m2;
  5014. this.l2z = this.az * this.m2;
  5015. this.a1x = this.t1x * this.i1e00 + this.t1y * this.i1e01 + this.t1z * this.i1e02;
  5016. this.a1y = this.t1x * this.i1e10 + this.t1y * this.i1e11 + this.t1z * this.i1e12;
  5017. this.a1z = this.t1x * this.i1e20 + this.t1y * this.i1e21 + this.t1z * this.i1e22;
  5018. this.a2x = this.t2x * this.i2e00 + this.t2y * this.i2e01 + this.t2z * this.i2e02;
  5019. this.a2y = this.t2x * this.i2e10 + this.t2y * this.i2e11 + this.t2z * this.i2e12;
  5020. this.a2z = this.t2x * this.i2e20 + this.t2y * this.i2e21 + this.t2z * this.i2e22;
  5021. this.motorDenom =
  5022. this.m1 + this.m2 +
  5023. this.ax * (this.a1y * this.r1z - this.a1z * this.r1y + this.a2y * this.r2z - this.a2z * this.r2y) +
  5024. this.ay * (this.a1z * this.r1x - this.a1x * this.r1z + this.a2z * this.r2x - this.a2x * this.r2z) +
  5025. this.az * (this.a1x * this.r1y - this.a1y * this.r1x + this.a2x * this.r2y - this.a2y * this.r2x);
  5026. this.invMotorDenom = 1 / this.motorDenom;
  5027. if (enableSpring && this.limitState != 2) {
  5028. var omega = 6.2831853 * frequency;
  5029. var k = omega * omega * timeStep;
  5030. var dmp = invTimeStep / (k + 2 * this.limitMotor.dampingRatio * omega);
  5031. this.cfm = this.motorDenom * dmp;
  5032. this.limitVelocity *= k * dmp;
  5033. } else {
  5034. this.cfm = 0;
  5035. this.limitVelocity *= invTimeStep * 0.05;
  5036. }
  5037. this.invDenom = 1 / (this.motorDenom + this.cfm);
  5038. var totalImpulse = this.limitImpulse + this.motorImpulse;
  5039. this.l1.x += totalImpulse * this.l1x;
  5040. this.l1.y += totalImpulse * this.l1y;
  5041. this.l1.z += totalImpulse * this.l1z;
  5042. this.a1.x += totalImpulse * this.a1x;
  5043. this.a1.y += totalImpulse * this.a1y;
  5044. this.a1.z += totalImpulse * this.a1z;
  5045. this.l2.x -= totalImpulse * this.l2x;
  5046. this.l2.y -= totalImpulse * this.l2y;
  5047. this.l2.z -= totalImpulse * this.l2z;
  5048. this.a2.x -= totalImpulse * this.a2x;
  5049. this.a2.y -= totalImpulse * this.a2y;
  5050. this.a2.z -= totalImpulse * this.a2z;
  5051. },
  5052. solve: function () {
  5053. var rvn =
  5054. this.ax * (this.l2.x - this.l1.x) + this.ay * (this.l2.y - this.l1.y) + this.az * (this.l2.z - this.l1.z) +
  5055. this.t2x * this.a2.x - this.t1x * this.a1.x + this.t2y * this.a2.y - this.t1y * this.a1.y + this.t2z * this.a2.z - this.t1z * this.a1.z;
  5056. // motor part
  5057. var newMotorImpulse;
  5058. if (this.enableMotor) {
  5059. newMotorImpulse = (rvn - this.motorSpeed) * this.invMotorDenom;
  5060. var oldMotorImpulse = this.motorImpulse;
  5061. this.motorImpulse += newMotorImpulse;
  5062. if (this.motorImpulse > this.maxMotorImpulse) this.motorImpulse = this.maxMotorImpulse;
  5063. else if (this.motorImpulse < -this.maxMotorImpulse) this.motorImpulse = -this.maxMotorImpulse;
  5064. newMotorImpulse = this.motorImpulse - oldMotorImpulse;
  5065. rvn -= newMotorImpulse * this.motorDenom;
  5066. } else newMotorImpulse = 0;
  5067. // limit part
  5068. var newLimitImpulse;
  5069. if (this.limitState != 2) {
  5070. newLimitImpulse = (rvn - this.limitVelocity - this.limitImpulse * this.cfm) * this.invDenom;
  5071. var oldLimitImpulse = this.limitImpulse;
  5072. this.limitImpulse += newLimitImpulse;
  5073. if (this.limitImpulse * this.limitState < 0) this.limitImpulse = 0;
  5074. newLimitImpulse = this.limitImpulse - oldLimitImpulse;
  5075. } else newLimitImpulse = 0;
  5076. var totalImpulse = newLimitImpulse + newMotorImpulse;
  5077. this.l1.x += totalImpulse * this.l1x;
  5078. this.l1.y += totalImpulse * this.l1y;
  5079. this.l1.z += totalImpulse * this.l1z;
  5080. this.a1.x += totalImpulse * this.a1x;
  5081. this.a1.y += totalImpulse * this.a1y;
  5082. this.a1.z += totalImpulse * this.a1z;
  5083. this.l2.x -= totalImpulse * this.l2x;
  5084. this.l2.y -= totalImpulse * this.l2y;
  5085. this.l2.z -= totalImpulse * this.l2z;
  5086. this.a2.x -= totalImpulse * this.a2x;
  5087. this.a2.y -= totalImpulse * this.a2y;
  5088. this.a2.z -= totalImpulse * this.a2z;
  5089. }
  5090. }
  5091. /**
  5092. * A contact is a pair of shapes whose axis-aligned bounding boxes are overlapping.
  5093. * @author saharan
  5094. */
  5095. OIMO.Contact = function () {
  5096. // The first shape.
  5097. this.shape1 = null;
  5098. // The second shape.
  5099. this.shape2 = null;
  5100. // The first rigid body.
  5101. this.body1 = null;
  5102. // The second rigid body.
  5103. this.body2 = null;
  5104. // The previous contact in the world.
  5105. this.prev = null;
  5106. // The next contact in the world.
  5107. this.next = null;
  5108. // Internal
  5109. this.persisting = false;
  5110. // Whether both the rigid bodies are sleeping or not.
  5111. this.sleeping = false;
  5112. // The collision detector between two shapes.
  5113. this.detector = null;
  5114. // The contact constraint of the contact.
  5115. this.constraint = null;
  5116. // Whether the shapes are touching or not.
  5117. this.touching = false;
  5118. this.b1Link = new OIMO.ContactLink(this);
  5119. this.b2Link = new OIMO.ContactLink(this);
  5120. this.s1Link = new OIMO.ContactLink(this);
  5121. this.s2Link = new OIMO.ContactLink(this);
  5122. // The contact manifold of the contact.
  5123. this.manifold = new OIMO.ContactManifold();
  5124. this.buffer = [];// vector 4
  5125. this.buffer.length = 4;
  5126. this.buffer[0] = new OIMO.ImpulseDataBuffer();
  5127. this.buffer[1] = new OIMO.ImpulseDataBuffer();
  5128. this.buffer[2] = new OIMO.ImpulseDataBuffer();
  5129. this.buffer[3] = new OIMO.ImpulseDataBuffer();
  5130. this.points = this.manifold.points;
  5131. this.constraint = new OIMO.ContactConstraint(this.manifold);
  5132. }
  5133. OIMO.Contact.prototype = {
  5134. constructor: OIMO.Contact,
  5135. mixRestitution: function (restitution1, restitution2) {
  5136. return OIMO.sqrt(restitution1 * restitution2);
  5137. },
  5138. mixFriction: function (friction1, friction2) {
  5139. return OIMO.sqrt(friction1 * friction2);
  5140. },
  5141. /**
  5142. * Update the contact manifold.
  5143. */
  5144. updateManifold: function () {
  5145. this.constraint.restitution = this.mixRestitution(this.shape1.restitution, this.shape2.restitution);
  5146. this.constraint.friction = this.mixFriction(this.shape1.friction, this.shape2.friction);
  5147. var numBuffers = this.manifold.numPoints;
  5148. var i = numBuffers;
  5149. while (i--) {
  5150. //for(var i=0;i<numBuffers;i++){
  5151. var b = this.buffer[i];
  5152. var p = this.points[i];
  5153. b.lp1X = p.localPoint1.x;
  5154. b.lp1Y = p.localPoint1.y;
  5155. b.lp1Z = p.localPoint1.z;
  5156. b.lp2X = p.localPoint2.x;
  5157. b.lp2Y = p.localPoint2.y;
  5158. b.lp2Z = p.localPoint2.z;
  5159. b.impulse = p.normalImpulse;
  5160. }
  5161. this.manifold.numPoints = 0;
  5162. this.detector.detectCollision(this.shape1, this.shape2, this.manifold);
  5163. var num = this.manifold.numPoints;
  5164. if (num == 0) {
  5165. this.touching = false;
  5166. return;
  5167. }
  5168. this.touching = true;
  5169. i = num;
  5170. while (i--) {
  5171. //for(i=0; i<num; i++){
  5172. p = this.points[i];
  5173. var lp1x = p.localPoint1.x;
  5174. var lp1y = p.localPoint1.y;
  5175. var lp1z = p.localPoint1.z;
  5176. var lp2x = p.localPoint2.x;
  5177. var lp2y = p.localPoint2.y;
  5178. var lp2z = p.localPoint2.z;
  5179. var index = -1;
  5180. var minDistance = 0.0004;
  5181. var j = numBuffers;
  5182. while (j--) {
  5183. //for(var j=0;j<numBuffers;j++){
  5184. b = this.buffer[j];
  5185. var dx = b.lp1X - lp1x;
  5186. var dy = b.lp1Y - lp1y;
  5187. var dz = b.lp1Z - lp1z;
  5188. var distance1 = dx * dx + dy * dy + dz * dz;
  5189. dx = b.lp2X - lp2x;
  5190. dy = b.lp2Y - lp2y;
  5191. dz = b.lp2Z - lp2z;
  5192. var distance2 = dx * dx + dy * dy + dz * dz;
  5193. if (distance1 < distance2) {
  5194. if (distance1 < minDistance) {
  5195. minDistance = distance1;
  5196. index = j;
  5197. }
  5198. } else {
  5199. if (distance2 < minDistance) {
  5200. minDistance = distance2;
  5201. index = j;
  5202. }
  5203. }
  5204. }
  5205. if (index != -1) {
  5206. var tmp = this.buffer[index];
  5207. this.buffer[index] = this.buffer[--numBuffers];
  5208. this.buffer[numBuffers] = tmp;
  5209. p.normalImpulse = tmp.impulse;
  5210. p.warmStarted = true;
  5211. } else {
  5212. p.normalImpulse = 0;
  5213. p.warmStarted = false;
  5214. }
  5215. }
  5216. },
  5217. /**
  5218. * Attach the contact to the shapes.
  5219. * @param shape1
  5220. * @param shape2
  5221. */
  5222. attach: function (shape1, shape2) {
  5223. this.shape1 = shape1;
  5224. this.shape2 = shape2;
  5225. this.body1 = shape1.parent;
  5226. this.body2 = shape2.parent;
  5227. this.manifold.body1 = this.body1;
  5228. this.manifold.body2 = this.body2;
  5229. this.constraint.body1 = this.body1;
  5230. this.constraint.body2 = this.body2;
  5231. this.constraint.attach();
  5232. this.s1Link.shape = shape2;
  5233. this.s1Link.body = this.body2;
  5234. this.s2Link.shape = shape1;
  5235. this.s2Link.body = this.body1;
  5236. if (shape1.contactLink != null) (this.s1Link.next = shape1.contactLink).prev = this.s1Link;
  5237. else this.s1Link.next = null;
  5238. shape1.contactLink = this.s1Link;
  5239. shape1.numContacts++;
  5240. if (shape2.contactLink != null) (this.s2Link.next = shape2.contactLink).prev = this.s2Link;
  5241. else this.s2Link.next = null;
  5242. shape2.contactLink = this.s2Link;
  5243. shape2.numContacts++;
  5244. this.b1Link.shape = shape2;
  5245. this.b1Link.body = this.body2;
  5246. this.b2Link.shape = shape1;
  5247. this.b2Link.body = this.body1;
  5248. if (this.body1.contactLink != null) (this.b1Link.next = this.body1.contactLink).prev = this.b1Link;
  5249. else this.b1Link.next = null;
  5250. this.body1.contactLink = this.b1Link;
  5251. this.body1.numContacts++;
  5252. if (this.body2.contactLink != null) (this.b2Link.next = this.body2.contactLink).prev = this.b2Link;
  5253. else this.b2Link.next = null;
  5254. this.body2.contactLink = this.b2Link;
  5255. this.body2.numContacts++;
  5256. this.prev = null;
  5257. this.next = null;
  5258. this.persisting = true;
  5259. this.sleeping = this.body1.sleeping && this.body2.sleeping;
  5260. this.manifold.numPoints = 0;
  5261. },
  5262. /**
  5263. * Detach the contact from the shapes.
  5264. */
  5265. detach: function () {
  5266. var prev = this.s1Link.prev;
  5267. var next = this.s1Link.next;
  5268. if (prev !== null) prev.next = next;
  5269. if (next !== null) next.prev = prev;
  5270. if (this.shape1.contactLink == this.s1Link) this.shape1.contactLink = next;
  5271. this.s1Link.prev = null;
  5272. this.s1Link.next = null;
  5273. this.s1Link.shape = null;
  5274. this.s1Link.body = null;
  5275. this.shape1.numContacts--;
  5276. prev = this.s2Link.prev;
  5277. next = this.s2Link.next;
  5278. if (prev !== null) prev.next = next;
  5279. if (next !== null) next.prev = prev;
  5280. if (this.shape2.contactLink == this.s2Link) this.shape2.contactLink = next;
  5281. this.s2Link.prev = null;
  5282. this.s2Link.next = null;
  5283. this.s2Link.shape = null;
  5284. this.s2Link.body = null;
  5285. this.shape2.numContacts--;
  5286. prev = this.b1Link.prev;
  5287. next = this.b1Link.next;
  5288. if (prev !== null) prev.next = next;
  5289. if (next !== null) next.prev = prev;
  5290. if (this.body1.contactLink == this.b1Link) this.body1.contactLink = next;
  5291. this.b1Link.prev = null;
  5292. this.b1Link.next = null;
  5293. this.b1Link.shape = null;
  5294. this.b1Link.body = null;
  5295. this.body1.numContacts--;
  5296. prev = this.b2Link.prev;
  5297. next = this.b2Link.next;
  5298. if (prev !== null) prev.next = next;
  5299. if (next !== null) next.prev = prev;
  5300. if (this.body2.contactLink == this.b2Link) this.body2.contactLink = next;
  5301. this.b2Link.prev = null;
  5302. this.b2Link.next = null;
  5303. this.b2Link.shape = null;
  5304. this.b2Link.body = null;
  5305. this.body2.numContacts--;
  5306. this.manifold.body1 = null;
  5307. this.manifold.body2 = null;
  5308. this.constraint.body1 = null;
  5309. this.constraint.body2 = null;
  5310. this.constraint.detach();
  5311. this.shape1 = null;
  5312. this.shape2 = null;
  5313. this.body1 = null;
  5314. this.body2 = null;
  5315. }
  5316. }
  5317. /**
  5318. * ...
  5319. * @author saharan
  5320. */
  5321. OIMO.ContactConstraint = function (manifold) {
  5322. OIMO.Constraint.call(this);
  5323. // The contact manifold of the constraint.
  5324. this.manifold = manifold;
  5325. // The coefficient of restitution of the constraint.
  5326. this.restitution = NaN;
  5327. // The coefficient of friction of the constraint.
  5328. this.friction = NaN;
  5329. this.p1 = null;
  5330. this.p2 = null;
  5331. this.lv1 = null;
  5332. this.lv2 = null;
  5333. this.av1 = null;
  5334. this.av2 = null;
  5335. this.i1 = null;
  5336. this.i2 = null;
  5337. this.ii1 = null;
  5338. this.ii2 = null;
  5339. this.m1 = NaN;
  5340. this.m2 = NaN;
  5341. this.num = 0;
  5342. this.ps = manifold.points;
  5343. this.cs = new OIMO.ContactPointDataBuffer();
  5344. this.cs.next = new OIMO.ContactPointDataBuffer();
  5345. this.cs.next.next = new OIMO.ContactPointDataBuffer();
  5346. this.cs.next.next.next = new OIMO.ContactPointDataBuffer();
  5347. }
  5348. OIMO.ContactConstraint.prototype = Object.create(OIMO.Constraint.prototype);
  5349. /**
  5350. * Attach the constraint to the bodies.
  5351. */
  5352. OIMO.ContactConstraint.prototype.attach = function () {
  5353. this.p1 = this.body1.position;
  5354. this.p2 = this.body2.position;
  5355. this.lv1 = this.body1.linearVelocity;
  5356. this.av1 = this.body1.angularVelocity;
  5357. this.lv2 = this.body2.linearVelocity;
  5358. this.av2 = this.body2.angularVelocity;
  5359. this.i1 = this.body1.inverseInertia;
  5360. this.i2 = this.body2.inverseInertia;
  5361. }
  5362. /**
  5363. * Detach the constraint from the bodies.
  5364. */
  5365. OIMO.ContactConstraint.prototype.detach = function () {
  5366. this.p1 = null;
  5367. this.p2 = null;
  5368. this.lv1 = null;
  5369. this.lv2 = null;
  5370. this.av1 = null;
  5371. this.av2 = null;
  5372. this.i1 = null;
  5373. this.i2 = null;
  5374. }
  5375. OIMO.ContactConstraint.prototype.preSolve = function (timeStep, invTimeStep) {
  5376. this.m1 = this.body1.inverseMass;
  5377. this.m2 = this.body2.inverseMass;
  5378. this.ii1 = this.i1.clone();
  5379. this.ii2 = this.i2.clone();
  5380. var ii1 = this.ii1.elements;
  5381. var ii2 = this.ii2.elements;
  5382. var p1x = this.p1.x;
  5383. var p1y = this.p1.y;
  5384. var p1z = this.p1.z;
  5385. var p2x = this.p2.x;
  5386. var p2y = this.p2.y;
  5387. var p2z = this.p2.z;
  5388. var m1m2 = this.m1 + this.m2;
  5389. this.num = this.manifold.numPoints;
  5390. var c = this.cs;
  5391. for (var i = 0; i < this.num; i++) {
  5392. var p = this.ps[i];
  5393. var tmp1X;
  5394. var tmp1Y;
  5395. var tmp1Z;
  5396. var tmp2X;
  5397. var tmp2Y;
  5398. var tmp2Z;
  5399. tmp1X = p.position.x;
  5400. tmp1Y = p.position.y;
  5401. tmp1Z = p.position.z;
  5402. var rp1X = tmp1X - p1x;
  5403. var rp1Y = tmp1Y - p1y;
  5404. var rp1Z = tmp1Z - p1z;
  5405. var rp2X = tmp1X - p2x;
  5406. var rp2Y = tmp1Y - p2y;
  5407. var rp2Z = tmp1Z - p2z;
  5408. c.rp1X = rp1X;
  5409. c.rp1Y = rp1Y;
  5410. c.rp1Z = rp1Z;
  5411. c.rp2X = rp2X;
  5412. c.rp2Y = rp2Y;
  5413. c.rp2Z = rp2Z;
  5414. c.norImp = p.normalImpulse;
  5415. c.tanImp = p.tangentImpulse;
  5416. c.binImp = p.binormalImpulse;
  5417. var norX = p.normal.x;
  5418. var norY = p.normal.y;
  5419. var norZ = p.normal.z;
  5420. var rvX = (this.lv2.x + this.av2.y * rp2Z - this.av2.z * rp2Y) - (this.lv1.x + this.av1.y * rp1Z - this.av1.z * rp1Y);
  5421. var rvY = (this.lv2.y + this.av2.z * rp2X - this.av2.x * rp2Z) - (this.lv1.y + this.av1.z * rp1X - this.av1.x * rp1Z);
  5422. var rvZ = (this.lv2.z + this.av2.x * rp2Y - this.av2.y * rp2X) - (this.lv1.z + this.av1.x * rp1Y - this.av1.y * rp1X);
  5423. var rvn = norX * rvX + norY * rvY + norZ * rvZ;
  5424. var tanX = rvX - rvn * norX;
  5425. var tanY = rvY - rvn * norY;
  5426. var tanZ = rvZ - rvn * norZ;
  5427. var len = tanX * tanX + tanY * tanY + tanZ * tanZ;
  5428. if (len > 0.04) {
  5429. len = 1 / OIMO.sqrt(len);
  5430. } else {
  5431. tanX = norY * norX - norZ * norZ;
  5432. tanY = -norZ * norY - norX * norX;
  5433. tanZ = norX * norZ + norY * norY;
  5434. len = 1 / OIMO.sqrt(tanX * tanX + tanY * tanY + tanZ * tanZ);
  5435. }
  5436. tanX *= len;
  5437. tanY *= len;
  5438. tanZ *= len;
  5439. var binX = norY * tanZ - norZ * tanY;
  5440. var binY = norZ * tanX - norX * tanZ;
  5441. var binZ = norX * tanY - norY * tanX;
  5442. c.norX = norX;
  5443. c.norY = norY;
  5444. c.norZ = norZ;
  5445. c.tanX = tanX;
  5446. c.tanY = tanY;
  5447. c.tanZ = tanZ;
  5448. c.binX = binX;
  5449. c.binY = binY;
  5450. c.binZ = binZ;
  5451. c.norU1X = norX * this.m1;
  5452. c.norU1Y = norY * this.m1;
  5453. c.norU1Z = norZ * this.m1;
  5454. c.norU2X = norX * this.m2;
  5455. c.norU2Y = norY * this.m2;
  5456. c.norU2Z = norZ * this.m2;
  5457. c.tanU1X = tanX * this.m1;
  5458. c.tanU1Y = tanY * this.m1;
  5459. c.tanU1Z = tanZ * this.m1;
  5460. c.tanU2X = tanX * this.m2;
  5461. c.tanU2Y = tanY * this.m2;
  5462. c.tanU2Z = tanZ * this.m2;
  5463. c.binU1X = binX * this.m1;
  5464. c.binU1Y = binY * this.m1;
  5465. c.binU1Z = binZ * this.m1;
  5466. c.binU2X = binX * this.m2;
  5467. c.binU2Y = binY * this.m2;
  5468. c.binU2Z = binZ * this.m2;
  5469. var norT1X = rp1Y * norZ - rp1Z * norY;
  5470. var norT1Y = rp1Z * norX - rp1X * norZ;
  5471. var norT1Z = rp1X * norY - rp1Y * norX;
  5472. var norT2X = rp2Y * norZ - rp2Z * norY;
  5473. var norT2Y = rp2Z * norX - rp2X * norZ;
  5474. var norT2Z = rp2X * norY - rp2Y * norX;
  5475. var tanT1X = rp1Y * tanZ - rp1Z * tanY;
  5476. var tanT1Y = rp1Z * tanX - rp1X * tanZ;
  5477. var tanT1Z = rp1X * tanY - rp1Y * tanX;
  5478. var tanT2X = rp2Y * tanZ - rp2Z * tanY;
  5479. var tanT2Y = rp2Z * tanX - rp2X * tanZ;
  5480. var tanT2Z = rp2X * tanY - rp2Y * tanX;
  5481. var binT1X = rp1Y * binZ - rp1Z * binY;
  5482. var binT1Y = rp1Z * binX - rp1X * binZ;
  5483. var binT1Z = rp1X * binY - rp1Y * binX;
  5484. var binT2X = rp2Y * binZ - rp2Z * binY;
  5485. var binT2Y = rp2Z * binX - rp2X * binZ;
  5486. var binT2Z = rp2X * binY - rp2Y * binX;
  5487. var norTU1X = norT1X * ii1[0] + norT1Y * ii1[1] + norT1Z * ii1[2];
  5488. var norTU1Y = norT1X * ii1[3] + norT1Y * ii1[4] + norT1Z * ii1[5];
  5489. var norTU1Z = norT1X * ii1[6] + norT1Y * ii1[7] + norT1Z * ii1[8];
  5490. var norTU2X = norT2X * ii2[0] + norT2Y * ii2[1] + norT2Z * ii2[2];
  5491. var norTU2Y = norT2X * ii2[3] + norT2Y * ii2[4] + norT2Z * ii2[5];
  5492. var norTU2Z = norT2X * ii2[6] + norT2Y * ii2[7] + norT2Z * ii2[8];
  5493. var tanTU1X = tanT1X * ii1[0] + tanT1Y * ii1[1] + tanT1Z * ii1[2];
  5494. var tanTU1Y = tanT1X * ii1[3] + tanT1Y * ii1[4] + tanT1Z * ii1[5];
  5495. var tanTU1Z = tanT1X * ii1[6] + tanT1Y * ii1[7] + tanT1Z * ii1[8];
  5496. var tanTU2X = tanT2X * ii2[0] + tanT2Y * ii2[1] + tanT2Z * ii2[2];
  5497. var tanTU2Y = tanT2X * ii2[3] + tanT2Y * ii2[4] + tanT2Z * ii2[5];
  5498. var tanTU2Z = tanT2X * ii2[6] + tanT2Y * ii2[7] + tanT2Z * ii2[8];
  5499. var binTU1X = binT1X * ii1[0] + binT1Y * ii1[1] + binT1Z * ii1[2];
  5500. var binTU1Y = binT1X * ii1[3] + binT1Y * ii1[4] + binT1Z * ii1[5];
  5501. var binTU1Z = binT1X * ii1[6] + binT1Y * ii1[7] + binT1Z * ii1[8];
  5502. var binTU2X = binT2X * ii2[0] + binT2Y * ii2[1] + binT2Z * ii2[2];
  5503. var binTU2Y = binT2X * ii2[3] + binT2Y * ii2[4] + binT2Z * ii2[5];
  5504. var binTU2Z = binT2X * ii2[6] + binT2Y * ii2[7] + binT2Z * ii2[8];
  5505. c.norT1X = norT1X;
  5506. c.norT1Y = norT1Y;
  5507. c.norT1Z = norT1Z;
  5508. c.tanT1X = tanT1X;
  5509. c.tanT1Y = tanT1Y;
  5510. c.tanT1Z = tanT1Z;
  5511. c.binT1X = binT1X;
  5512. c.binT1Y = binT1Y;
  5513. c.binT1Z = binT1Z;
  5514. c.norT2X = norT2X;
  5515. c.norT2Y = norT2Y;
  5516. c.norT2Z = norT2Z;
  5517. c.tanT2X = tanT2X;
  5518. c.tanT2Y = tanT2Y;
  5519. c.tanT2Z = tanT2Z;
  5520. c.binT2X = binT2X;
  5521. c.binT2Y = binT2Y;
  5522. c.binT2Z = binT2Z;
  5523. c.norTU1X = norTU1X;
  5524. c.norTU1Y = norTU1Y;
  5525. c.norTU1Z = norTU1Z;
  5526. c.tanTU1X = tanTU1X;
  5527. c.tanTU1Y = tanTU1Y;
  5528. c.tanTU1Z = tanTU1Z;
  5529. c.binTU1X = binTU1X;
  5530. c.binTU1Y = binTU1Y;
  5531. c.binTU1Z = binTU1Z;
  5532. c.norTU2X = norTU2X;
  5533. c.norTU2Y = norTU2Y;
  5534. c.norTU2Z = norTU2Z;
  5535. c.tanTU2X = tanTU2X;
  5536. c.tanTU2Y = tanTU2Y;
  5537. c.tanTU2Z = tanTU2Z;
  5538. c.binTU2X = binTU2X;
  5539. c.binTU2Y = binTU2Y;
  5540. c.binTU2Z = binTU2Z;
  5541. tmp1X = norT1X * ii1[0] + norT1Y * ii1[1] + norT1Z * ii1[2];
  5542. tmp1Y = norT1X * ii1[3] + norT1Y * ii1[4] + norT1Z * ii1[5];
  5543. tmp1Z = norT1X * ii1[6] + norT1Y * ii1[7] + norT1Z * ii1[8];
  5544. tmp2X = tmp1Y * rp1Z - tmp1Z * rp1Y;
  5545. tmp2Y = tmp1Z * rp1X - tmp1X * rp1Z;
  5546. tmp2Z = tmp1X * rp1Y - tmp1Y * rp1X;
  5547. tmp1X = norT2X * ii2[0] + norT2Y * ii2[1] + norT2Z * ii2[2];
  5548. tmp1Y = norT2X * ii2[3] + norT2Y * ii2[4] + norT2Z * ii2[5];
  5549. tmp1Z = norT2X * ii2[6] + norT2Y * ii2[7] + norT2Z * ii2[8];
  5550. tmp2X += tmp1Y * rp2Z - tmp1Z * rp2Y;
  5551. tmp2Y += tmp1Z * rp2X - tmp1X * rp2Z;
  5552. tmp2Z += tmp1X * rp2Y - tmp1Y * rp2X;
  5553. var norDen = 1 / (m1m2 + norX * tmp2X + norY * tmp2Y + norZ * tmp2Z);
  5554. tmp1X = tanT1X * ii1[0] + tanT1Y * ii1[1] + tanT1Z * ii1[2];
  5555. tmp1Y = tanT1X * ii1[3] + tanT1Y * ii1[4] + tanT1Z * ii1[5];
  5556. tmp1Z = tanT1X * ii1[6] + tanT1Y * ii1[7] + tanT1Z * ii1[8];
  5557. tmp2X = tmp1Y * rp1Z - tmp1Z * rp1Y;
  5558. tmp2Y = tmp1Z * rp1X - tmp1X * rp1Z;
  5559. tmp2Z = tmp1X * rp1Y - tmp1Y * rp1X;
  5560. tmp1X = tanT2X * ii2[0] + tanT2Y * ii2[1] + tanT2Z * ii2[2];
  5561. tmp1Y = tanT2X * ii2[3] + tanT2Y * ii2[4] + tanT2Z * ii2[5];
  5562. tmp1Z = tanT2X * ii2[6] + tanT2Y * ii2[7] + tanT2Z * ii2[8];
  5563. tmp2X += tmp1Y * rp2Z - tmp1Z * rp2Y;
  5564. tmp2Y += tmp1Z * rp2X - tmp1X * rp2Z;
  5565. tmp2Z += tmp1X * rp2Y - tmp1Y * rp2X;
  5566. var tanDen = 1 / (m1m2 + tanX * tmp2X + tanY * tmp2Y + tanZ * tmp2Z);
  5567. tmp1X = binT1X * ii1[0] + binT1Y * ii1[1] + binT1Z * ii1[2];
  5568. tmp1Y = binT1X * ii1[3] + binT1Y * ii1[4] + binT1Z * ii1[5];
  5569. tmp1Z = binT1X * ii1[6] + binT1Y * ii1[7] + binT1Z * ii1[8];
  5570. tmp2X = tmp1Y * rp1Z - tmp1Z * rp1Y;
  5571. tmp2Y = tmp1Z * rp1X - tmp1X * rp1Z;
  5572. tmp2Z = tmp1X * rp1Y - tmp1Y * rp1X;
  5573. tmp1X = binT2X * ii2[0] + binT2Y * ii2[1] + binT2Z * ii2[2];
  5574. tmp1Y = binT2X * ii2[3] + binT2Y * ii2[4] + binT2Z * ii2[5];
  5575. tmp1Z = binT2X * ii2[6] + binT2Y * ii2[7] + binT2Z * ii2[8];
  5576. tmp2X += tmp1Y * rp2Z - tmp1Z * rp2Y;
  5577. tmp2Y += tmp1Z * rp2X - tmp1X * rp2Z;
  5578. tmp2Z += tmp1X * rp2Y - tmp1Y * rp2X;
  5579. var binDen = 1 / (m1m2 + binX * tmp2X + binY * tmp2Y + binZ * tmp2Z);
  5580. c.norDen = norDen;
  5581. c.tanDen = tanDen;
  5582. c.binDen = binDen;
  5583. if (p.warmStarted) {
  5584. var norImp = p.normalImpulse;
  5585. this.lv1.x += c.norU1X * norImp;
  5586. this.lv1.y += c.norU1Y * norImp;
  5587. this.lv1.z += c.norU1Z * norImp;
  5588. this.av1.x += norTU1X * norImp;
  5589. this.av1.y += norTU1Y * norImp;
  5590. this.av1.z += norTU1Z * norImp;
  5591. this.lv2.x -= c.norU2X * norImp;
  5592. this.lv2.y -= c.norU2Y * norImp;
  5593. this.lv2.z -= c.norU2Z * norImp;
  5594. this.av2.x -= norTU2X * norImp;
  5595. this.av2.y -= norTU2Y * norImp;
  5596. this.av2.z -= norTU2Z * norImp;
  5597. c.norImp = norImp;
  5598. c.tanImp = 0;
  5599. c.binImp = 0;
  5600. rvn = 0; // disable bouncing
  5601. } else {
  5602. c.norImp = 0;
  5603. c.tanImp = 0;
  5604. c.binImp = 0;
  5605. }
  5606. if (rvn > -1) {
  5607. rvn = 0; // disable bouncing
  5608. }
  5609. var norTar = this.restitution * -rvn;
  5610. var sepV = -(p.penetration + 0.005) * invTimeStep * 0.05; // allow 0.5cm error
  5611. if (norTar < sepV) norTar = sepV;
  5612. c.norTar = norTar;
  5613. c.last = i == this.num - 1;
  5614. c = c.next;
  5615. }
  5616. }
  5617. OIMO.ContactConstraint.prototype.solve = function () {
  5618. var lv1x = this.lv1.x;
  5619. var lv1y = this.lv1.y;
  5620. var lv1z = this.lv1.z;
  5621. var lv2x = this.lv2.x;
  5622. var lv2y = this.lv2.y;
  5623. var lv2z = this.lv2.z;
  5624. var av1x = this.av1.x;
  5625. var av1y = this.av1.y;
  5626. var av1z = this.av1.z;
  5627. var av2x = this.av2.x;
  5628. var av2y = this.av2.y;
  5629. var av2z = this.av2.z;
  5630. var c = this.cs;
  5631. while (true) {
  5632. var oldImp1;
  5633. var newImp1;
  5634. var oldImp2;
  5635. var newImp2;
  5636. var rvn;
  5637. var norImp = c.norImp;
  5638. var tanImp = c.tanImp;
  5639. var binImp = c.binImp;
  5640. var max = -norImp * this.friction;
  5641. var rvX = lv2x - lv1x;
  5642. var rvY = lv2y - lv1y;
  5643. var rvZ = lv2z - lv1z;
  5644. rvn =
  5645. rvX * c.tanX + rvY * c.tanY + rvZ * c.tanZ +
  5646. av2x * c.tanT2X + av2y * c.tanT2Y + av2z * c.tanT2Z -
  5647. av1x * c.tanT1X - av1y * c.tanT1Y - av1z * c.tanT1Z
  5648. ;
  5649. oldImp1 = tanImp;
  5650. newImp1 = rvn * c.tanDen;
  5651. tanImp += newImp1;
  5652. rvn =
  5653. rvX * c.binX + rvY * c.binY + rvZ * c.binZ +
  5654. av2x * c.binT2X + av2y * c.binT2Y + av2z * c.binT2Z -
  5655. av1x * c.binT1X - av1y * c.binT1Y - av1z * c.binT1Z
  5656. ;
  5657. oldImp2 = binImp;
  5658. newImp2 = rvn * c.binDen;
  5659. binImp += newImp2;
  5660. // cone friction clamp
  5661. var len = tanImp * tanImp + binImp * binImp;
  5662. if (len > max * max) {
  5663. len = max / OIMO.sqrt(len);
  5664. tanImp *= len;
  5665. binImp *= len;
  5666. }
  5667. newImp1 = tanImp - oldImp1;
  5668. newImp2 = binImp - oldImp2;
  5669. lv1x += c.tanU1X * newImp1 + c.binU1X * newImp2;
  5670. lv1y += c.tanU1Y * newImp1 + c.binU1Y * newImp2;
  5671. lv1z += c.tanU1Z * newImp1 + c.binU1Z * newImp2;
  5672. av1x += c.tanTU1X * newImp1 + c.binTU1X * newImp2;
  5673. av1y += c.tanTU1Y * newImp1 + c.binTU1Y * newImp2;
  5674. av1z += c.tanTU1Z * newImp1 + c.binTU1Z * newImp2;
  5675. lv2x -= c.tanU2X * newImp1 + c.binU2X * newImp2;
  5676. lv2y -= c.tanU2Y * newImp1 + c.binU2Y * newImp2;
  5677. lv2z -= c.tanU2Z * newImp1 + c.binU2Z * newImp2;
  5678. av2x -= c.tanTU2X * newImp1 + c.binTU2X * newImp2;
  5679. av2y -= c.tanTU2Y * newImp1 + c.binTU2Y * newImp2;
  5680. av2z -= c.tanTU2Z * newImp1 + c.binTU2Z * newImp2;
  5681. // restitution part
  5682. rvn =
  5683. (lv2x - lv1x) * c.norX + (lv2y - lv1y) * c.norY + (lv2z - lv1z) * c.norZ +
  5684. av2x * c.norT2X + av2y * c.norT2Y + av2z * c.norT2Z -
  5685. av1x * c.norT1X - av1y * c.norT1Y - av1z * c.norT1Z;
  5686. oldImp1 = norImp;
  5687. newImp1 = (rvn - c.norTar) * c.norDen;
  5688. norImp += newImp1;
  5689. if (norImp > 0) norImp = 0;
  5690. newImp1 = norImp - oldImp1;
  5691. lv1x += c.norU1X * newImp1;
  5692. lv1y += c.norU1Y * newImp1;
  5693. lv1z += c.norU1Z * newImp1;
  5694. av1x += c.norTU1X * newImp1;
  5695. av1y += c.norTU1Y * newImp1;
  5696. av1z += c.norTU1Z * newImp1;
  5697. lv2x -= c.norU2X * newImp1;
  5698. lv2y -= c.norU2Y * newImp1;
  5699. lv2z -= c.norU2Z * newImp1;
  5700. av2x -= c.norTU2X * newImp1;
  5701. av2y -= c.norTU2Y * newImp1;
  5702. av2z -= c.norTU2Z * newImp1;
  5703. c.norImp = norImp;
  5704. c.tanImp = tanImp;
  5705. c.binImp = binImp;
  5706. if (c.last) break;
  5707. c = c.next;
  5708. }
  5709. this.lv1.x = lv1x;
  5710. this.lv1.y = lv1y;
  5711. this.lv1.z = lv1z;
  5712. this.lv2.x = lv2x;
  5713. this.lv2.y = lv2y;
  5714. this.lv2.z = lv2z;
  5715. this.av1.x = av1x;
  5716. this.av1.y = av1y;
  5717. this.av1.z = av1z;
  5718. this.av2.x = av2x;
  5719. this.av2.y = av2y;
  5720. this.av2.z = av2z;
  5721. }
  5722. OIMO.ContactConstraint.prototype.postSolve = function () {
  5723. var c = this.cs;
  5724. var i = this.num;
  5725. while (i--) {
  5726. //for(var i=0;i<this.num;i++){
  5727. var p = this.ps[i];
  5728. p.normal.x = c.norX;
  5729. p.normal.y = c.norY;
  5730. p.normal.z = c.norZ;
  5731. p.tangent.x = c.tanX;
  5732. p.tangent.y = c.tanY;
  5733. p.tangent.z = c.tanZ;
  5734. p.binormal.x = c.binX;
  5735. p.binormal.y = c.binY;
  5736. p.binormal.z = c.binZ;
  5737. p.normalImpulse = c.norImp;
  5738. p.tangentImpulse = c.tanImp;
  5739. p.binormalImpulse = c.binImp;
  5740. p.normalDenominator = c.norDen;
  5741. p.tangentDenominator = c.tanDen;
  5742. p.binormalDenominator = c.binDen;
  5743. c = c.next;
  5744. }
  5745. }
  5746. /**
  5747. * A link list of contacts.
  5748. * @author saharan
  5749. */
  5750. OIMO.ContactLink = function (contact) {
  5751. // The previous contact link.
  5752. this.prev = null;
  5753. // The next contact link.
  5754. this.next = null;
  5755. // The shape of the contact.
  5756. this.shape = null;
  5757. // The other rigid body.
  5758. this.body = null;
  5759. // The contact of the link.
  5760. this.contact = contact;
  5761. }
  5762. /**
  5763. * A contact manifold between two shapes.
  5764. * @author saharan
  5765. */
  5766. OIMO.ContactManifold = function () {
  5767. // The first rigid body.
  5768. this.body1 = null;
  5769. // The second rigid body.
  5770. this.body2 = null;
  5771. // The number of manifold points.
  5772. this.numPoints = 0;
  5773. // The manifold points.
  5774. this.points = [];
  5775. this.points.length = 4;
  5776. this.points[0] = new OIMO.ManifoldPoint();
  5777. this.points[1] = new OIMO.ManifoldPoint();
  5778. this.points[2] = new OIMO.ManifoldPoint();
  5779. this.points[3] = new OIMO.ManifoldPoint();
  5780. }
  5781. OIMO.ContactManifold.prototype = {
  5782. constructor: OIMO.ContactManifold,
  5783. /**
  5784. * Reset the manifold.
  5785. * @param shape1
  5786. * @param shape2
  5787. */
  5788. reset: function (shape1, shape2) {
  5789. this.body1 = shape1.parent;
  5790. this.body2 = shape2.parent;
  5791. this.numPoints = 0;
  5792. },
  5793. /**
  5794. * Add a point into this manifold.
  5795. * @param x
  5796. * @param y
  5797. * @param z
  5798. * @param normalX
  5799. * @param normalY
  5800. * @param normalZ
  5801. * @param penetration
  5802. * @param flip
  5803. */
  5804. addPoint: function (x, y, z, normalX, normalY, normalZ, penetration, flip) {
  5805. var p = this.points[this.numPoints++];
  5806. p.position.x = x;
  5807. p.position.y = y;
  5808. p.position.z = z;
  5809. var r = this.body1.rotation;
  5810. var rx = x - this.body1.position.x;
  5811. var ry = y - this.body1.position.y;
  5812. var rz = z - this.body1.position.z;
  5813. var tr = r.elements;
  5814. p.localPoint1.x = rx * tr[0] + ry * tr[3] + rz * tr[6];
  5815. p.localPoint1.y = rx * tr[1] + ry * tr[4] + rz * tr[7];
  5816. p.localPoint1.z = rx * tr[2] + ry * tr[5] + rz * tr[8];
  5817. r = this.body2.rotation;
  5818. rx = x - this.body2.position.x;
  5819. ry = y - this.body2.position.y;
  5820. rz = z - this.body2.position.z;
  5821. p.localPoint2.x = rx * tr[0] + ry * tr[3] + rz * tr[6];
  5822. p.localPoint2.y = rx * tr[1] + ry * tr[4] + rz * tr[7];
  5823. p.localPoint2.z = rx * tr[2] + ry * tr[5] + rz * tr[8];
  5824. p.normalImpulse = 0;
  5825. if (flip) {
  5826. p.normal.x = -normalX;
  5827. p.normal.y = -normalY;
  5828. p.normal.z = -normalZ;
  5829. } else {
  5830. p.normal.x = normalX;
  5831. p.normal.y = normalY;
  5832. p.normal.z = normalZ;
  5833. }
  5834. p.penetration = penetration;
  5835. p.warmStarted = false;
  5836. }
  5837. }
  5838. OIMO.ContactPointDataBuffer = function () {
  5839. this.norX = NaN;
  5840. this.norY = NaN;
  5841. this.norZ = NaN;
  5842. this.tanX = NaN;
  5843. this.tanY = NaN;
  5844. this.tanZ = NaN;
  5845. this.binX = NaN;
  5846. this.binY = NaN;
  5847. this.binZ = NaN;
  5848. this.rp1X = NaN;
  5849. this.rp1Y = NaN;
  5850. this.rp1Z = NaN;
  5851. this.rp2X = NaN;
  5852. this.rp2Y = NaN;
  5853. this.rp2Z = NaN;
  5854. this.norU1X = NaN;
  5855. this.norU1Y = NaN;
  5856. this.norU1Z = NaN;
  5857. this.norU2X = NaN;
  5858. this.norU2Y = NaN;
  5859. this.norU2Z = NaN;
  5860. this.tanU1X = NaN;
  5861. this.tanU1Y = NaN;
  5862. this.tanU1Z = NaN;
  5863. this.tanU2X = NaN;
  5864. this.tanU2Y = NaN;
  5865. this.tanU2Z = NaN;
  5866. this.binU1X = NaN;
  5867. this.binU1Y = NaN;
  5868. this.binU1Z = NaN;
  5869. this.binU2X = NaN;
  5870. this.binU2Y = NaN;
  5871. this.binU2Z = NaN;
  5872. this.norT1X = NaN;
  5873. this.norT1Y = NaN;
  5874. this.norT1Z = NaN;
  5875. this.norT2X = NaN;
  5876. this.norT2Y = NaN;
  5877. this.norT2Z = NaN;
  5878. this.tanT1X = NaN;
  5879. this.tanT1Y = NaN;
  5880. this.tanT1Z = NaN;
  5881. this.tanT2X = NaN;
  5882. this.tanT2Y = NaN;
  5883. this.tanT2Z = NaN;
  5884. this.binT1X = NaN;
  5885. this.binT1Y = NaN;
  5886. this.binT1Z = NaN;
  5887. this.binT2X = NaN;
  5888. this.binT2Y = NaN;
  5889. this.binT2Z = NaN;
  5890. this.norTU1X = NaN;
  5891. this.norTU1Y = NaN;
  5892. this.norTU1Z = NaN;
  5893. this.norTU2X = NaN;
  5894. this.norTU2Y = NaN;
  5895. this.norTU2Z = NaN;
  5896. this.tanTU1X = NaN;
  5897. this.tanTU1Y = NaN;
  5898. this.tanTU1Z = NaN;
  5899. this.tanTU2X = NaN;
  5900. this.tanTU2Y = NaN;
  5901. this.tanTU2Z = NaN;
  5902. this.binTU1X = NaN;
  5903. this.binTU1Y = NaN;
  5904. this.binTU1Z = NaN;
  5905. this.binTU2X = NaN;
  5906. this.binTU2Y = NaN;
  5907. this.binTU2Z = NaN;
  5908. this.norImp = NaN;
  5909. this.tanImp = NaN;
  5910. this.binImp = NaN;
  5911. this.norDen = NaN;
  5912. this.tanDen = NaN;
  5913. this.binDen = NaN;
  5914. this.norTar = NaN;
  5915. this.next = null;
  5916. this.last = false;
  5917. }
  5918. OIMO.ImpulseDataBuffer = function () {
  5919. this.lp1X = NaN;
  5920. this.lp1Y = NaN;
  5921. this.lp1Z = NaN;
  5922. this.lp2X = NaN;
  5923. this.lp2Y = NaN;
  5924. this.lp2Z = NaN;
  5925. this.impulse = NaN;
  5926. }
  5927. /**
  5928. * The class holds details of the contact point.
  5929. * @author saharan
  5930. */
  5931. OIMO.ManifoldPoint = function () {
  5932. // Whether this manifold point is persisting or not.
  5933. this.warmStarted = false;
  5934. // The position of this manifold point.
  5935. this.position = new OIMO.Vec3();
  5936. // The position in the first shape's coordinate.
  5937. this.localPoint1 = new OIMO.Vec3();
  5938. // The position in the second shape's coordinate.
  5939. this.localPoint2 = new OIMO.Vec3();
  5940. // The normal vector of this manifold point.
  5941. this.normal = new OIMO.Vec3();
  5942. // The tangent vector of this manifold point.
  5943. this.tangent = new OIMO.Vec3();
  5944. // The binormal vector of this manifold point.
  5945. this.binormal = new OIMO.Vec3();
  5946. // The impulse in normal direction.
  5947. this.normalImpulse = 0;
  5948. // The impulse in tangent direction.
  5949. this.tangentImpulse = 0;
  5950. // The impulse in binormal direction.
  5951. this.binormalImpulse = 0;
  5952. // The denominator in normal direction.
  5953. this.normalDenominator = 0;
  5954. // The denominator in tangent direction.
  5955. this.tangentDenominator = 0;
  5956. // The denominator in binormal direction.
  5957. this.binormalDenominator = 0;
  5958. // The depth of penetration.
  5959. this.penetration = 0;
  5960. }
  5961. /**
  5962. * This class holds mass information of a shape.
  5963. * @author saharan
  5964. */
  5965. OIMO.MassInfo = function () {
  5966. // Mass of the shape.
  5967. this.mass = 0;
  5968. // The moment inertia of the shape.
  5969. this.inertia = new OIMO.Mat33();
  5970. };
  5971. /**
  5972. * A shape is used to detect collisions of rigid bodies.
  5973. * @author saharan
  5974. * @author lo-th
  5975. */
  5976. OIMO.Shape = function (config) {
  5977. this.type = OIMO.SHAPE_NULL;
  5978. // The global identification of the shape should be unique to the shape.
  5979. this.id = OIMO.nextID++;
  5980. // The previous shape in parent rigid body.
  5981. this.prev = null;
  5982. // The next shape in parent rigid body.
  5983. this.next = null;
  5984. // The proxy of the shape used for broad-phase collision detection.
  5985. this.proxy = null;
  5986. // The parent rigid body of the shape.
  5987. this.parent = null;
  5988. // The linked list of the contacts with the shape.
  5989. this.contactLink = null;
  5990. // The number of the contacts with the shape.
  5991. this.numContacts = 0;
  5992. // The center of gravity of the shape in world coordinate system.
  5993. this.position = new OIMO.Vec3();
  5994. // The rotation matrix of the shape in world coordinate system
  5995. this.rotation = new OIMO.Mat33();
  5996. // The position of the shape in parent's coordinate system.
  5997. this.relativePosition = new OIMO.Vec3().copy(config.relativePosition);
  5998. // The rotation matrix of the shape in parent's coordinate system.
  5999. this.relativeRotation = new OIMO.Mat33().copy(config.relativeRotation);
  6000. // The axis-aligned bounding box of the shape.
  6001. this.aabb = new OIMO.AABB();
  6002. // The density of the shape.
  6003. this.density = config.density;
  6004. // The coefficient of friction of the shape.
  6005. this.friction = config.friction;
  6006. // The coefficient of restitution of the shape.
  6007. this.restitution = config.restitution;
  6008. // The bits of the collision groups to which the shape belongs.
  6009. this.belongsTo = config.belongsTo;
  6010. // The bits of the collision groups with which the shape collides.
  6011. this.collidesWith = config.collidesWith;
  6012. };
  6013. OIMO.Shape.prototype = {
  6014. constructor: OIMO.Shape,
  6015. // Calculate the mass information of the shape.
  6016. calculateMassInfo: function (out) {
  6017. OIMO.Error("Shape", "Inheritance error.");
  6018. },
  6019. // Update the proxy of the shape.
  6020. updateProxy: function () {
  6021. OIMO.Error("Shape", "Inheritance error.");
  6022. }
  6023. };
  6024. /**
  6025. * A shape configuration holds common configuration data for constructing a shape.
  6026. * Shape configurations can be reused safely.
  6027. * @author saharan
  6028. */
  6029. OIMO.ShapeConfig = function () {
  6030. // The position of the shape in parent's coordinate system.
  6031. this.relativePosition = new OIMO.Vec3();
  6032. // The rotation matrix of the shape in parent's coordinate system.
  6033. this.relativeRotation = new OIMO.Mat33();
  6034. // The coefficient of friction of the shape.
  6035. this.friction = 0.4;
  6036. // The coefficient of restitution of the shape.
  6037. this.restitution = 0.2;
  6038. // The density of the shape.
  6039. this.density = 1;
  6040. // The bits of the collision groups to which the shape belongs.
  6041. this.belongsTo = 1;
  6042. // The bits of the collision groups with which the shape collides.
  6043. this.collidesWith = 0xffffffff;
  6044. };
  6045. /**
  6046. * A box shape.
  6047. * @author saharan
  6048. * @author lo-th
  6049. */
  6050. OIMO.BoxShape = function (config, Width, Height, Depth) {
  6051. OIMO.Shape.call(this, config);
  6052. this.type = OIMO.SHAPE_BOX;
  6053. // The width of the box.
  6054. this.width = Width;
  6055. // The height of the box.
  6056. this.height = Height;
  6057. // The depth of the box.
  6058. this.depth = Depth;
  6059. // The half-width of the box.
  6060. this.halfWidth = Width * 0.5;
  6061. // The half-height of the box.
  6062. this.halfHeight = Height * 0.5;
  6063. // The half-depth of the box.
  6064. this.halfDepth = Depth * 0.5;
  6065. this.dimentions = new OIMO_ARRAY_TYPE(18);
  6066. this.elements = new OIMO_ARRAY_TYPE(24);
  6067. };
  6068. OIMO.BoxShape.prototype = Object.create(OIMO.Shape.prototype);
  6069. OIMO.BoxShape.prototype.constructor = OIMO.BoxShape;
  6070. OIMO.BoxShape.prototype.calculateMassInfo = function (out) {
  6071. var mass = this.width * this.height * this.depth * this.density;
  6072. var divid = 1 / 12;
  6073. out.mass = mass;
  6074. out.inertia.set(
  6075. mass * (this.height * this.height + this.depth * this.depth) * divid, 0, 0,
  6076. 0, mass * (this.width * this.width + this.depth * this.depth) * divid, 0,
  6077. 0, 0, mass * (this.width * this.width + this.height * this.height) * divid
  6078. );
  6079. };
  6080. OIMO.BoxShape.prototype.updateProxy = function () {
  6081. var te = this.rotation.elements;
  6082. var di = this.dimentions;
  6083. // Width
  6084. di[0] = te[0];
  6085. di[1] = te[3];
  6086. di[2] = te[6];
  6087. // Height
  6088. di[3] = te[1];
  6089. di[4] = te[4];
  6090. di[5] = te[7];
  6091. // Depth
  6092. di[6] = te[2];
  6093. di[7] = te[5];
  6094. di[8] = te[8];
  6095. // halp Width
  6096. di[9] = te[0] * this.halfWidth;
  6097. di[10] = te[3] * this.halfWidth;
  6098. di[11] = te[6] * this.halfWidth;
  6099. // halp Height
  6100. di[12] = te[1] * this.halfHeight;
  6101. di[13] = te[4] * this.halfHeight;
  6102. di[14] = te[7] * this.halfHeight;
  6103. // halp Depth
  6104. di[15] = te[2] * this.halfDepth;
  6105. di[16] = te[5] * this.halfDepth;
  6106. di[17] = te[8] * this.halfDepth;
  6107. var wx = di[9];
  6108. var wy = di[10];
  6109. var wz = di[11];
  6110. var hx = di[12];
  6111. var hy = di[13];
  6112. var hz = di[14];
  6113. var dx = di[15];
  6114. var dy = di[16];
  6115. var dz = di[17];
  6116. var x = this.position.x;
  6117. var y = this.position.y;
  6118. var z = this.position.z;
  6119. var v = this.elements;
  6120. //v1
  6121. v[0] = x + wx + hx + dx;
  6122. v[1] = y + wy + hy + dy;
  6123. v[2] = z + wz + hz + dz;
  6124. //v2
  6125. v[3] = x + wx + hx - dx;
  6126. v[4] = y + wy + hy - dy;
  6127. v[5] = z + wz + hz - dz;
  6128. //v3
  6129. v[6] = x + wx - hx + dx;
  6130. v[7] = y + wy - hy + dy;
  6131. v[8] = z + wz - hz + dz;
  6132. //v4
  6133. v[9] = x + wx - hx - dx;
  6134. v[10] = y + wy - hy - dy;
  6135. v[11] = z + wz - hz - dz;
  6136. //v5
  6137. v[12] = x - wx + hx + dx;
  6138. v[13] = y - wy + hy + dy;
  6139. v[14] = z - wz + hz + dz;
  6140. //v6
  6141. v[15] = x - wx + hx - dx;
  6142. v[16] = y - wy + hy - dy;
  6143. v[17] = z - wz + hz - dz;
  6144. //v7
  6145. v[18] = x - wx - hx + dx;
  6146. v[19] = y - wy - hy + dy;
  6147. v[20] = z - wz - hz + dz;
  6148. //v8
  6149. v[21] = x - wx - hx - dx;
  6150. v[22] = y - wy - hy - dy;
  6151. v[23] = z - wz - hz - dz;
  6152. var w = di[9] < 0 ? -di[9] : di[9];
  6153. var h = di[10] < 0 ? -di[10] : di[10];
  6154. var d = di[11] < 0 ? -di[11] : di[11];
  6155. w = di[12] < 0 ? w - di[12] : w + di[12];
  6156. h = di[13] < 0 ? h - di[13] : h + di[13];
  6157. d = di[14] < 0 ? d - di[14] : d + di[14];
  6158. w = di[15] < 0 ? w - di[15] : w + di[15];
  6159. h = di[16] < 0 ? h - di[16] : h + di[16];
  6160. d = di[17] < 0 ? d - di[17] : d + di[17];
  6161. var p = OIMO.AABB_PROX;
  6162. this.aabb.set(
  6163. this.position.x - w - p, this.position.x + w + p,
  6164. this.position.y - h - p, this.position.y + h + p,
  6165. this.position.z - d - p, this.position.z + d + p
  6166. );
  6167. if (this.proxy != null) this.proxy.update();
  6168. };
  6169. /**
  6170. * A sphere shape.
  6171. * @author saharan
  6172. * @author lo-th
  6173. */
  6174. OIMO.SphereShape = function (config, radius) {
  6175. OIMO.Shape.call(this, config);
  6176. this.type = OIMO.SHAPE_SPHERE;
  6177. // The radius of the shape.
  6178. this.radius = radius;
  6179. };
  6180. OIMO.SphereShape.prototype = Object.create(OIMO.Shape.prototype);
  6181. OIMO.SphereShape.prototype.constructor = OIMO.SphereShape;
  6182. OIMO.SphereShape.prototype.calculateMassInfo = function (out) {
  6183. var mass = 1.333 * OIMO.PI * this.radius * this.radius * this.radius * this.density;
  6184. out.mass = mass;
  6185. var inertia = mass * this.radius * this.radius * 0.4;
  6186. out.inertia.set(inertia, 0, 0, 0, inertia, 0, 0, 0, inertia);
  6187. };
  6188. OIMO.SphereShape.prototype.updateProxy = function () {
  6189. var p = OIMO.AABB_PROX;
  6190. this.aabb.set(
  6191. this.position.x - this.radius - p, this.position.x + this.radius + p,
  6192. this.position.y - this.radius - p, this.position.y + this.radius + p,
  6193. this.position.z - this.radius - p, this.position.z + this.radius + p
  6194. );
  6195. if (this.proxy != null) this.proxy.update();
  6196. };
  6197. /**
  6198. * A cylinder shap.
  6199. * @author saharan
  6200. * @author lo-th
  6201. */
  6202. OIMO.CylinderShape = function (config, radius, height) {
  6203. OIMO.Shape.call(this, config);
  6204. this.type = OIMO.SHAPE_CYLINDER;
  6205. this.radius = radius;
  6206. this.height = height;
  6207. this.halfHeight = height * 0.5;
  6208. this.normalDirection = new OIMO.Vec3();
  6209. this.halfDirection = new OIMO.Vec3();
  6210. };
  6211. OIMO.CylinderShape.prototype = Object.create(OIMO.Shape.prototype);
  6212. OIMO.CylinderShape.prototype.constructor = OIMO.CylinderShape;
  6213. OIMO.CylinderShape.prototype.calculateMassInfo = function (out) {
  6214. var rsq = this.radius * this.radius;
  6215. var mass = OIMO.PI * rsq * this.height * this.density;
  6216. var inertiaXZ = ((0.25 * rsq) + (0.0833 * this.height * this.height)) * mass;
  6217. var inertiaY = 0.5 * rsq;
  6218. out.mass = mass;
  6219. out.inertia.set(inertiaXZ, 0, 0, 0, inertiaY, 0, 0, 0, inertiaXZ);
  6220. };
  6221. OIMO.CylinderShape.prototype.updateProxy = function () {
  6222. var te = this.rotation.elements;
  6223. var len, wx, hy, dz, xx, yy, zz, w, h, d, p;
  6224. xx = te[1] * te[1];
  6225. yy = te[4] * te[4];
  6226. zz = te[7] * te[7];
  6227. this.normalDirection.set(te[1], te[4], te[7]);
  6228. this.halfDirection.scale(this.normalDirection, this.halfHeight);
  6229. wx = 1 - xx;
  6230. len = OIMO.sqrt(wx * wx + xx * yy + xx * zz);
  6231. if (len > 0) len = this.radius / len;
  6232. wx *= len;
  6233. hy = 1 - yy;
  6234. len = OIMO.sqrt(yy * xx + hy * hy + yy * zz);
  6235. if (len > 0) len = this.radius / len;
  6236. hy *= len;
  6237. dz = 1 - zz;
  6238. len = OIMO.sqrt(zz * xx + zz * yy + dz * dz);
  6239. if (len > 0) len = this.radius / len;
  6240. dz *= len;
  6241. w = this.halfDirection.x < 0 ? -this.halfDirection.x : this.halfDirection.x;
  6242. h = this.halfDirection.y < 0 ? -this.halfDirection.y : this.halfDirection.y;
  6243. d = this.halfDirection.z < 0 ? -this.halfDirection.z : this.halfDirection.z;
  6244. w = wx < 0 ? w - wx : w + wx;
  6245. h = hy < 0 ? h - hy : h + hy;
  6246. d = dz < 0 ? d - dz : d + dz;
  6247. p = OIMO.AABB_PROX;
  6248. this.aabb.set(
  6249. this.position.x - w - p, this.position.x + w + p,
  6250. this.position.y - h - p, this.position.y + h + p,
  6251. this.position.z - d - p, this.position.z + d + p
  6252. );
  6253. if (this.proxy != null) this.proxy.update();
  6254. };
  6255. /**
  6256. * A tetra shape.
  6257. * @author xprogram
  6258. */
  6259. OIMO.TetraShape = function (config, p1, p2, p3, p4) {
  6260. OIMO.Shape.call(this, config);
  6261. this.type = OIMO.SHAPE_TETRA;
  6262. // Vertices and faces of tetra
  6263. this.verts = [p1, p2, p3, p4];
  6264. this.faces = [
  6265. mtri(0, 1, 2),
  6266. mtri(1, 2, 3),
  6267. mtri(2, 3, 4),
  6268. mtri(4, 0, 1),
  6269. ];
  6270. };
  6271. OIMO.TetraShape.prototype = Object.create(OIMO.Shape.prototype);
  6272. OIMO.TetraShape.prototype.constructor = OIMO.TetraShape;
  6273. OIMO.TetraShape.prototype.calculateMassInfo = function () {
  6274. // I guess you could calculate box mass and split it
  6275. // in half for the tetra...
  6276. };
  6277. OIMO.TetraShape.prototype.updateProxy = function () {
  6278. this.aabb.setFromPoints(this.verts);
  6279. if (this.proxy !== null)
  6280. this.proxy.update();
  6281. };
  6282. function mtri(a, b, c) {
  6283. return { a: a, b: b, c: c };
  6284. }
  6285. OIMO.CollisionDetector = function () {
  6286. this.flip = false;
  6287. };
  6288. OIMO.CollisionDetector.prototype = {
  6289. constructor: OIMO.CollisionDetector,
  6290. detectCollision: function (shape1, shape2, manifold) {
  6291. OIMO.Error("CollisionDetector", "Inheritance error.");
  6292. }
  6293. };
  6294. /**
  6295. * A collision detector which detects collisions between two boxes.
  6296. * @author saharan
  6297. */
  6298. OIMO.BoxBoxCollisionDetector = function () {
  6299. OIMO.CollisionDetector.call(this);
  6300. this.clipVertices1 = new OIMO_ARRAY_TYPE(24); // 8 vertices x,y,z
  6301. this.clipVertices2 = new OIMO_ARRAY_TYPE(24);
  6302. this.used = new OIMO_ARRAY_TYPE(8);
  6303. this.INF = 1 / 0;
  6304. };
  6305. OIMO.BoxBoxCollisionDetector.prototype = Object.create(OIMO.CollisionDetector.prototype);
  6306. OIMO.BoxBoxCollisionDetector.prototype.constructor = OIMO.BoxBoxCollisionDetector;
  6307. OIMO.BoxBoxCollisionDetector.prototype.detectCollision = function (shape1, shape2, manifold) {
  6308. // What you are doing
  6309. // · I to prepare a separate axis of the fifteen
  6310. //-Six in each of three normal vectors of the xyz direction of the box both
  6311. // · Remaining nine 3x3 a vector perpendicular to the side of the box 2 and the side of the box 1
  6312. // · Calculate the depth to the separation axis
  6313. // Calculates the distance using the inner product and put the amount of embedment
  6314. // · However a vertical separation axis and side to weight a little to avoid vibration
  6315. // And end when there is a separate axis that is remote even one
  6316. // · I look for separation axis with little to dent most
  6317. // Men and if separation axis of the first six - end collision
  6318. // Heng If it separate axis of nine other - side collision
  6319. // Heng - case of a side collision
  6320. // · Find points of two sides on which you made ​​the separation axis
  6321. // Calculates the point of closest approach of a straight line consisting of separate axis points obtained, and the collision point
  6322. //-Surface - the case of the plane crash
  6323. //-Box A, box B and the other a box of better made ​​a separate axis
  6324. // • The surface A and the plane that made the separation axis of the box A, and B to the surface the face of the box B close in the opposite direction to the most isolated axis
  6325. // When viewed from the front surface A, and the cut part exceeding the area of the surface A is a surface B
  6326. //-Plane B becomes the 3-8 triangle, I a candidate for the collision point the vertex of surface B
  6327. // • If more than one candidate 5 exists, scraping up to four
  6328. // For potential collision points of all, to examine the distance between the surface A
  6329. // • If you were on the inside surface of A, and the collision point
  6330. var b1;
  6331. var b2;
  6332. if (shape1.id < shape2.id) {
  6333. b1 = (shape1);
  6334. b2 = (shape2);
  6335. } else {
  6336. b1 = (shape2);
  6337. b2 = (shape1);
  6338. }
  6339. var V1 = b1.elements;
  6340. var V2 = b2.elements;
  6341. var D1 = b1.dimentions;
  6342. var D2 = b2.dimentions;
  6343. var p1 = b1.position;
  6344. var p2 = b2.position;
  6345. var p1x = p1.x;
  6346. var p1y = p1.y;
  6347. var p1z = p1.z;
  6348. var p2x = p2.x;
  6349. var p2y = p2.y;
  6350. var p2z = p2.z;
  6351. // diff
  6352. var dx = p2x - p1x;
  6353. var dy = p2y - p1y;
  6354. var dz = p2z - p1z;
  6355. // distance
  6356. var w1 = b1.halfWidth;
  6357. var h1 = b1.halfHeight;
  6358. var d1 = b1.halfDepth;
  6359. var w2 = b2.halfWidth;
  6360. var h2 = b2.halfHeight;
  6361. var d2 = b2.halfDepth;
  6362. // direction
  6363. // ----------------------------
  6364. // 15 separating axes
  6365. // 1~6: face
  6366. // 7~f: edge
  6367. // http://marupeke296.com/COL_3D_No13_OBBvsOBB.html
  6368. // ----------------------------
  6369. var a1x = D1[0];
  6370. var a1y = D1[1];
  6371. var a1z = D1[2];
  6372. var a2x = D1[3];
  6373. var a2y = D1[4];
  6374. var a2z = D1[5];
  6375. var a3x = D1[6];
  6376. var a3y = D1[7];
  6377. var a3z = D1[8];
  6378. var d1x = D1[9];
  6379. var d1y = D1[10];
  6380. var d1z = D1[11];
  6381. var d2x = D1[12];
  6382. var d2y = D1[13];
  6383. var d2z = D1[14];
  6384. var d3x = D1[15];
  6385. var d3y = D1[16];
  6386. var d3z = D1[17];
  6387. var a4x = D2[0];
  6388. var a4y = D2[1];
  6389. var a4z = D2[2];
  6390. var a5x = D2[3];
  6391. var a5y = D2[4];
  6392. var a5z = D2[5];
  6393. var a6x = D2[6];
  6394. var a6y = D2[7];
  6395. var a6z = D2[8];
  6396. var d4x = D2[9];
  6397. var d4y = D2[10];
  6398. var d4z = D2[11];
  6399. var d5x = D2[12];
  6400. var d5y = D2[13];
  6401. var d5z = D2[14];
  6402. var d6x = D2[15];
  6403. var d6y = D2[16];
  6404. var d6z = D2[17];
  6405. var a7x = a1y * a4z - a1z * a4y;
  6406. var a7y = a1z * a4x - a1x * a4z;
  6407. var a7z = a1x * a4y - a1y * a4x;
  6408. var a8x = a1y * a5z - a1z * a5y;
  6409. var a8y = a1z * a5x - a1x * a5z;
  6410. var a8z = a1x * a5y - a1y * a5x;
  6411. var a9x = a1y * a6z - a1z * a6y;
  6412. var a9y = a1z * a6x - a1x * a6z;
  6413. var a9z = a1x * a6y - a1y * a6x;
  6414. var aax = a2y * a4z - a2z * a4y;
  6415. var aay = a2z * a4x - a2x * a4z;
  6416. var aaz = a2x * a4y - a2y * a4x;
  6417. var abx = a2y * a5z - a2z * a5y;
  6418. var aby = a2z * a5x - a2x * a5z;
  6419. var abz = a2x * a5y - a2y * a5x;
  6420. var acx = a2y * a6z - a2z * a6y;
  6421. var acy = a2z * a6x - a2x * a6z;
  6422. var acz = a2x * a6y - a2y * a6x;
  6423. var adx = a3y * a4z - a3z * a4y;
  6424. var ady = a3z * a4x - a3x * a4z;
  6425. var adz = a3x * a4y - a3y * a4x;
  6426. var aex = a3y * a5z - a3z * a5y;
  6427. var aey = a3z * a5x - a3x * a5z;
  6428. var aez = a3x * a5y - a3y * a5x;
  6429. var afx = a3y * a6z - a3z * a6y;
  6430. var afy = a3z * a6x - a3x * a6z;
  6431. var afz = a3x * a6y - a3y * a6x;
  6432. // right or left flags
  6433. var right1;
  6434. var right2;
  6435. var right3;
  6436. var right4;
  6437. var right5;
  6438. var right6;
  6439. var right7;
  6440. var right8;
  6441. var right9;
  6442. var righta;
  6443. var rightb;
  6444. var rightc;
  6445. var rightd;
  6446. var righte;
  6447. var rightf;
  6448. // overlapping distances
  6449. var overlap1;
  6450. var overlap2;
  6451. var overlap3;
  6452. var overlap4;
  6453. var overlap5;
  6454. var overlap6;
  6455. var overlap7;
  6456. var overlap8;
  6457. var overlap9;
  6458. var overlapa;
  6459. var overlapb;
  6460. var overlapc;
  6461. var overlapd;
  6462. var overlape;
  6463. var overlapf;
  6464. // invalid flags
  6465. var invalid7 = false;
  6466. var invalid8 = false;
  6467. var invalid9 = false;
  6468. var invalida = false;
  6469. var invalidb = false;
  6470. var invalidc = false;
  6471. var invalidd = false;
  6472. var invalide = false;
  6473. var invalidf = false;
  6474. // temporary variables
  6475. var len;
  6476. var len1;
  6477. var len2;
  6478. var dot1;
  6479. var dot2;
  6480. var dot3;
  6481. // try axis 1
  6482. len = a1x * dx + a1y * dy + a1z * dz;
  6483. right1 = len > 0;
  6484. if (!right1) len = -len;
  6485. len1 = w1;
  6486. dot1 = a1x * a4x + a1y * a4y + a1z * a4z;
  6487. dot2 = a1x * a5x + a1y * a5y + a1z * a5z;
  6488. dot3 = a1x * a6x + a1y * a6y + a1z * a6z;
  6489. if (dot1 < 0) dot1 = -dot1;
  6490. if (dot2 < 0) dot2 = -dot2;
  6491. if (dot3 < 0) dot3 = -dot3;
  6492. len2 = dot1 * w2 + dot2 * h2 + dot3 * d2;
  6493. overlap1 = len - len1 - len2;
  6494. if (overlap1 > 0) return;
  6495. // try axis 2
  6496. len = a2x * dx + a2y * dy + a2z * dz;
  6497. right2 = len > 0;
  6498. if (!right2) len = -len;
  6499. len1 = h1;
  6500. dot1 = a2x * a4x + a2y * a4y + a2z * a4z;
  6501. dot2 = a2x * a5x + a2y * a5y + a2z * a5z;
  6502. dot3 = a2x * a6x + a2y * a6y + a2z * a6z;
  6503. if (dot1 < 0) dot1 = -dot1;
  6504. if (dot2 < 0) dot2 = -dot2;
  6505. if (dot3 < 0) dot3 = -dot3;
  6506. len2 = dot1 * w2 + dot2 * h2 + dot3 * d2;
  6507. overlap2 = len - len1 - len2;
  6508. if (overlap2 > 0) return;
  6509. // try axis 3
  6510. len = a3x * dx + a3y * dy + a3z * dz;
  6511. right3 = len > 0;
  6512. if (!right3) len = -len;
  6513. len1 = d1;
  6514. dot1 = a3x * a4x + a3y * a4y + a3z * a4z;
  6515. dot2 = a3x * a5x + a3y * a5y + a3z * a5z;
  6516. dot3 = a3x * a6x + a3y * a6y + a3z * a6z;
  6517. if (dot1 < 0) dot1 = -dot1;
  6518. if (dot2 < 0) dot2 = -dot2;
  6519. if (dot3 < 0) dot3 = -dot3;
  6520. len2 = dot1 * w2 + dot2 * h2 + dot3 * d2;
  6521. overlap3 = len - len1 - len2;
  6522. if (overlap3 > 0) return;
  6523. // try axis 4
  6524. len = a4x * dx + a4y * dy + a4z * dz;
  6525. right4 = len > 0;
  6526. if (!right4) len = -len;
  6527. dot1 = a4x * a1x + a4y * a1y + a4z * a1z;
  6528. dot2 = a4x * a2x + a4y * a2y + a4z * a2z;
  6529. dot3 = a4x * a3x + a4y * a3y + a4z * a3z;
  6530. if (dot1 < 0) dot1 = -dot1;
  6531. if (dot2 < 0) dot2 = -dot2;
  6532. if (dot3 < 0) dot3 = -dot3;
  6533. len1 = dot1 * w1 + dot2 * h1 + dot3 * d1;
  6534. len2 = w2;
  6535. overlap4 = (len - len1 - len2) * 1.0;
  6536. if (overlap4 > 0) return;
  6537. // try axis 5
  6538. len = a5x * dx + a5y * dy + a5z * dz;
  6539. right5 = len > 0;
  6540. if (!right5) len = -len;
  6541. dot1 = a5x * a1x + a5y * a1y + a5z * a1z;
  6542. dot2 = a5x * a2x + a5y * a2y + a5z * a2z;
  6543. dot3 = a5x * a3x + a5y * a3y + a5z * a3z;
  6544. if (dot1 < 0) dot1 = -dot1;
  6545. if (dot2 < 0) dot2 = -dot2;
  6546. if (dot3 < 0) dot3 = -dot3;
  6547. len1 = dot1 * w1 + dot2 * h1 + dot3 * d1;
  6548. len2 = h2;
  6549. overlap5 = (len - len1 - len2) * 1.0;
  6550. if (overlap5 > 0) return;
  6551. // try axis 6
  6552. len = a6x * dx + a6y * dy + a6z * dz;
  6553. right6 = len > 0;
  6554. if (!right6) len = -len;
  6555. dot1 = a6x * a1x + a6y * a1y + a6z * a1z;
  6556. dot2 = a6x * a2x + a6y * a2y + a6z * a2z;
  6557. dot3 = a6x * a3x + a6y * a3y + a6z * a3z;
  6558. if (dot1 < 0) dot1 = -dot1;
  6559. if (dot2 < 0) dot2 = -dot2;
  6560. if (dot3 < 0) dot3 = -dot3;
  6561. len1 = dot1 * w1 + dot2 * h1 + dot3 * d1;
  6562. len2 = d2;
  6563. overlap6 = (len - len1 - len2) * 1.0;
  6564. if (overlap6 > 0) return;
  6565. // try axis 7
  6566. len = a7x * a7x + a7y * a7y + a7z * a7z;
  6567. if (len > 1e-5) {
  6568. len = 1 / OIMO.sqrt(len);
  6569. a7x *= len;
  6570. a7y *= len;
  6571. a7z *= len;
  6572. len = a7x * dx + a7y * dy + a7z * dz;
  6573. right7 = len > 0;
  6574. if (!right7) len = -len;
  6575. dot1 = a7x * a2x + a7y * a2y + a7z * a2z;
  6576. dot2 = a7x * a3x + a7y * a3y + a7z * a3z;
  6577. if (dot1 < 0) dot1 = -dot1;
  6578. if (dot2 < 0) dot2 = -dot2;
  6579. len1 = dot1 * h1 + dot2 * d1;
  6580. dot1 = a7x * a5x + a7y * a5y + a7z * a5z;
  6581. dot2 = a7x * a6x + a7y * a6y + a7z * a6z;
  6582. if (dot1 < 0) dot1 = -dot1;
  6583. if (dot2 < 0) dot2 = -dot2;
  6584. len2 = dot1 * h2 + dot2 * d2;
  6585. overlap7 = len - len1 - len2;
  6586. if (overlap7 > 0) return;
  6587. } else {
  6588. right7 = false;
  6589. overlap7 = 0;
  6590. invalid7 = true;
  6591. }
  6592. // try axis 8
  6593. len = a8x * a8x + a8y * a8y + a8z * a8z;
  6594. if (len > 1e-5) {
  6595. len = 1 / OIMO.sqrt(len);
  6596. a8x *= len;
  6597. a8y *= len;
  6598. a8z *= len;
  6599. len = a8x * dx + a8y * dy + a8z * dz;
  6600. right8 = len > 0;
  6601. if (!right8) len = -len;
  6602. dot1 = a8x * a2x + a8y * a2y + a8z * a2z;
  6603. dot2 = a8x * a3x + a8y * a3y + a8z * a3z;
  6604. if (dot1 < 0) dot1 = -dot1;
  6605. if (dot2 < 0) dot2 = -dot2;
  6606. len1 = dot1 * h1 + dot2 * d1;
  6607. dot1 = a8x * a4x + a8y * a4y + a8z * a4z;
  6608. dot2 = a8x * a6x + a8y * a6y + a8z * a6z;
  6609. if (dot1 < 0) dot1 = -dot1;
  6610. if (dot2 < 0) dot2 = -dot2;
  6611. len2 = dot1 * w2 + dot2 * d2;
  6612. overlap8 = len - len1 - len2;
  6613. if (overlap8 > 0) return;
  6614. } else {
  6615. right8 = false;
  6616. overlap8 = 0;
  6617. invalid8 = true;
  6618. }
  6619. // try axis 9
  6620. len = a9x * a9x + a9y * a9y + a9z * a9z;
  6621. if (len > 1e-5) {
  6622. len = 1 / OIMO.sqrt(len);
  6623. a9x *= len;
  6624. a9y *= len;
  6625. a9z *= len;
  6626. len = a9x * dx + a9y * dy + a9z * dz;
  6627. right9 = len > 0;
  6628. if (!right9) len = -len;
  6629. dot1 = a9x * a2x + a9y * a2y + a9z * a2z;
  6630. dot2 = a9x * a3x + a9y * a3y + a9z * a3z;
  6631. if (dot1 < 0) dot1 = -dot1;
  6632. if (dot2 < 0) dot2 = -dot2;
  6633. len1 = dot1 * h1 + dot2 * d1;
  6634. dot1 = a9x * a4x + a9y * a4y + a9z * a4z;
  6635. dot2 = a9x * a5x + a9y * a5y + a9z * a5z;
  6636. if (dot1 < 0) dot1 = -dot1;
  6637. if (dot2 < 0) dot2 = -dot2;
  6638. len2 = dot1 * w2 + dot2 * h2;
  6639. overlap9 = len - len1 - len2;
  6640. if (overlap9 > 0) return;
  6641. } else {
  6642. right9 = false;
  6643. overlap9 = 0;
  6644. invalid9 = true;
  6645. }
  6646. // try axis 10
  6647. len = aax * aax + aay * aay + aaz * aaz;
  6648. if (len > 1e-5) {
  6649. len = 1 / OIMO.sqrt(len);
  6650. aax *= len;
  6651. aay *= len;
  6652. aaz *= len;
  6653. len = aax * dx + aay * dy + aaz * dz;
  6654. righta = len > 0;
  6655. if (!righta) len = -len;
  6656. dot1 = aax * a1x + aay * a1y + aaz * a1z;
  6657. dot2 = aax * a3x + aay * a3y + aaz * a3z;
  6658. if (dot1 < 0) dot1 = -dot1;
  6659. if (dot2 < 0) dot2 = -dot2;
  6660. len1 = dot1 * w1 + dot2 * d1;
  6661. dot1 = aax * a5x + aay * a5y + aaz * a5z;
  6662. dot2 = aax * a6x + aay * a6y + aaz * a6z;
  6663. if (dot1 < 0) dot1 = -dot1;
  6664. if (dot2 < 0) dot2 = -dot2;
  6665. len2 = dot1 * h2 + dot2 * d2;
  6666. overlapa = len - len1 - len2;
  6667. if (overlapa > 0) return;
  6668. } else {
  6669. righta = false;
  6670. overlapa = 0;
  6671. invalida = true;
  6672. }
  6673. // try axis 11
  6674. len = abx * abx + aby * aby + abz * abz;
  6675. if (len > 1e-5) {
  6676. len = 1 / OIMO.sqrt(len);
  6677. abx *= len;
  6678. aby *= len;
  6679. abz *= len;
  6680. len = abx * dx + aby * dy + abz * dz;
  6681. rightb = len > 0;
  6682. if (!rightb) len = -len;
  6683. dot1 = abx * a1x + aby * a1y + abz * a1z;
  6684. dot2 = abx * a3x + aby * a3y + abz * a3z;
  6685. if (dot1 < 0) dot1 = -dot1;
  6686. if (dot2 < 0) dot2 = -dot2;
  6687. len1 = dot1 * w1 + dot2 * d1;
  6688. dot1 = abx * a4x + aby * a4y + abz * a4z;
  6689. dot2 = abx * a6x + aby * a6y + abz * a6z;
  6690. if (dot1 < 0) dot1 = -dot1;
  6691. if (dot2 < 0) dot2 = -dot2;
  6692. len2 = dot1 * w2 + dot2 * d2;
  6693. overlapb = len - len1 - len2;
  6694. if (overlapb > 0) return;
  6695. } else {
  6696. rightb = false;
  6697. overlapb = 0;
  6698. invalidb = true;
  6699. }
  6700. // try axis 12
  6701. len = acx * acx + acy * acy + acz * acz;
  6702. if (len > 1e-5) {
  6703. len = 1 / OIMO.sqrt(len);
  6704. acx *= len;
  6705. acy *= len;
  6706. acz *= len;
  6707. len = acx * dx + acy * dy + acz * dz;
  6708. rightc = len > 0;
  6709. if (!rightc) len = -len;
  6710. dot1 = acx * a1x + acy * a1y + acz * a1z;
  6711. dot2 = acx * a3x + acy * a3y + acz * a3z;
  6712. if (dot1 < 0) dot1 = -dot1;
  6713. if (dot2 < 0) dot2 = -dot2;
  6714. len1 = dot1 * w1 + dot2 * d1;
  6715. dot1 = acx * a4x + acy * a4y + acz * a4z;
  6716. dot2 = acx * a5x + acy * a5y + acz * a5z;
  6717. if (dot1 < 0) dot1 = -dot1;
  6718. if (dot2 < 0) dot2 = -dot2;
  6719. len2 = dot1 * w2 + dot2 * h2;
  6720. overlapc = len - len1 - len2;
  6721. if (overlapc > 0) return;
  6722. } else {
  6723. rightc = false;
  6724. overlapc = 0;
  6725. invalidc = true;
  6726. }
  6727. // try axis 13
  6728. len = adx * adx + ady * ady + adz * adz;
  6729. if (len > 1e-5) {
  6730. len = 1 / OIMO.sqrt(len);
  6731. adx *= len;
  6732. ady *= len;
  6733. adz *= len;
  6734. len = adx * dx + ady * dy + adz * dz;
  6735. rightd = len > 0;
  6736. if (!rightd) len = -len;
  6737. dot1 = adx * a1x + ady * a1y + adz * a1z;
  6738. dot2 = adx * a2x + ady * a2y + adz * a2z;
  6739. if (dot1 < 0) dot1 = -dot1;
  6740. if (dot2 < 0) dot2 = -dot2;
  6741. len1 = dot1 * w1 + dot2 * h1;
  6742. dot1 = adx * a5x + ady * a5y + adz * a5z;
  6743. dot2 = adx * a6x + ady * a6y + adz * a6z;
  6744. if (dot1 < 0) dot1 = -dot1;
  6745. if (dot2 < 0) dot2 = -dot2;
  6746. len2 = dot1 * h2 + dot2 * d2;
  6747. overlapd = len - len1 - len2;
  6748. if (overlapd > 0) return;
  6749. } else {
  6750. rightd = false;
  6751. overlapd = 0;
  6752. invalidd = true;
  6753. }
  6754. // try axis 14
  6755. len = aex * aex + aey * aey + aez * aez;
  6756. if (len > 1e-5) {
  6757. len = 1 / OIMO.sqrt(len);
  6758. aex *= len;
  6759. aey *= len;
  6760. aez *= len;
  6761. len = aex * dx + aey * dy + aez * dz;
  6762. righte = len > 0;
  6763. if (!righte) len = -len;
  6764. dot1 = aex * a1x + aey * a1y + aez * a1z;
  6765. dot2 = aex * a2x + aey * a2y + aez * a2z;
  6766. if (dot1 < 0) dot1 = -dot1;
  6767. if (dot2 < 0) dot2 = -dot2;
  6768. len1 = dot1 * w1 + dot2 * h1;
  6769. dot1 = aex * a4x + aey * a4y + aez * a4z;
  6770. dot2 = aex * a6x + aey * a6y + aez * a6z;
  6771. if (dot1 < 0) dot1 = -dot1;
  6772. if (dot2 < 0) dot2 = -dot2;
  6773. len2 = dot1 * w2 + dot2 * d2;
  6774. overlape = len - len1 - len2;
  6775. if (overlape > 0) return;
  6776. } else {
  6777. righte = false;
  6778. overlape = 0;
  6779. invalide = true;
  6780. }
  6781. // try axis 15
  6782. len = afx * afx + afy * afy + afz * afz;
  6783. if (len > 1e-5) {
  6784. len = 1 / OIMO.sqrt(len);
  6785. afx *= len;
  6786. afy *= len;
  6787. afz *= len;
  6788. len = afx * dx + afy * dy + afz * dz;
  6789. rightf = len > 0;
  6790. if (!rightf) len = -len;
  6791. dot1 = afx * a1x + afy * a1y + afz * a1z;
  6792. dot2 = afx * a2x + afy * a2y + afz * a2z;
  6793. if (dot1 < 0) dot1 = -dot1;
  6794. if (dot2 < 0) dot2 = -dot2;
  6795. len1 = dot1 * w1 + dot2 * h1;
  6796. dot1 = afx * a4x + afy * a4y + afz * a4z;
  6797. dot2 = afx * a5x + afy * a5y + afz * a5z;
  6798. if (dot1 < 0) dot1 = -dot1;
  6799. if (dot2 < 0) dot2 = -dot2;
  6800. len2 = dot1 * w2 + dot2 * h2;
  6801. overlapf = len - len1 - len2;
  6802. if (overlapf > 0) return;
  6803. } else {
  6804. rightf = false;
  6805. overlapf = 0;
  6806. invalidf = true;
  6807. }
  6808. // boxes are overlapping
  6809. var depth = overlap1;
  6810. var depth2 = overlap1;
  6811. var minIndex = 0;
  6812. var right = right1;
  6813. if (overlap2 > depth2) {
  6814. depth = overlap2;
  6815. depth2 = overlap2;
  6816. minIndex = 1;
  6817. right = right2;
  6818. }
  6819. if (overlap3 > depth2) {
  6820. depth = overlap3;
  6821. depth2 = overlap3;
  6822. minIndex = 2;
  6823. right = right3;
  6824. }
  6825. if (overlap4 > depth2) {
  6826. depth = overlap4;
  6827. depth2 = overlap4;
  6828. minIndex = 3;
  6829. right = right4;
  6830. }
  6831. if (overlap5 > depth2) {
  6832. depth = overlap5;
  6833. depth2 = overlap5;
  6834. minIndex = 4;
  6835. right = right5;
  6836. }
  6837. if (overlap6 > depth2) {
  6838. depth = overlap6;
  6839. depth2 = overlap6;
  6840. minIndex = 5;
  6841. right = right6;
  6842. }
  6843. if (overlap7 - 0.01 > depth2 && !invalid7) {
  6844. depth = overlap7;
  6845. depth2 = overlap7 - 0.01;
  6846. minIndex = 6;
  6847. right = right7;
  6848. }
  6849. if (overlap8 - 0.01 > depth2 && !invalid8) {
  6850. depth = overlap8;
  6851. depth2 = overlap8 - 0.01;
  6852. minIndex = 7;
  6853. right = right8;
  6854. }
  6855. if (overlap9 - 0.01 > depth2 && !invalid9) {
  6856. depth = overlap9;
  6857. depth2 = overlap9 - 0.01;
  6858. minIndex = 8;
  6859. right = right9;
  6860. }
  6861. if (overlapa - 0.01 > depth2 && !invalida) {
  6862. depth = overlapa;
  6863. depth2 = overlapa - 0.01;
  6864. minIndex = 9;
  6865. right = righta;
  6866. }
  6867. if (overlapb - 0.01 > depth2 && !invalidb) {
  6868. depth = overlapb;
  6869. depth2 = overlapb - 0.01;
  6870. minIndex = 10;
  6871. right = rightb;
  6872. }
  6873. if (overlapc - 0.01 > depth2 && !invalidc) {
  6874. depth = overlapc;
  6875. depth2 = overlapc - 0.01;
  6876. minIndex = 11;
  6877. right = rightc;
  6878. }
  6879. if (overlapd - 0.01 > depth2 && !invalidd) {
  6880. depth = overlapd;
  6881. depth2 = overlapd - 0.01;
  6882. minIndex = 12;
  6883. right = rightd;
  6884. }
  6885. if (overlape - 0.01 > depth2 && !invalide) {
  6886. depth = overlape;
  6887. depth2 = overlape - 0.01;
  6888. minIndex = 13;
  6889. right = righte;
  6890. }
  6891. if (overlapf - 0.01 > depth2 && !invalidf) {
  6892. depth = overlapf;
  6893. minIndex = 14;
  6894. right = rightf;
  6895. }
  6896. // normal
  6897. var nx = 0;
  6898. var ny = 0;
  6899. var nz = 0;
  6900. // edge line or face side normal
  6901. var n1x = 0;
  6902. var n1y = 0;
  6903. var n1z = 0;
  6904. var n2x = 0;
  6905. var n2y = 0;
  6906. var n2z = 0;
  6907. // center of current face
  6908. var cx = 0;
  6909. var cy = 0;
  6910. var cz = 0;
  6911. // face side
  6912. var s1x = 0;
  6913. var s1y = 0;
  6914. var s1z = 0;
  6915. var s2x = 0;
  6916. var s2y = 0;
  6917. var s2z = 0;
  6918. // swap b1 b2
  6919. var swap = false;
  6920. //_______________________________________
  6921. if (minIndex == 0) {// b1.x * b2
  6922. if (right) {
  6923. cx = p1x + d1x; cy = p1y + d1y; cz = p1z + d1z;
  6924. nx = a1x; ny = a1y; nz = a1z;
  6925. } else {
  6926. cx = p1x - d1x; cy = p1y - d1y; cz = p1z - d1z;
  6927. nx = -a1x; ny = -a1y; nz = -a1z;
  6928. }
  6929. s1x = d2x; s1y = d2y; s1z = d2z;
  6930. n1x = -a2x; n1y = -a2y; n1z = -a2z;
  6931. s2x = d3x; s2y = d3y; s2z = d3z;
  6932. n2x = -a3x; n2y = -a3y; n2z = -a3z;
  6933. }
  6934. else if (minIndex == 1) {// b1.y * b2
  6935. if (right) {
  6936. cx = p1x + d2x; cy = p1y + d2y; cz = p1z + d2z;
  6937. nx = a2x; ny = a2y; nz = a2z;
  6938. } else {
  6939. cx = p1x - d2x; cy = p1y - d2y; cz = p1z - d2z;
  6940. nx = -a2x; ny = -a2y; nz = -a2z;
  6941. }
  6942. s1x = d1x; s1y = d1y; s1z = d1z;
  6943. n1x = -a1x; n1y = -a1y; n1z = -a1z;
  6944. s2x = d3x; s2y = d3y; s2z = d3z;
  6945. n2x = -a3x; n2y = -a3y; n2z = -a3z;
  6946. }
  6947. else if (minIndex == 2) {// b1.z * b2
  6948. if (right) {
  6949. cx = p1x + d3x; cy = p1y + d3y; cz = p1z + d3z;
  6950. nx = a3x; ny = a3y; nz = a3z;
  6951. } else {
  6952. cx = p1x - d3x; cy = p1y - d3y; cz = p1z - d3z;
  6953. nx = -a3x; ny = -a3y; nz = -a3z;
  6954. }
  6955. s1x = d1x; s1y = d1y; s1z = d1z;
  6956. n1x = -a1x; n1y = -a1y; n1z = -a1z;
  6957. s2x = d2x; s2y = d2y; s2z = d2z;
  6958. n2x = -a2x; n2y = -a2y; n2z = -a2z;
  6959. }
  6960. else if (minIndex == 3) {// b2.x * b1
  6961. swap = true;
  6962. if (!right) {
  6963. cx = p2x + d4x; cy = p2y + d4y; cz = p2z + d4z;
  6964. nx = a4x; ny = a4y; nz = a4z;
  6965. } else {
  6966. cx = p2x - d4x; cy = p2y - d4y; cz = p2z - d4z;
  6967. nx = -a4x; ny = -a4y; nz = -a4z;
  6968. }
  6969. s1x = d5x; s1y = d5y; s1z = d5z;
  6970. n1x = -a5x; n1y = -a5y; n1z = -a5z;
  6971. s2x = d6x; s2y = d6y; s2z = d6z;
  6972. n2x = -a6x; n2y = -a6y; n2z = -a6z;
  6973. }
  6974. else if (minIndex == 4) {// b2.y * b1
  6975. swap = true;
  6976. if (!right) {
  6977. cx = p2x + d5x; cy = p2y + d5y; cz = p2z + d5z;
  6978. nx = a5x; ny = a5y; nz = a5z;
  6979. } else {
  6980. cx = p2x - d5x; cy = p2y - d5y; cz = p2z - d5z;
  6981. nx = -a5x; ny = -a5y; nz = -a5z;
  6982. }
  6983. s1x = d4x; s1y = d4y; s1z = d4z;
  6984. n1x = -a4x; n1y = -a4y; n1z = -a4z;
  6985. s2x = d6x; s2y = d6y; s2z = d6z;
  6986. n2x = -a6x; n2y = -a6y; n2z = -a6z;
  6987. }
  6988. else if (minIndex == 5) {// b2.z * b1
  6989. swap = true;
  6990. if (!right) {
  6991. cx = p2x + d6x; cy = p2y + d6y; cz = p2z + d6z;
  6992. nx = a6x; ny = a6y; nz = a6z;
  6993. } else {
  6994. cx = p2x - d6x; cy = p2y - d6y; cz = p2z - d6z;
  6995. nx = -a6x; ny = -a6y; nz = -a6z;
  6996. }
  6997. s1x = d4x; s1y = d4y; s1z = d4z;
  6998. n1x = -a4x; n1y = -a4y; n1z = -a4z;
  6999. s2x = d5x; s2y = d5y; s2z = d5z;
  7000. n2x = -a5x; n2y = -a5y; n2z = -a5z;
  7001. }
  7002. else if (minIndex == 6) {// b1.x * b2.x
  7003. nx = a7x; ny = a7y; nz = a7z;
  7004. n1x = a1x; n1y = a1y; n1z = a1z;
  7005. n2x = a4x; n2y = a4y; n2z = a4z;
  7006. }
  7007. else if (minIndex == 7) {// b1.x * b2.y
  7008. nx = a8x; ny = a8y; nz = a8z;
  7009. n1x = a1x; n1y = a1y; n1z = a1z;
  7010. n2x = a5x; n2y = a5y; n2z = a5z;
  7011. }
  7012. else if (minIndex == 8) {// b1.x * b2.z
  7013. nx = a9x; ny = a9y; nz = a9z;
  7014. n1x = a1x; n1y = a1y; n1z = a1z;
  7015. n2x = a6x; n2y = a6y; n2z = a6z;
  7016. }
  7017. else if (minIndex == 9) {// b1.y * b2.x
  7018. nx = aax; ny = aay; nz = aaz;
  7019. n1x = a2x; n1y = a2y; n1z = a2z;
  7020. n2x = a4x; n2y = a4y; n2z = a4z
  7021. }
  7022. else if (minIndex == 10) {// b1.y * b2.y
  7023. nx = abx; ny = aby; nz = abz;
  7024. n1x = a2x; n1y = a2y; n1z = a2z;
  7025. n2x = a5x; n2y = a5y; n2z = a5z;
  7026. }
  7027. else if (minIndex == 11) {// b1.y * b2.z
  7028. nx = acx; ny = acy; nz = acz;
  7029. n1x = a2x; n1y = a2y; n1z = a2z;
  7030. n2x = a6x; n2y = a6y; n2z = a6z;
  7031. }
  7032. else if (minIndex == 12) {// b1.z * b2.x
  7033. nx = adx; ny = ady; nz = adz;
  7034. n1x = a3x; n1y = a3y; n1z = a3z;
  7035. n2x = a4x; n2y = a4y; n2z = a4z;
  7036. }
  7037. else if (minIndex == 13) {// b1.z * b2.y
  7038. nx = aex; ny = aey; nz = aez;
  7039. n1x = a3x; n1y = a3y; n1z = a3z;
  7040. n2x = a5x; n2y = a5y; n2z = a5z;
  7041. }
  7042. else if (minIndex == 14) {// b1.z * b2.z
  7043. nx = afx; ny = afy; nz = afz;
  7044. n1x = a3x; n1y = a3y; n1z = a3z;
  7045. n2x = a6x; n2y = a6y; n2z = a6z;
  7046. }
  7047. //__________________________________________
  7048. var v;
  7049. if (minIndex > 5) {
  7050. if (!right) {
  7051. nx = -nx; ny = -ny; nz = -nz;
  7052. }
  7053. var distance;
  7054. var maxDistance;
  7055. var vx;
  7056. var vy;
  7057. var vz;
  7058. var v1x;
  7059. var v1y;
  7060. var v1z;
  7061. var v2x;
  7062. var v2y;
  7063. var v2z;
  7064. //vertex1;
  7065. v1x = V1[0]; v1y = V1[1]; v1z = V1[2];
  7066. maxDistance = nx * v1x + ny * v1y + nz * v1z;
  7067. //vertex2;
  7068. vx = V1[3]; vy = V1[4]; vz = V1[5];
  7069. distance = nx * vx + ny * vy + nz * vz;
  7070. if (distance > maxDistance) {
  7071. maxDistance = distance;
  7072. v1x = vx; v1y = vy; v1z = vz;
  7073. }
  7074. //vertex3;
  7075. vx = V1[6]; vy = V1[7]; vz = V1[8];
  7076. distance = nx * vx + ny * vy + nz * vz;
  7077. if (distance > maxDistance) {
  7078. maxDistance = distance;
  7079. v1x = vx; v1y = vy; v1z = vz;
  7080. }
  7081. //vertex4;
  7082. vx = V1[9]; vy = V1[10]; vz = V1[11];
  7083. distance = nx * vx + ny * vy + nz * vz;
  7084. if (distance > maxDistance) {
  7085. maxDistance = distance;
  7086. v1x = vx; v1y = vy; v1z = vz;
  7087. }
  7088. //vertex5;
  7089. vx = V1[12]; vy = V1[13]; vz = V1[14];
  7090. distance = nx * vx + ny * vy + nz * vz;
  7091. if (distance > maxDistance) {
  7092. maxDistance = distance;
  7093. v1x = vx; v1y = vy; v1z = vz;
  7094. }
  7095. //vertex6;
  7096. vx = V1[15]; vy = V1[16]; vz = V1[17];
  7097. distance = nx * vx + ny * vy + nz * vz;
  7098. if (distance > maxDistance) {
  7099. maxDistance = distance;
  7100. v1x = vx; v1y = vy; v1z = vz;
  7101. }
  7102. //vertex7;
  7103. vx = V1[18]; vy = V1[19]; vz = V1[20];
  7104. distance = nx * vx + ny * vy + nz * vz;
  7105. if (distance > maxDistance) {
  7106. maxDistance = distance;
  7107. v1x = vx; v1y = vy; v1z = vz;
  7108. }
  7109. //vertex8;
  7110. vx = V1[21]; vy = V1[22]; vz = V1[23];
  7111. distance = nx * vx + ny * vy + nz * vz;
  7112. if (distance > maxDistance) {
  7113. maxDistance = distance;
  7114. v1x = vx; v1y = vy; v1z = vz;
  7115. }
  7116. //vertex1;
  7117. v2x = V2[0]; v2y = V2[1]; v2z = V2[2];
  7118. maxDistance = nx * v2x + ny * v2y + nz * v2z;
  7119. //vertex2;
  7120. vx = V2[3]; vy = V2[4]; vz = V2[5];
  7121. distance = nx * vx + ny * vy + nz * vz;
  7122. if (distance < maxDistance) {
  7123. maxDistance = distance;
  7124. v2x = vx; v2y = vy; v2z = vz;
  7125. }
  7126. //vertex3;
  7127. vx = V2[6]; vy = V2[7]; vz = V2[8];
  7128. distance = nx * vx + ny * vy + nz * vz;
  7129. if (distance < maxDistance) {
  7130. maxDistance = distance;
  7131. v2x = vx; v2y = vy; v2z = vz;
  7132. }
  7133. //vertex4;
  7134. vx = V2[9]; vy = V2[10]; vz = V2[11];
  7135. distance = nx * vx + ny * vy + nz * vz;
  7136. if (distance < maxDistance) {
  7137. maxDistance = distance;
  7138. v2x = vx; v2y = vy; v2z = vz;
  7139. }
  7140. //vertex5;
  7141. vx = V2[12]; vy = V2[13]; vz = V2[14];
  7142. distance = nx * vx + ny * vy + nz * vz;
  7143. if (distance < maxDistance) {
  7144. maxDistance = distance;
  7145. v2x = vx; v2y = vy; v2z = vz;
  7146. }
  7147. //vertex6;
  7148. vx = V2[15]; vy = V2[16]; vz = V2[17];
  7149. distance = nx * vx + ny * vy + nz * vz;
  7150. if (distance < maxDistance) {
  7151. maxDistance = distance;
  7152. v2x = vx; v2y = vy; v2z = vz;
  7153. }
  7154. //vertex7;
  7155. vx = V2[18]; vy = V2[19]; vz = V2[20];
  7156. distance = nx * vx + ny * vy + nz * vz;
  7157. if (distance < maxDistance) {
  7158. maxDistance = distance;
  7159. v2x = vx; v2y = vy; v2z = vz;
  7160. }
  7161. //vertex8;
  7162. vx = V2[21]; vy = V2[22]; vz = V2[23];
  7163. distance = nx * vx + ny * vy + nz * vz;
  7164. if (distance < maxDistance) {
  7165. maxDistance = distance;
  7166. v2x = vx; v2y = vy; v2z = vz;
  7167. }
  7168. vx = v2x - v1x; vy = v2y - v1y; vz = v2z - v1z;
  7169. dot1 = n1x * n2x + n1y * n2y + n1z * n2z;
  7170. var t = (vx * (n1x - n2x * dot1) + vy * (n1y - n2y * dot1) + vz * (n1z - n2z * dot1)) / (1 - dot1 * dot1);
  7171. manifold.addPoint(v1x + n1x * t + nx * depth * 0.5, v1y + n1y * t + ny * depth * 0.5, v1z + n1z * t + nz * depth * 0.5, nx, ny, nz, depth, false);
  7172. return;
  7173. }
  7174. // now detect face-face collision...
  7175. // target quad
  7176. var q1x;
  7177. var q1y;
  7178. var q1z;
  7179. var q2x;
  7180. var q2y;
  7181. var q2z;
  7182. var q3x;
  7183. var q3y;
  7184. var q3z;
  7185. var q4x;
  7186. var q4y;
  7187. var q4z;
  7188. // search support face and vertex
  7189. var minDot = 1;
  7190. var dot = 0;
  7191. var minDotIndex = 0;
  7192. if (swap) {
  7193. dot = a1x * nx + a1y * ny + a1z * nz;
  7194. if (dot < minDot) {
  7195. minDot = dot;
  7196. minDotIndex = 0;
  7197. }
  7198. if (-dot < minDot) {
  7199. minDot = -dot;
  7200. minDotIndex = 1;
  7201. }
  7202. dot = a2x * nx + a2y * ny + a2z * nz;
  7203. if (dot < minDot) {
  7204. minDot = dot;
  7205. minDotIndex = 2;
  7206. }
  7207. if (-dot < minDot) {
  7208. minDot = -dot;
  7209. minDotIndex = 3;
  7210. }
  7211. dot = a3x * nx + a3y * ny + a3z * nz;
  7212. if (dot < minDot) {
  7213. minDot = dot;
  7214. minDotIndex = 4;
  7215. }
  7216. if (-dot < minDot) {
  7217. minDot = -dot;
  7218. minDotIndex = 5;
  7219. }
  7220. if (minDotIndex == 0) {// x+ face
  7221. q1x = V1[0]; q1y = V1[1]; q1z = V1[2];//vertex1
  7222. q2x = V1[6]; q2y = V1[7]; q2z = V1[8];//vertex3
  7223. q3x = V1[9]; q3y = V1[10]; q3z = V1[11];//vertex4
  7224. q4x = V1[3]; q4y = V1[4]; q4z = V1[5];//vertex2
  7225. }
  7226. else if (minDotIndex == 1) {// x- face
  7227. q1x = V1[15]; q1y = V1[16]; q1z = V1[17];//vertex6
  7228. q2x = V1[21]; q2y = V1[22]; q2z = V1[23];//vertex8
  7229. q3x = V1[18]; q3y = V1[19]; q3z = V1[20];//vertex7
  7230. q4x = V1[12]; q4y = V1[13]; q4z = V1[14];//vertex5
  7231. }
  7232. else if (minDotIndex == 2) {// y+ face
  7233. q1x = V1[12]; q1y = V1[13]; q1z = V1[14];//vertex5
  7234. q2x = V1[0]; q2y = V1[1]; q2z = V1[2];//vertex1
  7235. q3x = V1[3]; q3y = V1[4]; q3z = V1[5];//vertex2
  7236. q4x = V1[15]; q4y = V1[16]; q4z = V1[17];//vertex6
  7237. }
  7238. else if (minDotIndex == 3) {// y- face
  7239. q1x = V1[21]; q1y = V1[22]; q1z = V1[23];//vertex8
  7240. q2x = V1[9]; q2y = V1[10]; q2z = V1[11];//vertex4
  7241. q3x = V1[6]; q3y = V1[7]; q3z = V1[8];//vertex3
  7242. q4x = V1[18]; q4y = V1[19]; q4z = V1[20];//vertex7
  7243. }
  7244. else if (minDotIndex == 4) {// z+ face
  7245. q1x = V1[12]; q1y = V1[13]; q1z = V1[14];//vertex5
  7246. q2x = V1[18]; q2y = V1[19]; q2z = V1[20];//vertex7
  7247. q3x = V1[6]; q3y = V1[7]; q3z = V1[8];//vertex3
  7248. q4x = V1[0]; q4y = V1[1]; q4z = V1[2];//vertex1
  7249. }
  7250. else if (minDotIndex == 5) {// z- face
  7251. q1x = V1[3]; q1y = V1[4]; q1z = V1[5];//vertex2
  7252. q2x = V1[6]; q2y = V1[7]; q2z = V1[8];//vertex4
  7253. q3x = V1[21]; q3y = V1[22]; q3z = V1[23];//vertex8
  7254. q4x = V1[15]; q4y = V1[16]; q4z = V1[17];//vertex6
  7255. }
  7256. } else {
  7257. dot = a4x * nx + a4y * ny + a4z * nz;
  7258. if (dot < minDot) {
  7259. minDot = dot;
  7260. minDotIndex = 0;
  7261. }
  7262. if (-dot < minDot) {
  7263. minDot = -dot;
  7264. minDotIndex = 1;
  7265. }
  7266. dot = a5x * nx + a5y * ny + a5z * nz;
  7267. if (dot < minDot) {
  7268. minDot = dot;
  7269. minDotIndex = 2;
  7270. }
  7271. if (-dot < minDot) {
  7272. minDot = -dot;
  7273. minDotIndex = 3;
  7274. }
  7275. dot = a6x * nx + a6y * ny + a6z * nz;
  7276. if (dot < minDot) {
  7277. minDot = dot;
  7278. minDotIndex = 4;
  7279. }
  7280. if (-dot < minDot) {
  7281. minDot = -dot;
  7282. minDotIndex = 5;
  7283. }
  7284. //______________________________________________________
  7285. if (minDotIndex == 0) {// x+ face
  7286. q1x = V2[0]; q1y = V2[1]; q1z = V2[2];//vertex1
  7287. q2x = V2[6]; q2y = V2[7]; q2z = V2[8];//vertex3
  7288. q3x = V2[9]; q3y = V2[10]; q3z = V2[11];//vertex4
  7289. q4x = V2[3]; q4y = V2[4]; q4z = V2[5];//vertex2
  7290. }
  7291. else if (minDotIndex == 1) {// x- face
  7292. q1x = V2[15]; q1y = V2[16]; q1z = V2[17];//vertex6
  7293. q2x = V2[21]; q2y = V2[22]; q2z = V2[23]; //vertex8
  7294. q3x = V2[18]; q3y = V2[19]; q3z = V2[20];//vertex7
  7295. q4x = V2[12]; q4y = V2[13]; q4z = V2[14];//vertex5
  7296. }
  7297. else if (minDotIndex == 2) {// y+ face
  7298. q1x = V2[12]; q1y = V2[13]; q1z = V2[14];//vertex5
  7299. q2x = V2[0]; q2y = V2[1]; q2z = V2[2];//vertex1
  7300. q3x = V2[3]; q3y = V2[4]; q3z = V2[5];//vertex2
  7301. q4x = V2[15]; q4y = V2[16]; q4z = V2[17];//vertex6
  7302. }
  7303. else if (minDotIndex == 3) {// y- face
  7304. q1x = V2[21]; q1y = V2[22]; q1z = V2[23];//vertex8
  7305. q2x = V2[9]; q2y = V2[10]; q2z = V2[11];//vertex4
  7306. q3x = V2[6]; q3y = V2[7]; q3z = V2[8];//vertex3
  7307. q4x = V2[18]; q4y = V2[19]; q4z = V2[20];//vertex7
  7308. }
  7309. else if (minDotIndex == 4) {// z+ face
  7310. q1x = V2[12]; q1y = V2[13]; q1z = V2[14];//vertex5
  7311. q2x = V2[18]; q2y = V2[19]; q2z = V2[20];//vertex7
  7312. q3x = V2[6]; q3y = V2[7]; q3z = V2[8];//vertex3
  7313. q4x = V2[0]; q4y = V2[1]; q4z = V2[2];//vertex1
  7314. }
  7315. else if (minDotIndex == 5) {// z- face
  7316. q1x = V2[3]; q1y = V2[4]; q1z = V2[5];//vertex2
  7317. q2x = V2[9]; q2y = V2[10]; q2z = V2[11];//vertex4
  7318. q3x = V2[21]; q3y = V2[22]; q3z = V2[23];//vertex8
  7319. q4x = V2[15]; q4y = V2[16]; q4z = V2[17];//vertex6
  7320. }
  7321. }
  7322. // clip vertices
  7323. var numClipVertices;
  7324. var numAddedClipVertices;
  7325. var index;
  7326. var x1;
  7327. var y1;
  7328. var z1;
  7329. var x2;
  7330. var y2;
  7331. var z2;
  7332. this.clipVertices1[0] = q1x;
  7333. this.clipVertices1[1] = q1y;
  7334. this.clipVertices1[2] = q1z;
  7335. this.clipVertices1[3] = q2x;
  7336. this.clipVertices1[4] = q2y;
  7337. this.clipVertices1[5] = q2z;
  7338. this.clipVertices1[6] = q3x;
  7339. this.clipVertices1[7] = q3y;
  7340. this.clipVertices1[8] = q3z;
  7341. this.clipVertices1[9] = q4x;
  7342. this.clipVertices1[10] = q4y;
  7343. this.clipVertices1[11] = q4z;
  7344. numAddedClipVertices = 0;
  7345. x1 = this.clipVertices1[9];
  7346. y1 = this.clipVertices1[10];
  7347. z1 = this.clipVertices1[11];
  7348. dot1 = (x1 - cx - s1x) * n1x + (y1 - cy - s1y) * n1y + (z1 - cz - s1z) * n1z;
  7349. //var i = 4;
  7350. //while(i--){
  7351. for (var i = 0; i < 4; i++) {
  7352. index = i * 3;
  7353. x2 = this.clipVertices1[index];
  7354. y2 = this.clipVertices1[index + 1];
  7355. z2 = this.clipVertices1[index + 2];
  7356. dot2 = (x2 - cx - s1x) * n1x + (y2 - cy - s1y) * n1y + (z2 - cz - s1z) * n1z;
  7357. if (dot1 > 0) {
  7358. if (dot2 > 0) {
  7359. index = numAddedClipVertices * 3;
  7360. numAddedClipVertices++;
  7361. this.clipVertices2[index] = x2;
  7362. this.clipVertices2[index + 1] = y2;
  7363. this.clipVertices2[index + 2] = z2;
  7364. } else {
  7365. index = numAddedClipVertices * 3;
  7366. numAddedClipVertices++;
  7367. t = dot1 / (dot1 - dot2);
  7368. this.clipVertices2[index] = x1 + (x2 - x1) * t;
  7369. this.clipVertices2[index + 1] = y1 + (y2 - y1) * t;
  7370. this.clipVertices2[index + 2] = z1 + (z2 - z1) * t;
  7371. }
  7372. } else {
  7373. if (dot2 > 0) {
  7374. index = numAddedClipVertices * 3;
  7375. numAddedClipVertices++;
  7376. t = dot1 / (dot1 - dot2);
  7377. this.clipVertices2[index] = x1 + (x2 - x1) * t;
  7378. this.clipVertices2[index + 1] = y1 + (y2 - y1) * t;
  7379. this.clipVertices2[index + 2] = z1 + (z2 - z1) * t;
  7380. index = numAddedClipVertices * 3;
  7381. numAddedClipVertices++;
  7382. this.clipVertices2[index] = x2;
  7383. this.clipVertices2[index + 1] = y2;
  7384. this.clipVertices2[index + 2] = z2;
  7385. }
  7386. }
  7387. x1 = x2;
  7388. y1 = y2;
  7389. z1 = z2;
  7390. dot1 = dot2;
  7391. }
  7392. numClipVertices = numAddedClipVertices;
  7393. if (numClipVertices == 0) return;
  7394. numAddedClipVertices = 0;
  7395. index = (numClipVertices - 1) * 3;
  7396. x1 = this.clipVertices2[index];
  7397. y1 = this.clipVertices2[index + 1];
  7398. z1 = this.clipVertices2[index + 2];
  7399. dot1 = (x1 - cx - s2x) * n2x + (y1 - cy - s2y) * n2y + (z1 - cz - s2z) * n2z;
  7400. //i = numClipVertices;
  7401. //while(i--){
  7402. for (i = 0; i < numClipVertices; i++) {
  7403. index = i * 3;
  7404. x2 = this.clipVertices2[index];
  7405. y2 = this.clipVertices2[index + 1];
  7406. z2 = this.clipVertices2[index + 2];
  7407. dot2 = (x2 - cx - s2x) * n2x + (y2 - cy - s2y) * n2y + (z2 - cz - s2z) * n2z;
  7408. if (dot1 > 0) {
  7409. if (dot2 > 0) {
  7410. index = numAddedClipVertices * 3;
  7411. numAddedClipVertices++;
  7412. this.clipVertices1[index] = x2;
  7413. this.clipVertices1[index + 1] = y2;
  7414. this.clipVertices1[index + 2] = z2;
  7415. } else {
  7416. index = numAddedClipVertices * 3;
  7417. numAddedClipVertices++;
  7418. t = dot1 / (dot1 - dot2);
  7419. this.clipVertices1[index] = x1 + (x2 - x1) * t;
  7420. this.clipVertices1[index + 1] = y1 + (y2 - y1) * t;
  7421. this.clipVertices1[index + 2] = z1 + (z2 - z1) * t;
  7422. }
  7423. } else {
  7424. if (dot2 > 0) {
  7425. index = numAddedClipVertices * 3;
  7426. numAddedClipVertices++;
  7427. t = dot1 / (dot1 - dot2);
  7428. this.clipVertices1[index] = x1 + (x2 - x1) * t;
  7429. this.clipVertices1[index + 1] = y1 + (y2 - y1) * t;
  7430. this.clipVertices1[index + 2] = z1 + (z2 - z1) * t;
  7431. index = numAddedClipVertices * 3;
  7432. numAddedClipVertices++;
  7433. this.clipVertices1[index] = x2;
  7434. this.clipVertices1[index + 1] = y2;
  7435. this.clipVertices1[index + 2] = z2;
  7436. }
  7437. }
  7438. x1 = x2;
  7439. y1 = y2;
  7440. z1 = z2;
  7441. dot1 = dot2;
  7442. }
  7443. numClipVertices = numAddedClipVertices;
  7444. if (numClipVertices == 0) return;
  7445. numAddedClipVertices = 0;
  7446. index = (numClipVertices - 1) * 3;
  7447. x1 = this.clipVertices1[index];
  7448. y1 = this.clipVertices1[index + 1];
  7449. z1 = this.clipVertices1[index + 2];
  7450. dot1 = (x1 - cx + s1x) * -n1x + (y1 - cy + s1y) * -n1y + (z1 - cz + s1z) * -n1z;
  7451. //i = numClipVertices;
  7452. //while(i--){
  7453. for (i = 0; i < numClipVertices; i++) {
  7454. index = i * 3;
  7455. x2 = this.clipVertices1[index];
  7456. y2 = this.clipVertices1[index + 1];
  7457. z2 = this.clipVertices1[index + 2];
  7458. dot2 = (x2 - cx + s1x) * -n1x + (y2 - cy + s1y) * -n1y + (z2 - cz + s1z) * -n1z;
  7459. if (dot1 > 0) {
  7460. if (dot2 > 0) {
  7461. index = numAddedClipVertices * 3;
  7462. numAddedClipVertices++;
  7463. this.clipVertices2[index] = x2;
  7464. this.clipVertices2[index + 1] = y2;
  7465. this.clipVertices2[index + 2] = z2;
  7466. } else {
  7467. index = numAddedClipVertices * 3;
  7468. numAddedClipVertices++;
  7469. t = dot1 / (dot1 - dot2);
  7470. this.clipVertices2[index] = x1 + (x2 - x1) * t;
  7471. this.clipVertices2[index + 1] = y1 + (y2 - y1) * t;
  7472. this.clipVertices2[index + 2] = z1 + (z2 - z1) * t;
  7473. }
  7474. } else {
  7475. if (dot2 > 0) {
  7476. index = numAddedClipVertices * 3;
  7477. numAddedClipVertices++;
  7478. t = dot1 / (dot1 - dot2);
  7479. this.clipVertices2[index] = x1 + (x2 - x1) * t;
  7480. this.clipVertices2[index + 1] = y1 + (y2 - y1) * t;
  7481. this.clipVertices2[index + 2] = z1 + (z2 - z1) * t;
  7482. index = numAddedClipVertices * 3;
  7483. numAddedClipVertices++;
  7484. this.clipVertices2[index] = x2;
  7485. this.clipVertices2[index + 1] = y2;
  7486. this.clipVertices2[index + 2] = z2;
  7487. }
  7488. }
  7489. x1 = x2;
  7490. y1 = y2;
  7491. z1 = z2;
  7492. dot1 = dot2;
  7493. }
  7494. numClipVertices = numAddedClipVertices;
  7495. if (numClipVertices == 0) return;
  7496. numAddedClipVertices = 0;
  7497. index = (numClipVertices - 1) * 3;
  7498. x1 = this.clipVertices2[index];
  7499. y1 = this.clipVertices2[index + 1];
  7500. z1 = this.clipVertices2[index + 2];
  7501. dot1 = (x1 - cx + s2x) * -n2x + (y1 - cy + s2y) * -n2y + (z1 - cz + s2z) * -n2z;
  7502. //i = numClipVertices;
  7503. //while(i--){
  7504. for (i = 0; i < numClipVertices; i++) {
  7505. index = i * 3;
  7506. x2 = this.clipVertices2[index];
  7507. y2 = this.clipVertices2[index + 1];
  7508. z2 = this.clipVertices2[index + 2];
  7509. dot2 = (x2 - cx + s2x) * -n2x + (y2 - cy + s2y) * -n2y + (z2 - cz + s2z) * -n2z;
  7510. if (dot1 > 0) {
  7511. if (dot2 > 0) {
  7512. index = numAddedClipVertices * 3;
  7513. numAddedClipVertices++;
  7514. this.clipVertices1[index] = x2;
  7515. this.clipVertices1[index + 1] = y2;
  7516. this.clipVertices1[index + 2] = z2;
  7517. } else {
  7518. index = numAddedClipVertices * 3;
  7519. numAddedClipVertices++;
  7520. t = dot1 / (dot1 - dot2);
  7521. this.clipVertices1[index] = x1 + (x2 - x1) * t;
  7522. this.clipVertices1[index + 1] = y1 + (y2 - y1) * t;
  7523. this.clipVertices1[index + 2] = z1 + (z2 - z1) * t;
  7524. }
  7525. } else {
  7526. if (dot2 > 0) {
  7527. index = numAddedClipVertices * 3;
  7528. numAddedClipVertices++;
  7529. t = dot1 / (dot1 - dot2);
  7530. this.clipVertices1[index] = x1 + (x2 - x1) * t;
  7531. this.clipVertices1[index + 1] = y1 + (y2 - y1) * t;
  7532. this.clipVertices1[index + 2] = z1 + (z2 - z1) * t;
  7533. index = numAddedClipVertices * 3;
  7534. numAddedClipVertices++;
  7535. this.clipVertices1[index] = x2;
  7536. this.clipVertices1[index + 1] = y2;
  7537. this.clipVertices1[index + 2] = z2;
  7538. }
  7539. }
  7540. x1 = x2;
  7541. y1 = y2;
  7542. z1 = z2;
  7543. dot1 = dot2;
  7544. }
  7545. numClipVertices = numAddedClipVertices;
  7546. if (swap) {
  7547. var tb = b1;
  7548. b1 = b2;
  7549. b2 = tb;
  7550. }
  7551. if (numClipVertices == 0) return;
  7552. var flipped = b1 != shape1;
  7553. if (numClipVertices > 4) {
  7554. x1 = (q1x + q2x + q3x + q4x) * 0.25;
  7555. y1 = (q1y + q2y + q3y + q4y) * 0.25;
  7556. z1 = (q1z + q2z + q3z + q4z) * 0.25;
  7557. n1x = q1x - x1;
  7558. n1y = q1y - y1;
  7559. n1z = q1z - z1;
  7560. n2x = q2x - x1;
  7561. n2y = q2y - y1;
  7562. n2z = q2z - z1;
  7563. var index1 = 0;
  7564. var index2 = 0;
  7565. var index3 = 0;
  7566. var index4 = 0;
  7567. var maxDot = -this.INF;
  7568. minDot = this.INF;
  7569. //i = numClipVertices;
  7570. //while(i--){
  7571. for (i = 0; i < numClipVertices; i++) {
  7572. this.used[i] = false;
  7573. index = i * 3;
  7574. x1 = this.clipVertices1[index];
  7575. y1 = this.clipVertices1[index + 1];
  7576. z1 = this.clipVertices1[index + 2];
  7577. dot = x1 * n1x + y1 * n1y + z1 * n1z;
  7578. if (dot < minDot) {
  7579. minDot = dot;
  7580. index1 = i;
  7581. }
  7582. if (dot > maxDot) {
  7583. maxDot = dot;
  7584. index3 = i;
  7585. }
  7586. }
  7587. this.used[index1] = true;
  7588. this.used[index3] = true;
  7589. maxDot = -this.INF;
  7590. minDot = this.INF;
  7591. //i = numClipVertices;
  7592. //while(i--){
  7593. for (i = 0; i < numClipVertices; i++) {
  7594. if (this.used[i]) continue;
  7595. index = i * 3;
  7596. x1 = this.clipVertices1[index];
  7597. y1 = this.clipVertices1[index + 1];
  7598. z1 = this.clipVertices1[index + 2];
  7599. dot = x1 * n2x + y1 * n2y + z1 * n2z;
  7600. if (dot < minDot) {
  7601. minDot = dot;
  7602. index2 = i;
  7603. }
  7604. if (dot > maxDot) {
  7605. maxDot = dot;
  7606. index4 = i;
  7607. }
  7608. }
  7609. index = index1 * 3;
  7610. x1 = this.clipVertices1[index];
  7611. y1 = this.clipVertices1[index + 1];
  7612. z1 = this.clipVertices1[index + 2];
  7613. dot = (x1 - cx) * nx + (y1 - cy) * ny + (z1 - cz) * nz;
  7614. if (dot < 0) manifold.addPoint(x1, y1, z1, nx, ny, nz, dot, flipped);
  7615. index = index2 * 3;
  7616. x1 = this.clipVertices1[index];
  7617. y1 = this.clipVertices1[index + 1];
  7618. z1 = this.clipVertices1[index + 2];
  7619. dot = (x1 - cx) * nx + (y1 - cy) * ny + (z1 - cz) * nz;
  7620. if (dot < 0) manifold.addPoint(x1, y1, z1, nx, ny, nz, dot, flipped);
  7621. index = index3 * 3;
  7622. x1 = this.clipVertices1[index];
  7623. y1 = this.clipVertices1[index + 1];
  7624. z1 = this.clipVertices1[index + 2];
  7625. dot = (x1 - cx) * nx + (y1 - cy) * ny + (z1 - cz) * nz;
  7626. if (dot < 0) manifold.addPoint(x1, y1, z1, nx, ny, nz, dot, flipped);
  7627. index = index4 * 3;
  7628. x1 = this.clipVertices1[index];
  7629. y1 = this.clipVertices1[index + 1];
  7630. z1 = this.clipVertices1[index + 2];
  7631. dot = (x1 - cx) * nx + (y1 - cy) * ny + (z1 - cz) * nz;
  7632. if (dot < 0) manifold.addPoint(x1, y1, z1, nx, ny, nz, dot, flipped);
  7633. } else {
  7634. //i = numClipVertices;
  7635. //while(i--){
  7636. for (i = 0; i < numClipVertices; i++) {
  7637. index = i * 3;
  7638. x1 = this.clipVertices1[index];
  7639. y1 = this.clipVertices1[index + 1];
  7640. z1 = this.clipVertices1[index + 2];
  7641. dot = (x1 - cx) * nx + (y1 - cy) * ny + (z1 - cz) * nz;
  7642. if (dot < 0) manifold.addPoint(x1, y1, z1, nx, ny, nz, dot, flipped);
  7643. }
  7644. }
  7645. };
  7646. /**
  7647. * A collision detector which detects collisions between sphere and box.
  7648. * @author saharan
  7649. */
  7650. OIMO.SphereBoxCollisionDetector = function (flip) {
  7651. OIMO.CollisionDetector.call(this);
  7652. this.flip = flip;
  7653. };
  7654. OIMO.SphereBoxCollisionDetector.prototype = Object.create(OIMO.CollisionDetector.prototype);
  7655. OIMO.SphereBoxCollisionDetector.prototype.constructor = OIMO.SphereBoxCollisionDetector;
  7656. OIMO.SphereBoxCollisionDetector.prototype.detectCollision = function (shape1, shape2, manifold) {
  7657. var s;
  7658. var b;
  7659. if (this.flip) {
  7660. s = (shape2);
  7661. b = (shape1);
  7662. } else {
  7663. s = (shape1);
  7664. b = (shape2);
  7665. }
  7666. var D = b.dimentions;
  7667. var ps = s.position;
  7668. var psx = ps.x;
  7669. var psy = ps.y;
  7670. var psz = ps.z;
  7671. var pb = b.position;
  7672. var pbx = pb.x;
  7673. var pby = pb.y;
  7674. var pbz = pb.z;
  7675. var rad = s.radius;
  7676. var hw = b.halfWidth;
  7677. var hh = b.halfHeight;
  7678. var hd = b.halfDepth;
  7679. var dx = psx - pbx;
  7680. var dy = psy - pby;
  7681. var dz = psz - pbz;
  7682. var sx = D[0] * dx + D[1] * dy + D[2] * dz;
  7683. var sy = D[3] * dx + D[4] * dy + D[5] * dz;
  7684. var sz = D[6] * dx + D[7] * dy + D[8] * dz;
  7685. var cx;
  7686. var cy;
  7687. var cz;
  7688. var len;
  7689. var invLen;
  7690. var overlap = 0;
  7691. if (sx > hw) {
  7692. sx = hw;
  7693. } else if (sx < -hw) {
  7694. sx = -hw;
  7695. } else {
  7696. overlap = 1;
  7697. }
  7698. if (sy > hh) {
  7699. sy = hh;
  7700. } else if (sy < -hh) {
  7701. sy = -hh;
  7702. } else {
  7703. overlap |= 2;
  7704. }
  7705. if (sz > hd) {
  7706. sz = hd;
  7707. } else if (sz < -hd) {
  7708. sz = -hd;
  7709. } else {
  7710. overlap |= 4;
  7711. }
  7712. if (overlap == 7) {
  7713. // center of sphere is in the box
  7714. if (sx < 0) {
  7715. dx = hw + sx;
  7716. } else {
  7717. dx = hw - sx;
  7718. }
  7719. if (sy < 0) {
  7720. dy = hh + sy;
  7721. } else {
  7722. dy = hh - sy;
  7723. }
  7724. if (sz < 0) {
  7725. dz = hd + sz;
  7726. } else {
  7727. dz = hd - sz;
  7728. }
  7729. if (dx < dy) {
  7730. if (dx < dz) {
  7731. len = dx - hw;
  7732. if (sx < 0) {
  7733. sx = -hw;
  7734. dx = D[0];
  7735. dy = D[1];
  7736. dz = D[2];
  7737. } else {
  7738. sx = hw;
  7739. dx = -D[0];
  7740. dy = -D[1];
  7741. dz = -D[2];
  7742. }
  7743. } else {
  7744. len = dz - hd;
  7745. if (sz < 0) {
  7746. sz = -hd;
  7747. dx = D[6];
  7748. dy = D[7];
  7749. dz = D[8];
  7750. } else {
  7751. sz = hd;
  7752. dx = -D[6];
  7753. dy = -D[7];
  7754. dz = -D[8];
  7755. }
  7756. }
  7757. } else {
  7758. if (dy < dz) {
  7759. len = dy - hh;
  7760. if (sy < 0) {
  7761. sy = -hh;
  7762. dx = D[3];
  7763. dy = D[4];
  7764. dz = D[5];
  7765. } else {
  7766. sy = hh;
  7767. dx = -D[3];
  7768. dy = -D[4];
  7769. dz = -D[5];
  7770. }
  7771. } else {
  7772. len = dz - hd;
  7773. if (sz < 0) {
  7774. sz = -hd;
  7775. dx = D[6];
  7776. dy = D[7];
  7777. dz = D[8];
  7778. } else {
  7779. sz = hd;
  7780. dx = -D[6];
  7781. dy = -D[7];
  7782. dz = -D[8];
  7783. }
  7784. }
  7785. }
  7786. cx = pbx + sx * D[0] + sy * D[3] + sz * D[6];
  7787. cy = pby + sx * D[1] + sy * D[4] + sz * D[7];
  7788. cz = pbz + sx * D[2] + sy * D[5] + sz * D[8];
  7789. manifold.addPoint(psx + rad * dx, psy + rad * dy, psz + rad * dz, dx, dy, dz, len - rad, this.flip);
  7790. } else {
  7791. cx = pbx + sx * D[0] + sy * D[3] + sz * D[6];
  7792. cy = pby + sx * D[1] + sy * D[4] + sz * D[7];
  7793. cz = pbz + sx * D[2] + sy * D[5] + sz * D[8];
  7794. dx = cx - ps.x;
  7795. dy = cy - ps.y;
  7796. dz = cz - ps.z;
  7797. len = dx * dx + dy * dy + dz * dz;
  7798. if (len > 0 && len < rad * rad) {
  7799. len = OIMO.sqrt(len);
  7800. invLen = 1 / len;
  7801. dx *= invLen;
  7802. dy *= invLen;
  7803. dz *= invLen;
  7804. manifold.addPoint(psx + rad * dx, psy + rad * dy, psz + rad * dz, dx, dy, dz, len - rad, this.flip);
  7805. }
  7806. }
  7807. };
  7808. /**
  7809. * A collision detector which detects collisions between two spheres.
  7810. * @author saharan
  7811. */
  7812. OIMO.SphereSphereCollisionDetector = function () {
  7813. OIMO.CollisionDetector.call(this);
  7814. };
  7815. OIMO.SphereSphereCollisionDetector.prototype = Object.create(OIMO.CollisionDetector.prototype);
  7816. OIMO.SphereSphereCollisionDetector.prototype.constructor = OIMO.SphereSphereCollisionDetector;
  7817. OIMO.SphereSphereCollisionDetector.prototype.detectCollision = function (shape1, shape2, manifold) {
  7818. var s1 = shape1;
  7819. var s2 = shape2;
  7820. var p1 = s1.position;
  7821. var p2 = s2.position;
  7822. var dx = p2.x - p1.x;
  7823. var dy = p2.y - p1.y;
  7824. var dz = p2.z - p1.z;
  7825. var len = dx * dx + dy * dy + dz * dz;
  7826. var r1 = s1.radius;
  7827. var r2 = s2.radius;
  7828. var rad = r1 + r2;
  7829. if (len > 0 && len < rad * rad) {
  7830. len = OIMO.sqrt(len);
  7831. var invLen = 1 / len;
  7832. dx *= invLen;
  7833. dy *= invLen;
  7834. dz *= invLen;
  7835. manifold.addPoint(p1.x + dx * r1, p1.y + dy * r1, p1.z + dz * r1, dx, dy, dz, len - rad, false);
  7836. }
  7837. };
  7838. OIMO.BoxCylinderCollisionDetector = function (flip) {
  7839. OIMO.CollisionDetector.call(this);
  7840. this.flip = flip;
  7841. };
  7842. OIMO.BoxCylinderCollisionDetector.prototype = Object.create(OIMO.CollisionDetector.prototype);
  7843. OIMO.BoxCylinderCollisionDetector.prototype.constructor = OIMO.BoxCylinderCollisionDetector;
  7844. OIMO.BoxCylinderCollisionDetector.prototype.getSep = function (c1, c2, sep, pos, dep) {
  7845. var t1x;
  7846. var t1y;
  7847. var t1z;
  7848. var t2x;
  7849. var t2y;
  7850. var t2z;
  7851. var sup = new OIMO.Vec3();
  7852. var len;
  7853. var p1x;
  7854. var p1y;
  7855. var p1z;
  7856. var p2x;
  7857. var p2y;
  7858. var p2z;
  7859. var v01x = c1.position.x;
  7860. var v01y = c1.position.y;
  7861. var v01z = c1.position.z;
  7862. var v02x = c2.position.x;
  7863. var v02y = c2.position.y;
  7864. var v02z = c2.position.z;
  7865. var v0x = v02x - v01x;
  7866. var v0y = v02y - v01y;
  7867. var v0z = v02z - v01z;
  7868. if (v0x * v0x + v0y * v0y + v0z * v0z == 0) v0y = 0.001;
  7869. var nx = -v0x;
  7870. var ny = -v0y;
  7871. var nz = -v0z;
  7872. this.supportPointB(c1, -nx, -ny, -nz, sup);
  7873. var v11x = sup.x;
  7874. var v11y = sup.y;
  7875. var v11z = sup.z;
  7876. this.supportPointC(c2, nx, ny, nz, sup);
  7877. var v12x = sup.x;
  7878. var v12y = sup.y;
  7879. var v12z = sup.z;
  7880. var v1x = v12x - v11x;
  7881. var v1y = v12y - v11y;
  7882. var v1z = v12z - v11z;
  7883. if (v1x * nx + v1y * ny + v1z * nz <= 0) {
  7884. return false;
  7885. }
  7886. nx = v1y * v0z - v1z * v0y;
  7887. ny = v1z * v0x - v1x * v0z;
  7888. nz = v1x * v0y - v1y * v0x;
  7889. if (nx * nx + ny * ny + nz * nz == 0) {
  7890. sep.init(v1x - v0x, v1y - v0y, v1z - v0z);
  7891. sep.normalize(sep);
  7892. pos.init((v11x + v12x) * 0.5, (v11y + v12y) * 0.5, (v11z + v12z) * 0.5);
  7893. return true;
  7894. }
  7895. this.supportPointB(c1, -nx, -ny, -nz, sup);
  7896. var v21x = sup.x;
  7897. var v21y = sup.y;
  7898. var v21z = sup.z;
  7899. this.supportPointC(c2, nx, ny, nz, sup);
  7900. var v22x = sup.x;
  7901. var v22y = sup.y;
  7902. var v22z = sup.z;
  7903. var v2x = v22x - v21x;
  7904. var v2y = v22y - v21y;
  7905. var v2z = v22z - v21z;
  7906. if (v2x * nx + v2y * ny + v2z * nz <= 0) {
  7907. return false;
  7908. }
  7909. t1x = v1x - v0x;
  7910. t1y = v1y - v0y;
  7911. t1z = v1z - v0z;
  7912. t2x = v2x - v0x;
  7913. t2y = v2y - v0y;
  7914. t2z = v2z - v0z;
  7915. nx = t1y * t2z - t1z * t2y;
  7916. ny = t1z * t2x - t1x * t2z;
  7917. nz = t1x * t2y - t1y * t2x;
  7918. if (nx * v0x + ny * v0y + nz * v0z > 0) {
  7919. t1x = v1x;
  7920. t1y = v1y;
  7921. t1z = v1z;
  7922. v1x = v2x;
  7923. v1y = v2y;
  7924. v1z = v2z;
  7925. v2x = t1x;
  7926. v2y = t1y;
  7927. v2z = t1z;
  7928. t1x = v11x;
  7929. t1y = v11y;
  7930. t1z = v11z;
  7931. v11x = v21x;
  7932. v11y = v21y;
  7933. v11z = v21z;
  7934. v21x = t1x;
  7935. v21y = t1y;
  7936. v21z = t1z;
  7937. t1x = v12x;
  7938. t1y = v12y;
  7939. t1z = v12z;
  7940. v12x = v22x;
  7941. v12y = v22y;
  7942. v12z = v22z;
  7943. v22x = t1x;
  7944. v22y = t1y;
  7945. v22z = t1z;
  7946. nx = -nx;
  7947. ny = -ny;
  7948. nz = -nz;
  7949. }
  7950. var iterations = 0;
  7951. while (true) {
  7952. if (++iterations > 100) {
  7953. return false;
  7954. }
  7955. this.supportPointB(c1, -nx, -ny, -nz, sup);
  7956. var v31x = sup.x;
  7957. var v31y = sup.y;
  7958. var v31z = sup.z;
  7959. this.supportPointC(c2, nx, ny, nz, sup);
  7960. var v32x = sup.x;
  7961. var v32y = sup.y;
  7962. var v32z = sup.z;
  7963. var v3x = v32x - v31x;
  7964. var v3y = v32y - v31y;
  7965. var v3z = v32z - v31z;
  7966. if (v3x * nx + v3y * ny + v3z * nz <= 0) {
  7967. return false;
  7968. }
  7969. if ((v1y * v3z - v1z * v3y) * v0x + (v1z * v3x - v1x * v3z) * v0y + (v1x * v3y - v1y * v3x) * v0z < 0) {
  7970. v2x = v3x;
  7971. v2y = v3y;
  7972. v2z = v3z;
  7973. v21x = v31x;
  7974. v21y = v31y;
  7975. v21z = v31z;
  7976. v22x = v32x;
  7977. v22y = v32y;
  7978. v22z = v32z;
  7979. t1x = v1x - v0x;
  7980. t1y = v1y - v0y;
  7981. t1z = v1z - v0z;
  7982. t2x = v3x - v0x;
  7983. t2y = v3y - v0y;
  7984. t2z = v3z - v0z;
  7985. nx = t1y * t2z - t1z * t2y;
  7986. ny = t1z * t2x - t1x * t2z;
  7987. nz = t1x * t2y - t1y * t2x;
  7988. continue;
  7989. }
  7990. if ((v3y * v2z - v3z * v2y) * v0x + (v3z * v2x - v3x * v2z) * v0y + (v3x * v2y - v3y * v2x) * v0z < 0) {
  7991. v1x = v3x;
  7992. v1y = v3y;
  7993. v1z = v3z;
  7994. v11x = v31x;
  7995. v11y = v31y;
  7996. v11z = v31z;
  7997. v12x = v32x;
  7998. v12y = v32y;
  7999. v12z = v32z;
  8000. t1x = v3x - v0x;
  8001. t1y = v3y - v0y;
  8002. t1z = v3z - v0z;
  8003. t2x = v2x - v0x;
  8004. t2y = v2y - v0y;
  8005. t2z = v2z - v0z;
  8006. nx = t1y * t2z - t1z * t2y;
  8007. ny = t1z * t2x - t1x * t2z;
  8008. nz = t1x * t2y - t1y * t2x;
  8009. continue;
  8010. }
  8011. var hit = false;
  8012. while (true) {
  8013. t1x = v2x - v1x;
  8014. t1y = v2y - v1y;
  8015. t1z = v2z - v1z;
  8016. t2x = v3x - v1x;
  8017. t2y = v3y - v1y;
  8018. t2z = v3z - v1z;
  8019. nx = t1y * t2z - t1z * t2y;
  8020. ny = t1z * t2x - t1x * t2z;
  8021. nz = t1x * t2y - t1y * t2x;
  8022. len = 1 / OIMO.sqrt(nx * nx + ny * ny + nz * nz);
  8023. nx *= len;
  8024. ny *= len;
  8025. nz *= len;
  8026. if (nx * v1x + ny * v1y + nz * v1z >= 0 && !hit) {
  8027. var b0 = (v1y * v2z - v1z * v2y) * v3x + (v1z * v2x - v1x * v2z) * v3y + (v1x * v2y - v1y * v2x) * v3z;
  8028. var b1 = (v3y * v2z - v3z * v2y) * v0x + (v3z * v2x - v3x * v2z) * v0y + (v3x * v2y - v3y * v2x) * v0z;
  8029. var b2 = (v0y * v1z - v0z * v1y) * v3x + (v0z * v1x - v0x * v1z) * v3y + (v0x * v1y - v0y * v1x) * v3z;
  8030. var b3 = (v2y * v1z - v2z * v1y) * v0x + (v2z * v1x - v2x * v1z) * v0y + (v2x * v1y - v2y * v1x) * v0z;
  8031. var sum = b0 + b1 + b2 + b3;
  8032. if (sum <= 0) {
  8033. b0 = 0;
  8034. b1 = (v2y * v3z - v2z * v3y) * nx + (v2z * v3x - v2x * v3z) * ny + (v2x * v3y - v2y * v3x) * nz;
  8035. b2 = (v3y * v2z - v3z * v2y) * nx + (v3z * v2x - v3x * v2z) * ny + (v3x * v2y - v3y * v2x) * nz;
  8036. b3 = (v1y * v2z - v1z * v2y) * nx + (v1z * v2x - v1x * v2z) * ny + (v1x * v2y - v1y * v2x) * nz;
  8037. sum = b1 + b2 + b3;
  8038. }
  8039. var inv = 1 / sum;
  8040. p1x = (v01x * b0 + v11x * b1 + v21x * b2 + v31x * b3) * inv;
  8041. p1y = (v01y * b0 + v11y * b1 + v21y * b2 + v31y * b3) * inv;
  8042. p1z = (v01z * b0 + v11z * b1 + v21z * b2 + v31z * b3) * inv;
  8043. p2x = (v02x * b0 + v12x * b1 + v22x * b2 + v32x * b3) * inv;
  8044. p2y = (v02y * b0 + v12y * b1 + v22y * b2 + v32y * b3) * inv;
  8045. p2z = (v02z * b0 + v12z * b1 + v22z * b2 + v32z * b3) * inv;
  8046. hit = true;
  8047. }
  8048. this.supportPointB(c1, -nx, -ny, -nz, sup);
  8049. var v41x = sup.x;
  8050. var v41y = sup.y;
  8051. var v41z = sup.z;
  8052. this.supportPointC(c2, nx, ny, nz, sup);
  8053. var v42x = sup.x;
  8054. var v42y = sup.y;
  8055. var v42z = sup.z;
  8056. var v4x = v42x - v41x;
  8057. var v4y = v42y - v41y;
  8058. var v4z = v42z - v41z;
  8059. var separation = -(v4x * nx + v4y * ny + v4z * nz);
  8060. if ((v4x - v3x) * nx + (v4y - v3y) * ny + (v4z - v3z) * nz <= 0.01 || separation >= 0) {
  8061. if (hit) {
  8062. sep.init(-nx, -ny, -nz);
  8063. pos.init((p1x + p2x) * 0.5, (p1y + p2y) * 0.5, (p1z + p2z) * 0.5);
  8064. dep.x = separation;
  8065. return true;
  8066. }
  8067. return false;
  8068. }
  8069. if (
  8070. (v4y * v1z - v4z * v1y) * v0x +
  8071. (v4z * v1x - v4x * v1z) * v0y +
  8072. (v4x * v1y - v4y * v1x) * v0z < 0
  8073. ) {
  8074. if (
  8075. (v4y * v2z - v4z * v2y) * v0x +
  8076. (v4z * v2x - v4x * v2z) * v0y +
  8077. (v4x * v2y - v4y * v2x) * v0z < 0
  8078. ) {
  8079. v1x = v4x;
  8080. v1y = v4y;
  8081. v1z = v4z;
  8082. v11x = v41x;
  8083. v11y = v41y;
  8084. v11z = v41z;
  8085. v12x = v42x;
  8086. v12y = v42y;
  8087. v12z = v42z;
  8088. } else {
  8089. v3x = v4x;
  8090. v3y = v4y;
  8091. v3z = v4z;
  8092. v31x = v41x;
  8093. v31y = v41y;
  8094. v31z = v41z;
  8095. v32x = v42x;
  8096. v32y = v42y;
  8097. v32z = v42z;
  8098. }
  8099. } else {
  8100. if (
  8101. (v4y * v3z - v4z * v3y) * v0x +
  8102. (v4z * v3x - v4x * v3z) * v0y +
  8103. (v4x * v3y - v4y * v3x) * v0z < 0
  8104. ) {
  8105. v2x = v4x;
  8106. v2y = v4y;
  8107. v2z = v4z;
  8108. v21x = v41x;
  8109. v21y = v41y;
  8110. v21z = v41z;
  8111. v22x = v42x;
  8112. v22y = v42y;
  8113. v22z = v42z;
  8114. } else {
  8115. v1x = v4x;
  8116. v1y = v4y;
  8117. v1z = v4z;
  8118. v11x = v41x;
  8119. v11y = v41y;
  8120. v11z = v41z;
  8121. v12x = v42x;
  8122. v12y = v42y;
  8123. v12z = v42z;
  8124. }
  8125. }
  8126. }
  8127. }
  8128. //return false;
  8129. };
  8130. OIMO.BoxCylinderCollisionDetector.prototype.supportPointB = function (c, dx, dy, dz, out) {
  8131. var rot = c.rotation.elements;
  8132. var ldx = rot[0] * dx + rot[3] * dy + rot[6] * dz;
  8133. var ldy = rot[1] * dx + rot[4] * dy + rot[7] * dz;
  8134. var ldz = rot[2] * dx + rot[5] * dy + rot[8] * dz;
  8135. var w = c.halfWidth;
  8136. var h = c.halfHeight;
  8137. var d = c.halfDepth;
  8138. var ox;
  8139. var oy;
  8140. var oz;
  8141. if (ldx < 0) ox = -w;
  8142. else ox = w;
  8143. if (ldy < 0) oy = -h;
  8144. else oy = h;
  8145. if (ldz < 0) oz = -d;
  8146. else oz = d;
  8147. ldx = rot[0] * ox + rot[1] * oy + rot[2] * oz + c.position.x;
  8148. ldy = rot[3] * ox + rot[4] * oy + rot[5] * oz + c.position.y;
  8149. ldz = rot[6] * ox + rot[7] * oy + rot[8] * oz + c.position.z;
  8150. out.init(ldx, ldy, ldz);
  8151. };
  8152. OIMO.BoxCylinderCollisionDetector.prototype.supportPointC = function (c, dx, dy, dz, out) {
  8153. var rot = c.rotation.elements;
  8154. var ldx = rot[0] * dx + rot[3] * dy + rot[6] * dz;
  8155. var ldy = rot[1] * dx + rot[4] * dy + rot[7] * dz;
  8156. var ldz = rot[2] * dx + rot[5] * dy + rot[8] * dz;
  8157. var radx = ldx;
  8158. var radz = ldz;
  8159. var len = radx * radx + radz * radz;
  8160. var rad = c.radius;
  8161. var hh = c.halfHeight;
  8162. var ox;
  8163. var oy;
  8164. var oz;
  8165. if (len == 0) {
  8166. if (ldy < 0) {
  8167. ox = rad;
  8168. oy = -hh;
  8169. oz = 0;
  8170. } else {
  8171. ox = rad;
  8172. oy = hh;
  8173. oz = 0;
  8174. }
  8175. } else {
  8176. len = c.radius / OIMO.sqrt(len);
  8177. if (ldy < 0) {
  8178. ox = radx * len;
  8179. oy = -hh;
  8180. oz = radz * len;
  8181. } else {
  8182. ox = radx * len;
  8183. oy = hh;
  8184. oz = radz * len;
  8185. }
  8186. }
  8187. ldx = rot[0] * ox + rot[1] * oy + rot[2] * oz + c.position.x;
  8188. ldy = rot[3] * ox + rot[4] * oy + rot[5] * oz + c.position.y;
  8189. ldz = rot[6] * ox + rot[7] * oy + rot[8] * oz + c.position.z;
  8190. out.init(ldx, ldy, ldz);
  8191. };
  8192. OIMO.BoxCylinderCollisionDetector.prototype.detectCollision = function (shape1, shape2, manifold) {
  8193. var b;
  8194. var c;
  8195. if (this.flip) {
  8196. b = shape2;
  8197. c = shape1;
  8198. } else {
  8199. b = shape1;
  8200. c = shape2;
  8201. }
  8202. var sep = new OIMO.Vec3();
  8203. var pos = new OIMO.Vec3();
  8204. var dep = new OIMO.Vec3();
  8205. var co;
  8206. if (!this.getSep(b, c, sep, pos, dep)) return;
  8207. var pbx = b.position.x;
  8208. var pby = b.position.y;
  8209. var pbz = b.position.z;
  8210. var pcx = c.position.x;
  8211. var pcy = c.position.y;
  8212. var pcz = c.position.z;
  8213. var bw = b.halfWidth;
  8214. var bh = b.halfHeight;
  8215. var bd = b.halfDepth;
  8216. var ch = c.halfHeight;
  8217. var r = c.radius;
  8218. var D = b.dimentions;
  8219. var nwx = D[0];//b.normalDirectionWidth.x;
  8220. var nwy = D[1];//b.normalDirectionWidth.y;
  8221. var nwz = D[2];//b.normalDirectionWidth.z;
  8222. var nhx = D[3];//b.normalDirectionHeight.x;
  8223. var nhy = D[4];//b.normalDirectionHeight.y;
  8224. var nhz = D[5];//b.normalDirectionHeight.z;
  8225. var ndx = D[6];//b.normalDirectionDepth.x;
  8226. var ndy = D[7];//b.normalDirectionDepth.y;
  8227. var ndz = D[8];//b.normalDirectionDepth.z;
  8228. var dwx = D[9];//b.halfDirectionWidth.x;
  8229. var dwy = D[10];//b.halfDirectionWidth.y;
  8230. var dwz = D[11];//b.halfDirectionWidth.z;
  8231. var dhx = D[12];//b.halfDirectionHeight.x;
  8232. var dhy = D[13];//b.halfDirectionHeight.y;
  8233. var dhz = D[14];//b.halfDirectionHeight.z;
  8234. var ddx = D[15];//b.halfDirectionDepth.x;
  8235. var ddy = D[16];//b.halfDirectionDepth.y;
  8236. var ddz = D[17];//b.halfDirectionDepth.z;
  8237. var ncx = c.normalDirection.x;
  8238. var ncy = c.normalDirection.y;
  8239. var ncz = c.normalDirection.z;
  8240. var dcx = c.halfDirection.x;
  8241. var dcy = c.halfDirection.y;
  8242. var dcz = c.halfDirection.z;
  8243. var nx = sep.x;
  8244. var ny = sep.y;
  8245. var nz = sep.z;
  8246. var dotw = nx * nwx + ny * nwy + nz * nwz;
  8247. var doth = nx * nhx + ny * nhy + nz * nhz;
  8248. var dotd = nx * ndx + ny * ndy + nz * ndz;
  8249. var dotc = nx * ncx + ny * ncy + nz * ncz;
  8250. var right1 = dotw > 0;
  8251. var right2 = doth > 0;
  8252. var right3 = dotd > 0;
  8253. var right4 = dotc > 0;
  8254. if (!right1) dotw = -dotw;
  8255. if (!right2) doth = -doth;
  8256. if (!right3) dotd = -dotd;
  8257. if (!right4) dotc = -dotc;
  8258. var state = 0;
  8259. if (dotc > 0.999) {
  8260. if (dotw > 0.999) {
  8261. if (dotw > dotc) state = 1;
  8262. else state = 4;
  8263. } else if (doth > 0.999) {
  8264. if (doth > dotc) state = 2;
  8265. else state = 4;
  8266. } else if (dotd > 0.999) {
  8267. if (dotd > dotc) state = 3;
  8268. else state = 4;
  8269. } else state = 4;
  8270. } else {
  8271. if (dotw > 0.999) state = 1;
  8272. else if (doth > 0.999) state = 2;
  8273. else if (dotd > 0.999) state = 3;
  8274. }
  8275. var cbx;
  8276. var cby;
  8277. var cbz;
  8278. var ccx;
  8279. var ccy;
  8280. var ccz;
  8281. var r00;
  8282. var r01;
  8283. var r02;
  8284. var r10;
  8285. var r11;
  8286. var r12;
  8287. var r20;
  8288. var r21;
  8289. var r22;
  8290. var px;
  8291. var py;
  8292. var pz;
  8293. var pd;
  8294. var dot;
  8295. var len;
  8296. var tx;
  8297. var ty;
  8298. var tz;
  8299. var td;
  8300. var dx;
  8301. var dy;
  8302. var dz;
  8303. var d1x;
  8304. var d1y;
  8305. var d1z;
  8306. var d2x;
  8307. var d2y;
  8308. var d2z;
  8309. var sx;
  8310. var sy;
  8311. var sz;
  8312. var sd;
  8313. var ex;
  8314. var ey;
  8315. var ez;
  8316. var ed;
  8317. var dot1;
  8318. var dot2;
  8319. var t1;
  8320. var t2;
  8321. var dir1x;
  8322. var dir1y;
  8323. var dir1z;
  8324. var dir2x;
  8325. var dir2y;
  8326. var dir2z;
  8327. var dir1l;
  8328. var dir2l;
  8329. if (state == 0) {
  8330. //manifold.addPoint(pos.x,pos.y,pos.z,nx,ny,nz,dep.x,b,c,0,0,false);
  8331. manifold.addPoint(pos.x, pos.y, pos.z, nx, ny, nz, dep.x, this.flip);
  8332. } else if (state == 4) {
  8333. if (right4) {
  8334. ccx = pcx - dcx;
  8335. ccy = pcy - dcy;
  8336. ccz = pcz - dcz;
  8337. nx = -ncx;
  8338. ny = -ncy;
  8339. nz = -ncz;
  8340. } else {
  8341. ccx = pcx + dcx;
  8342. ccy = pcy + dcy;
  8343. ccz = pcz + dcz;
  8344. nx = ncx;
  8345. ny = ncy;
  8346. nz = ncz;
  8347. }
  8348. var v1x;
  8349. var v1y;
  8350. var v1z;
  8351. var v2x;
  8352. var v2y;
  8353. var v2z;
  8354. var v3x;
  8355. var v3y;
  8356. var v3z;
  8357. var v4x;
  8358. var v4y;
  8359. var v4z;
  8360. dot = 1;
  8361. state = 0;
  8362. dot1 = nwx * nx + nwy * ny + nwz * nz;
  8363. if (dot1 < dot) {
  8364. dot = dot1;
  8365. state = 0;
  8366. }
  8367. if (-dot1 < dot) {
  8368. dot = -dot1;
  8369. state = 1;
  8370. }
  8371. dot1 = nhx * nx + nhy * ny + nhz * nz;
  8372. if (dot1 < dot) {
  8373. dot = dot1;
  8374. state = 2;
  8375. }
  8376. if (-dot1 < dot) {
  8377. dot = -dot1;
  8378. state = 3;
  8379. }
  8380. dot1 = ndx * nx + ndy * ny + ndz * nz;
  8381. if (dot1 < dot) {
  8382. dot = dot1;
  8383. state = 4;
  8384. }
  8385. if (-dot1 < dot) {
  8386. dot = -dot1;
  8387. state = 5;
  8388. }
  8389. var v = b.elements;
  8390. switch (state) {
  8391. case 0:
  8392. //v=b.vertex1;
  8393. v1x = v[0];//v.x;
  8394. v1y = v[1];//v.y;
  8395. v1z = v[2];//v.z;
  8396. //v=b.vertex3;
  8397. v2x = v[6];//v.x;
  8398. v2y = v[7];//v.y;
  8399. v2z = v[8];//v.z;
  8400. //v=b.vertex4;
  8401. v3x = v[9];//v.x;
  8402. v3y = v[10];//v.y;
  8403. v3z = v[11];//v.z;
  8404. //v=b.vertex2;
  8405. v4x = v[3];//v.x;
  8406. v4y = v[4];//v.y;
  8407. v4z = v[5];//v.z;
  8408. break;
  8409. case 1:
  8410. //v=b.vertex6;
  8411. v1x = v[15];//v.x;
  8412. v1y = v[16];//v.y;
  8413. v1z = v[17];//v.z;
  8414. //v=b.vertex8;
  8415. v2x = v[21];//v.x;
  8416. v2y = v[22];//v.y;
  8417. v2z = v[23];//v.z;
  8418. //v=b.vertex7;
  8419. v3x = v[18];//v.x;
  8420. v3y = v[19];//v.y;
  8421. v3z = v[20];//v.z;
  8422. //v=b.vertex5;
  8423. v4x = v[12];//v.x;
  8424. v4y = v[13];//v.y;
  8425. v4z = v[14];//v.z;
  8426. break;
  8427. case 2:
  8428. //v=b.vertex5;
  8429. v1x = v[12];//v.x;
  8430. v1y = v[13];//v.y;
  8431. v1z = v[14];//v.z;
  8432. //v=b.vertex1;
  8433. v2x = v[0];//v.x;
  8434. v2y = v[1];//v.y;
  8435. v2z = v[2];//v.z;
  8436. //v=b.vertex2;
  8437. v3x = v[3];//v.x;
  8438. v3y = v[4];//v.y;
  8439. v3z = v[5];//v.z;
  8440. //v=b.vertex6;
  8441. v4x = v[15];//v.x;
  8442. v4y = v[16];//v.y;
  8443. v4z = v[17];//v.z;
  8444. break;
  8445. case 3:
  8446. //v=b.vertex8;
  8447. v1x = v[21];//v.x;
  8448. v1y = v[22];//v.y;
  8449. v1z = v[23];//v.z;
  8450. //v=b.vertex4;
  8451. v2x = v[9];//v.x;
  8452. v2y = v[10];//v.y;
  8453. v2z = v[11];//v.z;
  8454. //v=b.vertex3;
  8455. v3x = v[6];//v.x;
  8456. v3y = v[7];//v.y;
  8457. v3z = v[8];//v.z;
  8458. //v=b.vertex7;
  8459. v4x = v[18];//v.x;
  8460. v4y = v[19];//v.y;
  8461. v4z = v[20];//v.z;
  8462. break;
  8463. case 4:
  8464. //v=b.vertex5;
  8465. v1x = v[12];//v.x;
  8466. v1y = v[13];//v.y;
  8467. v1z = v[14];//v.z;
  8468. //v=b.vertex7;
  8469. v2x = v[18];//v.x;
  8470. v2y = v[19];//v.y;
  8471. v2z = v[20];//v.z;
  8472. //v=b.vertex3;
  8473. v3x = v[6];//v.x;
  8474. v3y = v[7];//v.y;
  8475. v3z = v[8];//v.z;
  8476. //v=b.vertex1;
  8477. v4x = v[0];//v.x;
  8478. v4y = v[1];//v.y;
  8479. v4z = v[2];//v.z;
  8480. break;
  8481. case 5:
  8482. //v=b.vertex2;
  8483. v1x = v[3];//v.x;
  8484. v1y = v[4];//v.y;
  8485. v1z = v[5];//v.z;
  8486. //v=b.vertex4;
  8487. v2x = v[9];//v.x;
  8488. v2y = v[10];//v.y;
  8489. v2z = v[11];//v.z;
  8490. //v=b.vertex8;
  8491. v3x = v[21];//v.x;
  8492. v3y = v[22];//v.y;
  8493. v3z = v[23];//v.z;
  8494. //v=b.vertex6;
  8495. v4x = v[15];//v.x;
  8496. v4y = v[16];//v.y;
  8497. v4z = v[17];//v.z;
  8498. break;
  8499. }
  8500. pd = nx * (v1x - ccx) + ny * (v1y - ccy) + nz * (v1z - ccz);
  8501. if (pd <= 0) manifold.addPoint(v1x, v1y, v1z, -nx, -ny, -nz, pd, this.flip);
  8502. pd = nx * (v2x - ccx) + ny * (v2y - ccy) + nz * (v2z - ccz);
  8503. if (pd <= 0) manifold.addPoint(v2x, v2y, v2z, -nx, -ny, -nz, pd, this.flip);
  8504. pd = nx * (v3x - ccx) + ny * (v3y - ccy) + nz * (v3z - ccz);
  8505. if (pd <= 0) manifold.addPoint(v3x, v3y, v3z, -nx, -ny, -nz, pd, this.flip);
  8506. pd = nx * (v4x - ccx) + ny * (v4y - ccy) + nz * (v4z - ccz);
  8507. if (pd <= 0) manifold.addPoint(v4x, v4y, v4z, -nx, -ny, -nz, pd, this.flip);
  8508. } else {
  8509. switch (state) {
  8510. case 1:
  8511. if (right1) {
  8512. cbx = pbx + dwx;
  8513. cby = pby + dwy;
  8514. cbz = pbz + dwz;
  8515. nx = nwx;
  8516. ny = nwy;
  8517. nz = nwz;
  8518. } else {
  8519. cbx = pbx - dwx;
  8520. cby = pby - dwy;
  8521. cbz = pbz - dwz;
  8522. nx = -nwx;
  8523. ny = -nwy;
  8524. nz = -nwz;
  8525. }
  8526. dir1x = nhx;
  8527. dir1y = nhy;
  8528. dir1z = nhz;
  8529. dir1l = bh;
  8530. dir2x = ndx;
  8531. dir2y = ndy;
  8532. dir2z = ndz;
  8533. dir2l = bd;
  8534. break;
  8535. case 2:
  8536. if (right2) {
  8537. cbx = pbx + dhx;
  8538. cby = pby + dhy;
  8539. cbz = pbz + dhz;
  8540. nx = nhx;
  8541. ny = nhy;
  8542. nz = nhz;
  8543. } else {
  8544. cbx = pbx - dhx;
  8545. cby = pby - dhy;
  8546. cbz = pbz - dhz;
  8547. nx = -nhx;
  8548. ny = -nhy;
  8549. nz = -nhz;
  8550. }
  8551. dir1x = nwx;
  8552. dir1y = nwy;
  8553. dir1z = nwz;
  8554. dir1l = bw;
  8555. dir2x = ndx;
  8556. dir2y = ndy;
  8557. dir2z = ndz;
  8558. dir2l = bd;
  8559. break;
  8560. case 3:
  8561. if (right3) {
  8562. cbx = pbx + ddx;
  8563. cby = pby + ddy;
  8564. cbz = pbz + ddz;
  8565. nx = ndx;
  8566. ny = ndy;
  8567. nz = ndz;
  8568. } else {
  8569. cbx = pbx - ddx;
  8570. cby = pby - ddy;
  8571. cbz = pbz - ddz;
  8572. nx = -ndx;
  8573. ny = -ndy;
  8574. nz = -ndz;
  8575. }
  8576. dir1x = nwx;
  8577. dir1y = nwy;
  8578. dir1z = nwz;
  8579. dir1l = bw;
  8580. dir2x = nhx;
  8581. dir2y = nhy;
  8582. dir2z = nhz;
  8583. dir2l = bh;
  8584. break;
  8585. }
  8586. dot = nx * ncx + ny * ncy + nz * ncz;
  8587. if (dot < 0) len = ch;
  8588. else len = -ch;
  8589. ccx = pcx + len * ncx;
  8590. ccy = pcy + len * ncy;
  8591. ccz = pcz + len * ncz;
  8592. if (dotc >= 0.999999) {
  8593. tx = -ny;
  8594. ty = nz;
  8595. tz = nx;
  8596. } else {
  8597. tx = nx;
  8598. ty = ny;
  8599. tz = nz;
  8600. }
  8601. len = tx * ncx + ty * ncy + tz * ncz;
  8602. dx = len * ncx - tx;
  8603. dy = len * ncy - ty;
  8604. dz = len * ncz - tz;
  8605. len = OIMO.sqrt(dx * dx + dy * dy + dz * dz);
  8606. if (len == 0) return;
  8607. len = r / len;
  8608. dx *= len;
  8609. dy *= len;
  8610. dz *= len;
  8611. tx = ccx + dx;
  8612. ty = ccy + dy;
  8613. tz = ccz + dz;
  8614. if (dot < -0.96 || dot > 0.96) {
  8615. r00 = ncx * ncx * 1.5 - 0.5;
  8616. r01 = ncx * ncy * 1.5 - ncz * 0.866025403;
  8617. r02 = ncx * ncz * 1.5 + ncy * 0.866025403;
  8618. r10 = ncy * ncx * 1.5 + ncz * 0.866025403;
  8619. r11 = ncy * ncy * 1.5 - 0.5;
  8620. r12 = ncy * ncz * 1.5 - ncx * 0.866025403;
  8621. r20 = ncz * ncx * 1.5 - ncy * 0.866025403;
  8622. r21 = ncz * ncy * 1.5 + ncx * 0.866025403;
  8623. r22 = ncz * ncz * 1.5 - 0.5;
  8624. px = tx;
  8625. py = ty;
  8626. pz = tz;
  8627. pd = nx * (px - cbx) + ny * (py - cby) + nz * (pz - cbz);
  8628. tx = px - pd * nx - cbx;
  8629. ty = py - pd * ny - cby;
  8630. tz = pz - pd * nz - cbz;
  8631. sd = dir1x * tx + dir1y * ty + dir1z * tz;
  8632. ed = dir2x * tx + dir2y * ty + dir2z * tz;
  8633. if (sd < -dir1l) sd = -dir1l;
  8634. else if (sd > dir1l) sd = dir1l;
  8635. if (ed < -dir2l) ed = -dir2l;
  8636. else if (ed > dir2l) ed = dir2l;
  8637. tx = sd * dir1x + ed * dir2x;
  8638. ty = sd * dir1y + ed * dir2y;
  8639. tz = sd * dir1z + ed * dir2z;
  8640. px = cbx + tx;
  8641. py = cby + ty;
  8642. pz = cbz + tz;
  8643. manifold.addPoint(px, py, pz, nx, ny, nz, pd, this.flip);
  8644. px = dx * r00 + dy * r01 + dz * r02;
  8645. py = dx * r10 + dy * r11 + dz * r12;
  8646. pz = dx * r20 + dy * r21 + dz * r22;
  8647. px = (dx = px) + ccx;
  8648. py = (dy = py) + ccy;
  8649. pz = (dz = pz) + ccz;
  8650. pd = nx * (px - cbx) + ny * (py - cby) + nz * (pz - cbz);
  8651. if (pd <= 0) {
  8652. tx = px - pd * nx - cbx;
  8653. ty = py - pd * ny - cby;
  8654. tz = pz - pd * nz - cbz;
  8655. sd = dir1x * tx + dir1y * ty + dir1z * tz;
  8656. ed = dir2x * tx + dir2y * ty + dir2z * tz;
  8657. if (sd < -dir1l) sd = -dir1l;
  8658. else if (sd > dir1l) sd = dir1l;
  8659. if (ed < -dir2l) ed = -dir2l;
  8660. else if (ed > dir2l) ed = dir2l;
  8661. tx = sd * dir1x + ed * dir2x;
  8662. ty = sd * dir1y + ed * dir2y;
  8663. tz = sd * dir1z + ed * dir2z;
  8664. px = cbx + tx;
  8665. py = cby + ty;
  8666. pz = cbz + tz;
  8667. //manifold.addPoint(px,py,pz,nx,ny,nz,pd,b,c,2,0,false);
  8668. manifold.addPoint(px, py, pz, nx, ny, nz, pd, this.flip);
  8669. }
  8670. px = dx * r00 + dy * r01 + dz * r02;
  8671. py = dx * r10 + dy * r11 + dz * r12;
  8672. pz = dx * r20 + dy * r21 + dz * r22;
  8673. px = (dx = px) + ccx;
  8674. py = (dy = py) + ccy;
  8675. pz = (dz = pz) + ccz;
  8676. pd = nx * (px - cbx) + ny * (py - cby) + nz * (pz - cbz);
  8677. if (pd <= 0) {
  8678. tx = px - pd * nx - cbx;
  8679. ty = py - pd * ny - cby;
  8680. tz = pz - pd * nz - cbz;
  8681. sd = dir1x * tx + dir1y * ty + dir1z * tz;
  8682. ed = dir2x * tx + dir2y * ty + dir2z * tz;
  8683. if (sd < -dir1l) sd = -dir1l;
  8684. else if (sd > dir1l) sd = dir1l;
  8685. if (ed < -dir2l) ed = -dir2l;
  8686. else if (ed > dir2l) ed = dir2l;
  8687. tx = sd * dir1x + ed * dir2x;
  8688. ty = sd * dir1y + ed * dir2y;
  8689. tz = sd * dir1z + ed * dir2z;
  8690. px = cbx + tx;
  8691. py = cby + ty;
  8692. pz = cbz + tz;
  8693. //manifold.addPoint(px,py,pz,nx,ny,nz,pd,b,c,3,0,false);
  8694. manifold.addPoint(px, py, pz, nx, ny, nz, pd, this.flip);
  8695. }
  8696. } else {
  8697. sx = tx;
  8698. sy = ty;
  8699. sz = tz;
  8700. sd = nx * (sx - cbx) + ny * (sy - cby) + nz * (sz - cbz);
  8701. sx -= sd * nx;
  8702. sy -= sd * ny;
  8703. sz -= sd * nz;
  8704. if (dot > 0) {
  8705. ex = tx + dcx * 2;
  8706. ey = ty + dcy * 2;
  8707. ez = tz + dcz * 2;
  8708. } else {
  8709. ex = tx - dcx * 2;
  8710. ey = ty - dcy * 2;
  8711. ez = tz - dcz * 2;
  8712. }
  8713. ed = nx * (ex - cbx) + ny * (ey - cby) + nz * (ez - cbz);
  8714. ex -= ed * nx;
  8715. ey -= ed * ny;
  8716. ez -= ed * nz;
  8717. d1x = sx - cbx;
  8718. d1y = sy - cby;
  8719. d1z = sz - cbz;
  8720. d2x = ex - cbx;
  8721. d2y = ey - cby;
  8722. d2z = ez - cbz;
  8723. tx = ex - sx;
  8724. ty = ey - sy;
  8725. tz = ez - sz;
  8726. td = ed - sd;
  8727. dotw = d1x * dir1x + d1y * dir1y + d1z * dir1z;
  8728. doth = d2x * dir1x + d2y * dir1y + d2z * dir1z;
  8729. dot1 = dotw - dir1l;
  8730. dot2 = doth - dir1l;
  8731. if (dot1 > 0) {
  8732. if (dot2 > 0) return;
  8733. t1 = dot1 / (dot1 - dot2);
  8734. sx = sx + tx * t1;
  8735. sy = sy + ty * t1;
  8736. sz = sz + tz * t1;
  8737. sd = sd + td * t1;
  8738. d1x = sx - cbx;
  8739. d1y = sy - cby;
  8740. d1z = sz - cbz;
  8741. dotw = d1x * dir1x + d1y * dir1y + d1z * dir1z;
  8742. tx = ex - sx;
  8743. ty = ey - sy;
  8744. tz = ez - sz;
  8745. td = ed - sd;
  8746. } else if (dot2 > 0) {
  8747. t1 = dot1 / (dot1 - dot2);
  8748. ex = sx + tx * t1;
  8749. ey = sy + ty * t1;
  8750. ez = sz + tz * t1;
  8751. ed = sd + td * t1;
  8752. d2x = ex - cbx;
  8753. d2y = ey - cby;
  8754. d2z = ez - cbz;
  8755. doth = d2x * dir1x + d2y * dir1y + d2z * dir1z;
  8756. tx = ex - sx;
  8757. ty = ey - sy;
  8758. tz = ez - sz;
  8759. td = ed - sd;
  8760. }
  8761. dot1 = dotw + dir1l;
  8762. dot2 = doth + dir1l;
  8763. if (dot1 < 0) {
  8764. if (dot2 < 0) return;
  8765. t1 = dot1 / (dot1 - dot2);
  8766. sx = sx + tx * t1;
  8767. sy = sy + ty * t1;
  8768. sz = sz + tz * t1;
  8769. sd = sd + td * t1;
  8770. d1x = sx - cbx;
  8771. d1y = sy - cby;
  8772. d1z = sz - cbz;
  8773. tx = ex - sx;
  8774. ty = ey - sy;
  8775. tz = ez - sz;
  8776. td = ed - sd;
  8777. } else if (dot2 < 0) {
  8778. t1 = dot1 / (dot1 - dot2);
  8779. ex = sx + tx * t1;
  8780. ey = sy + ty * t1;
  8781. ez = sz + tz * t1;
  8782. ed = sd + td * t1;
  8783. d2x = ex - cbx;
  8784. d2y = ey - cby;
  8785. d2z = ez - cbz;
  8786. tx = ex - sx;
  8787. ty = ey - sy;
  8788. tz = ez - sz;
  8789. td = ed - sd;
  8790. }
  8791. dotw = d1x * dir2x + d1y * dir2y + d1z * dir2z;
  8792. doth = d2x * dir2x + d2y * dir2y + d2z * dir2z;
  8793. dot1 = dotw - dir2l;
  8794. dot2 = doth - dir2l;
  8795. if (dot1 > 0) {
  8796. if (dot2 > 0) return;
  8797. t1 = dot1 / (dot1 - dot2);
  8798. sx = sx + tx * t1;
  8799. sy = sy + ty * t1;
  8800. sz = sz + tz * t1;
  8801. sd = sd + td * t1;
  8802. d1x = sx - cbx;
  8803. d1y = sy - cby;
  8804. d1z = sz - cbz;
  8805. dotw = d1x * dir2x + d1y * dir2y + d1z * dir2z;
  8806. tx = ex - sx;
  8807. ty = ey - sy;
  8808. tz = ez - sz;
  8809. td = ed - sd;
  8810. } else if (dot2 > 0) {
  8811. t1 = dot1 / (dot1 - dot2);
  8812. ex = sx + tx * t1;
  8813. ey = sy + ty * t1;
  8814. ez = sz + tz * t1;
  8815. ed = sd + td * t1;
  8816. d2x = ex - cbx;
  8817. d2y = ey - cby;
  8818. d2z = ez - cbz;
  8819. doth = d2x * dir2x + d2y * dir2y + d2z * dir2z;
  8820. tx = ex - sx;
  8821. ty = ey - sy;
  8822. tz = ez - sz;
  8823. td = ed - sd;
  8824. }
  8825. dot1 = dotw + dir2l;
  8826. dot2 = doth + dir2l;
  8827. if (dot1 < 0) {
  8828. if (dot2 < 0) return;
  8829. t1 = dot1 / (dot1 - dot2);
  8830. sx = sx + tx * t1;
  8831. sy = sy + ty * t1;
  8832. sz = sz + tz * t1;
  8833. sd = sd + td * t1;
  8834. } else if (dot2 < 0) {
  8835. t1 = dot1 / (dot1 - dot2);
  8836. ex = sx + tx * t1;
  8837. ey = sy + ty * t1;
  8838. ez = sz + tz * t1;
  8839. ed = sd + td * t1;
  8840. }
  8841. if (sd < 0) {
  8842. //manifold.addPoint(sx,sy,sz,nx,ny,nz,sd,b,c,1,0,false);
  8843. manifold.addPoint(sx, sy, sz, nx, ny, nz, sd, this.flip);
  8844. }
  8845. if (ed < 0) {
  8846. //manifold.addPoint(ex,ey,ez,nx,ny,nz,ed,b,c,4,0,false);
  8847. manifold.addPoint(ex, ey, ez, nx, ny, nz, ed, this.flip);
  8848. }
  8849. }
  8850. }
  8851. };
  8852. OIMO.CylinderCylinderCollisionDetector = function () {
  8853. OIMO.CollisionDetector.call(this);
  8854. };
  8855. OIMO.CylinderCylinderCollisionDetector.prototype = Object.create(OIMO.CollisionDetector.prototype);
  8856. OIMO.CylinderCylinderCollisionDetector.prototype.constructor = OIMO.CylinderCylinderCollisionDetector;
  8857. OIMO.CylinderCylinderCollisionDetector.prototype.getSep = function (c1, c2, sep, pos, dep) {
  8858. var t1x;
  8859. var t1y;
  8860. var t1z;
  8861. var t2x;
  8862. var t2y;
  8863. var t2z;
  8864. var sup = new OIMO.Vec3();
  8865. var len;
  8866. var p1x;
  8867. var p1y;
  8868. var p1z;
  8869. var p2x;
  8870. var p2y;
  8871. var p2z;
  8872. var v01x = c1.position.x;
  8873. var v01y = c1.position.y;
  8874. var v01z = c1.position.z;
  8875. var v02x = c2.position.x;
  8876. var v02y = c2.position.y;
  8877. var v02z = c2.position.z;
  8878. var v0x = v02x - v01x;
  8879. var v0y = v02y - v01y;
  8880. var v0z = v02z - v01z;
  8881. if (v0x * v0x + v0y * v0y + v0z * v0z == 0) v0y = 0.001;
  8882. var nx = -v0x;
  8883. var ny = -v0y;
  8884. var nz = -v0z;
  8885. this.supportPoint(c1, -nx, -ny, -nz, sup);
  8886. var v11x = sup.x;
  8887. var v11y = sup.y;
  8888. var v11z = sup.z;
  8889. this.supportPoint(c2, nx, ny, nz, sup);
  8890. var v12x = sup.x;
  8891. var v12y = sup.y;
  8892. var v12z = sup.z;
  8893. var v1x = v12x - v11x;
  8894. var v1y = v12y - v11y;
  8895. var v1z = v12z - v11z;
  8896. if (v1x * nx + v1y * ny + v1z * nz <= 0) {
  8897. return false;
  8898. }
  8899. nx = v1y * v0z - v1z * v0y;
  8900. ny = v1z * v0x - v1x * v0z;
  8901. nz = v1x * v0y - v1y * v0x;
  8902. if (nx * nx + ny * ny + nz * nz == 0) {
  8903. sep.init(v1x - v0x, v1y - v0y, v1z - v0z);
  8904. sep.normalize(sep);
  8905. pos.init((v11x + v12x) * 0.5, (v11y + v12y) * 0.5, (v11z + v12z) * 0.5);
  8906. return true;
  8907. }
  8908. this.supportPoint(c1, -nx, -ny, -nz, sup);
  8909. var v21x = sup.x;
  8910. var v21y = sup.y;
  8911. var v21z = sup.z;
  8912. this.supportPoint(c2, nx, ny, nz, sup);
  8913. var v22x = sup.x;
  8914. var v22y = sup.y;
  8915. var v22z = sup.z;
  8916. var v2x = v22x - v21x;
  8917. var v2y = v22y - v21y;
  8918. var v2z = v22z - v21z;
  8919. if (v2x * nx + v2y * ny + v2z * nz <= 0) {
  8920. return false;
  8921. }
  8922. t1x = v1x - v0x;
  8923. t1y = v1y - v0y;
  8924. t1z = v1z - v0z;
  8925. t2x = v2x - v0x;
  8926. t2y = v2y - v0y;
  8927. t2z = v2z - v0z;
  8928. nx = t1y * t2z - t1z * t2y;
  8929. ny = t1z * t2x - t1x * t2z;
  8930. nz = t1x * t2y - t1y * t2x;
  8931. if (nx * v0x + ny * v0y + nz * v0z > 0) {
  8932. t1x = v1x;
  8933. t1y = v1y;
  8934. t1z = v1z;
  8935. v1x = v2x;
  8936. v1y = v2y;
  8937. v1z = v2z;
  8938. v2x = t1x;
  8939. v2y = t1y;
  8940. v2z = t1z;
  8941. t1x = v11x;
  8942. t1y = v11y;
  8943. t1z = v11z;
  8944. v11x = v21x;
  8945. v11y = v21y;
  8946. v11z = v21z;
  8947. v21x = t1x;
  8948. v21y = t1y;
  8949. v21z = t1z;
  8950. t1x = v12x;
  8951. t1y = v12y;
  8952. t1z = v12z;
  8953. v12x = v22x;
  8954. v12y = v22y;
  8955. v12z = v22z;
  8956. v22x = t1x;
  8957. v22y = t1y;
  8958. v22z = t1z;
  8959. nx = -nx;
  8960. ny = -ny;
  8961. nz = -nz;
  8962. }
  8963. var iterations = 0;
  8964. while (true) {
  8965. if (++iterations > 100) {
  8966. return false;
  8967. }
  8968. this.supportPoint(c1, -nx, -ny, -nz, sup);
  8969. var v31x = sup.x;
  8970. var v31y = sup.y;
  8971. var v31z = sup.z;
  8972. this.supportPoint(c2, nx, ny, nz, sup);
  8973. var v32x = sup.x;
  8974. var v32y = sup.y;
  8975. var v32z = sup.z;
  8976. var v3x = v32x - v31x;
  8977. var v3y = v32y - v31y;
  8978. var v3z = v32z - v31z;
  8979. if (v3x * nx + v3y * ny + v3z * nz <= 0) {
  8980. return false;
  8981. }
  8982. if ((v1y * v3z - v1z * v3y) * v0x + (v1z * v3x - v1x * v3z) * v0y + (v1x * v3y - v1y * v3x) * v0z < 0) {
  8983. v2x = v3x;
  8984. v2y = v3y;
  8985. v2z = v3z;
  8986. v21x = v31x;
  8987. v21y = v31y;
  8988. v21z = v31z;
  8989. v22x = v32x;
  8990. v22y = v32y;
  8991. v22z = v32z;
  8992. t1x = v1x - v0x;
  8993. t1y = v1y - v0y;
  8994. t1z = v1z - v0z;
  8995. t2x = v3x - v0x;
  8996. t2y = v3y - v0y;
  8997. t2z = v3z - v0z;
  8998. nx = t1y * t2z - t1z * t2y;
  8999. ny = t1z * t2x - t1x * t2z;
  9000. nz = t1x * t2y - t1y * t2x;
  9001. continue;
  9002. }
  9003. if ((v3y * v2z - v3z * v2y) * v0x + (v3z * v2x - v3x * v2z) * v0y + (v3x * v2y - v3y * v2x) * v0z < 0) {
  9004. v1x = v3x;
  9005. v1y = v3y;
  9006. v1z = v3z;
  9007. v11x = v31x;
  9008. v11y = v31y;
  9009. v11z = v31z;
  9010. v12x = v32x;
  9011. v12y = v32y;
  9012. v12z = v32z;
  9013. t1x = v3x - v0x;
  9014. t1y = v3y - v0y;
  9015. t1z = v3z - v0z;
  9016. t2x = v2x - v0x;
  9017. t2y = v2y - v0y;
  9018. t2z = v2z - v0z;
  9019. nx = t1y * t2z - t1z * t2y;
  9020. ny = t1z * t2x - t1x * t2z;
  9021. nz = t1x * t2y - t1y * t2x;
  9022. continue;
  9023. }
  9024. var hit = false;
  9025. while (true) {
  9026. t1x = v2x - v1x;
  9027. t1y = v2y - v1y;
  9028. t1z = v2z - v1z;
  9029. t2x = v3x - v1x;
  9030. t2y = v3y - v1y;
  9031. t2z = v3z - v1z;
  9032. nx = t1y * t2z - t1z * t2y;
  9033. ny = t1z * t2x - t1x * t2z;
  9034. nz = t1x * t2y - t1y * t2x;
  9035. len = 1 / OIMO.sqrt(nx * nx + ny * ny + nz * nz);
  9036. nx *= len;
  9037. ny *= len;
  9038. nz *= len;
  9039. if (nx * v1x + ny * v1y + nz * v1z >= 0 && !hit) {
  9040. var b0 = (v1y * v2z - v1z * v2y) * v3x + (v1z * v2x - v1x * v2z) * v3y + (v1x * v2y - v1y * v2x) * v3z;
  9041. var b1 = (v3y * v2z - v3z * v2y) * v0x + (v3z * v2x - v3x * v2z) * v0y + (v3x * v2y - v3y * v2x) * v0z;
  9042. var b2 = (v0y * v1z - v0z * v1y) * v3x + (v0z * v1x - v0x * v1z) * v3y + (v0x * v1y - v0y * v1x) * v3z;
  9043. var b3 = (v2y * v1z - v2z * v1y) * v0x + (v2z * v1x - v2x * v1z) * v0y + (v2x * v1y - v2y * v1x) * v0z;
  9044. var sum = b0 + b1 + b2 + b3;
  9045. if (sum <= 0) {
  9046. b0 = 0;
  9047. b1 = (v2y * v3z - v2z * v3y) * nx + (v2z * v3x - v2x * v3z) * ny + (v2x * v3y - v2y * v3x) * nz;
  9048. b2 = (v3y * v2z - v3z * v2y) * nx + (v3z * v2x - v3x * v2z) * ny + (v3x * v2y - v3y * v2x) * nz;
  9049. b3 = (v1y * v2z - v1z * v2y) * nx + (v1z * v2x - v1x * v2z) * ny + (v1x * v2y - v1y * v2x) * nz;
  9050. sum = b1 + b2 + b3;
  9051. }
  9052. var inv = 1 / sum;
  9053. p1x = (v01x * b0 + v11x * b1 + v21x * b2 + v31x * b3) * inv;
  9054. p1y = (v01y * b0 + v11y * b1 + v21y * b2 + v31y * b3) * inv;
  9055. p1z = (v01z * b0 + v11z * b1 + v21z * b2 + v31z * b3) * inv;
  9056. p2x = (v02x * b0 + v12x * b1 + v22x * b2 + v32x * b3) * inv;
  9057. p2y = (v02y * b0 + v12y * b1 + v22y * b2 + v32y * b3) * inv;
  9058. p2z = (v02z * b0 + v12z * b1 + v22z * b2 + v32z * b3) * inv;
  9059. hit = true;
  9060. }
  9061. this.supportPoint(c1, -nx, -ny, -nz, sup);
  9062. var v41x = sup.x;
  9063. var v41y = sup.y;
  9064. var v41z = sup.z;
  9065. this.supportPoint(c2, nx, ny, nz, sup);
  9066. var v42x = sup.x;
  9067. var v42y = sup.y;
  9068. var v42z = sup.z;
  9069. var v4x = v42x - v41x;
  9070. var v4y = v42y - v41y;
  9071. var v4z = v42z - v41z;
  9072. var separation = -(v4x * nx + v4y * ny + v4z * nz);
  9073. if ((v4x - v3x) * nx + (v4y - v3y) * ny + (v4z - v3z) * nz <= 0.01 || separation >= 0) {
  9074. if (hit) {
  9075. sep.init(-nx, -ny, -nz);
  9076. pos.init((p1x + p2x) * 0.5, (p1y + p2y) * 0.5, (p1z + p2z) * 0.5);
  9077. dep.x = separation;
  9078. return true;
  9079. }
  9080. return false;
  9081. }
  9082. if (
  9083. (v4y * v1z - v4z * v1y) * v0x +
  9084. (v4z * v1x - v4x * v1z) * v0y +
  9085. (v4x * v1y - v4y * v1x) * v0z < 0
  9086. ) {
  9087. if (
  9088. (v4y * v2z - v4z * v2y) * v0x +
  9089. (v4z * v2x - v4x * v2z) * v0y +
  9090. (v4x * v2y - v4y * v2x) * v0z < 0
  9091. ) {
  9092. v1x = v4x;
  9093. v1y = v4y;
  9094. v1z = v4z;
  9095. v11x = v41x;
  9096. v11y = v41y;
  9097. v11z = v41z;
  9098. v12x = v42x;
  9099. v12y = v42y;
  9100. v12z = v42z;
  9101. } else {
  9102. v3x = v4x;
  9103. v3y = v4y;
  9104. v3z = v4z;
  9105. v31x = v41x;
  9106. v31y = v41y;
  9107. v31z = v41z;
  9108. v32x = v42x;
  9109. v32y = v42y;
  9110. v32z = v42z;
  9111. }
  9112. } else {
  9113. if (
  9114. (v4y * v3z - v4z * v3y) * v0x +
  9115. (v4z * v3x - v4x * v3z) * v0y +
  9116. (v4x * v3y - v4y * v3x) * v0z < 0
  9117. ) {
  9118. v2x = v4x;
  9119. v2y = v4y;
  9120. v2z = v4z;
  9121. v21x = v41x;
  9122. v21y = v41y;
  9123. v21z = v41z;
  9124. v22x = v42x;
  9125. v22y = v42y;
  9126. v22z = v42z;
  9127. } else {
  9128. v1x = v4x;
  9129. v1y = v4y;
  9130. v1z = v4z;
  9131. v11x = v41x;
  9132. v11y = v41y;
  9133. v11z = v41z;
  9134. v12x = v42x;
  9135. v12y = v42y;
  9136. v12z = v42z;
  9137. }
  9138. }
  9139. }
  9140. }
  9141. //return false;
  9142. };
  9143. OIMO.CylinderCylinderCollisionDetector.prototype.supportPoint = function (c, dx, dy, dz, out) {
  9144. var rot = c.rotation.elements;
  9145. var ldx = rot[0] * dx + rot[3] * dy + rot[6] * dz;
  9146. var ldy = rot[1] * dx + rot[4] * dy + rot[7] * dz;
  9147. var ldz = rot[2] * dx + rot[5] * dy + rot[8] * dz;
  9148. var radx = ldx;
  9149. var radz = ldz;
  9150. var len = radx * radx + radz * radz;
  9151. var rad = c.radius;
  9152. var hh = c.halfHeight;
  9153. var ox;
  9154. var oy;
  9155. var oz;
  9156. if (len == 0) {
  9157. if (ldy < 0) {
  9158. ox = rad;
  9159. oy = -hh;
  9160. oz = 0;
  9161. } else {
  9162. ox = rad;
  9163. oy = hh;
  9164. oz = 0;
  9165. }
  9166. } else {
  9167. len = c.radius / OIMO.sqrt(len);
  9168. if (ldy < 0) {
  9169. ox = radx * len;
  9170. oy = -hh;
  9171. oz = radz * len;
  9172. } else {
  9173. ox = radx * len;
  9174. oy = hh;
  9175. oz = radz * len;
  9176. }
  9177. }
  9178. ldx = rot[0] * ox + rot[1] * oy + rot[2] * oz + c.position.x;
  9179. ldy = rot[3] * ox + rot[4] * oy + rot[5] * oz + c.position.y;
  9180. ldz = rot[6] * ox + rot[7] * oy + rot[8] * oz + c.position.z;
  9181. out.init(ldx, ldy, ldz);
  9182. };
  9183. OIMO.CylinderCylinderCollisionDetector.prototype.detectCollision = function (shape1, shape2, manifold) {
  9184. var c1;
  9185. var c2;
  9186. if (shape1.id < shape2.id) {
  9187. c1 = shape1;
  9188. c2 = shape2;
  9189. } else {
  9190. c1 = shape2;
  9191. c2 = shape1;
  9192. }
  9193. var p1 = c1.position;
  9194. var p2 = c2.position;
  9195. var p1x = p1.x;
  9196. var p1y = p1.y;
  9197. var p1z = p1.z;
  9198. var p2x = p2.x;
  9199. var p2y = p2.y;
  9200. var p2z = p2.z;
  9201. var h1 = c1.halfHeight;
  9202. var h2 = c2.halfHeight;
  9203. var n1 = c1.normalDirection;
  9204. var n2 = c2.normalDirection;
  9205. var d1 = c1.halfDirection;
  9206. var d2 = c2.halfDirection;
  9207. var r1 = c1.radius;
  9208. var r2 = c2.radius;
  9209. var n1x = n1.x;
  9210. var n1y = n1.y;
  9211. var n1z = n1.z;
  9212. var n2x = n2.x;
  9213. var n2y = n2.y;
  9214. var n2z = n2.z;
  9215. var d1x = d1.x;
  9216. var d1y = d1.y;
  9217. var d1z = d1.z;
  9218. var d2x = d2.x;
  9219. var d2y = d2.y;
  9220. var d2z = d2.z;
  9221. var dx = p1x - p2x;
  9222. var dy = p1y - p2y;
  9223. var dz = p1z - p2z;
  9224. var len;
  9225. var len1;
  9226. var len2;
  9227. var c;
  9228. var c1x;
  9229. var c1y;
  9230. var c1z;
  9231. var c2x;
  9232. var c2y;
  9233. var c2z;
  9234. var tx;
  9235. var ty;
  9236. var tz;
  9237. var sx;
  9238. var sy;
  9239. var sz;
  9240. var ex;
  9241. var ey;
  9242. var ez;
  9243. var depth1;
  9244. var depth2;
  9245. var dot;
  9246. var t1;
  9247. var t2;
  9248. var sep = new OIMO.Vec3();
  9249. var pos = new OIMO.Vec3();
  9250. var dep = new OIMO.Vec3();
  9251. if (!this.getSep(c1, c2, sep, pos, dep)) return;
  9252. var dot1 = sep.x * n1x + sep.y * n1y + sep.z * n1z;
  9253. var dot2 = sep.x * n2x + sep.y * n2y + sep.z * n2z;
  9254. var right1 = dot1 > 0;
  9255. var right2 = dot2 > 0;
  9256. if (!right1) dot1 = -dot1;
  9257. if (!right2) dot2 = -dot2;
  9258. var state = 0;
  9259. if (dot1 > 0.999 || dot2 > 0.999) {
  9260. if (dot1 > dot2) state = 1;
  9261. else state = 2;
  9262. }
  9263. var nx;
  9264. var ny;
  9265. var nz;
  9266. var depth = dep.x;
  9267. var r00;
  9268. var r01;
  9269. var r02;
  9270. var r10;
  9271. var r11;
  9272. var r12;
  9273. var r20;
  9274. var r21;
  9275. var r22;
  9276. var px;
  9277. var py;
  9278. var pz;
  9279. var pd;
  9280. var a;
  9281. var b;
  9282. var e;
  9283. var f;
  9284. nx = sep.x;
  9285. ny = sep.y;
  9286. nz = sep.z;
  9287. switch (state) {
  9288. case 0:
  9289. manifold.addPoint(pos.x, pos.y, pos.z, nx, ny, nz, depth, false);
  9290. break;
  9291. case 1:
  9292. if (right1) {
  9293. c1x = p1x + d1x;
  9294. c1y = p1y + d1y;
  9295. c1z = p1z + d1z;
  9296. nx = n1x;
  9297. ny = n1y;
  9298. nz = n1z;
  9299. } else {
  9300. c1x = p1x - d1x;
  9301. c1y = p1y - d1y;
  9302. c1z = p1z - d1z;
  9303. nx = -n1x;
  9304. ny = -n1y;
  9305. nz = -n1z;
  9306. }
  9307. dot = nx * n2x + ny * n2y + nz * n2z;
  9308. if (dot < 0) len = h2;
  9309. else len = -h2;
  9310. c2x = p2x + len * n2x;
  9311. c2y = p2y + len * n2y;
  9312. c2z = p2z + len * n2z;
  9313. if (dot2 >= 0.999999) {
  9314. tx = -ny;
  9315. ty = nz;
  9316. tz = nx;
  9317. } else {
  9318. tx = nx;
  9319. ty = ny;
  9320. tz = nz;
  9321. }
  9322. len = tx * n2x + ty * n2y + tz * n2z;
  9323. dx = len * n2x - tx;
  9324. dy = len * n2y - ty;
  9325. dz = len * n2z - tz;
  9326. len = OIMO.sqrt(dx * dx + dy * dy + dz * dz);
  9327. if (len == 0) break;
  9328. len = r2 / len;
  9329. dx *= len;
  9330. dy *= len;
  9331. dz *= len;
  9332. tx = c2x + dx;
  9333. ty = c2y + dy;
  9334. tz = c2z + dz;
  9335. if (dot < -0.96 || dot > 0.96) {
  9336. r00 = n2x * n2x * 1.5 - 0.5;
  9337. r01 = n2x * n2y * 1.5 - n2z * 0.866025403;
  9338. r02 = n2x * n2z * 1.5 + n2y * 0.866025403;
  9339. r10 = n2y * n2x * 1.5 + n2z * 0.866025403;
  9340. r11 = n2y * n2y * 1.5 - 0.5;
  9341. r12 = n2y * n2z * 1.5 - n2x * 0.866025403;
  9342. r20 = n2z * n2x * 1.5 - n2y * 0.866025403;
  9343. r21 = n2z * n2y * 1.5 + n2x * 0.866025403;
  9344. r22 = n2z * n2z * 1.5 - 0.5;
  9345. px = tx;
  9346. py = ty;
  9347. pz = tz;
  9348. pd = nx * (px - c1x) + ny * (py - c1y) + nz * (pz - c1z);
  9349. tx = px - pd * nx - c1x;
  9350. ty = py - pd * ny - c1y;
  9351. tz = pz - pd * nz - c1z;
  9352. len = tx * tx + ty * ty + tz * tz;
  9353. if (len > r1 * r1) {
  9354. len = r1 / OIMO.sqrt(len);
  9355. tx *= len;
  9356. ty *= len;
  9357. tz *= len;
  9358. }
  9359. px = c1x + tx;
  9360. py = c1y + ty;
  9361. pz = c1z + tz;
  9362. manifold.addPoint(px, py, pz, nx, ny, nz, pd, false);
  9363. px = dx * r00 + dy * r01 + dz * r02;
  9364. py = dx * r10 + dy * r11 + dz * r12;
  9365. pz = dx * r20 + dy * r21 + dz * r22;
  9366. px = (dx = px) + c2x;
  9367. py = (dy = py) + c2y;
  9368. pz = (dz = pz) + c2z;
  9369. pd = nx * (px - c1x) + ny * (py - c1y) + nz * (pz - c1z);
  9370. if (pd <= 0) {
  9371. tx = px - pd * nx - c1x;
  9372. ty = py - pd * ny - c1y;
  9373. tz = pz - pd * nz - c1z;
  9374. len = tx * tx + ty * ty + tz * tz;
  9375. if (len > r1 * r1) {
  9376. len = r1 / OIMO.sqrt(len);
  9377. tx *= len;
  9378. ty *= len;
  9379. tz *= len;
  9380. }
  9381. px = c1x + tx;
  9382. py = c1y + ty;
  9383. pz = c1z + tz;
  9384. manifold.addPoint(px, py, pz, nx, ny, nz, pd, false);
  9385. }
  9386. px = dx * r00 + dy * r01 + dz * r02;
  9387. py = dx * r10 + dy * r11 + dz * r12;
  9388. pz = dx * r20 + dy * r21 + dz * r22;
  9389. px = (dx = px) + c2x;
  9390. py = (dy = py) + c2y;
  9391. pz = (dz = pz) + c2z;
  9392. pd = nx * (px - c1x) + ny * (py - c1y) + nz * (pz - c1z);
  9393. if (pd <= 0) {
  9394. tx = px - pd * nx - c1x;
  9395. ty = py - pd * ny - c1y;
  9396. tz = pz - pd * nz - c1z;
  9397. len = tx * tx + ty * ty + tz * tz;
  9398. if (len > r1 * r1) {
  9399. len = r1 / OIMO.sqrt(len);
  9400. tx *= len;
  9401. ty *= len;
  9402. tz *= len;
  9403. }
  9404. px = c1x + tx;
  9405. py = c1y + ty;
  9406. pz = c1z + tz;
  9407. manifold.addPoint(px, py, pz, nx, ny, nz, pd, false);
  9408. }
  9409. } else {
  9410. sx = tx;
  9411. sy = ty;
  9412. sz = tz;
  9413. depth1 = nx * (sx - c1x) + ny * (sy - c1y) + nz * (sz - c1z);
  9414. sx -= depth1 * nx;
  9415. sy -= depth1 * ny;
  9416. sz -= depth1 * nz;
  9417. if (dot > 0) {
  9418. ex = tx + n2x * h2 * 2;
  9419. ey = ty + n2y * h2 * 2;
  9420. ez = tz + n2z * h2 * 2;
  9421. } else {
  9422. ex = tx - n2x * h2 * 2;
  9423. ey = ty - n2y * h2 * 2;
  9424. ez = tz - n2z * h2 * 2;
  9425. }
  9426. depth2 = nx * (ex - c1x) + ny * (ey - c1y) + nz * (ez - c1z);
  9427. ex -= depth2 * nx;
  9428. ey -= depth2 * ny;
  9429. ez -= depth2 * nz;
  9430. dx = c1x - sx;
  9431. dy = c1y - sy;
  9432. dz = c1z - sz;
  9433. tx = ex - sx;
  9434. ty = ey - sy;
  9435. tz = ez - sz;
  9436. a = dx * dx + dy * dy + dz * dz;
  9437. b = dx * tx + dy * ty + dz * tz;
  9438. e = tx * tx + ty * ty + tz * tz;
  9439. f = b * b - e * (a - r1 * r1);
  9440. if (f < 0) break;
  9441. f = OIMO.sqrt(f);
  9442. t1 = (b + f) / e;
  9443. t2 = (b - f) / e;
  9444. if (t2 < t1) {
  9445. len = t1;
  9446. t1 = t2;
  9447. t2 = len;
  9448. }
  9449. if (t2 > 1) t2 = 1;
  9450. if (t1 < 0) t1 = 0;
  9451. tx = sx + (ex - sx) * t1;
  9452. ty = sy + (ey - sy) * t1;
  9453. tz = sz + (ez - sz) * t1;
  9454. ex = sx + (ex - sx) * t2;
  9455. ey = sy + (ey - sy) * t2;
  9456. ez = sz + (ez - sz) * t2;
  9457. sx = tx;
  9458. sy = ty;
  9459. sz = tz;
  9460. len = depth1 + (depth2 - depth1) * t1;
  9461. depth2 = depth1 + (depth2 - depth1) * t2;
  9462. depth1 = len;
  9463. if (depth1 < 0) manifold.addPoint(sx, sy, sz, nx, ny, nz, pd, false);
  9464. if (depth2 < 0) manifold.addPoint(ex, ey, ez, nx, ny, nz, pd, false);
  9465. }
  9466. break;
  9467. case 2:
  9468. if (right2) {
  9469. c2x = p2x - d2x;
  9470. c2y = p2y - d2y;
  9471. c2z = p2z - d2z;
  9472. nx = -n2x;
  9473. ny = -n2y;
  9474. nz = -n2z;
  9475. } else {
  9476. c2x = p2x + d2x;
  9477. c2y = p2y + d2y;
  9478. c2z = p2z + d2z;
  9479. nx = n2x;
  9480. ny = n2y;
  9481. nz = n2z;
  9482. }
  9483. dot = nx * n1x + ny * n1y + nz * n1z;
  9484. if (dot < 0) len = h1;
  9485. else len = -h1;
  9486. c1x = p1x + len * n1x;
  9487. c1y = p1y + len * n1y;
  9488. c1z = p1z + len * n1z;
  9489. if (dot1 >= 0.999999) {
  9490. tx = -ny;
  9491. ty = nz;
  9492. tz = nx;
  9493. } else {
  9494. tx = nx;
  9495. ty = ny;
  9496. tz = nz;
  9497. }
  9498. len = tx * n1x + ty * n1y + tz * n1z;
  9499. dx = len * n1x - tx;
  9500. dy = len * n1y - ty;
  9501. dz = len * n1z - tz;
  9502. len = OIMO.sqrt(dx * dx + dy * dy + dz * dz);
  9503. if (len == 0) break;
  9504. len = r1 / len;
  9505. dx *= len;
  9506. dy *= len;
  9507. dz *= len;
  9508. tx = c1x + dx;
  9509. ty = c1y + dy;
  9510. tz = c1z + dz;
  9511. if (dot < -0.96 || dot > 0.96) {
  9512. r00 = n1x * n1x * 1.5 - 0.5;
  9513. r01 = n1x * n1y * 1.5 - n1z * 0.866025403;
  9514. r02 = n1x * n1z * 1.5 + n1y * 0.866025403;
  9515. r10 = n1y * n1x * 1.5 + n1z * 0.866025403;
  9516. r11 = n1y * n1y * 1.5 - 0.5;
  9517. r12 = n1y * n1z * 1.5 - n1x * 0.866025403;
  9518. r20 = n1z * n1x * 1.5 - n1y * 0.866025403;
  9519. r21 = n1z * n1y * 1.5 + n1x * 0.866025403;
  9520. r22 = n1z * n1z * 1.5 - 0.5;
  9521. px = tx;
  9522. py = ty;
  9523. pz = tz;
  9524. pd = nx * (px - c2x) + ny * (py - c2y) + nz * (pz - c2z);
  9525. tx = px - pd * nx - c2x;
  9526. ty = py - pd * ny - c2y;
  9527. tz = pz - pd * nz - c2z;
  9528. len = tx * tx + ty * ty + tz * tz;
  9529. if (len > r2 * r2) {
  9530. len = r2 / OIMO.sqrt(len);
  9531. tx *= len;
  9532. ty *= len;
  9533. tz *= len;
  9534. }
  9535. px = c2x + tx;
  9536. py = c2y + ty;
  9537. pz = c2z + tz;
  9538. manifold.addPoint(px, py, pz, -nx, -ny, -nz, pd, false);
  9539. px = dx * r00 + dy * r01 + dz * r02;
  9540. py = dx * r10 + dy * r11 + dz * r12;
  9541. pz = dx * r20 + dy * r21 + dz * r22;
  9542. px = (dx = px) + c1x;
  9543. py = (dy = py) + c1y;
  9544. pz = (dz = pz) + c1z;
  9545. pd = nx * (px - c2x) + ny * (py - c2y) + nz * (pz - c2z);
  9546. if (pd <= 0) {
  9547. tx = px - pd * nx - c2x;
  9548. ty = py - pd * ny - c2y;
  9549. tz = pz - pd * nz - c2z;
  9550. len = tx * tx + ty * ty + tz * tz;
  9551. if (len > r2 * r2) {
  9552. len = r2 / OIMO.sqrt(len);
  9553. tx *= len;
  9554. ty *= len;
  9555. tz *= len;
  9556. }
  9557. px = c2x + tx;
  9558. py = c2y + ty;
  9559. pz = c2z + tz;
  9560. manifold.addPoint(px, py, pz, -nx, -ny, -nz, pd, false);
  9561. }
  9562. px = dx * r00 + dy * r01 + dz * r02;
  9563. py = dx * r10 + dy * r11 + dz * r12;
  9564. pz = dx * r20 + dy * r21 + dz * r22;
  9565. px = (dx = px) + c1x;
  9566. py = (dy = py) + c1y;
  9567. pz = (dz = pz) + c1z;
  9568. pd = nx * (px - c2x) + ny * (py - c2y) + nz * (pz - c2z);
  9569. if (pd <= 0) {
  9570. tx = px - pd * nx - c2x;
  9571. ty = py - pd * ny - c2y;
  9572. tz = pz - pd * nz - c2z;
  9573. len = tx * tx + ty * ty + tz * tz;
  9574. if (len > r2 * r2) {
  9575. len = r2 / OIMO.sqrt(len);
  9576. tx *= len;
  9577. ty *= len;
  9578. tz *= len;
  9579. }
  9580. px = c2x + tx;
  9581. py = c2y + ty;
  9582. pz = c2z + tz;
  9583. manifold.addPoint(px, py, pz, -nx, -ny, -nz, pd, false);
  9584. }
  9585. } else {
  9586. sx = tx;
  9587. sy = ty;
  9588. sz = tz;
  9589. depth1 = nx * (sx - c2x) + ny * (sy - c2y) + nz * (sz - c2z);
  9590. sx -= depth1 * nx;
  9591. sy -= depth1 * ny;
  9592. sz -= depth1 * nz;
  9593. if (dot > 0) {
  9594. ex = tx + n1x * h1 * 2;
  9595. ey = ty + n1y * h1 * 2;
  9596. ez = tz + n1z * h1 * 2;
  9597. } else {
  9598. ex = tx - n1x * h1 * 2;
  9599. ey = ty - n1y * h1 * 2;
  9600. ez = tz - n1z * h1 * 2;
  9601. }
  9602. depth2 = nx * (ex - c2x) + ny * (ey - c2y) + nz * (ez - c2z);
  9603. ex -= depth2 * nx;
  9604. ey -= depth2 * ny;
  9605. ez -= depth2 * nz;
  9606. dx = c2x - sx;
  9607. dy = c2y - sy;
  9608. dz = c2z - sz;
  9609. tx = ex - sx;
  9610. ty = ey - sy;
  9611. tz = ez - sz;
  9612. a = dx * dx + dy * dy + dz * dz;
  9613. b = dx * tx + dy * ty + dz * tz;
  9614. e = tx * tx + ty * ty + tz * tz;
  9615. f = b * b - e * (a - r2 * r2);
  9616. if (f < 0) break;
  9617. f = OIMO.sqrt(f);
  9618. t1 = (b + f) / e;
  9619. t2 = (b - f) / e;
  9620. if (t2 < t1) {
  9621. len = t1;
  9622. t1 = t2;
  9623. t2 = len;
  9624. }
  9625. if (t2 > 1) t2 = 1;
  9626. if (t1 < 0) t1 = 0;
  9627. tx = sx + (ex - sx) * t1;
  9628. ty = sy + (ey - sy) * t1;
  9629. tz = sz + (ez - sz) * t1;
  9630. ex = sx + (ex - sx) * t2;
  9631. ey = sy + (ey - sy) * t2;
  9632. ez = sz + (ez - sz) * t2;
  9633. sx = tx;
  9634. sy = ty;
  9635. sz = tz;
  9636. len = depth1 + (depth2 - depth1) * t1;
  9637. depth2 = depth1 + (depth2 - depth1) * t2;
  9638. depth1 = len;
  9639. if (depth1 < 0) {
  9640. manifold.addPoint(sx, sy, sz, -nx, -ny, -nz, depth1, false);
  9641. }
  9642. if (depth2 < 0) {
  9643. manifold.addPoint(ex, ey, ez, -nx, -ny, -nz, depth2, false);
  9644. }
  9645. }
  9646. break;
  9647. }
  9648. };
  9649. OIMO.SphereCylinderCollisionDetector = function (flip) {
  9650. OIMO.CollisionDetector.call(this);
  9651. this.flip = flip;
  9652. };
  9653. OIMO.SphereCylinderCollisionDetector.prototype = Object.create(OIMO.CollisionDetector.prototype);
  9654. OIMO.SphereCylinderCollisionDetector.prototype.constructor = OIMO.SphereCylinderCollisionDetector;
  9655. OIMO.SphereCylinderCollisionDetector.prototype.detectCollision = function (shape1, shape2, manifold) {
  9656. var s;
  9657. var c;
  9658. if (this.flip) {
  9659. s = shape2;
  9660. c = shape1;
  9661. } else {
  9662. s = shape1;
  9663. c = shape2;
  9664. }
  9665. var ps = s.position;
  9666. var psx = ps.x;
  9667. var psy = ps.y;
  9668. var psz = ps.z;
  9669. var pc = c.position;
  9670. var pcx = pc.x;
  9671. var pcy = pc.y;
  9672. var pcz = pc.z;
  9673. var dirx = c.normalDirection.x;
  9674. var diry = c.normalDirection.y;
  9675. var dirz = c.normalDirection.z;
  9676. var rads = s.radius;
  9677. var radc = c.radius;
  9678. var rad2 = rads + radc;
  9679. var halfh = c.halfHeight;
  9680. var dx = psx - pcx;
  9681. var dy = psy - pcy;
  9682. var dz = psz - pcz;
  9683. var dot = dx * dirx + dy * diry + dz * dirz;
  9684. if (dot < -halfh - rads || dot > halfh + rads) return;
  9685. var cx = pcx + dot * dirx;
  9686. var cy = pcy + dot * diry;
  9687. var cz = pcz + dot * dirz;
  9688. var d2x = psx - cx;
  9689. var d2y = psy - cy;
  9690. var d2z = psz - cz;
  9691. var len = d2x * d2x + d2y * d2y + d2z * d2z;
  9692. if (len > rad2 * rad2) return;
  9693. if (len > radc * radc) {
  9694. len = radc / OIMO.sqrt(len);
  9695. d2x *= len;
  9696. d2y *= len;
  9697. d2z *= len;
  9698. }
  9699. if (dot < -halfh) dot = -halfh;
  9700. else if (dot > halfh) dot = halfh;
  9701. cx = pcx + dot * dirx + d2x;
  9702. cy = pcy + dot * diry + d2y;
  9703. cz = pcz + dot * dirz + d2z;
  9704. dx = cx - psx;
  9705. dy = cy - psy;
  9706. dz = cz - psz;
  9707. len = dx * dx + dy * dy + dz * dz;
  9708. var invLen;
  9709. if (len > 0 && len < rads * rads) {
  9710. len = OIMO.sqrt(len);
  9711. invLen = 1 / len;
  9712. dx *= invLen;
  9713. dy *= invLen;
  9714. dz *= invLen;
  9715. ///result.addContactInfo(psx+dx*rads,psy+dy*rads,psz+dz*rads,dx,dy,dz,len-rads,s,c,0,0,false);
  9716. manifold.addPoint(psx + dx * rads, psy + dy * rads, psz + dz * rads, dx, dy, dz, len - rads, this.flip);
  9717. }
  9718. };
  9719. /**
  9720. * Class for checking collisions between 2 tetras,
  9721. * a shape that is made with 4 vertices and 4 faces
  9722. * arranged in triangles. With this algorigthm, soft
  9723. * body physics are possible and easier to implement.
  9724. * @author xprogram
  9725. */
  9726. OIMO.TetraTetraCollisionDetector = function () {
  9727. OIMO.CollisionDetector.call(this);
  9728. };
  9729. OIMO.TetraTetraCollisionDetector.prototype = Object.create(OIMO.CollisionDetector.prototype);
  9730. OIMO.TetraTetraCollisionDetector.prototype.constructor = OIMO.TetraTetraCollisionDetector;
  9731. OIMO.TetraTetraCollisionDetector.prototype.detectCollision = function (tet1, tet2, manifold) {
  9732. /*
  9733. * What we are doing:
  9734. * Each tetra is represented by four 3D triangles. The only
  9735. * quick way of finding if another tetra is within the other
  9736. * tetra is to see if a single vertex is within the triangles
  9737. * of the other tetra. So, for example, a tetra is represented
  9738. * by points B, C, D and E with triangles BCD, BCE, DCE and BDE.
  9739. * There is another tetra with a vertex A which was detected for
  9740. * collision by the broadphase. Now, if the point A is between ALL
  9741. * triangles of the other tetra (BCD, BCE, etc.) then the collision
  9742. * is valid and we can pass point A to the manifold. Since the only
  9743. * points on the tetra are the 4 vertices, collision detection is
  9744. * not so complex. However, it can be time-consuming because we
  9745. * need to split the 3D triangles into three 2D triangles each for
  9746. * collision detection.
  9747. */
  9748. var i, j, vec, fs1 = tet1.faces, vs1 = tet1.verts, fs2 = tet2.faces, vs2 = tet2.verts;
  9749. var j1, j2, j3, ts = 0; // Triangle vertices `j1`, `j2` and `j3`
  9750. // fs is undeclared
  9751. var fs = fs1;
  9752. for (i = 0; i < 4; i++) {
  9753. vec = vs1[i];
  9754. for (j = 0; j < 4; j++) {
  9755. j1 = vs2[fs[i].a];
  9756. j2 = vs2[fs[i].b];
  9757. j3 = vs2[fs[i].c];
  9758. if (
  9759. tricheck(pt(vec.x, vec.y), pt(j1.x, j1.y), pt(j2.x, j2.y), pt(j3.x, j3.y)) &&
  9760. tricheck(pt(vec.x, vec.z), pt(j1.x, j1.z), pt(j2.x, j2.z), pt(j3.x, j3.z)) &&
  9761. tricheck(pt(vec.z, vec.y), pt(j1.z, j1.y), pt(j2.z, j2.y), pt(j3.z, j3.y))
  9762. )
  9763. ts++;
  9764. if (ts === 4) // Only add point if it is inside all 4 triangles
  9765. manifold.addPoint(vec);
  9766. }
  9767. }
  9768. };
  9769. // Taken from: http://jsfiddle.net/PerroAZUL/zdaY8/1/
  9770. function tricheck(p, p0, p1, p2) {
  9771. var A = 0.5 * (-p1.y * p2.x + p0.y * (-p1.x + p2.x) + p0.x * (p1.y - p2.y) + p1.x * p2.y);
  9772. var sg = A < 0 ? -1 : 1;
  9773. var s = (p0.y * p2.x - p0.x * p2.y + (p2.y - p0.y) * p.x + (p0.x - p2.x) * p.y) * sg;
  9774. var t = (p0.x * p1.y - p0.y * p1.x + (p0.y - p1.y) * p.x + (p1.x - p0.x) * p.y) * sg;
  9775. return s > 0 && t > 0 && (s + t) < 2 * A * sg;
  9776. }
  9777. function pt(x, y) { return { x: x, y: y }; }
  9778. /**
  9779. * An axis-aligned bounding box.
  9780. * @author saharan
  9781. * @author lo-th
  9782. */
  9783. OIMO.AABB = function (minX, maxX, minY, maxY, minZ, maxZ) {
  9784. this.elements = new OIMO_ARRAY_TYPE(6);
  9785. var te = this.elements;
  9786. te[0] = minX || 0; te[1] = minY || 0; te[2] = minZ || 0;
  9787. te[3] = maxX || 0; te[4] = maxY || 0; te[5] = maxZ || 0;
  9788. };
  9789. OIMO.AABB.prototype = {
  9790. constructor: OIMO.AABB,
  9791. set: function (minX, maxX, minY, maxY, minZ, maxZ) {
  9792. var te = this.elements;
  9793. te[0] = minX; te[3] = maxX;
  9794. te[1] = minY; te[4] = maxY;
  9795. te[2] = minZ; te[5] = maxZ;
  9796. return this;
  9797. },
  9798. intersectTest: function (aabb) {
  9799. var te = this.elements;
  9800. var ue = aabb.elements;
  9801. return te[0] > ue[3] || te[1] > ue[4] || te[2] > ue[5] || te[3] < ue[0] || te[4] < ue[1] || te[5] < ue[2];
  9802. },
  9803. intersectTestTwo: function (aabb) {
  9804. var te = this.elements;
  9805. var ue = aabb.elements;
  9806. return te[0] < ue[0] || te[1] < ue[1] || te[2] < ue[2] || te[3] > ue[3] || te[4] > ue[4] || te[5] > ue[5];
  9807. },
  9808. clone: function () {
  9809. return new this.constructor().fromArray(this.elements);
  9810. },
  9811. copy: function (aabb, margin) {
  9812. var m = margin || 0;
  9813. var me = aabb.elements;
  9814. this.set(me[0] - m, me[3] + m, me[1] - m, me[4] + m, me[2] - m, me[5] + m);
  9815. return this;
  9816. },
  9817. fromArray: function (array) {
  9818. this.elements.set(array);
  9819. return this;
  9820. },
  9821. // Set this AABB to the combined AABB of aabb1 and aabb2.
  9822. combine: function (aabb1, aabb2) {
  9823. var a = aabb1.elements;
  9824. var b = aabb2.elements;
  9825. var te = this.elements;
  9826. te[0] = a[0] < b[0] ? a[0] : b[0];
  9827. te[1] = a[1] < b[1] ? a[1] : b[1];
  9828. te[2] = a[2] < b[2] ? a[2] : b[2];
  9829. te[3] = a[3] > b[3] ? a[3] : b[3];
  9830. te[4] = a[4] > b[4] ? a[4] : b[4];
  9831. te[5] = a[5] > b[5] ? a[5] : b[5];
  9832. return this;
  9833. },
  9834. // Get the surface area.
  9835. surfaceArea: function () {
  9836. var te = this.elements;
  9837. var a = te[3] - te[0];
  9838. var h = te[4] - te[1];
  9839. var d = te[5] - te[2];
  9840. return 2 * (a * (h + d) + h * d);
  9841. },
  9842. // Get whether the AABB intersects with the point or not.
  9843. intersectsWithPoint: function (x, y, z) {
  9844. var te = this.elements;
  9845. return x >= te[0] && x <= te[3] && y >= te[1] && y <= te[4] && z >= te[2] && z <= te[5];
  9846. },
  9847. /**
  9848. * Set the AABB from an array
  9849. * of vertices. From THREE.
  9850. * @author mrdoob
  9851. * @author xprogram
  9852. */
  9853. setFromPoints: function (arr) {
  9854. this.makeEmpty();
  9855. for (var i = 0; i < arr.length; i++) {
  9856. this.expandByPoint(arr[i]);
  9857. }
  9858. },
  9859. makeEmpty: function () {
  9860. this.set(-Infinity, -Infinity, -Infinity, Infinity, Infinity, Infinity);
  9861. },
  9862. expandByPoint: function (pt) {
  9863. var te = this.elements;
  9864. this.set(
  9865. OIMO.min(te[0], pt.x), OIMO.min(te[1], pt.y), OIMO.min(te[2], pt.z),
  9866. OIMO.max(te[3], pt.x), OIMO.max(te[4], pt.y), OIMO.max(te[5], pt.z)
  9867. );
  9868. }
  9869. };
  9870. /**
  9871. * A proxy is used for broad-phase collecting pairs that can be colliding.
  9872. */
  9873. OIMO.Proxy = function (shape) {
  9874. // The parent shape.
  9875. this.shape = shape;
  9876. // The axis-aligned bounding box.
  9877. this.aabb = shape.aabb;
  9878. };
  9879. OIMO.Proxy.prototype = {
  9880. constructor: OIMO.Proxy,
  9881. // Update the proxy.
  9882. update: function () {
  9883. OIMO.Error("Proxy", "Inheritance error.");
  9884. }
  9885. };
  9886. /**
  9887. * A basic implementation of proxies.
  9888. * @author saharan
  9889. */
  9890. OIMO.BasicProxy = function (shape) {
  9891. OIMO.Proxy.call(this, shape);
  9892. this.id = OIMO.proxyID++;
  9893. };
  9894. OIMO.BasicProxy.prototype = Object.create(OIMO.Proxy.prototype);
  9895. OIMO.BasicProxy.prototype.constructor = OIMO.BasicProxy;
  9896. OIMO.BasicProxy.prototype.update = function () {
  9897. };
  9898. /**
  9899. * The broad-phase is used for collecting all possible pairs for collision.
  9900. */
  9901. OIMO.BroadPhase = function () {
  9902. this.types = OIMO.BR_NULL;
  9903. this.numPairChecks = 0;
  9904. this.numPairs = 0;
  9905. this.pairs = [];
  9906. };
  9907. OIMO.BroadPhase.prototype = {
  9908. constructor: OIMO.BroadPhase,
  9909. /**
  9910. * Create a new proxy.
  9911. * @param shape
  9912. * @return
  9913. */
  9914. createProxy: function (shape) {
  9915. OIMO.Error("BroadPhase", "Inheritance error.");
  9916. },
  9917. /**
  9918. * Add the proxy into the broad-phase.
  9919. * @param proxy
  9920. */
  9921. addProxy: function (proxy) {
  9922. OIMO.Error("BroadPhase", "Inheritance error.");
  9923. },
  9924. /**
  9925. * Remove the proxy from the broad-phase.
  9926. * @param proxy
  9927. */
  9928. removeProxy: function (proxy) {
  9929. OIMO.Error("BroadPhase", "Inheritance error.");
  9930. },
  9931. /**
  9932. * Returns whether the pair is available or not.
  9933. * @param s1
  9934. * @param s2
  9935. * @return
  9936. */
  9937. isAvailablePair: function (s1, s2) {
  9938. var b1 = s1.parent;
  9939. var b2 = s2.parent;
  9940. if (b1 == b2 || // same parents
  9941. (!b1.isDynamic && !b2.isDynamic) || // static or kinematic object
  9942. (s1.belongsTo & s2.collidesWith) == 0 ||
  9943. (s2.belongsTo & s1.collidesWith) == 0 // collision filtering
  9944. ) { return false; }
  9945. var js;
  9946. if (b1.numJoints < b2.numJoints) js = b1.jointLink;
  9947. else js = b2.jointLink;
  9948. while (js !== null) {
  9949. var joint = js.joint;
  9950. if (!joint.allowCollision && ((joint.body1 == b1 && joint.body2 == b2) || (joint.body1 == b2 && joint.body2 == b1))) { return false; }
  9951. js = js.next;
  9952. }
  9953. return true;
  9954. },
  9955. // Detect overlapping pairs.
  9956. detectPairs: function () {
  9957. // clear old
  9958. this.pairs = [];
  9959. this.numPairs = 0;
  9960. this.numPairChecks = 0;
  9961. this.collectPairs();
  9962. },
  9963. collectPairs: function () {
  9964. OIMO.Error("BroadPhase", "Inheritance error.");
  9965. },
  9966. addPair: function (s1, s2) {
  9967. var pair = new OIMO.Pair(s1, s2);
  9968. this.pairs.push(pair);
  9969. this.numPairs++;
  9970. }
  9971. };
  9972. /**
  9973. * A broad-phase algorithm with brute-force search.
  9974. * This always checks for all possible pairs.
  9975. */
  9976. OIMO.BruteForceBroadPhase = function () {
  9977. OIMO.BroadPhase.call(this);
  9978. this.types = OIMO.BR_BRUTE_FORCE;;
  9979. //this.numProxies=0;
  9980. ///this.maxProxies = 256;
  9981. this.proxies = [];
  9982. //this.proxies.length = 256;
  9983. };
  9984. OIMO.BruteForceBroadPhase.prototype = Object.create(OIMO.BroadPhase.prototype);
  9985. OIMO.BruteForceBroadPhase.prototype.constructor = OIMO.BruteForceBroadPhase;
  9986. OIMO.BruteForceBroadPhase.prototype.createProxy = function (shape) {
  9987. return new OIMO.BasicProxy(shape);
  9988. };
  9989. OIMO.BruteForceBroadPhase.prototype.addProxy = function (proxy) {
  9990. /*if(this.numProxies==this.maxProxies){
  9991. //this.maxProxies<<=1;
  9992. this.maxProxies*=2;
  9993. var newProxies=[];
  9994. newProxies.length = this.maxProxies;
  9995. var i = this.numProxies;
  9996. while(i--){
  9997. //for(var i=0, l=this.numProxies;i<l;i++){
  9998. newProxies[i]=this.proxies[i];
  9999. }
  10000. this.proxies=newProxies;
  10001. }*/
  10002. //this.proxies[this.numProxies++] = proxy;
  10003. this.proxies.push(proxy);
  10004. //this.numProxies++;
  10005. };
  10006. OIMO.BruteForceBroadPhase.prototype.removeProxy = function (proxy) {
  10007. var n = this.proxies.indexOf(proxy);
  10008. if (n > -1) {
  10009. this.proxies.splice(n, 1);
  10010. //this.numProxies--;
  10011. }
  10012. /*var i = this.numProxies;
  10013. while(i--){
  10014. //for(var i=0, l=this.numProxies;i<l;i++){
  10015. if(this.proxies[i] == proxy){
  10016. this.proxies[i] = this.proxies[--this.numProxies];
  10017. this.proxies[this.numProxies] = null;
  10018. return;
  10019. }
  10020. }*/
  10021. };
  10022. OIMO.BruteForceBroadPhase.prototype.collectPairs = function () {
  10023. var i = 0, j, p1, p2;
  10024. var px = this.proxies;
  10025. var l = px.length;//this.numProxies;
  10026. //var ar1 = [];
  10027. //var ar2 = [];
  10028. //for( i = px.length ; i-- ; ar1[ i ] = px[ i ] ){};
  10029. //for( i = px.length ; i-- ; ar2[ i ] = px[ i ] ){};
  10030. //var ar1 = JSON.parse(JSON.stringify(this.proxies))
  10031. //var ar2 = JSON.parse(JSON.stringify(this.proxies))
  10032. this.numPairChecks = l * (l - 1) >> 1;
  10033. //this.numPairChecks=this.numProxies*(this.numProxies-1)*0.5;
  10034. while (i < l) {
  10035. p1 = px[i++];
  10036. j = i + 1;
  10037. while (j < l) {
  10038. p2 = px[j++];
  10039. if (p1.aabb.intersectTest(p2.aabb) || !this.isAvailablePair(p1.shape, p2.shape)) continue;
  10040. this.addPair(p1.shape, p2.shape);
  10041. }
  10042. }
  10043. };
  10044. /**
  10045. * A pair of shapes that may collide.
  10046. * @author saharan
  10047. */
  10048. OIMO.Pair = function (s1, s2) {
  10049. // The first shape.
  10050. this.shape1 = s1 || null;
  10051. // The second shape.
  10052. this.shape2 = s2 || null;
  10053. };
  10054. /**
  10055. * A projection axis for sweep and prune broad-phase.
  10056. * @author saharan
  10057. */
  10058. OIMO.SAPAxis = function () {
  10059. this.numElements = 0;
  10060. this.bufferSize = 256;
  10061. this.elements = [];
  10062. this.elements.length = this.bufferSize;
  10063. this.stack = new OIMO_ARRAY_TYPE(64);
  10064. };
  10065. OIMO.SAPAxis.prototype = {
  10066. constructor: OIMO.SAPAxis,
  10067. addElements: function (min, max) {
  10068. if (this.numElements + 2 >= this.bufferSize) {
  10069. //this.bufferSize<<=1;
  10070. this.bufferSize *= 2;
  10071. var newElements = [];
  10072. var i = this.numElements;
  10073. while (i--) {
  10074. //for(var i=0, l=this.numElements; i<l; i++){
  10075. newElements[i] = this.elements[i];
  10076. }
  10077. }
  10078. this.elements[this.numElements++] = min;
  10079. this.elements[this.numElements++] = max;
  10080. },
  10081. removeElements: function (min, max) {
  10082. var minIndex = -1;
  10083. var maxIndex = -1;
  10084. for (var i = 0, l = this.numElements; i < l; i++) {
  10085. var e = this.elements[i];
  10086. if (e == min || e == max) {
  10087. if (minIndex == -1) {
  10088. minIndex = i;
  10089. } else {
  10090. maxIndex = i;
  10091. break;
  10092. }
  10093. }
  10094. }
  10095. for (i = minIndex + 1, l = maxIndex; i < l; i++) {
  10096. this.elements[i - 1] = this.elements[i];
  10097. }
  10098. for (i = maxIndex + 1, l = this.numElements; i < l; i++) {
  10099. this.elements[i - 2] = this.elements[i];
  10100. }
  10101. this.elements[--this.numElements] = null;
  10102. this.elements[--this.numElements] = null;
  10103. },
  10104. sort: function () {
  10105. var count = 0;
  10106. var threshold = 1;
  10107. while ((this.numElements >> threshold) != 0) threshold++;
  10108. threshold = threshold * this.numElements >> 2;
  10109. count = 0;
  10110. var giveup = false;
  10111. var elements = this.elements;
  10112. for (var i = 1, l = this.numElements; i < l; i++) { // try insertion sort
  10113. var tmp = elements[i];
  10114. var pivot = tmp.value;
  10115. var tmp2 = elements[i - 1];
  10116. if (tmp2.value > pivot) {
  10117. var j = i;
  10118. do {
  10119. elements[j] = tmp2;
  10120. if (--j == 0) break;
  10121. tmp2 = elements[j - 1];
  10122. } while (tmp2.value > pivot);
  10123. elements[j] = tmp;
  10124. count += i - j;
  10125. if (count > threshold) {
  10126. giveup = true; // stop and use quick sort
  10127. break;
  10128. }
  10129. }
  10130. }
  10131. if (!giveup) return;
  10132. count = 2; var stack = this.stack;
  10133. stack[0] = 0;
  10134. stack[1] = this.numElements - 1;
  10135. while (count > 0) {
  10136. var right = stack[--count];
  10137. var left = stack[--count];
  10138. var diff = right - left;
  10139. if (diff > 16) { // quick sort
  10140. //var mid=left+(diff>>1);
  10141. var mid = left + (OIMO.floor(diff * 0.5));
  10142. tmp = elements[mid];
  10143. elements[mid] = elements[right];
  10144. elements[right] = tmp;
  10145. pivot = tmp.value;
  10146. i = left - 1;
  10147. j = right;
  10148. while (true) {
  10149. var ei;
  10150. var ej;
  10151. do { ei = elements[++i]; } while (ei.value < pivot);
  10152. do { ej = elements[--j]; } while (pivot < ej.value && j != left);
  10153. if (i >= j) break;
  10154. elements[i] = ej;
  10155. elements[j] = ei;
  10156. }
  10157. elements[right] = elements[i];
  10158. elements[i] = tmp;
  10159. if (i - left > right - i) {
  10160. stack[count++] = left;
  10161. stack[count++] = i - 1;
  10162. stack[count++] = i + 1;
  10163. stack[count++] = right;
  10164. } else {
  10165. stack[count++] = i + 1;
  10166. stack[count++] = right;
  10167. stack[count++] = left;
  10168. stack[count++] = i - 1;
  10169. }
  10170. } else {
  10171. for (i = left + 1; i <= right; i++) {
  10172. tmp = elements[i];
  10173. pivot = tmp.value;
  10174. tmp2 = elements[i - 1];
  10175. if (tmp2.value > pivot) {
  10176. j = i;
  10177. do {
  10178. elements[j] = tmp2;
  10179. if (--j == 0) break;
  10180. tmp2 = elements[j - 1];
  10181. } while (tmp2.value > pivot);
  10182. elements[j] = tmp;
  10183. }
  10184. }
  10185. }
  10186. }
  10187. },
  10188. calculateTestCount: function () {
  10189. var num = 1;
  10190. var sum = 0;
  10191. for (var i = 1, l = this.numElements; i < l; i++) {
  10192. if (this.elements[i].max) {
  10193. num--;
  10194. } else {
  10195. sum += num;
  10196. num++;
  10197. }
  10198. }
  10199. return sum;
  10200. }
  10201. }
  10202. /**
  10203. * A broad-phase collision detection algorithm using sweep and prune.
  10204. * @author saharan
  10205. * @author lo-th
  10206. */
  10207. OIMO.SAPBroadPhase = function () {
  10208. OIMO.BroadPhase.call(this);
  10209. this.types = OIMO.BR_SWEEP_AND_PRUNE;
  10210. this.numElementsD = 0;
  10211. this.numElementsS = 0;
  10212. // dynamic proxies
  10213. this.axesD = [
  10214. new OIMO.SAPAxis(),
  10215. new OIMO.SAPAxis(),
  10216. new OIMO.SAPAxis()
  10217. ];
  10218. // static or sleeping proxies
  10219. this.axesS = [
  10220. new OIMO.SAPAxis(),
  10221. new OIMO.SAPAxis(),
  10222. new OIMO.SAPAxis()
  10223. ];
  10224. this.index1 = 0;
  10225. this.index2 = 1;
  10226. };
  10227. OIMO.SAPBroadPhase.prototype = Object.create(OIMO.BroadPhase.prototype);
  10228. OIMO.SAPBroadPhase.prototype.constructor = OIMO.SAPBroadPhase;
  10229. OIMO.SAPBroadPhase.prototype.createProxy = function (shape) {
  10230. return new OIMO.SAPProxy(this, shape);
  10231. };
  10232. OIMO.SAPBroadPhase.prototype.addProxy = function (proxy) {
  10233. var p = proxy;
  10234. if (p.isDynamic()) {
  10235. this.axesD[0].addElements(p.min[0], p.max[0]);
  10236. this.axesD[1].addElements(p.min[1], p.max[1]);
  10237. this.axesD[2].addElements(p.min[2], p.max[2]);
  10238. p.belongsTo = 1;
  10239. this.numElementsD += 2;
  10240. } else {
  10241. this.axesS[0].addElements(p.min[0], p.max[0]);
  10242. this.axesS[1].addElements(p.min[1], p.max[1]);
  10243. this.axesS[2].addElements(p.min[2], p.max[2]);
  10244. p.belongsTo = 2;
  10245. this.numElementsS += 2;
  10246. }
  10247. };
  10248. OIMO.SAPBroadPhase.prototype.removeProxy = function (proxy) {
  10249. var p = proxy;
  10250. if (p.belongsTo == 0) return;
  10251. /*else if ( p.belongsTo == 1 ) {
  10252. this.axesD[0].removeElements( p.min[0], p.max[0] );
  10253. this.axesD[1].removeElements( p.min[1], p.max[1] );
  10254. this.axesD[2].removeElements( p.min[2], p.max[2] );
  10255. this.numElementsD -= 2;
  10256. } else if ( p.belongsTo == 2 ) {
  10257. this.axesS[0].removeElements( p.min[0], p.max[0] );
  10258. this.axesS[1].removeElements( p.min[1], p.max[1] );
  10259. this.axesS[2].removeElements( p.min[2], p.max[2] );
  10260. this.numElementsS -= 2;
  10261. }*/
  10262. switch (p.belongsTo) {
  10263. case 1:
  10264. this.axesD[0].removeElements(p.min[0], p.max[0]);
  10265. this.axesD[1].removeElements(p.min[1], p.max[1]);
  10266. this.axesD[2].removeElements(p.min[2], p.max[2]);
  10267. this.numElementsD -= 2;
  10268. break;
  10269. case 2:
  10270. this.axesS[0].removeElements(p.min[0], p.max[0]);
  10271. this.axesS[1].removeElements(p.min[1], p.max[1]);
  10272. this.axesS[2].removeElements(p.min[2], p.max[2]);
  10273. this.numElementsS -= 2;
  10274. break;
  10275. }
  10276. p.belongsTo = 0;
  10277. };
  10278. OIMO.SAPBroadPhase.prototype.collectPairs = function () {
  10279. if (this.numElementsD == 0) return;
  10280. var axis1 = this.axesD[this.index1];
  10281. var axis2 = this.axesD[this.index2];
  10282. axis1.sort();
  10283. axis2.sort();
  10284. var count1 = axis1.calculateTestCount();
  10285. var count2 = axis2.calculateTestCount();
  10286. var elementsD;
  10287. var elementsS;
  10288. if (count1 <= count2) {// select the best axis
  10289. axis2 = this.axesS[this.index1];
  10290. axis2.sort();
  10291. elementsD = axis1.elements;
  10292. elementsS = axis2.elements;
  10293. } else {
  10294. axis1 = this.axesS[this.index2];
  10295. axis1.sort();
  10296. elementsD = axis2.elements;
  10297. elementsS = axis1.elements;
  10298. this.index1 ^= this.index2;
  10299. this.index2 ^= this.index1;
  10300. this.index1 ^= this.index2;
  10301. }
  10302. var activeD;
  10303. var activeS;
  10304. var p = 0;
  10305. var q = 0;
  10306. while (p < this.numElementsD) {
  10307. var e1;
  10308. var dyn;
  10309. if (q == this.numElementsS) {
  10310. e1 = elementsD[p];
  10311. dyn = true;
  10312. p++;
  10313. } else {
  10314. var d = elementsD[p];
  10315. var s = elementsS[q];
  10316. if (d.value < s.value) {
  10317. e1 = d;
  10318. dyn = true;
  10319. p++;
  10320. } else {
  10321. e1 = s;
  10322. dyn = false;
  10323. q++;
  10324. }
  10325. }
  10326. if (!e1.max) {
  10327. var s1 = e1.proxy.shape;
  10328. var min1 = e1.min1.value;
  10329. var max1 = e1.max1.value;
  10330. var min2 = e1.min2.value;
  10331. var max2 = e1.max2.value;
  10332. for (var e2 = activeD; e2 != null; e2 = e2.pair) {// test for dynamic
  10333. var s2 = e2.proxy.shape;
  10334. this.numPairChecks++;
  10335. if (min1 > e2.max1.value || max1 < e2.min1.value || min2 > e2.max2.value || max2 < e2.min2.value || !this.isAvailablePair(s1, s2)) continue;
  10336. this.addPair(s1, s2);
  10337. }
  10338. if (dyn) {
  10339. for (e2 = activeS; e2 != null; e2 = e2.pair) {// test for static
  10340. s2 = e2.proxy.shape;
  10341. this.numPairChecks++;
  10342. if (min1 > e2.max1.value || max1 < e2.min1.value || min2 > e2.max2.value || max2 < e2.min2.value || !this.isAvailablePair(s1, s2)) continue;
  10343. this.addPair(s1, s2);
  10344. }
  10345. e1.pair = activeD;
  10346. activeD = e1;
  10347. } else {
  10348. e1.pair = activeS;
  10349. activeS = e1;
  10350. }
  10351. } else {
  10352. var min = e1.pair;
  10353. if (dyn) {
  10354. if (min == activeD) {
  10355. activeD = activeD.pair;
  10356. continue;
  10357. } else {
  10358. e1 = activeD;
  10359. }
  10360. } else {
  10361. if (min == activeS) {
  10362. activeS = activeS.pair;
  10363. continue;
  10364. } else {
  10365. e1 = activeS;
  10366. }
  10367. }
  10368. do {
  10369. e2 = e1.pair;
  10370. if (e2 == min) {
  10371. e1.pair = e2.pair;
  10372. break;
  10373. }
  10374. e1 = e2;
  10375. } while (e1 != null);
  10376. }
  10377. }
  10378. this.index2 = (this.index1 | this.index2) ^ 3;
  10379. };
  10380. /**
  10381. * An element of proxies.
  10382. * @author saharan
  10383. */
  10384. OIMO.SAPElement = function (proxy, max) {
  10385. // The parent proxy
  10386. this.proxy = proxy;
  10387. // The pair element.
  10388. this.pair = null;
  10389. // The minimum element on other axis.
  10390. this.min1 = null;
  10391. // The maximum element on other axis.
  10392. this.max1 = null;
  10393. // The minimum element on other axis.
  10394. this.min2 = null;
  10395. // The maximum element on other axis.
  10396. this.max2 = null;
  10397. // Whether the element has maximum value or not.
  10398. this.max = max;
  10399. // The value of the element.
  10400. this.value = 0;
  10401. };
  10402. /**
  10403. * A proxy for sweep and prune broad-phase.
  10404. * @author saharan
  10405. * @author lo-th
  10406. */
  10407. OIMO.SAPProxy = function (sap, shape) {
  10408. OIMO.Proxy.call(this, shape);
  10409. // Type of the axis to which the proxy belongs to. [0:none, 1:dynamic, 2:static]
  10410. this.belongsTo = 0;
  10411. // The maximum elements on each axis.
  10412. this.max = [];
  10413. // The minimum elements on each axis.
  10414. this.min = [];
  10415. this.sap = sap;
  10416. this.min[0] = new OIMO.SAPElement(this, false);
  10417. this.max[0] = new OIMO.SAPElement(this, true);
  10418. this.min[1] = new OIMO.SAPElement(this, false);
  10419. this.max[1] = new OIMO.SAPElement(this, true);
  10420. this.min[2] = new OIMO.SAPElement(this, false);
  10421. this.max[2] = new OIMO.SAPElement(this, true);
  10422. this.max[0].pair = this.min[0];
  10423. this.max[1].pair = this.min[1];
  10424. this.max[2].pair = this.min[2];
  10425. this.min[0].min1 = this.min[1];
  10426. this.min[0].max1 = this.max[1];
  10427. this.min[0].min2 = this.min[2];
  10428. this.min[0].max2 = this.max[2];
  10429. this.min[1].min1 = this.min[0];
  10430. this.min[1].max1 = this.max[0];
  10431. this.min[1].min2 = this.min[2];
  10432. this.min[1].max2 = this.max[2];
  10433. this.min[2].min1 = this.min[0];
  10434. this.min[2].max1 = this.max[0];
  10435. this.min[2].min2 = this.min[1];
  10436. this.min[2].max2 = this.max[1];
  10437. };
  10438. OIMO.SAPProxy.prototype = Object.create(OIMO.Proxy.prototype);
  10439. OIMO.SAPProxy.prototype.constructor = OIMO.SAPProxy;
  10440. // Returns whether the proxy is dynamic or not.
  10441. OIMO.SAPProxy.prototype.isDynamic = function () {
  10442. var body = this.shape.parent;
  10443. return body.isDynamic && !body.sleeping;
  10444. };
  10445. OIMO.SAPProxy.prototype.update = function () {
  10446. var te = this.aabb.elements;
  10447. this.min[0].value = te[0];
  10448. this.min[1].value = te[1];
  10449. this.min[2].value = te[2];
  10450. this.max[0].value = te[3];
  10451. this.max[1].value = te[4];
  10452. this.max[2].value = te[5];
  10453. if (this.belongsTo == 1 && !this.isDynamic() || this.belongsTo == 2 && this.isDynamic()) {
  10454. this.sap.removeProxy(this);
  10455. this.sap.addProxy(this);
  10456. }
  10457. };
  10458. /**
  10459. * A dynamic bounding volume tree for the broad-phase algorithm.
  10460. * @author saharan
  10461. * @author lo-th
  10462. */
  10463. OIMO.DBVT = function () {
  10464. // The root of the tree.
  10465. this.root = null;
  10466. this.freeNodes = [];
  10467. this.freeNodes.length = 16384;
  10468. this.numFreeNodes = 0;
  10469. this.aabb = new OIMO.AABB();
  10470. };
  10471. OIMO.DBVT.prototype = {
  10472. constructor: OIMO.DBVT,
  10473. /**
  10474. * Move a leaf.
  10475. * @param leaf
  10476. */
  10477. moveLeaf: function (leaf) {
  10478. this.deleteLeaf(leaf);
  10479. this.insertLeaf(leaf);
  10480. },
  10481. /**
  10482. * Insert a leaf to the tree.
  10483. * @param node
  10484. */
  10485. insertLeaf: function (leaf) {
  10486. if (this.root == null) {
  10487. this.root = leaf;
  10488. return;
  10489. }
  10490. var lb = leaf.aabb;
  10491. var sibling = this.root;
  10492. var oldArea;
  10493. var newArea;
  10494. while (sibling.proxy == null) { // descend the node to search the best pair
  10495. var c1 = sibling.child1;
  10496. var c2 = sibling.child2;
  10497. var b = sibling.aabb;
  10498. var c1b = c1.aabb;
  10499. var c2b = c2.aabb;
  10500. oldArea = b.surfaceArea();
  10501. this.aabb.combine(lb, b);
  10502. newArea = this.aabb.surfaceArea();
  10503. var creatingCost = newArea * 2;
  10504. var incrementalCost = (newArea - oldArea) * 2; // cost of creating a new pair with the node
  10505. var discendingCost1 = incrementalCost;
  10506. this.aabb.combine(lb, c1b);
  10507. if (c1.proxy != null) {
  10508. // leaf cost = area(combined aabb)
  10509. discendingCost1 += this.aabb.surfaceArea();
  10510. } else {
  10511. // node cost = area(combined aabb) - area(old aabb)
  10512. discendingCost1 += this.aabb.surfaceArea() - c1b.surfaceArea();
  10513. }
  10514. var discendingCost2 = incrementalCost;
  10515. this.aabb.combine(lb, c2b);
  10516. if (c2.proxy != null) {
  10517. // leaf cost = area(combined aabb)
  10518. discendingCost2 += this.aabb.surfaceArea();
  10519. } else {
  10520. // node cost = area(combined aabb) - area(old aabb)
  10521. discendingCost2 += this.aabb.surfaceArea() - c2b.surfaceArea();
  10522. }
  10523. if (discendingCost1 < discendingCost2) {
  10524. if (creatingCost < discendingCost1) {
  10525. break;// stop descending
  10526. } else {
  10527. sibling = c1;// descend into first child
  10528. }
  10529. } else {
  10530. if (creatingCost < discendingCost2) {
  10531. break;// stop descending
  10532. } else {
  10533. sibling = c2;// descend into second child
  10534. }
  10535. }
  10536. }
  10537. var oldParent = sibling.parent;
  10538. var newParent;
  10539. if (this.numFreeNodes > 0) {
  10540. newParent = this.freeNodes[--this.numFreeNodes];
  10541. } else {
  10542. newParent = new OIMO.DBVTNode();
  10543. }
  10544. newParent.parent = oldParent;
  10545. newParent.child1 = leaf;
  10546. newParent.child2 = sibling;
  10547. newParent.aabb.combine(leaf.aabb, sibling.aabb);
  10548. newParent.height = sibling.height + 1;
  10549. sibling.parent = newParent;
  10550. leaf.parent = newParent;
  10551. if (sibling == this.root) {
  10552. // replace root
  10553. this.root = newParent;
  10554. } else {
  10555. // replace child
  10556. if (oldParent.child1 == sibling) {
  10557. oldParent.child1 = newParent;
  10558. } else {
  10559. oldParent.child2 = newParent;
  10560. }
  10561. }
  10562. // update whole tree
  10563. do {
  10564. newParent = this.balance(newParent);
  10565. this.fix(newParent);
  10566. newParent = newParent.parent;
  10567. } while (newParent != null);
  10568. },
  10569. getBalance: function (node) {
  10570. if (node.proxy != null) return 0;
  10571. return node.child1.height - node.child2.height;
  10572. },
  10573. /*print:function(node,indent,text){
  10574. var hasChild=node.proxy==null;
  10575. if(hasChild)text=this.print(node.child1,indent+1,text);
  10576. for(var i=indent*2;i>=0;i--){
  10577. text+=" ";
  10578. }
  10579. text+=(hasChild?this.getBalance(node):"["+node.proxy.aabb.minX+"]")+"\n";
  10580. if(hasChild)text=this.print(node.child2,indent+1,text);
  10581. return text;
  10582. },*/
  10583. /**
  10584. * Delete a leaf from the tree.
  10585. * @param node
  10586. */
  10587. deleteLeaf: function (leaf) {
  10588. if (leaf == this.root) {
  10589. this.root = null;
  10590. return;
  10591. }
  10592. var parent = leaf.parent;
  10593. var sibling;
  10594. if (parent.child1 == leaf) {
  10595. sibling = parent.child2;
  10596. } else {
  10597. sibling = parent.child1;
  10598. }
  10599. if (parent == this.root) {
  10600. this.root = sibling;
  10601. sibling.parent = null;
  10602. return;
  10603. }
  10604. var grandParent = parent.parent;
  10605. sibling.parent = grandParent;
  10606. if (grandParent.child1 == parent) {
  10607. grandParent.child1 = sibling;
  10608. } else {
  10609. grandParent.child2 = sibling;
  10610. }
  10611. if (this.numFreeNodes < 16384) {
  10612. this.freeNodes[this.numFreeNodes++] = parent;
  10613. }
  10614. do {
  10615. grandParent = this.balance(grandParent);
  10616. this.fix(grandParent);
  10617. grandParent = grandParent.parent;
  10618. } while (grandParent != null);
  10619. },
  10620. balance: function (node) {
  10621. var nh = node.height;
  10622. if (nh < 2) {
  10623. return node;
  10624. }
  10625. var p = node.parent;
  10626. var l = node.child1;
  10627. var r = node.child2;
  10628. var lh = l.height;
  10629. var rh = r.height;
  10630. var balance = lh - rh;
  10631. var t;// for bit operation
  10632. // [ N ]
  10633. // / \
  10634. // [ L ] [ R ]
  10635. // / \ / \
  10636. // [L-L] [L-R] [R-L] [R-R]
  10637. // Is the tree balanced?
  10638. if (balance > 1) {
  10639. var ll = l.child1;
  10640. var lr = l.child2;
  10641. var llh = ll.height;
  10642. var lrh = lr.height;
  10643. // Is L-L higher than L-R?
  10644. if (llh > lrh) {
  10645. // set N to L-R
  10646. l.child2 = node;
  10647. node.parent = l;
  10648. // [ L ]
  10649. // / \
  10650. // [L-L] [ N ]
  10651. // / \ / \
  10652. // [...] [...] [ L ] [ R ]
  10653. // set L-R
  10654. node.child1 = lr;
  10655. lr.parent = node;
  10656. // [ L ]
  10657. // / \
  10658. // [L-L] [ N ]
  10659. // / \ / \
  10660. // [...] [...] [L-R] [ R ]
  10661. // fix bounds and heights
  10662. node.aabb.combine(lr.aabb, r.aabb);
  10663. t = lrh - rh;
  10664. node.height = lrh - (t & t >> 31) + 1;
  10665. l.aabb.combine(ll.aabb, node.aabb);
  10666. t = llh - nh;
  10667. l.height = llh - (t & t >> 31) + 1;
  10668. } else {
  10669. // set N to L-L
  10670. l.child1 = node;
  10671. node.parent = l;
  10672. // [ L ]
  10673. // / \
  10674. // [ N ] [L-R]
  10675. // / \ / \
  10676. // [ L ] [ R ] [...] [...]
  10677. // set L-L
  10678. node.child1 = ll;
  10679. ll.parent = node;
  10680. // [ L ]
  10681. // / \
  10682. // [ N ] [L-R]
  10683. // / \ / \
  10684. // [L-L] [ R ] [...] [...]
  10685. // fix bounds and heights
  10686. node.aabb.combine(ll.aabb, r.aabb);
  10687. t = llh - rh;
  10688. node.height = llh - (t & t >> 31) + 1;
  10689. l.aabb.combine(node.aabb, lr.aabb);
  10690. t = nh - lrh;
  10691. l.height = nh - (t & t >> 31) + 1;
  10692. }
  10693. // set new parent of L
  10694. if (p != null) {
  10695. if (p.child1 == node) {
  10696. p.child1 = l;
  10697. } else {
  10698. p.child2 = l;
  10699. }
  10700. } else {
  10701. this.root = l;
  10702. }
  10703. l.parent = p;
  10704. return l;
  10705. } else if (balance < -1) {
  10706. var rl = r.child1;
  10707. var rr = r.child2;
  10708. var rlh = rl.height;
  10709. var rrh = rr.height;
  10710. // Is R-L higher than R-R?
  10711. if (rlh > rrh) {
  10712. // set N to R-R
  10713. r.child2 = node;
  10714. node.parent = r;
  10715. // [ R ]
  10716. // / \
  10717. // [R-L] [ N ]
  10718. // / \ / \
  10719. // [...] [...] [ L ] [ R ]
  10720. // set R-R
  10721. node.child2 = rr;
  10722. rr.parent = node;
  10723. // [ R ]
  10724. // / \
  10725. // [R-L] [ N ]
  10726. // / \ / \
  10727. // [...] [...] [ L ] [R-R]
  10728. // fix bounds and heights
  10729. node.aabb.combine(l.aabb, rr.aabb);
  10730. t = lh - rrh;
  10731. node.height = lh - (t & t >> 31) + 1;
  10732. r.aabb.combine(rl.aabb, node.aabb);
  10733. t = rlh - nh;
  10734. r.height = rlh - (t & t >> 31) + 1;
  10735. } else {
  10736. // set N to R-L
  10737. r.child1 = node;
  10738. node.parent = r;
  10739. // [ R ]
  10740. // / \
  10741. // [ N ] [R-R]
  10742. // / \ / \
  10743. // [ L ] [ R ] [...] [...]
  10744. // set R-L
  10745. node.child2 = rl;
  10746. rl.parent = node;
  10747. // [ R ]
  10748. // / \
  10749. // [ N ] [R-R]
  10750. // / \ / \
  10751. // [ L ] [R-L] [...] [...]
  10752. // fix bounds and heights
  10753. node.aabb.combine(l.aabb, rl.aabb);
  10754. t = lh - rlh;
  10755. node.height = lh - (t & t >> 31) + 1;
  10756. r.aabb.combine(node.aabb, rr.aabb);
  10757. t = nh - rrh;
  10758. r.height = nh - (t & t >> 31) + 1;
  10759. }
  10760. // set new parent of R
  10761. if (p != null) {
  10762. if (p.child1 == node) {
  10763. p.child1 = r;
  10764. } else {
  10765. p.child2 = r;
  10766. }
  10767. } else {
  10768. this.root = r;
  10769. }
  10770. r.parent = p;
  10771. return r;
  10772. }
  10773. return node;
  10774. },
  10775. fix: function (node) {
  10776. var c1 = node.child1;
  10777. var c2 = node.child2;
  10778. node.aabb.combine(c1.aabb, c2.aabb);
  10779. //var h1 = c1.height;
  10780. //var h2 = c2.height;
  10781. node.height = c1.height < c2.height ? c2.height + 1 : c1.height + 1;
  10782. /*if( h1 < h2 ) {
  10783. node.height = h2+1;
  10784. }else{
  10785. node.height = h1+1;
  10786. }*/
  10787. }
  10788. }
  10789. /**
  10790. * A broad-phase algorithm using dynamic bounding volume tree.
  10791. * @author saharan
  10792. * @author lo-th
  10793. */
  10794. OIMO.DBVTBroadPhase = function () {
  10795. OIMO.BroadPhase.call(this);
  10796. this.types = OIMO.BR_BOUNDING_VOLUME_TREE;
  10797. this.tree = new OIMO.DBVT();
  10798. this.stack = [];
  10799. this.leaves = [];
  10800. this.numLeaves = 0;
  10801. };
  10802. OIMO.DBVTBroadPhase.prototype = Object.create(OIMO.BroadPhase.prototype);
  10803. OIMO.DBVTBroadPhase.prototype.constructor = OIMO.DBVTBroadPhase;
  10804. OIMO.DBVTBroadPhase.prototype.createProxy = function (shape) {
  10805. return new OIMO.DBVTProxy(shape);
  10806. };
  10807. OIMO.DBVTBroadPhase.prototype.addProxy = function (proxy) {
  10808. this.tree.insertLeaf(proxy.leaf);
  10809. this.leaves.push(proxy.leaf);
  10810. this.numLeaves++;
  10811. };
  10812. OIMO.DBVTBroadPhase.prototype.removeProxy = function (proxy) {
  10813. this.tree.deleteLeaf(proxy.leaf);
  10814. var n = this.leaves.indexOf(proxy.leaf);
  10815. if (n > -1) {
  10816. this.leaves.splice(n, 1);
  10817. this.numLeaves--;
  10818. }
  10819. };
  10820. OIMO.DBVTBroadPhase.prototype.collectPairs = function () {
  10821. if (this.numLeaves < 2) return;
  10822. var leaf, margin = 0.1, i = this.numLeaves;
  10823. while (i--) {
  10824. leaf = this.leaves[i];
  10825. if (leaf.proxy.aabb.intersectTestTwo(leaf.aabb)) {
  10826. leaf.aabb.copy(leaf.proxy.aabb, margin);
  10827. this.tree.deleteLeaf(leaf);
  10828. this.tree.insertLeaf(leaf);
  10829. this.collide(leaf, this.tree.root);
  10830. }
  10831. }
  10832. };
  10833. OIMO.DBVTBroadPhase.prototype.collide = function (node1, node2) {
  10834. var stackCount = 2;
  10835. var s1, s2, n1, n2, l1, l2;
  10836. this.stack[0] = node1;
  10837. this.stack[1] = node2;
  10838. while (stackCount > 0) {
  10839. n1 = this.stack[--stackCount];
  10840. n2 = this.stack[--stackCount];
  10841. l1 = n1.proxy != null;
  10842. l2 = n2.proxy != null;
  10843. this.numPairChecks++;
  10844. if (l1 && l2) {
  10845. s1 = n1.proxy.shape;
  10846. s2 = n2.proxy.shape;
  10847. if (s1 == s2 || s1.aabb.intersectTest(s2.aabb) || !this.isAvailablePair(s1, s2)) continue;
  10848. this.addPair(s1, s2);
  10849. } else {
  10850. if (n1.aabb.intersectTest(n2.aabb)) continue;
  10851. /*if(stackCount+4>=this.maxStack){// expand the stack
  10852. //this.maxStack<<=1;
  10853. this.maxStack*=2;
  10854. var newStack = [];// vector
  10855. newStack.length = this.maxStack;
  10856. for(var i=0;i<stackCount;i++){
  10857. newStack[i] = this.stack[i];
  10858. }
  10859. this.stack = newStack;
  10860. }*/
  10861. if (l2 || !l1 && (n1.aabb.surfaceArea() > n2.aabb.surfaceArea())) {
  10862. this.stack[stackCount++] = n1.child1;
  10863. this.stack[stackCount++] = n2;
  10864. this.stack[stackCount++] = n1.child2;
  10865. this.stack[stackCount++] = n2;
  10866. } else {
  10867. this.stack[stackCount++] = n1;
  10868. this.stack[stackCount++] = n2.child1;
  10869. this.stack[stackCount++] = n1;
  10870. this.stack[stackCount++] = n2.child2;
  10871. }
  10872. }
  10873. }
  10874. };
  10875. /**
  10876. * A node of the dynamic bounding volume tree.
  10877. * @author saharan
  10878. */
  10879. OIMO.DBVTNode = function () {
  10880. // The first child node of this node.
  10881. this.child1 = null;
  10882. // The second child node of this node.
  10883. this.child2 = null;
  10884. // The parent node of this tree.
  10885. this.parent = null;
  10886. // The proxy of this node. This has no value if this node is not leaf.
  10887. this.proxy = null;
  10888. // The maximum distance from leaf nodes.
  10889. this.height = 0;
  10890. // The AABB of this node.
  10891. this.aabb = new OIMO.AABB();
  10892. };
  10893. /**
  10894. * A proxy for dynamic bounding volume tree broad-phase.
  10895. * @author saharan
  10896. */
  10897. OIMO.DBVTProxy = function (shape) {
  10898. OIMO.Proxy.call(this, shape);
  10899. // The leaf of the proxy.
  10900. this.leaf = new OIMO.DBVTNode();
  10901. this.leaf.proxy = this;
  10902. };
  10903. OIMO.DBVTProxy.prototype = Object.create(OIMO.Proxy.prototype);
  10904. OIMO.DBVTProxy.prototype.constructor = OIMO.DBVTProxy;
  10905. OIMO.DBVTProxy.prototype.update = function () {
  10906. };
  10907. OIMO.World.prototype.add = function (obj) {
  10908. obj = obj || {};
  10909. var type = obj.type || "box";
  10910. if (typeof type === 'string') type = [type];// single shape
  10911. if (type[0].substring(0, 5) == 'joint') { // is joint
  10912. if (type[0] === 'joint') type[0] = 'jointHinge';
  10913. var axe1 = obj.axe1 || [1, 0, 0];
  10914. var axe2 = obj.axe2 || [1, 0, 0];
  10915. var pos1 = obj.pos1 || [0, 0, 0];
  10916. var pos2 = obj.pos2 || [0, 0, 0];
  10917. pos1 = pos1.map(function (x) { return x * OIMO.INV_SCALE; });
  10918. pos2 = pos2.map(function (x) { return x * OIMO.INV_SCALE; });
  10919. var min, max;
  10920. if (type[0] === "jointDistance") {
  10921. min = obj.min || 0;
  10922. max = obj.max || 10;
  10923. min = min * OIMO.INV_SCALE;
  10924. max = max * OIMO.INV_SCALE;
  10925. } else {
  10926. min = obj.min || 57.29578;
  10927. max = obj.max || 0;
  10928. min = min * OIMO.degtorad;
  10929. max = max * OIMO.degtorad;
  10930. }
  10931. var limit = obj.limit || null;
  10932. var spring = obj.spring || null;
  10933. var motor = obj.motor || null;
  10934. // joint setting
  10935. var jc = new OIMO.JointConfig();
  10936. jc.allowCollision = obj.collision || false;;
  10937. jc.localAxis1.init(axe1[0], axe1[1], axe1[2]);
  10938. jc.localAxis2.init(axe2[0], axe2[1], axe2[2]);
  10939. jc.localAnchorPoint1.init(pos1[0], pos1[1], pos1[2]);
  10940. jc.localAnchorPoint2.init(pos2[0], pos2[1], pos2[2]);
  10941. if (typeof obj.body1 == 'string' || obj.body1 instanceof String) obj.body1 = this.getByName(obj.body1);
  10942. if (typeof obj.body2 == 'string' || obj.body2 instanceof String) obj.body2 = this.getByName(obj.body2);
  10943. jc.body1 = obj.body1;
  10944. jc.body2 = obj.body2;
  10945. var joint;
  10946. switch (type[0]) {
  10947. case "jointDistance": joint = new OIMO.DistanceJoint(jc, min, max);
  10948. if (spring !== null) joint.limitMotor.setSpring(spring[0], spring[1]);
  10949. if (motor !== null) joint.limitMotor.setSpring(motor[0], motor[1]);
  10950. break;
  10951. case "jointHinge": joint = new OIMO.HingeJoint(jc, min, max);
  10952. if (spring !== null) joint.limitMotor.setSpring(spring[0], spring[1]);// soften the joint ex: 100, 0.2
  10953. if (motor !== null) joint.limitMotor.setSpring(motor[0], motor[1]);
  10954. break;
  10955. case "jointPrisme": joint = new OIMO.PrismaticJoint(jc, min, max); break;
  10956. case "jointSlide": joint = new OIMO.SliderJoint(jc, min, max); break;
  10957. case "jointBall": joint = new OIMO.BallAndSocketJoint(jc); break;
  10958. case "jointWheel": joint = new OIMO.WheelJoint(jc);
  10959. if (limit !== null) joint.rotationalLimitMotor1.setLimit(limit[0], limit[1]);
  10960. if (spring !== null) joint.rotationalLimitMotor1.setSpring(spring[0], spring[1]);
  10961. if (motor !== null) joint.rotationalLimitMotor1.setSpring(motor[0], motor[1]);
  10962. break;
  10963. }
  10964. joint.name = obj.name || '';
  10965. // finaly add to physics world
  10966. this.addJoint(joint);
  10967. return joint;
  10968. } else { // is body
  10969. // I'm dynamique or not
  10970. var move = obj.move || false;
  10971. // I can sleep or not
  10972. var noSleep = obj.noSleep || false;
  10973. // My start position
  10974. var p = obj.pos || [0, 0, 0];
  10975. p = p.map(function (x) { return x * OIMO.INV_SCALE; });
  10976. // My size
  10977. var s = obj.size || [1, 1, 1];
  10978. s = s.map(function (x) { return x * OIMO.INV_SCALE; });
  10979. // My rotation in degre
  10980. var rot = obj.rot || [0, 0, 0];
  10981. rot = rot.map(function (x) { return x * OIMO.degtorad; });
  10982. var r = [];
  10983. for (var i = 0; i < rot.length / 3; i++) {
  10984. var tmp = OIMO.EulerToAxis(rot[i + 0], rot[i + 1], rot[i + 2]);
  10985. r.push(tmp[0]); r.push(tmp[1]); r.push(tmp[2]); r.push(tmp[3]);
  10986. }
  10987. // My physics setting
  10988. var sc = new OIMO.ShapeConfig();
  10989. if (obj.sc !== undefined) sc = obj.sc;
  10990. if (obj.config) {
  10991. // The density of the shape.
  10992. sc.density = obj.config[0] === undefined ? 1 : obj.config[0];
  10993. // The coefficient of friction of the shape.
  10994. sc.friction = obj.config[1] === undefined ? 0.4 : obj.config[1];
  10995. // The coefficient of restitution of the shape.
  10996. sc.restitution = obj.config[2] === undefined ? 0.2 : obj.config[2];
  10997. // The bits of the collision groups to which the shape belongs.
  10998. sc.belongsTo = obj.config[3] || 1;
  10999. //sc.belongsTo = obj.config[3] === undefined ? 1 : obj.config[3];
  11000. // The bits of the collision groups with which the shape collides.
  11001. sc.collidesWith = obj.config[4] || 0xffffffff;
  11002. //sc.collidesWith = obj.config[4] === undefined ? 0xffffffff : obj.config[4];
  11003. }
  11004. // direct physics setting
  11005. if (obj.density !== undefined) sc.density = obj.density;
  11006. if (obj.friction !== undefined) sc.friction = obj.friction;
  11007. if (obj.restitution !== undefined) sc.restitution = obj.restitution;
  11008. if (obj.belongsTo !== undefined) sc.belongsTo = obj.belongsTo;
  11009. if (obj.collidesWith !== undefined) sc.collidesWith = obj.collidesWith;
  11010. if (obj.massPos) {
  11011. obj.massPos = obj.massPos.map(function (x) { return x * OIMO.INV_SCALE; });
  11012. sc.relativePosition.init(obj.massPos[0], obj.massPos[1], obj.massPos[2]);
  11013. }
  11014. if (obj.massRot) {
  11015. obj.massRot = obj.massRot.map(function (x) { return x * OIMO.degtorad; });
  11016. sc.relativeRotation = OIMO.EulerToMatrix(obj.massRot[0], obj.massRot[1], obj.massRot[2]);
  11017. }
  11018. // My rigidbody
  11019. var body = new OIMO.RigidBody(p[0], p[1], p[2], r[0], r[1], r[2], r[3]);
  11020. // My shapes
  11021. var shapes = [];
  11022. //if( typeof type === 'string' ) type = [type];// single shape
  11023. var n, n2;
  11024. for (var i = 0; i < type.length; i++) {
  11025. n = i * 3;
  11026. n2 = i * 4;
  11027. switch (type[i]) {
  11028. case "sphere": shapes[i] = new OIMO.SphereShape(sc, s[n]); break;
  11029. case "cylinder": shapes[i] = new OIMO.CylinderShape(sc, s[n], s[n + 1]); break;
  11030. case "box": shapes[i] = new OIMO.BoxShape(sc, s[n], s[n + 1], s[n + 2]); break;
  11031. }
  11032. body.addShape(shapes[i]);
  11033. if (i > 0) {
  11034. //shapes[i].position.init(p[0]+p[n+0], p[1]+p[n+1], p[2]+p[n+2] );
  11035. shapes[i].relativePosition = new OIMO.Vec3(p[n], p[n + 1], p[n + 2]);
  11036. if (r[n2 + 0]) shapes[i].relativeRotation = [r[n2], r[n2 + 1], r[n2 + 2], r[n2 + 3]];
  11037. }
  11038. }
  11039. // I'm static or i move
  11040. if (move) {
  11041. if (obj.massPos || obj.massRot) body.setupMass(0x1, false);
  11042. else body.setupMass(0x1, true);
  11043. if (noSleep) body.allowSleep = false;
  11044. else body.allowSleep = true;
  11045. } else {
  11046. body.setupMass(0x2);
  11047. }
  11048. body.name = obj.name || ' ';
  11049. // finaly add to physics world
  11050. this.addRigidBody(body);
  11051. return body;
  11052. }
  11053. }
  11054. //UMD simplified
  11055. var root = this;
  11056. if (!root['OIMO']) {
  11057. if (typeof exports === 'object' && typeof module === 'object')
  11058. module.exports = OIMO;
  11059. else if (typeof define === 'function' && define.amd)
  11060. define([], function () {
  11061. return OIMO;
  11062. });
  11063. else if (typeof exports === 'object')
  11064. exports["OIMO"] = OIMO;
  11065. else {
  11066. root["OIMO"] = OIMO;
  11067. }
  11068. }