Oimo.js 414 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835108361083710838108391084010841108421084310844108451084610847108481084910850108511085210853108541085510856108571085810859108601086110862108631086410865108661086710868108691087010871108721087310874108751087610877108781087910880108811088210883108841088510886108871088810889108901089110892108931089410895108961089710898108991090010901109021090310904109051090610907109081090910910109111091210913109141091510916109171091810919109201092110922109231092410925109261092710928109291093010931109321093310934109351093610937109381093910940109411094210943109441094510946109471094810949109501095110952109531095410955109561095710958109591096010961109621096310964109651096610967109681096910970109711097210973109741097510976109771097810979109801098110982109831098410985109861098710988109891099010991109921099310994109951099610997109981099911000110011100211003110041100511006110071100811009110101101111012110131101411015110161101711018110191102011021110221102311024110251102611027110281102911030110311103211033110341103511036110371103811039110401104111042110431104411045110461104711048110491105011051110521105311054110551105611057110581105911060110611106211063110641106511066110671106811069110701107111072110731107411075110761107711078110791108011081110821108311084110851108611087110881108911090110911109211093110941109511096110971109811099111001110111102111031110411105111061110711108111091111011111111121111311114111151111611117111181111911120111211112211123111241112511126111271112811129111301113111132111331113411135111361113711138111391114011141111421114311144111451114611147111481114911150111511115211153111541115511156111571115811159111601116111162111631116411165111661116711168111691117011171111721117311174111751117611177111781117911180111811118211183111841118511186111871118811189111901119111192111931119411195111961119711198111991120011201112021120311204112051120611207112081120911210112111121211213112141121511216112171121811219112201122111222112231122411225112261122711228112291123011231112321123311234112351123611237112381123911240112411124211243112441124511246112471124811249112501125111252112531125411255112561125711258112591126011261112621126311264112651126611267112681126911270112711127211273112741127511276112771127811279112801128111282112831128411285112861128711288112891129011291112921129311294112951129611297112981129911300113011130211303113041130511306113071130811309113101131111312113131131411315113161131711318113191132011321113221132311324113251132611327113281132911330113311133211333113341133511336113371133811339113401134111342113431134411345113461134711348113491135011351113521135311354113551135611357113581135911360113611136211363113641136511366113671136811369113701137111372113731137411375113761137711378113791138011381113821138311384113851138611387113881138911390113911139211393113941139511396113971139811399114001140111402114031140411405114061140711408114091141011411114121141311414114151141611417114181141911420114211142211423114241142511426114271142811429114301143111432114331143411435114361143711438114391144011441114421144311444114451144611447114481144911450114511145211453114541145511456114571145811459114601146111462114631146411465114661146711468114691147011471114721147311474114751147611477114781147911480114811148211483114841148511486114871148811489114901149111492114931149411495114961149711498114991150011501115021150311504115051150611507115081150911510115111151211513115141151511516115171151811519115201152111522115231152411525115261152711528115291153011531115321153311534115351153611537115381153911540115411154211543115441154511546115471154811549115501155111552115531155411555115561155711558115591156011561115621156311564115651156611567115681156911570115711157211573115741157511576115771157811579115801158111582115831158411585115861158711588115891159011591115921159311594115951159611597115981159911600116011160211603116041160511606116071160811609116101161111612116131161411615116161161711618116191162011621116221162311624116251162611627116281162911630116311163211633116341163511636116371163811639116401164111642116431164411645116461164711648116491165011651116521165311654116551165611657116581165911660116611166211663116641166511666116671166811669116701167111672116731167411675116761167711678116791168011681116821168311684116851168611687116881168911690116911169211693116941169511696116971169811699117001170111702117031170411705117061170711708117091171011711117121171311714117151171611717117181171911720117211172211723117241172511726117271172811729117301173111732117331173411735117361173711738117391174011741117421174311744117451174611747117481174911750117511175211753117541175511756117571175811759117601176111762117631176411765117661176711768117691177011771117721177311774117751177611777117781177911780117811178211783117841178511786117871178811789117901179111792117931179411795117961179711798117991180011801118021180311804118051180611807118081180911810118111181211813118141181511816118171181811819118201182111822118231182411825118261182711828118291183011831118321183311834118351183611837118381183911840118411184211843118441184511846118471184811849118501185111852118531185411855118561185711858118591186011861118621186311864118651186611867118681186911870118711187211873118741187511876118771187811879118801188111882118831188411885118861188711888118891189011891118921189311894118951189611897118981189911900119011190211903119041190511906119071190811909119101191111912119131191411915119161191711918119191192011921119221192311924119251192611927119281192911930119311193211933119341193511936119371193811939119401194111942119431194411945119461194711948119491195011951119521195311954119551195611957119581195911960119611196211963119641196511966119671196811969119701197111972119731197411975119761197711978119791198011981119821198311984119851198611987119881198911990119911199211993119941199511996119971199811999120001200112002120031200412005120061200712008120091201012011120121201312014120151201612017120181201912020120211202212023120241202512026120271202812029120301203112032120331203412035120361203712038120391204012041120421204312044120451204612047120481204912050120511205212053120541205512056120571205812059120601206112062120631206412065120661206712068120691207012071120721207312074120751207612077120781207912080120811208212083120841208512086120871208812089120901209112092120931209412095120961209712098120991210012101121021210312104121051210612107121081210912110121111211212113121141211512116121171211812119121201212112122121231212412125121261212712128121291213012131121321213312134121351213612137121381213912140121411214212143121441214512146121471214812149121501215112152121531215412155121561215712158121591216012161121621216312164121651216612167121681216912170121711217212173121741217512176121771217812179121801218112182121831218412185121861218712188121891219012191121921219312194121951219612197121981219912200122011220212203122041220512206122071220812209122101221112212122131221412215122161221712218122191222012221122221222312224122251222612227122281222912230122311223212233122341223512236122371223812239122401224112242122431224412245122461224712248122491225012251122521225312254122551225612257122581225912260122611226212263122641226512266122671226812269122701227112272122731227412275122761227712278122791228012281122821228312284122851228612287122881228912290122911229212293122941229512296122971229812299123001230112302123031230412305123061230712308123091231012311123121231312314123151231612317123181231912320123211232212323123241232512326123271232812329123301233112332123331233412335123361233712338123391234012341123421234312344123451234612347123481234912350123511235212353123541235512356123571235812359123601236112362123631236412365123661236712368123691237012371123721237312374123751237612377123781237912380123811238212383123841238512386123871238812389123901239112392123931239412395123961239712398123991240012401124021240312404124051240612407124081240912410124111241212413124141241512416124171241812419124201242112422124231242412425124261242712428124291243012431124321243312434124351243612437124381243912440124411244212443124441244512446124471244812449124501245112452124531245412455124561245712458124591246012461124621246312464124651246612467124681246912470124711247212473124741247512476124771247812479124801248112482124831248412485124861248712488124891249012491124921249312494124951249612497124981249912500125011250212503125041250512506125071250812509125101251112512
  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. }