Oimo.js 302 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595
  1. /**
  2. * OimoPhysics DEV 1.1.0a
  3. * @author Saharan / http://el-ement.com/
  4. *
  5. * Oimo.js 2014
  6. * @author LoTh / http://3dflashlo.wordpress.com/
  7. */
  8. var OIMO = { REVISION: 'DEV.1.1.2a' };
  9. OIMO.SHAPE_SPHERE = 0x1;
  10. OIMO.SHAPE_BOX = 0x2;
  11. OIMO.WORLD_SCALE = 1;
  12. OIMO.INV_SCALE = 1;
  13. OIMO.TO_RAD = Math.PI / 180;
  14. OIMO.TwoPI = 2.0 * Math.PI;
  15. // Global identification of next shape.
  16. // This will be incremented every time a shape is created.
  17. OIMO.nextID = 0;
  18. var OIMO_ARRAY_TYPE;
  19. if(!OIMO_ARRAY_TYPE) { OIMO_ARRAY_TYPE = typeof Float32Array !== 'undefined' ? Float32Array : Array; }
  20. /**
  21. * The class of physical computing world.
  22. * You must be added to the world physical all computing objects
  23. * @author saharan
  24. */
  25. OIMO.World = function(TimeStep, BroadPhaseType, Iterations, NoStat){
  26. // The time between each step
  27. this.timeStep= TimeStep || 1/60;
  28. // The number of iterations for constraint solvers.
  29. this.numIterations = Iterations || 8;
  30. // It is a wide-area collision judgment that is used in order to reduce as much as possible a detailed collision judgment.
  31. var broadPhaseType = BroadPhaseType || 2;
  32. switch(broadPhaseType){
  33. case 1: this.broadPhase=new OIMO.BruteForceBroadPhase(); break;
  34. case 2: default: this.broadPhase=new OIMO.SAPBroadPhase(); break;
  35. case 3: this.broadPhase=new OIMO.DBVTBroadPhase(); break;
  36. }
  37. // Whether the constraints randomizer is enabled or not.
  38. this.enableRandomizer = true;
  39. this.isNoStat = NoStat || false;
  40. // The rigid body list
  41. this.rigidBodies=null;
  42. // number of rigid body
  43. this.numRigidBodies=0;
  44. // The contact list
  45. this.contacts=null;
  46. this.unusedContacts=null;
  47. // The number of contact
  48. this.numContacts=0;
  49. // The number of contact points
  50. this.numContactPoints=0;
  51. // The joint list
  52. this.joints=null;
  53. // The number of joints.
  54. this.numJoints=0;
  55. // The number of simulation islands.
  56. this.numIslands=0;
  57. // The gravity in the world.
  58. this.gravity=new OIMO.Vec3(0,-9.80665,0);
  59. // This is the detailed information of the performance.
  60. this.performance = null;
  61. if(!this.isNoStat) this.performance = new OIMO.Performance(this);
  62. var numShapeTypes=3;
  63. this.detectors=[];
  64. this.detectors.length = numShapeTypes;
  65. var i=numShapeTypes;
  66. while(i--){
  67. this.detectors[i]=[];
  68. this.detectors[i].length = numShapeTypes;
  69. }
  70. this.detectors[OIMO.SHAPE_SPHERE][OIMO.SHAPE_SPHERE]=new OIMO.SphereSphereCollisionDetector();
  71. this.detectors[OIMO.SHAPE_SPHERE][OIMO.SHAPE_BOX]=new OIMO.SphereBoxCollisionDetector(false);
  72. this.detectors[OIMO.SHAPE_BOX][OIMO.SHAPE_SPHERE]=new OIMO.SphereBoxCollisionDetector(true);
  73. this.detectors[OIMO.SHAPE_BOX][OIMO.SHAPE_BOX]=new OIMO.BoxBoxCollisionDetector();
  74. this.randX=65535;
  75. this.randA=98765;
  76. this.randB=123456789;
  77. this.maxIslandRigidBodies=64;
  78. this.islandRigidBodies=[];
  79. this.islandRigidBodies.length = this.maxIslandRigidBodies;
  80. this.islandStack=[];
  81. this.islandStack.length = this.maxIslandRigidBodies;
  82. this.maxIslandConstraints=128;
  83. this.islandConstraints=[];
  84. this.islandConstraints.length = this.maxIslandConstraints;
  85. };
  86. OIMO.World.prototype = {
  87. constructor: OIMO.World,
  88. /**
  89. * Reset the randomizer and remove all rigid bodies, shapes, joints and any object from the world.
  90. */
  91. clear:function(){
  92. this.randX=65535;
  93. while(this.joints!==null){
  94. this.removeJoint(this.joints);
  95. }
  96. while(this.contacts!==null){
  97. this.removeContact(this.contacts);
  98. }
  99. while(this.rigidBodies!==null){
  100. this.removeRigidBody(this.rigidBodies);
  101. }
  102. OIMO.nextID=0;
  103. },
  104. /**
  105. * I'll add a rigid body to the world.
  106. * Rigid body that has been added will be the operands of each step.
  107. * @param rigidBody Rigid body that you want to add
  108. */
  109. addRigidBody:function(rigidBody){
  110. if(rigidBody.parent){
  111. throw new Error("It is not possible to be added to more than one world one of the rigid body");
  112. }
  113. rigidBody.parent=this;
  114. rigidBody.awake();
  115. for(var shape=rigidBody.shapes; shape!==null; shape=shape.next){
  116. this.addShape(shape);
  117. }
  118. if(this.rigidBodies!==null)(this.rigidBodies.prev=rigidBody).next=this.rigidBodies;
  119. this.rigidBodies = rigidBody;
  120. this.numRigidBodies++;
  121. },
  122. /**
  123. * I will remove the rigid body from the world.
  124. * Rigid body that has been deleted is excluded from the calculation on a step-by-step basis.
  125. * @param rigidBody Rigid body to be removed
  126. */
  127. removeRigidBody:function(rigidBody){
  128. var remove=rigidBody;
  129. if(remove.parent!==this)return;
  130. remove.awake();
  131. var js=remove.jointLink;
  132. while(js!=null){
  133. var joint=js.joint;
  134. js=js.next;
  135. this.removeJoint(joint);
  136. }
  137. for(var shape=rigidBody.shapes; shape!==null; shape=shape.next){
  138. this.removeShape(shape);
  139. }
  140. var prev=remove.prev;
  141. var next=remove.next;
  142. if(prev!==null) prev.next=next;
  143. if(next!==null) next.prev=prev;
  144. if(this.rigidBodies==remove) this.rigidBodies=next;
  145. remove.prev=null;
  146. remove.next=null;
  147. remove.parent=null;
  148. this.numRigidBodies--;
  149. },
  150. getByName:function(name){
  151. var result = null;
  152. var body=this.rigidBodies;
  153. while(body!==null){
  154. if(body.name!== " " && body.name === name) result = body;
  155. body=body.next;
  156. }
  157. var joint=this.joints;
  158. while(joint!==null){
  159. if(joint.name!== "" && joint.name === name) result = joint;
  160. joint=joint.next;
  161. }
  162. return result;
  163. },
  164. /**
  165. * I'll add a shape to the world..
  166. * Add to the rigid world, and if you add a shape to a rigid body that has been added to the world,
  167. * Shape will be added to the world automatically, please do not call from outside this method.
  168. * @param shape Shape you want to add
  169. */
  170. addShape:function(shape){
  171. if(!shape.parent || !shape.parent.parent){
  172. throw new Error("It is not possible to be added alone to shape world");
  173. }
  174. shape.proxy = this.broadPhase.createProxy(shape);
  175. shape.updateProxy();
  176. this.broadPhase.addProxy(shape.proxy);
  177. },
  178. /**
  179. * I will remove the shape from the world.
  180. * Add to the rigid world, and if you add a shape to a rigid body that has been added to the world,
  181. * Shape will be added to the world automatically, please do not call from outside this method.
  182. * @param shape Shape you want to delete
  183. */
  184. removeShape:function(shape){
  185. this.broadPhase.removeProxy(shape.proxy);
  186. shape.proxy=null;
  187. },
  188. /**
  189. * I'll add a joint to the world.
  190. * Joint that has been added will be the operands of each step.
  191. * @param shape Joint to be added
  192. */
  193. addJoint:function(joint){
  194. if(joint.parent){
  195. throw new Error("It is not possible to be added to more than one world one of the joint");
  196. }
  197. if(this.joints!=null)(this.joints.prev=joint).next=this.joints;
  198. this.joints=joint;
  199. joint.parent=this;
  200. this.numJoints++;
  201. joint.awake();
  202. joint.attach();
  203. },
  204. /**
  205. * I will remove the joint from the world.
  206. * Joint that has been added will be the operands of each step.
  207. * @param shape Joint to be deleted
  208. */
  209. removeJoint:function(joint){
  210. var remove=joint;
  211. var prev=remove.prev;
  212. var next=remove.next;
  213. if(prev!==null)prev.next=next;
  214. if(next!==null)next.prev=prev;
  215. if(this.joints==remove)this.joints=next;
  216. remove.prev=null;
  217. remove.next=null;
  218. this.numJoints--;
  219. remove.awake();
  220. remove.detach();
  221. remove.parent=null;
  222. },
  223. worldscale:function(scale){
  224. OIMO.WORLD_SCALE = scale || 100;
  225. OIMO.INV_SCALE = 1/OIMO.WORLD_SCALE;
  226. },
  227. /**
  228. * I will proceed only time step seconds time of World.
  229. */
  230. step:function(){
  231. var time0, time1, time2, time3;
  232. if(!this.isNoStat) time0=Date.now();
  233. var body=this.rigidBodies;
  234. while(body!==null){
  235. body.addedToIsland=false;
  236. if(body.sleeping){
  237. if( body.linearVelocity.testZero() || body.position.testDiff(body.sleepPosition) || body.orientation.testDiff(body.sleepOrientation)){ body.awake(); } // awake the body
  238. /*var lv=body.linearVelocity;
  239. var av=body.linearVelocity;
  240. var p=body.position;
  241. var sp=body.sleepPosition;
  242. var o=body.orientation;
  243. var so=body.sleepOrientation;
  244. if( lv.x!==0 || lv.y!==0 || lv.z!==0 || av.x!==0 || av.y!==0 || av.z!==0 ||
  245. p.x!==sp.x || p.y!==sp.y || p.z!==sp.z ||
  246. o.s!==so.s || o.x!==so.x || o.y!==so.y || o.z!==so.z
  247. ){ body.awake(); }*/
  248. }
  249. body=body.next;
  250. }
  251. //------------------------------------------------------
  252. // UPDATE CONTACT
  253. //------------------------------------------------------
  254. // broad phase
  255. if(!this.isNoStat) time1=Date.now();
  256. this.broadPhase.detectPairs();
  257. var pairs=this.broadPhase.pairs;
  258. var numPairs=this.broadPhase.numPairs;
  259. var i = numPairs;
  260. //do{
  261. while(i--){
  262. //for(var i=0, l=numPairs; i<l; i++){
  263. var pair=pairs[i];
  264. var s1;
  265. var s2;
  266. if(pair.shape1.id<pair.shape2.id){
  267. s1=pair.shape1;
  268. s2=pair.shape2;
  269. }else{
  270. s1=pair.shape2;
  271. s2=pair.shape1;
  272. }
  273. var link;
  274. if(s1.numContacts<s2.numContacts){
  275. link=s1.contactLink;
  276. }else{
  277. link=s2.contactLink;
  278. }
  279. var exists=false;
  280. while(link){
  281. var contact=link.contact;
  282. if(contact.shape1==s1&&contact.shape2==s2){
  283. contact.persisting=true;
  284. exists=true;// contact already exists
  285. break;
  286. }
  287. link=link.next;
  288. }
  289. if(!exists){
  290. this.addContact(s1,s2);
  291. }
  292. }// while(i-- >0);
  293. if(!this.isNoStat){
  294. time2=Date.now();
  295. this.performance.broadPhaseTime=time2-time1;
  296. }
  297. // update & narrow phase
  298. this.numContactPoints=0;
  299. contact=this.contacts;
  300. while(contact!==null){
  301. if(!contact.persisting){
  302. var aabb1=contact.shape1.aabb;
  303. var aabb2=contact.shape2.aabb;
  304. if(
  305. aabb1.minX>aabb2.maxX || aabb1.maxX<aabb2.minX ||
  306. aabb1.minY>aabb2.maxY || aabb1.maxY<aabb2.minY ||
  307. aabb1.minZ>aabb2.maxZ || aabb1.maxZ<aabb2.minZ
  308. ){
  309. var next=contact.next;
  310. this.removeContact(contact);
  311. contact=next;
  312. continue;
  313. }
  314. }
  315. var b1=contact.body1;
  316. var b2=contact.body2;
  317. if(b1.isDynamic && !b1.sleeping || b2.isDynamic && !b2.sleeping){
  318. contact.updateManifold();
  319. }
  320. this.numContactPoints+=contact.manifold.numPoints;
  321. contact.persisting=false;
  322. contact.constraint.addedToIsland=false;
  323. contact=contact.next;
  324. }
  325. if(!this.isNoStat){
  326. time3=Date.now();
  327. this.performance.narrowPhaseTime=time3-time2;
  328. }
  329. //------------------------------------------------------
  330. // SOLVE ISLANDS
  331. //------------------------------------------------------
  332. var invTimeStep=1/this.timeStep;
  333. //var body;
  334. var joint;
  335. var constraint;
  336. var num;
  337. for(joint=this.joints; joint!==null; joint=joint.next){
  338. joint.addedToIsland=false;
  339. }
  340. // expand island buffers
  341. if(this.maxIslandRigidBodies<this.numRigidBodies){
  342. this.maxIslandRigidBodies=this.numRigidBodies<<1;
  343. //this.maxIslandRigidBodies=this.numRigidBodies*2;
  344. this.islandRigidBodies=[];
  345. this.islandStack=[];
  346. this.islandRigidBodies.length = this.maxIslandRigidBodies;
  347. this.islandStack.length = this.maxIslandRigidBodies;
  348. }
  349. var numConstraints=this.numJoints+this.numContacts;
  350. if(this.maxIslandConstraints<numConstraints){
  351. this.maxIslandConstraints=numConstraints<<1;
  352. //this.maxIslandConstraints=numConstraints*2;
  353. this.islandConstraints=[];
  354. this.islandConstraints.length = this.maxIslandConstraints;
  355. }
  356. time1=Date.now();
  357. this.numIslands=0;
  358. // build and solve simulation islands
  359. for(var base=this.rigidBodies; base!==null; base=base.next){
  360. if(base.addedToIsland || base.isStatic || base.sleeping){
  361. continue;// ignore
  362. }
  363. if(base.isLonely()){// update single body
  364. if(base.isDynamic){
  365. base.linearVelocity.addTime(this.gravity, this.timeStep);
  366. /*base.linearVelocity.x+=this.gravity.x*this.timeStep;
  367. base.linearVelocity.y+=this.gravity.y*this.timeStep;
  368. base.linearVelocity.z+=this.gravity.z*this.timeStep;*/
  369. }
  370. if(this.calSleep(base)){
  371. base.sleepTime+=this.timeStep;
  372. if(base.sleepTime>0.5){
  373. base.sleep();
  374. }else{
  375. base.updatePosition(this.timeStep);
  376. }
  377. }else{
  378. base.sleepTime=0;
  379. base.updatePosition(this.timeStep);
  380. }
  381. this.numIslands++;
  382. continue;
  383. }
  384. var islandNumRigidBodies=0;
  385. var islandNumConstraints=0;
  386. var stackCount=1;
  387. // add rigid body to stack
  388. this.islandStack[0]=base;
  389. base.addedToIsland=true;
  390. // build an island
  391. do{
  392. // get rigid body from stack
  393. body=this.islandStack[--stackCount];
  394. this.islandStack[stackCount]=null;
  395. body.sleeping=false;
  396. // add rigid body to the island
  397. this.islandRigidBodies[islandNumRigidBodies++]=body;
  398. if(body.isStatic){
  399. continue;
  400. }
  401. // search connections
  402. for(var cs=body.contactLink; cs!==null; cs=cs.next){
  403. var contact=cs.contact;
  404. constraint=contact.constraint;
  405. if(constraint.addedToIsland||!contact.touching){
  406. continue;// ignore
  407. }
  408. // add constraint to the island
  409. this.islandConstraints[islandNumConstraints++]=constraint;
  410. constraint.addedToIsland=true;
  411. var next=cs.body;
  412. if(next.addedToIsland){
  413. continue;
  414. }
  415. // add rigid body to stack
  416. this.islandStack[stackCount++]=next;
  417. next.addedToIsland=true;
  418. }
  419. for(var js=body.jointLink; js!==null; js=js.next){
  420. constraint=js.joint;
  421. if(constraint.addedToIsland){
  422. continue;// ignore
  423. }
  424. // add constraint to the island
  425. this.islandConstraints[islandNumConstraints++]=constraint;
  426. constraint.addedToIsland=true;
  427. next=js.body;
  428. if(next.addedToIsland || !next.isDynamic){
  429. continue;
  430. }
  431. // add rigid body to stack
  432. this.islandStack[stackCount++]=next;
  433. next.addedToIsland=true;
  434. }
  435. }while(stackCount!=0);
  436. // update velocities
  437. var gVel = new OIMO.Vec3().addTime(this.gravity, this.timeStep);
  438. /*var gx=this.gravity.x*this.timeStep;
  439. var gy=this.gravity.y*this.timeStep;
  440. var gz=this.gravity.z*this.timeStep;*/
  441. var j = islandNumRigidBodies;
  442. while (j--){
  443. //or(var j=0, l=islandNumRigidBodies; j<l; j++){
  444. body=this.islandRigidBodies[j];
  445. if(body.isDynamic){
  446. body.linearVelocity.addEqual(gVel);
  447. /*body.linearVelocity.x+=gx;
  448. body.linearVelocity.y+=gy;
  449. body.linearVelocity.z+=gz;*/
  450. }
  451. }
  452. // randomizing order
  453. if(this.enableRandomizer){
  454. //for(var j=1, l=islandNumConstraints; j<l; j++){
  455. j = islandNumConstraints;
  456. while(j--){ if(j!==0){
  457. var swap=(this.randX=(this.randX*this.randA+this.randB&0x7fffffff))/2147483648.0*j|0;
  458. constraint=this.islandConstraints[j];
  459. this.islandConstraints[j]=this.islandConstraints[swap];
  460. this.islandConstraints[swap]=constraint;
  461. }
  462. }
  463. }
  464. // solve contraints
  465. j = islandNumConstraints;
  466. while(j--){
  467. //for(j=0, l=islandNumConstraints; j<l; j++){
  468. this.islandConstraints[j].preSolve(this.timeStep,invTimeStep);// pre-solve
  469. }
  470. var k = this.numIterations;
  471. while(k--){
  472. //for(var k=0, l=this.numIterations; k<l; k++){
  473. j = islandNumConstraints;
  474. while(j--){
  475. //for(j=0, m=islandNumConstraints; j<m; j++){
  476. this.islandConstraints[j].solve();// main-solve
  477. }
  478. }
  479. j = islandNumConstraints;
  480. while(j--){
  481. //for(j=0, l=islandNumConstraints; j<l; j++){
  482. this.islandConstraints[j].postSolve();// post-solve
  483. this.islandConstraints[j]=null;// gc
  484. }
  485. // sleeping check
  486. var sleepTime=10;
  487. j = islandNumRigidBodies;
  488. while(j--){
  489. //for(j=0, l=islandNumRigidBodies;j<l;j++){
  490. body=this.islandRigidBodies[j];
  491. if(this.calSleep(body)){
  492. body.sleepTime+=this.timeStep;
  493. if(body.sleepTime<sleepTime)sleepTime=body.sleepTime;
  494. }else{
  495. body.sleepTime=0;
  496. sleepTime=0;
  497. continue;
  498. }
  499. }
  500. if(sleepTime>0.5){
  501. // sleep the island
  502. j = islandNumRigidBodies;
  503. while(j--){
  504. //for(j=0, l=islandNumRigidBodies;j<l;j++){
  505. this.islandRigidBodies[j].sleep();
  506. this.islandRigidBodies[j]=null;// gc
  507. }
  508. }else{
  509. // update positions
  510. j = islandNumRigidBodies;
  511. while(j--){
  512. //for(j=0, l=islandNumRigidBodies;j<l;j++){
  513. this.islandRigidBodies[j].updatePosition(this.timeStep);
  514. this.islandRigidBodies[j]=null;// gc
  515. }
  516. }
  517. this.numIslands++;
  518. }
  519. if(!this.isNoStat){
  520. time2=Date.now();
  521. this.performance.solvingTime=time2-time1;
  522. //------------------------------------------------------
  523. // END SIMULATION
  524. //------------------------------------------------------
  525. time2=Date.now();
  526. // fps update
  527. this.performance.upfps();
  528. this.performance.totalTime=time2-time0;
  529. this.performance.updatingTime=this.performance.totalTime-(this.performance.broadPhaseTime+this.performance.narrowPhaseTime+this.performance.solvingTime);
  530. }
  531. },
  532. addContact:function(s1,s2){
  533. var newContact;
  534. if(this.unusedContacts!==null){
  535. newContact=this.unusedContacts;
  536. this.unusedContacts=this.unusedContacts.next;
  537. }else{
  538. newContact = new OIMO.Contact();
  539. }
  540. newContact.attach(s1,s2);
  541. newContact.detector=this.detectors[s1.type][s2.type];
  542. if(this.contacts)(this.contacts.prev=newContact).next=this.contacts;
  543. this.contacts=newContact;
  544. this.numContacts++;
  545. },
  546. removeContact:function(contact){
  547. var prev=contact.prev;
  548. var next=contact.next;
  549. if(next)next.prev=prev;
  550. if(prev)prev.next=next;
  551. if(this.contacts==contact)this.contacts=next;
  552. contact.prev=null;
  553. contact.next=null;
  554. contact.detach();
  555. contact.next=this.unusedContacts;
  556. this.unusedContacts=contact;
  557. this.numContacts--;
  558. },
  559. checkContact:function(name1, name2){
  560. var n1, n2;
  561. var contact = this.contacts;
  562. while(contact!==null){
  563. n1 = contact.body1.name || ' ';
  564. n2 = contact.body2.name || ' ';
  565. if((n1==name1 && n2==name2) || (n2==name1 && n1==name2)){ if(contact.touching) return true; else return false;}
  566. else contact = contact.next;
  567. }
  568. return false;
  569. },
  570. calSleep:function(body){
  571. if(!body.allowSleep)return false;
  572. if(body.linearVelocity.len()>0.04)return false;
  573. if(body.angularVelocity.len()>0.25)return false;
  574. /*var v=body.linearVelocity;
  575. if(v.x*v.x+v.y*v.y+v.z*v.z>0.04){return false;}
  576. v=body.angularVelocity;
  577. if(v.x*v.x+v.y*v.y+v.z*v.z>0.25){return false;}*/
  578. return true;
  579. }
  580. }
  581. /**
  582. * The class of rigid body.
  583. * Rigid body has the shape of a single or multiple collision processing,
  584. * I can set the parameters individually.
  585. * @author saharan
  586. */
  587. OIMO.RigidBody = function(X,Y,Z,Rad,Ax,Ay,Az){
  588. var rad = Rad || 0;
  589. var ax = Ax || 0;
  590. var ay = Ay || 0;
  591. var az = Az || 0;
  592. var x = X || 0;
  593. var y = Y || 0;
  594. var z = Z || 0;
  595. this.name = " ";
  596. // It is a kind of rigid body that represents the dynamic rigid body.
  597. this.BODY_DYNAMIC=0x1;
  598. // It is a kind of rigid body that represents the static rigid body.
  599. this.BODY_STATIC=0x2;
  600. // The maximum number of shapes that can be added to a one rigid.
  601. this.MAX_SHAPES=64;
  602. this.prev=null;
  603. this.next=null;
  604. // I represent the kind of rigid body.
  605. // Please do not change from the outside this variable.
  606. // If you want to change the type of rigid body, always
  607. // Please specify the type you want to set the arguments of setupMass method.
  608. this.type=0;
  609. this.massInfo= new OIMO.MassInfo();
  610. // It is the world coordinate of the center of gravity.
  611. this.position=new OIMO.Vec3(x,y,z);
  612. this.newPosition = new OIMO.Vec3(0,0,0);
  613. this.controlPos = false;
  614. this.newOrientation = new OIMO.Quat();
  615. this.newRotation = new OIMO.Vec3(0,0,0);
  616. this.currentRotation = new OIMO.Vec3(0,0,0);
  617. this.controlRot = false;
  618. this.controlRotInTime = false;
  619. this.orientation = this.rotationAxisToQuad(rad,ax,ay,az);
  620. /*var len=ax*ax+ay*ay+az*az;
  621. if(len>0){
  622. len=1/Math.sqrt(len);
  623. ax*=len;
  624. ay*=len;
  625. az*=len;
  626. }
  627. var sin=Math.sin(rad*0.5);
  628. var cos=Math.cos(rad*0.5);*/
  629. // It is a quaternion that represents the attitude.
  630. //this.orientation = new OIMO.Quat(cos,sin*ax,sin*ay,sin*az);
  631. // Is the translational velocity.
  632. this.linearVelocity = new OIMO.Vec3();
  633. // Is the angular velocity.
  634. this.angularVelocity = new OIMO.Vec3();
  635. // return matrix for three.js
  636. this.matrix = new OIMO.Mat44();
  637. //--------------------------------------------
  638. // Please do not change from the outside this variables.
  639. //--------------------------------------------
  640. // It is a world that rigid body has been added.
  641. this.parent=null;
  642. this.contactLink=null;
  643. this.numContacts=0;
  644. // An array of shapes that are included in the rigid body.
  645. this.shapes=null;
  646. // The number of shapes that are included in the rigid body.
  647. this.numShapes=0;
  648. // It is the link array of joint that is connected to the rigid body.
  649. this.jointLink=null;
  650. // The number of joints that are connected to the rigid body.
  651. this.numJoints=0;
  652. // It is the world coordinate of the center of gravity in the sleep just before.
  653. this.sleepPosition=new OIMO.Vec3();
  654. // It is a quaternion that represents the attitude of sleep just before.
  655. this.sleepOrientation=new OIMO.Quat();
  656. // I will show this rigid body to determine whether it is a rigid body static.
  657. this.isStatic=false;
  658. // I indicates that this rigid body to determine whether it is a rigid body dynamic.
  659. this.isDynamic=false;
  660. // It is a rotation matrix representing the orientation.
  661. this.rotation=new OIMO.Mat33();
  662. //--------------------------------------------
  663. // It will be recalculated automatically from the shape, which is included.
  664. //--------------------------------------------
  665. // This is the weight.
  666. this.mass=NaN;
  667. // It is the reciprocal of the mass.
  668. this.inverseMass=NaN;
  669. // It is the inverse of the inertia tensor in the world system.
  670. this.inverseInertia=new OIMO.Mat33();
  671. // It is the inertia tensor in the initial state.
  672. this.localInertia=new OIMO.Mat33();
  673. // It is the inverse of the inertia tensor in the initial state.
  674. this.inverseLocalInertia=new OIMO.Mat33();
  675. // I indicates rigid body whether it has been added to the simulation Island.
  676. this.addedToIsland=false;
  677. // It shows how to sleep rigid body.
  678. this.allowSleep=true;
  679. // This is the time from when the rigid body at rest.
  680. this.sleepTime=0;
  681. // I shows rigid body to determine whether it is a sleep state.
  682. this.sleeping=false;
  683. }
  684. OIMO.RigidBody.prototype = {
  685. constructor: OIMO.RigidBody,
  686. /**
  687. * I'll add a shape to rigid body.
  688. * If you add a shape, please call the setupMass method to step up to the start of the next.
  689. * @param shape shape to Add
  690. */
  691. addShape:function(shape){
  692. if(shape.parent){
  693. throw new Error("It is not possible that you add to the multi-rigid body the shape of one");
  694. }
  695. if(this.shapes!=null)(this.shapes.prev=shape).next=this.shapes;
  696. this.shapes=shape;
  697. shape.parent=this;
  698. if(this.parent)this.parent.addShape(shape);
  699. this.numShapes++;
  700. },
  701. /**
  702. * I will delete the shape from the rigid body.
  703. * If you delete a shape, please call the setupMass method to step up to the start of the next.
  704. * @param shape shape to Delete
  705. */
  706. removeShape:function(shape){
  707. var remove=shape;
  708. if(remove.parent!=this)return;
  709. var prev=remove.prev;
  710. var next=remove.next;
  711. if(prev!=null)prev.next=next;
  712. if(next!=null)next.prev=prev;
  713. if(this.shapes==remove)this.shapes=next;
  714. remove.prev=null;
  715. remove.next=null;
  716. remove.parent=null;
  717. if(this.parent)this.parent.removeShape(remove);
  718. this.numShapes--;
  719. },
  720. /**
  721. * Calulates mass datas(center of gravity, mass, moment inertia, etc...).
  722. * If the parameter type is set to BODY_STATIC, the rigid body will be fixed to the space.
  723. * If the parameter adjustPosition is set to true, the shapes' relative positions and
  724. * the rigid body's position will be adjusted to the center of gravity.
  725. * @param type
  726. * @param adjustPosition
  727. */
  728. setupMass:function(Type,AdjustPosition){
  729. var adjustPosition = ( AdjustPosition !== undefined ) ? AdjustPosition : true;
  730. var type = Type || this.BODY_DYNAMIC;
  731. //var te = this.localInertia.elements;
  732. this.type=type;
  733. this.isDynamic=type==this.BODY_DYNAMIC;
  734. this.isStatic=type==this.BODY_STATIC;
  735. this.mass=0;
  736. this.localInertia.init(0,0,0,0,0,0,0,0,0);
  737. var te = this.localInertia.elements;
  738. //
  739. var tmpM=new OIMO.Mat33();
  740. var tmpV=new OIMO.Vec3();
  741. for(var shape=this.shapes;shape!=null;shape=shape.next){
  742. shape.calculateMassInfo(this.massInfo);
  743. var shapeMass=this.massInfo.mass;
  744. var relX=shape.relativePosition.x;
  745. var relY=shape.relativePosition.y;
  746. var relZ=shape.relativePosition.z;
  747. /*tmpV.x+=relX*shapeMass;
  748. tmpV.y+=relY*shapeMass;
  749. tmpV.z+=relZ*shapeMass;*/
  750. tmpV.addScale(shape.relativePosition, shapeMass);
  751. this.mass+=shapeMass;
  752. this.rotateInertia(shape.relativeRotation,this.massInfo.inertia,tmpM);
  753. this.localInertia.addEqual(tmpM);
  754. // add offset inertia
  755. te[0]+=shapeMass*(relY*relY+relZ*relZ);
  756. te[4]+=shapeMass*(relX*relX+relZ*relZ);
  757. te[8]+=shapeMass*(relX*relX+relY*relY);
  758. var xy=shapeMass*relX*relY;
  759. var yz=shapeMass*relY*relZ;
  760. var zx=shapeMass*relZ*relX;
  761. te[1]-=xy;
  762. te[3]-=xy;
  763. te[2]-=yz;
  764. te[6]-=yz;
  765. te[5]-=zx;
  766. te[7]-=zx;
  767. }
  768. this.inverseMass=1/this.mass;
  769. tmpV.scaleEqual(this.inverseMass);
  770. if(adjustPosition){
  771. this.position.addEqual(tmpV);
  772. for(shape=this.shapes;shape!=null;shape=shape.next){
  773. shape.relativePosition.subEqual(tmpV);
  774. }
  775. // subtract offset inertia
  776. relX=tmpV.x;
  777. relY=tmpV.y;
  778. relZ=tmpV.z;
  779. //var te = this.localInertia.elements;
  780. te[0]-=this.mass*(relY*relY+relZ*relZ);
  781. te[4]-=this.mass*(relX*relX+relZ*relZ);
  782. te[8]-=this.mass*(relX*relX+relY*relY);
  783. xy=this.mass*relX*relY;
  784. yz=this.mass*relY*relZ;
  785. zx=this.mass*relZ*relX;
  786. te[1]+=xy;
  787. te[3]+=xy;
  788. te[2]+=yz;
  789. te[6]+=yz;
  790. te[5]+=zx;
  791. te[7]+=zx;
  792. }
  793. this.inverseLocalInertia.invert(this.localInertia);
  794. if(type==this.BODY_STATIC){
  795. this.inverseMass=0;
  796. this.inverseLocalInertia.init(0,0,0,0,0,0,0,0,0);
  797. }
  798. this.syncShapes();
  799. this.awake();
  800. },
  801. /**
  802. * Awake the rigid body.
  803. */
  804. awake:function(){
  805. if(!this.allowSleep||!this.sleeping)return;
  806. this.sleeping=false;
  807. this.sleepTime=0;
  808. // awake connected constraints
  809. var cs=this.contactLink;
  810. while(cs!=null){
  811. cs.body.sleepTime=0;
  812. cs.body.sleeping=false;
  813. cs=cs.next;
  814. }
  815. var js=this.jointLink;
  816. while(js!=null){
  817. js.body.sleepTime=0;
  818. js.body.sleeping=false;
  819. js=js.next;
  820. }
  821. for(var shape=this.shapes;shape!=null;shape=shape.next){
  822. shape.updateProxy();
  823. }
  824. },
  825. /**
  826. * Sleep the rigid body.
  827. */
  828. sleep:function(){
  829. if(!this.allowSleep||this.sleeping)return;
  830. this.linearVelocity.init();
  831. this.angularVelocity.init();
  832. this.sleepPosition.copy(this.position);
  833. this.sleepOrientation.copy(this.orientation);
  834. /*this.linearVelocity.x=0;
  835. this.linearVelocity.y=0;
  836. this.linearVelocity.z=0;
  837. this.angularVelocity.x=0;
  838. this.angularVelocity.y=0;
  839. this.angularVelocity.z=0;
  840. this.sleepPosition.x=this.position.x;
  841. this.sleepPosition.y=this.position.y;
  842. this.sleepPosition.z=this.position.z;*/
  843. /*this.sleepOrientation.s=this.orientation.s;
  844. this.sleepOrientation.x=this.orientation.x;
  845. this.sleepOrientation.y=this.orientation.y;
  846. this.sleepOrientation.z=this.orientation.z;*/
  847. this.sleepTime=0;
  848. this.sleeping=true;
  849. for(var shape=this.shapes;shape!=null;shape=shape.next){
  850. shape.updateProxy();
  851. }
  852. },
  853. /**
  854. * Get whether the rigid body has not any connection with others.
  855. * @return
  856. */
  857. isLonely:function(){
  858. return this.numJoints==0&&this.numContacts==0;
  859. },
  860. /**
  861. * The time integration of the motion of a rigid body, you can update the information such as the shape.
  862. * This method is invoked automatically when calling the step of the World,
  863. * There is no need to call from outside usually.
  864. * @param timeStep time
  865. */
  866. updatePosition:function(timeStep){
  867. switch(this.type){
  868. case this.BODY_STATIC:
  869. this.linearVelocity.init();
  870. this.angularVelocity.init();
  871. // ONLY FOR TEST
  872. if(this.controlPos){
  873. this.position.copy(this.newPosition);
  874. this.controlPos = false;
  875. }
  876. if(this.controlRot){
  877. this.orientation.copy(this.newOrientation);
  878. this.controlRot = false;
  879. }
  880. /*this.linearVelocity.x=0;
  881. this.linearVelocity.y=0;
  882. this.linearVelocity.z=0;
  883. this.angularVelocity.x=0;
  884. this.angularVelocity.y=0;
  885. this.angularVelocity.z=0;*/
  886. break;
  887. case this.BODY_DYNAMIC:
  888. if(this.controlPos){
  889. this.angularVelocity.init();
  890. this.linearVelocity.init();
  891. this.linearVelocity.x = (this.newPosition.x - this.position.x)/timeStep;
  892. this.linearVelocity.y = (this.newPosition.y - this.position.y)/timeStep;
  893. this.linearVelocity.z = (this.newPosition.z - this.position.z)/timeStep;
  894. this.controlPos = false;
  895. }
  896. if(this.controlRot){
  897. this.angularVelocity.init();
  898. this.orientation.copy(this.newOrientation);
  899. //var t=timeStep//*0.5;
  900. //var q = new OIMO.Quat();
  901. //q.sub(this.newOrientation, this.orientation);
  902. //q.normalize(q);
  903. /*q.s = (this.newOrientation.s - this.orientation.s)/t;
  904. q.x = (this.newOrientation.x - this.orientation.x)/t;
  905. q.y = (this.newOrientation.y - this.orientation.y)/t;
  906. q.z = (this.newOrientation.z - this.orientation.z)/t;*/
  907. //this.angularVelocity.applyQuaternion(q);
  908. //this.angularVelocity.x = this.angularVelocity.x/t;
  909. //this.angularVelocity.y = this.angularVelocity.y/t;
  910. //this.angularVelocity.z = this.angularVelocity.z/t;
  911. this.controlRot = false;
  912. }
  913. this.position.addTime(this.linearVelocity, timeStep);
  914. this.orientation.addTime(this.angularVelocity, timeStep);
  915. break;
  916. default:
  917. throw new Error("Invalid type.");
  918. }
  919. this.syncShapes();
  920. },
  921. rotateInertia:function(rot,inertia,out){
  922. var tm1 = rot.elements;
  923. var tm2 = inertia.elements;
  924. var a0 = tm1[0], a3 = tm1[3], a6 = tm1[6];
  925. var a1 = tm1[1], a4 = tm1[4], a7 = tm1[7];
  926. var a2 = tm1[2], a5 = tm1[5], a8 = tm1[8];
  927. var b0 = tm2[0], b3 = tm2[3], b6 = tm2[6];
  928. var b1 = tm2[1], b4 = tm2[4], b7 = tm2[7];
  929. var b2 = tm2[2], b5 = tm2[5], b8 = tm2[8];
  930. var e00 = a0*b0 + a1*b3 + a2*b6;
  931. var e01 = a0*b1 + a1*b4 + a2*b7;
  932. var e02 = a0*b2 + a1*b5 + a2*b8;
  933. var e10 = a3*b0 + a4*b3 + a5*b6;
  934. var e11 = a3*b1 + a4*b4 + a5*b7;
  935. var e12 = a3*b2 + a4*b5 + a5*b8;
  936. var e20 = a6*b0 + a7*b3 + a8*b6;
  937. var e21 = a6*b1 + a7*b4 + a8*b7;
  938. var e22 = a6*b2 + a7*b5 + a8*b8;
  939. var oe = out.elements;
  940. oe[0] = e00*a0 + e01*a1 + e02*a2;
  941. oe[1] = e00*a3 + e01*a4 + e02*a5;
  942. oe[2] = e00*a6 + e01*a7 + e02*a8;
  943. oe[3] = e10*a0 + e11*a1 + e12*a2;
  944. oe[4] = e10*a3 + e11*a4 + e12*a5;
  945. oe[5] = e10*a6 + e11*a7 + e12*a8;
  946. oe[6] = e20*a0 + e21*a1 + e22*a2;
  947. oe[7] = e20*a3 + e21*a4 + e22*a5;
  948. oe[8] = e20*a6 + e21*a7 + e22*a8;
  949. },
  950. syncShapes:function(){
  951. var s=this.orientation.s;
  952. var x=this.orientation.x;
  953. var y=this.orientation.y;
  954. var z=this.orientation.z;
  955. var x2=2*x;
  956. var y2=2*y;
  957. var z2=2*z;
  958. var xx=x*x2;
  959. var yy=y*y2;
  960. var zz=z*z2;
  961. var xy=x*y2;
  962. var yz=y*z2;
  963. var xz=x*z2;
  964. var sx=s*x2;
  965. var sy=s*y2;
  966. var sz=s*z2;
  967. var tr = this.rotation.elements;
  968. tr[0]=1-yy-zz;
  969. tr[1]=xy-sz;
  970. tr[2]=xz+sy;
  971. tr[3]=xy+sz;
  972. tr[4]=1-xx-zz;
  973. tr[5]=yz-sx;
  974. tr[6]=xz-sy;
  975. tr[7]=yz+sx;
  976. tr[8]=1-xx-yy;
  977. this.rotateInertia(this.rotation,this.inverseLocalInertia,this.inverseInertia);
  978. for(var shape=this.shapes;shape!=null;shape=shape.next){
  979. //var relPos=shape.relativePosition;
  980. //var relRot=shape.relativeRotation;
  981. //var rot=shape.rotation;
  982. /*var lx=relPos.x;
  983. var ly=relPos.y;
  984. var lz=relPos.z;
  985. shape.position.x=this.position.x+lx*tr[0]+ly*tr[1]+lz*tr[2];
  986. shape.position.y=this.position.y+lx*tr[3]+ly*tr[4]+lz*tr[5];
  987. shape.position.z=this.position.z+lx*tr[6]+ly*tr[7]+lz*tr[8];*/
  988. shape.position.mul(this.position,shape.relativePosition,this.rotation);
  989. shape.rotation.mul(shape.relativeRotation,this.rotation);
  990. shape.updateProxy();
  991. }
  992. },
  993. applyImpulse:function(position,force){
  994. this.linearVelocity.addScale(force, this.inverseMass);
  995. /*this.linearVelocity.x+=force.x*this.inverseMass;
  996. this.linearVelocity.y+=force.y*this.inverseMass;
  997. this.linearVelocity.z+=force.z*this.inverseMass;*/
  998. var rel=new OIMO.Vec3();
  999. rel.sub(position,this.position).cross(rel,force).mulMat(this.inverseInertia,rel);
  1000. this.angularVelocity.addEqual(rel);
  1001. /*this.angularVelocity.x+=rel.x;
  1002. this.angularVelocity.y+=rel.y;
  1003. this.angularVelocity.z+=rel.z;*/
  1004. },
  1005. //---------------------------------------------
  1006. //
  1007. // FOR THREE JS
  1008. //
  1009. //---------------------------------------------
  1010. rotationVectToQuad: function(rot){
  1011. var r = OIMO.EulerToAxis( rot.x * OIMO.TO_RAD, rot.y * OIMO.TO_RAD, rot.z * OIMO.TO_RAD );
  1012. return this.rotationAxisToQuad(r[0], r[1], r[2], r[3]);
  1013. },
  1014. rotationAxisToQuad: function(rad, ax, ay, az){ // in radian
  1015. var len=ax*ax+ay*ay+az*az;
  1016. if(len>0){
  1017. len=1/Math.sqrt(len);
  1018. ax*=len;
  1019. ay*=len;
  1020. az*=len;
  1021. }
  1022. var sin=Math.sin(rad*0.5);
  1023. var cos=Math.cos(rad*0.5);
  1024. return new OIMO.Quat(cos,sin*ax,sin*ay,sin*az);
  1025. },
  1026. //---------------------------------------------
  1027. // SET DYNAMIQUE POSITION AND ROTATION
  1028. //---------------------------------------------
  1029. setPosition:function(pos){
  1030. this.newPosition.init(pos.x*OIMO.INV_SCALE,pos.y*OIMO.INV_SCALE,pos.z*OIMO.INV_SCALE);
  1031. this.controlPos = true;
  1032. },
  1033. setQuaternion:function(q){
  1034. //if(this.type == this.BODY_STATIC)this.orientation.init(q.w,q.x,q.y,q.z);
  1035. this.newOrientation.init(q.w,q.x,q.y,q.z);
  1036. this.controlRot = true;
  1037. },
  1038. setRotation:function(rot){
  1039. this.newOrientation = this.rotationVectToQuad(rot);
  1040. this.controlRot = true;
  1041. },
  1042. //---------------------------------------------
  1043. // RESET DYNAMIQUE POSITION AND ROTATION
  1044. //---------------------------------------------
  1045. resetPosition:function(x,y,z){
  1046. this.linearVelocity.init();
  1047. this.angularVelocity.init();
  1048. this.position.init(x*OIMO.INV_SCALE,y*OIMO.INV_SCALE,z*OIMO.INV_SCALE);
  1049. this.awake();
  1050. },
  1051. resetQuaternion:function(q){
  1052. this.angularVelocity.init();
  1053. this.orientation = new OIMO.Quat(q.w,q.x,q.y,q.z);
  1054. this.awake();
  1055. },
  1056. resetRotation:function(x,y,z){
  1057. this.angularVelocity.init();
  1058. this.orientation = this.rotationVectToQuad(new OIMO.Vec3(x,y,z));
  1059. this.awake();
  1060. },
  1061. //---------------------------------------------
  1062. // GET POSITION AND ROTATION
  1063. //---------------------------------------------
  1064. getPosition:function(){
  1065. return new OIMO.Vec3().scale(this.position, OIMO.WORLD_SCALE);
  1066. },
  1067. getRotation:function(){
  1068. return new OIMO.Euler().setFromRotationMatrix(this.rotation);
  1069. },
  1070. getQuaternion:function(){
  1071. return new OIMO.Quaternion().setFromRotationMatrix(this.rotation);
  1072. },
  1073. getMatrix:function(){
  1074. var m = this.matrix.elements;
  1075. var r,p;
  1076. if(!this.sleeping){
  1077. // rotation matrix
  1078. r = this.rotation.elements;
  1079. m[0] = r[0]; m[1] = r[3]; m[2] = r[6]; m[3] = 0;
  1080. m[4] = r[1]; m[5] = r[4]; m[6] = r[7]; m[7] = 0;
  1081. m[8] = r[2]; m[9] = r[5]; m[10] = r[8]; m[11] = 0;
  1082. // position matrix
  1083. p = this.position;
  1084. m[12] = p.x*OIMO.WORLD_SCALE;
  1085. m[13] = p.y*OIMO.WORLD_SCALE;
  1086. m[14] = p.z*OIMO.WORLD_SCALE;
  1087. // sleep or not ?
  1088. m[15] = 0;
  1089. } else {
  1090. m[15] = 1;
  1091. }
  1092. return m;
  1093. }
  1094. }
  1095. /**
  1096. * The main class of body.
  1097. * is for simplify creation process and data access of rigidRody
  1098. * Rigid body has the shape of a single or multiple collision processing,
  1099. * all setting in object
  1100. *
  1101. * @author loth
  1102. */
  1103. OIMO.Body = function(Obj){
  1104. var obj = Obj || {};
  1105. if(!obj.world) return;
  1106. // the world where i am
  1107. this.parent = obj.world;
  1108. // Yep my name
  1109. this.name = obj.name || '';
  1110. // I'm dynamique or not
  1111. var move = obj.move || false;
  1112. // I can sleep or not
  1113. var noSleep = obj.noSleep || false;
  1114. // My start position
  1115. var p = obj.pos || [0,0,0];
  1116. p = p.map(function(x) { return x * OIMO.INV_SCALE; });
  1117. // My size
  1118. var s = obj.size || [1,1,1];
  1119. s = s.map(function(x) { return x * OIMO.INV_SCALE; });
  1120. // My rotation in degre
  1121. var rot = obj.rot || [0,0,0];
  1122. rot = rot.map(function(x) { return x * OIMO.TO_RAD; });
  1123. var r = [];
  1124. for (var i=0; i<rot.length/3; i++){
  1125. var tmp = OIMO.EulerToAxis(rot[i+0], rot[i+1], rot[i+2]);
  1126. r.push(tmp[0]); r.push(tmp[1]); r.push(tmp[2]); r.push(tmp[3]);
  1127. }
  1128. // My physics setting
  1129. var sc = obj.sc || new OIMO.ShapeConfig();
  1130. if(obj.config){
  1131. // The density of the shape.
  1132. sc.density = obj.config[0] || 1;
  1133. // The coefficient of friction of the shape.
  1134. sc.friction = obj.config[1] || 0.4;
  1135. // The coefficient of restitution of the shape.
  1136. sc.restitution = obj.config[2] || 0.2;
  1137. // The bits of the collision groups to which the shape belongs.
  1138. sc.belongsTo = obj.config[3] || 1;
  1139. // The bits of the collision groups with which the shape collides.
  1140. sc.collidesWith = obj.config[4] || 0xffffffff;
  1141. }
  1142. if(obj.massPos){
  1143. obj.massPos = obj.massPos.map(function(x) { return x * OIMO.INV_SCALE; });
  1144. sc.relativePosition.init(obj.massPos[0], obj.massPos[1], obj.massPos[2]);
  1145. }
  1146. if(obj.massRot){
  1147. obj.massRot = obj.massRot.map(function(x) { return x * OIMO.TO_RAD; });
  1148. sc.relativeRotation = OIMO.EulerToMatrix(obj.massRot[0], obj.massRot[1], obj.massRot[2]);
  1149. }
  1150. // My rigidbody
  1151. this.body = new OIMO.RigidBody(p[0], p[1], p[2], r[0], r[1], r[2], r[3]);
  1152. // My shapes
  1153. var shapes = [];
  1154. var type = obj.type || "box";
  1155. if( typeof type === 'string' ) type = [type];// single shape
  1156. var n, n2;
  1157. for(var i=0; i<type.length; i++){
  1158. n = i*3;
  1159. n2 = i*4;
  1160. switch(type[i]){
  1161. case "sphere": shapes[i] = new OIMO.SphereShape(sc, s[n+0]); break;
  1162. case "cylinder": shapes[i] = new OIMO.BoxShape(sc, s[n+0], s[n+1], s[n+2]); break; // fake cylinder
  1163. case "box": shapes[i] = new OIMO.BoxShape(sc, s[n+0], s[n+1], s[n+2]); break;
  1164. }
  1165. this.body.addShape(shapes[i]);
  1166. if(i>0){
  1167. //shapes[i].position.init(p[0]+p[n+0], p[1]+p[n+1], p[2]+p[n+2] );
  1168. shapes[i].relativePosition = new OIMO.Vec3( p[n+0], p[n+1], p[n+2] );
  1169. if(r[n2+0]) shapes[i].relativeRotation = [ r[n2+0], r[n2+1], r[n2+2], r[n2+3] ];
  1170. }
  1171. }
  1172. // I'm static or i move
  1173. if(move){
  1174. if(obj.massPos || obj.massRot)this.body.setupMass(0x1, false);
  1175. else this.body.setupMass(0x1, true);
  1176. if(noSleep) this.body.allowSleep = false;
  1177. else this.body.allowSleep = true;
  1178. } else {
  1179. this.body.setupMass(0x2);
  1180. }
  1181. this.body.name = this.name;
  1182. this.sleeping = this.body.sleeping;
  1183. // finaly add to physics world
  1184. this.parent.addRigidBody(this.body);
  1185. }
  1186. OIMO.Body.prototype = {
  1187. constructor: OIMO.Body,
  1188. // SET
  1189. setPosition:function(pos){
  1190. this.body.setPosition(pos);
  1191. },
  1192. setQuaternion:function(q){
  1193. this.body.setQuaternion(q);
  1194. },
  1195. setRotation:function(rot){
  1196. this.body.setRotation(rot);
  1197. },
  1198. // GET
  1199. getPosition:function(){
  1200. return this.body.getPosition();
  1201. },
  1202. getRotation:function(){
  1203. return this.body.getRotation();
  1204. },
  1205. getQuaternion:function(){
  1206. return this.body.getQuaternion();
  1207. },
  1208. getMatrix:function(){
  1209. return this.body.getMatrix();
  1210. },
  1211. getSleep:function(){
  1212. return this.body.sleeping;
  1213. },
  1214. // RESET
  1215. resetPosition:function(x,y,z){
  1216. this.body.resetPosition(x,y,z);
  1217. },
  1218. resetRotation:function(x,y,z){
  1219. this.body.resetRotation(x,y,z);
  1220. },
  1221. // force wakeup
  1222. awake:function(){
  1223. this.body.awake();
  1224. },
  1225. // remove rigidbody
  1226. remove:function(){
  1227. this.parent.removeRigidBody(this.body);
  1228. },
  1229. // test if this object hit another
  1230. checkContact:function(name){
  1231. this.parent.checkContact(this.name, name);
  1232. }
  1233. }
  1234. /**
  1235. * The main class of link.
  1236. * is for simplify creation process and data access of Joint
  1237. * all setting in object
  1238. *
  1239. * @author loth
  1240. */
  1241. OIMO.Link = function(Obj){
  1242. var obj = Obj || {};
  1243. if(!obj.world) return;
  1244. // the world where i am
  1245. this.parent = obj.world;
  1246. this.name = obj.name || '';
  1247. var type = obj.type || "jointHinge";
  1248. var axe1 = obj.axe1 || [1,0,0];
  1249. var axe2 = obj.axe2 || [1,0,0];
  1250. var pos1 = obj.pos1 || [0,0,0];
  1251. var pos2 = obj.pos2 || [0,0,0];
  1252. pos1 = pos1.map(function(x){ return x * OIMO.INV_SCALE; });
  1253. pos2 = pos2.map(function(x){ return x * OIMO.INV_SCALE; });
  1254. var min, max;
  1255. if(type==="jointDistance"){
  1256. min = obj.min || 0;
  1257. max = obj.max || 10;
  1258. min = min*OIMO.INV_SCALE;
  1259. max = max*OIMO.INV_SCALE;
  1260. }else{
  1261. min = obj.min || 57.29578;
  1262. max = obj.max || 0;
  1263. min = min*OIMO.TO_RAD;
  1264. max = max*OIMO.TO_RAD;
  1265. }
  1266. var limit = obj.limit || null;
  1267. var spring = obj.spring || null;
  1268. var motor = obj.motor || null;
  1269. // joint setting
  1270. var jc = new OIMO.JointConfig();
  1271. jc.allowCollision = obj.collision || false;;
  1272. jc.localAxis1.init(axe1[0], axe1[1], axe1[2]);
  1273. jc.localAxis2.init(axe2[0], axe2[1], axe2[2]);
  1274. jc.localAnchorPoint1.init(pos1[0], pos1[1], pos1[2]);
  1275. jc.localAnchorPoint2.init(pos2[0], pos2[1], pos2[2]);
  1276. if (typeof obj.body1 == 'string' || obj.body1 instanceof String) obj.body1 = obj.world.getByName(obj.body1);
  1277. if (typeof obj.body2 == 'string' || obj.body2 instanceof String) obj.body2 = obj.world.getByName(obj.body2);
  1278. jc.body1 = obj.body1;
  1279. jc.body2 = obj.body2;
  1280. switch(type){
  1281. case "jointDistance": this.joint = new OIMO.DistanceJoint(jc, min, max);
  1282. if(spring !== null) this.joint.limitMotor.setSpring(spring[0], spring[1]);
  1283. if(motor !== null) this.joint.limitMotor.setSpring(motor[0], motor[1]);
  1284. break;
  1285. case "jointHinge": this.joint = new OIMO.HingeJoint(jc, min, max);
  1286. if(spring !== null) this.joint.limitMotor.setSpring(spring[0], spring[1]);// soften the joint ex: 100, 0.2
  1287. if(motor !== null) this.joint.limitMotor.setSpring(motor[0], motor[1]);
  1288. break;
  1289. case "jointPrisme": this.joint = new OIMO.PrismaticJoint(jc, min, max); break;
  1290. case "jointSlide": this.joint = new OIMO.SliderJoint(jc, min, max); break;
  1291. case "jointBall": this.joint = new OIMO.BallAndSocketJoint(jc); break;
  1292. case "jointWheel": this.joint = new OIMO.WheelJoint(jc);
  1293. if(limit !== null) this.joint.rotationalLimitMotor1.setLimit(limit[0], limit[1]);
  1294. if(spring !== null) this.joint.rotationalLimitMotor1.setSpring(spring[0], spring[1]);
  1295. if(motor !== null) this.joint.rotationalLimitMotor1.setSpring(motor[0], motor[1]);
  1296. break;
  1297. }
  1298. this.joint.name = this.name;
  1299. // finaly add to physics world
  1300. this.parent.addJoint(this.joint);
  1301. }
  1302. OIMO.Link.prototype = {
  1303. constructor: OIMO.Link,
  1304. getPosition:function(){
  1305. // array of two vect3 [point1, point2]
  1306. return this.joint.getPosition();
  1307. },
  1308. getMatrix:function(){
  1309. return this.joint.getMatrix();
  1310. },
  1311. // remove joint
  1312. remove:function(){
  1313. this.parent.removeJoint(this.joint);
  1314. },
  1315. // force wakeup linked body
  1316. awake:function(){
  1317. this.joint.awake();
  1318. }
  1319. }
  1320. OIMO.Performance = function(world){
  1321. this.parent = world;
  1322. this.infos = new OIMO_ARRAY_TYPE(13);
  1323. this.f = [0,0,0];
  1324. this.fps=0;
  1325. this.broadPhaseTime=0;
  1326. this.narrowPhaseTime=0;
  1327. this.solvingTime=0;
  1328. this.updatingTime=0;
  1329. this.totalTime=0;
  1330. }
  1331. OIMO.Performance.prototype = {
  1332. upfps : function(){
  1333. this.f[1] = Date.now();
  1334. 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]++;
  1335. },
  1336. show : function(){
  1337. var info =[
  1338. "Oimo.js DEV.1.1.2a<br><br>",
  1339. "FPS: " + this.fps +" fps<br><br>",
  1340. "rigidbody "+this.parent.numRigidBodies+"<br>",
  1341. "contact &nbsp;&nbsp;"+this.parent.numContacts+"<br>",
  1342. "paircheck "+this.parent.broadPhase.numPairChecks+"<br>",
  1343. "contact &nbsp;&nbsp;"+this.parent.numContactPoints+"<br>",
  1344. "island &nbsp;&nbsp;&nbsp;"+this.parent.numIslands +"<br><br>",
  1345. "Time in ms <br>",
  1346. "broad-phase &nbsp;"+this.broadPhaseTime + "<br>",
  1347. "narrow-phase "+this.narrowPhaseTime + "<br>",
  1348. "solving &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"+this.solvingTime + "<br>",
  1349. "updating &nbsp;&nbsp;&nbsp;&nbsp;"+this.updatingTime + "<br>",
  1350. "total &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"+this.totalTime
  1351. ].join("\n");
  1352. return info;
  1353. },
  1354. toArray : function(){
  1355. this.infos[0] = this.parent.broadPhase.types;
  1356. this.infos[1] = this.parent.numRigidBodies;
  1357. this.infos[2] = this.parent.numContacts;
  1358. this.infos[3] = this.parent.broadPhase.numPairChecks;
  1359. this.infos[4] = this.parent.numContactPoints;
  1360. this.infos[5] = this.parent.numIslands;
  1361. this.infos[6] = this.broadPhaseTime;
  1362. this.infos[7] = this.narrowPhaseTime;
  1363. this.infos[8] = this.solvingTime;
  1364. this.infos[9] = this.updatingTime;
  1365. this.infos[10] = this.totalTime;
  1366. this.infos[11] = this.fps;
  1367. return this.infos;
  1368. }
  1369. }
  1370. OIMO.Mat44 = function(n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44){
  1371. this.elements = new OIMO_ARRAY_TYPE(16);
  1372. var te = this.elements;
  1373. te[0] = ( n11 !== undefined ) ? n11 : 1; te[4] = n12 || 0; te[8] = n13 || 0; te[12] = n14 || 0;
  1374. te[1] = n21 || 0; te[5] = ( n22 !== undefined ) ? n22 : 1; te[9] = n23 || 0; te[13] = n24 || 0;
  1375. te[2] = n31 || 0; te[6] = n32 || 0; te[10] = ( n33 !== undefined ) ? n33 : 1; te[14] = n34 || 0;
  1376. te[3] = n41 || 0; te[7] = n42 || 0; te[11] = n43 || 0; te[15] = ( n44 !== undefined ) ? n44 : 1;
  1377. };
  1378. OIMO.Mat44.prototype = {
  1379. constructor: OIMO.Mat44,
  1380. set: function ( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) {
  1381. var te = this.elements;
  1382. te[0] = n11; te[4] = n12; te[8] = n13; te[12] = n14;
  1383. te[1] = n21; te[5] = n22; te[9] = n23; te[13] = n24;
  1384. te[2] = n31; te[6] = n32; te[10] = n33; te[14] = n34;
  1385. te[3] = n41; te[7] = n42; te[11] = n43; te[15] = n44;
  1386. return this;
  1387. }/*,
  1388. extractRotation: function () {
  1389. var v1 = new THREE.Vector3();
  1390. return function ( m ) {
  1391. var te = this.elements;
  1392. var me = m.elements;
  1393. var scaleX = 1 / v1.set( me[ 0 ], me[ 1 ], me[ 2 ] ).length();
  1394. var scaleY = 1 / v1.set( me[ 4 ], me[ 5 ], me[ 6 ] ).length();
  1395. var scaleZ = 1 / v1.set( me[ 8 ], me[ 9 ], me[ 10 ] ).length();
  1396. te[ 0 ] = me[ 0 ] * scaleX;
  1397. te[ 1 ] = me[ 1 ] * scaleX;
  1398. te[ 2 ] = me[ 2 ] * scaleX;
  1399. te[ 4 ] = me[ 4 ] * scaleY;
  1400. te[ 5 ] = me[ 5 ] * scaleY;
  1401. te[ 6 ] = me[ 6 ] * scaleY;
  1402. te[ 8 ] = me[ 8 ] * scaleZ;
  1403. te[ 9 ] = me[ 9 ] * scaleZ;
  1404. te[ 10 ] = me[ 10 ] * scaleZ;
  1405. return this;
  1406. };
  1407. }() */
  1408. }
  1409. OIMO.Mat33 = function(e00,e01,e02,e10,e11,e12,e20,e21,e22){
  1410. this.elements = new OIMO_ARRAY_TYPE(9);
  1411. var te = this.elements;
  1412. this.init(
  1413. ( e00 !== undefined ) ? e00 : 1, e01 || 0, e02 || 0,
  1414. e10 || 0, ( e11 !== undefined ) ? e11 : 1, e12 || 0,
  1415. e20 || 0, e21 || 0, ( e22 !== undefined ) ? e22 : 1
  1416. );
  1417. };
  1418. OIMO.Mat33.prototype = {
  1419. constructor: OIMO.Mat33,
  1420. init: function(e00,e01,e02,e10,e11,e12,e20,e21,e22){
  1421. var te = this.elements;
  1422. te[0] = e00; te[1] = e01; te[2] = e02;
  1423. te[3] = e10; te[4] = e11; te[5] = e12;
  1424. te[6] = e20; te[7] = e21; te[8] = e22;
  1425. return this;
  1426. },
  1427. add: function(m1,m2){
  1428. var te = this.elements, tem1 = m1.elements, tem2 = m2.elements;
  1429. te[0] = tem1[0] + tem2[0]; te[1] = tem1[1] + tem2[1]; te[2] = tem1[2] + tem2[2];
  1430. te[3] = tem1[3] + tem2[3]; te[4] = tem1[4] + tem2[4]; te[5] = tem1[5] + tem2[5];
  1431. te[6] = tem1[6] + tem2[6]; te[7] = tem1[7] + tem2[7]; te[8] = tem1[8] + tem2[8];
  1432. return this;
  1433. },
  1434. addEqual: function(m){
  1435. var te = this.elements, tem = m.elements;
  1436. te[0] += tem[0]; te[1] += tem[1]; te[2] += tem[2];
  1437. te[3] += tem[3]; te[4] += tem[4]; te[5] += tem[5];
  1438. te[6] += tem[6]; te[7] += tem[7]; te[8] += tem[8];
  1439. return this;
  1440. },
  1441. sub: function(m1,m2){
  1442. var te = this.elements, tem1 = m1.elements, tem2 = m2.elements;
  1443. te[0] = tem1[0] - tem2[0]; te[1] = tem1[1] - tem2[1]; te[2] = tem1[2] - tem2[2];
  1444. te[3] = tem1[3] - tem2[3]; te[4] = tem1[4] - tem2[4]; te[5] = tem1[5] - tem2[5];
  1445. te[6] = tem1[6] - tem2[6]; te[7] = tem1[7] - tem2[7]; te[8] = tem1[8] - tem2[8];
  1446. return this;
  1447. },
  1448. subEqual:function(m){
  1449. var te = this.elements, tem = m.elements;
  1450. te[0] -= tem[0]; te[1] -= tem[1]; te[2] -= tem[2];
  1451. te[3] -= tem[3]; te[4] -= tem[4]; te[5] -= tem[5];
  1452. te[6] -= tem[6]; te[7] -= tem[7]; te[8] -= tem[8];
  1453. return this;
  1454. },
  1455. scale: function(m,s){
  1456. var te = this.elements, tm = m.elements;
  1457. te[0] = tm[0] * s; te[1] = tm[1] * s; te[2] = tm[2] * s;
  1458. te[3] = tm[3] * s; te[4] = tm[4] * s; te[5] = tm[5] * s;
  1459. te[6] = tm[6] * s; te[7] = tm[7] * s; te[8] = tm[8] * s;
  1460. return this;
  1461. },
  1462. scaleEqual: function(s){
  1463. var te = this.elements;
  1464. te[0] *= s; te[1] *= s; te[2] *= s;
  1465. te[3] *= s; te[4] *= s; te[5] *= s;
  1466. te[6] *= s; te[7] *= s; te[8] *= s;
  1467. return this;
  1468. },
  1469. mul: function(m1,m2){
  1470. var te = this.elements, tm1 = m1.elements, tm2 = m2.elements,
  1471. a0 = tm1[0], a3 = tm1[3], a6 = tm1[6],
  1472. a1 = tm1[1], a4 = tm1[4], a7 = tm1[7],
  1473. a2 = tm1[2], a5 = tm1[5], a8 = tm1[8],
  1474. b0 = tm2[0], b3 = tm2[3], b6 = tm2[6],
  1475. b1 = tm2[1], b4 = tm2[4], b7 = tm2[7],
  1476. b2 = tm2[2], b5 = tm2[5], b8 = tm2[8];
  1477. te[0] = a0*b0 + a1*b3 + a2*b6;
  1478. te[1] = a0*b1 + a1*b4 + a2*b7;
  1479. te[2] = a0*b2 + a1*b5 + a2*b8;
  1480. te[3] = a3*b0 + a4*b3 + a5*b6;
  1481. te[4] = a3*b1 + a4*b4 + a5*b7;
  1482. te[5] = a3*b2 + a4*b5 + a5*b8;
  1483. te[6] = a6*b0 + a7*b3 + a8*b6;
  1484. te[7] = a6*b1 + a7*b4 + a8*b7;
  1485. te[8] = a6*b2 + a7*b5 + a8*b8;
  1486. return this;
  1487. },
  1488. mulScale: function(m,sx,sy,sz,Prepend){
  1489. var prepend = Prepend || false;
  1490. var te = this.elements, tm = m.elements;
  1491. if(prepend){
  1492. te[0] = sx*tm[0]; te[1] = sx*tm[1]; te[2] = sx*tm[2];
  1493. te[3] = sy*tm[3]; te[4] = sy*tm[4]; te[5] = sy*tm[5];
  1494. te[6] = sz*tm[6]; te[7] = sz*tm[7]; te[8] = sz*tm[8];
  1495. }else{
  1496. te[0] = tm[0]*sx; te[1] = tm[1]*sy; te[2] = tm[2]*sz;
  1497. te[3] = tm[3]*sx; te[4] = tm[4]*sy; te[5] = tm[5]*sz;
  1498. te[6] = tm[6]*sx; te[7] = tm[7]*sy; te[8] = tm[8]*sz;
  1499. }
  1500. return this;
  1501. },
  1502. mulRotate: function(m,rad,ax,ay,az,Prepend){
  1503. var prepend = Prepend || false;
  1504. var s=Math.sin(rad);
  1505. var c=Math.cos(rad);
  1506. var c1=1-c;
  1507. var r00=ax*ax*c1+c;
  1508. var r01=ax*ay*c1-az*s;
  1509. var r02=ax*az*c1+ay*s;
  1510. var r10=ay*ax*c1+az*s;
  1511. var r11=ay*ay*c1+c;
  1512. var r12=ay*az*c1-ax*s;
  1513. var r20=az*ax*c1-ay*s;
  1514. var r21=az*ay*c1+ax*s;
  1515. var r22=az*az*c1+c;
  1516. var tm = m.elements;
  1517. var a0 = tm[0], a3 = tm[3], a6 = tm[6];
  1518. var a1 = tm[1], a4 = tm[4], a7 = tm[7];
  1519. var a2 = tm[2], a5 = tm[5], a8 = tm[8];
  1520. var te = this.elements;
  1521. if(prepend){
  1522. te[0]=r00*a0+r01*a3+r02*a6;
  1523. te[1]=r00*a1+r01*a4+r02*a7;
  1524. te[2]=r00*a2+r01*a5+r02*a8;
  1525. te[3]=r10*a0+r11*a3+r12*a6;
  1526. te[4]=r10*a1+r11*a4+r12*a7;
  1527. te[5]=r10*a2+r11*a5+r12*a8;
  1528. te[6]=r20*a0+r21*a3+r22*a6;
  1529. te[7]=r20*a1+r21*a4+r22*a7;
  1530. te[8]=r20*a2+r21*a5+r22*a8;
  1531. }else{
  1532. te[0]=a0*r00+a1*r10+a2*r20;
  1533. te[1]=a0*r01+a1*r11+a2*r21;
  1534. te[2]=a0*r02+a1*r12+a2*r22;
  1535. te[3]=a3*r00+a4*r10+a5*r20;
  1536. te[4]=a3*r01+a4*r11+a5*r21;
  1537. te[5]=a3*r02+a4*r12+a5*r22;
  1538. te[6]=a6*r00+a7*r10+a8*r20;
  1539. te[7]=a6*r01+a7*r11+a8*r21;
  1540. te[8]=a6*r02+a7*r12+a8*r22;
  1541. }
  1542. return this;
  1543. },
  1544. transpose: function(m){
  1545. var te = this.elements, tm = m.elements;
  1546. te[0] = tm[0]; te[1] = tm[3]; te[2] = tm[6];
  1547. te[3] = tm[1]; te[4] = tm[4]; te[5] = tm[7];
  1548. te[6] = tm[2]; te[7] = tm[5]; te[8] = tm[8];
  1549. return this;
  1550. },
  1551. setQuat: function(q){
  1552. var te = this.elements,
  1553. x2=2*q.x, y2=2*q.y, z2=2*q.z,
  1554. xx=q.x*x2, yy=q.y*y2, zz=q.z*z2,
  1555. xy=q.x*y2, yz=q.y*z2, xz=q.x*z2,
  1556. sx=q.s*x2, sy=q.s*y2, sz=q.s*z2;
  1557. te[0]=1-yy-zz;
  1558. te[1]=xy-sz;
  1559. te[2]=xz+sy;
  1560. te[3]=xy+sz;
  1561. te[4]=1-xx-zz;
  1562. te[5]=yz-sx;
  1563. te[6]=xz-sy;
  1564. te[7]=yz+sx;
  1565. te[8]=1-xx-yy;
  1566. return this;
  1567. },
  1568. invert: function(m){
  1569. var te = this.elements, tm = m.elements,
  1570. a0 = tm[0], a3 = tm[3], a6 = tm[6],
  1571. a1 = tm[1], a4 = tm[4], a7 = tm[7],
  1572. a2 = tm[2], a5 = tm[5], a8 = tm[8],
  1573. b01 = a4*a8-a7*a5,
  1574. b11 = a7*a2-a1*a8,
  1575. b21 = a1*a5-a4*a2,
  1576. dt= a0 * (b01) + a3 * (b11) + a6 * (b21);
  1577. if(dt!=0){dt=1.0/dt;}
  1578. te[0] = dt*b01;//(a4*a8 - a5*a7);
  1579. te[1] = dt*b11;//(a2*a7 - a1*a8);
  1580. te[2] = dt*b21;//(a1*a5 - a2*a4);
  1581. te[3] = dt*(a5*a6 - a3*a8);
  1582. te[4] = dt*(a0*a8 - a2*a6);
  1583. te[5] = dt*(a2*a3 - a0*a5);
  1584. te[6] = dt*(a3*a7 - a4*a6);
  1585. te[7] = dt*(a1*a6 - a0*a7);
  1586. te[8] = dt*(a0*a4 - a1*a3);
  1587. return this;
  1588. },
  1589. copy: function(m){
  1590. var te = this.elements, tem = m.elements;
  1591. te[0] = tem[0]; te[1] = tem[1]; te[2] = tem[2];
  1592. te[3] = tem[3]; te[4] = tem[4]; te[5] = tem[5];
  1593. te[6] = tem[6]; te[7] = tem[7]; te[8] = tem[8];
  1594. return this;
  1595. },
  1596. toEuler: function(){ // not work !!
  1597. function clamp( x ) {
  1598. return Math.min( Math.max( x, -1 ), 1 );
  1599. }
  1600. var te = this.elements;
  1601. var m11 = te[0], m12 = te[3], m13 = te[6];
  1602. var m21 = te[1], m22 = te[4], m23 = te[7];
  1603. var m31 = te[2], m32 = te[5], m33 = te[8];
  1604. var p = new OIMO.Vec3();
  1605. var d = new OIMO.Quat();
  1606. var s;
  1607. p.y = Math.asin( clamp( m13 ) );
  1608. if ( Math.abs( m13 ) < 0.99999 ) {
  1609. p.x = Math.atan2( - m23, m33 );
  1610. p.z = Math.atan2( - m12, m11 );
  1611. } else {
  1612. p.x = Math.atan2( m32, m22 );
  1613. p.z = 0;
  1614. }
  1615. return p;
  1616. },
  1617. clone: function(){
  1618. var te = this.elements;
  1619. return new OIMO.Mat33(
  1620. te[0], te[1], te[2],
  1621. te[3], te[4], te[5],
  1622. te[6], te[7], te[8]
  1623. );
  1624. },
  1625. toString: function(){
  1626. var te = this.elements;
  1627. var text=
  1628. "Mat33|"+te[0].toFixed(4)+", "+te[1].toFixed(4)+", "+te[2].toFixed(4)+"|\n"+
  1629. " |"+te[3].toFixed(4)+", "+te[4].toFixed(4)+", "+te[5].toFixed(4)+"|\n"+
  1630. " |"+te[6].toFixed(4)+", "+te[7].toFixed(4)+", "+te[8].toFixed(4)+"|" ;
  1631. return text;
  1632. }
  1633. };
  1634. OIMO.Quat = function( s, x, y, z){
  1635. this.s=( s !== undefined ) ? s : 1;
  1636. this.x=x || 0;
  1637. this.y=y || 0;
  1638. this.z=z || 0;
  1639. };
  1640. OIMO.Quat.prototype = {
  1641. constructor: OIMO.Quat,
  1642. init: function(s,x,y,z){
  1643. this.s=( s !== undefined ) ? s : 1;
  1644. this.x=x || 0;
  1645. this.y=y || 0;
  1646. this.z=z || 0;
  1647. return this;
  1648. },
  1649. add: function(q1,q2){
  1650. this.s=q1.s+q2.s;
  1651. this.x=q1.x+q2.x;
  1652. this.y=q1.y+q2.y;
  1653. this.z=q1.z+q2.z;
  1654. return this;
  1655. },
  1656. addTime: function(v,t){
  1657. var x = v.x;
  1658. var y = v.y;
  1659. var z = v.z;
  1660. var qs=this.s;
  1661. var qx=this.x;
  1662. var qy=this.y;
  1663. var qz=this.z;
  1664. t*=0.5;
  1665. var ns=(-x*qx - y*qy - z*qz)*t;
  1666. var nx=( x*qs + y*qz - z*qy)*t;
  1667. var ny=(-x*qz + y*qs + z*qx)*t;
  1668. var nz=( x*qy - y*qx + z*qs)*t;
  1669. qs += ns;
  1670. qx += nx;
  1671. qy += ny;
  1672. qz += nz;
  1673. var s=1/Math.sqrt(qs*qs+qx*qx+qy*qy+qz*qz);
  1674. this.s=qs*s;
  1675. this.x=qx*s;
  1676. this.y=qy*s;
  1677. this.z=qz*s;
  1678. return this;
  1679. },
  1680. sub: function(q1,q2){
  1681. this.s=q1.s-q2.s;
  1682. this.x=q1.x-q2.x;
  1683. this.y=q1.y-q2.y;
  1684. this.z=q1.z-q2.z;
  1685. return this;
  1686. },
  1687. scale: function(q,s){
  1688. this.s=q.s*s;
  1689. this.x=q.x*s;
  1690. this.y=q.y*s;
  1691. this.z=q.z*s;
  1692. return this;
  1693. },
  1694. mul: function(q1,q2){
  1695. var ax = q1.x, ay = q1.y, az = q1.z, as = q1.s,
  1696. bx = q2.x, by = q2.y, bz = q2.z, bs = q2.s;
  1697. this.x = ax * bs + as * bx + ay * bz - az * by;
  1698. this.y = ay * bs + as * by + az * bx - ax * bz;
  1699. this.z = az * bs + as * bz + ax * by - ay * bx;
  1700. this.s = as * bs - ax * bx - ay * by - az * bz;
  1701. return this;
  1702. },
  1703. arc: function(v1,v2){
  1704. var x1=v1.x;
  1705. var y1=v1.y;
  1706. var z1=v1.z;
  1707. var x2=v2.x;
  1708. var y2=v2.y;
  1709. var z2=v2.z;
  1710. var d=x1*x2+y1*y2+z1*z2;
  1711. if(d==-1){
  1712. x2=y1*x1-z1*z1;
  1713. y2=-z1*y1-x1*x1;
  1714. z2=x1*z1+y1*y1;
  1715. d=1/Math.sqrt(x2*x2+y2*y2+z2*z2);
  1716. this.s=0;
  1717. this.x=x2*d;
  1718. this.y=y2*d;
  1719. this.z=z2*d;
  1720. return this;
  1721. }
  1722. var cx=y1*z2-z1*y2;
  1723. var cy=z1*x2-x1*z2;
  1724. var cz=x1*y2-y1*x2;
  1725. this.s=Math.sqrt((1+d)*0.5);
  1726. d=0.5/this.s;
  1727. this.x=cx*d;
  1728. this.y=cy*d;
  1729. this.z=cz*d;
  1730. return this;
  1731. },
  1732. normalize: function(q){
  1733. var len=Math.sqrt(q.s*q.s+q.x*q.x+q.y*q.y+q.z*q.z);
  1734. if(len>0){len=1/len;}
  1735. this.s=q.s*len;
  1736. this.x=q.x*len;
  1737. this.y=q.y*len;
  1738. this.z=q.z*len;
  1739. return this;
  1740. },
  1741. invert: function(q){
  1742. this.s=q.s;
  1743. this.x=-q.x;
  1744. this.y=-q.y;
  1745. this.z=-q.z;
  1746. return this;
  1747. },
  1748. length: function(){
  1749. return Math.sqrt(this.s*this.s+this.x*this.x+this.y*this.y+this.z*this.z);
  1750. },
  1751. copy: function(q){
  1752. this.s=q.s;
  1753. this.x=q.x;
  1754. this.y=q.y;
  1755. this.z=q.z;
  1756. return this;
  1757. },
  1758. testDiff: function(q){
  1759. if(this.s!==q.s || this.x!==q.x || this.y!==q.y || this.z!==q.z) return true;
  1760. else return false;
  1761. },
  1762. clone: function(q){
  1763. return new OIMO.Quat(this.s,this.x,this.y,this.z);
  1764. },
  1765. toString: function(){
  1766. return"Quat["+this.s.toFixed(4)+", ("+this.x.toFixed(4)+", "+this.y.toFixed(4)+", "+this.z.toFixed(4)+")]";
  1767. }
  1768. }
  1769. // for three easy export
  1770. OIMO.Quaternion = function ( x, y, z, w ) {
  1771. this.x = x || 0;
  1772. this.y = y || 0;
  1773. this.z = z || 0;
  1774. this.w = ( w !== undefined ) ? w : 1;
  1775. };
  1776. OIMO.Quaternion.prototype = {
  1777. constructor: OIMO.Quaternion,
  1778. setFromRotationMatrix: function ( m ) {
  1779. // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm
  1780. // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)
  1781. var te = m.elements,
  1782. m11 = te[ 0 ], m12 = te[ 1 ], m13 = te[ 2 ],
  1783. m21 = te[ 3 ], m22 = te[ 4 ], m23 = te[ 5 ],
  1784. m31 = te[ 6 ], m32 = te[ 7 ], m33 = te[ 8 ],
  1785. trace = m11 + m22 + m33,
  1786. s;
  1787. if ( trace > 0 ) {
  1788. s = 0.5 / Math.sqrt( trace + 1.0 );
  1789. this.w = 0.25 / s;
  1790. this.x = ( m32 - m23 ) * s;
  1791. this.y = ( m13 - m31 ) * s;
  1792. this.z = ( m21 - m12 ) * s;
  1793. } else if ( m11 > m22 && m11 > m33 ) {
  1794. s = 2.0 * Math.sqrt( 1.0 + m11 - m22 - m33 );
  1795. this.w = ( m32 - m23 ) / s;
  1796. this.x = 0.25 * s;
  1797. this.y = ( m12 + m21 ) / s;
  1798. this.z = ( m13 + m31 ) / s;
  1799. } else if ( m22 > m33 ) {
  1800. s = 2.0 * Math.sqrt( 1.0 + m22 - m11 - m33 );
  1801. this.w = ( m13 - m31 ) / s;
  1802. this.x = ( m12 + m21 ) / s;
  1803. this.y = 0.25 * s;
  1804. this.z = ( m23 + m32 ) / s;
  1805. } else {
  1806. s = 2.0 * Math.sqrt( 1.0 + m33 - m11 - m22 );
  1807. this.w = ( m21 - m12 ) / s;
  1808. this.x = ( m13 + m31 ) / s;
  1809. this.y = ( m23 + m32 ) / s;
  1810. this.z = 0.25 * s;
  1811. }
  1812. //this.onChangeCallback();
  1813. return this;
  1814. }
  1815. }
  1816. OIMO.Vec3 = function(x,y,z){
  1817. this.x=x || 0;
  1818. this.y=y || 0;
  1819. this.z=z || 0;
  1820. };
  1821. OIMO.Vec3.prototype = {
  1822. constructor: OIMO.Vec3,
  1823. init: function(x,y,z){
  1824. this.x=x || 0;
  1825. this.y=y || 0;
  1826. this.z=z || 0;
  1827. return this;
  1828. },
  1829. set: function(x,y,z){
  1830. this.x=x;
  1831. this.y=y;
  1832. this.z=z;
  1833. return this;
  1834. },
  1835. add: function(v1,v2){
  1836. this.x=v1.x+v2.x;
  1837. this.y=v1.y+v2.y;
  1838. this.z=v1.z+v2.z;
  1839. return this;
  1840. },
  1841. addEqual: function(v){
  1842. this.x+=v.x;
  1843. this.y+=v.y;
  1844. this.z+=v.z;
  1845. return this;
  1846. },
  1847. addTime: function(v, t){
  1848. this.x+=v.x*t;
  1849. this.y+=v.y*t;
  1850. this.z+=v.z*t;
  1851. return this;
  1852. },
  1853. sub: function(v1,v2){
  1854. this.x=v1.x-v2.x;
  1855. this.y=v1.y-v2.y;
  1856. this.z=v1.z-v2.z;
  1857. return this;
  1858. },
  1859. subEqual: function(v){
  1860. this.x-=v.x;
  1861. this.y-=v.y;
  1862. this.z-=v.z;
  1863. return this;
  1864. },
  1865. addScale: function(v,s){
  1866. this.x+=v.x*s;
  1867. this.y+=v.y*s;
  1868. this.z+=v.z*s;
  1869. return this;
  1870. },
  1871. scale: function(v,s){
  1872. this.x=v.x*s;
  1873. this.y=v.y*s;
  1874. this.z=v.z*s;
  1875. return this;
  1876. },
  1877. scaleEqual: function(s){
  1878. this.x*=s;
  1879. this.y*=s;
  1880. this.z*=s;
  1881. return this;
  1882. },
  1883. dot: function(v){
  1884. return this.x*v.x+this.y*v.y+this.z*v.z;
  1885. },
  1886. cross: function(v1,v2){
  1887. var ax = v1.x, ay = v1.y, az = v1.z,
  1888. bx = v2.x, by = v2.y, bz = v2.z;
  1889. this.x = ay * bz - az * by;
  1890. this.y = az * bx - ax * bz;
  1891. this.z = ax * by - ay * bx;
  1892. return this;
  1893. },
  1894. mul: function(o, v, m){
  1895. var te = m.elements;
  1896. this.x=o.x+v.x*te[0]+v.y*te[1]+v.z*te[2];
  1897. this.y=o.y+v.x*te[3]+v.y*te[4]+v.z*te[5];
  1898. this.z=o.z+v.x*te[6]+v.y*te[7]+v.z*te[8];
  1899. return this;
  1900. },
  1901. mulMat: function(m,v){
  1902. var te = m.elements;
  1903. var x=te[0]*v.x+te[1]*v.y+te[2]*v.z;
  1904. var y=te[3]*v.x+te[4]*v.y+te[5]*v.z;
  1905. var z=te[6]*v.x+te[7]*v.y+te[8]*v.z;
  1906. this.x=x;
  1907. this.y=y;
  1908. this.z=z;
  1909. return this;
  1910. },
  1911. normalize: function(v){
  1912. var x = v.x, y = v.y, z = v.z;
  1913. var l = x*x + y*y + z*z;
  1914. if (l > 0) {
  1915. l = 1 / Math.sqrt(l);
  1916. this.x = x*l;
  1917. this.y = y*l;
  1918. this.z = z*l;
  1919. }
  1920. return this;
  1921. },
  1922. invert: function(v){
  1923. this.x=-v.x;
  1924. this.y=-v.y;
  1925. this.z=-v.z;
  1926. return this;
  1927. },
  1928. length: function(){
  1929. var x = this.x, y = this.y, z = this.z;
  1930. return Math.sqrt(x*x + y*y + z*z);
  1931. },
  1932. len: function(){
  1933. var x = this.x, y = this.y, z = this.z;
  1934. return x*x + y*y + z*z;
  1935. },
  1936. copy: function(v){
  1937. this.x=v.x;
  1938. this.y=v.y;
  1939. this.z=v.z;
  1940. return this;
  1941. },
  1942. applyQuaternion: function ( q ) {
  1943. var x = this.x;
  1944. var y = this.y;
  1945. var z = this.z;
  1946. var qx = q.x;
  1947. var qy = q.y;
  1948. var qz = q.z;
  1949. var qs = q.s;
  1950. // calculate quat * vector
  1951. var ix = qs * x + qy * z - qz * y;
  1952. var iy = qs * y + qz * x - qx * z;
  1953. var iz = qs * z + qx * y - qy * x;
  1954. var iw = - qx * x - qy * y - qz * z;
  1955. // calculate result * inverse quat
  1956. this.x = ix * qs + iw * - qx + iy * - qz - iz * - qy;
  1957. this.y = iy * qs + iw * - qy + iz * - qx - ix * - qz;
  1958. this.z = iz * qs + iw * - qz + ix * - qy - iy * - qx;
  1959. return this;
  1960. },
  1961. testZero: function(){
  1962. if(this.x!==0 || this.y!==0 || this.z!==0) return true;
  1963. else return false;
  1964. },
  1965. testDiff: function(v){
  1966. if(this.x!==v.x || this.y!==v.y || this.z!==v.z) return true;
  1967. else return false;
  1968. },
  1969. clone: function(){
  1970. return new OIMO.Vec3(this.x,this.y,this.z);
  1971. },
  1972. toString: function(){
  1973. return"Vec3["+this.x.toFixed(4)+", "+this.y.toFixed(4)+", "+this.z.toFixed(4)+"]";
  1974. }
  1975. }
  1976. OIMO.Euler = function ( x, y, z, order ) {
  1977. this._x = x || 0;
  1978. this._y = y || 0;
  1979. this._z = z || 0;
  1980. this._order = order || OIMO.Euler.DefaultOrder;
  1981. };
  1982. OIMO.Euler.RotationOrders = [ 'XYZ', 'YZX', 'ZXY', 'XZY', 'YXZ', 'ZYX' ];
  1983. OIMO.Euler.DefaultOrder = 'XYZ';
  1984. OIMO.clamp = function ( x, a, b ) {
  1985. return ( x < a ) ? a : ( ( x > b ) ? b : x );
  1986. }
  1987. OIMO.Euler.prototype = {
  1988. constructor: OIMO.Euler,
  1989. _x: 0, _y: 0, _z: 0, _order: OIMO.Euler.DefaultOrder,
  1990. get x () {
  1991. return this._x;
  1992. },
  1993. set x ( value ) {
  1994. this._x = value;
  1995. this.onChangeCallback();
  1996. },
  1997. get y () {
  1998. return this._y;
  1999. },
  2000. set y ( value ) {
  2001. this._y = value;
  2002. this.onChangeCallback();
  2003. },
  2004. get z () {
  2005. return this._z;
  2006. },
  2007. set z ( value ) {
  2008. this._z = value;
  2009. this.onChangeCallback();
  2010. },
  2011. get order () {
  2012. return this._order;
  2013. },
  2014. set order ( value ) {
  2015. this._order = value;
  2016. this.onChangeCallback();
  2017. },
  2018. set: function ( x, y, z, order ) {
  2019. this._x = x;
  2020. this._y = y;
  2021. this._z = z;
  2022. this._order = order || this._order;
  2023. this.onChangeCallback();
  2024. return this;
  2025. },
  2026. copy: function ( euler ) {
  2027. this._x = euler._x;
  2028. this._y = euler._y;
  2029. this._z = euler._z;
  2030. this._order = euler._order;
  2031. this.onChangeCallback();
  2032. return this;
  2033. },
  2034. setFromRotationMatrix: function ( m, order ) {
  2035. var clamp = OIMO.clamp;
  2036. // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)
  2037. var te = m.elements;
  2038. /*var m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ];
  2039. var m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ];
  2040. var m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ];*/
  2041. var m11 = te[ 0 ], m12 = te[ 1 ], m13 = te[ 2 ],
  2042. m21 = te[ 3 ], m22 = te[ 4 ], m23 = te[ 5 ],
  2043. m31 = te[ 6 ], m32 = te[ 7 ], m33 = te[ 8 ];
  2044. order = order || this._order;
  2045. if ( order === 'XYZ' ) {
  2046. this._y = Math.asin( clamp( m13, - 1, 1 ) );
  2047. if ( Math.abs( m13 ) < 0.99999 ) {
  2048. this._x = Math.atan2( - m23, m33 );
  2049. this._z = Math.atan2( - m12, m11 );
  2050. } else {
  2051. this._x = Math.atan2( m32, m22 );
  2052. this._z = 0;
  2053. }
  2054. } else if ( order === 'YXZ' ) {
  2055. this._x = Math.asin( - clamp( m23, - 1, 1 ) );
  2056. if ( Math.abs( m23 ) < 0.99999 ) {
  2057. this._y = Math.atan2( m13, m33 );
  2058. this._z = Math.atan2( m21, m22 );
  2059. } else {
  2060. this._y = Math.atan2( - m31, m11 );
  2061. this._z = 0;
  2062. }
  2063. } else if ( order === 'ZXY' ) {
  2064. this._x = Math.asin( clamp( m32, - 1, 1 ) );
  2065. if ( Math.abs( m32 ) < 0.99999 ) {
  2066. this._y = Math.atan2( - m31, m33 );
  2067. this._z = Math.atan2( - m12, m22 );
  2068. } else {
  2069. this._y = 0;
  2070. this._z = Math.atan2( m21, m11 );
  2071. }
  2072. } else if ( order === 'ZYX' ) {
  2073. this._y = Math.asin( - clamp( m31, - 1, 1 ) );
  2074. if ( Math.abs( m31 ) < 0.99999 ) {
  2075. this._x = Math.atan2( m32, m33 );
  2076. this._z = Math.atan2( m21, m11 );
  2077. } else {
  2078. this._x = 0;
  2079. this._z = Math.atan2( - m12, m22 );
  2080. }
  2081. } else if ( order === 'YZX' ) {
  2082. this._z = Math.asin( clamp( m21, - 1, 1 ) );
  2083. if ( Math.abs( m21 ) < 0.99999 ) {
  2084. this._x = Math.atan2( - m23, m22 );
  2085. this._y = Math.atan2( - m31, m11 );
  2086. } else {
  2087. this._x = 0;
  2088. this._y = Math.atan2( m13, m33 );
  2089. }
  2090. } else if ( order === 'XZY' ) {
  2091. this._z = Math.asin( - clamp( m12, - 1, 1 ) );
  2092. if ( Math.abs( m12 ) < 0.99999 ) {
  2093. this._x = Math.atan2( m32, m22 );
  2094. this._y = Math.atan2( m13, m11 );
  2095. } else {
  2096. this._x = Math.atan2( - m23, m33 );
  2097. this._y = 0;
  2098. }
  2099. } else {
  2100. console.warn( 'THREE.Euler: .setFromRotationMatrix() given unsupported order: ' + order )
  2101. }
  2102. this._order = order;
  2103. this.onChangeCallback();
  2104. return this;
  2105. },
  2106. setFromQuaternion: function ( q, order, update ) {
  2107. var clamp = OIMO.clamp;
  2108. // q is assumed to be normalized
  2109. // http://www.mathworks.com/matlabcentral/fileexchange/20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/content/SpinCalc.m
  2110. var sqx = q.x * q.x;
  2111. var sqy = q.y * q.y;
  2112. var sqz = q.z * q.z;
  2113. var sqw = q.s * q.s;
  2114. order = order || this._order;
  2115. if ( order === 'XYZ' ) {
  2116. this._x = Math.atan2( 2 * ( q.x * q.s - q.y * q.z ), ( sqw - sqx - sqy + sqz ) );
  2117. this._y = Math.asin( clamp( 2 * ( q.x * q.z + q.y * q.s ), - 1, 1 ) );
  2118. this._z = Math.atan2( 2 * ( q.z * q.s - q.x * q.y ), ( sqw + sqx - sqy - sqz ) );
  2119. } else if ( order === 'YXZ' ) {
  2120. this._x = Math.asin( clamp( 2 * ( q.x * q.s - q.y * q.z ), - 1, 1 ) );
  2121. this._y = Math.atan2( 2 * ( q.x * q.z + q.y * q.s ), ( sqw - sqx - sqy + sqz ) );
  2122. this._z = Math.atan2( 2 * ( q.x * q.y + q.z * q.s ), ( sqw - sqx + sqy - sqz ) );
  2123. } else if ( order === 'ZXY' ) {
  2124. this._x = Math.asin( clamp( 2 * ( q.x * q.s + q.y * q.z ), - 1, 1 ) );
  2125. this._y = Math.atan2( 2 * ( q.y * q.s - q.z * q.x ), ( sqw - sqx - sqy + sqz ) );
  2126. this._z = Math.atan2( 2 * ( q.z * q.s - q.x * q.y ), ( sqw - sqx + sqy - sqz ) );
  2127. } else if ( order === 'ZYX' ) {
  2128. this._x = Math.atan2( 2 * ( q.x * q.s + q.z * q.y ), ( sqw - sqx - sqy + sqz ) );
  2129. this._y = Math.asin( clamp( 2 * ( q.y * q.s - q.x * q.z ), - 1, 1 ) );
  2130. this._z = Math.atan2( 2 * ( q.x * q.y + q.z * q.s ), ( sqw + sqx - sqy - sqz ) );
  2131. } else if ( order === 'YZX' ) {
  2132. this._x = Math.atan2( 2 * ( q.x * q.s - q.z * q.y ), ( sqw - sqx + sqy - sqz ) );
  2133. this._y = Math.atan2( 2 * ( q.y * q.s - q.x * q.z ), ( sqw + sqx - sqy - sqz ) );
  2134. this._z = Math.asin( clamp( 2 * ( q.x * q.y + q.z * q.s ), - 1, 1 ) );
  2135. } else if ( order === 'XZY' ) {
  2136. this._x = Math.atan2( 2 * ( q.x * q.s + q.y * q.z ), ( sqw - sqx + sqy - sqz ) );
  2137. this._y = Math.atan2( 2 * ( q.x * q.z + q.y * q.s ), ( sqw + sqx - sqy - sqz ) );
  2138. this._z = Math.asin( clamp( 2 * ( q.z * q.s - q.x * q.y ), - 1, 1 ) );
  2139. } else {
  2140. console.warn( 'OIMO.Euler: .setFromQuaternion() given unsupported order: ' + order )
  2141. }
  2142. this._order = order;
  2143. if ( update !== false ) this.onChangeCallback();
  2144. return this;
  2145. },
  2146. reorder: function () {
  2147. // WARNING: this discards revolution information -bhouston
  2148. var q = new OIMO.Quat();
  2149. return function ( newOrder ) {
  2150. q.setFromEuler( this );
  2151. this.setFromQuaternion( q, newOrder );
  2152. };
  2153. }(),
  2154. equals: function ( euler ) {
  2155. return ( euler._x === this._x ) && ( euler._y === this._y ) && ( euler._z === this._z ) && ( euler._order === this._order );
  2156. },
  2157. fromArray: function ( array ) {
  2158. this._x = array[ 0 ];
  2159. this._y = array[ 1 ];
  2160. this._z = array[ 2 ];
  2161. if ( array[ 3 ] !== undefined ) this._order = array[ 3 ];
  2162. this.onChangeCallback();
  2163. return this;
  2164. },
  2165. toArray: function () {
  2166. return [ this._x, this._y, this._z, this._order ];
  2167. },
  2168. onChange: function ( callback ) {
  2169. this.onChangeCallback = callback;
  2170. return this;
  2171. },
  2172. onChangeCallback: function () {},
  2173. clone: function () {
  2174. return new OIMO.Euler( this._x, this._y, this._z, this._order );
  2175. }
  2176. };
  2177. OIMO.EulerToAxis = function( ox, oy, oz ){// angles in radians
  2178. var c1 = Math.cos(oy*0.5);//heading
  2179. var s1 = Math.sin(oy*0.5);
  2180. var c2 = Math.cos(oz*0.5);//altitude
  2181. var s2 = Math.sin(oz*0.5);
  2182. var c3 = Math.cos(ox*0.5);//bank
  2183. var s3 = Math.sin(ox*0.5);
  2184. var c1c2 = c1*c2;
  2185. var s1s2 = s1*s2;
  2186. var w =c1c2*c3 - s1s2*s3;
  2187. var x =c1c2*s3 + s1s2*c3;
  2188. var y =s1*c2*c3 + c1*s2*s3;
  2189. var z =c1*s2*c3 - s1*c2*s3;
  2190. var angle = 2 * Math.acos(w);
  2191. var norm = x*x+y*y+z*z;
  2192. if (norm < 0.001) {
  2193. x=1;
  2194. y=z=0;
  2195. } else {
  2196. norm = Math.sqrt(norm);
  2197. x /= norm;
  2198. y /= norm;
  2199. z /= norm;
  2200. }
  2201. return [angle, x, y, z];
  2202. }
  2203. OIMO.EulerToMatrix = function( ox, oy, oz ) {// angles in radians
  2204. var ch = Math.cos(oy);//heading
  2205. var sh = Math.sin(oy);
  2206. var ca = Math.cos(oz);//altitude
  2207. var sa = Math.sin(oz);
  2208. var cb = Math.cos(ox);//bank
  2209. var sb = Math.sin(ox);
  2210. var mtx = new OIMO.Mat33();
  2211. var te = mtx.elements;
  2212. te[0] = ch * ca;
  2213. te[1] = sh*sb - ch*sa*cb;
  2214. te[2] = ch*sa*sb + sh*cb;
  2215. te[3] = sa;
  2216. te[4] = ca*cb;
  2217. te[5] = -ca*sb;
  2218. te[6] = -sh*ca;
  2219. te[7] = sh*sa*cb + ch*sb;
  2220. te[8] = -sh*sa*sb + ch*cb;
  2221. return mtx;
  2222. }
  2223. OIMO.MatrixToEuler = function(mtx){// angles in radians
  2224. var te = mtx.elements;
  2225. var x, y, z;
  2226. if (te[3] > 0.998) { // singularity at north pole
  2227. y = Math.atan2(te[2],te[8]);
  2228. z = Math.PI/2;
  2229. x = 0;
  2230. } else if (te[3] < -0.998) { // singularity at south pole
  2231. y = Math.atan2(te[2],te[8]);
  2232. z = -Math.PI/2;
  2233. x = 0;
  2234. } else {
  2235. y = Math.atan2(-te[6],te[0]);
  2236. x = Math.atan2(-te[5],te[4]);
  2237. z = Math.asin(te[3]);
  2238. }
  2239. return [x, y, z];
  2240. }
  2241. OIMO.unwrapDegrees = function (r) {
  2242. r = r % 360;
  2243. if (r > 180) r -= 360;
  2244. if (r < -180) r += 360;
  2245. return r;
  2246. }
  2247. OIMO.unwrapRadian = function(r){
  2248. r = r % OIMO.TwoPI;
  2249. if (r > Math.PI) r -= OIMO.TwoPI;
  2250. if (r < -Math.PI) r += OIMO.TwoPI;
  2251. return r;
  2252. }
  2253. OIMO.Distance3d = function(p1, p2){
  2254. var xd = p2[0]-p1[0];
  2255. var yd = p2[1]-p1[1];
  2256. var zd = p2[2]-p1[2];
  2257. return Math.sqrt(xd*xd + yd*yd + zd*zd);
  2258. }
  2259. /**
  2260. * The base class of all type of the constraints.
  2261. * @author saharan
  2262. */
  2263. OIMO.Constraint = function(){
  2264. // The parent world of the constraint.
  2265. this.parent=null;
  2266. // The first body of the constraint.
  2267. this.body1=null;
  2268. // The second body of the constraint.
  2269. this.body2=null;
  2270. // Internal
  2271. this.addedToIsland=false;
  2272. }
  2273. OIMO.Constraint.prototype = {
  2274. constructor: OIMO.Constraint,
  2275. /**
  2276. * Prepare for solving the constraint.
  2277. * @param timeStep
  2278. * @param invTimeStep
  2279. */
  2280. preSolve:function(timeStep,invTimeStep){
  2281. throw new Error("Inheritance error.");
  2282. },
  2283. /**
  2284. * Solve the constraint.
  2285. * This is usually called iteratively.
  2286. */
  2287. solve:function(){
  2288. throw new Error("Inheritance error.");
  2289. },
  2290. /**
  2291. * Do the post-processing.
  2292. */
  2293. postSolve:function(){
  2294. throw new Error("Inheritance error.");
  2295. }
  2296. }
  2297. /**
  2298. * Joints are used to constrain the motion between two rigid bodies.
  2299. * @author saharan
  2300. */
  2301. OIMO.Joint = function(config){
  2302. OIMO.Constraint.call( this );
  2303. this.name = "";
  2304. // Distance joint
  2305. this.JOINT_DISTANCE=0x1;
  2306. // Ball-and-socket joint
  2307. this.JOINT_BALL_AND_SOCKET=0x2;
  2308. // Hinge joint
  2309. this.JOINT_HINGE=0x3;
  2310. // Wheel joint
  2311. this.JOINT_WHEEL=0x4;
  2312. // Slider joint
  2313. this.JOINT_SLIDER=0x5;
  2314. // Prismatic joint
  2315. this.JOINT_PRISMATIC=0x6;
  2316. // The type of the joint.
  2317. this.type=0;
  2318. // The previous joint in the world.
  2319. this.prev=null;
  2320. // The next joint in the world.
  2321. this.next=null;
  2322. this.body1=config.body1;
  2323. this.body2=config.body2;
  2324. // The anchor point on the first rigid body in local coordinate system.
  2325. this.localAnchorPoint1=new OIMO.Vec3().copy(config.localAnchorPoint1);
  2326. // The anchor point on the second rigid body in local coordinate system.
  2327. this.localAnchorPoint2=new OIMO.Vec3().copy(config.localAnchorPoint2);
  2328. // The anchor point on the first rigid body in world coordinate system relative to the body's origin.
  2329. this.relativeAnchorPoint1=new OIMO.Vec3();
  2330. // The anchor point on the second rigid body in world coordinate system relative to the body's origin.
  2331. this.relativeAnchorPoint2=new OIMO.Vec3();
  2332. // The anchor point on the first rigid body in world coordinate system.
  2333. this.anchorPoint1=new OIMO.Vec3();
  2334. // The anchor point on the second rigid body in world coordinate system.
  2335. this.anchorPoint2=new OIMO.Vec3();
  2336. // Whether allow collision between connected rigid bodies or not.
  2337. this.allowCollision=config.allowCollision;
  2338. this.b1Link=new OIMO.JointLink(this);
  2339. this.b2Link=new OIMO.JointLink(this);
  2340. this.matrix = new OIMO.Mat44();
  2341. }
  2342. OIMO.Joint.prototype = Object.create( OIMO.Constraint.prototype );
  2343. /**
  2344. * Update all the anchor points.
  2345. */
  2346. OIMO.Joint.prototype.updateAnchorPoints = function () {
  2347. var p1=this.body1.position;
  2348. var p2=this.body2.position;
  2349. var tr1 = this.body1.rotation.elements;
  2350. var tr2 = this.body2.rotation.elements;
  2351. var l1x=this.localAnchorPoint1.x;
  2352. var l1y=this.localAnchorPoint1.y;
  2353. var l1z=this.localAnchorPoint1.z;
  2354. var l2x=this.localAnchorPoint2.x;
  2355. var l2y=this.localAnchorPoint2.y;
  2356. var l2z=this.localAnchorPoint2.z;
  2357. var r1x=l1x*tr1[0]+l1y*tr1[1]+l1z*tr1[2];
  2358. var r1y=l1x*tr1[3]+l1y*tr1[4]+l1z*tr1[5];
  2359. var r1z=l1x*tr1[6]+l1y*tr1[7]+l1z*tr1[8];
  2360. var r2x=l2x*tr2[0]+l2y*tr2[1]+l2z*tr2[2];
  2361. var r2y=l2x*tr2[3]+l2y*tr2[4]+l2z*tr2[5];
  2362. var r2z=l2x*tr2[6]+l2y*tr2[7]+l2z*tr2[8];
  2363. this.relativeAnchorPoint1.x=r1x;
  2364. this.relativeAnchorPoint1.y=r1y;
  2365. this.relativeAnchorPoint1.z=r1z;
  2366. this.relativeAnchorPoint2.x=r2x;
  2367. this.relativeAnchorPoint2.y=r2y;
  2368. this.relativeAnchorPoint2.z=r2z;
  2369. var p1x=r1x+p1.x;
  2370. var p1y=r1y+p1.y;
  2371. var p1z=r1z+p1.z;
  2372. var p2x=r2x+p2.x;
  2373. var p2y=r2y+p2.y;
  2374. var p2z=r2z+p2.z;
  2375. this.anchorPoint1.x=p1x;
  2376. this.anchorPoint1.y=p1y;
  2377. this.anchorPoint1.z=p1z;
  2378. this.anchorPoint2.x=p2x;
  2379. this.anchorPoint2.y=p2y;
  2380. this.anchorPoint2.z=p2z;
  2381. }
  2382. /**
  2383. * Attach the joint from the bodies.
  2384. */
  2385. OIMO.Joint.prototype.attach = function () {
  2386. this.b1Link.body=this.body2;
  2387. this.b2Link.body=this.body1;
  2388. if(this.body1.jointLink!=null)(this.b1Link.next=this.body1.jointLink).prev=this.b1Link;
  2389. else this.b1Link.next=null;
  2390. this.body1.jointLink=this.b1Link;
  2391. this.body1.numJoints++;
  2392. if(this.body2.jointLink!=null)(this.b2Link.next=this.body2.jointLink).prev=this.b2Link;
  2393. else this.b2Link.next=null;
  2394. this.body2.jointLink=this.b2Link;
  2395. this.body2.numJoints++;
  2396. }
  2397. OIMO.Joint.prototype.detach = function () {
  2398. var prev=this.b1Link.prev;
  2399. var next=this.b1Link.next;
  2400. if(prev!=null)prev.next=next;
  2401. if(next!=null)next.prev=prev;
  2402. if(this.body1.jointLink==this.b1Link)this.body1.jointLink=next;
  2403. this.b1Link.prev=null;
  2404. this.b1Link.next=null;
  2405. this.b1Link.body=null;
  2406. this.body1.numJoints--;
  2407. prev=this.b2Link.prev;
  2408. next=this.b2Link.next;
  2409. if(prev!=null)prev.next=next;
  2410. if(next!=null)next.prev=prev;
  2411. if(this.body2.jointLink==this.b2Link)this.body2.jointLink=next;
  2412. this.b2Link.prev=null;
  2413. this.b2Link.next=null;
  2414. this.b2Link.body=null;
  2415. this.body2.numJoints--;
  2416. this.b1Link.body=null;
  2417. this.b2Link.body=null;
  2418. }
  2419. /**
  2420. * Awake the bodies.
  2421. */
  2422. OIMO.Joint.prototype.awake = function () {
  2423. this.body1.awake();
  2424. this.body2.awake();
  2425. }
  2426. OIMO.Joint.prototype.preSolve = function (timeStep,invTimeStep) {
  2427. }
  2428. OIMO.Joint.prototype.solve = function () {
  2429. }
  2430. OIMO.Joint.prototype.postSolve = function () {
  2431. }
  2432. /**
  2433. * Three js add
  2434. */
  2435. OIMO.Joint.prototype.getPosition = function () {
  2436. var p1 = new OIMO.Vec3().scale(this.anchorPoint1, OIMO.WORLD_SCALE);
  2437. var p2 = new OIMO.Vec3().scale(this.anchorPoint2, OIMO.WORLD_SCALE);
  2438. return [p1, p2];
  2439. }
  2440. OIMO.Joint.prototype.getMatrix = function () {
  2441. var m = this.matrix.elements;
  2442. var p1 = this.anchorPoint1;
  2443. var p2 = this.anchorPoint2;
  2444. m[0] = p1.x * OIMO.WORLD_SCALE;
  2445. m[1] = p1.y * OIMO.WORLD_SCALE;
  2446. m[2] = p1.z * OIMO.WORLD_SCALE;
  2447. m[3] = 0;
  2448. m[4] = p2.x * OIMO.WORLD_SCALE;
  2449. m[5] = p2.y * OIMO.WORLD_SCALE;
  2450. m[6] = p2.z * OIMO.WORLD_SCALE;
  2451. m[7] = 0;
  2452. return m;
  2453. }
  2454. /**
  2455. * A joint configuration holds all configuration data for constructing a joint.
  2456. * Joint configurations can be reused safely.
  2457. * @author saharan
  2458. */
  2459. OIMO.JointConfig = function(){
  2460. // The first rigid body of the joint.
  2461. this.body1 = null;
  2462. // The second rigid body of the joint.
  2463. this.body2 = null;
  2464. // The anchor point on the first rigid body in local coordinate system.
  2465. this.localAnchorPoint1=new OIMO.Vec3();
  2466. // The anchor point on the second rigid body in local coordinate system.
  2467. this.localAnchorPoint2=new OIMO.Vec3();
  2468. // The axis in the first body's coordinate system.
  2469. // his property is available in some joints.
  2470. this.localAxis1=new OIMO.Vec3();
  2471. // The axis in the second body's coordinate system.
  2472. // This property is available in some joints.
  2473. this.localAxis2=new OIMO.Vec3();
  2474. // Whether allow collision between connected rigid bodies or not.
  2475. this.allowCollision=false;
  2476. }
  2477. /**
  2478. * A link list of joints.
  2479. * @author saharan
  2480. */
  2481. OIMO.JointLink = function(joint){
  2482. // The previous joint link.
  2483. this.prev = null;
  2484. // The next joint link.
  2485. this.next = null;
  2486. // The other rigid body connected to the joint.
  2487. this.body = null;
  2488. // The joint of the link.
  2489. this.joint = joint;
  2490. }
  2491. /**
  2492. * An information of limit and motor.
  2493. * @author saharan
  2494. */
  2495. OIMO.LimitMotor = function(axis,fixed){
  2496. // The axis of the constraint.
  2497. this.axis=axis;
  2498. // The current angle for rotational constraints.
  2499. this.angle=0;
  2500. // The lower limit. Set lower > upper to disable.
  2501. if(fixed)this.lowerLimit=0;
  2502. else this.lowerLimit=1;
  2503. // The upper limit. Set lower > upper to disable.
  2504. this.upperLimit=0;
  2505. // The target motor speed.
  2506. this.motorSpeed=0;
  2507. // The maximum motor force or torque. Set 0 to disable.
  2508. this.maxMotorForce=0;
  2509. // The frequency of the spring. Set 0 to disable.
  2510. this.frequency=0;
  2511. // The damping ratio of the spring. Set 0 for no damping, 1 for critical damping.
  2512. this.dampingRatio=0;
  2513. }
  2514. OIMO.LimitMotor.prototype = {
  2515. constructor: OIMO.LimitMotor,
  2516. /**
  2517. * Set limit data into this constraint.
  2518. * @param lowerLimit
  2519. * @param upperLimit
  2520. */
  2521. setLimit:function(lowerLimit,upperLimit){
  2522. this.lowerLimit=lowerLimit;
  2523. this.upperLimit=upperLimit;
  2524. },
  2525. /**
  2526. * Set motor data into this constraint.
  2527. * @param motorSpeed
  2528. * @param maxMotorForce
  2529. */
  2530. setMotor:function(motorSpeed,maxMotorForce){
  2531. this.motorSpeed=motorSpeed;
  2532. this.maxMotorForce=maxMotorForce;
  2533. },
  2534. /**
  2535. * Set spring data into this constraint.
  2536. * @param frequency
  2537. * @param dampingRatio
  2538. */
  2539. setSpring:function(frequency,dampingRatio){
  2540. this.frequency=frequency;
  2541. this.dampingRatio=dampingRatio;
  2542. }
  2543. }
  2544. /**
  2545. * A ball-and-socket joint limits relative translation on two anchor points on rigid bodies.
  2546. * @author saharan
  2547. */
  2548. OIMO.BallAndSocketJoint = function(config){
  2549. OIMO.Joint.call( this, config);
  2550. this.type=this.JOINT_BALL_AND_SOCKET;
  2551. this.lc=new OIMO.LinearConstraint(this);
  2552. }
  2553. OIMO.BallAndSocketJoint.prototype = Object.create( OIMO.Joint.prototype );
  2554. OIMO.BallAndSocketJoint.prototype.preSolve = function (timeStep,invTimeStep) {
  2555. this.updateAnchorPoints();
  2556. this.lc.preSolve(timeStep,invTimeStep);
  2557. }
  2558. OIMO.BallAndSocketJoint.prototype.solve = function () {
  2559. this.lc.solve();
  2560. }
  2561. OIMO.BallAndSocketJoint.prototype.postSolve = function () {
  2562. }
  2563. /**
  2564. * A distance joint limits the distance between two anchor points on rigid bodies.
  2565. * @author saharan
  2566. */
  2567. OIMO.DistanceJoint = function(config,minDistance,maxDistance){
  2568. OIMO.Joint.call( this, config);
  2569. this.type=this.JOINT_DISTANCE;
  2570. this.normal=new OIMO.Vec3();
  2571. // The limit and motor information of the joint.
  2572. this.limitMotor=new OIMO.LimitMotor(this.normal,true);
  2573. this.limitMotor.lowerLimit=minDistance;
  2574. this.limitMotor.upperLimit=maxDistance;
  2575. this.t=new OIMO.TranslationalConstraint(this,this.limitMotor);
  2576. }
  2577. OIMO.DistanceJoint.prototype = Object.create( OIMO.Joint.prototype );
  2578. OIMO.DistanceJoint.prototype.preSolve = function (timeStep,invTimeStep) {
  2579. this.updateAnchorPoints();
  2580. var nx=this.anchorPoint2.x-this.anchorPoint1.x;
  2581. var ny=this.anchorPoint2.y-this.anchorPoint1.y;
  2582. var nz=this.anchorPoint2.z-this.anchorPoint1.z;
  2583. var len=Math.sqrt(nx*nx+ny*ny+nz*nz);
  2584. if(len>0)len=1/len;
  2585. this.normal.init(nx*len,ny*len,nz*len);
  2586. this.t.preSolve(timeStep,invTimeStep);
  2587. }
  2588. OIMO.DistanceJoint.prototype.solve = function () {
  2589. this.t.solve();
  2590. }
  2591. OIMO.DistanceJoint.prototype.postSolve = function () {
  2592. }
  2593. /**
  2594. * A hinge joint allows only for relative rotation of rigid bodies along the axis.
  2595. * @author saharan
  2596. */
  2597. OIMO.HingeJoint = function(config,lowerAngleLimit,upperAngleLimit){
  2598. OIMO.Joint.call( this, config);
  2599. this.type=this.JOINT_HINGE;
  2600. // The axis in the first body's coordinate system.
  2601. this.localAxis1=new OIMO.Vec3().normalize(config.localAxis1);
  2602. // The axis in the second body's coordinate system.
  2603. this.localAxis2=new OIMO.Vec3().normalize(config.localAxis2);
  2604. var len;
  2605. this.localAxis1X=this.localAxis1.x;
  2606. this.localAxis1Y=this.localAxis1.y;
  2607. this.localAxis1Z=this.localAxis1.z;
  2608. this.localAngAxis1X=this.localAxis1Y*this.localAxis1X-this.localAxis1Z*this.localAxis1Z;
  2609. this.localAngAxis1Y=-this.localAxis1Z*this.localAxis1Y-this.localAxis1X*this.localAxis1X;
  2610. this.localAngAxis1Z=this.localAxis1X*this.localAxis1Z+this.localAxis1Y*this.localAxis1Y;
  2611. len=1/Math.sqrt(this.localAngAxis1X*this.localAngAxis1X+this.localAngAxis1Y*this.localAngAxis1Y+this.localAngAxis1Z*this.localAngAxis1Z);
  2612. this.localAngAxis1X*=len;
  2613. this.localAngAxis1Y*=len;
  2614. this.localAngAxis1Z*=len;
  2615. this.localAxis2X=this.localAxis2.x;
  2616. this.localAxis2Y=this.localAxis2.y;
  2617. this.localAxis2Z=this.localAxis2.z;
  2618. // make angle axis 2
  2619. var arc=new OIMO.Mat33().setQuat(new OIMO.Quat().arc(this.localAxis1,this.localAxis2));
  2620. var tarc = arc.elements;
  2621. this.localAngAxis2X=this.localAngAxis1X*tarc[0]+this.localAngAxis1Y*tarc[1]+this.localAngAxis1Z*tarc[2];
  2622. this.localAngAxis2Y=this.localAngAxis1X*tarc[3]+this.localAngAxis1Y*tarc[4]+this.localAngAxis1Z*tarc[5];
  2623. this.localAngAxis2Z=this.localAngAxis1X*tarc[6]+this.localAngAxis1Y*tarc[7]+this.localAngAxis1Z*tarc[8];
  2624. this.nor=new OIMO.Vec3();
  2625. this.tan=new OIMO.Vec3();
  2626. this.bin=new OIMO.Vec3();
  2627. // The rotational limit and motor information of the joint.
  2628. this.limitMotor=new OIMO.LimitMotor(this.nor,false);
  2629. this.limitMotor.lowerLimit=lowerAngleLimit;
  2630. this.limitMotor.upperLimit=upperAngleLimit;
  2631. this.lc=new OIMO.LinearConstraint(this);
  2632. this.r3=new OIMO.Rotational3Constraint(this,this.limitMotor,new OIMO.LimitMotor(this.tan,true),new OIMO.LimitMotor(this.bin,true));
  2633. }
  2634. OIMO.HingeJoint.prototype = Object.create( OIMO.Joint.prototype );
  2635. OIMO.HingeJoint.prototype.preSolve = function (timeStep,invTimeStep) {
  2636. var tmpM;
  2637. var tmp1X;
  2638. var tmp1Y;
  2639. var tmp1Z;
  2640. this.updateAnchorPoints();
  2641. tmpM=this.body1.rotation.elements;
  2642. var axis1X=this.localAxis1X*tmpM[0]+this.localAxis1Y*tmpM[1]+this.localAxis1Z*tmpM[2];
  2643. var axis1Y=this.localAxis1X*tmpM[3]+this.localAxis1Y*tmpM[4]+this.localAxis1Z*tmpM[5];
  2644. var axis1Z=this.localAxis1X*tmpM[6]+this.localAxis1Y*tmpM[7]+this.localAxis1Z*tmpM[8];
  2645. var angAxis1X=this.localAngAxis1X*tmpM[0]+this.localAngAxis1Y*tmpM[1]+this.localAngAxis1Z*tmpM[2];
  2646. var angAxis1Y=this.localAngAxis1X*tmpM[3]+this.localAngAxis1Y*tmpM[4]+this.localAngAxis1Z*tmpM[5];
  2647. var angAxis1Z=this.localAngAxis1X*tmpM[6]+this.localAngAxis1Y*tmpM[7]+this.localAngAxis1Z*tmpM[8];
  2648. tmpM=this.body2.rotation.elements;
  2649. var axis2X=this.localAxis2X*tmpM[0]+this.localAxis2Y*tmpM[1]+this.localAxis2Z*tmpM[2];
  2650. var axis2Y=this.localAxis2X*tmpM[3]+this.localAxis2Y*tmpM[4]+this.localAxis2Z*tmpM[5];
  2651. var axis2Z=this.localAxis2X*tmpM[6]+this.localAxis2Y*tmpM[7]+this.localAxis2Z*tmpM[8];
  2652. var angAxis2X=this.localAngAxis2X*tmpM[0]+this.localAngAxis2Y*tmpM[1]+this.localAngAxis2Z*tmpM[2];
  2653. var angAxis2Y=this.localAngAxis2X*tmpM[3]+this.localAngAxis2Y*tmpM[4]+this.localAngAxis2Z*tmpM[5];
  2654. var angAxis2Z=this.localAngAxis2X*tmpM[6]+this.localAngAxis2Y*tmpM[7]+this.localAngAxis2Z*tmpM[8];
  2655. var nx=axis1X*this.body2.inverseMass+axis2X*this.body1.inverseMass;
  2656. var ny=axis1Y*this.body2.inverseMass+axis2Y*this.body1.inverseMass;
  2657. var nz=axis1Z*this.body2.inverseMass+axis2Z*this.body1.inverseMass;
  2658. tmp1X=Math.sqrt(nx*nx+ny*ny+nz*nz);
  2659. if(tmp1X>0)tmp1X=1/tmp1X;
  2660. nx*=tmp1X;
  2661. ny*=tmp1X;
  2662. nz*=tmp1X;
  2663. var tx=ny*nx-nz*nz;
  2664. var ty=-nz*ny-nx*nx;
  2665. var tz=nx*nz+ny*ny;
  2666. tmp1X=1/Math.sqrt(tx*tx+ty*ty+tz*tz);
  2667. tx*=tmp1X;
  2668. ty*=tmp1X;
  2669. tz*=tmp1X;
  2670. var bx=ny*tz-nz*ty;
  2671. var by=nz*tx-nx*tz;
  2672. var bz=nx*ty-ny*tx;
  2673. this.nor.init(nx,ny,nz);
  2674. this.tan.init(tx,ty,tz);
  2675. this.bin.init(bx,by,bz);
  2676. // ----------------------------------------------
  2677. // calculate hinge angle
  2678. // ----------------------------------------------
  2679. if(
  2680. nx*(angAxis1Y*angAxis2Z-angAxis1Z*angAxis2Y)+
  2681. ny*(angAxis1Z*angAxis2X-angAxis1X*angAxis2Z)+
  2682. nz*(angAxis1X*angAxis2Y-angAxis1Y*angAxis2X)<0
  2683. ){
  2684. this.limitMotor.angle=-this.acosClamp(angAxis1X*angAxis2X+angAxis1Y*angAxis2Y+angAxis1Z*angAxis2Z);
  2685. }else{
  2686. this.limitMotor.angle=this.acosClamp(angAxis1X*angAxis2X+angAxis1Y*angAxis2Y+angAxis1Z*angAxis2Z);
  2687. }
  2688. // angular error
  2689. tmp1X=axis1Y*axis2Z-axis1Z*axis2Y;
  2690. tmp1Y=axis1Z*axis2X-axis1X*axis2Z;
  2691. tmp1Z=axis1X*axis2Y-axis1Y*axis2X;
  2692. this.r3.limitMotor2.angle=tx*tmp1X+ty*tmp1Y+tz*tmp1Z;
  2693. this.r3.limitMotor3.angle=bx*tmp1X+by*tmp1Y+bz*tmp1Z;
  2694. this.r3.preSolve(timeStep,invTimeStep);
  2695. this.lc.preSolve(timeStep,invTimeStep);
  2696. }
  2697. OIMO.HingeJoint.prototype.solve = function () {
  2698. this.r3.solve();
  2699. this.lc.solve();
  2700. }
  2701. OIMO.HingeJoint.prototype.postSolve = function () {
  2702. }
  2703. OIMO.HingeJoint.prototype.acosClamp = function(cos){
  2704. if(cos>1)return 0;
  2705. else if(cos<-1)return Math.PI;
  2706. else return Math.acos(cos);
  2707. }
  2708. /**
  2709. * A prismatic joint allows only for relative translation of rigid bodies along the axis.
  2710. * @author saharan
  2711. */
  2712. OIMO.PrismaticJoint = function(config,lowerTranslation,upperTranslation){
  2713. OIMO.Joint.call( this, config);
  2714. this.type=this.JOINT_PRISMATIC;
  2715. // The axis in the first body's coordinate system.
  2716. this.localAxis1=new OIMO.Vec3().normalize(config.localAxis1);
  2717. // The axis in the second body's coordinate system.
  2718. this.localAxis2=new OIMO.Vec3().normalize(config.localAxis2);
  2719. this.localAxis1X=this.localAxis1.x;
  2720. this.localAxis1Y=this.localAxis1.y;
  2721. this.localAxis1Z=this.localAxis1.z;
  2722. this.localAxis2X=this.localAxis2.x;
  2723. this.localAxis2Y=this.localAxis2.y;
  2724. this.localAxis2Z=this.localAxis2.z;
  2725. this.nor=new OIMO.Vec3();
  2726. this.tan=new OIMO.Vec3();
  2727. this.bin=new OIMO.Vec3();
  2728. this.ac=new OIMO.AngularConstraint(this,new OIMO.Quat().arc(this.localAxis1,this.localAxis2));
  2729. // The translational limit and motor information of the joint.
  2730. this.limitMotor=new OIMO.LimitMotor(this.nor,true);
  2731. this.limitMotor.lowerLimit=lowerTranslation;
  2732. this.limitMotor.upperLimit=upperTranslation;
  2733. this.t3=new OIMO.Translational3Constraint(this,this.limitMotor,new OIMO.LimitMotor(this.tan,true),new OIMO.LimitMotor(this.bin,true));
  2734. }
  2735. OIMO.PrismaticJoint.prototype = Object.create( OIMO.Joint.prototype );
  2736. OIMO.PrismaticJoint.prototype.preSolve = function (timeStep,invTimeStep) {
  2737. var tmpM;
  2738. var tmp1X;
  2739. var tmp1Y;
  2740. var tmp1Z;
  2741. this.updateAnchorPoints();
  2742. tmpM=this.body1.rotation.elements;
  2743. var axis1X=this.localAxis1X*tmpM[0]+this.localAxis1Y*tmpM[1]+this.localAxis1Z*tmpM[2];
  2744. var axis1Y=this.localAxis1X*tmpM[3]+this.localAxis1Y*tmpM[4]+this.localAxis1Z*tmpM[5];
  2745. var axis1Z=this.localAxis1X*tmpM[6]+this.localAxis1Y*tmpM[7]+this.localAxis1Z*tmpM[8];
  2746. tmpM=this.body2.rotation.elements;
  2747. var axis2X=this.localAxis2X*tmpM[0]+this.localAxis2Y*tmpM[1]+this.localAxis2Z*tmpM[2];
  2748. var axis2Y=this.localAxis2X*tmpM[3]+this.localAxis2Y*tmpM[4]+this.localAxis2Z*tmpM[5];
  2749. var axis2Z=this.localAxis2X*tmpM[6]+this.localAxis2Y*tmpM[7]+this.localAxis2Z*tmpM[8];
  2750. var nx=axis1X*this.body2.inverseMass+axis2X*this.body1.inverseMass;
  2751. var ny=axis1Y*this.body2.inverseMass+axis2Y*this.body1.inverseMass;
  2752. var nz=axis1Z*this.body2.inverseMass+axis2Z*this.body1.inverseMass;
  2753. tmp1X=Math.sqrt(nx*nx+ny*ny+nz*nz);
  2754. if(tmp1X>0)tmp1X=1/tmp1X;
  2755. nx*=tmp1X;
  2756. ny*=tmp1X;
  2757. nz*=tmp1X;
  2758. var tx=ny*nx-nz*nz;
  2759. var ty=-nz*ny-nx*nx;
  2760. var tz=nx*nz+ny*ny;
  2761. tmp1X=1/Math.sqrt(tx*tx+ty*ty+tz*tz);
  2762. tx*=tmp1X;
  2763. ty*=tmp1X;
  2764. tz*=tmp1X;
  2765. var bx=ny*tz-nz*ty;
  2766. var by=nz*tx-nx*tz;
  2767. var bz=nx*ty-ny*tx;
  2768. this.nor.init(nx,ny,nz);
  2769. this.tan.init(tx,ty,tz);
  2770. this.bin.init(bx,by,bz);
  2771. this.ac.preSolve(timeStep,invTimeStep);
  2772. this.t3.preSolve(timeStep,invTimeStep);
  2773. }
  2774. OIMO.PrismaticJoint.prototype.solve = function () {
  2775. this.ac.solve();
  2776. this.t3.solve();
  2777. }
  2778. OIMO.PrismaticJoint.prototype.postSolve = function () {
  2779. }
  2780. /**
  2781. * A slider joint allows for relative translation and relative rotation between two rigid bodies along the axis.
  2782. * @author saharan
  2783. */
  2784. OIMO.SliderJoint = function(config,lowerTranslation,upperTranslation){
  2785. OIMO.Joint.call( this, config);
  2786. this.type=this.JOINT_SLIDER;
  2787. // The first axis in local coordinate system.
  2788. this.localAxis1=new OIMO.Vec3().normalize(config.localAxis1);
  2789. // The second axis in local coordinate system.
  2790. this.localAxis2=new OIMO.Vec3().normalize(config.localAxis2);
  2791. var len;
  2792. this.localAxis1X=this.localAxis1.x;
  2793. this.localAxis1Y=this.localAxis1.y;
  2794. this.localAxis1Z=this.localAxis1.z;
  2795. this.localAngAxis1X=this.localAxis1Y*this.localAxis1X-this.localAxis1Z*this.localAxis1Z;
  2796. this.localAngAxis1Y=-this.localAxis1Z*this.localAxis1Y-this.localAxis1X*this.localAxis1X;
  2797. this.localAngAxis1Z=this.localAxis1X*this.localAxis1Z+this.localAxis1Y*this.localAxis1Y;
  2798. len=1/Math.sqrt(this.localAngAxis1X*this.localAngAxis1X+this.localAngAxis1Y*this.localAngAxis1Y+this.localAngAxis1Z*this.localAngAxis1Z);
  2799. this.localAngAxis1X*=len;
  2800. this.localAngAxis1Y*=len;
  2801. this.localAngAxis1Z*=len;
  2802. this.localAxis2X=this.localAxis2.x;
  2803. this.localAxis2Y=this.localAxis2.y;
  2804. this.localAxis2Z=this.localAxis2.z;
  2805. // make angle axis 2
  2806. var arc=new OIMO.Mat33().setQuat(new OIMO.Quat().arc(this.localAxis1,this.localAxis2));
  2807. var tarc = arc.elements;
  2808. this.localAngAxis2X=this.localAngAxis1X*tarc[0]+this.localAngAxis1Y*tarc[1]+this.localAngAxis1Z*tarc[2];
  2809. this.localAngAxis2Y=this.localAngAxis1X*tarc[3]+this.localAngAxis1Y*tarc[4]+this.localAngAxis1Z*tarc[5];
  2810. this.localAngAxis2Z=this.localAngAxis1X*tarc[6]+this.localAngAxis1Y*tarc[7]+this.localAngAxis1Z*tarc[8];
  2811. this.nor=new OIMO.Vec3();
  2812. this.tan=new OIMO.Vec3();
  2813. this.bin=new OIMO.Vec3();
  2814. // The limit and motor for the rotation
  2815. this.rotationalLimitMotor=new OIMO.LimitMotor(this.nor,false);
  2816. this.r3=new OIMO.Rotational3Constraint(this,this.rotationalLimitMotor,new OIMO.LimitMotor(this.tan,true),new OIMO.LimitMotor(this.bin,true));
  2817. // The limit and motor for the translation.
  2818. this.translationalLimitMotor=new OIMO.LimitMotor(this.nor,true);
  2819. this.translationalLimitMotor.lowerLimit=lowerTranslation;
  2820. this.translationalLimitMotor.upperLimit=upperTranslation;
  2821. this.t3=new OIMO.Translational3Constraint(this,this.translationalLimitMotor,new OIMO.LimitMotor(this.tan,true),new OIMO.LimitMotor(this.bin,true));
  2822. }
  2823. OIMO.SliderJoint.prototype = Object.create( OIMO.Joint.prototype );
  2824. OIMO.SliderJoint.prototype.preSolve = function (timeStep,invTimeStep) {
  2825. var tmpM;
  2826. var tmp1X;
  2827. var tmp1Y;
  2828. var tmp1Z;
  2829. this.updateAnchorPoints();
  2830. tmpM=this.body1.rotation.elements;
  2831. var axis1X=this.localAxis1X*tmpM[0]+this.localAxis1Y*tmpM[1]+this.localAxis1Z*tmpM[2];
  2832. var axis1Y=this.localAxis1X*tmpM[3]+this.localAxis1Y*tmpM[4]+this.localAxis1Z*tmpM[5];
  2833. var axis1Z=this.localAxis1X*tmpM[6]+this.localAxis1Y*tmpM[7]+this.localAxis1Z*tmpM[8];
  2834. var angAxis1X=this.localAngAxis1X*tmpM[0]+this.localAngAxis1Y*tmpM[1]+this.localAngAxis1Z*tmpM[2];
  2835. var angAxis1Y=this.localAngAxis1X*tmpM[3]+this.localAngAxis1Y*tmpM[4]+this.localAngAxis1Z*tmpM[5];
  2836. var angAxis1Z=this.localAngAxis1X*tmpM[6]+this.localAngAxis1Y*tmpM[7]+this.localAngAxis1Z*tmpM[8];
  2837. tmpM=this.body2.rotation.elements;
  2838. var axis2X=this.localAxis2X*tmpM[0]+this.localAxis2Y*tmpM[1]+this.localAxis2Z*tmpM[2];
  2839. var axis2Y=this.localAxis2X*tmpM[3]+this.localAxis2Y*tmpM[4]+this.localAxis2Z*tmpM[5];
  2840. var axis2Z=this.localAxis2X*tmpM[6]+this.localAxis2Y*tmpM[7]+this.localAxis2Z*tmpM[8];
  2841. var angAxis2X=this.localAngAxis2X*tmpM[0]+this.localAngAxis2Y*tmpM[1]+this.localAngAxis2Z*tmpM[2];
  2842. var angAxis2Y=this.localAngAxis2X*tmpM[3]+this.localAngAxis2Y*tmpM[4]+this.localAngAxis2Z*tmpM[5];
  2843. var angAxis2Z=this.localAngAxis2X*tmpM[6]+this.localAngAxis2Y*tmpM[7]+this.localAngAxis2Z*tmpM[8];
  2844. var nx=axis1X*this.body2.inverseMass+axis2X*this.body1.inverseMass;
  2845. var ny=axis1Y*this.body2.inverseMass+axis2Y*this.body1.inverseMass;
  2846. var nz=axis1Z*this.body2.inverseMass+axis2Z*this.body1.inverseMass;
  2847. tmp1X=Math.sqrt(nx*nx+ny*ny+nz*nz);
  2848. if(tmp1X>0)tmp1X=1/tmp1X;
  2849. nx*=tmp1X;
  2850. ny*=tmp1X;
  2851. nz*=tmp1X;
  2852. var tx=ny*nx-nz*nz;
  2853. var ty=-nz*ny-nx*nx;
  2854. var tz=nx*nz+ny*ny;
  2855. tmp1X=1/Math.sqrt(tx*tx+ty*ty+tz*tz);
  2856. tx*=tmp1X;
  2857. ty*=tmp1X;
  2858. tz*=tmp1X;
  2859. var bx=ny*tz-nz*ty;
  2860. var by=nz*tx-nx*tz;
  2861. var bz=nx*ty-ny*tx;
  2862. this.nor.init(nx,ny,nz);
  2863. this.tan.init(tx,ty,tz);
  2864. this.bin.init(bx,by,bz);
  2865. // ----------------------------------------------
  2866. // calculate hinge angle
  2867. // ----------------------------------------------
  2868. if(
  2869. nx*(angAxis1Y*angAxis2Z-angAxis1Z*angAxis2Y)+
  2870. ny*(angAxis1Z*angAxis2X-angAxis1X*angAxis2Z)+
  2871. nz*(angAxis1X*angAxis2Y-angAxis1Y*angAxis2X)<0
  2872. ){
  2873. this.rotationalLimitMotor.angle=-this.acosClamp(angAxis1X*angAxis2X+angAxis1Y*angAxis2Y+angAxis1Z*angAxis2Z);
  2874. }else{
  2875. this.rotationalLimitMotor.angle=this.acosClamp(angAxis1X*angAxis2X+angAxis1Y*angAxis2Y+angAxis1Z*angAxis2Z);
  2876. }
  2877. // angular error
  2878. tmp1X=axis1Y*axis2Z-axis1Z*axis2Y;
  2879. tmp1Y=axis1Z*axis2X-axis1X*axis2Z;
  2880. tmp1Z=axis1X*axis2Y-axis1Y*axis2X;
  2881. this.r3.limitMotor2.angle=tx*tmp1X+ty*tmp1Y+tz*tmp1Z;
  2882. this.r3.limitMotor3.angle=bx*tmp1X+by*tmp1Y+bz*tmp1Z;
  2883. this.r3.preSolve(timeStep,invTimeStep);
  2884. this.t3.preSolve(timeStep,invTimeStep);
  2885. }
  2886. OIMO.SliderJoint.prototype.solve = function () {
  2887. this.r3.solve();
  2888. this.t3.solve();
  2889. }
  2890. OIMO.SliderJoint.prototype.postSolve = function () {
  2891. }
  2892. OIMO.SliderJoint.prototype.acosClamp = function(cos){
  2893. if(cos>1)return 0;
  2894. else if(cos<-1)return Math.PI;
  2895. else return Math.acos(cos);
  2896. }
  2897. /**
  2898. * A wheel joint allows for relative rotation between two rigid bodies along two axes.
  2899. * The wheel joint also allows for relative translation for the suspension.
  2900. */
  2901. OIMO.WheelJoint = function(config){
  2902. OIMO.Joint.call( this, config);
  2903. this.type=this.JOINT_WHEEL;
  2904. // The first axis in local coordinate system.
  2905. this.localAxis1=new OIMO.Vec3().normalize(config.localAxis1);
  2906. // The second axis in local coordinate system.
  2907. this.localAxis2=new OIMO.Vec3().normalize(config.localAxis2);
  2908. var len;
  2909. this.localAxis1X=this.localAxis1.x;
  2910. this.localAxis1Y=this.localAxis1.y;
  2911. this.localAxis1Z=this.localAxis1.z;
  2912. this.localAxis2X=this.localAxis2.x;
  2913. this.localAxis2Y=this.localAxis2.y;
  2914. this.localAxis2Z=this.localAxis2.z;
  2915. var dot=this.localAxis1X*this.localAxis2X+this.localAxis1Y*this.localAxis2Y+this.localAxis1Z*this.localAxis2Z;
  2916. if(dot>-1&&dot<1){
  2917. this.localAngAxis1X=this.localAxis2X-dot*this.localAxis1X;
  2918. this.localAngAxis1Y=this.localAxis2Y-dot*this.localAxis1Y;
  2919. this.localAngAxis1Z=this.localAxis2Z-dot*this.localAxis1Z;
  2920. this.localAngAxis2X=this.localAxis1X-dot*this.localAxis2X;
  2921. this.localAngAxis2Y=this.localAxis1Y-dot*this.localAxis2Y;
  2922. this.localAngAxis2Z=this.localAxis1Z-dot*this.localAxis2Z;
  2923. len=1/Math.sqrt(this.localAngAxis1X*this.localAngAxis1X+this.localAngAxis1Y*this.localAngAxis1Y+this.localAngAxis1Z*this.localAngAxis1Z);
  2924. this.localAngAxis1X*=len;
  2925. this.localAngAxis1Y*=len;
  2926. this.localAngAxis1Z*=len;
  2927. len=1/Math.sqrt(this.localAngAxis2X*this.localAngAxis2X+this.localAngAxis2Y*this.localAngAxis2Y+this.localAngAxis2Z*this.localAngAxis2Z);
  2928. this.localAngAxis2X*=len;
  2929. this.localAngAxis2Y*=len;
  2930. this.localAngAxis2Z*=len;
  2931. }else{
  2932. this.localAngAxis1X=this.localAxis1Y*this.localAxis1X-this.localAxis1Z*this.localAxis1Z;
  2933. this.localAngAxis1Y=-this.localAxis1Z*this.localAxis1Y-this.localAxis1X*this.localAxis1X;
  2934. this.localAngAxis1Z=this.localAxis1X*this.localAxis1Z+this.localAxis1Y*this.localAxis1Y;
  2935. len=1/Math.sqrt(this.localAngAxis1X*this.localAngAxis1X+this.localAngAxis1Y*this.localAngAxis1Y+this.localAngAxis1Z*this.localAngAxis1Z);
  2936. this.localAngAxis1X*=len;
  2937. this.localAngAxis1Y*=len;
  2938. this.localAngAxis1Z*=len;
  2939. var arc=new OIMO.Mat33().setQuat(new OIMO.Quat().arc(this.localAxis1,this.localAxis2));
  2940. var tarc = arc.elements;
  2941. this.localAngAxis2X=this.localAngAxis1X*tarc[0]+this.localAngAxis1Y*tarc[1]+this.localAngAxis1Z*tarc[2];
  2942. this.localAngAxis2Y=this.localAngAxis1X*tarc[3]+this.localAngAxis1Y*tarc[4]+this.localAngAxis1Z*tarc[5];
  2943. this.localAngAxis2Z=this.localAngAxis1X*tarc[6]+this.localAngAxis1Y*tarc[7]+this.localAngAxis1Z*tarc[8];
  2944. }
  2945. this.nor=new OIMO.Vec3();
  2946. this.tan=new OIMO.Vec3();
  2947. this.bin=new OIMO.Vec3();
  2948. // The translational limit and motor information of the joint.
  2949. this.translationalLimitMotor=new OIMO.LimitMotor(this.tan,true);
  2950. this.translationalLimitMotor.frequency=8;
  2951. this.translationalLimitMotor.dampingRatio=1;
  2952. // The first rotational limit and motor information of the joint.
  2953. this.rotationalLimitMotor1=new OIMO.LimitMotor(this.tan,false);
  2954. // The second rotational limit and motor information of the joint.
  2955. this.rotationalLimitMotor2=new OIMO.LimitMotor(this.bin,false);
  2956. this.t3=new OIMO.Translational3Constraint(this,new OIMO.LimitMotor(this.nor,true),this.translationalLimitMotor,new OIMO.LimitMotor(this.bin,true));
  2957. this.t3.weight=1;
  2958. this.r3=new OIMO.Rotational3Constraint(this,new OIMO.LimitMotor(this.nor,true),this.rotationalLimitMotor1,this.rotationalLimitMotor2);
  2959. }
  2960. OIMO.WheelJoint.prototype = Object.create( OIMO.Joint.prototype );
  2961. OIMO.WheelJoint.prototype.preSolve = function (timeStep,invTimeStep) {
  2962. var tmpM;
  2963. var tmp1X;
  2964. var tmp1Y;
  2965. var tmp1Z;
  2966. this.updateAnchorPoints();
  2967. tmpM=this.body1.rotation.elements;
  2968. var x1=this.localAxis1X*tmpM[0]+this.localAxis1Y*tmpM[1]+this.localAxis1Z*tmpM[2];
  2969. var y1=this.localAxis1X*tmpM[3]+this.localAxis1Y*tmpM[4]+this.localAxis1Z*tmpM[5];
  2970. var z1=this.localAxis1X*tmpM[6]+this.localAxis1Y*tmpM[7]+this.localAxis1Z*tmpM[8];
  2971. var angAxis1X=this.localAngAxis1X*tmpM[0]+this.localAngAxis1Y*tmpM[1]+this.localAngAxis1Z*tmpM[2];
  2972. var angAxis1Y=this.localAngAxis1X*tmpM[3]+this.localAngAxis1Y*tmpM[4]+this.localAngAxis1Z*tmpM[5];
  2973. var angAxis1Z=this.localAngAxis1X*tmpM[6]+this.localAngAxis1Y*tmpM[7]+this.localAngAxis1Z*tmpM[8];
  2974. tmpM=this.body2.rotation.elements;
  2975. var x2=this.localAxis2X*tmpM[0]+this.localAxis2Y*tmpM[1]+this.localAxis2Z*tmpM[2];
  2976. var y2=this.localAxis2X*tmpM[3]+this.localAxis2Y*tmpM[4]+this.localAxis2Z*tmpM[5];
  2977. var z2=this.localAxis2X*tmpM[6]+this.localAxis2Y*tmpM[7]+this.localAxis2Z*tmpM[8];
  2978. var angAxis2X=this.localAngAxis2X*tmpM[0]+this.localAngAxis2Y*tmpM[1]+this.localAngAxis2Z*tmpM[2];
  2979. var angAxis2Y=this.localAngAxis2X*tmpM[3]+this.localAngAxis2Y*tmpM[4]+this.localAngAxis2Z*tmpM[5];
  2980. var angAxis2Z=this.localAngAxis2X*tmpM[6]+this.localAngAxis2Y*tmpM[7]+this.localAngAxis2Z*tmpM[8];
  2981. this.r3.limitMotor1.angle=x1*x2+y1*y2+z1*z2;
  2982. if( x1*(angAxis1Y*z2-angAxis1Z*y2)+ y1*(angAxis1Z*x2-angAxis1X*z2)+ z1*(angAxis1X*y2-angAxis1Y*x2)<0 ){
  2983. this.rotationalLimitMotor1.angle=-this.acosClamp(angAxis1X*x2+angAxis1Y*y2+angAxis1Z*z2);
  2984. }else{
  2985. this.rotationalLimitMotor1.angle=this.acosClamp(angAxis1X*x2+angAxis1Y*y2+angAxis1Z*z2);
  2986. }
  2987. if( x2*(angAxis2Y*z1-angAxis2Z*y1)+ y2*(angAxis2Z*x1-angAxis2X*z1)+ z2*(angAxis2X*y1-angAxis2Y*x1)<0 ){
  2988. this.rotationalLimitMotor2.angle=this.acosClamp(angAxis2X*x1+angAxis2Y*y1+angAxis2Z*z1);
  2989. }else{
  2990. this.rotationalLimitMotor2.angle=-this.acosClamp(angAxis2X*x1+angAxis2Y*y1+angAxis2Z*z1);
  2991. }
  2992. var nx=y2*z1-z2*y1;
  2993. var ny=z2*x1-x2*z1;
  2994. var nz=x2*y1-y2*x1;
  2995. tmp1X=Math.sqrt(nx*nx+ny*ny+nz*nz);
  2996. if(tmp1X>0)tmp1X=1/tmp1X;
  2997. nx*=tmp1X;
  2998. ny*=tmp1X;
  2999. nz*=tmp1X;
  3000. var tx=ny*z2-nz*y2;
  3001. var ty=nz*x2-nx*z2;
  3002. var tz=nx*y2-ny*x2;
  3003. tmp1X=Math.sqrt(tx*tx+ty*ty+tz*tz);
  3004. if(tmp1X>0)tmp1X=1/tmp1X;
  3005. tx*=tmp1X;
  3006. ty*=tmp1X;
  3007. tz*=tmp1X;
  3008. var bx=y1*nz-z1*ny;
  3009. var by=z1*nx-x1*nz;
  3010. var bz=x1*ny-y1*nx;
  3011. tmp1X=Math.sqrt(bx*bx+by*by+bz*bz);
  3012. if(tmp1X>0)tmp1X=1/tmp1X;
  3013. bx*=tmp1X;
  3014. by*=tmp1X;
  3015. bz*=tmp1X;
  3016. this.nor.init(nx,ny,nz);
  3017. this.tan.init(tx,ty,tz);
  3018. this.bin.init(bx,by,bz);
  3019. this.r3.preSolve(timeStep,invTimeStep);
  3020. this.t3.preSolve(timeStep,invTimeStep);
  3021. }
  3022. OIMO.WheelJoint.prototype.solve = function () {
  3023. this.r3.solve();
  3024. this.t3.solve();
  3025. }
  3026. OIMO.WheelJoint.prototype.postSolve = function () {
  3027. }
  3028. OIMO.WheelJoint.prototype.acosClamp = function(cos){
  3029. if(cos>1)return 0;
  3030. else if(cos<-1)return Math.PI;
  3031. else return Math.acos(cos);
  3032. }
  3033. /**
  3034. * An angular constraint for all axes for various joints.
  3035. * @author saharan
  3036. */
  3037. OIMO.AngularConstraint = function(joint,targetOrientation){
  3038. this.i1e00=NaN;
  3039. this.i1e01=NaN;
  3040. this.i1e02=NaN;
  3041. this.i1e10=NaN;
  3042. this.i1e11=NaN;
  3043. this.i1e12=NaN;
  3044. this.i1e20=NaN;
  3045. this.i1e21=NaN;
  3046. this.i1e22=NaN;
  3047. this.i2e00=NaN;
  3048. this.i2e01=NaN;
  3049. this.i2e02=NaN;
  3050. this.i2e10=NaN;
  3051. this.i2e11=NaN;
  3052. this.i2e12=NaN;
  3053. this.i2e20=NaN;
  3054. this.i2e21=NaN;
  3055. this.i2e22=NaN;
  3056. this.d00=NaN;
  3057. this.d01=NaN;
  3058. this.d02=NaN;
  3059. this.d10=NaN;
  3060. this.d11=NaN;
  3061. this.d12=NaN;
  3062. this.d20=NaN;
  3063. this.d21=NaN;
  3064. this.d22=NaN;
  3065. this.ax=NaN;
  3066. this.ay=NaN;
  3067. this.az=NaN;
  3068. this.velx=NaN;
  3069. this.vely=NaN;
  3070. this.velz=NaN;
  3071. this.joint=joint;
  3072. this.targetOrientation=new OIMO.Quat().invert(targetOrientation);
  3073. this.relativeOrientation=new OIMO.Quat();
  3074. this.b1=joint.body1;
  3075. this.b2=joint.body2;
  3076. this.a1=this.b1.angularVelocity;
  3077. this.a2=this.b2.angularVelocity;
  3078. this.i1=this.b1.inverseInertia;
  3079. this.i2=this.b2.inverseInertia;
  3080. this.impx=0;
  3081. this.impy=0;
  3082. this.impz=0;
  3083. }
  3084. OIMO.AngularConstraint.prototype = {
  3085. constructor: OIMO.AngularConstraint,
  3086. preSolve:function(timeStep,invTimeStep){
  3087. var ti1 = this.i1.elements;
  3088. var ti2 = this.i2.elements;
  3089. this.i1e00=ti1[0];
  3090. this.i1e01=ti1[1];
  3091. this.i1e02=ti1[2];
  3092. this.i1e10=ti1[3];
  3093. this.i1e11=ti1[4];
  3094. this.i1e12=ti1[5];
  3095. this.i1e20=ti1[6];
  3096. this.i1e21=ti1[7];
  3097. this.i1e22=ti1[8];
  3098. this.i2e00=ti2[0];
  3099. this.i2e01=ti2[1];
  3100. this.i2e02=ti2[2];
  3101. this.i2e10=ti2[3];
  3102. this.i2e11=ti2[4];
  3103. this.i2e12=ti2[5];
  3104. this.i2e20=ti2[6];
  3105. this.i2e21=ti2[7];
  3106. this.i2e22=ti2[8];
  3107. var v00=this.i1e00+this.i2e00;
  3108. var v01=this.i1e01+this.i2e01;
  3109. var v02=this.i1e02+this.i2e02;
  3110. var v10=this.i1e10+this.i2e10;
  3111. var v11=this.i1e11+this.i2e11;
  3112. var v12=this.i1e12+this.i2e12;
  3113. var v20=this.i1e20+this.i2e20;
  3114. var v21=this.i1e21+this.i2e21;
  3115. var v22=this.i1e22+this.i2e22;
  3116. var inv=1/(
  3117. v00*(v11*v22-v21*v12)+
  3118. v10*(v21*v02-v01*v22)+
  3119. v20*(v01*v12-v11*v02)
  3120. );
  3121. this.d00=(v11*v22-v12*v21)*inv;
  3122. this.d01=(v02*v21-v01*v22)*inv;
  3123. this.d02=(v01*v12-v02*v11)*inv;
  3124. this.d10=(v12*v20-v10*v22)*inv;
  3125. this.d11=(v00*v22-v02*v20)*inv;
  3126. this.d12=(v02*v10-v00*v12)*inv;
  3127. this.d20=(v10*v21-v11*v20)*inv;
  3128. this.d21=(v01*v20-v00*v21)*inv;
  3129. this.d22=(v00*v11-v01*v10)*inv;
  3130. this.relativeOrientation.invert(this.b1.orientation);// error = b2 - b1 - target
  3131. this.relativeOrientation.mul(this.targetOrientation,this.relativeOrientation);
  3132. this.relativeOrientation.mul(this.b2.orientation,this.relativeOrientation);
  3133. inv=this.relativeOrientation.s*2;
  3134. this.velx=this.relativeOrientation.x*inv;
  3135. this.vely=this.relativeOrientation.y*inv;
  3136. this.velz=this.relativeOrientation.z*inv;
  3137. var len=Math.sqrt(this.velx*this.velx+this.vely*this.vely+this.velz*this.velz);
  3138. if(len>0.02){
  3139. len=(0.02-len)/len*invTimeStep*0.05;
  3140. this.velx*=len;
  3141. this.vely*=len;
  3142. this.velz*=len;
  3143. }else{
  3144. this.velx=0;
  3145. this.vely=0;
  3146. this.velz=0;
  3147. }
  3148. this.a1.x+=this.impx*this.i1e00+this.impy*this.i1e01+this.impz*this.i1e02;
  3149. this.a1.y+=this.impx*this.i1e10+this.impy*this.i1e11+this.impz*this.i1e12;
  3150. this.a1.z+=this.impx*this.i1e20+this.impy*this.i1e21+this.impz*this.i1e22;
  3151. this.a2.x-=this.impx*this.i2e00+this.impy*this.i2e01+this.impz*this.i2e02;
  3152. this.a2.y-=this.impx*this.i2e10+this.impy*this.i2e11+this.impz*this.i2e12;
  3153. this.a2.z-=this.impx*this.i2e20+this.impy*this.i2e21+this.impz*this.i2e22;
  3154. },
  3155. solve:function(){
  3156. var rvx=this.a2.x-this.a1.x-this.velx;
  3157. var rvy=this.a2.y-this.a1.y-this.vely;
  3158. var rvz=this.a2.z-this.a1.z-this.velz;
  3159. var nimpx=rvx*this.d00+rvy*this.d01+rvz*this.d02;
  3160. var nimpy=rvx*this.d10+rvy*this.d11+rvz*this.d12;
  3161. var nimpz=rvx*this.d20+rvy*this.d21+rvz*this.d22;
  3162. this.impx+=nimpx;
  3163. this.impy+=nimpy;
  3164. this.impz+=nimpz;
  3165. this.a1.x+=nimpx*this.i1e00+nimpy*this.i1e01+nimpz*this.i1e02;
  3166. this.a1.y+=nimpx*this.i1e10+nimpy*this.i1e11+nimpz*this.i1e12;
  3167. this.a1.z+=nimpx*this.i1e20+nimpy*this.i1e21+nimpz*this.i1e22;
  3168. this.a2.x-=nimpx*this.i2e00+nimpy*this.i2e01+nimpz*this.i2e02;
  3169. this.a2.y-=nimpx*this.i2e10+nimpy*this.i2e11+nimpz*this.i2e12;
  3170. this.a2.z-=nimpx*this.i2e20+nimpy*this.i2e21+nimpz*this.i2e22;
  3171. }
  3172. }
  3173. /**
  3174. * A linear constraint for all axes for various joints.
  3175. * @author saharan
  3176. */
  3177. OIMO.LinearConstraint = function(joint){
  3178. this.m1=NaN;
  3179. this.m2=NaN;
  3180. this.i1e00=NaN;
  3181. this.i1e01=NaN;
  3182. this.i1e02=NaN;
  3183. this.i1e10=NaN;
  3184. this.i1e11=NaN;
  3185. this.i1e12=NaN;
  3186. this.i1e20=NaN;
  3187. this.i1e21=NaN;
  3188. this.i1e22=NaN;
  3189. this.i2e00=NaN;
  3190. this.i2e01=NaN;
  3191. this.i2e02=NaN;
  3192. this.i2e10=NaN;
  3193. this.i2e11=NaN;
  3194. this.i2e12=NaN;
  3195. this.i2e20=NaN;
  3196. this.i2e21=NaN;
  3197. this.i2e22=NaN;
  3198. this.d00=NaN;
  3199. this.d01=NaN;
  3200. this.d02=NaN;
  3201. this.d10=NaN;
  3202. this.d11=NaN;
  3203. this.d12=NaN;
  3204. this.d20=NaN;
  3205. this.d21=NaN;
  3206. this.d22=NaN;
  3207. this.r1x=NaN;
  3208. this.r1y=NaN;
  3209. this.r1z=NaN;
  3210. this.r2x=NaN;
  3211. this.r2y=NaN;
  3212. this.r2z=NaN;
  3213. this.ax1x=NaN;
  3214. this.ax1y=NaN;
  3215. this.ax1z=NaN;
  3216. this.ay1x=NaN;
  3217. this.ay1y=NaN;
  3218. this.ay1z=NaN;
  3219. this.az1x=NaN;
  3220. this.az1y=NaN;
  3221. this.az1z=NaN;
  3222. this.ax2x=NaN;
  3223. this.ax2y=NaN;
  3224. this.ax2z=NaN;
  3225. this.ay2x=NaN;
  3226. this.ay2y=NaN;
  3227. this.ay2z=NaN;
  3228. this.az2x=NaN;
  3229. this.az2y=NaN;
  3230. this.az2z=NaN;
  3231. this.vel=NaN;
  3232. this.velx=NaN;
  3233. this.vely=NaN;
  3234. this.velz=NaN;
  3235. this.joint=joint;
  3236. this.r1=joint.relativeAnchorPoint1;
  3237. this.r2=joint.relativeAnchorPoint2;
  3238. this.p1=joint.anchorPoint1;
  3239. this.p2=joint.anchorPoint2;
  3240. this.b1=joint.body1;
  3241. this.b2=joint.body2;
  3242. this.l1=this.b1.linearVelocity;
  3243. this.l2=this.b2.linearVelocity;
  3244. this.a1=this.b1.angularVelocity;
  3245. this.a2=this.b2.angularVelocity;
  3246. this.i1=this.b1.inverseInertia;
  3247. this.i2=this.b2.inverseInertia;
  3248. this.impx=0;
  3249. this.impy=0;
  3250. this.impz=0;
  3251. }
  3252. OIMO.LinearConstraint.prototype = {
  3253. constructor: OIMO.LinearConstraint,
  3254. preSolve:function(timeStep,invTimeStep){
  3255. this.r1x=this.r1.x;
  3256. this.r1y=this.r1.y;
  3257. this.r1z=this.r1.z;
  3258. this.r2x=this.r2.x;
  3259. this.r2y=this.r2.y;
  3260. this.r2z=this.r2.z;
  3261. this.m1=this.b1.inverseMass;
  3262. this.m2=this.b2.inverseMass;
  3263. var ti1 = this.i1.elements;
  3264. var ti2 = this.i2.elements;
  3265. this.i1e00=ti1[0];
  3266. this.i1e01=ti1[1];
  3267. this.i1e02=ti1[2];
  3268. this.i1e10=ti1[3];
  3269. this.i1e11=ti1[4];
  3270. this.i1e12=ti1[5];
  3271. this.i1e20=ti1[6];
  3272. this.i1e21=ti1[7];
  3273. this.i1e22=ti1[8];
  3274. this.i2e00=ti2[0];
  3275. this.i2e01=ti2[1];
  3276. this.i2e02=ti2[2];
  3277. this.i2e10=ti2[3];
  3278. this.i2e11=ti2[4];
  3279. this.i2e12=ti2[5];
  3280. this.i2e20=ti2[6];
  3281. this.i2e21=ti2[7];
  3282. this.i2e22=ti2[8];
  3283. this.ax1x=this.r1z*this.i1e01+-this.r1y*this.i1e02;
  3284. this.ax1y=this.r1z*this.i1e11+-this.r1y*this.i1e12;
  3285. this.ax1z=this.r1z*this.i1e21+-this.r1y*this.i1e22;
  3286. this.ay1x=-this.r1z*this.i1e00+this.r1x*this.i1e02;
  3287. this.ay1y=-this.r1z*this.i1e10+this.r1x*this.i1e12;
  3288. this.ay1z=-this.r1z*this.i1e20+this.r1x*this.i1e22;
  3289. this.az1x=this.r1y*this.i1e00+-this.r1x*this.i1e01;
  3290. this.az1y=this.r1y*this.i1e10+-this.r1x*this.i1e11;
  3291. this.az1z=this.r1y*this.i1e20+-this.r1x*this.i1e21;
  3292. this.ax2x=this.r2z*this.i2e01+-this.r2y*this.i2e02;
  3293. this.ax2y=this.r2z*this.i2e11+-this.r2y*this.i2e12;
  3294. this.ax2z=this.r2z*this.i2e21+-this.r2y*this.i2e22;
  3295. this.ay2x=-this.r2z*this.i2e00+this.r2x*this.i2e02;
  3296. this.ay2y=-this.r2z*this.i2e10+this.r2x*this.i2e12;
  3297. this.ay2z=-this.r2z*this.i2e20+this.r2x*this.i2e22;
  3298. this.az2x=this.r2y*this.i2e00+-this.r2x*this.i2e01;
  3299. this.az2y=this.r2y*this.i2e10+-this.r2x*this.i2e11;
  3300. this.az2z=this.r2y*this.i2e20+-this.r2x*this.i2e21;
  3301. // calculate point-to-point mass matrix
  3302. // from impulse equation
  3303. //
  3304. // M = ([/m] - [r^][/I][r^]) ^ -1
  3305. //
  3306. // where
  3307. //
  3308. // [/m] = |1/m, 0, 0|
  3309. // |0, 1/m, 0|
  3310. // |0, 0, 1/m|
  3311. //
  3312. // [r^] = |0, -rz, ry|
  3313. // |rz, 0, -rx|
  3314. // |-ry, rx, 0|
  3315. //
  3316. // [/I] = Inverted moment inertia
  3317. var k00=this.m1+this.m2;
  3318. var k01=0;
  3319. var k02=0;
  3320. var k10=0;
  3321. var k11=k00;
  3322. var k12=0;
  3323. var k20=0;
  3324. var k21=0;
  3325. var k22=k00;
  3326. k00+=this.i1e11*this.r1z*this.r1z-(this.i1e21+this.i1e12)*this.r1y*this.r1z+this.i1e22*this.r1y*this.r1y;
  3327. k01+=(this.i1e20*this.r1y+this.i1e12*this.r1x)*this.r1z-this.i1e10*this.r1z*this.r1z-this.i1e22*this.r1x*this.r1y;
  3328. k02+=(this.i1e10*this.r1y-this.i1e11*this.r1x)*this.r1z-this.i1e20*this.r1y*this.r1y+this.i1e21*this.r1x*this.r1y;
  3329. k10+=(this.i1e02*this.r1y+this.i1e21*this.r1x)*this.r1z-this.i1e01*this.r1z*this.r1z-this.i1e22*this.r1x*this.r1y;
  3330. k11+=this.i1e00*this.r1z*this.r1z-(this.i1e20+this.i1e02)*this.r1x*this.r1z+this.i1e22*this.r1x*this.r1x;
  3331. k12+=(this.i1e01*this.r1x-this.i1e00*this.r1y)*this.r1z-this.i1e21*this.r1x*this.r1x+this.i1e20*this.r1x*this.r1y;
  3332. k20+=(this.i1e01*this.r1y-this.i1e11*this.r1x)*this.r1z-this.i1e02*this.r1y*this.r1y+this.i1e12*this.r1x*this.r1y;
  3333. k21+=(this.i1e10*this.r1x-this.i1e00*this.r1y)*this.r1z-this.i1e12*this.r1x*this.r1x+this.i1e02*this.r1x*this.r1y;
  3334. k22+=this.i1e00*this.r1y*this.r1y-(this.i1e10+this.i1e01)*this.r1x*this.r1y+this.i1e11*this.r1x*this.r1x;
  3335. k00+=this.i2e11*this.r2z*this.r2z-(this.i2e21+this.i2e12)*this.r2y*this.r2z+this.i2e22*this.r2y*this.r2y;
  3336. k01+=(this.i2e20*this.r2y+this.i2e12*this.r2x)*this.r2z-this.i2e10*this.r2z*this.r2z-this.i2e22*this.r2x*this.r2y;
  3337. k02+=(this.i2e10*this.r2y-this.i2e11*this.r2x)*this.r2z-this.i2e20*this.r2y*this.r2y+this.i2e21*this.r2x*this.r2y;
  3338. k10+=(this.i2e02*this.r2y+this.i2e21*this.r2x)*this.r2z-this.i2e01*this.r2z*this.r2z-this.i2e22*this.r2x*this.r2y;
  3339. k11+=this.i2e00*this.r2z*this.r2z-(this.i2e20+this.i2e02)*this.r2x*this.r2z+this.i2e22*this.r2x*this.r2x;
  3340. k12+=(this.i2e01*this.r2x-this.i2e00*this.r2y)*this.r2z-this.i2e21*this.r2x*this.r2x+this.i2e20*this.r2x*this.r2y;
  3341. k20+=(this.i2e01*this.r2y-this.i2e11*this.r2x)*this.r2z-this.i2e02*this.r2y*this.r2y+this.i2e12*this.r2x*this.r2y;
  3342. k21+=(this.i2e10*this.r2x-this.i2e00*this.r2y)*this.r2z-this.i2e12*this.r2x*this.r2x+this.i2e02*this.r2x*this.r2y;
  3343. k22+=this.i2e00*this.r2y*this.r2y-(this.i2e10+this.i2e01)*this.r2x*this.r2y+this.i2e11*this.r2x*this.r2x;
  3344. var inv=1/(
  3345. k00*(k11*k22-k21*k12)+
  3346. k10*(k21*k02-k01*k22)+
  3347. k20*(k01*k12-k11*k02)
  3348. );
  3349. this.d00=(k11*k22-k12*k21)*inv;
  3350. this.d01=(k02*k21-k01*k22)*inv;
  3351. this.d02=(k01*k12-k02*k11)*inv;
  3352. this.d10=(k12*k20-k10*k22)*inv;
  3353. this.d11=(k00*k22-k02*k20)*inv;
  3354. this.d12=(k02*k10-k00*k12)*inv;
  3355. this.d20=(k10*k21-k11*k20)*inv;
  3356. this.d21=(k01*k20-k00*k21)*inv;
  3357. this.d22=(k00*k11-k01*k10)*inv;
  3358. this.velx=this.p2.x-this.p1.x;
  3359. this.vely=this.p2.y-this.p1.y;
  3360. this.velz=this.p2.z-this.p1.z;
  3361. var len=Math.sqrt(this.velx*this.velx+this.vely*this.vely+this.velz*this.velz);
  3362. if(len>0.005){
  3363. len=(0.005-len)/len*invTimeStep*0.05;
  3364. this.velx*=len;
  3365. this.vely*=len;
  3366. this.velz*=len;
  3367. }else{
  3368. this.velx=0;
  3369. this.vely=0;
  3370. this.velz=0;
  3371. }
  3372. this.impx*=0.95;
  3373. this.impy*=0.95;
  3374. this.impz*=0.95;
  3375. this.l1.x+=this.impx*this.m1;
  3376. this.l1.y+=this.impy*this.m1;
  3377. this.l1.z+=this.impz*this.m1;
  3378. this.a1.x+=this.impx*this.ax1x+this.impy*this.ay1x+this.impz*this.az1x;
  3379. this.a1.y+=this.impx*this.ax1y+this.impy*this.ay1y+this.impz*this.az1y;
  3380. this.a1.z+=this.impx*this.ax1z+this.impy*this.ay1z+this.impz*this.az1z;
  3381. this.l2.x-=this.impx*this.m2;
  3382. this.l2.y-=this.impy*this.m2;
  3383. this.l2.z-=this.impz*this.m2;
  3384. this.a2.x-=this.impx*this.ax2x+this.impy*this.ay2x+this.impz*this.az2x;
  3385. this.a2.y-=this.impx*this.ax2y+this.impy*this.ay2y+this.impz*this.az2y;
  3386. this.a2.z-=this.impx*this.ax2z+this.impy*this.ay2z+this.impz*this.az2z;
  3387. },
  3388. solve:function(){
  3389. 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;
  3390. 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;
  3391. 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;
  3392. var nimpx=rvx*this.d00+rvy*this.d01+rvz*this.d02;
  3393. var nimpy=rvx*this.d10+rvy*this.d11+rvz*this.d12;
  3394. var nimpz=rvx*this.d20+rvy*this.d21+rvz*this.d22;
  3395. this.impx+=nimpx;
  3396. this.impy+=nimpy;
  3397. this.impz+=nimpz;
  3398. this.l1.x+=nimpx*this.m1;
  3399. this.l1.y+=nimpy*this.m1;
  3400. this.l1.z+=nimpz*this.m1;
  3401. this.a1.x+=nimpx*this.ax1x+nimpy*this.ay1x+nimpz*this.az1x;
  3402. this.a1.y+=nimpx*this.ax1y+nimpy*this.ay1y+nimpz*this.az1y;
  3403. this.a1.z+=nimpx*this.ax1z+nimpy*this.ay1z+nimpz*this.az1z;
  3404. this.l2.x-=nimpx*this.m2;
  3405. this.l2.y-=nimpy*this.m2;
  3406. this.l2.z-=nimpz*this.m2;
  3407. this.a2.x-=nimpx*this.ax2x+nimpy*this.ay2x+nimpz*this.az2x;
  3408. this.a2.y-=nimpx*this.ax2y+nimpy*this.ay2y+nimpz*this.az2y;
  3409. this.a2.z-=nimpx*this.ax2z+nimpy*this.ay2z+nimpz*this.az2z;
  3410. }
  3411. }
  3412. /**
  3413. * A three-axis rotational constraint for various joints.
  3414. * @author saharan
  3415. */
  3416. OIMO.Rotational3Constraint = function(joint,limitMotor1,limitMotor2,limitMotor3){
  3417. this.cfm1=NaN;
  3418. this.cfm2=NaN;
  3419. this.cfm3=NaN;
  3420. this.i1e00=NaN;
  3421. this.i1e01=NaN;
  3422. this.i1e02=NaN;
  3423. this.i1e10=NaN;
  3424. this.i1e11=NaN;
  3425. this.i1e12=NaN;
  3426. this.i1e20=NaN;
  3427. this.i1e21=NaN;
  3428. this.i1e22=NaN;
  3429. this.i2e00=NaN;
  3430. this.i2e01=NaN;
  3431. this.i2e02=NaN;
  3432. this.i2e10=NaN;
  3433. this.i2e11=NaN;
  3434. this.i2e12=NaN;
  3435. this.i2e20=NaN;
  3436. this.i2e21=NaN;
  3437. this.i2e22=NaN;
  3438. this.ax1=NaN;
  3439. this.ay1=NaN;
  3440. this.az1=NaN;
  3441. this.ax2=NaN;
  3442. this.ay2=NaN;
  3443. this.az2=NaN;
  3444. this.ax3=NaN;
  3445. this.ay3=NaN;
  3446. this.az3=NaN;
  3447. this.a1x1=NaN; // jacoians
  3448. this.a1y1=NaN;
  3449. this.a1z1=NaN;
  3450. this.a2x1=NaN;
  3451. this.a2y1=NaN;
  3452. this.a2z1=NaN;
  3453. this.a1x2=NaN;
  3454. this.a1y2=NaN;
  3455. this.a1z2=NaN;
  3456. this.a2x2=NaN;
  3457. this.a2y2=NaN;
  3458. this.a2z2=NaN;
  3459. this.a1x3=NaN;
  3460. this.a1y3=NaN;
  3461. this.a1z3=NaN;
  3462. this.a2x3=NaN;
  3463. this.a2y3=NaN;
  3464. this.a2z3=NaN;
  3465. this.lowerLimit1=NaN;
  3466. this.upperLimit1=NaN;
  3467. this.limitVelocity1=NaN;
  3468. this.limitState1=0; // -1: at lower, 0: locked, 1: at upper, 2: free
  3469. this.enableMotor1=false;
  3470. this.motorSpeed1=NaN;
  3471. this.maxMotorForce1=NaN;
  3472. this.maxMotorImpulse1=NaN;
  3473. this.lowerLimit2=NaN;
  3474. this.upperLimit2=NaN;
  3475. this.limitVelocity2=NaN;
  3476. this.limitState2=0; // -1: at lower, 0: locked, 1: at upper, 2: free
  3477. this.enableMotor2=false;
  3478. this.motorSpeed2=NaN;
  3479. this.maxMotorForce2=NaN;
  3480. this.maxMotorImpulse2=NaN;
  3481. this.lowerLimit3=NaN;
  3482. this.upperLimit3=NaN;
  3483. this.limitVelocity3=NaN;
  3484. this.limitState3=0; // -1: at lower, 0: locked, 1: at upper, 2: free
  3485. this.enableMotor3=false;
  3486. this.motorSpeed3=NaN;
  3487. this.maxMotorForce3=NaN;
  3488. this.maxMotorImpulse3=NaN;
  3489. this.k00=NaN; // K = J*M*JT
  3490. this.k01=NaN;
  3491. this.k02=NaN;
  3492. this.k10=NaN;
  3493. this.k11=NaN;
  3494. this.k12=NaN;
  3495. this.k20=NaN;
  3496. this.k21=NaN;
  3497. this.k22=NaN;
  3498. this.kv00=NaN; // diagonals without CFMs
  3499. this.kv11=NaN;
  3500. this.kv22=NaN;
  3501. this.dv00=NaN; // ...inverted
  3502. this.dv11=NaN;
  3503. this.dv22=NaN;
  3504. this.d00=NaN; // K^-1
  3505. this.d01=NaN;
  3506. this.d02=NaN;
  3507. this.d10=NaN;
  3508. this.d11=NaN;
  3509. this.d12=NaN;
  3510. this.d20=NaN;
  3511. this.d21=NaN;
  3512. this.d22=NaN;
  3513. this.limitMotor1=limitMotor1;
  3514. this.limitMotor2=limitMotor2;
  3515. this.limitMotor3=limitMotor3;
  3516. this.b1=joint.body1;
  3517. this.b2=joint.body2;
  3518. this.a1=this.b1.angularVelocity;
  3519. this.a2=this.b2.angularVelocity;
  3520. this.i1=this.b1.inverseInertia;
  3521. this.i2=this.b2.inverseInertia;
  3522. this.limitImpulse1=0;
  3523. this.motorImpulse1=0;
  3524. this.limitImpulse2=0;
  3525. this.motorImpulse2=0;
  3526. this.limitImpulse3=0;
  3527. this.motorImpulse3=0;
  3528. }
  3529. OIMO.Rotational3Constraint.prototype = {
  3530. constructor: OIMO.Rotational3Constraint,
  3531. preSolve:function(timeStep,invTimeStep){
  3532. this.ax1=this.limitMotor1.axis.x;
  3533. this.ay1=this.limitMotor1.axis.y;
  3534. this.az1=this.limitMotor1.axis.z;
  3535. this.ax2=this.limitMotor2.axis.x;
  3536. this.ay2=this.limitMotor2.axis.y;
  3537. this.az2=this.limitMotor2.axis.z;
  3538. this.ax3=this.limitMotor3.axis.x;
  3539. this.ay3=this.limitMotor3.axis.y;
  3540. this.az3=this.limitMotor3.axis.z;
  3541. this.lowerLimit1=this.limitMotor1.lowerLimit;
  3542. this.upperLimit1=this.limitMotor1.upperLimit;
  3543. this.motorSpeed1=this.limitMotor1.motorSpeed;
  3544. this.maxMotorForce1=this.limitMotor1.maxMotorForce;
  3545. this.enableMotor1=this.maxMotorForce1>0;
  3546. this.lowerLimit2=this.limitMotor2.lowerLimit;
  3547. this.upperLimit2=this.limitMotor2.upperLimit;
  3548. this.motorSpeed2=this.limitMotor2.motorSpeed;
  3549. this.maxMotorForce2=this.limitMotor2.maxMotorForce;
  3550. this.enableMotor2=this.maxMotorForce2>0;
  3551. this.lowerLimit3=this.limitMotor3.lowerLimit;
  3552. this.upperLimit3=this.limitMotor3.upperLimit;
  3553. this.motorSpeed3=this.limitMotor3.motorSpeed;
  3554. this.maxMotorForce3=this.limitMotor3.maxMotorForce;
  3555. this.enableMotor3=this.maxMotorForce3>0;
  3556. var ti1 = this.i1.elements;
  3557. var ti2 = this.i2.elements;
  3558. this.i1e00=ti1[0];
  3559. this.i1e01=ti1[1];
  3560. this.i1e02=ti1[2];
  3561. this.i1e10=ti1[3];
  3562. this.i1e11=ti1[4];
  3563. this.i1e12=ti1[5];
  3564. this.i1e20=ti1[6];
  3565. this.i1e21=ti1[7];
  3566. this.i1e22=ti1[8];
  3567. this.i2e00=ti2[0];
  3568. this.i2e01=ti2[1];
  3569. this.i2e02=ti2[2];
  3570. this.i2e10=ti2[3];
  3571. this.i2e11=ti2[4];
  3572. this.i2e12=ti2[5];
  3573. this.i2e20=ti2[6];
  3574. this.i2e21=ti2[7];
  3575. this.i2e22=ti2[8];
  3576. var frequency1=this.limitMotor1.frequency;
  3577. var frequency2=this.limitMotor2.frequency;
  3578. var frequency3=this.limitMotor3.frequency;
  3579. var enableSpring1=frequency1>0;
  3580. var enableSpring2=frequency2>0;
  3581. var enableSpring3=frequency3>0;
  3582. var enableLimit1=this.lowerLimit1<=this.upperLimit1;
  3583. var enableLimit2=this.lowerLimit2<=this.upperLimit2;
  3584. var enableLimit3=this.lowerLimit3<=this.upperLimit3;
  3585. var angle1=this.limitMotor1.angle;
  3586. if(enableLimit1){
  3587. if(this.lowerLimit1==this.upperLimit1){
  3588. if(this.limitState1!=0){
  3589. this.limitState1=0;
  3590. this.limitImpulse1=0;
  3591. }
  3592. this.limitVelocity1=this.lowerLimit1-angle1;
  3593. }else if(angle1<this.lowerLimit1){
  3594. if(this.limitState1!=-1){
  3595. this.limitState1=-1;
  3596. this.limitImpulse1=0;
  3597. }
  3598. this.limitVelocity1=this.lowerLimit1-angle1;
  3599. }else if(angle1>this.upperLimit1){
  3600. if(this.limitState1!=1){
  3601. this.limitState1=1;
  3602. this.limitImpulse1=0;
  3603. }
  3604. this.limitVelocity1=this.upperLimit1-angle1;
  3605. }else{
  3606. this.limitState1=2;
  3607. this.limitImpulse1=0;
  3608. this.limitVelocity1=0;
  3609. }
  3610. if(!enableSpring1){
  3611. if(this.limitVelocity1>0.02)this.limitVelocity1-=0.02;
  3612. else if(this.limitVelocity1<-0.02)this.limitVelocity1+=0.02;
  3613. else this.limitVelocity1=0;
  3614. }
  3615. }else{
  3616. this.limitState1=2;
  3617. this.limitImpulse1=0;
  3618. }
  3619. var angle2=this.limitMotor2.angle;
  3620. if(enableLimit2){
  3621. if(this.lowerLimit2==this.upperLimit2){
  3622. if(this.limitState2!=0){
  3623. this.limitState2=0;
  3624. this.limitImpulse2=0;
  3625. }
  3626. this.limitVelocity2=this.lowerLimit2-angle2;
  3627. }else if(angle2<this.lowerLimit2){
  3628. if(this.limitState2!=-1){
  3629. this.limitState2=-1;
  3630. this.limitImpulse2=0;
  3631. }
  3632. this.limitVelocity2=this.lowerLimit2-angle2;
  3633. }else if(angle2>this.upperLimit2){
  3634. if(this.limitState2!=1){
  3635. this.limitState2=1;
  3636. this.limitImpulse2=0;
  3637. }
  3638. this.limitVelocity2=this.upperLimit2-angle2;
  3639. }else{
  3640. this.limitState2=2;
  3641. this.limitImpulse2=0;
  3642. this.limitVelocity2=0;
  3643. }
  3644. if(!enableSpring2){
  3645. if(this.limitVelocity2>0.02)this.limitVelocity2-=0.02;
  3646. else if(this.limitVelocity2<-0.02)this.limitVelocity2+=0.02;
  3647. else this.limitVelocity2=0;
  3648. }
  3649. }else{
  3650. this.limitState2=2;
  3651. this.limitImpulse2=0;
  3652. }
  3653. var angle3=this.limitMotor3.angle;
  3654. if(enableLimit3){
  3655. if(this.lowerLimit3==this.upperLimit3){
  3656. if(this.limitState3!=0){
  3657. this.limitState3=0;
  3658. this.limitImpulse3=0;
  3659. }
  3660. this.limitVelocity3=this.lowerLimit3-angle3;
  3661. }else if(angle3<this.lowerLimit3){
  3662. if(this.limitState3!=-1){
  3663. this.limitState3=-1;
  3664. this.limitImpulse3=0;
  3665. }
  3666. this.limitVelocity3=this.lowerLimit3-angle3;
  3667. }else if(angle3>this.upperLimit3){
  3668. if(this.limitState3!=1){
  3669. this.limitState3=1;
  3670. this.limitImpulse3=0;
  3671. }
  3672. this.limitVelocity3=this.upperLimit3-angle3;
  3673. }else{
  3674. this.limitState3=2;
  3675. this.limitImpulse3=0;
  3676. this.limitVelocity3=0;
  3677. }
  3678. if(!enableSpring3){
  3679. if(this.limitVelocity3>0.02)this.limitVelocity3-=0.02;
  3680. else if(this.limitVelocity3<-0.02)this.limitVelocity3+=0.02;
  3681. else this.limitVelocity3=0;
  3682. }
  3683. }else{
  3684. this.limitState3=2;
  3685. this.limitImpulse3=0;
  3686. }
  3687. if(this.enableMotor1&&(this.limitState1!=0||enableSpring1)){
  3688. this.maxMotorImpulse1=this.maxMotorForce1*timeStep;
  3689. }else{
  3690. this.motorImpulse1=0;
  3691. this.maxMotorImpulse1=0;
  3692. }
  3693. if(this.enableMotor2&&(this.limitState2!=0||enableSpring2)){
  3694. this.maxMotorImpulse2=this.maxMotorForce2*timeStep;
  3695. }else{
  3696. this.motorImpulse2=0;
  3697. this.maxMotorImpulse2=0;
  3698. }
  3699. if(this.enableMotor3&&(this.limitState3!=0||enableSpring3)){
  3700. this.maxMotorImpulse3=this.maxMotorForce3*timeStep;
  3701. }else{
  3702. this.motorImpulse3=0;
  3703. this.maxMotorImpulse3=0;
  3704. }
  3705. // build jacobians
  3706. this.a1x1=this.ax1*this.i1e00+this.ay1*this.i1e01+this.az1*this.i1e02;
  3707. this.a1y1=this.ax1*this.i1e10+this.ay1*this.i1e11+this.az1*this.i1e12;
  3708. this.a1z1=this.ax1*this.i1e20+this.ay1*this.i1e21+this.az1*this.i1e22;
  3709. this.a2x1=this.ax1*this.i2e00+this.ay1*this.i2e01+this.az1*this.i2e02;
  3710. this.a2y1=this.ax1*this.i2e10+this.ay1*this.i2e11+this.az1*this.i2e12;
  3711. this.a2z1=this.ax1*this.i2e20+this.ay1*this.i2e21+this.az1*this.i2e22;
  3712. this.a1x2=this.ax2*this.i1e00+this.ay2*this.i1e01+this.az2*this.i1e02;
  3713. this.a1y2=this.ax2*this.i1e10+this.ay2*this.i1e11+this.az2*this.i1e12;
  3714. this.a1z2=this.ax2*this.i1e20+this.ay2*this.i1e21+this.az2*this.i1e22;
  3715. this.a2x2=this.ax2*this.i2e00+this.ay2*this.i2e01+this.az2*this.i2e02;
  3716. this.a2y2=this.ax2*this.i2e10+this.ay2*this.i2e11+this.az2*this.i2e12;
  3717. this.a2z2=this.ax2*this.i2e20+this.ay2*this.i2e21+this.az2*this.i2e22;
  3718. this.a1x3=this.ax3*this.i1e00+this.ay3*this.i1e01+this.az3*this.i1e02;
  3719. this.a1y3=this.ax3*this.i1e10+this.ay3*this.i1e11+this.az3*this.i1e12;
  3720. this.a1z3=this.ax3*this.i1e20+this.ay3*this.i1e21+this.az3*this.i1e22;
  3721. this.a2x3=this.ax3*this.i2e00+this.ay3*this.i2e01+this.az3*this.i2e02;
  3722. this.a2y3=this.ax3*this.i2e10+this.ay3*this.i2e11+this.az3*this.i2e12;
  3723. this.a2z3=this.ax3*this.i2e20+this.ay3*this.i2e21+this.az3*this.i2e22;
  3724. // build an impulse matrix
  3725. this.k00=this.ax1*(this.a1x1+this.a2x1)+this.ay1*(this.a1y1+this.a2y1)+this.az1*(this.a1z1+this.a2z1);
  3726. this.k01=this.ax1*(this.a1x2+this.a2x2)+this.ay1*(this.a1y2+this.a2y2)+this.az1*(this.a1z2+this.a2z2);
  3727. this.k02=this.ax1*(this.a1x3+this.a2x3)+this.ay1*(this.a1y3+this.a2y3)+this.az1*(this.a1z3+this.a2z3);
  3728. this.k10=this.ax2*(this.a1x1+this.a2x1)+this.ay2*(this.a1y1+this.a2y1)+this.az2*(this.a1z1+this.a2z1);
  3729. this.k11=this.ax2*(this.a1x2+this.a2x2)+this.ay2*(this.a1y2+this.a2y2)+this.az2*(this.a1z2+this.a2z2);
  3730. this.k12=this.ax2*(this.a1x3+this.a2x3)+this.ay2*(this.a1y3+this.a2y3)+this.az2*(this.a1z3+this.a2z3);
  3731. this.k20=this.ax3*(this.a1x1+this.a2x1)+this.ay3*(this.a1y1+this.a2y1)+this.az3*(this.a1z1+this.a2z1);
  3732. this.k21=this.ax3*(this.a1x2+this.a2x2)+this.ay3*(this.a1y2+this.a2y2)+this.az3*(this.a1z2+this.a2z2);
  3733. this.k22=this.ax3*(this.a1x3+this.a2x3)+this.ay3*(this.a1y3+this.a2y3)+this.az3*(this.a1z3+this.a2z3);
  3734. this.kv00=this.k00;
  3735. this.kv11=this.k11;
  3736. this.kv22=this.k22;
  3737. this.dv00=1/this.kv00;
  3738. this.dv11=1/this.kv11;
  3739. this.dv22=1/this.kv22;
  3740. if(enableSpring1&&this.limitState1!=2){
  3741. var omega=6.2831853*frequency1;
  3742. var k=omega*omega*timeStep;
  3743. var dmp=invTimeStep/(k+2*this.limitMotor1.dampingRatio*omega);
  3744. this.cfm1=this.kv00*dmp;
  3745. this.limitVelocity1*=k*dmp;
  3746. }else{
  3747. this.cfm1=0;
  3748. this.limitVelocity1*=invTimeStep*0.05;
  3749. }
  3750. if(enableSpring2&&this.limitState2!=2){
  3751. omega=6.2831853*frequency2;
  3752. k=omega*omega*timeStep;
  3753. dmp=invTimeStep/(k+2*this.limitMotor2.dampingRatio*omega);
  3754. this.cfm2=this.kv11*dmp;
  3755. this.limitVelocity2*=k*dmp;
  3756. }else{
  3757. this.cfm2=0;
  3758. this.limitVelocity2*=invTimeStep*0.05;
  3759. }
  3760. if(enableSpring3&&this.limitState3!=2){
  3761. omega=6.2831853*frequency3;
  3762. k=omega*omega*timeStep;
  3763. dmp=invTimeStep/(k+2*this.limitMotor3.dampingRatio*omega);
  3764. this.cfm3=this.kv22*dmp;
  3765. this.limitVelocity3*=k*dmp;
  3766. }else{
  3767. this.cfm3=0;
  3768. this.limitVelocity3*=invTimeStep*0.05;
  3769. }
  3770. this.k00+=this.cfm1;
  3771. this.k11+=this.cfm2;
  3772. this.k22+=this.cfm3;
  3773. var inv=1/(
  3774. this.k00*(this.k11*this.k22-this.k21*this.k12)+
  3775. this.k10*(this.k21*this.k02-this.k01*this.k22)+
  3776. this.k20*(this.k01*this.k12-this.k11*this.k02)
  3777. );
  3778. this.d00=(this.k11*this.k22-this.k12*this.k21)*inv;
  3779. this.d01=(this.k02*this.k21-this.k01*this.k22)*inv;
  3780. this.d02=(this.k01*this.k12-this.k02*this.k11)*inv;
  3781. this.d10=(this.k12*this.k20-this.k10*this.k22)*inv;
  3782. this.d11=(this.k00*this.k22-this.k02*this.k20)*inv;
  3783. this.d12=(this.k02*this.k10-this.k00*this.k12)*inv;
  3784. this.d20=(this.k10*this.k21-this.k11*this.k20)*inv;
  3785. this.d21=(this.k01*this.k20-this.k00*this.k21)*inv;
  3786. this.d22=(this.k00*this.k11-this.k01*this.k10)*inv;
  3787. this.limitImpulse1*=0.95;
  3788. this.motorImpulse1*=0.95;
  3789. this.limitImpulse2*=0.95;
  3790. this.motorImpulse2*=0.95;
  3791. this.limitImpulse3*=0.95;
  3792. this.motorImpulse3*=0.95;
  3793. var totalImpulse1=this.limitImpulse1+this.motorImpulse1;
  3794. var totalImpulse2=this.limitImpulse2+this.motorImpulse2;
  3795. var totalImpulse3=this.limitImpulse3+this.motorImpulse3;
  3796. this.a1.x+=totalImpulse1*this.a1x1+totalImpulse2*this.a1x2+totalImpulse3*this.a1x3;
  3797. this.a1.y+=totalImpulse1*this.a1y1+totalImpulse2*this.a1y2+totalImpulse3*this.a1y3;
  3798. this.a1.z+=totalImpulse1*this.a1z1+totalImpulse2*this.a1z2+totalImpulse3*this.a1z3;
  3799. this.a2.x-=totalImpulse1*this.a2x1+totalImpulse2*this.a2x2+totalImpulse3*this.a2x3;
  3800. this.a2.y-=totalImpulse1*this.a2y1+totalImpulse2*this.a2y2+totalImpulse3*this.a2y3;
  3801. this.a2.z-=totalImpulse1*this.a2z1+totalImpulse2*this.a2z2+totalImpulse3*this.a2z3;
  3802. },
  3803. solve_:function(){
  3804. var rvx=this.a2.x-this.a1.x;
  3805. var rvy=this.a2.y-this.a1.y;
  3806. var rvz=this.a2.z-this.a1.z;
  3807. this.limitVelocity3=30;
  3808. var rvn1=rvx*this.ax1+rvy*this.ay1+rvz*this.az1-this.limitVelocity1;
  3809. var rvn2=rvx*this.ax2+rvy*this.ay2+rvz*this.az2-this.limitVelocity2;
  3810. var rvn3=rvx*this.ax3+rvy*this.ay3+rvz*this.az3-this.limitVelocity3;
  3811. var dLimitImpulse1=rvn1*this.d00+rvn2*this.d01+rvn3*this.d02;
  3812. var dLimitImpulse2=rvn1*this.d10+rvn2*this.d11+rvn3*this.d12;
  3813. var dLimitImpulse3=rvn1*this.d20+rvn2*this.d21+rvn3*this.d22;
  3814. this.limitImpulse1+=dLimitImpulse1;
  3815. this.limitImpulse2+=dLimitImpulse2;
  3816. this.limitImpulse3+=dLimitImpulse3;
  3817. this.a1.x+=dLimitImpulse1*this.a1x1+dLimitImpulse2*this.a1x2+dLimitImpulse3*this.a1x3;
  3818. this.a1.y+=dLimitImpulse1*this.a1y1+dLimitImpulse2*this.a1y2+dLimitImpulse3*this.a1y3;
  3819. this.a1.z+=dLimitImpulse1*this.a1z1+dLimitImpulse2*this.a1z2+dLimitImpulse3*this.a1z3;
  3820. this.a2.x-=dLimitImpulse1*this.a2x1+dLimitImpulse2*this.a2x2+dLimitImpulse3*this.a2x3;
  3821. this.a2.y-=dLimitImpulse1*this.a2y1+dLimitImpulse2*this.a2y2+dLimitImpulse3*this.a2y3;
  3822. this.a2.z-=dLimitImpulse1*this.a2z1+dLimitImpulse2*this.a2z2+dLimitImpulse3*this.a2z3;
  3823. },
  3824. solve:function(){
  3825. var rvx=this.a2.x-this.a1.x;
  3826. var rvy=this.a2.y-this.a1.y;
  3827. var rvz=this.a2.z-this.a1.z;
  3828. var rvn1=rvx*this.ax1+rvy*this.ay1+rvz*this.az1;
  3829. var rvn2=rvx*this.ax2+rvy*this.ay2+rvz*this.az2;
  3830. var rvn3=rvx*this.ax3+rvy*this.ay3+rvz*this.az3;
  3831. var oldMotorImpulse1=this.motorImpulse1;
  3832. var oldMotorImpulse2=this.motorImpulse2;
  3833. var oldMotorImpulse3=this.motorImpulse3;
  3834. var dMotorImpulse1=0;
  3835. var dMotorImpulse2=0;
  3836. var dMotorImpulse3=0;
  3837. if(this.enableMotor1){
  3838. dMotorImpulse1=(rvn1-this.motorSpeed1)*this.dv00;
  3839. this.motorImpulse1+=dMotorImpulse1;
  3840. if(this.motorImpulse1>this.maxMotorImpulse1){ // clamp motor impulse
  3841. this.motorImpulse1=this.maxMotorImpulse1;
  3842. }else if(this.motorImpulse1<-this.maxMotorImpulse1){
  3843. this.motorImpulse1=-this.maxMotorImpulse1;
  3844. }
  3845. dMotorImpulse1=this.motorImpulse1-oldMotorImpulse1;
  3846. }
  3847. if(this.enableMotor2){
  3848. dMotorImpulse2=(rvn2-this.motorSpeed2)*this.dv11;
  3849. this.motorImpulse2+=dMotorImpulse2;
  3850. if(this.motorImpulse2>this.maxMotorImpulse2){ // clamp motor impulse
  3851. this.motorImpulse2=this.maxMotorImpulse2;
  3852. }else if(this.motorImpulse2<-this.maxMotorImpulse2){
  3853. this.motorImpulse2=-this.maxMotorImpulse2;
  3854. }
  3855. dMotorImpulse2=this.motorImpulse2-oldMotorImpulse2;
  3856. }
  3857. if(this.enableMotor3){
  3858. dMotorImpulse3=(rvn3-this.motorSpeed3)*this.dv22;
  3859. this.motorImpulse3+=dMotorImpulse3;
  3860. if(this.motorImpulse3>this.maxMotorImpulse3){ // clamp motor impulse
  3861. this.motorImpulse3=this.maxMotorImpulse3;
  3862. }else if(this.motorImpulse3<-this.maxMotorImpulse3){
  3863. this.motorImpulse3=-this.maxMotorImpulse3;
  3864. }
  3865. dMotorImpulse3=this.motorImpulse3-oldMotorImpulse3;
  3866. }
  3867. // apply motor impulse to relative velocity
  3868. rvn1+=dMotorImpulse1*this.kv00+dMotorImpulse2*this.k01+dMotorImpulse3*this.k02;
  3869. rvn2+=dMotorImpulse1*this.k10+dMotorImpulse2*this.kv11+dMotorImpulse3*this.k12;
  3870. rvn3+=dMotorImpulse1*this.k20+dMotorImpulse2*this.k21+dMotorImpulse3*this.kv22;
  3871. // subtract target velocity and applied impulse
  3872. rvn1-=this.limitVelocity1+this.limitImpulse1*this.cfm1;
  3873. rvn2-=this.limitVelocity2+this.limitImpulse2*this.cfm2;
  3874. rvn3-=this.limitVelocity3+this.limitImpulse3*this.cfm3;
  3875. var oldLimitImpulse1=this.limitImpulse1;
  3876. var oldLimitImpulse2=this.limitImpulse2;
  3877. var oldLimitImpulse3=this.limitImpulse3;
  3878. var dLimitImpulse1=rvn1*this.d00+rvn2*this.d01+rvn3*this.d02;
  3879. var dLimitImpulse2=rvn1*this.d10+rvn2*this.d11+rvn3*this.d12;
  3880. var dLimitImpulse3=rvn1*this.d20+rvn2*this.d21+rvn3*this.d22;
  3881. this.limitImpulse1+=dLimitImpulse1;
  3882. this.limitImpulse2+=dLimitImpulse2;
  3883. this.limitImpulse3+=dLimitImpulse3;
  3884. // clamp
  3885. var clampState=0;
  3886. if(this.limitState1==2||this.limitImpulse1*this.limitState1<0){
  3887. dLimitImpulse1=-oldLimitImpulse1;
  3888. rvn2+=dLimitImpulse1*this.k10;
  3889. rvn3+=dLimitImpulse1*this.k20;
  3890. clampState|=1;
  3891. }
  3892. if(this.limitState2==2||this.limitImpulse2*this.limitState2<0){
  3893. dLimitImpulse2=-oldLimitImpulse2;
  3894. rvn1+=dLimitImpulse2*this.k01;
  3895. rvn3+=dLimitImpulse2*this.k21;
  3896. clampState|=2;
  3897. }
  3898. if(this.limitState3==2||this.limitImpulse3*this.limitState3<0){
  3899. dLimitImpulse3=-oldLimitImpulse3;
  3900. rvn1+=dLimitImpulse3*this.k02;
  3901. rvn2+=dLimitImpulse3*this.k12;
  3902. clampState|=4;
  3903. }
  3904. // update un-clamped impulse
  3905. // TODO: isolate division
  3906. var det;
  3907. switch(clampState){
  3908. case 1: // update 2 3
  3909. det=1/(this.k11*this.k22-this.k12*this.k21);
  3910. dLimitImpulse2=(this.k22*rvn2+-this.k12*rvn3)*det;
  3911. dLimitImpulse3=(-this.k21*rvn2+this.k11*rvn3)*det;
  3912. break;
  3913. case 2: // update 1 3
  3914. det=1/(this.k00*this.k22-this.k02*this.k20);
  3915. dLimitImpulse1=(this.k22*rvn1+-this.k02*rvn3)*det;
  3916. dLimitImpulse3=(-this.k20*rvn1+this.k00*rvn3)*det;
  3917. break;
  3918. case 3: // update 3
  3919. dLimitImpulse3=rvn3/this.k22;
  3920. break;
  3921. case 4: // update 1 2
  3922. det=1/(this.k00*this.k11-this.k01*this.k10);
  3923. dLimitImpulse1=(this.k11*rvn1+-this.k01*rvn2)*det;
  3924. dLimitImpulse2=(-this.k10*rvn1+this.k00*rvn2)*det;
  3925. break;
  3926. case 5: // update 2
  3927. dLimitImpulse2=rvn2/this.k11;
  3928. break;
  3929. case 6: // update 1
  3930. dLimitImpulse1=rvn1/this.k00;
  3931. break;
  3932. }
  3933. this.limitImpulse1=dLimitImpulse1+oldLimitImpulse1;
  3934. this.limitImpulse2=dLimitImpulse2+oldLimitImpulse2;
  3935. this.limitImpulse3=dLimitImpulse3+oldLimitImpulse3;
  3936. var dImpulse1=dMotorImpulse1+dLimitImpulse1;
  3937. var dImpulse2=dMotorImpulse2+dLimitImpulse2;
  3938. var dImpulse3=dMotorImpulse3+dLimitImpulse3;
  3939. // apply impulse
  3940. this.a1.x+=dImpulse1*this.a1x1+dImpulse2*this.a1x2+dImpulse3*this.a1x3;
  3941. this.a1.y+=dImpulse1*this.a1y1+dImpulse2*this.a1y2+dImpulse3*this.a1y3;
  3942. this.a1.z+=dImpulse1*this.a1z1+dImpulse2*this.a1z2+dImpulse3*this.a1z3;
  3943. this.a2.x-=dImpulse1*this.a2x1+dImpulse2*this.a2x2+dImpulse3*this.a2x3;
  3944. this.a2.y-=dImpulse1*this.a2y1+dImpulse2*this.a2y2+dImpulse3*this.a2y3;
  3945. this.a2.z-=dImpulse1*this.a2z1+dImpulse2*this.a2z2+dImpulse3*this.a2z3;
  3946. rvx=this.a2.x-this.a1.x;
  3947. rvy=this.a2.y-this.a1.y;
  3948. rvz=this.a2.z-this.a1.z;
  3949. rvn2=rvx*this.ax2+rvy*this.ay2+rvz*this.az2;
  3950. }
  3951. }
  3952. /**
  3953. * A rotational constraint for various joints.
  3954. * @author saharan
  3955. */
  3956. OIMO.RotationalConstraint = function(joint,limitMotor){
  3957. this.cfm=NaN;
  3958. this.i1e00=NaN;
  3959. this.i1e01=NaN;
  3960. this.i1e02=NaN;
  3961. this.i1e10=NaN;
  3962. this.i1e11=NaN;
  3963. this.i1e12=NaN;
  3964. this.i1e20=NaN;
  3965. this.i1e21=NaN;
  3966. this.i1e22=NaN;
  3967. this.i2e00=NaN;
  3968. this.i2e01=NaN;
  3969. this.i2e02=NaN;
  3970. this.i2e10=NaN;
  3971. this.i2e11=NaN;
  3972. this.i2e12=NaN;
  3973. this.i2e20=NaN;
  3974. this.i2e21=NaN;
  3975. this.i2e22=NaN;
  3976. this.motorDenom=NaN;
  3977. this.invMotorDenom=NaN;
  3978. this.invDenom=NaN;
  3979. this.ax=NaN;
  3980. this.ay=NaN;
  3981. this.az=NaN;
  3982. this.a1x=NaN;
  3983. this.a1y=NaN;
  3984. this.a1z=NaN;
  3985. this.a2x=NaN;
  3986. this.a2y=NaN;
  3987. this.a2z=NaN;
  3988. this.enableLimit=false;
  3989. this.lowerLimit=NaN;
  3990. this.upperLimit=NaN;
  3991. this.limitVelocity=NaN;
  3992. this.limitState=0; // -1: at lower, 0: locked, 1: at upper, 2: free
  3993. this.enableMotor=false;
  3994. this.motorSpeed=NaN;
  3995. this.maxMotorForce=NaN;
  3996. this.maxMotorImpulse=NaN;
  3997. this.limitMotor=limitMotor;
  3998. this.b1=joint.body1;
  3999. this.b2=joint.body2;
  4000. this.a1=this.b1.angularVelocity;
  4001. this.a2=this.b2.angularVelocity;
  4002. this.i1=this.b1.inverseInertia;
  4003. this.i2=this.b2.inverseInertia;
  4004. this.limitImpulse=0;
  4005. this.motorImpulse=0;
  4006. }
  4007. OIMO.RotationalConstraint.prototype = {
  4008. constructor: OIMO.RotationalConstraint,
  4009. preSolve:function(timeStep,invTimeStep){
  4010. this.ax=this.limitMotor.axis.x;
  4011. this.ay=this.limitMotor.axis.y;
  4012. this.az=this.limitMotor.axis.z;
  4013. this.lowerLimit=this.limitMotor.lowerLimit;
  4014. this.upperLimit=this.limitMotor.upperLimit;
  4015. this.motorSpeed=this.limitMotor.motorSpeed;
  4016. this.maxMotorForce=this.limitMotor.maxMotorForce;
  4017. this.enableMotor=this.maxMotorForce>0;
  4018. var ti1 = this.i1.elements;
  4019. var ti2 = this.i2.elements;
  4020. this.i1e00=ti1[0];
  4021. this.i1e01=ti1[1];
  4022. this.i1e02=ti1[2];
  4023. this.i1e10=ti1[3];
  4024. this.i1e11=ti1[4];
  4025. this.i1e12=ti1[5];
  4026. this.i1e20=ti1[6];
  4027. this.i1e21=ti1[7];
  4028. this.i1e22=ti1[8];
  4029. this.i2e00=ti2[0];
  4030. this.i2e01=ti2[1];
  4031. this.i2e02=ti2[2];
  4032. this.i2e10=ti2[3];
  4033. this.i2e11=ti2[4];
  4034. this.i2e12=ti2[5];
  4035. this.i2e20=ti2[6];
  4036. this.i2e21=ti2[7];
  4037. this.i2e22=ti2[8];
  4038. var frequency=this.limitMotor.frequency;
  4039. var enableSpring=frequency>0;
  4040. var enableLimit=this.lowerLimit<=this.upperLimit;
  4041. var angle=this.limitMotor.angle;
  4042. if(enableLimit){
  4043. if(this.lowerLimit==this.upperLimit){
  4044. if(this.limitState!=0){
  4045. this.limitState=0;
  4046. this.limitImpulse=0;
  4047. }
  4048. this.limitVelocity=this.lowerLimit-angle;
  4049. }else if(angle<this.lowerLimit){
  4050. if(this.limitState!=-1){
  4051. this.limitState=-1;
  4052. this.limitImpulse=0;
  4053. }
  4054. this.limitVelocity=this.lowerLimit-angle;
  4055. }else if(angle>this.upperLimit){
  4056. if(this.limitState!=1){
  4057. this.limitState=1;
  4058. this.limitImpulse=0;
  4059. }
  4060. this.limitVelocity=this.upperLimit-angle;
  4061. }else{
  4062. this.limitState=2;
  4063. this.limitImpulse=0;
  4064. this.limitVelocity=0;
  4065. }
  4066. if(!enableSpring){
  4067. if(this.limitVelocity>0.02)this.limitVelocity-=0.02;
  4068. else if(this.limitVelocity<-0.02)this.limitVelocity+=0.02;
  4069. else this.limitVelocity=0;
  4070. }
  4071. }else{
  4072. this.limitState=2;
  4073. this.limitImpulse=0;
  4074. }
  4075. if(this.enableMotor&&(this.limitState!=0||enableSpring)){
  4076. this.maxMotorImpulse=this.maxMotorForce*timeStep;
  4077. }else{
  4078. this.motorImpulse=0;
  4079. this.maxMotorImpulse=0;
  4080. }
  4081. this.a1x=this.ax*this.i1e00+this.ay*this.i1e01+this.az*this.i1e02;
  4082. this.a1y=this.ax*this.i1e10+this.ay*this.i1e11+this.az*this.i1e12;
  4083. this.a1z=this.ax*this.i1e20+this.ay*this.i1e21+this.az*this.i1e22;
  4084. this.a2x=this.ax*this.i2e00+this.ay*this.i2e01+this.az*this.i2e02;
  4085. this.a2y=this.ax*this.i2e10+this.ay*this.i2e11+this.az*this.i2e12;
  4086. this.a2z=this.ax*this.i2e20+this.ay*this.i2e21+this.az*this.i2e22;
  4087. this.motorDenom=this.ax*(this.a1x+this.a2x)+this.ay*(this.a1y+this.a2y)+this.az*(this.a1z+this.a2z);
  4088. this.invMotorDenom=1/this.motorDenom;
  4089. if(enableSpring&&this.limitState!=2){
  4090. var omega=6.2831853*frequency;
  4091. var k=omega*omega*timeStep;
  4092. var dmp=invTimeStep/(k+2*this.limitMotor.dampingRatio*omega);
  4093. this.cfm=this.motorDenom*dmp;
  4094. this.limitVelocity*=k*dmp;
  4095. }else{
  4096. this.cfm=0;
  4097. this.limitVelocity*=invTimeStep*0.05;
  4098. }
  4099. this.invDenom=1/(this.motorDenom+this.cfm);
  4100. this.limitImpulse*=0.95;
  4101. this.motorImpulse*=0.95;
  4102. var totalImpulse=this.limitImpulse+this.motorImpulse;
  4103. this.a1.x+=totalImpulse*this.a1x;
  4104. this.a1.y+=totalImpulse*this.a1y;
  4105. this.a1.z+=totalImpulse*this.a1z;
  4106. this.a2.x-=totalImpulse*this.a2x;
  4107. this.a2.y-=totalImpulse*this.a2y;
  4108. this.a2.z-=totalImpulse*this.a2z;
  4109. },
  4110. solve:function(){
  4111. 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);
  4112. // motor part
  4113. var newMotorImpulse;
  4114. if(this.enableMotor){
  4115. newMotorImpulse=(rvn-this.motorSpeed)*this.invMotorDenom;
  4116. var oldMotorImpulse=this.motorImpulse;
  4117. this.motorImpulse+=newMotorImpulse;
  4118. if(this.motorImpulse>this.maxMotorImpulse)this.motorImpulse=this.maxMotorImpulse;
  4119. else if(this.motorImpulse<-this.maxMotorImpulse)this.motorImpulse=-this.maxMotorImpulse;
  4120. newMotorImpulse=this.motorImpulse-oldMotorImpulse;
  4121. rvn-=newMotorImpulse*this.motorDenom;
  4122. }else newMotorImpulse=0;
  4123. // limit part
  4124. var newLimitImpulse;
  4125. if(this.limitState!=2){
  4126. newLimitImpulse=(rvn-this.limitVelocity-this.limitImpulse*this.cfm)*this.invDenom;
  4127. var oldLimitImpulse=this.limitImpulse;
  4128. this.limitImpulse+=newLimitImpulse;
  4129. if(this.limitImpulse*this.limitState<0)this.limitImpulse=0;
  4130. newLimitImpulse=this.limitImpulse-oldLimitImpulse;
  4131. }else newLimitImpulse=0;
  4132. var totalImpulse=newLimitImpulse+newMotorImpulse;
  4133. this.a1.x+=totalImpulse*this.a1x;
  4134. this.a1.y+=totalImpulse*this.a1y;
  4135. this.a1.z+=totalImpulse*this.a1z;
  4136. this.a2.x-=totalImpulse*this.a2x;
  4137. this.a2.y-=totalImpulse*this.a2y;
  4138. this.a2.z-=totalImpulse*this.a2z;
  4139. }
  4140. }
  4141. /**
  4142. * A three-axis translational constraint for various joints.
  4143. * @author saharan
  4144. */
  4145. OIMO.Translational3Constraint = function(joint,limitMotor1,limitMotor2,limitMotor3){
  4146. this.m1=NaN;
  4147. this.m2=NaN;
  4148. this.i1e00=NaN;
  4149. this.i1e01=NaN;
  4150. this.i1e02=NaN;
  4151. this.i1e10=NaN;
  4152. this.i1e11=NaN;
  4153. this.i1e12=NaN;
  4154. this.i1e20=NaN;
  4155. this.i1e21=NaN;
  4156. this.i1e22=NaN;
  4157. this.i2e00=NaN;
  4158. this.i2e01=NaN;
  4159. this.i2e02=NaN;
  4160. this.i2e10=NaN;
  4161. this.i2e11=NaN;
  4162. this.i2e12=NaN;
  4163. this.i2e20=NaN;
  4164. this.i2e21=NaN;
  4165. this.i2e22=NaN;
  4166. this.ax1=NaN;
  4167. this.ay1=NaN;
  4168. this.az1=NaN;
  4169. this.ax2=NaN;
  4170. this.ay2=NaN;
  4171. this.az2=NaN;
  4172. this.ax3=NaN;
  4173. this.ay3=NaN;
  4174. this.az3=NaN;
  4175. this.r1x=NaN;
  4176. this.r1y=NaN;
  4177. this.r1z=NaN;
  4178. this.r2x=NaN;
  4179. this.r2y=NaN;
  4180. this.r2z=NaN;
  4181. this.t1x1=NaN;// jacobians
  4182. this.t1y1=NaN;
  4183. this.t1z1=NaN;
  4184. this.t2x1=NaN;
  4185. this.t2y1=NaN;
  4186. this.t2z1=NaN;
  4187. this.l1x1=NaN;
  4188. this.l1y1=NaN;
  4189. this.l1z1=NaN;
  4190. this.l2x1=NaN;
  4191. this.l2y1=NaN;
  4192. this.l2z1=NaN;
  4193. this.a1x1=NaN;
  4194. this.a1y1=NaN;
  4195. this.a1z1=NaN;
  4196. this.a2x1=NaN;
  4197. this.a2y1=NaN;
  4198. this.a2z1=NaN;
  4199. this.t1x2=NaN;
  4200. this.t1y2=NaN;
  4201. this.t1z2=NaN;
  4202. this.t2x2=NaN;
  4203. this.t2y2=NaN;
  4204. this.t2z2=NaN;
  4205. this.l1x2=NaN;
  4206. this.l1y2=NaN;
  4207. this.l1z2=NaN;
  4208. this.l2x2=NaN;
  4209. this.l2y2=NaN;
  4210. this.l2z2=NaN;
  4211. this.a1x2=NaN;
  4212. this.a1y2=NaN;
  4213. this.a1z2=NaN;
  4214. this.a2x2=NaN;
  4215. this.a2y2=NaN;
  4216. this.a2z2=NaN;
  4217. this.t1x3=NaN;
  4218. this.t1y3=NaN;
  4219. this.t1z3=NaN;
  4220. this.t2x3=NaN;
  4221. this.t2y3=NaN;
  4222. this.t2z3=NaN;
  4223. this.l1x3=NaN;
  4224. this.l1y3=NaN;
  4225. this.l1z3=NaN;
  4226. this.l2x3=NaN;
  4227. this.l2y3=NaN;
  4228. this.l2z3=NaN;
  4229. this.a1x3=NaN;
  4230. this.a1y3=NaN;
  4231. this.a1z3=NaN;
  4232. this.a2x3=NaN;
  4233. this.a2y3=NaN;
  4234. this.a2z3=NaN;
  4235. this.lowerLimit1=NaN;
  4236. this.upperLimit1=NaN;
  4237. this.limitVelocity1=NaN;
  4238. this.limitState1=0; // -1: at lower, 0: locked, 1: at upper, 2: unlimited
  4239. this.enableMotor1=false;
  4240. this.motorSpeed1=NaN;
  4241. this.maxMotorForce1=NaN;
  4242. this.maxMotorImpulse1=NaN;
  4243. this.lowerLimit2=NaN;
  4244. this.upperLimit2=NaN;
  4245. this.limitVelocity2=NaN;
  4246. this.limitState2=0; // -1: at lower, 0: locked, 1: at upper, 2: unlimited
  4247. this.enableMotor2=false;
  4248. this.motorSpeed2=NaN;
  4249. this.maxMotorForce2=NaN;
  4250. this.maxMotorImpulse2=NaN;
  4251. this.lowerLimit3=NaN;
  4252. this.upperLimit3=NaN;
  4253. this.limitVelocity3=NaN;
  4254. this.limitState3=0; // -1: at lower, 0: locked, 1: at upper, 2: unlimited
  4255. this.enableMotor3=false;
  4256. this.motorSpeed3=NaN;
  4257. this.maxMotorForce3=NaN;
  4258. this.maxMotorImpulse3=NaN;
  4259. this.k00=NaN; // K = J*M*JT
  4260. this.k01=NaN;
  4261. this.k02=NaN;
  4262. this.k10=NaN;
  4263. this.k11=NaN;
  4264. this.k12=NaN;
  4265. this.k20=NaN;
  4266. this.k21=NaN;
  4267. this.k22=NaN;
  4268. this.kv00=NaN; // diagonals without CFMs
  4269. this.kv11=NaN;
  4270. this.kv22=NaN;
  4271. this.dv00=NaN; // ...inverted
  4272. this.dv11=NaN;
  4273. this.dv22=NaN;
  4274. this.d00=NaN; // K^-1
  4275. this.d01=NaN;
  4276. this.d02=NaN;
  4277. this.d10=NaN;
  4278. this.d11=NaN;
  4279. this.d12=NaN;
  4280. this.d20=NaN;
  4281. this.d21=NaN;
  4282. this.d22=NaN;
  4283. this.limitMotor1=limitMotor1;
  4284. this.limitMotor2=limitMotor2;
  4285. this.limitMotor3=limitMotor3;
  4286. this.b1=joint.body1;
  4287. this.b2=joint.body2;
  4288. this.p1=joint.anchorPoint1;
  4289. this.p2=joint.anchorPoint2;
  4290. this.r1=joint.relativeAnchorPoint1;
  4291. this.r2=joint.relativeAnchorPoint2;
  4292. this.l1=this.b1.linearVelocity;
  4293. this.l2=this.b2.linearVelocity;
  4294. this.a1=this.b1.angularVelocity;
  4295. this.a2=this.b2.angularVelocity;
  4296. this.i1=this.b1.inverseInertia;
  4297. this.i2=this.b2.inverseInertia;
  4298. this.limitImpulse1=0;
  4299. this.motorImpulse1=0;
  4300. this.limitImpulse2=0;
  4301. this.motorImpulse2=0;
  4302. this.limitImpulse3=0;
  4303. this.motorImpulse3=0;
  4304. this.cfm1=0;// Constraint Force Mixing
  4305. this.cfm2=0;
  4306. this.cfm3=0;
  4307. this.weight=-1;
  4308. }
  4309. OIMO.Translational3Constraint.prototype = {
  4310. constructor: OIMO.Translational3Constraint,
  4311. preSolve:function(timeStep,invTimeStep){
  4312. this.ax1=this.limitMotor1.axis.x;
  4313. this.ay1=this.limitMotor1.axis.y;
  4314. this.az1=this.limitMotor1.axis.z;
  4315. this.ax2=this.limitMotor2.axis.x;
  4316. this.ay2=this.limitMotor2.axis.y;
  4317. this.az2=this.limitMotor2.axis.z;
  4318. this.ax3=this.limitMotor3.axis.x;
  4319. this.ay3=this.limitMotor3.axis.y;
  4320. this.az3=this.limitMotor3.axis.z;
  4321. this.lowerLimit1=this.limitMotor1.lowerLimit;
  4322. this.upperLimit1=this.limitMotor1.upperLimit;
  4323. this.motorSpeed1=this.limitMotor1.motorSpeed;
  4324. this.maxMotorForce1=this.limitMotor1.maxMotorForce;
  4325. this.enableMotor1=this.maxMotorForce1>0;
  4326. this.lowerLimit2=this.limitMotor2.lowerLimit;
  4327. this.upperLimit2=this.limitMotor2.upperLimit;
  4328. this.motorSpeed2=this.limitMotor2.motorSpeed;
  4329. this.maxMotorForce2=this.limitMotor2.maxMotorForce;
  4330. this.enableMotor2=this.maxMotorForce2>0;
  4331. this.lowerLimit3=this.limitMotor3.lowerLimit;
  4332. this.upperLimit3=this.limitMotor3.upperLimit;
  4333. this.motorSpeed3=this.limitMotor3.motorSpeed;
  4334. this.maxMotorForce3=this.limitMotor3.maxMotorForce;
  4335. this.enableMotor3=this.maxMotorForce3>0;
  4336. this.m1=this.b1.inverseMass;
  4337. this.m2=this.b2.inverseMass;
  4338. var ti1 = this.i1.elements;
  4339. var ti2 = this.i2.elements;
  4340. this.i1e00=ti1[0];
  4341. this.i1e01=ti1[1];
  4342. this.i1e02=ti1[2];
  4343. this.i1e10=ti1[3];
  4344. this.i1e11=ti1[4];
  4345. this.i1e12=ti1[5];
  4346. this.i1e20=ti1[6];
  4347. this.i1e21=ti1[7];
  4348. this.i1e22=ti1[8];
  4349. this.i2e00=ti2[0];
  4350. this.i2e01=ti2[1];
  4351. this.i2e02=ti2[2];
  4352. this.i2e10=ti2[3];
  4353. this.i2e11=ti2[4];
  4354. this.i2e12=ti2[5];
  4355. this.i2e20=ti2[6];
  4356. this.i2e21=ti2[7];
  4357. this.i2e22=ti2[8];
  4358. var dx=this.p2.x-this.p1.x;
  4359. var dy=this.p2.y-this.p1.y;
  4360. var dz=this.p2.z-this.p1.z;
  4361. var d1=dx*this.ax1+dy*this.ay1+dz*this.az1;
  4362. var d2=dx*this.ax2+dy*this.ay2+dz*this.az2;
  4363. var d3=dx*this.ax3+dy*this.ay3+dz*this.az3;
  4364. var frequency1=this.limitMotor1.frequency;
  4365. var frequency2=this.limitMotor2.frequency;
  4366. var frequency3=this.limitMotor3.frequency;
  4367. var enableSpring1=frequency1>0;
  4368. var enableSpring2=frequency2>0;
  4369. var enableSpring3=frequency3>0;
  4370. var enableLimit1=this.lowerLimit1<=this.upperLimit1;
  4371. var enableLimit2=this.lowerLimit2<=this.upperLimit2;
  4372. var enableLimit3=this.lowerLimit3<=this.upperLimit3;
  4373. // for stability
  4374. if(enableSpring1&&d1>20||d1<-20){
  4375. enableSpring1=false;
  4376. }
  4377. if(enableSpring2&&d2>20||d2<-20){
  4378. enableSpring2=false;
  4379. }
  4380. if(enableSpring3&&d3>20||d3<-20){
  4381. enableSpring3=false;
  4382. }
  4383. if(enableLimit1){
  4384. if(this.lowerLimit1==this.upperLimit1){
  4385. if(this.limitState1!=0){
  4386. this.limitState1=0;
  4387. this.limitImpulse1=0;
  4388. }
  4389. this.limitVelocity1=this.lowerLimit1-d1;
  4390. if(!enableSpring1)d1=this.lowerLimit1;
  4391. }else if(d1<this.lowerLimit1){
  4392. if(this.limitState1!=-1){
  4393. this.limitState1=-1;
  4394. this.limitImpulse1=0;
  4395. }
  4396. this.limitVelocity1=this.lowerLimit1-d1;
  4397. if(!enableSpring1)d1=this.lowerLimit1;
  4398. }else if(d1>this.upperLimit1){
  4399. if(this.limitState1!=1){
  4400. this.limitState1=1;
  4401. this.limitImpulse1=0;
  4402. }
  4403. this.limitVelocity1=this.upperLimit1-d1;
  4404. if(!enableSpring1)d1=this.upperLimit1;
  4405. }else{
  4406. this.limitState1=2;
  4407. this.limitImpulse1=0;
  4408. this.limitVelocity1=0;
  4409. }
  4410. if(!enableSpring1){
  4411. if(this.limitVelocity1>0.005)this.limitVelocity1-=0.005;
  4412. else if(this.limitVelocity1<-0.005)this.limitVelocity1+=0.005;
  4413. else this.limitVelocity1=0;
  4414. }
  4415. }else{
  4416. this.limitState1=2;
  4417. this.limitImpulse1=0;
  4418. }
  4419. if(enableLimit2){
  4420. if(this.lowerLimit2==this.upperLimit2){
  4421. if(this.limitState2!=0){
  4422. this.limitState2=0;
  4423. this.limitImpulse2=0;
  4424. }
  4425. this.limitVelocity2=this.lowerLimit2-d2;
  4426. if(!enableSpring2)d2=this.lowerLimit2;
  4427. }else if(d2<this.lowerLimit2){
  4428. if(this.limitState2!=-1){
  4429. this.limitState2=-1;
  4430. this.limitImpulse2=0;
  4431. }
  4432. this.limitVelocity2=this.lowerLimit2-d2;
  4433. if(!enableSpring2)d2=this.lowerLimit2;
  4434. }else if(d2>this.upperLimit2){
  4435. if(this.limitState2!=1){
  4436. this.limitState2=1;
  4437. this.limitImpulse2=0;
  4438. }
  4439. this.limitVelocity2=this.upperLimit2-d2;
  4440. if(!enableSpring2)d2=this.upperLimit2;
  4441. }else{
  4442. this.limitState2=2;
  4443. this.limitImpulse2=0;
  4444. this.limitVelocity2=0;
  4445. }
  4446. if(!enableSpring2){
  4447. if(this.limitVelocity2>0.005)this.limitVelocity2-=0.005;
  4448. else if(this.limitVelocity2<-0.005)this.limitVelocity2+=0.005;
  4449. else this.limitVelocity2=0;
  4450. }
  4451. }else{
  4452. this.limitState2=2;
  4453. this.limitImpulse2=0;
  4454. }
  4455. if(enableLimit3){
  4456. if(this.lowerLimit3==this.upperLimit3){
  4457. if(this.limitState3!=0){
  4458. this.limitState3=0;
  4459. this.limitImpulse3=0;
  4460. }
  4461. this.limitVelocity3=this.lowerLimit3-d3;
  4462. if(!enableSpring3)d3=this.lowerLimit3;
  4463. }else if(d3<this.lowerLimit3){
  4464. if(this.limitState3!=-1){
  4465. this.limitState3=-1;
  4466. this.limitImpulse3=0;
  4467. }
  4468. this.limitVelocity3=this.lowerLimit3-d3;
  4469. if(!enableSpring3)d3=this.lowerLimit3;
  4470. }else if(d3>this.upperLimit3){
  4471. if(this.limitState3!=1){
  4472. this.limitState3=1;
  4473. this.limitImpulse3=0;
  4474. }
  4475. this.limitVelocity3=this.upperLimit3-d3;
  4476. if(!enableSpring3)d3=this.upperLimit3;
  4477. }else{
  4478. this.limitState3=2;
  4479. this.limitImpulse3=0;
  4480. this.limitVelocity3=0;
  4481. }
  4482. if(!enableSpring3){
  4483. if(this.limitVelocity3>0.005)this.limitVelocity3-=0.005;
  4484. else if(this.limitVelocity3<-0.005)this.limitVelocity3+=0.005;
  4485. else this.limitVelocity3=0;
  4486. }
  4487. }else{
  4488. this.limitState3=2;
  4489. this.limitImpulse3=0;
  4490. }
  4491. if(this.enableMotor1&&(this.limitState1!=0||enableSpring1)){
  4492. this.maxMotorImpulse1=this.maxMotorForce1*timeStep;
  4493. }else{
  4494. this.motorImpulse1=0;
  4495. this.maxMotorImpulse1=0;
  4496. }
  4497. if(this.enableMotor2&&(this.limitState2!=0||enableSpring2)){
  4498. this.maxMotorImpulse2=this.maxMotorForce2*timeStep;
  4499. }else{
  4500. this.motorImpulse2=0;
  4501. this.maxMotorImpulse2=0;
  4502. }
  4503. if(this.enableMotor3&&(this.limitState3!=0||enableSpring3)){
  4504. this.maxMotorImpulse3=this.maxMotorForce3*timeStep;
  4505. }else{
  4506. this.motorImpulse3=0;
  4507. this.maxMotorImpulse3=0;
  4508. }
  4509. var rdx=d1*this.ax1+d2*this.ax2+d3*this.ax2;
  4510. var rdy=d1*this.ay1+d2*this.ay2+d3*this.ay2;
  4511. var rdz=d1*this.az1+d2*this.az2+d3*this.az2;
  4512. var w1=this.m2/(this.m1+this.m2);
  4513. if(this.weight>=0)w1=this.weight; // use given weight
  4514. var w2=1-w1;
  4515. this.r1x=this.r1.x+rdx*w1;
  4516. this.r1y=this.r1.y+rdy*w1;
  4517. this.r1z=this.r1.z+rdz*w1;
  4518. this.r2x=this.r2.x-rdx*w2;
  4519. this.r2y=this.r2.y-rdy*w2;
  4520. this.r2z=this.r2.z-rdz*w2;
  4521. // build jacobians
  4522. this.t1x1=this.r1y*this.az1-this.r1z*this.ay1;
  4523. this.t1y1=this.r1z*this.ax1-this.r1x*this.az1;
  4524. this.t1z1=this.r1x*this.ay1-this.r1y*this.ax1;
  4525. this.t2x1=this.r2y*this.az1-this.r2z*this.ay1;
  4526. this.t2y1=this.r2z*this.ax1-this.r2x*this.az1;
  4527. this.t2z1=this.r2x*this.ay1-this.r2y*this.ax1;
  4528. this.l1x1=this.ax1*this.m1;
  4529. this.l1y1=this.ay1*this.m1;
  4530. this.l1z1=this.az1*this.m1;
  4531. this.l2x1=this.ax1*this.m2;
  4532. this.l2y1=this.ay1*this.m2;
  4533. this.l2z1=this.az1*this.m2;
  4534. this.a1x1=this.t1x1*this.i1e00+this.t1y1*this.i1e01+this.t1z1*this.i1e02;
  4535. this.a1y1=this.t1x1*this.i1e10+this.t1y1*this.i1e11+this.t1z1*this.i1e12;
  4536. this.a1z1=this.t1x1*this.i1e20+this.t1y1*this.i1e21+this.t1z1*this.i1e22;
  4537. this.a2x1=this.t2x1*this.i2e00+this.t2y1*this.i2e01+this.t2z1*this.i2e02;
  4538. this.a2y1=this.t2x1*this.i2e10+this.t2y1*this.i2e11+this.t2z1*this.i2e12;
  4539. this.a2z1=this.t2x1*this.i2e20+this.t2y1*this.i2e21+this.t2z1*this.i2e22;
  4540. this.t1x2=this.r1y*this.az2-this.r1z*this.ay2;
  4541. this.t1y2=this.r1z*this.ax2-this.r1x*this.az2;
  4542. this.t1z2=this.r1x*this.ay2-this.r1y*this.ax2;
  4543. this.t2x2=this.r2y*this.az2-this.r2z*this.ay2;
  4544. this.t2y2=this.r2z*this.ax2-this.r2x*this.az2;
  4545. this.t2z2=this.r2x*this.ay2-this.r2y*this.ax2;
  4546. this.l1x2=this.ax2*this.m1;
  4547. this.l1y2=this.ay2*this.m1;
  4548. this.l1z2=this.az2*this.m1;
  4549. this.l2x2=this.ax2*this.m2;
  4550. this.l2y2=this.ay2*this.m2;
  4551. this.l2z2=this.az2*this.m2;
  4552. this.a1x2=this.t1x2*this.i1e00+this.t1y2*this.i1e01+this.t1z2*this.i1e02;
  4553. this.a1y2=this.t1x2*this.i1e10+this.t1y2*this.i1e11+this.t1z2*this.i1e12;
  4554. this.a1z2=this.t1x2*this.i1e20+this.t1y2*this.i1e21+this.t1z2*this.i1e22;
  4555. this.a2x2=this.t2x2*this.i2e00+this.t2y2*this.i2e01+this.t2z2*this.i2e02;
  4556. this.a2y2=this.t2x2*this.i2e10+this.t2y2*this.i2e11+this.t2z2*this.i2e12;
  4557. this.a2z2=this.t2x2*this.i2e20+this.t2y2*this.i2e21+this.t2z2*this.i2e22;
  4558. this.t1x3=this.r1y*this.az3-this.r1z*this.ay3;
  4559. this.t1y3=this.r1z*this.ax3-this.r1x*this.az3;
  4560. this.t1z3=this.r1x*this.ay3-this.r1y*this.ax3;
  4561. this.t2x3=this.r2y*this.az3-this.r2z*this.ay3;
  4562. this.t2y3=this.r2z*this.ax3-this.r2x*this.az3;
  4563. this.t2z3=this.r2x*this.ay3-this.r2y*this.ax3;
  4564. this.l1x3=this.ax3*this.m1;
  4565. this.l1y3=this.ay3*this.m1;
  4566. this.l1z3=this.az3*this.m1;
  4567. this.l2x3=this.ax3*this.m2;
  4568. this.l2y3=this.ay3*this.m2;
  4569. this.l2z3=this.az3*this.m2;
  4570. this.a1x3=this.t1x3*this.i1e00+this.t1y3*this.i1e01+this.t1z3*this.i1e02;
  4571. this.a1y3=this.t1x3*this.i1e10+this.t1y3*this.i1e11+this.t1z3*this.i1e12;
  4572. this.a1z3=this.t1x3*this.i1e20+this.t1y3*this.i1e21+this.t1z3*this.i1e22;
  4573. this.a2x3=this.t2x3*this.i2e00+this.t2y3*this.i2e01+this.t2z3*this.i2e02;
  4574. this.a2y3=this.t2x3*this.i2e10+this.t2y3*this.i2e11+this.t2z3*this.i2e12;
  4575. this.a2z3=this.t2x3*this.i2e20+this.t2y3*this.i2e21+this.t2z3*this.i2e22;
  4576. // build an impulse matrix
  4577. var m12=this.m1+this.m2;
  4578. this.k00=(this.ax1*this.ax1+this.ay1*this.ay1+this.az1*this.az1)*m12;
  4579. this.k01=(this.ax1*this.ax2+this.ay1*this.ay2+this.az1*this.az2)*m12;
  4580. this.k02=(this.ax1*this.ax3+this.ay1*this.ay3+this.az1*this.az3)*m12;
  4581. this.k10=(this.ax2*this.ax1+this.ay2*this.ay1+this.az2*this.az1)*m12;
  4582. this.k11=(this.ax2*this.ax2+this.ay2*this.ay2+this.az2*this.az2)*m12;
  4583. this.k12=(this.ax2*this.ax3+this.ay2*this.ay3+this.az2*this.az3)*m12;
  4584. this.k20=(this.ax3*this.ax1+this.ay3*this.ay1+this.az3*this.az1)*m12;
  4585. this.k21=(this.ax3*this.ax2+this.ay3*this.ay2+this.az3*this.az2)*m12;
  4586. this.k22=(this.ax3*this.ax3+this.ay3*this.ay3+this.az3*this.az3)*m12;
  4587. this.k00+=this.t1x1*this.a1x1+this.t1y1*this.a1y1+this.t1z1*this.a1z1;
  4588. this.k01+=this.t1x1*this.a1x2+this.t1y1*this.a1y2+this.t1z1*this.a1z2;
  4589. this.k02+=this.t1x1*this.a1x3+this.t1y1*this.a1y3+this.t1z1*this.a1z3;
  4590. this.k10+=this.t1x2*this.a1x1+this.t1y2*this.a1y1+this.t1z2*this.a1z1;
  4591. this.k11+=this.t1x2*this.a1x2+this.t1y2*this.a1y2+this.t1z2*this.a1z2;
  4592. this.k12+=this.t1x2*this.a1x3+this.t1y2*this.a1y3+this.t1z2*this.a1z3;
  4593. this.k20+=this.t1x3*this.a1x1+this.t1y3*this.a1y1+this.t1z3*this.a1z1;
  4594. this.k21+=this.t1x3*this.a1x2+this.t1y3*this.a1y2+this.t1z3*this.a1z2;
  4595. this.k22+=this.t1x3*this.a1x3+this.t1y3*this.a1y3+this.t1z3*this.a1z3;
  4596. this.k00+=this.t2x1*this.a2x1+this.t2y1*this.a2y1+this.t2z1*this.a2z1;
  4597. this.k01+=this.t2x1*this.a2x2+this.t2y1*this.a2y2+this.t2z1*this.a2z2;
  4598. this.k02+=this.t2x1*this.a2x3+this.t2y1*this.a2y3+this.t2z1*this.a2z3;
  4599. this.k10+=this.t2x2*this.a2x1+this.t2y2*this.a2y1+this.t2z2*this.a2z1;
  4600. this.k11+=this.t2x2*this.a2x2+this.t2y2*this.a2y2+this.t2z2*this.a2z2;
  4601. this.k12+=this.t2x2*this.a2x3+this.t2y2*this.a2y3+this.t2z2*this.a2z3;
  4602. this.k20+=this.t2x3*this.a2x1+this.t2y3*this.a2y1+this.t2z3*this.a2z1;
  4603. this.k21+=this.t2x3*this.a2x2+this.t2y3*this.a2y2+this.t2z3*this.a2z2;
  4604. this.k22+=this.t2x3*this.a2x3+this.t2y3*this.a2y3+this.t2z3*this.a2z3;
  4605. this.kv00=this.k00;
  4606. this.kv11=this.k11;
  4607. this.kv22=this.k22;
  4608. this.dv00=1/this.kv00;
  4609. this.dv11=1/this.kv11;
  4610. this.dv22=1/this.kv22;
  4611. if(enableSpring1&&this.limitState1!=2){
  4612. var omega=6.2831853*frequency1;
  4613. var k=omega*omega*timeStep;
  4614. var dmp=invTimeStep/(k+2*this.limitMotor1.dampingRatio*omega);
  4615. this.cfm1=this.kv00*dmp;
  4616. this.limitVelocity1*=k*dmp;
  4617. }else{
  4618. this.cfm1=0;
  4619. this.limitVelocity1*=invTimeStep*0.05;
  4620. }
  4621. if(enableSpring2&&this.limitState2!=2){
  4622. omega=6.2831853*frequency2;
  4623. k=omega*omega*timeStep;
  4624. dmp=invTimeStep/(k+2*this.limitMotor2.dampingRatio*omega);
  4625. this.cfm2=this.kv11*dmp;
  4626. this.limitVelocity2*=k*dmp;
  4627. }else{
  4628. this.cfm2=0;
  4629. this.limitVelocity2*=invTimeStep*0.05;
  4630. }
  4631. if(enableSpring3&&this.limitState3!=2){
  4632. omega=6.2831853*frequency3;
  4633. k=omega*omega*timeStep;
  4634. dmp=invTimeStep/(k+2*this.limitMotor3.dampingRatio*omega);
  4635. this.cfm3=this.kv22*dmp;
  4636. this.limitVelocity3*=k*dmp;
  4637. }else{
  4638. this.cfm3=0;
  4639. this.limitVelocity3*=invTimeStep*0.05;
  4640. }
  4641. this.k00+=this.cfm1;
  4642. this.k11+=this.cfm2;
  4643. this.k22+=this.cfm3;
  4644. var inv=1/(
  4645. this.k00*(this.k11*this.k22-this.k21*this.k12)+
  4646. this.k10*(this.k21*this.k02-this.k01*this.k22)+
  4647. this.k20*(this.k01*this.k12-this.k11*this.k02)
  4648. );
  4649. this.d00=(this.k11*this.k22-this.k12*this.k21)*inv;
  4650. this.d01=(this.k02*this.k21-this.k01*this.k22)*inv;
  4651. this.d02=(this.k01*this.k12-this.k02*this.k11)*inv;
  4652. this.d10=(this.k12*this.k20-this.k10*this.k22)*inv;
  4653. this.d11=(this.k00*this.k22-this.k02*this.k20)*inv;
  4654. this.d12=(this.k02*this.k10-this.k00*this.k12)*inv;
  4655. this.d20=(this.k10*this.k21-this.k11*this.k20)*inv;
  4656. this.d21=(this.k01*this.k20-this.k00*this.k21)*inv;
  4657. this.d22=(this.k00*this.k11-this.k01*this.k10)*inv;
  4658. // warm starting
  4659. var totalImpulse1=this.limitImpulse1+this.motorImpulse1;
  4660. var totalImpulse2=this.limitImpulse2+this.motorImpulse2;
  4661. var totalImpulse3=this.limitImpulse3+this.motorImpulse3;
  4662. this.l1.x+=totalImpulse1*this.l1x1+totalImpulse2*this.l1x2+totalImpulse3*this.l1x3;
  4663. this.l1.y+=totalImpulse1*this.l1y1+totalImpulse2*this.l1y2+totalImpulse3*this.l1y3;
  4664. this.l1.z+=totalImpulse1*this.l1z1+totalImpulse2*this.l1z2+totalImpulse3*this.l1z3;
  4665. this.a1.x+=totalImpulse1*this.a1x1+totalImpulse2*this.a1x2+totalImpulse3*this.a1x3;
  4666. this.a1.y+=totalImpulse1*this.a1y1+totalImpulse2*this.a1y2+totalImpulse3*this.a1y3;
  4667. this.a1.z+=totalImpulse1*this.a1z1+totalImpulse2*this.a1z2+totalImpulse3*this.a1z3;
  4668. this.l2.x-=totalImpulse1*this.l2x1+totalImpulse2*this.l2x2+totalImpulse3*this.l2x3;
  4669. this.l2.y-=totalImpulse1*this.l2y1+totalImpulse2*this.l2y2+totalImpulse3*this.l2y3;
  4670. this.l2.z-=totalImpulse1*this.l2z1+totalImpulse2*this.l2z2+totalImpulse3*this.l2z3;
  4671. this.a2.x-=totalImpulse1*this.a2x1+totalImpulse2*this.a2x2+totalImpulse3*this.a2x3;
  4672. this.a2.y-=totalImpulse1*this.a2y1+totalImpulse2*this.a2y2+totalImpulse3*this.a2y3;
  4673. this.a2.z-=totalImpulse1*this.a2z1+totalImpulse2*this.a2z2+totalImpulse3*this.a2z3;
  4674. },
  4675. solve:function(){
  4676. 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;
  4677. 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;
  4678. 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;
  4679. var rvn1=rvx*this.ax1+rvy*this.ay1+rvz*this.az1;
  4680. var rvn2=rvx*this.ax2+rvy*this.ay2+rvz*this.az2;
  4681. var rvn3=rvx*this.ax3+rvy*this.ay3+rvz*this.az3;
  4682. var oldMotorImpulse1=this.motorImpulse1;
  4683. var oldMotorImpulse2=this.motorImpulse2;
  4684. var oldMotorImpulse3=this.motorImpulse3;
  4685. var dMotorImpulse1=0;
  4686. var dMotorImpulse2=0;
  4687. var dMotorImpulse3=0;
  4688. if(this.enableMotor1){
  4689. dMotorImpulse1=(rvn1-this.motorSpeed1)*this.dv00;
  4690. this.motorImpulse1+=dMotorImpulse1;
  4691. if(this.motorImpulse1>this.maxMotorImpulse1){ // clamp motor impulse
  4692. this.motorImpulse1=this.maxMotorImpulse1;
  4693. }else if(this.motorImpulse1<-this.maxMotorImpulse1){
  4694. this.motorImpulse1=-this.maxMotorImpulse1;
  4695. }
  4696. dMotorImpulse1=this.motorImpulse1-oldMotorImpulse1;
  4697. }
  4698. if(this.enableMotor2){
  4699. dMotorImpulse2=(rvn2-this.motorSpeed2)*this.dv11;
  4700. this.motorImpulse2+=dMotorImpulse2;
  4701. if(this.motorImpulse2>this.maxMotorImpulse2){ // clamp motor impulse
  4702. this.motorImpulse2=this.maxMotorImpulse2;
  4703. }else if(this.motorImpulse2<-this.maxMotorImpulse2){
  4704. this.motorImpulse2=-this.maxMotorImpulse2;
  4705. }
  4706. dMotorImpulse2=this.motorImpulse2-oldMotorImpulse2;
  4707. }
  4708. if(this.enableMotor3){
  4709. dMotorImpulse3=(rvn3-this.motorSpeed3)*this.dv22;
  4710. this.motorImpulse3+=dMotorImpulse3;
  4711. if(this.motorImpulse3>this.maxMotorImpulse3){ // clamp motor impulse
  4712. this.motorImpulse3=this.maxMotorImpulse3;
  4713. }else if(this.motorImpulse3<-this.maxMotorImpulse3){
  4714. this.motorImpulse3=-this.maxMotorImpulse3;
  4715. }
  4716. dMotorImpulse3=this.motorImpulse3-oldMotorImpulse3;
  4717. }
  4718. // apply motor impulse to relative velocity
  4719. rvn1+=dMotorImpulse1*this.kv00+dMotorImpulse2*this.k01+dMotorImpulse3*this.k02;
  4720. rvn2+=dMotorImpulse1*this.k10+dMotorImpulse2*this.kv11+dMotorImpulse3*this.k12;
  4721. rvn3+=dMotorImpulse1*this.k20+dMotorImpulse2*this.k21+dMotorImpulse3*this.kv22;
  4722. // subtract target velocity and applied impulse
  4723. rvn1-=this.limitVelocity1+this.limitImpulse1*this.cfm1;
  4724. rvn2-=this.limitVelocity2+this.limitImpulse2*this.cfm2;
  4725. rvn3-=this.limitVelocity3+this.limitImpulse3*this.cfm3;
  4726. var oldLimitImpulse1=this.limitImpulse1;
  4727. var oldLimitImpulse2=this.limitImpulse2;
  4728. var oldLimitImpulse3=this.limitImpulse3;
  4729. var dLimitImpulse1=rvn1*this.d00+rvn2*this.d01+rvn3*this.d02;
  4730. var dLimitImpulse2=rvn1*this.d10+rvn2*this.d11+rvn3*this.d12;
  4731. var dLimitImpulse3=rvn1*this.d20+rvn2*this.d21+rvn3*this.d22;
  4732. this.limitImpulse1+=dLimitImpulse1;
  4733. this.limitImpulse2+=dLimitImpulse2;
  4734. this.limitImpulse3+=dLimitImpulse3;
  4735. // clamp
  4736. var clampState=0;
  4737. if(this.limitState1==2||this.limitImpulse1*this.limitState1<0){
  4738. dLimitImpulse1=-oldLimitImpulse1;
  4739. rvn2+=dLimitImpulse1*this.k10;
  4740. rvn3+=dLimitImpulse1*this.k20;
  4741. clampState|=1;
  4742. }
  4743. if(this.limitState2==2||this.limitImpulse2*this.limitState2<0){
  4744. dLimitImpulse2=-oldLimitImpulse2;
  4745. rvn1+=dLimitImpulse2*this.k01;
  4746. rvn3+=dLimitImpulse2*this.k21;
  4747. clampState|=2;
  4748. }
  4749. if(this.limitState3==2||this.limitImpulse3*this.limitState3<0){
  4750. dLimitImpulse3=-oldLimitImpulse3;
  4751. rvn1+=dLimitImpulse3*this.k02;
  4752. rvn2+=dLimitImpulse3*this.k12;
  4753. clampState|=4;
  4754. }
  4755. // update un-clamped impulse
  4756. // TODO: isolate division
  4757. var det;
  4758. switch(clampState){
  4759. case 1:// update 2 3
  4760. det=1/(this.k11*this.k22-this.k12*this.k21);
  4761. dLimitImpulse2=(this.k22*rvn2+-this.k12*rvn3)*det;
  4762. dLimitImpulse3=(-this.k21*rvn2+this.k11*rvn3)*det;
  4763. break;
  4764. case 2:// update 1 3
  4765. det=1/(this.k00*this.k22-this.k02*this.k20);
  4766. dLimitImpulse1=(this.k22*rvn1+-this.k02*rvn3)*det;
  4767. dLimitImpulse3=(-this.k20*rvn1+this.k00*rvn3)*det;
  4768. break;
  4769. case 3:// update 3
  4770. dLimitImpulse3=rvn3/this.k22;
  4771. break;
  4772. case 4:// update 1 2
  4773. det=1/(this.k00*this.k11-this.k01*this.k10);
  4774. dLimitImpulse1=(this.k11*rvn1+-this.k01*rvn2)*det;
  4775. dLimitImpulse2=(-this.k10*rvn1+this.k00*rvn2)*det;
  4776. break;
  4777. case 5:// update 2
  4778. dLimitImpulse2=rvn2/this.k11;
  4779. break;
  4780. case 6:// update 1
  4781. dLimitImpulse1=rvn1/this.k00;
  4782. break;
  4783. }
  4784. this.limitImpulse1=oldLimitImpulse1+dLimitImpulse1;
  4785. this.limitImpulse2=oldLimitImpulse2+dLimitImpulse2;
  4786. this.limitImpulse3=oldLimitImpulse3+dLimitImpulse3;
  4787. var dImpulse1=dMotorImpulse1+dLimitImpulse1;
  4788. var dImpulse2=dMotorImpulse2+dLimitImpulse2;
  4789. var dImpulse3=dMotorImpulse3+dLimitImpulse3;
  4790. // apply impulse
  4791. this.l1.x+=dImpulse1*this.l1x1+dImpulse2*this.l1x2+dImpulse3*this.l1x3;
  4792. this.l1.y+=dImpulse1*this.l1y1+dImpulse2*this.l1y2+dImpulse3*this.l1y3;
  4793. this.l1.z+=dImpulse1*this.l1z1+dImpulse2*this.l1z2+dImpulse3*this.l1z3;
  4794. this.a1.x+=dImpulse1*this.a1x1+dImpulse2*this.a1x2+dImpulse3*this.a1x3;
  4795. this.a1.y+=dImpulse1*this.a1y1+dImpulse2*this.a1y2+dImpulse3*this.a1y3;
  4796. this.a1.z+=dImpulse1*this.a1z1+dImpulse2*this.a1z2+dImpulse3*this.a1z3;
  4797. this.l2.x-=dImpulse1*this.l2x1+dImpulse2*this.l2x2+dImpulse3*this.l2x3;
  4798. this.l2.y-=dImpulse1*this.l2y1+dImpulse2*this.l2y2+dImpulse3*this.l2y3;
  4799. this.l2.z-=dImpulse1*this.l2z1+dImpulse2*this.l2z2+dImpulse3*this.l2z3;
  4800. this.a2.x-=dImpulse1*this.a2x1+dImpulse2*this.a2x2+dImpulse3*this.a2x3;
  4801. this.a2.y-=dImpulse1*this.a2y1+dImpulse2*this.a2y2+dImpulse3*this.a2y3;
  4802. this.a2.z-=dImpulse1*this.a2z1+dImpulse2*this.a2z2+dImpulse3*this.a2z3;
  4803. }
  4804. }
  4805. /**
  4806. * A translational constraint for various joints.
  4807. * @author saharan
  4808. */
  4809. OIMO.TranslationalConstraint = function(joint,limitMotor){
  4810. this.cfm=NaN;
  4811. this.m1=NaN;
  4812. this.m2=NaN;
  4813. this.i1e00=NaN;
  4814. this.i1e01=NaN;
  4815. this.i1e02=NaN;
  4816. this.i1e10=NaN;
  4817. this.i1e11=NaN;
  4818. this.i1e12=NaN;
  4819. this.i1e20=NaN;
  4820. this.i1e21=NaN;
  4821. this.i1e22=NaN;
  4822. this.i2e00=NaN;
  4823. this.i2e01=NaN;
  4824. this.i2e02=NaN;
  4825. this.i2e10=NaN;
  4826. this.i2e11=NaN;
  4827. this.i2e12=NaN;
  4828. this.i2e20=NaN;
  4829. this.i2e21=NaN;
  4830. this.i2e22=NaN;
  4831. this.motorDenom=NaN;
  4832. this.invMotorDenom=NaN;
  4833. this.invDenom=NaN;
  4834. this.ax=NaN;
  4835. this.ay=NaN;
  4836. this.az=NaN;
  4837. this.r1x=NaN;
  4838. this.r1y=NaN;
  4839. this.r1z=NaN;
  4840. this.r2x=NaN;
  4841. this.r2y=NaN;
  4842. this.r2z=NaN;
  4843. this.t1x=NaN;
  4844. this.t1y=NaN;
  4845. this.t1z=NaN;
  4846. this.t2x=NaN;
  4847. this.t2y=NaN;
  4848. this.t2z=NaN;
  4849. this.l1x=NaN;
  4850. this.l1y=NaN;
  4851. this.l1z=NaN;
  4852. this.l2x=NaN;
  4853. this.l2y=NaN;
  4854. this.l2z=NaN;
  4855. this.a1x=NaN;
  4856. this.a1y=NaN;
  4857. this.a1z=NaN;
  4858. this.a2x=NaN;
  4859. this.a2y=NaN;
  4860. this.a2z=NaN;
  4861. this.lowerLimit=NaN;
  4862. this.upperLimit=NaN;
  4863. this.limitVelocity=NaN;
  4864. this.limitState=0; // -1: at lower, 0: locked, 1: at upper, 2: free
  4865. this.enableMotor=false;
  4866. this.motorSpeed=NaN;
  4867. this.maxMotorForce=NaN;
  4868. this.maxMotorImpulse=NaN;
  4869. this.limitMotor=limitMotor;
  4870. this.b1=joint.body1;
  4871. this.b2=joint.body2;
  4872. this.p1=joint.anchorPoint1;
  4873. this.p2=joint.anchorPoint2;
  4874. this.r1=joint.relativeAnchorPoint1;
  4875. this.r2=joint.relativeAnchorPoint2;
  4876. this.l1=this.b1.linearVelocity;
  4877. this.l2=this.b2.linearVelocity;
  4878. this.a1=this.b1.angularVelocity;
  4879. this.a2=this.b2.angularVelocity;
  4880. this.i1=this.b1.inverseInertia;
  4881. this.i2=this.b2.inverseInertia;
  4882. this.limitImpulse=0;
  4883. this.motorImpulse=0;
  4884. }
  4885. OIMO.TranslationalConstraint.prototype = {
  4886. constructor: OIMO.TranslationalConstraint,
  4887. preSolve:function(timeStep,invTimeStep){
  4888. this.ax=this.limitMotor.axis.x;
  4889. this.ay=this.limitMotor.axis.y;
  4890. this.az=this.limitMotor.axis.z;
  4891. this.lowerLimit=this.limitMotor.lowerLimit;
  4892. this.upperLimit=this.limitMotor.upperLimit;
  4893. this.motorSpeed=this.limitMotor.motorSpeed;
  4894. this.maxMotorForce=this.limitMotor.maxMotorForce;
  4895. this.enableMotor=this.maxMotorForce>0;
  4896. this.m1=this.b1.inverseMass;
  4897. this.m2=this.b2.inverseMass;
  4898. var ti1 = this.i1.elements;
  4899. var ti2 = this.i2.elements;
  4900. this.i1e00=ti1[0];
  4901. this.i1e01=ti1[1];
  4902. this.i1e02=ti1[2];
  4903. this.i1e10=ti1[3];
  4904. this.i1e11=ti1[4];
  4905. this.i1e12=ti1[5];
  4906. this.i1e20=ti1[6];
  4907. this.i1e21=ti1[7];
  4908. this.i1e22=ti1[8];
  4909. this.i2e00=ti2[0];
  4910. this.i2e01=ti2[1];
  4911. this.i2e02=ti2[2];
  4912. this.i2e10=ti2[3];
  4913. this.i2e11=ti2[4];
  4914. this.i2e12=ti2[5];
  4915. this.i2e20=ti2[6];
  4916. this.i2e21=ti2[7];
  4917. this.i2e22=ti2[8];
  4918. var dx=this.p2.x-this.p1.x;
  4919. var dy=this.p2.y-this.p1.y;
  4920. var dz=this.p2.z-this.p1.z;
  4921. var d=dx*this.ax+dy*this.ay+dz*this.az;
  4922. var frequency=this.limitMotor.frequency;
  4923. var enableSpring=frequency>0;
  4924. var enableLimit=this.lowerLimit<=this.upperLimit;
  4925. if(enableSpring&&d>20||d<-20){
  4926. enableSpring=false;
  4927. }
  4928. if(enableLimit){
  4929. if(this.lowerLimit==this.upperLimit){
  4930. if(this.limitState!=0){
  4931. this.limitState=0;
  4932. this.limitImpulse=0;
  4933. }
  4934. this.limitVelocity=this.lowerLimit-d;
  4935. if(!enableSpring)d=this.lowerLimit;
  4936. }else if(d<this.lowerLimit){
  4937. if(this.limitState!=-1){
  4938. this.limitState=-1;
  4939. this.limitImpulse=0;
  4940. }
  4941. this.limitVelocity=this.lowerLimit-d;
  4942. if(!enableSpring)d=this.lowerLimit;
  4943. }else if(d>this.upperLimit){
  4944. if(this.limitState!=1){
  4945. this.limitState=1;
  4946. this.limitImpulse=0;
  4947. }
  4948. this.limitVelocity=this.upperLimit-d;
  4949. if(!enableSpring)d=this.upperLimit;
  4950. }else{
  4951. this.limitState=2;
  4952. this.limitImpulse=0;
  4953. this.limitVelocity=0;
  4954. }
  4955. if(!enableSpring){
  4956. if(this.limitVelocity>0.005)this.limitVelocity-=0.005;
  4957. else if(this.limitVelocity<-0.005)this.limitVelocity+=0.005;
  4958. else this.limitVelocity=0;
  4959. }
  4960. }else{
  4961. this.limitState=2;
  4962. this.limitImpulse=0;
  4963. }
  4964. if(this.enableMotor&&(this.limitState!=0||enableSpring)){
  4965. this.maxMotorImpulse=this.maxMotorForce*timeStep;
  4966. }else{
  4967. this.motorImpulse=0;
  4968. this.maxMotorImpulse=0;
  4969. }
  4970. var rdx=d*this.ax;
  4971. var rdy=d*this.ay;
  4972. var rdz=d*this.az;
  4973. var w1=this.m1/(this.m1+this.m2);
  4974. var w2=1-w1;
  4975. this.r1x=this.r1.x+rdx*w1;
  4976. this.r1y=this.r1.y+rdy*w1;
  4977. this.r1z=this.r1.z+rdz*w1;
  4978. this.r2x=this.r2.x-rdx*w2;
  4979. this.r2y=this.r2.y-rdy*w2;
  4980. this.r2z=this.r2.z-rdz*w2;
  4981. this.t1x=this.r1y*this.az-this.r1z*this.ay;
  4982. this.t1y=this.r1z*this.ax-this.r1x*this.az;
  4983. this.t1z=this.r1x*this.ay-this.r1y*this.ax;
  4984. this.t2x=this.r2y*this.az-this.r2z*this.ay;
  4985. this.t2y=this.r2z*this.ax-this.r2x*this.az;
  4986. this.t2z=this.r2x*this.ay-this.r2y*this.ax;
  4987. this.l1x=this.ax*this.m1;
  4988. this.l1y=this.ay*this.m1;
  4989. this.l1z=this.az*this.m1;
  4990. this.l2x=this.ax*this.m2;
  4991. this.l2y=this.ay*this.m2;
  4992. this.l2z=this.az*this.m2;
  4993. this.a1x=this.t1x*this.i1e00+this.t1y*this.i1e01+this.t1z*this.i1e02;
  4994. this.a1y=this.t1x*this.i1e10+this.t1y*this.i1e11+this.t1z*this.i1e12;
  4995. this.a1z=this.t1x*this.i1e20+this.t1y*this.i1e21+this.t1z*this.i1e22;
  4996. this.a2x=this.t2x*this.i2e00+this.t2y*this.i2e01+this.t2z*this.i2e02;
  4997. this.a2y=this.t2x*this.i2e10+this.t2y*this.i2e11+this.t2z*this.i2e12;
  4998. this.a2z=this.t2x*this.i2e20+this.t2y*this.i2e21+this.t2z*this.i2e22;
  4999. this.motorDenom=
  5000. this.m1+this.m2+
  5001. this.ax*(this.a1y*this.r1z-this.a1z*this.r1y+this.a2y*this.r2z-this.a2z*this.r2y)+
  5002. this.ay*(this.a1z*this.r1x-this.a1x*this.r1z+this.a2z*this.r2x-this.a2x*this.r2z)+
  5003. this.az*(this.a1x*this.r1y-this.a1y*this.r1x+this.a2x*this.r2y-this.a2y*this.r2x);
  5004. this.invMotorDenom=1/this.motorDenom;
  5005. if(enableSpring&&this.limitState!=2){
  5006. var omega=6.2831853*frequency;
  5007. var k=omega*omega*timeStep;
  5008. var dmp=invTimeStep/(k+2*this.limitMotor.dampingRatio*omega);
  5009. this.cfm=this.motorDenom*dmp;
  5010. this.limitVelocity*=k*dmp;
  5011. }else{
  5012. this.cfm=0;
  5013. this.limitVelocity*=invTimeStep*0.05;
  5014. }
  5015. this.invDenom=1/(this.motorDenom+this.cfm);
  5016. var totalImpulse=this.limitImpulse+this.motorImpulse;
  5017. this.l1.x+=totalImpulse*this.l1x;
  5018. this.l1.y+=totalImpulse*this.l1y;
  5019. this.l1.z+=totalImpulse*this.l1z;
  5020. this.a1.x+=totalImpulse*this.a1x;
  5021. this.a1.y+=totalImpulse*this.a1y;
  5022. this.a1.z+=totalImpulse*this.a1z;
  5023. this.l2.x-=totalImpulse*this.l2x;
  5024. this.l2.y-=totalImpulse*this.l2y;
  5025. this.l2.z-=totalImpulse*this.l2z;
  5026. this.a2.x-=totalImpulse*this.a2x;
  5027. this.a2.y-=totalImpulse*this.a2y;
  5028. this.a2.z-=totalImpulse*this.a2z;
  5029. },
  5030. solve:function(){
  5031. var rvn=
  5032. this.ax*(this.l2.x-this.l1.x)+this.ay*(this.l2.y-this.l1.y)+this.az*(this.l2.z-this.l1.z)+
  5033. 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;
  5034. // motor part
  5035. var newMotorImpulse;
  5036. if(this.enableMotor){
  5037. newMotorImpulse=(rvn-this.motorSpeed)*this.invMotorDenom;
  5038. var oldMotorImpulse=this.motorImpulse;
  5039. this.motorImpulse+=newMotorImpulse;
  5040. if(this.motorImpulse>this.maxMotorImpulse)this.motorImpulse=this.maxMotorImpulse;
  5041. else if(this.motorImpulse<-this.maxMotorImpulse)this.motorImpulse=-this.maxMotorImpulse;
  5042. newMotorImpulse=this.motorImpulse-oldMotorImpulse;
  5043. rvn-=newMotorImpulse*this.motorDenom;
  5044. }else newMotorImpulse=0;
  5045. // limit part
  5046. var newLimitImpulse;
  5047. if(this.limitState!=2){
  5048. newLimitImpulse=(rvn-this.limitVelocity-this.limitImpulse*this.cfm)*this.invDenom;
  5049. var oldLimitImpulse=this.limitImpulse;
  5050. this.limitImpulse+=newLimitImpulse;
  5051. if(this.limitImpulse*this.limitState<0)this.limitImpulse=0;
  5052. newLimitImpulse=this.limitImpulse-oldLimitImpulse;
  5053. }else newLimitImpulse=0;
  5054. var totalImpulse=newLimitImpulse+newMotorImpulse;
  5055. this.l1.x+=totalImpulse*this.l1x;
  5056. this.l1.y+=totalImpulse*this.l1y;
  5057. this.l1.z+=totalImpulse*this.l1z;
  5058. this.a1.x+=totalImpulse*this.a1x;
  5059. this.a1.y+=totalImpulse*this.a1y;
  5060. this.a1.z+=totalImpulse*this.a1z;
  5061. this.l2.x-=totalImpulse*this.l2x;
  5062. this.l2.y-=totalImpulse*this.l2y;
  5063. this.l2.z-=totalImpulse*this.l2z;
  5064. this.a2.x-=totalImpulse*this.a2x;
  5065. this.a2.y-=totalImpulse*this.a2y;
  5066. this.a2.z-=totalImpulse*this.a2z;
  5067. }
  5068. }
  5069. /**
  5070. * A contact is a pair of shapes whose axis-aligned bounding boxes are overlapping.
  5071. * @author saharan
  5072. */
  5073. OIMO.Contact = function(){
  5074. // The first shape.
  5075. this.shape1=null;
  5076. // The second shape.
  5077. this.shape2=null;
  5078. // The first rigid body.
  5079. this.body1=null;
  5080. // The second rigid body.
  5081. this.body2=null;
  5082. // The previous contact in the world.
  5083. this.prev=null;
  5084. // The next contact in the world.
  5085. this.next=null;
  5086. // Internal
  5087. this.persisting=false;
  5088. // Whether both the rigid bodies are sleeping or not.
  5089. this.sleeping=false;
  5090. // The collision detector between two shapes.
  5091. this.detector=null;
  5092. // The contact constraint of the contact.
  5093. this.constraint=null;
  5094. // Whether the shapes are touching or not.
  5095. this.touching=false;
  5096. this.b1Link=new OIMO.ContactLink(this);
  5097. this.b2Link=new OIMO.ContactLink(this);
  5098. this.s1Link=new OIMO.ContactLink(this);
  5099. this.s2Link=new OIMO.ContactLink(this);
  5100. // The contact manifold of the contact.
  5101. this.manifold=new OIMO.ContactManifold();
  5102. this.buffer=[];// vector 4
  5103. this.buffer.length = 4;
  5104. this.buffer[0]=new OIMO.ImpulseDataBuffer();
  5105. this.buffer[1]=new OIMO.ImpulseDataBuffer();
  5106. this.buffer[2]=new OIMO.ImpulseDataBuffer();
  5107. this.buffer[3]=new OIMO.ImpulseDataBuffer();
  5108. this.points=this.manifold.points;
  5109. this.constraint=new OIMO.ContactConstraint(this.manifold);
  5110. }
  5111. OIMO.Contact.prototype = {
  5112. constructor: OIMO.Contact,
  5113. mixRestitution:function(restitution1,restitution2){
  5114. return Math.sqrt(restitution1*restitution2);
  5115. },
  5116. mixFriction:function(friction1,friction2){
  5117. return Math.sqrt(friction1*friction2);
  5118. },
  5119. /**
  5120. * Update the contact manifold.
  5121. */
  5122. updateManifold:function(){
  5123. this.constraint.restitution=this.mixRestitution(this.shape1.restitution,this.shape2.restitution);
  5124. this.constraint.friction=this.mixFriction(this.shape1.friction,this.shape2.friction);
  5125. var numBuffers=this.manifold.numPoints;
  5126. var i = numBuffers;
  5127. while(i--){
  5128. //for(var i=0;i<numBuffers;i++){
  5129. var b=this.buffer[i];
  5130. var p=this.points[i];
  5131. b.lp1X=p.localPoint1.x;
  5132. b.lp1Y=p.localPoint1.y;
  5133. b.lp1Z=p.localPoint1.z;
  5134. b.lp2X=p.localPoint2.x;
  5135. b.lp2Y=p.localPoint2.y;
  5136. b.lp2Z=p.localPoint2.z;
  5137. b.impulse=p.normalImpulse;
  5138. }
  5139. this.manifold.numPoints=0;
  5140. this.detector.detectCollision(this.shape1,this.shape2,this.manifold);
  5141. var num=this.manifold.numPoints;
  5142. if(num==0){
  5143. this.touching=false;
  5144. return;
  5145. }
  5146. this.touching=true;
  5147. i = num;
  5148. while(i--){
  5149. //for(i=0; i<num; i++){
  5150. p=this.points[i];
  5151. var lp1x=p.localPoint1.x;
  5152. var lp1y=p.localPoint1.y;
  5153. var lp1z=p.localPoint1.z;
  5154. var lp2x=p.localPoint2.x;
  5155. var lp2y=p.localPoint2.y;
  5156. var lp2z=p.localPoint2.z;
  5157. var index=-1;
  5158. var minDistance=0.0004;
  5159. var j = numBuffers;
  5160. while(j--){
  5161. //for(var j=0;j<numBuffers;j++){
  5162. b=this.buffer[j];
  5163. var dx=b.lp1X-lp1x;
  5164. var dy=b.lp1Y-lp1y;
  5165. var dz=b.lp1Z-lp1z;
  5166. var distance1=dx*dx+dy*dy+dz*dz;
  5167. dx=b.lp2X-lp2x;
  5168. dy=b.lp2Y-lp2y;
  5169. dz=b.lp2Z-lp2z;
  5170. var distance2=dx*dx+dy*dy+dz*dz;
  5171. if(distance1<distance2){
  5172. if(distance1<minDistance){
  5173. minDistance=distance1;
  5174. index=j;
  5175. }
  5176. }else{
  5177. if(distance2<minDistance){
  5178. minDistance=distance2;
  5179. index=j;
  5180. }
  5181. }
  5182. }
  5183. if(index!=-1){
  5184. var tmp=this.buffer[index];
  5185. this.buffer[index]=this.buffer[--numBuffers];
  5186. this.buffer[numBuffers]=tmp;
  5187. p.normalImpulse=tmp.impulse;
  5188. p.warmStarted=true;
  5189. }else{
  5190. p.normalImpulse=0;
  5191. p.warmStarted=false;
  5192. }
  5193. }
  5194. },
  5195. /**
  5196. * Attach the contact to the shapes.
  5197. * @param shape1
  5198. * @param shape2
  5199. */
  5200. attach:function(shape1,shape2){
  5201. this.shape1=shape1;
  5202. this.shape2=shape2;
  5203. this.body1=shape1.parent;
  5204. this.body2=shape2.parent;
  5205. this.manifold.body1=this.body1;
  5206. this.manifold.body2=this.body2;
  5207. this.constraint.body1=this.body1;
  5208. this.constraint.body2=this.body2;
  5209. this.constraint.attach();
  5210. this.s1Link.shape=shape2;
  5211. this.s1Link.body=this.body2;
  5212. this.s2Link.shape=shape1;
  5213. this.s2Link.body=this.body1;
  5214. if(shape1.contactLink!=null)(this.s1Link.next=shape1.contactLink).prev=this.s1Link;
  5215. else this.s1Link.next=null;
  5216. shape1.contactLink=this.s1Link;
  5217. shape1.numContacts++;
  5218. if(shape2.contactLink!=null)(this.s2Link.next=shape2.contactLink).prev=this.s2Link;
  5219. else this.s2Link.next=null;
  5220. shape2.contactLink=this.s2Link;
  5221. shape2.numContacts++;
  5222. this.b1Link.shape=shape2;
  5223. this.b1Link.body=this.body2;
  5224. this.b2Link.shape=shape1;
  5225. this.b2Link.body=this.body1;
  5226. if(this.body1.contactLink!=null)(this.b1Link.next=this.body1.contactLink).prev=this.b1Link;
  5227. else this.b1Link.next=null;
  5228. this.body1.contactLink=this.b1Link;
  5229. this.body1.numContacts++;
  5230. if(this.body2.contactLink!=null)(this.b2Link.next=this.body2.contactLink).prev=this.b2Link;
  5231. else this.b2Link.next=null;
  5232. this.body2.contactLink=this.b2Link;
  5233. this.body2.numContacts++;
  5234. this.prev=null;
  5235. this.next=null;
  5236. this.persisting=true;
  5237. this.sleeping=this.body1.sleeping&&this.body2.sleeping;
  5238. this.manifold.numPoints=0;
  5239. },
  5240. /**
  5241. * Detach the contact from the shapes.
  5242. */
  5243. detach:function(){
  5244. var prev=this.s1Link.prev;
  5245. var next=this.s1Link.next;
  5246. if(prev!==null)prev.next=next;
  5247. if(next!==null)next.prev=prev;
  5248. if(this.shape1.contactLink==this.s1Link)this.shape1.contactLink=next;
  5249. this.s1Link.prev=null;
  5250. this.s1Link.next=null;
  5251. this.s1Link.shape=null;
  5252. this.s1Link.body=null;
  5253. this.shape1.numContacts--;
  5254. prev=this.s2Link.prev;
  5255. next=this.s2Link.next;
  5256. if(prev!==null)prev.next=next;
  5257. if(next!==null)next.prev=prev;
  5258. if(this.shape2.contactLink==this.s2Link)this.shape2.contactLink=next;
  5259. this.s2Link.prev=null;
  5260. this.s2Link.next=null;
  5261. this.s2Link.shape=null;
  5262. this.s2Link.body=null;
  5263. this.shape2.numContacts--;
  5264. prev=this.b1Link.prev;
  5265. next=this.b1Link.next;
  5266. if(prev!==null)prev.next=next;
  5267. if(next!==null)next.prev=prev;
  5268. if(this.body1.contactLink==this.b1Link)this.body1.contactLink=next;
  5269. this.b1Link.prev=null;
  5270. this.b1Link.next=null;
  5271. this.b1Link.shape=null;
  5272. this.b1Link.body=null;
  5273. this.body1.numContacts--;
  5274. prev=this.b2Link.prev;
  5275. next=this.b2Link.next;
  5276. if(prev!==null)prev.next=next;
  5277. if(next!==null)next.prev=prev;
  5278. if(this.body2.contactLink==this.b2Link)this.body2.contactLink=next;
  5279. this.b2Link.prev=null;
  5280. this.b2Link.next=null;
  5281. this.b2Link.shape=null;
  5282. this.b2Link.body=null;
  5283. this.body2.numContacts--;
  5284. this.manifold.body1=null;
  5285. this.manifold.body2=null;
  5286. this.constraint.body1=null;
  5287. this.constraint.body2=null;
  5288. this.constraint.detach();
  5289. this.shape1=null;
  5290. this.shape2=null;
  5291. this.body1=null;
  5292. this.body2=null;
  5293. }
  5294. }
  5295. /**
  5296. * ...
  5297. * @author saharan
  5298. */
  5299. OIMO.ContactConstraint = function(manifold){
  5300. OIMO.Constraint.call( this);
  5301. // The contact manifold of the constraint.
  5302. this.manifold=manifold;
  5303. // The coefficient of restitution of the constraint.
  5304. this.restitution=NaN;
  5305. // The coefficient of friction of the constraint.
  5306. this.friction=NaN;
  5307. this.p1=null;
  5308. this.p2=null;
  5309. this.lv1=null;
  5310. this.lv2=null;
  5311. this.av1=null;
  5312. this.av2=null;
  5313. this.i1=null;
  5314. this.i2=null;
  5315. this.i1e00=NaN;
  5316. this.i1e01=NaN;
  5317. this.i1e02=NaN;
  5318. this.i1e10=NaN;
  5319. this.i1e11=NaN;
  5320. this.i1e12=NaN;
  5321. this.i1e20=NaN;
  5322. this.i1e21=NaN;
  5323. this.i1e22=NaN;
  5324. this.i2e00=NaN;
  5325. this.i2e01=NaN;
  5326. this.i2e02=NaN;
  5327. this.i2e10=NaN;
  5328. this.i2e11=NaN;
  5329. this.i2e12=NaN;
  5330. this.i2e20=NaN;
  5331. this.i2e21=NaN;
  5332. this.i2e22=NaN;
  5333. this.m1=NaN;
  5334. this.m2=NaN;
  5335. this.num=0;
  5336. this.ps=manifold.points;
  5337. this.cs=new OIMO.ContactPointDataBuffer();
  5338. this.cs.next=new OIMO.ContactPointDataBuffer();
  5339. this.cs.next.next=new OIMO.ContactPointDataBuffer();
  5340. this.cs.next.next.next=new OIMO.ContactPointDataBuffer();
  5341. }
  5342. OIMO.ContactConstraint.prototype = Object.create( OIMO.Constraint.prototype );
  5343. /**
  5344. * Attach the constraint to the bodies.
  5345. */
  5346. OIMO.ContactConstraint.prototype.attach = function(){
  5347. this.p1=this.body1.position;
  5348. this.p2=this.body2.position;
  5349. this.lv1=this.body1.linearVelocity;
  5350. this.av1=this.body1.angularVelocity;
  5351. this.lv2=this.body2.linearVelocity;
  5352. this.av2=this.body2.angularVelocity;
  5353. this.i1=this.body1.inverseInertia;
  5354. this.i2=this.body2.inverseInertia;
  5355. }
  5356. /**
  5357. * Detach the constraint from the bodies.
  5358. */
  5359. OIMO.ContactConstraint.prototype.detach = function(){
  5360. this.p1=null;
  5361. this.p2=null;
  5362. this.lv1=null;
  5363. this.lv2=null;
  5364. this.av1=null;
  5365. this.av2=null;
  5366. this.i1=null;
  5367. this.i2=null;
  5368. }
  5369. OIMO.ContactConstraint.prototype.preSolve = function(timeStep,invTimeStep){
  5370. this.m1=this.body1.inverseMass;
  5371. this.m2=this.body2.inverseMass;
  5372. var ti1 = this.i1.elements;
  5373. var ti2 = this.i2.elements;
  5374. this.i1e00=ti1[0];
  5375. this.i1e01=ti1[1];
  5376. this.i1e02=ti1[2];
  5377. this.i1e10=ti1[3];
  5378. this.i1e11=ti1[4];
  5379. this.i1e12=ti1[5];
  5380. this.i1e20=ti1[6];
  5381. this.i1e21=ti1[7];
  5382. this.i1e22=ti1[8];
  5383. this.i2e00=ti2[0];
  5384. this.i2e01=ti2[1];
  5385. this.i2e02=ti2[2];
  5386. this.i2e10=ti2[3];
  5387. this.i2e11=ti2[4];
  5388. this.i2e12=ti2[5];
  5389. this.i2e20=ti2[6];
  5390. this.i2e21=ti2[7];
  5391. this.i2e22=ti2[8];
  5392. var p1x=this.p1.x;
  5393. var p1y=this.p1.y;
  5394. var p1z=this.p1.z;
  5395. var p2x=this.p2.x;
  5396. var p2y=this.p2.y;
  5397. var p2z=this.p2.z;
  5398. var m1m2=this.m1+this.m2;
  5399. this.num=this.manifold.numPoints;
  5400. var c=this.cs;
  5401. for(var i=0;i<this.num;i++){
  5402. var p=this.ps[i];
  5403. var tmp1X;
  5404. var tmp1Y;
  5405. var tmp1Z;
  5406. var tmp2X;
  5407. var tmp2Y;
  5408. var tmp2Z;
  5409. tmp1X=p.position.x;
  5410. tmp1Y=p.position.y;
  5411. tmp1Z=p.position.z;
  5412. var rp1X=tmp1X-p1x;
  5413. var rp1Y=tmp1Y-p1y;
  5414. var rp1Z=tmp1Z-p1z;
  5415. var rp2X=tmp1X-p2x;
  5416. var rp2Y=tmp1Y-p2y;
  5417. var rp2Z=tmp1Z-p2z;
  5418. c.rp1X=rp1X;
  5419. c.rp1Y=rp1Y;
  5420. c.rp1Z=rp1Z;
  5421. c.rp2X=rp2X;
  5422. c.rp2Y=rp2Y;
  5423. c.rp2Z=rp2Z;
  5424. c.norImp=p.normalImpulse;
  5425. c.tanImp=p.tangentImpulse;
  5426. c.binImp=p.binormalImpulse;
  5427. var norX=p.normal.x;
  5428. var norY=p.normal.y;
  5429. var norZ=p.normal.z;
  5430. var rvX=(this.lv2.x+this.av2.y*rp2Z-this.av2.z*rp2Y)-(this.lv1.x+this.av1.y*rp1Z-this.av1.z*rp1Y);
  5431. var rvY=(this.lv2.y+this.av2.z*rp2X-this.av2.x*rp2Z)-(this.lv1.y+this.av1.z*rp1X-this.av1.x*rp1Z);
  5432. var rvZ=(this.lv2.z+this.av2.x*rp2Y-this.av2.y*rp2X)-(this.lv1.z+this.av1.x*rp1Y-this.av1.y*rp1X);
  5433. var rvn=norX*rvX+norY*rvY+norZ*rvZ;
  5434. var tanX=rvX-rvn*norX;
  5435. var tanY=rvY-rvn*norY;
  5436. var tanZ=rvZ-rvn*norZ;
  5437. var len=tanX*tanX+tanY*tanY+tanZ*tanZ;
  5438. if(len>0.04){
  5439. len=1/Math.sqrt(len);
  5440. }else{
  5441. tanX=norY*norX-norZ*norZ;
  5442. tanY=-norZ*norY-norX*norX;
  5443. tanZ=norX*norZ+norY*norY;
  5444. len=1/Math.sqrt(tanX*tanX+tanY*tanY+tanZ*tanZ);
  5445. }
  5446. tanX*=len;
  5447. tanY*=len;
  5448. tanZ*=len;
  5449. var binX=norY*tanZ-norZ*tanY;
  5450. var binY=norZ*tanX-norX*tanZ;
  5451. var binZ=norX*tanY-norY*tanX;
  5452. c.norX=norX;
  5453. c.norY=norY;
  5454. c.norZ=norZ;
  5455. c.tanX=tanX;
  5456. c.tanY=tanY;
  5457. c.tanZ=tanZ;
  5458. c.binX=binX;
  5459. c.binY=binY;
  5460. c.binZ=binZ;
  5461. c.norU1X=norX*this.m1;
  5462. c.norU1Y=norY*this.m1;
  5463. c.norU1Z=norZ*this.m1;
  5464. c.norU2X=norX*this.m2;
  5465. c.norU2Y=norY*this.m2;
  5466. c.norU2Z=norZ*this.m2;
  5467. c.tanU1X=tanX*this.m1;
  5468. c.tanU1Y=tanY*this.m1;
  5469. c.tanU1Z=tanZ*this.m1;
  5470. c.tanU2X=tanX*this.m2;
  5471. c.tanU2Y=tanY*this.m2;
  5472. c.tanU2Z=tanZ*this.m2;
  5473. c.binU1X=binX*this.m1;
  5474. c.binU1Y=binY*this.m1;
  5475. c.binU1Z=binZ*this.m1;
  5476. c.binU2X=binX*this.m2;
  5477. c.binU2Y=binY*this.m2;
  5478. c.binU2Z=binZ*this.m2;
  5479. var norT1X=rp1Y*norZ-rp1Z*norY;
  5480. var norT1Y=rp1Z*norX-rp1X*norZ;
  5481. var norT1Z=rp1X*norY-rp1Y*norX;
  5482. var norT2X=rp2Y*norZ-rp2Z*norY;
  5483. var norT2Y=rp2Z*norX-rp2X*norZ;
  5484. var norT2Z=rp2X*norY-rp2Y*norX;
  5485. var tanT1X=rp1Y*tanZ-rp1Z*tanY;
  5486. var tanT1Y=rp1Z*tanX-rp1X*tanZ;
  5487. var tanT1Z=rp1X*tanY-rp1Y*tanX;
  5488. var tanT2X=rp2Y*tanZ-rp2Z*tanY;
  5489. var tanT2Y=rp2Z*tanX-rp2X*tanZ;
  5490. var tanT2Z=rp2X*tanY-rp2Y*tanX;
  5491. var binT1X=rp1Y*binZ-rp1Z*binY;
  5492. var binT1Y=rp1Z*binX-rp1X*binZ;
  5493. var binT1Z=rp1X*binY-rp1Y*binX;
  5494. var binT2X=rp2Y*binZ-rp2Z*binY;
  5495. var binT2Y=rp2Z*binX-rp2X*binZ;
  5496. var binT2Z=rp2X*binY-rp2Y*binX;
  5497. var norTU1X=norT1X*this.i1e00+norT1Y*this.i1e01+norT1Z*this.i1e02;
  5498. var norTU1Y=norT1X*this.i1e10+norT1Y*this.i1e11+norT1Z*this.i1e12;
  5499. var norTU1Z=norT1X*this.i1e20+norT1Y*this.i1e21+norT1Z*this.i1e22;
  5500. var norTU2X=norT2X*this.i2e00+norT2Y*this.i2e01+norT2Z*this.i2e02;
  5501. var norTU2Y=norT2X*this.i2e10+norT2Y*this.i2e11+norT2Z*this.i2e12;
  5502. var norTU2Z=norT2X*this.i2e20+norT2Y*this.i2e21+norT2Z*this.i2e22;
  5503. var tanTU1X=tanT1X*this.i1e00+tanT1Y*this.i1e01+tanT1Z*this.i1e02;
  5504. var tanTU1Y=tanT1X*this.i1e10+tanT1Y*this.i1e11+tanT1Z*this.i1e12;
  5505. var tanTU1Z=tanT1X*this.i1e20+tanT1Y*this.i1e21+tanT1Z*this.i1e22;
  5506. var tanTU2X=tanT2X*this.i2e00+tanT2Y*this.i2e01+tanT2Z*this.i2e02;
  5507. var tanTU2Y=tanT2X*this.i2e10+tanT2Y*this.i2e11+tanT2Z*this.i2e12;
  5508. var tanTU2Z=tanT2X*this.i2e20+tanT2Y*this.i2e21+tanT2Z*this.i2e22;
  5509. var binTU1X=binT1X*this.i1e00+binT1Y*this.i1e01+binT1Z*this.i1e02;
  5510. var binTU1Y=binT1X*this.i1e10+binT1Y*this.i1e11+binT1Z*this.i1e12;
  5511. var binTU1Z=binT1X*this.i1e20+binT1Y*this.i1e21+binT1Z*this.i1e22;
  5512. var binTU2X=binT2X*this.i2e00+binT2Y*this.i2e01+binT2Z*this.i2e02;
  5513. var binTU2Y=binT2X*this.i2e10+binT2Y*this.i2e11+binT2Z*this.i2e12;
  5514. var binTU2Z=binT2X*this.i2e20+binT2Y*this.i2e21+binT2Z*this.i2e22;
  5515. c.norT1X=norT1X;
  5516. c.norT1Y=norT1Y;
  5517. c.norT1Z=norT1Z;
  5518. c.tanT1X=tanT1X;
  5519. c.tanT1Y=tanT1Y;
  5520. c.tanT1Z=tanT1Z;
  5521. c.binT1X=binT1X;
  5522. c.binT1Y=binT1Y;
  5523. c.binT1Z=binT1Z;
  5524. c.norT2X=norT2X;
  5525. c.norT2Y=norT2Y;
  5526. c.norT2Z=norT2Z;
  5527. c.tanT2X=tanT2X;
  5528. c.tanT2Y=tanT2Y;
  5529. c.tanT2Z=tanT2Z;
  5530. c.binT2X=binT2X;
  5531. c.binT2Y=binT2Y;
  5532. c.binT2Z=binT2Z;
  5533. c.norTU1X=norTU1X;
  5534. c.norTU1Y=norTU1Y;
  5535. c.norTU1Z=norTU1Z;
  5536. c.tanTU1X=tanTU1X;
  5537. c.tanTU1Y=tanTU1Y;
  5538. c.tanTU1Z=tanTU1Z;
  5539. c.binTU1X=binTU1X;
  5540. c.binTU1Y=binTU1Y;
  5541. c.binTU1Z=binTU1Z;
  5542. c.norTU2X=norTU2X;
  5543. c.norTU2Y=norTU2Y;
  5544. c.norTU2Z=norTU2Z;
  5545. c.tanTU2X=tanTU2X;
  5546. c.tanTU2Y=tanTU2Y;
  5547. c.tanTU2Z=tanTU2Z;
  5548. c.binTU2X=binTU2X;
  5549. c.binTU2Y=binTU2Y;
  5550. c.binTU2Z=binTU2Z;
  5551. tmp1X=norT1X*this.i1e00+norT1Y*this.i1e01+norT1Z*this.i1e02;
  5552. tmp1Y=norT1X*this.i1e10+norT1Y*this.i1e11+norT1Z*this.i1e12;
  5553. tmp1Z=norT1X*this.i1e20+norT1Y*this.i1e21+norT1Z*this.i1e22;
  5554. tmp2X=tmp1Y*rp1Z-tmp1Z*rp1Y;
  5555. tmp2Y=tmp1Z*rp1X-tmp1X*rp1Z;
  5556. tmp2Z=tmp1X*rp1Y-tmp1Y*rp1X;
  5557. tmp1X=norT2X*this.i2e00+norT2Y*this.i2e01+norT2Z*this.i2e02;
  5558. tmp1Y=norT2X*this.i2e10+norT2Y*this.i2e11+norT2Z*this.i2e12;
  5559. tmp1Z=norT2X*this.i2e20+norT2Y*this.i2e21+norT2Z*this.i2e22;
  5560. tmp2X+=tmp1Y*rp2Z-tmp1Z*rp2Y;
  5561. tmp2Y+=tmp1Z*rp2X-tmp1X*rp2Z;
  5562. tmp2Z+=tmp1X*rp2Y-tmp1Y*rp2X;
  5563. var norDen=1/(m1m2+norX*tmp2X+norY*tmp2Y+norZ*tmp2Z);
  5564. tmp1X=tanT1X*this.i1e00+tanT1Y*this.i1e01+tanT1Z*this.i1e02;
  5565. tmp1Y=tanT1X*this.i1e10+tanT1Y*this.i1e11+tanT1Z*this.i1e12;
  5566. tmp1Z=tanT1X*this.i1e20+tanT1Y*this.i1e21+tanT1Z*this.i1e22;
  5567. tmp2X=tmp1Y*rp1Z-tmp1Z*rp1Y;
  5568. tmp2Y=tmp1Z*rp1X-tmp1X*rp1Z;
  5569. tmp2Z=tmp1X*rp1Y-tmp1Y*rp1X;
  5570. tmp1X=tanT2X*this.i2e00+tanT2Y*this.i2e01+tanT2Z*this.i2e02;
  5571. tmp1Y=tanT2X*this.i2e10+tanT2Y*this.i2e11+tanT2Z*this.i2e12;
  5572. tmp1Z=tanT2X*this.i2e20+tanT2Y*this.i2e21+tanT2Z*this.i2e22;
  5573. tmp2X+=tmp1Y*rp2Z-tmp1Z*rp2Y;
  5574. tmp2Y+=tmp1Z*rp2X-tmp1X*rp2Z;
  5575. tmp2Z+=tmp1X*rp2Y-tmp1Y*rp2X;
  5576. var tanDen=1/(m1m2+tanX*tmp2X+tanY*tmp2Y+tanZ*tmp2Z);
  5577. tmp1X=binT1X*this.i1e00+binT1Y*this.i1e01+binT1Z*this.i1e02;
  5578. tmp1Y=binT1X*this.i1e10+binT1Y*this.i1e11+binT1Z*this.i1e12;
  5579. tmp1Z=binT1X*this.i1e20+binT1Y*this.i1e21+binT1Z*this.i1e22;
  5580. tmp2X=tmp1Y*rp1Z-tmp1Z*rp1Y;
  5581. tmp2Y=tmp1Z*rp1X-tmp1X*rp1Z;
  5582. tmp2Z=tmp1X*rp1Y-tmp1Y*rp1X;
  5583. tmp1X=binT2X*this.i2e00+binT2Y*this.i2e01+binT2Z*this.i2e02;
  5584. tmp1Y=binT2X*this.i2e10+binT2Y*this.i2e11+binT2Z*this.i2e12;
  5585. tmp1Z=binT2X*this.i2e20+binT2Y*this.i2e21+binT2Z*this.i2e22;
  5586. tmp2X+=tmp1Y*rp2Z-tmp1Z*rp2Y;
  5587. tmp2Y+=tmp1Z*rp2X-tmp1X*rp2Z;
  5588. tmp2Z+=tmp1X*rp2Y-tmp1Y*rp2X;
  5589. var binDen=1/(m1m2+binX*tmp2X+binY*tmp2Y+binZ*tmp2Z);
  5590. c.norDen=norDen;
  5591. c.tanDen=tanDen;
  5592. c.binDen=binDen;
  5593. if(p.warmStarted){
  5594. var norImp=p.normalImpulse;
  5595. this.lv1.x+=c.norU1X*norImp;
  5596. this.lv1.y+=c.norU1Y*norImp;
  5597. this.lv1.z+=c.norU1Z*norImp;
  5598. this.av1.x+=norTU1X*norImp;
  5599. this.av1.y+=norTU1Y*norImp;
  5600. this.av1.z+=norTU1Z*norImp;
  5601. this.lv2.x-=c.norU2X*norImp;
  5602. this.lv2.y-=c.norU2Y*norImp;
  5603. this.lv2.z-=c.norU2Z*norImp;
  5604. this.av2.x-=norTU2X*norImp;
  5605. this.av2.y-=norTU2Y*norImp;
  5606. this.av2.z-=norTU2Z*norImp;
  5607. c.norImp=norImp;
  5608. c.tanImp=0;
  5609. c.binImp=0;
  5610. rvn=0; // disable bouncing
  5611. }else{
  5612. c.norImp=0;
  5613. c.tanImp=0;
  5614. c.binImp=0;
  5615. }
  5616. if(rvn>-1){
  5617. rvn=0; // disable bouncing
  5618. }
  5619. var norTar=this.restitution*-rvn;
  5620. var sepV=-(p.penetration+0.005)*invTimeStep*0.05; // allow 0.5cm error
  5621. if(norTar<sepV)norTar=sepV;
  5622. c.norTar=norTar;
  5623. c.last=i==this.num-1;
  5624. c=c.next;
  5625. }
  5626. }
  5627. OIMO.ContactConstraint.prototype.solve = function(){
  5628. var lv1x=this.lv1.x;
  5629. var lv1y=this.lv1.y;
  5630. var lv1z=this.lv1.z;
  5631. var lv2x=this.lv2.x;
  5632. var lv2y=this.lv2.y;
  5633. var lv2z=this.lv2.z;
  5634. var av1x=this.av1.x;
  5635. var av1y=this.av1.y;
  5636. var av1z=this.av1.z;
  5637. var av2x=this.av2.x;
  5638. var av2y=this.av2.y;
  5639. var av2z=this.av2.z;
  5640. var c=this.cs;
  5641. while(true){
  5642. var oldImp1;
  5643. var newImp1;
  5644. var oldImp2;
  5645. var newImp2;
  5646. var rvn;
  5647. var norImp=c.norImp;
  5648. var tanImp=c.tanImp;
  5649. var binImp=c.binImp;
  5650. var max=-norImp*this.friction;
  5651. var rvX=lv2x-lv1x;
  5652. var rvY=lv2y-lv1y;
  5653. var rvZ=lv2z-lv1z;
  5654. rvn=
  5655. rvX*c.tanX+rvY*c.tanY+rvZ*c.tanZ+
  5656. av2x*c.tanT2X+av2y*c.tanT2Y+av2z*c.tanT2Z-
  5657. av1x*c.tanT1X-av1y*c.tanT1Y-av1z*c.tanT1Z
  5658. ;
  5659. oldImp1=tanImp;
  5660. newImp1=rvn*c.tanDen;
  5661. tanImp+=newImp1;
  5662. rvn=
  5663. rvX*c.binX+rvY*c.binY+rvZ*c.binZ+
  5664. av2x*c.binT2X+av2y*c.binT2Y+av2z*c.binT2Z-
  5665. av1x*c.binT1X-av1y*c.binT1Y-av1z*c.binT1Z
  5666. ;
  5667. oldImp2=binImp;
  5668. newImp2=rvn*c.binDen;
  5669. binImp+=newImp2;
  5670. // cone friction clamp
  5671. var len=tanImp*tanImp+binImp*binImp;
  5672. if(len>max*max){
  5673. len=max/Math.sqrt(len);
  5674. tanImp*=len;
  5675. binImp*=len;
  5676. }
  5677. newImp1=tanImp-oldImp1;
  5678. newImp2=binImp-oldImp2;
  5679. lv1x+=c.tanU1X*newImp1+c.binU1X*newImp2;
  5680. lv1y+=c.tanU1Y*newImp1+c.binU1Y*newImp2;
  5681. lv1z+=c.tanU1Z*newImp1+c.binU1Z*newImp2;
  5682. av1x+=c.tanTU1X*newImp1+c.binTU1X*newImp2;
  5683. av1y+=c.tanTU1Y*newImp1+c.binTU1Y*newImp2;
  5684. av1z+=c.tanTU1Z*newImp1+c.binTU1Z*newImp2;
  5685. lv2x-=c.tanU2X*newImp1+c.binU2X*newImp2;
  5686. lv2y-=c.tanU2Y*newImp1+c.binU2Y*newImp2;
  5687. lv2z-=c.tanU2Z*newImp1+c.binU2Z*newImp2;
  5688. av2x-=c.tanTU2X*newImp1+c.binTU2X*newImp2;
  5689. av2y-=c.tanTU2Y*newImp1+c.binTU2Y*newImp2;
  5690. av2z-=c.tanTU2Z*newImp1+c.binTU2Z*newImp2;
  5691. // restitution part
  5692. rvn=
  5693. (lv2x-lv1x)*c.norX+(lv2y-lv1y)*c.norY+(lv2z-lv1z)*c.norZ+
  5694. av2x*c.norT2X+av2y*c.norT2Y+av2z*c.norT2Z-
  5695. av1x*c.norT1X-av1y*c.norT1Y-av1z*c.norT1Z;
  5696. oldImp1=norImp;
  5697. newImp1=(rvn-c.norTar)*c.norDen;
  5698. norImp+=newImp1;
  5699. if(norImp>0)norImp=0;
  5700. newImp1=norImp-oldImp1;
  5701. lv1x+=c.norU1X*newImp1;
  5702. lv1y+=c.norU1Y*newImp1;
  5703. lv1z+=c.norU1Z*newImp1;
  5704. av1x+=c.norTU1X*newImp1;
  5705. av1y+=c.norTU1Y*newImp1;
  5706. av1z+=c.norTU1Z*newImp1;
  5707. lv2x-=c.norU2X*newImp1;
  5708. lv2y-=c.norU2Y*newImp1;
  5709. lv2z-=c.norU2Z*newImp1;
  5710. av2x-=c.norTU2X*newImp1;
  5711. av2y-=c.norTU2Y*newImp1;
  5712. av2z-=c.norTU2Z*newImp1;
  5713. c.norImp=norImp;
  5714. c.tanImp=tanImp;
  5715. c.binImp=binImp;
  5716. if(c.last)break;
  5717. c=c.next;
  5718. }
  5719. this.lv1.x=lv1x;
  5720. this.lv1.y=lv1y;
  5721. this.lv1.z=lv1z;
  5722. this.lv2.x=lv2x;
  5723. this.lv2.y=lv2y;
  5724. this.lv2.z=lv2z;
  5725. this.av1.x=av1x;
  5726. this.av1.y=av1y;
  5727. this.av1.z=av1z;
  5728. this.av2.x=av2x;
  5729. this.av2.y=av2y;
  5730. this.av2.z=av2z;
  5731. }
  5732. OIMO.ContactConstraint.prototype.postSolve = function(){
  5733. var c=this.cs;
  5734. var i = this.num;
  5735. while(i--){
  5736. //for(var i=0;i<this.num;i++){
  5737. var p=this.ps[i];
  5738. p.normal.x=c.norX;
  5739. p.normal.y=c.norY;
  5740. p.normal.z=c.norZ;
  5741. p.tangent.x=c.tanX;
  5742. p.tangent.y=c.tanY;
  5743. p.tangent.z=c.tanZ;
  5744. p.binormal.x=c.binX;
  5745. p.binormal.y=c.binY;
  5746. p.binormal.z=c.binZ;
  5747. p.normalImpulse=c.norImp;
  5748. p.tangentImpulse=c.tanImp;
  5749. p.binormalImpulse=c.binImp;
  5750. p.normalDenominator=c.norDen;
  5751. p.tangentDenominator=c.tanDen;
  5752. p.binormalDenominator=c.binDen;
  5753. c=c.next;
  5754. }
  5755. }
  5756. /**
  5757. * A link list of contacts.
  5758. * @author saharan
  5759. */
  5760. OIMO.ContactLink = function(contact){
  5761. // The previous contact link.
  5762. this.prev=null;
  5763. // The next contact link.
  5764. this.next=null;
  5765. // The shape of the contact.
  5766. this.shape=null;
  5767. // The other rigid body.
  5768. this.body=null;
  5769. // The contact of the link.
  5770. this.contact = contact;
  5771. }
  5772. /**
  5773. * A contact manifold between two shapes.
  5774. * @author saharan
  5775. */
  5776. OIMO.ContactManifold = function(){
  5777. // The first rigid body.
  5778. this.body1 = null;
  5779. // The second rigid body.
  5780. this.body2 = null;
  5781. // The number of manifold points.
  5782. this.numPoints = 0;
  5783. // The manifold points.
  5784. this.points = [];
  5785. this.points.length = 4;
  5786. this.points[0] = new OIMO.ManifoldPoint();
  5787. this.points[1] = new OIMO.ManifoldPoint();
  5788. this.points[2] = new OIMO.ManifoldPoint();
  5789. this.points[3] = new OIMO.ManifoldPoint();
  5790. }
  5791. OIMO.ContactManifold.prototype = {
  5792. constructor: OIMO.ContactManifold,
  5793. /**
  5794. * Reset the manifold.
  5795. * @param shape1
  5796. * @param shape2
  5797. */
  5798. reset:function(shape1,shape2){
  5799. this.body1=shape1.parent;
  5800. this.body2=shape2.parent;
  5801. this.numPoints=0;
  5802. },
  5803. /**
  5804. * Add a point into this manifold.
  5805. * @param x
  5806. * @param y
  5807. * @param z
  5808. * @param normalX
  5809. * @param normalY
  5810. * @param normalZ
  5811. * @param penetration
  5812. * @param flip
  5813. */
  5814. addPoint:function(x,y,z,normalX,normalY,normalZ,penetration,flip){
  5815. var p=this.points[this.numPoints++];
  5816. p.position.x=x;
  5817. p.position.y=y;
  5818. p.position.z=z;
  5819. var r=this.body1.rotation;
  5820. var rx=x-this.body1.position.x;
  5821. var ry=y-this.body1.position.y;
  5822. var rz=z-this.body1.position.z;
  5823. var tr = r.elements;
  5824. p.localPoint1.x=rx*tr[0]+ry*tr[3]+rz*tr[6];
  5825. p.localPoint1.y=rx*tr[1]+ry*tr[4]+rz*tr[7];
  5826. p.localPoint1.z=rx*tr[2]+ry*tr[5]+rz*tr[8];
  5827. r=this.body2.rotation;
  5828. rx=x-this.body2.position.x;
  5829. ry=y-this.body2.position.y;
  5830. rz=z-this.body2.position.z;
  5831. p.localPoint2.x=rx*tr[0]+ry*tr[3]+rz*tr[6];
  5832. p.localPoint2.y=rx*tr[1]+ry*tr[4]+rz*tr[7];
  5833. p.localPoint2.z=rx*tr[2]+ry*tr[5]+rz*tr[8];
  5834. p.normalImpulse=0;
  5835. if(flip){
  5836. p.normal.x=-normalX;
  5837. p.normal.y=-normalY;
  5838. p.normal.z=-normalZ;
  5839. }else{
  5840. p.normal.x=normalX;
  5841. p.normal.y=normalY;
  5842. p.normal.z=normalZ;
  5843. }
  5844. p.penetration=penetration;
  5845. p.warmStarted=false;
  5846. }
  5847. }
  5848. OIMO.ContactPointDataBuffer = function(){
  5849. this.norX=NaN;
  5850. this.norY=NaN;
  5851. this.norZ=NaN;
  5852. this.tanX=NaN;
  5853. this.tanY=NaN;
  5854. this.tanZ=NaN;
  5855. this.binX=NaN;
  5856. this.binY=NaN;
  5857. this.binZ=NaN;
  5858. this.rp1X=NaN;
  5859. this.rp1Y=NaN;
  5860. this.rp1Z=NaN;
  5861. this.rp2X=NaN;
  5862. this.rp2Y=NaN;
  5863. this.rp2Z=NaN;
  5864. this.norU1X=NaN;
  5865. this.norU1Y=NaN;
  5866. this.norU1Z=NaN;
  5867. this.norU2X=NaN;
  5868. this.norU2Y=NaN;
  5869. this.norU2Z=NaN;
  5870. this.tanU1X=NaN;
  5871. this.tanU1Y=NaN;
  5872. this.tanU1Z=NaN;
  5873. this.tanU2X=NaN;
  5874. this.tanU2Y=NaN;
  5875. this.tanU2Z=NaN;
  5876. this.binU1X=NaN;
  5877. this.binU1Y=NaN;
  5878. this.binU1Z=NaN;
  5879. this.binU2X=NaN;
  5880. this.binU2Y=NaN;
  5881. this.binU2Z=NaN;
  5882. this.norT1X=NaN;
  5883. this.norT1Y=NaN;
  5884. this.norT1Z=NaN;
  5885. this.norT2X=NaN;
  5886. this.norT2Y=NaN;
  5887. this.norT2Z=NaN;
  5888. this.tanT1X=NaN;
  5889. this.tanT1Y=NaN;
  5890. this.tanT1Z=NaN;
  5891. this.tanT2X=NaN;
  5892. this.tanT2Y=NaN;
  5893. this.tanT2Z=NaN;
  5894. this.binT1X=NaN;
  5895. this.binT1Y=NaN;
  5896. this.binT1Z=NaN;
  5897. this.binT2X=NaN;
  5898. this.binT2Y=NaN;
  5899. this.binT2Z=NaN;
  5900. this.norTU1X=NaN;
  5901. this.norTU1Y=NaN;
  5902. this.norTU1Z=NaN;
  5903. this.norTU2X=NaN;
  5904. this.norTU2Y=NaN;
  5905. this.norTU2Z=NaN;
  5906. this.tanTU1X=NaN;
  5907. this.tanTU1Y=NaN;
  5908. this.tanTU1Z=NaN;
  5909. this.tanTU2X=NaN;
  5910. this.tanTU2Y=NaN;
  5911. this.tanTU2Z=NaN;
  5912. this.binTU1X=NaN;
  5913. this.binTU1Y=NaN;
  5914. this.binTU1Z=NaN;
  5915. this.binTU2X=NaN;
  5916. this.binTU2Y=NaN;
  5917. this.binTU2Z=NaN;
  5918. this.norImp=NaN;
  5919. this.tanImp=NaN;
  5920. this.binImp=NaN;
  5921. this.norDen=NaN;
  5922. this.tanDen=NaN;
  5923. this.binDen=NaN;
  5924. this.norTar=NaN;
  5925. this.next=null;
  5926. this.last=false;
  5927. }
  5928. OIMO.ImpulseDataBuffer = function(){
  5929. this.lp1X=NaN;
  5930. this.lp1Y=NaN;
  5931. this.lp1Z=NaN;
  5932. this.lp2X=NaN;
  5933. this.lp2Y=NaN;
  5934. this.lp2Z=NaN;
  5935. this.impulse=NaN;
  5936. }
  5937. /**
  5938. * The class holds details of the contact point.
  5939. * @author saharan
  5940. */
  5941. OIMO.ManifoldPoint = function(){
  5942. // Whether this manifold point is persisting or not.
  5943. this.warmStarted=false;
  5944. // The position of this manifold point.
  5945. this.position=new OIMO.Vec3();
  5946. // The position in the first shape's coordinate.
  5947. this.localPoint1=new OIMO.Vec3();
  5948. // The position in the second shape's coordinate.
  5949. this.localPoint2=new OIMO.Vec3();
  5950. // The normal vector of this manifold point.
  5951. this.normal=new OIMO.Vec3();
  5952. // The tangent vector of this manifold point.
  5953. this.tangent=new OIMO.Vec3();
  5954. // The binormal vector of this manifold point.
  5955. this.binormal=new OIMO.Vec3();
  5956. // The impulse in normal direction.
  5957. this.normalImpulse=0;
  5958. // The impulse in tangent direction.
  5959. this.tangentImpulse=0;
  5960. // The impulse in binormal direction.
  5961. this.binormalImpulse=0;
  5962. // The denominator in normal direction.
  5963. this.normalDenominator=0;
  5964. // The denominator in tangent direction.
  5965. this.tangentDenominator=0;
  5966. // The denominator in binormal direction.
  5967. this.binormalDenominator=0;
  5968. // The depth of penetration.
  5969. this.penetration=0;
  5970. }
  5971. /**
  5972. * This class holds mass information of a shape.
  5973. * @author saharan
  5974. */
  5975. OIMO.MassInfo = function(){
  5976. // Mass of the shape.
  5977. this.mass = 0;
  5978. // The moment inertia of the shape.
  5979. this.inertia = new OIMO.Mat33();
  5980. }
  5981. /**
  5982. * A shape is used to detect collisions of rigid bodies.
  5983. * @author saharan
  5984. */
  5985. OIMO.Shape = function(config){
  5986. // The global identification of the shape.
  5987. // This value should be unique to the shape.
  5988. this.id = OIMO.nextID++;
  5989. // The previous shape in parent rigid body.
  5990. this.prev = null;
  5991. // The next shape in parent rigid body.
  5992. this.next = null;
  5993. // The type of the shape.
  5994. this.type = 0;
  5995. // The proxy of the shape.
  5996. // This is used for broad-phase collision detection.
  5997. this.proxy = null;
  5998. // The parent rigid body of the shape.
  5999. this.parent = null;
  6000. // The linked list of the contacts with the shape.
  6001. this.contactLink = null;
  6002. // The number of the contacts with the shape.
  6003. this.numContacts=0;
  6004. // The center of gravity of the shape in world coordinate system.
  6005. this.position = new OIMO.Vec3();
  6006. // The rotation matrix of the shape in world coordinate system
  6007. this.rotation = new OIMO.Mat33();
  6008. // The position of the shape in parent's coordinate system.
  6009. this.relativePosition = new OIMO.Vec3().copy(config.relativePosition);
  6010. // The rotation matrix of the shape in parent's coordinate system.
  6011. this.relativeRotation = new OIMO.Mat33().copy(config.relativeRotation);
  6012. // The axis-aligned bounding box of the shape.
  6013. this.aabb = new OIMO.AABB();
  6014. // The density of the shape.
  6015. this.density = config.density;
  6016. // The coefficient of friction of the shape.
  6017. this.friction = config.friction;
  6018. // The coefficient of restitution of the shape.
  6019. this.restitution = config.restitution;
  6020. // The bits of the collision groups to which the shape belongs.
  6021. this.belongsTo = config.belongsTo;
  6022. // The bits of the collision groups with which the shape collides.
  6023. this.collidesWith = config.collidesWith;
  6024. }
  6025. OIMO.Shape.prototype = {
  6026. constructor: OIMO.Shape,
  6027. /**
  6028. * Calculate the mass information of the shape.
  6029. * @param out
  6030. */
  6031. calculateMassInfo:function(out){
  6032. throw new Error("Inheritance error.");
  6033. },
  6034. /**
  6035. * Update the proxy of the shape.
  6036. */
  6037. updateProxy:function(){
  6038. throw new Error("Inheritance error.");
  6039. }
  6040. }
  6041. /**
  6042. * A shape configuration holds common configuration data for constructing a shape.
  6043. * Shape configurations can be reused safely.
  6044. * @author saharan
  6045. */
  6046. OIMO.ShapeConfig = function(){
  6047. // The position of the shape in parent's coordinate system.
  6048. this.relativePosition = new OIMO.Vec3();
  6049. // The rotation matrix of the shape in parent's coordinate system.
  6050. this.relativeRotation = new OIMO.Mat33();
  6051. // The coefficient of friction of the shape.
  6052. this.friction = 0.4;
  6053. // The coefficient of restitution of the shape.
  6054. this.restitution = 0.2;
  6055. // The density of the shape.
  6056. this.density = 1;
  6057. // The bits of the collision groups to which the shape belongs.
  6058. this.belongsTo = 1;
  6059. // The bits of the collision groups with which the shape collides.
  6060. this.collidesWith = 0xffffffff;
  6061. }
  6062. /**
  6063. * A box shape.
  6064. * @author saharan
  6065. * @author loth
  6066. */
  6067. OIMO.BoxShape = function(config,Width,Height,Depth){
  6068. OIMO.Shape.call( this, config );
  6069. // The width of the box.
  6070. this.width = Width;
  6071. // The height of the box.
  6072. this.height = Height;
  6073. // The depth of the box.
  6074. this.depth = Depth;
  6075. // The half-width of the box.
  6076. this.halfWidth = Width*0.5;
  6077. // The half-height of the box.
  6078. this.halfHeight = Height*0.5;
  6079. // The half-depth of the box.
  6080. this.halfDepth = Depth*0.5;
  6081. this.dimentions = new OIMO_ARRAY_TYPE(18);
  6082. this.elements = new OIMO_ARRAY_TYPE(24);
  6083. this.type = OIMO.SHAPE_BOX;
  6084. }
  6085. OIMO.BoxShape.prototype = Object.create( OIMO.Shape.prototype );
  6086. OIMO.BoxShape.prototype.calculateMassInfo = function(out){
  6087. var mass=this.width*this.height*this.depth*this.density;
  6088. out.mass=mass;
  6089. out.inertia.init(
  6090. mass*(this.height*this.height+this.depth*this.depth)/12,0,0,
  6091. 0,mass*(this.width*this.width+this.depth*this.depth)/12,0,
  6092. 0,0,mass*(this.width*this.width+this.height*this.height)/12
  6093. );
  6094. }
  6095. OIMO.BoxShape.prototype.updateProxy = function(){
  6096. var te = this.rotation.elements;
  6097. var di = this.dimentions;
  6098. // Width
  6099. di[0]=te[0];
  6100. di[1]=te[3];
  6101. di[2]=te[6];
  6102. // Height
  6103. di[3]=te[1];
  6104. di[4]=te[4];
  6105. di[5]=te[7];
  6106. // Depth
  6107. di[6]=te[2];
  6108. di[7]=te[5];
  6109. di[8]=te[8];
  6110. // halp Width
  6111. di[9]=te[0]*this.halfWidth;
  6112. di[10]=te[3]*this.halfWidth;
  6113. di[11]=te[6]*this.halfWidth;
  6114. // halp Height
  6115. di[12]=te[1]*this.halfHeight;
  6116. di[13]=te[4]*this.halfHeight;
  6117. di[14]=te[7]*this.halfHeight;
  6118. // halp Depth
  6119. di[15]=te[2]*this.halfDepth;
  6120. di[16]=te[5]*this.halfDepth;
  6121. di[17]=te[8]*this.halfDepth;
  6122. var wx=di[9];
  6123. var wy=di[10];
  6124. var wz=di[11];
  6125. var hx=di[12];
  6126. var hy=di[13];
  6127. var hz=di[14];
  6128. var dx=di[15];
  6129. var dy=di[16];
  6130. var dz=di[17];
  6131. var x=this.position.x;
  6132. var y=this.position.y;
  6133. var z=this.position.z;
  6134. var v=this.elements;
  6135. //v1
  6136. v[0]=x+wx+hx+dx;
  6137. v[1]=y+wy+hy+dy;
  6138. v[2]=z+wz+hz+dz;
  6139. //v2
  6140. v[3]=x+wx+hx-dx;
  6141. v[4]=y+wy+hy-dy;
  6142. v[5]=z+wz+hz-dz;
  6143. //v3
  6144. v[6]=x+wx-hx+dx;
  6145. v[7]=y+wy-hy+dy;
  6146. v[8]=z+wz-hz+dz;
  6147. //v4
  6148. v[9]=x+wx-hx-dx;
  6149. v[10]=y+wy-hy-dy;
  6150. v[11]=z+wz-hz-dz;
  6151. //v5
  6152. v[12]=x-wx+hx+dx;
  6153. v[13]=y-wy+hy+dy;
  6154. v[14]=z-wz+hz+dz;
  6155. //v6
  6156. v[15]=x-wx+hx-dx;
  6157. v[16]=y-wy+hy-dy;
  6158. v[17]=z-wz+hz-dz;
  6159. //v7
  6160. v[18]=x-wx-hx+dx;
  6161. v[19]=y-wy-hy+dy;
  6162. v[20]=z-wz-hz+dz;
  6163. //v8
  6164. v[21]=x-wx-hx-dx;
  6165. v[22]=y-wy-hy-dy;
  6166. v[23]=z-wz-hz-dz;
  6167. var w = (di[9]<0) ? -di[9] : di[9];
  6168. var h = (di[10]<0) ? -di[10] : di[10];
  6169. var d = (di[11]<0) ? -di[11] : di[11];
  6170. w = (di[12]<0) ? w-di[12] : w+di[12];
  6171. h = (di[13]<0) ? h-di[13] : h+di[13];
  6172. d = (di[14]<0) ? d-di[14] : d+di[14];
  6173. w = (di[15]<0) ? w-di[15] : w+di[15];
  6174. h = (di[16]<0) ? h-di[16] : h+di[16];
  6175. d = (di[17]<0) ? d-di[17] : d+di[17];
  6176. this.aabb.init(
  6177. this.position.x-w-0.005,this.position.x+w+0.005,
  6178. this.position.y-h-0.005,this.position.y+h+0.005,
  6179. this.position.z-d-0.005,this.position.z+d+0.005
  6180. );
  6181. if(this.proxy!==null){
  6182. this.proxy.update();
  6183. }
  6184. }
  6185. /**
  6186. * A sphere shape.
  6187. * @author saharan
  6188. */
  6189. OIMO.SphereShape = function(config,radius){
  6190. OIMO.Shape.call( this, config);
  6191. // The radius of the shape.
  6192. this.radius = radius;
  6193. this.type = OIMO.SHAPE_SPHERE;
  6194. }
  6195. OIMO.SphereShape.prototype = Object.create( OIMO.Shape.prototype );
  6196. OIMO.SphereShape.prototype.calculateMassInfo = function(out){
  6197. var mass = 4/3*Math.PI*this.radius*this.radius*this.radius*this.density;
  6198. out.mass = mass;
  6199. var inertia = mass*this.radius*this.radius*2/5;
  6200. out.inertia.init( inertia,0,0,0,inertia,0,0,0,inertia );
  6201. }
  6202. OIMO.SphereShape.prototype.updateProxy = function(){
  6203. this.aabb.init(
  6204. this.position.x-this.radius-0.005,this.position.x+this.radius+0.005,
  6205. this.position.y-this.radius-0.005,this.position.y+this.radius+0.005,
  6206. this.position.z-this.radius-0.005,this.position.z+this.radius+0.005
  6207. );
  6208. if(this.proxy!==null){ this.proxy.update(); }
  6209. }
  6210. OIMO.CollisionDetector = function(){
  6211. this.flip = false;
  6212. }
  6213. OIMO.CollisionDetector.prototype = {
  6214. constructor: OIMO.CollisionDetector,
  6215. detectCollision:function(shape1,shape2,manifold){
  6216. throw new Error("Inheritance error.");
  6217. }
  6218. }
  6219. /**
  6220. * A collision detector which detects collisions between two boxes.
  6221. * @author saharan
  6222. */
  6223. OIMO.BoxBoxCollisionDetector = function(){
  6224. OIMO.CollisionDetector.call( this );
  6225. this.clipVertices1=new OIMO_ARRAY_TYPE(24); // 8 vertices x,y,z
  6226. this.clipVertices2=new OIMO_ARRAY_TYPE(24);
  6227. this.used=new OIMO_ARRAY_TYPE(8);
  6228. this.INF = 1/0;
  6229. }
  6230. OIMO.BoxBoxCollisionDetector.prototype = Object.create( OIMO.CollisionDetector.prototype );
  6231. OIMO.BoxBoxCollisionDetector.prototype.detectCollision = function(shape1,shape2,manifold){
  6232. // What you are doing
  6233. // · I to prepare a separate axis of the fifteen
  6234. //-Six in each of three normal vectors of the xyz direction of the box both
  6235. // · Remaining nine 3x3 a vector perpendicular to the side of the box 2 and the side of the box 1
  6236. // · Calculate the depth to the separation axis
  6237. // Calculates the distance using the inner product and put the amount of embedment
  6238. // · However a vertical separation axis and side to weight a little to avoid vibration
  6239. // And end when there is a separate axis that is remote even one
  6240. // · I look for separation axis with little to dent most
  6241. // Men and if separation axis of the first six - end collision
  6242. // Heng If it separate axis of nine other - side collision
  6243. // Heng - case of a side collision
  6244. // · Find points of two sides on which you made ​​the separation axis
  6245. // Calculates the point of closest approach of a straight line consisting of separate axis points obtained, and the collision point
  6246. //-Surface - the case of the plane crash
  6247. //-Box A, box B and the other a box of better made ​​a separate axis
  6248. // • 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
  6249. // When viewed from the front surface A, and the cut part exceeding the area of the surface A is a surface B
  6250. //-Plane B becomes the 3-8 triangle, I a candidate for the collision point the vertex of surface B
  6251. // • If more than one candidate 5 exists, scraping up to four
  6252. // For potential collision points of all, to examine the distance between the surface A
  6253. // • If you were on the inside surface of A, and the collision point
  6254. var b1;
  6255. var b2;
  6256. if(shape1.id<shape2.id){
  6257. b1=(shape1);
  6258. b2=(shape2);
  6259. }else{
  6260. b1=(shape2);
  6261. b2=(shape1);
  6262. }
  6263. var V1 = b1.elements;
  6264. var V2 = b2.elements;
  6265. var D1 = b1.dimentions;
  6266. var D2 = b2.dimentions;
  6267. var p1=b1.position;
  6268. var p2=b2.position;
  6269. var p1x=p1.x;
  6270. var p1y=p1.y;
  6271. var p1z=p1.z;
  6272. var p2x=p2.x;
  6273. var p2y=p2.y;
  6274. var p2z=p2.z;
  6275. // diff
  6276. var dx=p2x-p1x;
  6277. var dy=p2y-p1y;
  6278. var dz=p2z-p1z;
  6279. // distance
  6280. var w1=b1.halfWidth;
  6281. var h1=b1.halfHeight;
  6282. var d1=b1.halfDepth;
  6283. var w2=b2.halfWidth;
  6284. var h2=b2.halfHeight;
  6285. var d2=b2.halfDepth;
  6286. // direction
  6287. // ----------------------------
  6288. // 15 separating axes
  6289. // 1~6: face
  6290. // 7~f: edge
  6291. // http://marupeke296.com/COL_3D_No13_OBBvsOBB.html
  6292. // ----------------------------
  6293. var a1x=D1[0];
  6294. var a1y=D1[1];
  6295. var a1z=D1[2];
  6296. var a2x=D1[3];
  6297. var a2y=D1[4];
  6298. var a2z=D1[5];
  6299. var a3x=D1[6];
  6300. var a3y=D1[7];
  6301. var a3z=D1[8];
  6302. var d1x=D1[9];
  6303. var d1y=D1[10];
  6304. var d1z=D1[11];
  6305. var d2x=D1[12];
  6306. var d2y=D1[13];
  6307. var d2z=D1[14];
  6308. var d3x=D1[15];
  6309. var d3y=D1[16];
  6310. var d3z=D1[17];
  6311. var a4x=D2[0];
  6312. var a4y=D2[1];
  6313. var a4z=D2[2];
  6314. var a5x=D2[3];
  6315. var a5y=D2[4];
  6316. var a5z=D2[5];
  6317. var a6x=D2[6];
  6318. var a6y=D2[7];
  6319. var a6z=D2[8];
  6320. var d4x=D2[9];
  6321. var d4y=D2[10];
  6322. var d4z=D2[11];
  6323. var d5x=D2[12];
  6324. var d5y=D2[13];
  6325. var d5z=D2[14];
  6326. var d6x=D2[15];
  6327. var d6y=D2[16];
  6328. var d6z=D2[17];
  6329. var a7x=a1y*a4z-a1z*a4y;
  6330. var a7y=a1z*a4x-a1x*a4z;
  6331. var a7z=a1x*a4y-a1y*a4x;
  6332. var a8x=a1y*a5z-a1z*a5y;
  6333. var a8y=a1z*a5x-a1x*a5z;
  6334. var a8z=a1x*a5y-a1y*a5x;
  6335. var a9x=a1y*a6z-a1z*a6y;
  6336. var a9y=a1z*a6x-a1x*a6z;
  6337. var a9z=a1x*a6y-a1y*a6x;
  6338. var aax=a2y*a4z-a2z*a4y;
  6339. var aay=a2z*a4x-a2x*a4z;
  6340. var aaz=a2x*a4y-a2y*a4x;
  6341. var abx=a2y*a5z-a2z*a5y;
  6342. var aby=a2z*a5x-a2x*a5z;
  6343. var abz=a2x*a5y-a2y*a5x;
  6344. var acx=a2y*a6z-a2z*a6y;
  6345. var acy=a2z*a6x-a2x*a6z;
  6346. var acz=a2x*a6y-a2y*a6x;
  6347. var adx=a3y*a4z-a3z*a4y;
  6348. var ady=a3z*a4x-a3x*a4z;
  6349. var adz=a3x*a4y-a3y*a4x;
  6350. var aex=a3y*a5z-a3z*a5y;
  6351. var aey=a3z*a5x-a3x*a5z;
  6352. var aez=a3x*a5y-a3y*a5x;
  6353. var afx=a3y*a6z-a3z*a6y;
  6354. var afy=a3z*a6x-a3x*a6z;
  6355. var afz=a3x*a6y-a3y*a6x;
  6356. // right or left flags
  6357. var right1;
  6358. var right2;
  6359. var right3;
  6360. var right4;
  6361. var right5;
  6362. var right6;
  6363. var right7;
  6364. var right8;
  6365. var right9;
  6366. var righta;
  6367. var rightb;
  6368. var rightc;
  6369. var rightd;
  6370. var righte;
  6371. var rightf;
  6372. // overlapping distances
  6373. var overlap1;
  6374. var overlap2;
  6375. var overlap3;
  6376. var overlap4;
  6377. var overlap5;
  6378. var overlap6;
  6379. var overlap7;
  6380. var overlap8;
  6381. var overlap9;
  6382. var overlapa;
  6383. var overlapb;
  6384. var overlapc;
  6385. var overlapd;
  6386. var overlape;
  6387. var overlapf;
  6388. // invalid flags
  6389. var invalid7=false;
  6390. var invalid8=false;
  6391. var invalid9=false;
  6392. var invalida=false;
  6393. var invalidb=false;
  6394. var invalidc=false;
  6395. var invalidd=false;
  6396. var invalide=false;
  6397. var invalidf=false;
  6398. // temporary variables
  6399. var len;
  6400. var len1;
  6401. var len2;
  6402. var dot1;
  6403. var dot2;
  6404. var dot3;
  6405. // try axis 1
  6406. len=a1x*dx+a1y*dy+a1z*dz;
  6407. right1=len>0;
  6408. if(!right1)len=-len;
  6409. len1=w1;
  6410. dot1=a1x*a4x+a1y*a4y+a1z*a4z;
  6411. dot2=a1x*a5x+a1y*a5y+a1z*a5z;
  6412. dot3=a1x*a6x+a1y*a6y+a1z*a6z;
  6413. if(dot1<0)dot1=-dot1;
  6414. if(dot2<0)dot2=-dot2;
  6415. if(dot3<0)dot3=-dot3;
  6416. len2=dot1*w2+dot2*h2+dot3*d2;
  6417. overlap1=len-len1-len2;
  6418. if(overlap1>0)return;
  6419. // try axis 2
  6420. len=a2x*dx+a2y*dy+a2z*dz;
  6421. right2=len>0;
  6422. if(!right2)len=-len;
  6423. len1=h1;
  6424. dot1=a2x*a4x+a2y*a4y+a2z*a4z;
  6425. dot2=a2x*a5x+a2y*a5y+a2z*a5z;
  6426. dot3=a2x*a6x+a2y*a6y+a2z*a6z;
  6427. if(dot1<0)dot1=-dot1;
  6428. if(dot2<0)dot2=-dot2;
  6429. if(dot3<0)dot3=-dot3;
  6430. len2=dot1*w2+dot2*h2+dot3*d2;
  6431. overlap2=len-len1-len2;
  6432. if(overlap2>0)return;
  6433. // try axis 3
  6434. len=a3x*dx+a3y*dy+a3z*dz;
  6435. right3=len>0;
  6436. if(!right3)len=-len;
  6437. len1=d1;
  6438. dot1=a3x*a4x+a3y*a4y+a3z*a4z;
  6439. dot2=a3x*a5x+a3y*a5y+a3z*a5z;
  6440. dot3=a3x*a6x+a3y*a6y+a3z*a6z;
  6441. if(dot1<0)dot1=-dot1;
  6442. if(dot2<0)dot2=-dot2;
  6443. if(dot3<0)dot3=-dot3;
  6444. len2=dot1*w2+dot2*h2+dot3*d2;
  6445. overlap3=len-len1-len2;
  6446. if(overlap3>0)return;
  6447. // try axis 4
  6448. len=a4x*dx+a4y*dy+a4z*dz;
  6449. right4=len>0;
  6450. if(!right4)len=-len;
  6451. dot1=a4x*a1x+a4y*a1y+a4z*a1z;
  6452. dot2=a4x*a2x+a4y*a2y+a4z*a2z;
  6453. dot3=a4x*a3x+a4y*a3y+a4z*a3z;
  6454. if(dot1<0)dot1=-dot1;
  6455. if(dot2<0)dot2=-dot2;
  6456. if(dot3<0)dot3=-dot3;
  6457. len1=dot1*w1+dot2*h1+dot3*d1;
  6458. len2=w2;
  6459. overlap4=(len-len1-len2)*1.0;
  6460. if(overlap4>0)return;
  6461. // try axis 5
  6462. len=a5x*dx+a5y*dy+a5z*dz;
  6463. right5=len>0;
  6464. if(!right5)len=-len;
  6465. dot1=a5x*a1x+a5y*a1y+a5z*a1z;
  6466. dot2=a5x*a2x+a5y*a2y+a5z*a2z;
  6467. dot3=a5x*a3x+a5y*a3y+a5z*a3z;
  6468. if(dot1<0)dot1=-dot1;
  6469. if(dot2<0)dot2=-dot2;
  6470. if(dot3<0)dot3=-dot3;
  6471. len1=dot1*w1+dot2*h1+dot3*d1;
  6472. len2=h2;
  6473. overlap5=(len-len1-len2)*1.0;
  6474. if(overlap5>0)return;
  6475. // try axis 6
  6476. len=a6x*dx+a6y*dy+a6z*dz;
  6477. right6=len>0;
  6478. if(!right6)len=-len;
  6479. dot1=a6x*a1x+a6y*a1y+a6z*a1z;
  6480. dot2=a6x*a2x+a6y*a2y+a6z*a2z;
  6481. dot3=a6x*a3x+a6y*a3y+a6z*a3z;
  6482. if(dot1<0)dot1=-dot1;
  6483. if(dot2<0)dot2=-dot2;
  6484. if(dot3<0)dot3=-dot3;
  6485. len1=dot1*w1+dot2*h1+dot3*d1;
  6486. len2=d2;
  6487. overlap6=(len-len1-len2)*1.0;
  6488. if(overlap6>0)return;
  6489. // try axis 7
  6490. len=a7x*a7x+a7y*a7y+a7z*a7z;
  6491. if(len>1e-5){
  6492. len=1/Math.sqrt(len);
  6493. a7x*=len;
  6494. a7y*=len;
  6495. a7z*=len;
  6496. len=a7x*dx+a7y*dy+a7z*dz;
  6497. right7=len>0;
  6498. if(!right7)len=-len;
  6499. dot1=a7x*a2x+a7y*a2y+a7z*a2z;
  6500. dot2=a7x*a3x+a7y*a3y+a7z*a3z;
  6501. if(dot1<0)dot1=-dot1;
  6502. if(dot2<0)dot2=-dot2;
  6503. len1=dot1*h1+dot2*d1;
  6504. dot1=a7x*a5x+a7y*a5y+a7z*a5z;
  6505. dot2=a7x*a6x+a7y*a6y+a7z*a6z;
  6506. if(dot1<0)dot1=-dot1;
  6507. if(dot2<0)dot2=-dot2;
  6508. len2=dot1*h2+dot2*d2;
  6509. overlap7=len-len1-len2;
  6510. if(overlap7>0)return;
  6511. }else{
  6512. right7=false;
  6513. overlap7=0;
  6514. invalid7=true;
  6515. }
  6516. // try axis 8
  6517. len=a8x*a8x+a8y*a8y+a8z*a8z;
  6518. if(len>1e-5){
  6519. len=1/Math.sqrt(len);
  6520. a8x*=len;
  6521. a8y*=len;
  6522. a8z*=len;
  6523. len=a8x*dx+a8y*dy+a8z*dz;
  6524. right8=len>0;
  6525. if(!right8)len=-len;
  6526. dot1=a8x*a2x+a8y*a2y+a8z*a2z;
  6527. dot2=a8x*a3x+a8y*a3y+a8z*a3z;
  6528. if(dot1<0)dot1=-dot1;
  6529. if(dot2<0)dot2=-dot2;
  6530. len1=dot1*h1+dot2*d1;
  6531. dot1=a8x*a4x+a8y*a4y+a8z*a4z;
  6532. dot2=a8x*a6x+a8y*a6y+a8z*a6z;
  6533. if(dot1<0)dot1=-dot1;
  6534. if(dot2<0)dot2=-dot2;
  6535. len2=dot1*w2+dot2*d2;
  6536. overlap8=len-len1-len2;
  6537. if(overlap8>0)return;
  6538. }else{
  6539. right8=false;
  6540. overlap8=0;
  6541. invalid8=true;
  6542. }
  6543. // try axis 9
  6544. len=a9x*a9x+a9y*a9y+a9z*a9z;
  6545. if(len>1e-5){
  6546. len=1/Math.sqrt(len);
  6547. a9x*=len;
  6548. a9y*=len;
  6549. a9z*=len;
  6550. len=a9x*dx+a9y*dy+a9z*dz;
  6551. right9=len>0;
  6552. if(!right9)len=-len;
  6553. dot1=a9x*a2x+a9y*a2y+a9z*a2z;
  6554. dot2=a9x*a3x+a9y*a3y+a9z*a3z;
  6555. if(dot1<0)dot1=-dot1;
  6556. if(dot2<0)dot2=-dot2;
  6557. len1=dot1*h1+dot2*d1;
  6558. dot1=a9x*a4x+a9y*a4y+a9z*a4z;
  6559. dot2=a9x*a5x+a9y*a5y+a9z*a5z;
  6560. if(dot1<0)dot1=-dot1;
  6561. if(dot2<0)dot2=-dot2;
  6562. len2=dot1*w2+dot2*h2;
  6563. overlap9=len-len1-len2;
  6564. if(overlap9>0)return;
  6565. }else{
  6566. right9=false;
  6567. overlap9=0;
  6568. invalid9=true;
  6569. }
  6570. // try axis 10
  6571. len=aax*aax+aay*aay+aaz*aaz;
  6572. if(len>1e-5){
  6573. len=1/Math.sqrt(len);
  6574. aax*=len;
  6575. aay*=len;
  6576. aaz*=len;
  6577. len=aax*dx+aay*dy+aaz*dz;
  6578. righta=len>0;
  6579. if(!righta)len=-len;
  6580. dot1=aax*a1x+aay*a1y+aaz*a1z;
  6581. dot2=aax*a3x+aay*a3y+aaz*a3z;
  6582. if(dot1<0)dot1=-dot1;
  6583. if(dot2<0)dot2=-dot2;
  6584. len1=dot1*w1+dot2*d1;
  6585. dot1=aax*a5x+aay*a5y+aaz*a5z;
  6586. dot2=aax*a6x+aay*a6y+aaz*a6z;
  6587. if(dot1<0)dot1=-dot1;
  6588. if(dot2<0)dot2=-dot2;
  6589. len2=dot1*h2+dot2*d2;
  6590. overlapa=len-len1-len2;
  6591. if(overlapa>0)return;
  6592. }else{
  6593. righta=false;
  6594. overlapa=0;
  6595. invalida=true;
  6596. }
  6597. // try axis 11
  6598. len=abx*abx+aby*aby+abz*abz;
  6599. if(len>1e-5){
  6600. len=1/Math.sqrt(len);
  6601. abx*=len;
  6602. aby*=len;
  6603. abz*=len;
  6604. len=abx*dx+aby*dy+abz*dz;
  6605. rightb=len>0;
  6606. if(!rightb)len=-len;
  6607. dot1=abx*a1x+aby*a1y+abz*a1z;
  6608. dot2=abx*a3x+aby*a3y+abz*a3z;
  6609. if(dot1<0)dot1=-dot1;
  6610. if(dot2<0)dot2=-dot2;
  6611. len1=dot1*w1+dot2*d1;
  6612. dot1=abx*a4x+aby*a4y+abz*a4z;
  6613. dot2=abx*a6x+aby*a6y+abz*a6z;
  6614. if(dot1<0)dot1=-dot1;
  6615. if(dot2<0)dot2=-dot2;
  6616. len2=dot1*w2+dot2*d2;
  6617. overlapb=len-len1-len2;
  6618. if(overlapb>0)return;
  6619. }else{
  6620. rightb=false;
  6621. overlapb=0;
  6622. invalidb=true;
  6623. }
  6624. // try axis 12
  6625. len=acx*acx+acy*acy+acz*acz;
  6626. if(len>1e-5){
  6627. len=1/Math.sqrt(len);
  6628. acx*=len;
  6629. acy*=len;
  6630. acz*=len;
  6631. len=acx*dx+acy*dy+acz*dz;
  6632. rightc=len>0;
  6633. if(!rightc)len=-len;
  6634. dot1=acx*a1x+acy*a1y+acz*a1z;
  6635. dot2=acx*a3x+acy*a3y+acz*a3z;
  6636. if(dot1<0)dot1=-dot1;
  6637. if(dot2<0)dot2=-dot2;
  6638. len1=dot1*w1+dot2*d1;
  6639. dot1=acx*a4x+acy*a4y+acz*a4z;
  6640. dot2=acx*a5x+acy*a5y+acz*a5z;
  6641. if(dot1<0)dot1=-dot1;
  6642. if(dot2<0)dot2=-dot2;
  6643. len2=dot1*w2+dot2*h2;
  6644. overlapc=len-len1-len2;
  6645. if(overlapc>0)return;
  6646. }else{
  6647. rightc=false;
  6648. overlapc=0;
  6649. invalidc=true;
  6650. }
  6651. // try axis 13
  6652. len=adx*adx+ady*ady+adz*adz;
  6653. if(len>1e-5){
  6654. len=1/Math.sqrt(len);
  6655. adx*=len;
  6656. ady*=len;
  6657. adz*=len;
  6658. len=adx*dx+ady*dy+adz*dz;
  6659. rightd=len>0;
  6660. if(!rightd)len=-len;
  6661. dot1=adx*a1x+ady*a1y+adz*a1z;
  6662. dot2=adx*a2x+ady*a2y+adz*a2z;
  6663. if(dot1<0)dot1=-dot1;
  6664. if(dot2<0)dot2=-dot2;
  6665. len1=dot1*w1+dot2*h1;
  6666. dot1=adx*a5x+ady*a5y+adz*a5z;
  6667. dot2=adx*a6x+ady*a6y+adz*a6z;
  6668. if(dot1<0)dot1=-dot1;
  6669. if(dot2<0)dot2=-dot2;
  6670. len2=dot1*h2+dot2*d2;
  6671. overlapd=len-len1-len2;
  6672. if(overlapd>0)return;
  6673. }else{
  6674. rightd=false;
  6675. overlapd=0;
  6676. invalidd=true;
  6677. }
  6678. // try axis 14
  6679. len=aex*aex+aey*aey+aez*aez;
  6680. if(len>1e-5){
  6681. len=1/Math.sqrt(len);
  6682. aex*=len;
  6683. aey*=len;
  6684. aez*=len;
  6685. len=aex*dx+aey*dy+aez*dz;
  6686. righte=len>0;
  6687. if(!righte)len=-len;
  6688. dot1=aex*a1x+aey*a1y+aez*a1z;
  6689. dot2=aex*a2x+aey*a2y+aez*a2z;
  6690. if(dot1<0)dot1=-dot1;
  6691. if(dot2<0)dot2=-dot2;
  6692. len1=dot1*w1+dot2*h1;
  6693. dot1=aex*a4x+aey*a4y+aez*a4z;
  6694. dot2=aex*a6x+aey*a6y+aez*a6z;
  6695. if(dot1<0)dot1=-dot1;
  6696. if(dot2<0)dot2=-dot2;
  6697. len2=dot1*w2+dot2*d2;
  6698. overlape=len-len1-len2;
  6699. if(overlape>0)return;
  6700. }else{
  6701. righte=false;
  6702. overlape=0;
  6703. invalide=true;
  6704. }
  6705. // try axis 15
  6706. len=afx*afx+afy*afy+afz*afz;
  6707. if(len>1e-5){
  6708. len=1/Math.sqrt(len);
  6709. afx*=len;
  6710. afy*=len;
  6711. afz*=len;
  6712. len=afx*dx+afy*dy+afz*dz;
  6713. rightf=len>0;
  6714. if(!rightf)len=-len;
  6715. dot1=afx*a1x+afy*a1y+afz*a1z;
  6716. dot2=afx*a2x+afy*a2y+afz*a2z;
  6717. if(dot1<0)dot1=-dot1;
  6718. if(dot2<0)dot2=-dot2;
  6719. len1=dot1*w1+dot2*h1;
  6720. dot1=afx*a4x+afy*a4y+afz*a4z;
  6721. dot2=afx*a5x+afy*a5y+afz*a5z;
  6722. if(dot1<0)dot1=-dot1;
  6723. if(dot2<0)dot2=-dot2;
  6724. len2=dot1*w2+dot2*h2;
  6725. overlapf=len-len1-len2;
  6726. if(overlapf>0)return;
  6727. }else{
  6728. rightf=false;
  6729. overlapf=0;
  6730. invalidf=true;
  6731. }
  6732. // boxes are overlapping
  6733. var depth=overlap1;
  6734. var depth2=overlap1;
  6735. var minIndex=0;
  6736. var right=right1;
  6737. if(overlap2>depth2){
  6738. depth=overlap2;
  6739. depth2=overlap2;
  6740. minIndex=1;
  6741. right=right2;
  6742. }
  6743. if(overlap3>depth2){
  6744. depth=overlap3;
  6745. depth2=overlap3;
  6746. minIndex=2;
  6747. right=right3;
  6748. }
  6749. if(overlap4>depth2){
  6750. depth=overlap4;
  6751. depth2=overlap4;
  6752. minIndex=3;
  6753. right=right4;
  6754. }
  6755. if(overlap5>depth2){
  6756. depth=overlap5;
  6757. depth2=overlap5;
  6758. minIndex=4;
  6759. right=right5;
  6760. }
  6761. if(overlap6>depth2){
  6762. depth=overlap6;
  6763. depth2=overlap6;
  6764. minIndex=5;
  6765. right=right6;
  6766. }
  6767. if(overlap7-0.01>depth2&&!invalid7){
  6768. depth=overlap7;
  6769. depth2=overlap7-0.01;
  6770. minIndex=6;
  6771. right=right7;
  6772. }
  6773. if(overlap8-0.01>depth2&&!invalid8){
  6774. depth=overlap8;
  6775. depth2=overlap8-0.01;
  6776. minIndex=7;
  6777. right=right8;
  6778. }
  6779. if(overlap9-0.01>depth2&&!invalid9){
  6780. depth=overlap9;
  6781. depth2=overlap9-0.01;
  6782. minIndex=8;
  6783. right=right9;
  6784. }
  6785. if(overlapa-0.01>depth2&&!invalida){
  6786. depth=overlapa;
  6787. depth2=overlapa-0.01;
  6788. minIndex=9;
  6789. right=righta;
  6790. }
  6791. if(overlapb-0.01>depth2&&!invalidb){
  6792. depth=overlapb;
  6793. depth2=overlapb-0.01;
  6794. minIndex=10;
  6795. right=rightb;
  6796. }
  6797. if(overlapc-0.01>depth2&&!invalidc){
  6798. depth=overlapc;
  6799. depth2=overlapc-0.01;
  6800. minIndex=11;
  6801. right=rightc;
  6802. }
  6803. if(overlapd-0.01>depth2&&!invalidd){
  6804. depth=overlapd;
  6805. depth2=overlapd-0.01;
  6806. minIndex=12;
  6807. right=rightd;
  6808. }
  6809. if(overlape-0.01>depth2&&!invalide){
  6810. depth=overlape;
  6811. depth2=overlape-0.01;
  6812. minIndex=13;
  6813. right=righte;
  6814. }
  6815. if(overlapf-0.01>depth2&&!invalidf){
  6816. depth=overlapf;
  6817. minIndex=14;
  6818. right=rightf;
  6819. }
  6820. // normal
  6821. var nx=0;
  6822. var ny=0;
  6823. var nz=0;
  6824. // edge line or face side normal
  6825. var n1x=0;
  6826. var n1y=0;
  6827. var n1z=0;
  6828. var n2x=0;
  6829. var n2y=0;
  6830. var n2z=0;
  6831. // center of current face
  6832. var cx=0;
  6833. var cy=0;
  6834. var cz=0;
  6835. // face side
  6836. var s1x=0;
  6837. var s1y=0;
  6838. var s1z=0;
  6839. var s2x=0;
  6840. var s2y=0;
  6841. var s2z=0;
  6842. // swap b1 b2
  6843. var swap=false;
  6844. //_______________________________________
  6845. if(minIndex==0){// b1.x * b2
  6846. if(right){
  6847. cx=p1x+d1x; cy=p1y+d1y; cz=p1z+d1z;
  6848. nx=a1x; ny=a1y; nz=a1z;
  6849. }else{
  6850. cx=p1x-d1x; cy=p1y-d1y; cz=p1z-d1z;
  6851. nx=-a1x; ny=-a1y; nz=-a1z;
  6852. }
  6853. s1x=d2x; s1y=d2y; s1z=d2z;
  6854. n1x=-a2x; n1y=-a2y; n1z=-a2z;
  6855. s2x=d3x; s2y=d3y; s2z=d3z;
  6856. n2x=-a3x; n2y=-a3y; n2z=-a3z;
  6857. }
  6858. else if(minIndex==1){// b1.y * b2
  6859. if(right){
  6860. cx=p1x+d2x; cy=p1y+d2y; cz=p1z+d2z;
  6861. nx=a2x; ny=a2y; nz=a2z;
  6862. }else{
  6863. cx=p1x-d2x; cy=p1y-d2y; cz=p1z-d2z;
  6864. nx=-a2x; ny=-a2y; nz=-a2z;
  6865. }
  6866. s1x=d1x; s1y=d1y; s1z=d1z;
  6867. n1x=-a1x; n1y=-a1y; n1z=-a1z;
  6868. s2x=d3x; s2y=d3y; s2z=d3z;
  6869. n2x=-a3x; n2y=-a3y; n2z=-a3z;
  6870. }
  6871. else if(minIndex==2){// b1.z * b2
  6872. if(right){
  6873. cx=p1x+d3x; cy=p1y+d3y; cz=p1z+d3z;
  6874. nx=a3x; ny=a3y; nz=a3z;
  6875. }else{
  6876. cx=p1x-d3x; cy=p1y-d3y; cz=p1z-d3z;
  6877. nx=-a3x; ny=-a3y; nz=-a3z;
  6878. }
  6879. s1x=d1x; s1y=d1y; s1z=d1z;
  6880. n1x=-a1x; n1y=-a1y; n1z=-a1z;
  6881. s2x=d2x; s2y=d2y; s2z=d2z;
  6882. n2x=-a2x; n2y=-a2y; n2z=-a2z;
  6883. }
  6884. else if(minIndex==3){// b2.x * b1
  6885. swap=true;
  6886. if(!right){
  6887. cx=p2x+d4x; cy=p2y+d4y; cz=p2z+d4z;
  6888. nx=a4x; ny=a4y; nz=a4z;
  6889. }else{
  6890. cx=p2x-d4x; cy=p2y-d4y; cz=p2z-d4z;
  6891. nx=-a4x; ny=-a4y; nz=-a4z;
  6892. }
  6893. s1x=d5x; s1y=d5y; s1z=d5z;
  6894. n1x=-a5x; n1y=-a5y; n1z=-a5z;
  6895. s2x=d6x; s2y=d6y; s2z=d6z;
  6896. n2x=-a6x; n2y=-a6y; n2z=-a6z;
  6897. }
  6898. else if(minIndex==4){// b2.y * b1
  6899. swap=true;
  6900. if(!right){
  6901. cx=p2x+d5x; cy=p2y+d5y; cz=p2z+d5z;
  6902. nx=a5x; ny=a5y; nz=a5z;
  6903. }else{
  6904. cx=p2x-d5x; cy=p2y-d5y; cz=p2z-d5z;
  6905. nx=-a5x; ny=-a5y; nz=-a5z;
  6906. }
  6907. s1x=d4x; s1y=d4y; s1z=d4z;
  6908. n1x=-a4x; n1y=-a4y; n1z=-a4z;
  6909. s2x=d6x; s2y=d6y; s2z=d6z;
  6910. n2x=-a6x; n2y=-a6y; n2z=-a6z;
  6911. }
  6912. else if(minIndex==5){// b2.z * b1
  6913. swap=true;
  6914. if(!right){
  6915. cx=p2x+d6x; cy=p2y+d6y; cz=p2z+d6z;
  6916. nx=a6x; ny=a6y; nz=a6z;
  6917. }else{
  6918. cx=p2x-d6x; cy=p2y-d6y; cz=p2z-d6z;
  6919. nx=-a6x; ny=-a6y; nz=-a6z;
  6920. }
  6921. s1x=d4x; s1y=d4y; s1z=d4z;
  6922. n1x=-a4x; n1y=-a4y; n1z=-a4z;
  6923. s2x=d5x; s2y=d5y; s2z=d5z;
  6924. n2x=-a5x; n2y=-a5y; n2z=-a5z;
  6925. }
  6926. else if(minIndex==6){// b1.x * b2.x
  6927. nx=a7x; ny=a7y; nz=a7z;
  6928. n1x=a1x; n1y=a1y; n1z=a1z;
  6929. n2x=a4x; n2y=a4y; n2z=a4z;
  6930. }
  6931. else if(minIndex==7){// b1.x * b2.y
  6932. nx=a8x; ny=a8y; nz=a8z;
  6933. n1x=a1x; n1y=a1y; n1z=a1z;
  6934. n2x=a5x; n2y=a5y; n2z=a5z;
  6935. }
  6936. else if(minIndex==8){// b1.x * b2.z
  6937. nx=a9x; ny=a9y; nz=a9z;
  6938. n1x=a1x; n1y=a1y; n1z=a1z;
  6939. n2x=a6x; n2y=a6y; n2z=a6z;
  6940. }
  6941. else if(minIndex==9){// b1.y * b2.x
  6942. nx=aax; ny=aay; nz=aaz;
  6943. n1x=a2x; n1y=a2y; n1z=a2z;
  6944. n2x=a4x; n2y=a4y; n2z=a4z
  6945. }
  6946. else if(minIndex==10){// b1.y * b2.y
  6947. nx=abx; ny=aby; nz=abz;
  6948. n1x=a2x; n1y=a2y; n1z=a2z;
  6949. n2x=a5x; n2y=a5y; n2z=a5z;
  6950. }
  6951. else if(minIndex==11){// b1.y * b2.z
  6952. nx=acx; ny=acy; nz=acz;
  6953. n1x=a2x; n1y=a2y; n1z=a2z;
  6954. n2x=a6x; n2y=a6y; n2z=a6z;
  6955. }
  6956. else if(minIndex==12){// b1.z * b2.x
  6957. nx=adx; ny=ady; nz=adz;
  6958. n1x=a3x; n1y=a3y; n1z=a3z;
  6959. n2x=a4x; n2y=a4y; n2z=a4z;
  6960. }
  6961. else if(minIndex==13){// b1.z * b2.y
  6962. nx=aex; ny=aey; nz=aez;
  6963. n1x=a3x; n1y=a3y; n1z=a3z;
  6964. n2x=a5x; n2y=a5y; n2z=a5z;
  6965. }
  6966. else if(minIndex==14){// b1.z * b2.z
  6967. nx=afx; ny=afy; nz=afz;
  6968. n1x=a3x; n1y=a3y; n1z=a3z;
  6969. n2x=a6x; n2y=a6y; n2z=a6z;
  6970. }
  6971. //__________________________________________
  6972. var v;
  6973. if(minIndex>5){
  6974. if(!right){
  6975. nx=-nx; ny=-ny; nz=-nz;
  6976. }
  6977. var distance;
  6978. var maxDistance;
  6979. var vx;
  6980. var vy;
  6981. var vz;
  6982. var v1x;
  6983. var v1y;
  6984. var v1z;
  6985. var v2x;
  6986. var v2y;
  6987. var v2z;
  6988. //vertex1;
  6989. v1x=V1[0]; v1y=V1[1]; v1z=V1[2];
  6990. maxDistance=nx*v1x+ny*v1y+nz*v1z;
  6991. //vertex2;
  6992. vx=V1[3]; vy=V1[4]; vz=V1[5];
  6993. distance=nx*vx+ny*vy+nz*vz;
  6994. if(distance>maxDistance){
  6995. maxDistance=distance;
  6996. v1x=vx; v1y=vy; v1z=vz;
  6997. }
  6998. //vertex3;
  6999. vx=V1[6]; vy=V1[7]; vz=V1[8];
  7000. distance=nx*vx+ny*vy+nz*vz;
  7001. if(distance>maxDistance){
  7002. maxDistance=distance;
  7003. v1x=vx; v1y=vy; v1z=vz;
  7004. }
  7005. //vertex4;
  7006. vx=V1[9]; vy=V1[10]; vz=V1[11];
  7007. distance=nx*vx+ny*vy+nz*vz;
  7008. if(distance>maxDistance){
  7009. maxDistance=distance;
  7010. v1x=vx; v1y=vy; v1z=vz;
  7011. }
  7012. //vertex5;
  7013. vx=V1[12]; vy=V1[13]; vz=V1[14];
  7014. distance=nx*vx+ny*vy+nz*vz;
  7015. if(distance>maxDistance){
  7016. maxDistance=distance;
  7017. v1x=vx; v1y=vy; v1z=vz;
  7018. }
  7019. //vertex6;
  7020. vx=V1[15]; vy=V1[16]; vz=V1[17];
  7021. distance=nx*vx+ny*vy+nz*vz;
  7022. if(distance>maxDistance){
  7023. maxDistance=distance;
  7024. v1x=vx; v1y=vy; v1z=vz;
  7025. }
  7026. //vertex7;
  7027. vx=V1[18]; vy=V1[19]; vz=V1[20];
  7028. distance=nx*vx+ny*vy+nz*vz;
  7029. if(distance>maxDistance){
  7030. maxDistance=distance;
  7031. v1x=vx; v1y=vy; v1z=vz;
  7032. }
  7033. //vertex8;
  7034. vx=V1[21]; vy=V1[22]; vz=V1[23];
  7035. distance=nx*vx+ny*vy+nz*vz;
  7036. if(distance>maxDistance){
  7037. maxDistance=distance;
  7038. v1x=vx; v1y=vy; v1z=vz;
  7039. }
  7040. //vertex1;
  7041. v2x=V2[0]; v2y=V2[1]; v2z=V2[2];
  7042. maxDistance=nx*v2x+ny*v2y+nz*v2z;
  7043. //vertex2;
  7044. vx=V2[3]; vy=V2[4]; vz=V2[5];
  7045. distance=nx*vx+ny*vy+nz*vz;
  7046. if(distance<maxDistance){
  7047. maxDistance=distance;
  7048. v2x=vx; v2y=vy; v2z=vz;
  7049. }
  7050. //vertex3;
  7051. vx=V2[6]; vy=V2[7]; vz=V2[8];
  7052. distance=nx*vx+ny*vy+nz*vz;
  7053. if(distance<maxDistance){
  7054. maxDistance=distance;
  7055. v2x=vx; v2y=vy; v2z=vz;
  7056. }
  7057. //vertex4;
  7058. vx=V2[9]; vy=V2[10]; vz=V2[11];
  7059. distance=nx*vx+ny*vy+nz*vz;
  7060. if(distance<maxDistance){
  7061. maxDistance=distance;
  7062. v2x=vx; v2y=vy; v2z=vz;
  7063. }
  7064. //vertex5;
  7065. vx=V2[12]; vy=V2[13]; vz=V2[14];
  7066. distance=nx*vx+ny*vy+nz*vz;
  7067. if(distance<maxDistance){
  7068. maxDistance=distance;
  7069. v2x=vx; v2y=vy; v2z=vz;
  7070. }
  7071. //vertex6;
  7072. vx=V2[15]; vy=V2[16]; vz=V2[17];
  7073. distance=nx*vx+ny*vy+nz*vz;
  7074. if(distance<maxDistance){
  7075. maxDistance=distance;
  7076. v2x=vx; v2y=vy; v2z=vz;
  7077. }
  7078. //vertex7;
  7079. vx=V2[18]; vy=V2[19]; vz=V2[20];
  7080. distance=nx*vx+ny*vy+nz*vz;
  7081. if(distance<maxDistance){
  7082. maxDistance=distance;
  7083. v2x=vx; v2y=vy; v2z=vz;
  7084. }
  7085. //vertex8;
  7086. vx=V2[21]; vy=V2[22]; vz=V2[23];
  7087. distance=nx*vx+ny*vy+nz*vz;
  7088. if(distance<maxDistance){
  7089. maxDistance=distance;
  7090. v2x=vx; v2y=vy; v2z=vz;
  7091. }
  7092. vx=v2x-v1x; vy=v2y-v1y; vz=v2z-v1z;
  7093. dot1=n1x*n2x+n1y*n2y+n1z*n2z;
  7094. var t=(vx*(n1x-n2x*dot1)+vy*(n1y-n2y*dot1)+vz*(n1z-n2z*dot1))/(1-dot1*dot1);
  7095. 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);
  7096. return;
  7097. }
  7098. // now detect face-face collision...
  7099. // target quad
  7100. var q1x;
  7101. var q1y;
  7102. var q1z;
  7103. var q2x;
  7104. var q2y;
  7105. var q2z;
  7106. var q3x;
  7107. var q3y;
  7108. var q3z;
  7109. var q4x;
  7110. var q4y;
  7111. var q4z;
  7112. // search support face and vertex
  7113. var minDot=1;
  7114. var dot=0;
  7115. var minDotIndex=0;
  7116. if(swap){
  7117. dot=a1x*nx+a1y*ny+a1z*nz;
  7118. if(dot<minDot){
  7119. minDot=dot;
  7120. minDotIndex=0;
  7121. }
  7122. if(-dot<minDot){
  7123. minDot=-dot;
  7124. minDotIndex=1;
  7125. }
  7126. dot=a2x*nx+a2y*ny+a2z*nz;
  7127. if(dot<minDot){
  7128. minDot=dot;
  7129. minDotIndex=2;
  7130. }
  7131. if(-dot<minDot){
  7132. minDot=-dot;
  7133. minDotIndex=3;
  7134. }
  7135. dot=a3x*nx+a3y*ny+a3z*nz;
  7136. if(dot<minDot){
  7137. minDot=dot;
  7138. minDotIndex=4;
  7139. }
  7140. if(-dot<minDot){
  7141. minDot=-dot;
  7142. minDotIndex=5;
  7143. }
  7144. if(minDotIndex==0){// x+ face
  7145. q1x=V1[0]; q1y=V1[1]; q1z=V1[2];//vertex1
  7146. q2x=V1[6]; q2y=V1[7]; q2z=V1[8];//vertex3
  7147. q3x=V1[9]; q3y=V1[10]; q3z=V1[11];//vertex4
  7148. q4x=V1[3]; q4y=V1[4]; q4z=V1[5];//vertex2
  7149. }
  7150. else if(minDotIndex==1){// x- face
  7151. q1x=V1[15]; q1y=V1[16]; q1z=V1[17];//vertex6
  7152. q2x=V1[21]; q2y=V1[22]; q2z=V1[23];//vertex8
  7153. q3x=V1[18]; q3y=V1[19]; q3z=V1[20];//vertex7
  7154. q4x=V1[12]; q4y=V1[13]; q4z=V1[14];//vertex5
  7155. }
  7156. else if(minDotIndex==2){// y+ face
  7157. q1x=V1[12]; q1y=V1[13]; q1z=V1[14];//vertex5
  7158. q2x=V1[0]; q2y=V1[1]; q2z=V1[2];//vertex1
  7159. q3x=V1[3]; q3y=V1[4]; q3z=V1[5];//vertex2
  7160. q4x=V1[15]; q4y=V1[16]; q4z=V1[17];//vertex6
  7161. }
  7162. else if(minDotIndex==3){// y- face
  7163. q1x=V1[21]; q1y=V1[22]; q1z=V1[23];//vertex8
  7164. q2x=V1[9]; q2y=V1[10]; q2z=V1[11];//vertex4
  7165. q3x=V1[6]; q3y=V1[7]; q3z=V1[8];//vertex3
  7166. q4x=V1[18]; q4y=V1[19]; q4z=V1[20];//vertex7
  7167. }
  7168. else if(minDotIndex==4){// z+ face
  7169. q1x=V1[12]; q1y=V1[13]; q1z=V1[14];//vertex5
  7170. q2x=V1[18]; q2y=V1[19]; q2z=V1[20];//vertex7
  7171. q3x=V1[6]; q3y=V1[7]; q3z=V1[8];//vertex3
  7172. q4x=V1[0]; q4y=V1[1]; q4z=V1[2];//vertex1
  7173. }
  7174. else if(minDotIndex==5){// z- face
  7175. q1x=V1[3]; q1y=V1[4]; q1z=V1[5];//vertex2
  7176. q2x=V1[6]; q2y=V1[7]; q2z=V1[8];//vertex4
  7177. q3x=V1[21]; q3y=V1[22]; q3z=V1[23];//vertex8
  7178. q4x=V1[15]; q4y=V1[16]; q4z=V1[17];//vertex6
  7179. }
  7180. }else{
  7181. dot=a4x*nx+a4y*ny+a4z*nz;
  7182. if(dot<minDot){
  7183. minDot=dot;
  7184. minDotIndex=0;
  7185. }
  7186. if(-dot<minDot){
  7187. minDot=-dot;
  7188. minDotIndex=1;
  7189. }
  7190. dot=a5x*nx+a5y*ny+a5z*nz;
  7191. if(dot<minDot){
  7192. minDot=dot;
  7193. minDotIndex=2;
  7194. }
  7195. if(-dot<minDot){
  7196. minDot=-dot;
  7197. minDotIndex=3;
  7198. }
  7199. dot=a6x*nx+a6y*ny+a6z*nz;
  7200. if(dot<minDot){
  7201. minDot=dot;
  7202. minDotIndex=4;
  7203. }
  7204. if(-dot<minDot){
  7205. minDot=-dot;
  7206. minDotIndex=5;
  7207. }
  7208. //______________________________________________________
  7209. if(minDotIndex==0){// x+ face
  7210. q1x=V2[0]; q1y=V2[1]; q1z=V2[2];//vertex1
  7211. q2x=V2[6]; q2y=V2[7]; q2z=V2[8];//vertex3
  7212. q3x=V2[9]; q3y=V2[10]; q3z=V2[11];//vertex4
  7213. q4x=V2[3]; q4y=V2[4]; q4z=V2[5];//vertex2
  7214. }
  7215. else if(minDotIndex==1){// x- face
  7216. q1x=V2[15]; q1y=V2[16]; q1z=V2[17];//vertex6
  7217. q2x=V2[21]; q2y=V2[22]; q2z=V2[23]; //vertex8
  7218. q3x=V2[18]; q3y=V2[19]; q3z=V2[20];//vertex7
  7219. q4x=V2[12]; q4y=V2[13]; q4z=V2[14];//vertex5
  7220. }
  7221. else if(minDotIndex==2){// y+ face
  7222. q1x=V2[12]; q1y=V2[13]; q1z=V2[14];//vertex5
  7223. q2x=V2[0]; q2y=V2[1]; q2z=V2[2];//vertex1
  7224. q3x=V2[3]; q3y=V2[4]; q3z=V2[5];//vertex2
  7225. q4x=V2[15]; q4y=V2[16]; q4z=V2[17];//vertex6
  7226. }
  7227. else if(minDotIndex==3){// y- face
  7228. q1x=V2[21]; q1y=V2[22]; q1z=V2[23];//vertex8
  7229. q2x=V2[9]; q2y=V2[10]; q2z=V2[11];//vertex4
  7230. q3x=V2[6]; q3y=V2[7]; q3z=V2[8];//vertex3
  7231. q4x=V2[18]; q4y=V2[19]; q4z=V2[20];//vertex7
  7232. }
  7233. else if(minDotIndex==4){// z+ face
  7234. q1x=V2[12]; q1y=V2[13]; q1z=V2[14];//vertex5
  7235. q2x=V2[18]; q2y=V2[19]; q2z=V2[20];//vertex7
  7236. q3x=V2[6]; q3y=V2[7]; q3z=V2[8];//vertex3
  7237. q4x=V2[0]; q4y=V2[1]; q4z=V2[2];//vertex1
  7238. }
  7239. else if(minDotIndex==5){// z- face
  7240. q1x=V2[3]; q1y=V2[4]; q1z=V2[5];//vertex2
  7241. q2x=V2[9]; q2y=V2[10]; q2z=V2[11];//vertex4
  7242. q3x=V2[21]; q3y=V2[22]; q3z=V2[23];//vertex8
  7243. q4x=V2[15]; q4y=V2[16]; q4z=V2[17];//vertex6
  7244. }
  7245. }
  7246. // clip vertices
  7247. var numClipVertices;
  7248. var numAddedClipVertices;
  7249. var index;
  7250. var x1;
  7251. var y1;
  7252. var z1;
  7253. var x2;
  7254. var y2;
  7255. var z2;
  7256. this.clipVertices1[0]=q1x;
  7257. this.clipVertices1[1]=q1y;
  7258. this.clipVertices1[2]=q1z;
  7259. this.clipVertices1[3]=q2x;
  7260. this.clipVertices1[4]=q2y;
  7261. this.clipVertices1[5]=q2z;
  7262. this.clipVertices1[6]=q3x;
  7263. this.clipVertices1[7]=q3y;
  7264. this.clipVertices1[8]=q3z;
  7265. this.clipVertices1[9]=q4x;
  7266. this.clipVertices1[10]=q4y;
  7267. this.clipVertices1[11]=q4z;
  7268. numAddedClipVertices=0;
  7269. x1=this.clipVertices1[9];
  7270. y1=this.clipVertices1[10];
  7271. z1=this.clipVertices1[11];
  7272. dot1=(x1-cx-s1x)*n1x+(y1-cy-s1y)*n1y+(z1-cz-s1z)*n1z;
  7273. //var i = 4;
  7274. //while(i--){
  7275. for(var i=0;i<4;i++){
  7276. index=i*3;
  7277. x2=this.clipVertices1[index];
  7278. y2=this.clipVertices1[index+1];
  7279. z2=this.clipVertices1[index+2];
  7280. dot2=(x2-cx-s1x)*n1x+(y2-cy-s1y)*n1y+(z2-cz-s1z)*n1z;
  7281. if(dot1>0){
  7282. if(dot2>0){
  7283. index=numAddedClipVertices*3;
  7284. numAddedClipVertices++;
  7285. this.clipVertices2[index]=x2;
  7286. this.clipVertices2[index+1]=y2;
  7287. this.clipVertices2[index+2]=z2;
  7288. }else{
  7289. index=numAddedClipVertices*3;
  7290. numAddedClipVertices++;
  7291. t=dot1/(dot1-dot2);
  7292. this.clipVertices2[index]=x1+(x2-x1)*t;
  7293. this.clipVertices2[index+1]=y1+(y2-y1)*t;
  7294. this.clipVertices2[index+2]=z1+(z2-z1)*t;
  7295. }
  7296. }else{
  7297. if(dot2>0){
  7298. index=numAddedClipVertices*3;
  7299. numAddedClipVertices++;
  7300. t=dot1/(dot1-dot2);
  7301. this.clipVertices2[index]=x1+(x2-x1)*t;
  7302. this.clipVertices2[index+1]=y1+(y2-y1)*t;
  7303. this.clipVertices2[index+2]=z1+(z2-z1)*t;
  7304. index=numAddedClipVertices*3;
  7305. numAddedClipVertices++;
  7306. this.clipVertices2[index]=x2;
  7307. this.clipVertices2[index+1]=y2;
  7308. this.clipVertices2[index+2]=z2;
  7309. }
  7310. }
  7311. x1=x2;
  7312. y1=y2;
  7313. z1=z2;
  7314. dot1=dot2;
  7315. }
  7316. numClipVertices=numAddedClipVertices;
  7317. if(numClipVertices==0)return;
  7318. numAddedClipVertices=0;
  7319. index=(numClipVertices-1)*3;
  7320. x1=this.clipVertices2[index];
  7321. y1=this.clipVertices2[index+1];
  7322. z1=this.clipVertices2[index+2];
  7323. dot1=(x1-cx-s2x)*n2x+(y1-cy-s2y)*n2y+(z1-cz-s2z)*n2z;
  7324. //i = numClipVertices;
  7325. //while(i--){
  7326. for(i=0;i<numClipVertices;i++){
  7327. index=i*3;
  7328. x2=this.clipVertices2[index];
  7329. y2=this.clipVertices2[index+1];
  7330. z2=this.clipVertices2[index+2];
  7331. dot2=(x2-cx-s2x)*n2x+(y2-cy-s2y)*n2y+(z2-cz-s2z)*n2z;
  7332. if(dot1>0){
  7333. if(dot2>0){
  7334. index=numAddedClipVertices*3;
  7335. numAddedClipVertices++;
  7336. this.clipVertices1[index]=x2;
  7337. this.clipVertices1[index+1]=y2;
  7338. this.clipVertices1[index+2]=z2;
  7339. }else{
  7340. index=numAddedClipVertices*3;
  7341. numAddedClipVertices++;
  7342. t=dot1/(dot1-dot2);
  7343. this.clipVertices1[index]=x1+(x2-x1)*t;
  7344. this.clipVertices1[index+1]=y1+(y2-y1)*t;
  7345. this.clipVertices1[index+2]=z1+(z2-z1)*t;
  7346. }
  7347. }else{
  7348. if(dot2>0){
  7349. index=numAddedClipVertices*3;
  7350. numAddedClipVertices++;
  7351. t=dot1/(dot1-dot2);
  7352. this.clipVertices1[index]=x1+(x2-x1)*t;
  7353. this.clipVertices1[index+1]=y1+(y2-y1)*t;
  7354. this.clipVertices1[index+2]=z1+(z2-z1)*t;
  7355. index=numAddedClipVertices*3;
  7356. numAddedClipVertices++;
  7357. this.clipVertices1[index]=x2;
  7358. this.clipVertices1[index+1]=y2;
  7359. this.clipVertices1[index+2]=z2;
  7360. }
  7361. }
  7362. x1=x2;
  7363. y1=y2;
  7364. z1=z2;
  7365. dot1=dot2;
  7366. }
  7367. numClipVertices=numAddedClipVertices;
  7368. if(numClipVertices==0)return;
  7369. numAddedClipVertices=0;
  7370. index=(numClipVertices-1)*3;
  7371. x1=this.clipVertices1[index];
  7372. y1=this.clipVertices1[index+1];
  7373. z1=this.clipVertices1[index+2];
  7374. dot1=(x1-cx+s1x)*-n1x+(y1-cy+s1y)*-n1y+(z1-cz+s1z)*-n1z;
  7375. //i = numClipVertices;
  7376. //while(i--){
  7377. for(i=0;i<numClipVertices;i++){
  7378. index=i*3;
  7379. x2=this.clipVertices1[index];
  7380. y2=this.clipVertices1[index+1];
  7381. z2=this.clipVertices1[index+2];
  7382. dot2=(x2-cx+s1x)*-n1x+(y2-cy+s1y)*-n1y+(z2-cz+s1z)*-n1z;
  7383. if(dot1>0){
  7384. if(dot2>0){
  7385. index=numAddedClipVertices*3;
  7386. numAddedClipVertices++;
  7387. this.clipVertices2[index]=x2;
  7388. this.clipVertices2[index+1]=y2;
  7389. this.clipVertices2[index+2]=z2;
  7390. }else{
  7391. index=numAddedClipVertices*3;
  7392. numAddedClipVertices++;
  7393. t=dot1/(dot1-dot2);
  7394. this.clipVertices2[index]=x1+(x2-x1)*t;
  7395. this.clipVertices2[index+1]=y1+(y2-y1)*t;
  7396. this.clipVertices2[index+2]=z1+(z2-z1)*t;
  7397. }
  7398. }else{
  7399. if(dot2>0){
  7400. index=numAddedClipVertices*3;
  7401. numAddedClipVertices++;
  7402. t=dot1/(dot1-dot2);
  7403. this.clipVertices2[index]=x1+(x2-x1)*t;
  7404. this.clipVertices2[index+1]=y1+(y2-y1)*t;
  7405. this.clipVertices2[index+2]=z1+(z2-z1)*t;
  7406. index=numAddedClipVertices*3;
  7407. numAddedClipVertices++;
  7408. this.clipVertices2[index]=x2;
  7409. this.clipVertices2[index+1]=y2;
  7410. this.clipVertices2[index+2]=z2;
  7411. }
  7412. }
  7413. x1=x2;
  7414. y1=y2;
  7415. z1=z2;
  7416. dot1=dot2;
  7417. }
  7418. numClipVertices=numAddedClipVertices;
  7419. if(numClipVertices==0)return;
  7420. numAddedClipVertices=0;
  7421. index=(numClipVertices-1)*3;
  7422. x1=this.clipVertices2[index];
  7423. y1=this.clipVertices2[index+1];
  7424. z1=this.clipVertices2[index+2];
  7425. dot1=(x1-cx+s2x)*-n2x+(y1-cy+s2y)*-n2y+(z1-cz+s2z)*-n2z;
  7426. //i = numClipVertices;
  7427. //while(i--){
  7428. for(i=0;i<numClipVertices;i++){
  7429. index=i*3;
  7430. x2=this.clipVertices2[index];
  7431. y2=this.clipVertices2[index+1];
  7432. z2=this.clipVertices2[index+2];
  7433. dot2=(x2-cx+s2x)*-n2x+(y2-cy+s2y)*-n2y+(z2-cz+s2z)*-n2z;
  7434. if(dot1>0){
  7435. if(dot2>0){
  7436. index=numAddedClipVertices*3;
  7437. numAddedClipVertices++;
  7438. this.clipVertices1[index]=x2;
  7439. this.clipVertices1[index+1]=y2;
  7440. this.clipVertices1[index+2]=z2;
  7441. }else{
  7442. index=numAddedClipVertices*3;
  7443. numAddedClipVertices++;
  7444. t=dot1/(dot1-dot2);
  7445. this.clipVertices1[index]=x1+(x2-x1)*t;
  7446. this.clipVertices1[index+1]=y1+(y2-y1)*t;
  7447. this.clipVertices1[index+2]=z1+(z2-z1)*t;
  7448. }
  7449. }else{
  7450. if(dot2>0){
  7451. index=numAddedClipVertices*3;
  7452. numAddedClipVertices++;
  7453. t=dot1/(dot1-dot2);
  7454. this.clipVertices1[index]=x1+(x2-x1)*t;
  7455. this.clipVertices1[index+1]=y1+(y2-y1)*t;
  7456. this.clipVertices1[index+2]=z1+(z2-z1)*t;
  7457. index=numAddedClipVertices*3;
  7458. numAddedClipVertices++;
  7459. this.clipVertices1[index]=x2;
  7460. this.clipVertices1[index+1]=y2;
  7461. this.clipVertices1[index+2]=z2;
  7462. }
  7463. }
  7464. x1=x2;
  7465. y1=y2;
  7466. z1=z2;
  7467. dot1=dot2;
  7468. }
  7469. numClipVertices=numAddedClipVertices;
  7470. if(swap){
  7471. var tb=b1;
  7472. b1=b2;
  7473. b2=tb;
  7474. }
  7475. if(numClipVertices==0)return;
  7476. var flipped=b1!=shape1;
  7477. if(numClipVertices>4){
  7478. x1=(q1x+q2x+q3x+q4x)*0.25;
  7479. y1=(q1y+q2y+q3y+q4y)*0.25;
  7480. z1=(q1z+q2z+q3z+q4z)*0.25;
  7481. n1x=q1x-x1;
  7482. n1y=q1y-y1;
  7483. n1z=q1z-z1;
  7484. n2x=q2x-x1;
  7485. n2y=q2y-y1;
  7486. n2z=q2z-z1;
  7487. var index1=0;
  7488. var index2=0;
  7489. var index3=0;
  7490. var index4=0;
  7491. var maxDot=-this.INF;
  7492. minDot=this.INF;
  7493. //i = numClipVertices;
  7494. //while(i--){
  7495. for(i=0;i<numClipVertices;i++){
  7496. this.used[i]=false;
  7497. index=i*3;
  7498. x1=this.clipVertices1[index];
  7499. y1=this.clipVertices1[index+1];
  7500. z1=this.clipVertices1[index+2];
  7501. dot=x1*n1x+y1*n1y+z1*n1z;
  7502. if(dot<minDot){
  7503. minDot=dot;
  7504. index1=i;
  7505. }
  7506. if(dot>maxDot){
  7507. maxDot=dot;
  7508. index3=i;
  7509. }
  7510. }
  7511. this.used[index1]=true;
  7512. this.used[index3]=true;
  7513. maxDot=-this.INF;
  7514. minDot=this.INF;
  7515. //i = numClipVertices;
  7516. //while(i--){
  7517. for(i=0;i<numClipVertices;i++){
  7518. if(this.used[i])continue;
  7519. index=i*3;
  7520. x1=this.clipVertices1[index];
  7521. y1=this.clipVertices1[index+1];
  7522. z1=this.clipVertices1[index+2];
  7523. dot=x1*n2x+y1*n2y+z1*n2z;
  7524. if(dot<minDot){
  7525. minDot=dot;
  7526. index2=i;
  7527. }
  7528. if(dot>maxDot){
  7529. maxDot=dot;
  7530. index4=i;
  7531. }
  7532. }
  7533. index=index1*3;
  7534. x1=this.clipVertices1[index];
  7535. y1=this.clipVertices1[index+1];
  7536. z1=this.clipVertices1[index+2];
  7537. dot=(x1-cx)*nx+(y1-cy)*ny+(z1-cz)*nz;
  7538. if(dot<0) manifold.addPoint(x1,y1,z1,nx,ny,nz,dot,flipped);
  7539. index=index2*3;
  7540. x1=this.clipVertices1[index];
  7541. y1=this.clipVertices1[index+1];
  7542. z1=this.clipVertices1[index+2];
  7543. dot=(x1-cx)*nx+(y1-cy)*ny+(z1-cz)*nz;
  7544. if(dot<0) manifold.addPoint(x1,y1,z1,nx,ny,nz,dot,flipped);
  7545. index=index3*3;
  7546. x1=this.clipVertices1[index];
  7547. y1=this.clipVertices1[index+1];
  7548. z1=this.clipVertices1[index+2];
  7549. dot=(x1-cx)*nx+(y1-cy)*ny+(z1-cz)*nz;
  7550. if(dot<0) manifold.addPoint(x1,y1,z1,nx,ny,nz,dot,flipped);
  7551. index=index4*3;
  7552. x1=this.clipVertices1[index];
  7553. y1=this.clipVertices1[index+1];
  7554. z1=this.clipVertices1[index+2];
  7555. dot=(x1-cx)*nx+(y1-cy)*ny+(z1-cz)*nz;
  7556. if(dot<0) manifold.addPoint(x1,y1,z1,nx,ny,nz,dot,flipped);
  7557. }else{
  7558. //i = numClipVertices;
  7559. //while(i--){
  7560. for(i=0;i<numClipVertices;i++){
  7561. index=i*3;
  7562. x1=this.clipVertices1[index];
  7563. y1=this.clipVertices1[index+1];
  7564. z1=this.clipVertices1[index+2];
  7565. dot=(x1-cx)*nx+(y1-cy)*ny+(z1-cz)*nz;
  7566. if(dot<0)manifold.addPoint(x1,y1,z1,nx,ny,nz,dot,flipped);
  7567. }
  7568. }
  7569. }
  7570. /**
  7571. * A collision detector which detects collisions between sphere and box.
  7572. * @author saharan
  7573. */
  7574. OIMO.SphereBoxCollisionDetector = function(flip){
  7575. OIMO.CollisionDetector.call( this );
  7576. this.flip=flip;
  7577. }
  7578. OIMO.SphereBoxCollisionDetector.prototype = Object.create( OIMO.CollisionDetector.prototype );
  7579. OIMO.SphereBoxCollisionDetector.prototype.detectCollision = function(shape1,shape2,manifold){
  7580. var s;
  7581. var b;
  7582. if(this.flip){
  7583. s=(shape2);
  7584. b=(shape1);
  7585. }else{
  7586. s=(shape1);
  7587. b=(shape2);
  7588. }
  7589. var D = b.dimentions;
  7590. var ps=s.position;
  7591. var psx=ps.x;
  7592. var psy=ps.y;
  7593. var psz=ps.z;
  7594. var pb=b.position;
  7595. var pbx=pb.x;
  7596. var pby=pb.y;
  7597. var pbz=pb.z;
  7598. var rad=s.radius;
  7599. var hw=b.halfWidth;
  7600. var hh=b.halfHeight;
  7601. var hd=b.halfDepth;
  7602. var dx=psx-pbx;
  7603. var dy=psy-pby;
  7604. var dz=psz-pbz;
  7605. var sx=D[0]*dx+D[1]*dy+D[2]*dz;
  7606. var sy=D[3]*dx+D[4]*dy+D[5]*dz;
  7607. var sz=D[6]*dx+D[7]*dy+D[8]*dz;
  7608. var cx;
  7609. var cy;
  7610. var cz;
  7611. var len;
  7612. var invLen;
  7613. var overlap=0;
  7614. if(sx>hw){
  7615. sx=hw;
  7616. }else if(sx<-hw){
  7617. sx=-hw;
  7618. }else{
  7619. overlap=1;
  7620. }
  7621. if(sy>hh){
  7622. sy=hh;
  7623. }else if(sy<-hh){
  7624. sy=-hh;
  7625. }else{
  7626. overlap|=2;
  7627. }
  7628. if(sz>hd){
  7629. sz=hd;
  7630. }else if(sz<-hd){
  7631. sz=-hd;
  7632. }else{
  7633. overlap|=4;
  7634. }
  7635. if(overlap==7){
  7636. // center of sphere is in the box
  7637. if(sx<0){
  7638. dx=hw+sx;
  7639. }else{
  7640. dx=hw-sx;
  7641. }
  7642. if(sy<0){
  7643. dy=hh+sy;
  7644. }else{
  7645. dy=hh-sy;
  7646. }
  7647. if(sz<0){
  7648. dz=hd+sz;
  7649. }else{
  7650. dz=hd-sz;
  7651. }
  7652. if(dx<dy){
  7653. if(dx<dz){
  7654. len=dx-hw;
  7655. if(sx<0){
  7656. sx=-hw;
  7657. dx=D[0];
  7658. dy=D[1];
  7659. dz=D[2];
  7660. }else{
  7661. sx=hw;
  7662. dx=-D[0];
  7663. dy=-D[1];
  7664. dz=-D[2];
  7665. }
  7666. }else{
  7667. len=dz-hd;
  7668. if(sz<0){
  7669. sz=-hd;
  7670. dx=D[6];
  7671. dy=D[7];
  7672. dz=D[8];
  7673. }else{
  7674. sz=hd;
  7675. dx=-D[6];
  7676. dy=-D[7];
  7677. dz=-D[8];
  7678. }
  7679. }
  7680. }else{
  7681. if(dy<dz){
  7682. len=dy-hh;
  7683. if(sy<0){
  7684. sy=-hh;
  7685. dx=D[3];
  7686. dy=D[4];
  7687. dz=D[5];
  7688. }else{
  7689. sy=hh;
  7690. dx=-D[3];
  7691. dy=-D[4];
  7692. dz=-D[5];
  7693. }
  7694. }else{
  7695. len=dz-hd;
  7696. if(sz<0){
  7697. sz=-hd;
  7698. dx=D[6];
  7699. dy=D[7];
  7700. dz=D[8];
  7701. }else{
  7702. sz=hd;
  7703. dx=-D[6];
  7704. dy=-D[7];
  7705. dz=-D[8];
  7706. }
  7707. }
  7708. }
  7709. cx=pbx+sx*D[0]+sy*D[3]+sz*D[6];
  7710. cy=pby+sx*D[1]+sy*D[4]+sz*D[7];
  7711. cz=pbz+sx*D[2]+sy*D[5]+sz*D[8];
  7712. manifold.addPoint(psx+rad*dx,psy+rad*dy,psz+rad*dz,dx,dy,dz,len-rad,this.flip);
  7713. }else{
  7714. cx=pbx+sx*D[0]+sy*D[3]+sz*D[6];
  7715. cy=pby+sx*D[1]+sy*D[4]+sz*D[7];
  7716. cz=pbz+sx*D[2]+sy*D[5]+sz*D[8];
  7717. dx=cx-ps.x;
  7718. dy=cy-ps.y;
  7719. dz=cz-ps.z;
  7720. len=dx*dx+dy*dy+dz*dz;
  7721. if(len>0&&len<rad*rad){
  7722. len=Math.sqrt(len);
  7723. invLen=1/len;
  7724. dx*=invLen;
  7725. dy*=invLen;
  7726. dz*=invLen;
  7727. manifold.addPoint(psx+rad*dx,psy+rad*dy,psz+rad*dz,dx,dy,dz,len-rad,this.flip);
  7728. }
  7729. }
  7730. }
  7731. /**
  7732. * A collision detector which detects collisions between two spheres.
  7733. * @author saharan
  7734. */
  7735. OIMO.SphereSphereCollisionDetector = function(){
  7736. OIMO.CollisionDetector.call( this );
  7737. }
  7738. OIMO.SphereSphereCollisionDetector.prototype = Object.create( OIMO.CollisionDetector.prototype );
  7739. OIMO.SphereSphereCollisionDetector.prototype.detectCollision = function(shape1,shape2,manifold){
  7740. var s1=(shape1);
  7741. var s2=(shape2);
  7742. var p1=s1.position;
  7743. var p2=s2.position;
  7744. var dx=p2.x-p1.x;
  7745. var dy=p2.y-p1.y;
  7746. var dz=p2.z-p1.z;
  7747. var len=dx*dx+dy*dy+dz*dz;
  7748. var r1=s1.radius;
  7749. var r2=s2.radius;
  7750. var rad=r1+r2;
  7751. if(len>0&&len<rad*rad){
  7752. len=Math.sqrt(len);
  7753. var invLen=1/len;
  7754. dx*=invLen;
  7755. dy*=invLen;
  7756. dz*=invLen;
  7757. manifold.addPoint(p1.x+dx*r1,p1.y+dy*r1,p1.z+dz*r1,dx,dy,dz,len-rad,false);
  7758. }
  7759. }
  7760. /**
  7761. * An axis-aligned bounding box.
  7762. * @author saharan
  7763. */
  7764. OIMO.AABB = function(minX,maxX,minY,maxY,minZ,maxZ){
  7765. this.minX=minX || 0;
  7766. this.maxX=maxX || 0;
  7767. this.minY=minY || 0;
  7768. this.maxY=maxY || 0;
  7769. this.minZ=minZ || 0;
  7770. this.maxZ=maxZ || 0;
  7771. }
  7772. OIMO.AABB.prototype = {
  7773. constructor: OIMO.AABB,
  7774. init:function(minX,maxX,minY,maxY,minZ,maxZ){
  7775. this.minX=minX;
  7776. this.maxX=maxX;
  7777. this.minY=minY;
  7778. this.maxY=maxY;
  7779. this.minZ=minZ;
  7780. this.maxZ=maxZ;
  7781. },
  7782. /**
  7783. * Set this AABB to the combined AABB of aabb1 and aabb2.
  7784. * @param aabb1
  7785. * @param aabb2
  7786. */
  7787. combine:function(aabb1,aabb2){
  7788. this.minX = (aabb1.minX<aabb2.minX) ? aabb1.minX : aabb2.minX;
  7789. this.maxX = (aabb1.maxX>aabb2.maxX) ? aabb1.maxX : aabb2.maxX;
  7790. this.minY = (aabb1.minY<aabb2.minY) ? aabb1.minY : aabb2.minY;
  7791. this.maxY = (aabb1.maxY>aabb2.maxY) ? aabb1.maxY : aabb2.maxY;
  7792. this.minZ = (aabb1.minZ<aabb2.minZ) ? aabb1.minZ : aabb2.minZ;
  7793. this.maxZ = (aabb1.maxZ>aabb2.maxZ) ? aabb1.maxZ : aabb2.maxZ;
  7794. /*
  7795. var margin=0;
  7796. this.minX-=margin;
  7797. this.minY-=margin;
  7798. this.minZ-=margin;
  7799. this.maxX+=margin;
  7800. this.maxY+=margin;
  7801. this.maxZ+=margin;
  7802. */
  7803. },
  7804. /**
  7805. * Get the surface area.
  7806. * @return
  7807. */
  7808. surfaceArea:function(){
  7809. var h=this.maxY-this.minY;
  7810. var d=this.maxZ-this.minZ;
  7811. return 2*((this.maxX-this.minX)*(h+d)+h*d);
  7812. },
  7813. /**
  7814. * Get whether the AABB intersects with the point or not.
  7815. * @param x
  7816. * @param y
  7817. * @param z
  7818. * @return
  7819. */
  7820. intersectsWithPoint:function(x,y,z){
  7821. return x>=this.minX&&x<=this.maxX&&y>=this.minY&&y<=this.maxY&&z>=this.minZ&&z<=this.maxZ;
  7822. }
  7823. }
  7824. /**
  7825. * A proxy is used for broad-phase collecting pairs that can be colliding.
  7826. */
  7827. OIMO.Proxy = function(shape){
  7828. // The parent shape.
  7829. this.shape=shape;
  7830. // The axis-aligned bounding box.
  7831. this.aabb=shape.aabb;
  7832. };
  7833. OIMO.Proxy.prototype = {
  7834. constructor: OIMO.Proxy,
  7835. /**
  7836. * Update the proxy.
  7837. */
  7838. update:function(){
  7839. throw new Error("Inheritance error.");
  7840. }
  7841. }
  7842. /**
  7843. * A basic implementation of proxies.
  7844. * @author saharan
  7845. */
  7846. OIMO.BasicProxy = function(shape){
  7847. OIMO.Proxy.call( this, shape );
  7848. }
  7849. OIMO.BasicProxy.prototype = Object.create( OIMO.Proxy.prototype );
  7850. OIMO.BasicProxy.prototype.update = function () {
  7851. }
  7852. /**
  7853. * The broad-phase is used for collecting all possible pairs for collision.
  7854. */
  7855. OIMO.BroadPhase = function(){
  7856. this.types = 0x0;
  7857. this.numPairChecks=0;
  7858. this.numPairs=0;
  7859. this.bufferSize=256;
  7860. this.pairs=[];// vector
  7861. this.pairs.length = this.bufferSize;
  7862. var i = this.bufferSize;
  7863. while(i--){
  7864. this.pairs[i] = new OIMO.Pair();
  7865. }
  7866. }
  7867. OIMO.BroadPhase.prototype = {
  7868. constructor: OIMO.BroadPhase,
  7869. /**
  7870. * Create a new proxy.
  7871. * @param shape
  7872. * @return
  7873. */
  7874. createProxy:function(shape){
  7875. throw new Error("Inheritance error.");
  7876. },
  7877. /**
  7878. * Add the proxy into the broad-phase.
  7879. * @param proxy
  7880. */
  7881. addProxy:function(proxy){
  7882. throw new Error("Inheritance error.");
  7883. },
  7884. /**
  7885. * Remove the proxy from the broad-phase.
  7886. * @param proxy
  7887. */
  7888. removeProxy:function(proxy){
  7889. throw new Error("Inheritance error.");
  7890. },
  7891. /**
  7892. * Returns whether the pair is available or not.
  7893. * @param s1
  7894. * @param s2
  7895. * @return
  7896. */
  7897. isAvailablePair:function(s1,s2){
  7898. var b1=s1.parent;
  7899. var b2=s2.parent;
  7900. if( b1==b2 || // same parents
  7901. (!b1.isDynamic&&!b2.isDynamic) || // static or kinematic object
  7902. (s1.belongsTo&s2.collidesWith)==0 ||
  7903. (s2.belongsTo&s1.collidesWith)==0 // collision filtering
  7904. ){ return false; }
  7905. var js;
  7906. if(b1.numJoints<b2.numJoints) js=b1.jointLink;
  7907. else js=b2.jointLink;
  7908. while(js!=null){
  7909. var joint=js.joint;
  7910. if( !joint.allowCollision && (joint.body1==b1&&joint.body2==b2 || joint.body1==b2&&joint.body2==b1) ){ return false; }
  7911. js=js.next;
  7912. }
  7913. return true;
  7914. },
  7915. // Detect overlapping pairs.
  7916. detectPairs:function(){
  7917. while(this.numPairs>0){
  7918. var pair=this.pairs[--this.numPairs];
  7919. pair.shape1=null;
  7920. pair.shape2=null;
  7921. }
  7922. this.numPairChecks=0;
  7923. this.collectPairs();
  7924. },
  7925. collectPairs:function(){
  7926. throw new Error("Inheritance error.");
  7927. },
  7928. addPair:function(s1,s2){
  7929. if(this.numPairs==this.bufferSize){ // expand pair buffer
  7930. var newBufferSize=this.bufferSize<<1;
  7931. //var newBufferSize=this.bufferSize*2;
  7932. var newPairs=[];// vector
  7933. newPairs.length = this.bufferSize;
  7934. //var i = this.bufferSize;
  7935. //var j;
  7936. //while(i--){
  7937. for(var i=0, j=this.bufferSize;i<j;i++){
  7938. newPairs[i]=this.pairs[i];
  7939. }
  7940. i = this.newBufferSize;
  7941. //j = this.bufferSize;
  7942. //while(i-- >= j){
  7943. for(i=this.bufferSize, j=newBufferSize;i<j;i++){
  7944. newPairs[i]=new OIMO.Pair();
  7945. }
  7946. this.pairs=newPairs;
  7947. this.bufferSize=newBufferSize;
  7948. }
  7949. var pair=this.pairs[this.numPairs++];
  7950. pair.shape1=s1;
  7951. pair.shape2=s2;
  7952. }
  7953. }
  7954. /**
  7955. * A broad-phase algorithm with brute-force search.
  7956. * This always checks for all possible pairs.
  7957. */
  7958. OIMO.BruteForceBroadPhase = function(){
  7959. OIMO.BroadPhase.call( this);
  7960. this.types = 0x1;
  7961. this.numProxies=0;
  7962. this.maxProxies = 256;
  7963. this.proxies = [];// Vector !
  7964. this.proxies.length = 256;
  7965. }
  7966. OIMO.BruteForceBroadPhase.prototype = Object.create( OIMO.BroadPhase.prototype );
  7967. OIMO.BruteForceBroadPhase.prototype.createProxy = function (shape) {
  7968. return new OIMO.BasicProxy(shape);
  7969. }
  7970. OIMO.BruteForceBroadPhase.prototype.addProxy = function (proxy) {
  7971. if(this.numProxies==this.maxProxies){
  7972. //this.maxProxies<<=1;
  7973. this.maxProxies*=2;
  7974. var newProxies=[];
  7975. newProxies.length = this.maxProxies;
  7976. var i = this.numProxies;
  7977. while(i--){
  7978. //for(var i=0, l=this.numProxies;i<l;i++){
  7979. newProxies[i]=this.proxies[i];
  7980. }
  7981. this.proxies=newProxies;
  7982. }
  7983. this.proxies[this.numProxies++]=proxy;
  7984. }
  7985. OIMO.BruteForceBroadPhase.prototype.removeProxy = function (proxy) {
  7986. var i = this.numProxies;
  7987. while(i--){
  7988. //for(var i=0, l=this.numProxies;i<l;i++){
  7989. if(this.proxies[i]==proxy){
  7990. this.proxies[i]=this.proxies[--this.numProxies];
  7991. this.proxies[this.numProxies]=null;
  7992. return;
  7993. }
  7994. }
  7995. }
  7996. OIMO.BruteForceBroadPhase.prototype.collectPairs = function () {
  7997. this.numPairChecks=this.numProxies*(this.numProxies-1)>>1;
  7998. //this.numPairChecks=this.numProxies*(this.numProxies-1)*0.5;
  7999. var i = this.numProxies;
  8000. while(i--){
  8001. //for(var i=0, l=this.numProxies;i<l;i++){
  8002. var p1=this.proxies[i];
  8003. var b1=p1.aabb;
  8004. var s1=p1.shape;
  8005. var j = this.numProxies;
  8006. while(j--){ if(j!==i){
  8007. //for(var j=i+1, m=this.numProxies;j<m;j++){
  8008. var p2=this.proxies[j];
  8009. var b2=p2.aabb;
  8010. var s2=p2.shape;
  8011. if(b1.maxX<b2.minX||b1.minX>b2.maxX|| b1.maxY<b2.minY||b1.minY>b2.maxY|| b1.maxZ<b2.minZ||b1.minZ>b2.maxZ|| !this.isAvailablePair(s1,s2) ){
  8012. continue;
  8013. }
  8014. this.addPair(s1,s2);
  8015. }}
  8016. }
  8017. }
  8018. /**
  8019. * A pair of shapes that may collide.
  8020. * @author saharan
  8021. */
  8022. OIMO.Pair = function(){
  8023. // The first shape.
  8024. this.shape1=null;
  8025. // The second shape.
  8026. this.shape2=null;
  8027. };
  8028. /**
  8029. * A projection axis for sweep and prune broad-phase.
  8030. * @author saharan
  8031. */
  8032. OIMO.SAPAxis = function(){
  8033. this.numElements=0;
  8034. this.bufferSize=256;
  8035. this.elements=[];
  8036. this.elements.length = this.bufferSize;
  8037. this.stack=new OIMO_ARRAY_TYPE(64);
  8038. };
  8039. OIMO.SAPAxis.prototype = {
  8040. constructor: OIMO.SAPAxis,
  8041. addElements:function(min,max){
  8042. if(this.numElements+2>=this.bufferSize){
  8043. //this.bufferSize<<=1;
  8044. this.bufferSize*=2;
  8045. var newElements=[];
  8046. var i = this.numElements;
  8047. while(i--){
  8048. //for(var i=0, l=this.numElements; i<l; i++){
  8049. newElements[i]=this.elements[i];
  8050. }
  8051. }
  8052. this.elements[this.numElements++]=min;
  8053. this.elements[this.numElements++]=max;
  8054. },
  8055. removeElements:function(min,max){
  8056. var minIndex=-1;
  8057. var maxIndex=-1;
  8058. for(var i=0, l=this.numElements; i<l; i++){
  8059. var e=this.elements[i];
  8060. if(e==min||e==max){
  8061. if(minIndex==-1){
  8062. minIndex=i;
  8063. }else{
  8064. maxIndex=i;
  8065. break;
  8066. }
  8067. }
  8068. }
  8069. for(i=minIndex+1, l=maxIndex; i<l; i++){
  8070. this.elements[i-1]=this.elements[i];
  8071. }
  8072. for(i=maxIndex+1, l=this.numElements; i<l; i++){
  8073. this.elements[i-2]=this.elements[i];
  8074. }
  8075. this.elements[--this.numElements]=null;
  8076. this.elements[--this.numElements]=null;
  8077. },
  8078. sort:function(){
  8079. var count=0;
  8080. var threshold=1;
  8081. while((this.numElements>>threshold)!=0)threshold++;
  8082. threshold=threshold*this.numElements>>2;
  8083. count=0;
  8084. var giveup=false;
  8085. var elements=this.elements;
  8086. for(var i=1, l=this.numElements; i<l; i++){ // try insertion sort
  8087. var tmp=elements[i];
  8088. var pivot=tmp.value;
  8089. var tmp2=elements[i-1];
  8090. if(tmp2.value>pivot){
  8091. var j=i;
  8092. do{
  8093. elements[j]=tmp2;
  8094. if(--j==0)break;
  8095. tmp2=elements[j-1];
  8096. }while(tmp2.value>pivot);
  8097. elements[j]=tmp;
  8098. count+=i-j;
  8099. if(count>threshold){
  8100. giveup=true; // stop and use quick sort
  8101. break;
  8102. }
  8103. }
  8104. }
  8105. if(!giveup)return;
  8106. count=2;var stack=this.stack;
  8107. stack[0]=0;
  8108. stack[1]=this.numElements-1;
  8109. while(count>0){
  8110. var right=stack[--count];
  8111. var left=stack[--count];
  8112. var diff=right-left;
  8113. if(diff>16){ // quick sort
  8114. //var mid=left+(diff>>1);
  8115. var mid=left+(Math.floor(diff*0.5));
  8116. tmp=elements[mid];
  8117. elements[mid]=elements[right];
  8118. elements[right]=tmp;
  8119. pivot=tmp.value;
  8120. i=left-1;
  8121. j=right;
  8122. while(true){
  8123. var ei;
  8124. var ej;
  8125. do{ ei=elements[++i]; }while(ei.value<pivot);
  8126. do{ ej=elements[--j]; }while(pivot<ej.value&&j!=left);
  8127. if(i>=j)break;
  8128. elements[i]=ej;
  8129. elements[j]=ei;
  8130. }
  8131. elements[right]=elements[i];
  8132. elements[i]=tmp;
  8133. if(i-left>right-i){
  8134. stack[count++]=left;
  8135. stack[count++]=i-1;
  8136. stack[count++]=i+1;
  8137. stack[count++]=right;
  8138. }else{
  8139. stack[count++]=i+1;
  8140. stack[count++]=right;
  8141. stack[count++]=left;
  8142. stack[count++]=i-1;
  8143. }
  8144. }else{
  8145. for(i=left+1;i<=right;i++){
  8146. tmp=elements[i];
  8147. pivot=tmp.value;
  8148. tmp2=elements[i-1];
  8149. if(tmp2.value>pivot){
  8150. j=i;
  8151. do{
  8152. elements[j]=tmp2;
  8153. if(--j==0)break;
  8154. tmp2=elements[j-1];
  8155. }while(tmp2.value>pivot);
  8156. elements[j]=tmp;
  8157. }
  8158. }
  8159. }
  8160. }
  8161. },
  8162. calculateTestCount:function(){
  8163. var num=1;
  8164. var sum=0;
  8165. for(var i=1, l=this.numElements; i<l; i++){
  8166. if(this.elements[i].max){
  8167. num--;
  8168. }else{
  8169. sum+=num;
  8170. num++;
  8171. }
  8172. }
  8173. return sum;
  8174. }
  8175. }
  8176. /**
  8177. * A broad-phase collision detection algorithm using sweep and prune.
  8178. * @author saharan
  8179. */
  8180. OIMO.SAPBroadPhase = function(){
  8181. OIMO.BroadPhase.call( this);
  8182. this.types = 0x2;
  8183. this.numElementsD = 0;
  8184. this.numElementsS = 0;
  8185. // dynamic proxies
  8186. this.axesD = [];// vector !
  8187. // static or sleeping proxies
  8188. this.axesS = [];// vector !
  8189. this.axesD.length = 3;
  8190. this.axesS.length = 3;
  8191. this.axesD[0]=new OIMO.SAPAxis();
  8192. this.axesD[1]=new OIMO.SAPAxis();
  8193. this.axesD[2]=new OIMO.SAPAxis();
  8194. this.axesS[0]=new OIMO.SAPAxis();
  8195. this.axesS[1]=new OIMO.SAPAxis();
  8196. this.axesS[2]=new OIMO.SAPAxis();
  8197. this.index1=0;
  8198. this.index2=1;
  8199. }
  8200. OIMO.SAPBroadPhase.prototype = Object.create( OIMO.BroadPhase.prototype );
  8201. OIMO.SAPBroadPhase.prototype.createProxy = function (shape) {
  8202. return new OIMO.SAPProxy(this,shape);
  8203. }
  8204. OIMO.SAPBroadPhase.prototype.addProxy = function (proxy) {
  8205. var p=(proxy);
  8206. if(p.isDynamic()){
  8207. this.axesD[0].addElements(p.min[0],p.max[0]);
  8208. this.axesD[1].addElements(p.min[1],p.max[1]);
  8209. this.axesD[2].addElements(p.min[2],p.max[2]);
  8210. p.belongsTo=1;
  8211. this.numElementsD+=2;
  8212. }else{
  8213. this.axesS[0].addElements(p.min[0],p.max[0]);
  8214. this.axesS[1].addElements(p.min[1],p.max[1]);
  8215. this.axesS[2].addElements(p.min[2],p.max[2]);
  8216. p.belongsTo=2;
  8217. this.numElementsS+=2;
  8218. }
  8219. }
  8220. OIMO.SAPBroadPhase.prototype.removeProxy = function (proxy) {
  8221. var p=(proxy);
  8222. if(p.belongsTo==0)return;
  8223. switch(p.belongsTo){
  8224. case 1:
  8225. this.axesD[0].removeElements(p.min[0],p.max[0]);
  8226. this.axesD[1].removeElements(p.min[1],p.max[1]);
  8227. this.axesD[2].removeElements(p.min[2],p.max[2]);
  8228. this.numElementsD-=2;
  8229. break;
  8230. case 2:
  8231. this.axesS[0].removeElements(p.min[0],p.max[0]);
  8232. this.axesS[1].removeElements(p.min[1],p.max[1]);
  8233. this.axesS[2].removeElements(p.min[2],p.max[2]);
  8234. this.numElementsS-=2;
  8235. break;
  8236. }
  8237. p.belongsTo=0;
  8238. }
  8239. OIMO.SAPBroadPhase.prototype.collectPairs = function () {
  8240. if(this.numElementsD==0)return;
  8241. var axis1=this.axesD[this.index1];
  8242. var axis2=this.axesD[this.index2];
  8243. axis1.sort();
  8244. axis2.sort();
  8245. var count1=axis1.calculateTestCount();
  8246. var count2=axis2.calculateTestCount();
  8247. var elementsD;
  8248. var elementsS;
  8249. if(count1<=count2){// select the best axis
  8250. axis2=this.axesS[this.index1];
  8251. axis2.sort();
  8252. elementsD=axis1.elements;
  8253. elementsS=axis2.elements;
  8254. }else{
  8255. axis1=this.axesS[this.index2];
  8256. axis1.sort();
  8257. elementsD=axis2.elements;
  8258. elementsS=axis1.elements;
  8259. this.index1^=this.index2;
  8260. this.index2^=this.index1;
  8261. this.index1^=this.index2;
  8262. }
  8263. var activeD;
  8264. var activeS;
  8265. var p=0;
  8266. var q=0;
  8267. while(p<this.numElementsD){
  8268. var e1;
  8269. var dyn;
  8270. if(q==this.numElementsS){
  8271. e1=elementsD[p];
  8272. dyn=true;
  8273. p++;
  8274. }else{
  8275. var d=elementsD[p];
  8276. var s=elementsS[q];
  8277. if(d.value<s.value){
  8278. e1=d;
  8279. dyn=true;
  8280. p++;
  8281. }else{
  8282. e1=s;
  8283. dyn=false;
  8284. q++;
  8285. }
  8286. }
  8287. if(!e1.max){
  8288. var s1=e1.proxy.shape;var min1=e1.min1.value;var max1=e1.max1.value;var min2=e1.min2.value;var max2=e1.max2.value;
  8289. for(var e2=activeD;e2!=null;e2=e2.pair){// test for dynamic
  8290. var s2=e2.proxy.shape;
  8291. this.numPairChecks++;
  8292. if( min1>e2.max1.value||max1<e2.min1.value|| min2>e2.max2.value||max2<e2.min2.value|| !this.isAvailablePair(s1,s2) ){ continue; }
  8293. this.addPair(s1,s2);
  8294. }
  8295. if(dyn){
  8296. for(e2=activeS;e2!=null;e2=e2.pair){// test for static
  8297. s2=e2.proxy.shape;
  8298. this.numPairChecks++;
  8299. if( min1>e2.max1.value||max1<e2.min1.value|| min2>e2.max2.value||max2<e2.min2.value|| !this.isAvailablePair(s1,s2) ){ continue; }
  8300. this.addPair(s1,s2);
  8301. }
  8302. e1.pair=activeD;
  8303. activeD=e1;
  8304. }else{
  8305. e1.pair=activeS;
  8306. activeS=e1;
  8307. }
  8308. }else{
  8309. var min=e1.pair;
  8310. if(dyn){
  8311. if(min==activeD){
  8312. activeD=activeD.pair;
  8313. continue;
  8314. }else{
  8315. e1=activeD;
  8316. }
  8317. }else{
  8318. if(min==activeS){
  8319. activeS=activeS.pair;
  8320. continue;
  8321. }else{
  8322. e1=activeS;
  8323. }
  8324. }
  8325. do{
  8326. e2=e1.pair;
  8327. if(e2===min){
  8328. e1.pair=e2.pair;
  8329. break;
  8330. }
  8331. e1=e2;
  8332. }while(e1!==null);
  8333. }
  8334. }
  8335. this.index2=(this.index1|this.index2)^3;
  8336. }
  8337. /**
  8338. * An element of proxies.
  8339. * @author saharan
  8340. */
  8341. OIMO.SAPElement = function(proxy,max){
  8342. // The parent proxy
  8343. this.proxy=proxy;
  8344. // The pair element.
  8345. this.pair = null;
  8346. // The minimum element on other axis.
  8347. this.min1 = null;
  8348. // The maximum element on other axis.
  8349. this.max1 = null;
  8350. // The minimum element on other axis.
  8351. this.min2 = null;
  8352. // The maximum element on other axis.
  8353. this.max2 = null;
  8354. // Whether the element has maximum value or not.
  8355. this.max = max;
  8356. // The value of the element.
  8357. this.value = 0;
  8358. };
  8359. /**
  8360. * A proxy for sweep and prune broad-phase.
  8361. * @author saharan
  8362. */
  8363. OIMO.SAPProxy = function(sap,shape){
  8364. OIMO.Proxy.call( this, shape);
  8365. // Type of the axis to which the proxy belongs to. [0:none, 1:dynamic, 2:static]
  8366. this.belongsTo = 0;
  8367. // The maximum elements on each axis.
  8368. this.max = [];
  8369. // The minimum elements on each axis.
  8370. this.min = [];
  8371. this.sap=sap;
  8372. this.min[0]=new OIMO.SAPElement(this,false);
  8373. this.max[0]=new OIMO.SAPElement(this,true);
  8374. this.min[1]=new OIMO.SAPElement(this,false);
  8375. this.max[1]=new OIMO.SAPElement(this,true);
  8376. this.min[2]=new OIMO.SAPElement(this,false);
  8377. this.max[2]=new OIMO.SAPElement(this,true);
  8378. this.max[0].pair=this.min[0];
  8379. this.max[1].pair=this.min[1];
  8380. this.max[2].pair=this.min[2];
  8381. this.min[0].min1=this.min[1];
  8382. this.min[0].max1=this.max[1];
  8383. this.min[0].min2=this.min[2];
  8384. this.min[0].max2=this.max[2];
  8385. this.min[1].min1=this.min[0];
  8386. this.min[1].max1=this.max[0];
  8387. this.min[1].min2=this.min[2];
  8388. this.min[1].max2=this.max[2];
  8389. this.min[2].min1=this.min[0];
  8390. this.min[2].max1=this.max[0];
  8391. this.min[2].min2=this.min[1];
  8392. this.min[2].max2=this.max[1];
  8393. };
  8394. OIMO.SAPProxy.prototype = Object.create( OIMO.Proxy.prototype );
  8395. /**
  8396. * Returns whether the proxy is dynamic or not.
  8397. * @return
  8398. */
  8399. OIMO.SAPProxy.prototype.isDynamic = function () {
  8400. var body=this.shape.parent;
  8401. return body.isDynamic&&!body.sleeping;
  8402. }
  8403. OIMO.SAPProxy.prototype.update = function () {
  8404. this.min[0].value=this.aabb.minX;
  8405. this.max[0].value=this.aabb.maxX;
  8406. this.min[1].value=this.aabb.minY;
  8407. this.max[1].value=this.aabb.maxY;
  8408. this.min[2].value=this.aabb.minZ;
  8409. this.max[2].value=this.aabb.maxZ;
  8410. if(this.belongsTo==1&&!this.isDynamic()||this.belongsTo==2&&this.isDynamic()){
  8411. this.sap.removeProxy(this);
  8412. this.sap.addProxy(this);
  8413. }
  8414. }
  8415. /**
  8416. * A dynamic bounding volume tree for the broad-phase algorithm.
  8417. * @author saharan
  8418. */
  8419. OIMO.DBVT = function(){
  8420. // The root of the tree.
  8421. this.root=null;
  8422. this.freeNodes=[];// vector
  8423. this.freeNodes.length = 16384;
  8424. this.numFreeNodes=0;
  8425. this.aabb=new OIMO.AABB();
  8426. }
  8427. OIMO.DBVT.prototype = {
  8428. constructor: OIMO.DBVT,
  8429. /**
  8430. * Move a leaf.
  8431. * @param leaf
  8432. */
  8433. moveLeaf:function(leaf){
  8434. this.deleteLeaf(leaf);
  8435. this.insertLeaf(leaf);
  8436. },
  8437. /**
  8438. * Insert a leaf to the tree.
  8439. * @param node
  8440. */
  8441. insertLeaf:function(leaf){
  8442. if(this.root==null){
  8443. this.root=leaf;
  8444. return;
  8445. }
  8446. var lb=leaf.aabb;
  8447. var sibling=this.root;
  8448. var oldArea;
  8449. var newArea;
  8450. while(sibling.proxy==null){ // descend the node to search the best pair
  8451. var c1=sibling.child1;
  8452. var c2=sibling.child2;
  8453. var b=sibling.aabb;
  8454. var c1b=c1.aabb;
  8455. var c2b=c2.aabb;
  8456. oldArea=b.surfaceArea();
  8457. this.aabb.combine(lb,b);
  8458. newArea=this.aabb.surfaceArea();
  8459. var creatingCost=newArea*2;
  8460. var incrementalCost=(newArea-oldArea)*2; // cost of creating a new pair with the node
  8461. var discendingCost1=incrementalCost;
  8462. this.aabb.combine(lb,c1b);
  8463. if(c1.proxy!=null){
  8464. // leaf cost = area(combined aabb)
  8465. discendingCost1+=this.aabb.surfaceArea();
  8466. }else{
  8467. // node cost = area(combined aabb) - area(old aabb)
  8468. discendingCost1+=this.aabb.surfaceArea()-c1b.surfaceArea();
  8469. }
  8470. var discendingCost2=incrementalCost;
  8471. this.aabb.combine(lb,c2b);
  8472. if(c2.proxy!=null){
  8473. // leaf cost = area(combined aabb)
  8474. discendingCost2+=this.aabb.surfaceArea();
  8475. }else{
  8476. // node cost = area(combined aabb) - area(old aabb)
  8477. discendingCost2+=this.aabb.surfaceArea()-c2b.surfaceArea();
  8478. }
  8479. if(discendingCost1<discendingCost2){
  8480. if(creatingCost<discendingCost1){
  8481. break;// stop descending
  8482. }else{
  8483. sibling=c1;// descend into first child
  8484. }
  8485. }else{
  8486. if(creatingCost<discendingCost2){
  8487. break;// stop descending
  8488. }else{
  8489. sibling=c2;// descend into second child
  8490. }
  8491. }
  8492. }
  8493. var oldParent=sibling.parent;
  8494. var newParent;
  8495. if(this.numFreeNodes>0){
  8496. newParent=this.freeNodes[--this.numFreeNodes];
  8497. }else{
  8498. newParent=new OIMO.DBVTNode();
  8499. }
  8500. newParent.parent=oldParent;
  8501. newParent.child1=leaf;
  8502. newParent.child2=sibling;
  8503. newParent.aabb.combine(leaf.aabb,sibling.aabb);
  8504. newParent.height=sibling.height+1;
  8505. sibling.parent=newParent;
  8506. leaf.parent=newParent;
  8507. if(sibling==this.root){
  8508. // replace root
  8509. this.root=newParent;
  8510. }else{
  8511. // replace child
  8512. if(oldParent.child1==sibling){
  8513. oldParent.child1=newParent;
  8514. }else{
  8515. oldParent.child2=newParent;
  8516. }
  8517. }
  8518. // update whole tree
  8519. do{
  8520. newParent=this.balance(newParent);
  8521. this.fix(newParent);
  8522. newParent=newParent.parent;
  8523. }while(newParent!=null);
  8524. },
  8525. getBalance:function(node){
  8526. if(node.proxy!=null)return 0;
  8527. return node.child1.height-node.child2.height;
  8528. },
  8529. print:function(node,indent,text){
  8530. var hasChild=node.proxy==null;
  8531. if(hasChild)text=this.print(node.child1,indent+1,text);
  8532. for(var i=indent*2;i>=0;i--){
  8533. text+=" ";
  8534. }
  8535. text+=(hasChild?this.getBalance(node):"["+node.proxy.aabb.minX+"]")+"\n";
  8536. if(hasChild)text=this.print(node.child2,indent+1,text);
  8537. return text;
  8538. },
  8539. /**
  8540. * Delete a leaf from the tree.
  8541. * @param node
  8542. */
  8543. deleteLeaf:function(leaf){
  8544. if(leaf==this.root){
  8545. this.root=null;
  8546. return;
  8547. }
  8548. var parent=leaf.parent;
  8549. var sibling;
  8550. if(parent.child1==leaf){
  8551. sibling=parent.child2;
  8552. }else{
  8553. sibling=parent.child1;
  8554. }
  8555. if(parent==this.root){
  8556. this.root=sibling;
  8557. sibling.parent=null;
  8558. return;
  8559. }
  8560. var grandParent=parent.parent;
  8561. sibling.parent=grandParent;
  8562. if(grandParent.child1==parent){
  8563. grandParent.child1=sibling;
  8564. }else{
  8565. grandParent.child2=sibling;
  8566. }
  8567. if(this.numFreeNodes<16384){
  8568. this.freeNodes[this.numFreeNodes++]=parent;
  8569. }
  8570. do{
  8571. grandParent=this.balance(grandParent);
  8572. this.fix(grandParent);
  8573. grandParent=grandParent.parent;
  8574. }while(grandParent!=null);
  8575. },
  8576. balance:function(node){
  8577. var nh=node.height;
  8578. if(nh<2){
  8579. return node;
  8580. }
  8581. var p=node.parent;
  8582. var l=node.child1;
  8583. var r=node.child2;
  8584. var lh=l.height;
  8585. var rh=r.height;
  8586. var balance=lh-rh;
  8587. var t;// for bit operation
  8588. // [ N ]
  8589. // / \
  8590. // [ L ] [ R ]
  8591. // / \ / \
  8592. // [L-L] [L-R] [R-L] [R-R]
  8593. // Is the tree balanced?
  8594. if(balance>1){
  8595. var ll=l.child1;
  8596. var lr=l.child2;
  8597. var llh=ll.height;
  8598. var lrh=lr.height;
  8599. // Is L-L higher than L-R?
  8600. if(llh>lrh){
  8601. // set N to L-R
  8602. l.child2=node;
  8603. node.parent=l;
  8604. // [ L ]
  8605. // / \
  8606. // [L-L] [ N ]
  8607. // / \ / \
  8608. // [...] [...] [ L ] [ R ]
  8609. // set L-R
  8610. node.child1=lr;
  8611. lr.parent=node;
  8612. // [ L ]
  8613. // / \
  8614. // [L-L] [ N ]
  8615. // / \ / \
  8616. // [...] [...] [L-R] [ R ]
  8617. // fix bounds and heights
  8618. node.aabb.combine(lr.aabb,r.aabb);
  8619. t=lrh-rh;
  8620. node.height=lrh-(t&t>>31)+1;
  8621. l.aabb.combine(ll.aabb,node.aabb);
  8622. t=llh-nh;
  8623. l.height=llh-(t&t>>31)+1;
  8624. }else{
  8625. // set N to L-L
  8626. l.child1=node;
  8627. node.parent=l;
  8628. // [ L ]
  8629. // / \
  8630. // [ N ] [L-R]
  8631. // / \ / \
  8632. // [ L ] [ R ] [...] [...]
  8633. // set L-L
  8634. node.child1=ll;
  8635. ll.parent=node;
  8636. // [ L ]
  8637. // / \
  8638. // [ N ] [L-R]
  8639. // / \ / \
  8640. // [L-L] [ R ] [...] [...]
  8641. // fix bounds and heights
  8642. node.aabb.combine(ll.aabb,r.aabb);
  8643. t=llh-rh;
  8644. node.height=llh-(t&t>>31)+1;
  8645. l.aabb.combine(node.aabb,lr.aabb);
  8646. t=nh-lrh;
  8647. l.height=nh-(t&t>>31)+1;
  8648. }
  8649. // set new parent of L
  8650. if(p!=null){
  8651. if(p.child1==node){
  8652. p.child1=l;
  8653. }else{
  8654. p.child2=l;
  8655. }
  8656. }else{
  8657. this.root=l;
  8658. }
  8659. l.parent=p;
  8660. return l;
  8661. }else if(balance<-1){
  8662. var rl=r.child1;
  8663. var rr=r.child2;
  8664. var rlh=rl.height;
  8665. var rrh=rr.height;
  8666. // Is R-L higher than R-R?
  8667. if(rlh>rrh){
  8668. // set N to R-R
  8669. r.child2=node;
  8670. node.parent=r;
  8671. // [ R ]
  8672. // / \
  8673. // [R-L] [ N ]
  8674. // / \ / \
  8675. // [...] [...] [ L ] [ R ]
  8676. // set R-R
  8677. node.child2=rr;
  8678. rr.parent=node;
  8679. // [ R ]
  8680. // / \
  8681. // [R-L] [ N ]
  8682. // / \ / \
  8683. // [...] [...] [ L ] [R-R]
  8684. // fix bounds and heights
  8685. node.aabb.combine(l.aabb,rr.aabb);
  8686. t=lh-rrh;
  8687. node.height=lh-(t&t>>31)+1;
  8688. r.aabb.combine(rl.aabb,node.aabb);
  8689. t=rlh-nh;
  8690. r.height=rlh-(t&t>>31)+1;
  8691. }else{
  8692. // set N to R-L
  8693. r.child1=node;
  8694. node.parent=r;
  8695. // [ R ]
  8696. // / \
  8697. // [ N ] [R-R]
  8698. // / \ / \
  8699. // [ L ] [ R ] [...] [...]
  8700. // set R-L
  8701. node.child2=rl;
  8702. rl.parent=node;
  8703. // [ R ]
  8704. // / \
  8705. // [ N ] [R-R]
  8706. // / \ / \
  8707. // [ L ] [R-L] [...] [...]
  8708. // fix bounds and heights
  8709. node.aabb.combine(l.aabb,rl.aabb);
  8710. t=lh-rlh;
  8711. node.height=lh-(t&t>>31)+1;
  8712. r.aabb.combine(node.aabb,rr.aabb);
  8713. t=nh-rrh;
  8714. r.height=nh-(t&t>>31)+1;
  8715. }
  8716. // set new parent of R
  8717. if(p!=null){
  8718. if(p.child1==node){
  8719. p.child1=r;
  8720. }else{
  8721. p.child2=r;
  8722. }
  8723. }else{
  8724. this.root=r;
  8725. }
  8726. r.parent=p;
  8727. return r;
  8728. }
  8729. return node;
  8730. },
  8731. fix:function(node){
  8732. var c1=node.child1;
  8733. var c2=node.child2;
  8734. node.aabb.combine(c1.aabb,c2.aabb);
  8735. var h1=c1.height;
  8736. var h2=c2.height;
  8737. if(h1<h2){
  8738. node.height=h2+1;
  8739. }else{
  8740. node.height=h1+1;
  8741. }
  8742. }
  8743. }
  8744. /**
  8745. * A broad-phase algorithm using dynamic bounding volume tree.
  8746. * @author saharan
  8747. */
  8748. OIMO.DBVTBroadPhase = function(){
  8749. OIMO.BroadPhase.call( this);
  8750. this.types = 0x3;
  8751. this.numLeaves = 0;
  8752. this.maxLeaves = 0;
  8753. this.tree=new OIMO.DBVT();
  8754. this.maxStack=256;
  8755. this.stack=[];// vector
  8756. this.stack.length = this.maxStack;
  8757. this.maxLeaves=256;
  8758. this.leaves=[];// vector
  8759. this.leaves.length = this.maxLeaves;
  8760. }
  8761. OIMO.DBVTBroadPhase.prototype = Object.create( OIMO.BroadPhase.prototype );
  8762. OIMO.DBVTBroadPhase.prototype.createProxy = function (shape) {
  8763. return new OIMO.DBVTProxy(shape);
  8764. }
  8765. OIMO.DBVTBroadPhase.prototype.addProxy = function (proxy) {
  8766. var p=(proxy);
  8767. this.tree.insertLeaf(p.leaf);
  8768. if(this.numLeaves==this.maxLeaves){
  8769. //this.maxLeaves<<=1;
  8770. this.maxLeaves*=2;
  8771. var newLeaves=[];// vector
  8772. newLeaves.length = this.maxLeaves;
  8773. for(var i=0;i<this.numLeaves;i++){
  8774. newLeaves[i]=this.leaves[i];
  8775. }
  8776. this.leaves=newLeaves;
  8777. }
  8778. this.leaves[this.numLeaves++]=p.leaf;
  8779. }
  8780. OIMO.DBVTBroadPhase.prototype.removeProxy = function (proxy) {
  8781. var p=(proxy);
  8782. this.tree.deleteLeaf(p.leaf);
  8783. for(var i=0;i<this.numLeaves;i++){
  8784. if(this.leaves[i]==p.leaf){
  8785. this.leaves[i]=this.leaves[--this.numLeaves];
  8786. this.leaves[this.numLeaves]=null;
  8787. return;
  8788. }
  8789. }
  8790. }
  8791. OIMO.DBVTBroadPhase.prototype.collectPairs = function () {
  8792. if(this.numLeaves<2)return;
  8793. for(var i=0;i<this.numLeaves;i++){
  8794. var leaf=this.leaves[i];
  8795. var trueB=leaf.proxy.aabb;
  8796. var leafB=leaf.aabb;
  8797. if(
  8798. trueB.minX<leafB.minX||trueB.maxX>leafB.maxX||
  8799. trueB.minY<leafB.minY||trueB.maxY>leafB.maxY||
  8800. trueB.minZ<leafB.minZ||trueB.maxZ>leafB.maxZ
  8801. ){// the leaf needs correcting
  8802. var margin=0.1;
  8803. this.tree.deleteLeaf(leaf);
  8804. leafB.minX=trueB.minX-margin;
  8805. leafB.maxX=trueB.maxX+margin;
  8806. leafB.minY=trueB.minY-margin;
  8807. leafB.maxY=trueB.maxY+margin;
  8808. leafB.minZ=trueB.minZ-margin;
  8809. leafB.maxZ=trueB.maxZ+margin;
  8810. this.tree.insertLeaf(leaf);
  8811. this.collide(leaf,this.tree.root);
  8812. }
  8813. }
  8814. }
  8815. OIMO.DBVTBroadPhase.prototype.collide = function (node1,node2) {
  8816. var stackCount=2;
  8817. this.stack[0]=node1;
  8818. this.stack[1]=node2;
  8819. while(stackCount>0){
  8820. var n1=this.stack[--stackCount];
  8821. var n2=this.stack[--stackCount];
  8822. var l1=n1.proxy!=null;
  8823. var l2=n2.proxy!=null;
  8824. this.numPairChecks++;
  8825. if(l1&&l2){
  8826. var s1=n1.proxy.shape;
  8827. var s2=n2.proxy.shape;
  8828. var b1=s1.aabb;
  8829. var b2=s2.aabb;
  8830. if(
  8831. s1==s2||
  8832. b1.maxX<b2.minX||b1.minX>b2.maxX||
  8833. b1.maxY<b2.minY||b1.minY>b2.maxY||
  8834. b1.maxZ<b2.minZ||b1.minZ>b2.maxZ||
  8835. !this.isAvailablePair(s1,s2)
  8836. ){
  8837. continue;
  8838. }
  8839. this.addPair(s1,s2);
  8840. }else{
  8841. b1=n1.aabb;
  8842. b2=n2.aabb;
  8843. if(
  8844. b1.maxX<b2.minX||b1.minX>b2.maxX||
  8845. b1.maxY<b2.minY||b1.minY>b2.maxY||
  8846. b1.maxZ<b2.minZ||b1.minZ>b2.maxZ
  8847. ){
  8848. continue;
  8849. }
  8850. if(stackCount+4>=this.maxStack){// expand the stack
  8851. //this.maxStack<<=1;
  8852. this.maxStack*=2;
  8853. var newStack=[];// vector
  8854. newStack.length = this.maxStack;
  8855. for(var i=0;i<stackCount;i++){
  8856. newStack[i]=this.stack[i];
  8857. }
  8858. this.stack=newStack;
  8859. }
  8860. if(l2||!l1&&(n1.aabb.surfaceArea()>n2.aabb.surfaceArea())){
  8861. this.stack[stackCount++]=n1.child1;
  8862. this.stack[stackCount++]=n2;
  8863. this.stack[stackCount++]=n1.child2;
  8864. this.stack[stackCount++]=n2;
  8865. }else{
  8866. this.stack[stackCount++]=n1;
  8867. this.stack[stackCount++]=n2.child1;
  8868. this.stack[stackCount++]=n1;
  8869. this.stack[stackCount++]=n2.child2;
  8870. }
  8871. }
  8872. }
  8873. }
  8874. /**
  8875. * A node of the dynamic bounding volume tree.
  8876. * @author saharan
  8877. */
  8878. OIMO.DBVTNode = function(){
  8879. // The first child node of this node.
  8880. this.child1=null;
  8881. // The second child node of this node.
  8882. this.child2=null;
  8883. // The parent node of this tree.
  8884. this.parent=null;
  8885. // The proxy of this node. This has no value if this node is not leaf.
  8886. this.proxy=null;
  8887. // The maximum distance from leaf nodes.
  8888. this.height=0;
  8889. // The AABB of this node.
  8890. this.aabb=new OIMO.AABB();
  8891. }
  8892. /**
  8893. * A proxy for dynamic bounding volume tree broad-phase.
  8894. * @author saharan
  8895. */
  8896. OIMO.DBVTProxy = function(shape){
  8897. OIMO.Proxy.call( this, shape);
  8898. // The leaf of the proxy.
  8899. this.leaf = new OIMO.DBVTNode();
  8900. this.leaf.proxy = this;
  8901. }
  8902. OIMO.DBVTProxy.prototype = Object.create( OIMO.Proxy.prototype );
  8903. OIMO.DBVTProxy.prototype.update = function () {
  8904. }