123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854108551085610857108581085910860108611086210863108641086510866108671086810869108701087110872108731087410875108761087710878108791088010881108821088310884108851088610887108881088910890108911089210893108941089510896108971089810899109001090110902109031090410905109061090710908109091091010911109121091310914109151091610917109181091910920109211092210923109241092510926109271092810929109301093110932109331093410935109361093710938109391094010941109421094310944109451094610947109481094910950109511095210953109541095510956109571095810959109601096110962109631096410965109661096710968109691097010971109721097310974109751097610977109781097910980109811098210983109841098510986109871098810989109901099110992109931099410995109961099710998109991100011001110021100311004110051100611007110081100911010110111101211013110141101511016110171101811019110201102111022110231102411025110261102711028110291103011031110321103311034110351103611037110381103911040110411104211043110441104511046110471104811049110501105111052110531105411055110561105711058110591106011061110621106311064110651106611067110681106911070110711107211073110741107511076110771107811079110801108111082110831108411085110861108711088110891109011091110921109311094110951109611097110981109911100111011110211103111041110511106111071110811109111101111111112111131111411115111161111711118111191112011121111221112311124111251112611127111281112911130111311113211133111341113511136111371113811139111401114111142111431114411145111461114711148111491115011151111521115311154111551115611157111581115911160111611116211163111641116511166111671116811169111701117111172111731117411175111761117711178111791118011181111821118311184111851118611187111881118911190111911119211193111941119511196111971119811199112001120111202112031120411205112061120711208112091121011211112121121311214112151121611217112181121911220112211122211223112241122511226112271122811229112301123111232112331123411235112361123711238112391124011241112421124311244112451124611247112481124911250112511125211253112541125511256112571125811259112601126111262112631126411265112661126711268112691127011271112721127311274112751127611277112781127911280112811128211283112841128511286112871128811289112901129111292112931129411295112961129711298112991130011301113021130311304113051130611307113081130911310113111131211313113141131511316113171131811319113201132111322113231132411325113261132711328113291133011331113321133311334113351133611337113381133911340113411134211343113441134511346113471134811349113501135111352113531135411355113561135711358113591136011361113621136311364113651136611367113681136911370113711137211373113741137511376113771137811379113801138111382113831138411385113861138711388113891139011391113921139311394113951139611397113981139911400114011140211403114041140511406114071140811409114101141111412114131141411415114161141711418114191142011421114221142311424114251142611427114281142911430114311143211433114341143511436114371143811439114401144111442114431144411445114461144711448114491145011451114521145311454114551145611457114581145911460114611146211463114641146511466114671146811469114701147111472114731147411475114761147711478114791148011481114821148311484114851148611487114881148911490114911149211493114941149511496114971149811499115001150111502115031150411505115061150711508115091151011511115121151311514115151151611517115181151911520115211152211523115241152511526115271152811529115301153111532115331153411535115361153711538115391154011541115421154311544115451154611547115481154911550115511155211553115541155511556115571155811559115601156111562115631156411565115661156711568115691157011571115721157311574115751157611577115781157911580115811158211583115841158511586115871158811589115901159111592115931159411595115961159711598115991160011601116021160311604116051160611607116081160911610116111161211613116141161511616116171161811619116201162111622116231162411625116261162711628116291163011631116321163311634116351163611637116381163911640116411164211643116441164511646116471164811649116501165111652116531165411655116561165711658116591166011661116621166311664116651166611667116681166911670116711167211673116741167511676116771167811679116801168111682116831168411685116861168711688116891169011691116921169311694116951169611697116981169911700117011170211703117041170511706117071170811709117101171111712117131171411715117161171711718117191172011721117221172311724117251172611727117281172911730117311173211733117341173511736117371173811739117401174111742117431174411745117461174711748117491175011751117521175311754117551175611757117581175911760117611176211763117641176511766117671176811769117701177111772117731177411775117761177711778117791178011781117821178311784117851178611787117881178911790117911179211793117941179511796117971179811799118001180111802118031180411805118061180711808118091181011811118121181311814118151181611817118181181911820118211182211823118241182511826118271182811829118301183111832118331183411835118361183711838118391184011841118421184311844118451184611847118481184911850118511185211853118541185511856118571185811859118601186111862118631186411865118661186711868118691187011871118721187311874118751187611877118781187911880118811188211883118841188511886118871188811889118901189111892118931189411895118961189711898118991190011901119021190311904119051190611907119081190911910119111191211913119141191511916119171191811919119201192111922119231192411925119261192711928119291193011931119321193311934119351193611937119381193911940119411194211943119441194511946119471194811949119501195111952119531195411955119561195711958119591196011961119621196311964119651196611967119681196911970119711197211973119741197511976119771197811979119801198111982119831198411985119861198711988119891199011991119921199311994119951199611997119981199912000120011200212003120041200512006120071200812009120101201112012120131201412015120161201712018120191202012021120221202312024120251202612027120281202912030120311203212033120341203512036120371203812039120401204112042120431204412045120461204712048120491205012051120521205312054120551205612057120581205912060120611206212063120641206512066120671206812069120701207112072120731207412075120761207712078120791208012081120821208312084120851208612087120881208912090120911209212093120941209512096120971209812099121001210112102121031210412105121061210712108121091211012111121121211312114121151211612117121181211912120121211212212123121241212512126121271212812129121301213112132121331213412135121361213712138121391214012141121421214312144121451214612147121481214912150121511215212153121541215512156121571215812159121601216112162121631216412165121661216712168121691217012171121721217312174121751217612177121781217912180121811218212183121841218512186121871218812189121901219112192121931219412195121961219712198121991220012201122021220312204122051220612207122081220912210122111221212213122141221512216122171221812219122201222112222122231222412225122261222712228122291223012231122321223312234122351223612237122381223912240122411224212243122441224512246122471224812249122501225112252122531225412255122561225712258122591226012261122621226312264122651226612267122681226912270122711227212273122741227512276122771227812279122801228112282122831228412285122861228712288122891229012291122921229312294122951229612297122981229912300123011230212303123041230512306123071230812309123101231112312123131231412315123161231712318123191232012321123221232312324123251232612327123281232912330123311233212333123341233512336123371233812339123401234112342123431234412345123461234712348123491235012351123521235312354123551235612357123581235912360123611236212363123641236512366123671236812369123701237112372123731237412375123761237712378123791238012381123821238312384123851238612387123881238912390123911239212393123941239512396123971239812399124001240112402124031240412405124061240712408124091241012411124121241312414124151241612417124181241912420124211242212423124241242512426124271242812429124301243112432124331243412435124361243712438124391244012441124421244312444124451244612447124481244912450124511245212453124541245512456124571245812459124601246112462124631246412465124661246712468124691247012471124721247312474124751247612477124781247912480124811248212483124841248512486124871248812489124901249112492124931249412495124961249712498124991250012501125021250312504125051250612507125081250912510125111251212513125141251512516125171251812519125201252112522125231252412525125261252712528125291253012531125321253312534125351253612537125381253912540125411254212543125441254512546125471254812549125501255112552125531255412555125561255712558125591256012561125621256312564125651256612567125681256912570125711257212573125741257512576125771257812579125801258112582125831258412585125861258712588125891259012591125921259312594125951259612597125981259912600126011260212603126041260512606126071260812609126101261112612126131261412615126161261712618126191262012621126221262312624126251262612627126281262912630126311263212633126341263512636126371263812639126401264112642126431264412645126461264712648126491265012651126521265312654126551265612657126581265912660126611266212663126641266512666126671266812669126701267112672126731267412675126761267712678126791268012681126821268312684126851268612687126881268912690126911269212693126941269512696126971269812699127001270112702127031270412705127061270712708127091271012711127121271312714127151271612717127181271912720127211272212723127241272512726127271272812729127301273112732127331273412735127361273712738127391274012741127421274312744127451274612747127481274912750127511275212753127541275512756127571275812759127601276112762127631276412765127661276712768127691277012771127721277312774127751277612777127781277912780127811278212783127841278512786127871278812789127901279112792127931279412795127961279712798127991280012801128021280312804128051280612807128081280912810128111281212813128141281512816128171281812819128201282112822128231282412825128261282712828128291283012831128321283312834128351283612837128381283912840128411284212843128441284512846128471284812849128501285112852128531285412855128561285712858128591286012861128621286312864128651286612867128681286912870128711287212873128741287512876128771287812879128801288112882128831288412885128861288712888128891289012891128921289312894128951289612897128981289912900129011290212903129041290512906129071290812909129101291112912129131291412915129161291712918129191292012921129221292312924129251292612927129281292912930129311293212933129341293512936129371293812939129401294112942129431294412945129461294712948129491295012951129521295312954129551295612957129581295912960129611296212963129641296512966129671296812969129701297112972129731297412975129761297712978129791298012981129821298312984129851298612987129881298912990129911299212993129941299512996129971299812999130001300113002130031300413005130061300713008130091301013011130121301313014130151301613017130181301913020130211302213023130241302513026130271302813029130301303113032130331303413035130361303713038130391304013041130421304313044130451304613047130481304913050130511305213053130541305513056130571305813059130601306113062130631306413065130661306713068130691307013071130721307313074130751307613077130781307913080130811308213083130841308513086130871308813089130901309113092130931309413095130961309713098130991310013101131021310313104131051310613107131081310913110131111311213113131141311513116131171311813119131201312113122131231312413125131261312713128131291313013131131321313313134131351313613137131381313913140131411314213143131441314513146131471314813149131501315113152131531315413155131561315713158131591316013161131621316313164131651316613167131681316913170131711317213173131741317513176131771317813179131801318113182131831318413185131861318713188131891319013191131921319313194131951319613197131981319913200132011320213203132041320513206132071320813209132101321113212132131321413215132161321713218132191322013221132221322313224132251322613227132281322913230132311323213233132341323513236132371323813239132401324113242132431324413245132461324713248132491325013251132521325313254132551325613257132581325913260132611326213263132641326513266132671326813269132701327113272132731327413275132761327713278132791328013281132821328313284132851328613287132881328913290132911329213293132941329513296132971329813299133001330113302133031330413305133061330713308133091331013311133121331313314133151331613317133181331913320133211332213323133241332513326133271332813329133301333113332133331333413335133361333713338133391334013341133421334313344133451334613347133481334913350133511335213353133541335513356133571335813359133601336113362133631336413365133661336713368133691337013371133721337313374133751337613377133781337913380133811338213383133841338513386133871338813389133901339113392133931339413395133961339713398133991340013401134021340313404134051340613407134081340913410134111341213413134141341513416134171341813419134201342113422134231342413425134261342713428134291343013431134321343313434134351343613437134381343913440134411344213443134441344513446134471344813449134501345113452134531345413455134561345713458134591346013461134621346313464134651346613467134681346913470134711347213473134741347513476134771347813479134801348113482134831348413485134861348713488134891349013491134921349313494134951349613497134981349913500135011350213503135041350513506135071350813509135101351113512135131351413515135161351713518135191352013521135221352313524135251352613527135281352913530135311353213533135341353513536135371353813539135401354113542135431354413545135461354713548135491355013551135521355313554135551355613557135581355913560135611356213563135641356513566135671356813569135701357113572135731357413575135761357713578135791358013581135821358313584135851358613587135881358913590135911359213593135941359513596135971359813599136001360113602136031360413605136061360713608136091361013611136121361313614136151361613617136181361913620136211362213623136241362513626136271362813629136301363113632136331363413635136361363713638136391364013641136421364313644136451364613647136481364913650136511365213653136541365513656136571365813659136601366113662136631366413665136661366713668136691367013671136721367313674136751367613677136781367913680136811368213683136841368513686136871368813689136901369113692136931369413695136961369713698136991370013701137021370313704137051370613707137081370913710137111371213713137141371513716137171371813719137201372113722137231372413725137261372713728137291373013731137321373313734137351373613737137381373913740137411374213743137441374513746137471374813749137501375113752137531375413755137561375713758137591376013761137621376313764137651376613767137681376913770137711377213773137741377513776137771377813779137801378113782137831378413785137861378713788137891379013791137921379313794137951379613797137981379913800138011380213803138041380513806138071380813809138101381113812138131381413815138161381713818138191382013821138221382313824138251382613827138281382913830138311383213833138341383513836138371383813839138401384113842138431384413845138461384713848138491385013851138521385313854138551385613857138581385913860138611386213863138641386513866138671386813869138701387113872138731387413875138761387713878138791388013881138821388313884138851388613887138881388913890138911389213893138941389513896138971389813899139001390113902139031390413905139061390713908139091391013911139121391313914139151391613917139181391913920139211392213923139241392513926139271392813929139301393113932139331393413935139361393713938139391394013941139421394313944139451394613947139481394913950139511395213953139541395513956139571395813959139601396113962139631396413965139661396713968139691397013971139721397313974139751397613977139781397913980139811398213983139841398513986139871398813989139901399113992139931399413995139961399713998139991400014001140021400314004140051400614007140081400914010140111401214013140141401514016140171401814019140201402114022140231402414025140261402714028140291403014031140321403314034140351403614037140381403914040140411404214043140441404514046140471404814049140501405114052140531405414055140561405714058140591406014061140621406314064140651406614067140681406914070140711407214073140741407514076140771407814079140801408114082140831408414085140861408714088140891409014091140921409314094140951409614097140981409914100141011410214103141041410514106141071410814109141101411114112141131411414115141161411714118141191412014121141221412314124141251412614127141281412914130141311413214133141341413514136141371413814139141401414114142141431414414145141461414714148141491415014151141521415314154141551415614157141581415914160141611416214163141641416514166141671416814169141701417114172141731417414175141761417714178141791418014181141821418314184141851418614187141881418914190141911419214193141941419514196141971419814199142001420114202142031420414205142061420714208142091421014211142121421314214142151421614217142181421914220142211422214223142241422514226142271422814229142301423114232142331423414235142361423714238142391424014241142421424314244142451424614247142481424914250142511425214253142541425514256142571425814259142601426114262142631426414265142661426714268142691427014271142721427314274142751427614277142781427914280142811428214283142841428514286142871428814289142901429114292142931429414295142961429714298142991430014301143021430314304143051430614307143081430914310143111431214313143141431514316143171431814319143201432114322143231432414325143261432714328143291433014331143321433314334143351433614337143381433914340143411434214343143441434514346143471434814349143501435114352143531435414355143561435714358143591436014361143621436314364143651436614367143681436914370143711437214373143741437514376143771437814379143801438114382143831438414385143861438714388143891439014391143921439314394143951439614397143981439914400144011440214403144041440514406144071440814409144101441114412144131441414415144161441714418144191442014421144221442314424144251442614427144281442914430144311443214433144341443514436144371443814439144401444114442144431444414445144461444714448144491445014451144521445314454144551445614457144581445914460144611446214463144641446514466144671446814469144701447114472144731447414475144761447714478144791448014481144821448314484144851448614487144881448914490144911449214493144941449514496144971449814499145001450114502145031450414505145061450714508145091451014511145121451314514145151451614517145181451914520145211452214523145241452514526145271452814529145301453114532145331453414535145361453714538145391454014541145421454314544145451454614547145481454914550145511455214553145541455514556145571455814559145601456114562145631456414565145661456714568145691457014571145721457314574145751457614577145781457914580145811458214583145841458514586145871458814589145901459114592145931459414595145961459714598145991460014601146021460314604146051460614607146081460914610146111461214613146141461514616146171461814619146201462114622146231462414625146261462714628146291463014631146321463314634146351463614637146381463914640146411464214643146441464514646146471464814649146501465114652146531465414655146561465714658146591466014661146621466314664146651466614667146681466914670146711467214673146741467514676146771467814679146801468114682146831468414685146861468714688146891469014691146921469314694146951469614697146981469914700147011470214703147041470514706147071470814709147101471114712147131471414715147161471714718147191472014721147221472314724147251472614727147281472914730147311473214733147341473514736147371473814739147401474114742147431474414745147461474714748147491475014751147521475314754147551475614757147581475914760147611476214763147641476514766147671476814769147701477114772147731477414775147761477714778147791478014781147821478314784147851478614787147881478914790147911479214793147941479514796147971479814799148001480114802148031480414805148061480714808148091481014811148121481314814148151481614817148181481914820148211482214823148241482514826148271482814829148301483114832148331483414835148361483714838148391484014841148421484314844148451484614847148481484914850148511485214853148541485514856148571485814859148601486114862148631486414865148661486714868148691487014871148721487314874148751487614877148781487914880148811488214883148841488514886148871488814889148901489114892148931489414895148961489714898148991490014901149021490314904149051490614907149081490914910149111491214913149141491514916149171491814919149201492114922149231492414925149261492714928149291493014931149321493314934149351493614937149381493914940149411494214943149441494514946149471494814949149501495114952149531495414955149561495714958149591496014961149621496314964149651496614967149681496914970149711497214973149741497514976149771497814979149801498114982149831498414985149861498714988149891499014991149921499314994149951499614997149981499915000150011500215003150041500515006150071500815009150101501115012150131501415015150161501715018150191502015021150221502315024150251502615027150281502915030150311503215033150341503515036150371503815039150401504115042150431504415045150461504715048150491505015051150521505315054150551505615057150581505915060150611506215063150641506515066150671506815069150701507115072150731507415075150761507715078150791508015081150821508315084150851508615087150881508915090150911509215093150941509515096150971509815099151001510115102151031510415105151061510715108151091511015111151121511315114151151511615117151181511915120151211512215123151241512515126151271512815129151301513115132151331513415135151361513715138151391514015141151421514315144151451514615147151481514915150151511515215153151541515515156151571515815159151601516115162151631516415165151661516715168151691517015171151721517315174151751517615177151781517915180151811518215183151841518515186151871518815189151901519115192151931519415195151961519715198151991520015201152021520315204152051520615207152081520915210152111521215213152141521515216152171521815219152201522115222152231522415225152261522715228152291523015231152321523315234152351523615237152381523915240152411524215243152441524515246152471524815249152501525115252152531525415255152561525715258152591526015261152621526315264152651526615267152681526915270152711527215273152741527515276152771527815279152801528115282152831528415285152861528715288152891529015291152921529315294152951529615297152981529915300153011530215303153041530515306153071530815309153101531115312153131531415315153161531715318153191532015321153221532315324153251532615327153281532915330153311533215333153341533515336153371533815339153401534115342153431534415345153461534715348153491535015351153521535315354153551535615357153581535915360153611536215363153641536515366153671536815369153701537115372153731537415375153761537715378153791538015381153821538315384153851538615387153881538915390153911539215393153941539515396153971539815399154001540115402154031540415405154061540715408154091541015411154121541315414154151541615417154181541915420154211542215423154241542515426154271542815429154301543115432154331543415435154361543715438154391544015441154421544315444154451544615447154481544915450154511545215453154541545515456154571545815459154601546115462154631546415465154661546715468154691547015471154721547315474154751547615477154781547915480154811548215483154841548515486154871548815489154901549115492154931549415495154961549715498154991550015501155021550315504155051550615507155081550915510155111551215513155141551515516155171551815519155201552115522155231552415525155261552715528155291553015531155321553315534155351553615537155381553915540155411554215543155441554515546155471554815549155501555115552155531555415555155561555715558155591556015561155621556315564155651556615567155681556915570155711557215573155741557515576155771557815579155801558115582155831558415585155861558715588155891559015591155921559315594155951559615597155981559915600156011560215603156041560515606156071560815609156101561115612156131561415615156161561715618156191562015621156221562315624156251562615627156281562915630156311563215633156341563515636156371563815639156401564115642156431564415645156461564715648156491565015651156521565315654156551565615657156581565915660156611566215663156641566515666156671566815669156701567115672156731567415675156761567715678156791568015681156821568315684156851568615687156881568915690156911569215693156941569515696156971569815699157001570115702157031570415705157061570715708157091571015711157121571315714157151571615717157181571915720157211572215723157241572515726157271572815729157301573115732157331573415735157361573715738157391574015741157421574315744157451574615747157481574915750157511575215753157541575515756157571575815759157601576115762157631576415765157661576715768157691577015771157721577315774157751577615777157781577915780157811578215783157841578515786157871578815789157901579115792157931579415795157961579715798157991580015801158021580315804158051580615807158081580915810158111581215813158141581515816158171581815819158201582115822158231582415825158261582715828158291583015831158321583315834158351583615837158381583915840158411584215843158441584515846158471584815849158501585115852158531585415855158561585715858158591586015861158621586315864158651586615867158681586915870158711587215873158741587515876158771587815879158801588115882158831588415885158861588715888158891589015891158921589315894158951589615897158981589915900159011590215903159041590515906159071590815909159101591115912159131591415915159161591715918159191592015921159221592315924159251592615927159281592915930159311593215933159341593515936159371593815939159401594115942159431594415945159461594715948159491595015951159521595315954159551595615957159581595915960159611596215963159641596515966159671596815969159701597115972159731597415975159761597715978159791598015981159821598315984159851598615987159881598915990159911599215993159941599515996159971599815999160001600116002160031600416005160061600716008160091601016011160121601316014160151601616017160181601916020160211602216023160241602516026160271602816029160301603116032160331603416035160361603716038160391604016041160421604316044160451604616047160481604916050160511605216053160541605516056160571605816059160601606116062160631606416065160661606716068160691607016071160721607316074160751607616077160781607916080160811608216083160841608516086160871608816089160901609116092160931609416095160961609716098160991610016101161021610316104161051610616107161081610916110161111611216113161141611516116161171611816119161201612116122161231612416125161261612716128161291613016131161321613316134161351613616137161381613916140161411614216143161441614516146161471614816149161501615116152161531615416155161561615716158161591616016161161621616316164161651616616167161681616916170161711617216173161741617516176161771617816179161801618116182161831618416185161861618716188161891619016191161921619316194161951619616197161981619916200162011620216203162041620516206162071620816209162101621116212162131621416215162161621716218162191622016221162221622316224162251622616227162281622916230162311623216233162341623516236162371623816239162401624116242162431624416245162461624716248162491625016251162521625316254162551625616257162581625916260162611626216263162641626516266162671626816269162701627116272162731627416275162761627716278162791628016281162821628316284162851628616287162881628916290162911629216293162941629516296162971629816299163001630116302163031630416305163061630716308163091631016311163121631316314163151631616317163181631916320163211632216323163241632516326163271632816329163301633116332163331633416335163361633716338163391634016341163421634316344163451634616347163481634916350163511635216353163541635516356163571635816359163601636116362163631636416365163661636716368163691637016371163721637316374163751637616377163781637916380163811638216383163841638516386163871638816389163901639116392163931639416395163961639716398163991640016401164021640316404164051640616407164081640916410164111641216413164141641516416164171641816419164201642116422164231642416425164261642716428164291643016431164321643316434164351643616437164381643916440164411644216443164441644516446164471644816449164501645116452164531645416455164561645716458164591646016461164621646316464164651646616467164681646916470164711647216473164741647516476164771647816479164801648116482164831648416485164861648716488164891649016491164921649316494164951649616497164981649916500165011650216503165041650516506165071650816509165101651116512165131651416515165161651716518165191652016521165221652316524165251652616527165281652916530165311653216533165341653516536165371653816539165401654116542165431654416545165461654716548165491655016551165521655316554165551655616557165581655916560165611656216563165641656516566165671656816569165701657116572165731657416575165761657716578165791658016581165821658316584165851658616587165881658916590165911659216593165941659516596165971659816599166001660116602166031660416605166061660716608166091661016611166121661316614166151661616617166181661916620166211662216623166241662516626166271662816629166301663116632166331663416635166361663716638166391664016641166421664316644166451664616647166481664916650166511665216653166541665516656166571665816659166601666116662166631666416665166661666716668166691667016671166721667316674166751667616677166781667916680166811668216683166841668516686166871668816689166901669116692166931669416695166961669716698166991670016701167021670316704167051670616707167081670916710167111671216713167141671516716167171671816719167201672116722167231672416725167261672716728167291673016731167321673316734167351673616737167381673916740167411674216743167441674516746167471674816749167501675116752167531675416755167561675716758167591676016761167621676316764167651676616767167681676916770167711677216773167741677516776167771677816779167801678116782167831678416785167861678716788167891679016791167921679316794167951679616797167981679916800168011680216803168041680516806168071680816809168101681116812168131681416815168161681716818168191682016821168221682316824168251682616827168281682916830168311683216833168341683516836168371683816839168401684116842168431684416845168461684716848168491685016851168521685316854168551685616857168581685916860168611686216863168641686516866168671686816869168701687116872168731687416875168761687716878168791688016881168821688316884168851688616887168881688916890168911689216893168941689516896168971689816899169001690116902169031690416905169061690716908169091691016911169121691316914169151691616917169181691916920169211692216923169241692516926169271692816929169301693116932169331693416935169361693716938169391694016941169421694316944169451694616947169481694916950169511695216953169541695516956169571695816959169601696116962169631696416965169661696716968169691697016971169721697316974169751697616977169781697916980169811698216983169841698516986169871698816989169901699116992169931699416995169961699716998169991700017001170021700317004170051700617007170081700917010170111701217013170141701517016170171701817019170201702117022170231702417025170261702717028170291703017031170321703317034170351703617037170381703917040170411704217043170441704517046170471704817049170501705117052170531705417055170561705717058170591706017061170621706317064170651706617067170681706917070170711707217073170741707517076170771707817079170801708117082170831708417085170861708717088170891709017091170921709317094170951709617097170981709917100171011710217103171041710517106171071710817109171101711117112171131711417115171161711717118171191712017121171221712317124171251712617127171281712917130171311713217133171341713517136171371713817139171401714117142171431714417145171461714717148171491715017151171521715317154171551715617157171581715917160171611716217163171641716517166171671716817169171701717117172171731717417175171761717717178171791718017181171821718317184171851718617187171881718917190171911719217193171941719517196171971719817199172001720117202172031720417205172061720717208172091721017211172121721317214172151721617217172181721917220172211722217223172241722517226172271722817229172301723117232172331723417235172361723717238172391724017241172421724317244172451724617247172481724917250172511725217253172541725517256172571725817259172601726117262172631726417265172661726717268172691727017271172721727317274172751727617277172781727917280172811728217283172841728517286172871728817289172901729117292172931729417295172961729717298172991730017301173021730317304173051730617307173081730917310173111731217313173141731517316173171731817319173201732117322173231732417325173261732717328173291733017331173321733317334173351733617337173381733917340173411734217343173441734517346173471734817349173501735117352173531735417355173561735717358173591736017361173621736317364173651736617367173681736917370173711737217373173741737517376173771737817379173801738117382173831738417385173861738717388173891739017391173921739317394173951739617397173981739917400174011740217403174041740517406174071740817409174101741117412174131741417415174161741717418174191742017421174221742317424174251742617427174281742917430174311743217433174341743517436174371743817439174401744117442174431744417445174461744717448174491745017451174521745317454174551745617457174581745917460174611746217463174641746517466174671746817469174701747117472174731747417475174761747717478174791748017481174821748317484174851748617487174881748917490174911749217493174941749517496174971749817499175001750117502175031750417505175061750717508175091751017511175121751317514175151751617517175181751917520175211752217523175241752517526175271752817529175301753117532175331753417535175361753717538175391754017541175421754317544175451754617547175481754917550175511755217553175541755517556175571755817559175601756117562175631756417565175661756717568175691757017571175721757317574175751757617577175781757917580175811758217583175841758517586175871758817589175901759117592175931759417595175961759717598175991760017601176021760317604176051760617607176081760917610176111761217613176141761517616176171761817619176201762117622176231762417625176261762717628176291763017631176321763317634176351763617637176381763917640176411764217643176441764517646176471764817649176501765117652176531765417655176561765717658176591766017661176621766317664176651766617667176681766917670176711767217673176741767517676176771767817679176801768117682176831768417685176861768717688176891769017691176921769317694176951769617697176981769917700177011770217703177041770517706177071770817709177101771117712177131771417715177161771717718177191772017721177221772317724177251772617727177281772917730177311773217733177341773517736177371773817739177401774117742177431774417745177461774717748177491775017751177521775317754177551775617757177581775917760177611776217763177641776517766177671776817769177701777117772177731777417775177761777717778177791778017781177821778317784177851778617787177881778917790177911779217793177941779517796177971779817799178001780117802178031780417805178061780717808178091781017811178121781317814178151781617817178181781917820178211782217823178241782517826178271782817829178301783117832178331783417835178361783717838178391784017841178421784317844178451784617847178481784917850178511785217853178541785517856178571785817859178601786117862178631786417865178661786717868178691787017871178721787317874178751787617877178781787917880178811788217883178841788517886178871788817889178901789117892178931789417895178961789717898178991790017901179021790317904179051790617907179081790917910179111791217913179141791517916179171791817919179201792117922179231792417925179261792717928179291793017931179321793317934179351793617937179381793917940179411794217943179441794517946179471794817949179501795117952179531795417955179561795717958179591796017961179621796317964179651796617967179681796917970179711797217973179741797517976179771797817979179801798117982179831798417985179861798717988179891799017991179921799317994 |
- (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
- require('./src/controls').registerAll();
- },{"./src/controls":78}],2:[function(require,module,exports){
- module.exports = Object.assign(function GamepadButton () {}, {
- FACE_1: 0,
- FACE_2: 1,
- FACE_3: 2,
- FACE_4: 3,
- L_SHOULDER_1: 4,
- R_SHOULDER_1: 5,
- L_SHOULDER_2: 6,
- R_SHOULDER_2: 7,
- SELECT: 8,
- START: 9,
- DPAD_UP: 12,
- DPAD_DOWN: 13,
- DPAD_LEFT: 14,
- DPAD_RIGHT: 15,
- VENDOR: 16,
- });
- },{}],3:[function(require,module,exports){
- function GamepadButtonEvent (type, index, details) {
- this.type = type;
- this.index = index;
- this.pressed = details.pressed;
- this.value = details.value;
- }
- module.exports = GamepadButtonEvent;
- },{}],4:[function(require,module,exports){
- (function(global) {
- var nativeKeyboardEvent = ('KeyboardEvent' in global);
- if (!nativeKeyboardEvent)
- global.KeyboardEvent = function KeyboardEvent() { throw TypeError('Illegal constructor'); };
- global.KeyboardEvent.DOM_KEY_LOCATION_STANDARD = 0x00;
- global.KeyboardEvent.DOM_KEY_LOCATION_LEFT = 0x01;
- global.KeyboardEvent.DOM_KEY_LOCATION_RIGHT = 0x02;
- global.KeyboardEvent.DOM_KEY_LOCATION_NUMPAD = 0x03;
- var STANDARD = window.KeyboardEvent.DOM_KEY_LOCATION_STANDARD,
- LEFT = window.KeyboardEvent.DOM_KEY_LOCATION_LEFT,
- RIGHT = window.KeyboardEvent.DOM_KEY_LOCATION_RIGHT,
- NUMPAD = window.KeyboardEvent.DOM_KEY_LOCATION_NUMPAD;
-
-
-
-
-
- function contains(s, ss) { return String(s).indexOf(ss) !== -1; }
- var os = (function() {
- if (contains(navigator.platform, 'Win')) { return 'win'; }
- if (contains(navigator.platform, 'Mac')) { return 'mac'; }
- if (contains(navigator.platform, 'CrOS')) { return 'cros'; }
- if (contains(navigator.platform, 'Linux')) { return 'linux'; }
- if (contains(navigator.userAgent, 'iPad') || contains(navigator.platform, 'iPod') || contains(navigator.platform, 'iPhone')) { return 'ios'; }
- return '';
- } ());
- var browser = (function() {
- if (contains(navigator.userAgent, 'Chrome/')) { return 'chrome'; }
- if (contains(navigator.vendor, 'Apple')) { return 'safari'; }
- if (contains(navigator.userAgent, 'MSIE')) { return 'ie'; }
- if (contains(navigator.userAgent, 'Gecko/')) { return 'moz'; }
- if (contains(navigator.userAgent, 'Opera/')) { return 'opera'; }
- return '';
- } ());
- var browser_os = browser + '-' + os;
- function mergeIf(baseTable, select, table) {
- if (browser_os === select || browser === select || os === select) {
- Object.keys(table).forEach(function(keyCode) {
- baseTable[keyCode] = table[keyCode];
- });
- }
- }
- function remap(o, key) {
- var r = {};
- Object.keys(o).forEach(function(k) {
- var item = o[k];
- if (key in item) {
- r[item[key]] = item;
- }
- });
- return r;
- }
- function invert(o) {
- var r = {};
- Object.keys(o).forEach(function(k) {
- r[o[k]] = k;
- });
- return r;
- }
-
-
-
-
-
-
-
-
-
-
-
-
- var keyCodeToInfoTable = {
-
-
- 0x03: { code: 'Cancel' },
-
-
-
- 0x06: { code: 'Help' },
-
- 0x08: { code: 'Backspace' },
- 0x09: { code: 'Tab' },
-
- 0X0C: { code: 'Clear' },
- 0X0D: { code: 'Enter' },
-
- 0x10: { code: 'Shift' },
- 0x11: { code: 'Control' },
- 0x12: { code: 'Alt' },
- 0x13: { code: 'Pause' },
- 0x14: { code: 'CapsLock' },
- 0x15: { code: 'KanaMode' },
- 0x16: { code: 'HangulMode' },
- 0x17: { code: 'JunjaMode' },
- 0x18: { code: 'FinalMode' },
- 0x19: { code: 'KanjiMode' },
-
- 0x1B: { code: 'Escape' },
- 0x1C: { code: 'Convert' },
- 0x1D: { code: 'NonConvert' },
- 0x1E: { code: 'Accept' },
- 0x1F: { code: 'ModeChange' },
- 0x20: { code: 'Space' },
- 0x21: { code: 'PageUp' },
- 0x22: { code: 'PageDown' },
- 0x23: { code: 'End' },
- 0x24: { code: 'Home' },
- 0x25: { code: 'ArrowLeft' },
- 0x26: { code: 'ArrowUp' },
- 0x27: { code: 'ArrowRight' },
- 0x28: { code: 'ArrowDown' },
- 0x29: { code: 'Select' },
- 0x2A: { code: 'Print' },
- 0x2B: { code: 'Execute' },
- 0x2C: { code: 'PrintScreen' },
- 0x2D: { code: 'Insert' },
- 0x2E: { code: 'Delete' },
- 0x2F: { code: 'Help' },
- 0x30: { code: 'Digit0', keyCap: '0' },
- 0x31: { code: 'Digit1', keyCap: '1' },
- 0x32: { code: 'Digit2', keyCap: '2' },
- 0x33: { code: 'Digit3', keyCap: '3' },
- 0x34: { code: 'Digit4', keyCap: '4' },
- 0x35: { code: 'Digit5', keyCap: '5' },
- 0x36: { code: 'Digit6', keyCap: '6' },
- 0x37: { code: 'Digit7', keyCap: '7' },
- 0x38: { code: 'Digit8', keyCap: '8' },
- 0x39: { code: 'Digit9', keyCap: '9' },
-
- 0x41: { code: 'KeyA', keyCap: 'a' },
- 0x42: { code: 'KeyB', keyCap: 'b' },
- 0x43: { code: 'KeyC', keyCap: 'c' },
- 0x44: { code: 'KeyD', keyCap: 'd' },
- 0x45: { code: 'KeyE', keyCap: 'e' },
- 0x46: { code: 'KeyF', keyCap: 'f' },
- 0x47: { code: 'KeyG', keyCap: 'g' },
- 0x48: { code: 'KeyH', keyCap: 'h' },
- 0x49: { code: 'KeyI', keyCap: 'i' },
- 0x4A: { code: 'KeyJ', keyCap: 'j' },
- 0x4B: { code: 'KeyK', keyCap: 'k' },
- 0x4C: { code: 'KeyL', keyCap: 'l' },
- 0x4D: { code: 'KeyM', keyCap: 'm' },
- 0x4E: { code: 'KeyN', keyCap: 'n' },
- 0x4F: { code: 'KeyO', keyCap: 'o' },
- 0x50: { code: 'KeyP', keyCap: 'p' },
- 0x51: { code: 'KeyQ', keyCap: 'q' },
- 0x52: { code: 'KeyR', keyCap: 'r' },
- 0x53: { code: 'KeyS', keyCap: 's' },
- 0x54: { code: 'KeyT', keyCap: 't' },
- 0x55: { code: 'KeyU', keyCap: 'u' },
- 0x56: { code: 'KeyV', keyCap: 'v' },
- 0x57: { code: 'KeyW', keyCap: 'w' },
- 0x58: { code: 'KeyX', keyCap: 'x' },
- 0x59: { code: 'KeyY', keyCap: 'y' },
- 0x5A: { code: 'KeyZ', keyCap: 'z' },
- 0x5B: { code: 'OSLeft', location: LEFT },
- 0x5C: { code: 'OSRight', location: RIGHT },
- 0x5D: { code: 'ContextMenu' },
-
- 0x5F: { code: 'Standby' },
- 0x60: { code: 'Numpad0', keyCap: '0', location: NUMPAD },
- 0x61: { code: 'Numpad1', keyCap: '1', location: NUMPAD },
- 0x62: { code: 'Numpad2', keyCap: '2', location: NUMPAD },
- 0x63: { code: 'Numpad3', keyCap: '3', location: NUMPAD },
- 0x64: { code: 'Numpad4', keyCap: '4', location: NUMPAD },
- 0x65: { code: 'Numpad5', keyCap: '5', location: NUMPAD },
- 0x66: { code: 'Numpad6', keyCap: '6', location: NUMPAD },
- 0x67: { code: 'Numpad7', keyCap: '7', location: NUMPAD },
- 0x68: { code: 'Numpad8', keyCap: '8', location: NUMPAD },
- 0x69: { code: 'Numpad9', keyCap: '9', location: NUMPAD },
- 0x6A: { code: 'NumpadMultiply', keyCap: '*', location: NUMPAD },
- 0x6B: { code: 'NumpadAdd', keyCap: '+', location: NUMPAD },
- 0x6C: { code: 'NumpadComma', keyCap: ',', location: NUMPAD },
- 0x6D: { code: 'NumpadSubtract', keyCap: '-', location: NUMPAD },
- 0x6E: { code: 'NumpadDecimal', keyCap: '.', location: NUMPAD },
- 0x6F: { code: 'NumpadDivide', keyCap: '/', location: NUMPAD },
- 0x70: { code: 'F1' },
- 0x71: { code: 'F2' },
- 0x72: { code: 'F3' },
- 0x73: { code: 'F4' },
- 0x74: { code: 'F5' },
- 0x75: { code: 'F6' },
- 0x76: { code: 'F7' },
- 0x77: { code: 'F8' },
- 0x78: { code: 'F9' },
- 0x79: { code: 'F10' },
- 0x7A: { code: 'F11' },
- 0x7B: { code: 'F12' },
- 0x7C: { code: 'F13' },
- 0x7D: { code: 'F14' },
- 0x7E: { code: 'F15' },
- 0x7F: { code: 'F16' },
- 0x80: { code: 'F17' },
- 0x81: { code: 'F18' },
- 0x82: { code: 'F19' },
- 0x83: { code: 'F20' },
- 0x84: { code: 'F21' },
- 0x85: { code: 'F22' },
- 0x86: { code: 'F23' },
- 0x87: { code: 'F24' },
-
- 0x90: { code: 'NumLock', location: NUMPAD },
- 0x91: { code: 'ScrollLock' },
-
-
-
- 0xA0: { code: 'ShiftLeft', location: LEFT },
- 0xA1: { code: 'ShiftRight', location: RIGHT },
- 0xA2: { code: 'ControlLeft', location: LEFT },
- 0xA3: { code: 'ControlRight', location: RIGHT },
- 0xA4: { code: 'AltLeft', location: LEFT },
- 0xA5: { code: 'AltRight', location: RIGHT },
- 0xA6: { code: 'BrowserBack' },
- 0xA7: { code: 'BrowserForward' },
- 0xA8: { code: 'BrowserRefresh' },
- 0xA9: { code: 'BrowserStop' },
- 0xAA: { code: 'BrowserSearch' },
- 0xAB: { code: 'BrowserFavorites' },
- 0xAC: { code: 'BrowserHome' },
- 0xAD: { code: 'VolumeMute' },
- 0xAE: { code: 'VolumeDown' },
- 0xAF: { code: 'VolumeUp' },
- 0xB0: { code: 'MediaTrackNext' },
- 0xB1: { code: 'MediaTrackPrevious' },
- 0xB2: { code: 'MediaStop' },
- 0xB3: { code: 'MediaPlayPause' },
- 0xB4: { code: 'LaunchMail' },
- 0xB5: { code: 'MediaSelect' },
- 0xB6: { code: 'LaunchApp1' },
- 0xB7: { code: 'LaunchApp2' },
-
- 0xBA: { code: 'Semicolon', keyCap: ';' },
- 0xBB: { code: 'Equal', keyCap: '=' },
- 0xBC: { code: 'Comma', keyCap: ',' },
- 0xBD: { code: 'Minus', keyCap: '-' },
- 0xBE: { code: 'Period', keyCap: '.' },
- 0xBF: { code: 'Slash', keyCap: '/' },
- 0xC0: { code: 'Backquote', keyCap: '`' },
-
-
-
- 0xDB: { code: 'BracketLeft', keyCap: '[' },
- 0xDC: { code: 'Backslash', keyCap: '\\' },
- 0xDD: { code: 'BracketRight', keyCap: ']' },
- 0xDE: { code: 'Quote', keyCap: '\'' },
-
-
-
- 0xE2: { code: 'IntlBackslash', keyCap: '\\' },
-
- 0xE5: { code: 'Process' },
-
-
-
-
-
- 0xF6: { code: 'Attn' },
- 0xF7: { code: 'CrSel' },
- 0xF8: { code: 'ExSel' },
- 0xF9: { code: 'EraseEof' },
- 0xFA: { code: 'Play' },
- 0xFB: { code: 'ZoomToggle' },
-
-
- 0xFE: { code: 'Clear' }
- };
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- mergeIf(keyCodeToInfoTable,
- 'moz', {
- 0x3B: { code: 'Semicolon', keyCap: ';' },
- 0x3D: { code: 'Equal', keyCap: '=' },
- 0x6B: { code: 'Equal', keyCap: '=' },
- 0x6D: { code: 'Minus', keyCap: '-' },
- 0xBB: { code: 'NumpadAdd', keyCap: '+', location: NUMPAD },
- 0xBD: { code: 'NumpadSubtract', keyCap: '-', location: NUMPAD }
- });
- mergeIf(keyCodeToInfoTable,
- 'moz-mac', {
- 0x0C: { code: 'NumLock', location: NUMPAD },
- 0xAD: { code: 'Minus', keyCap: '-' }
- });
- mergeIf(keyCodeToInfoTable,
- 'moz-win', {
- 0xAD: { code: 'Minus', keyCap: '-' }
- });
- mergeIf(keyCodeToInfoTable,
- 'chrome-mac', {
- 0x5D: { code: 'OSRight', location: RIGHT }
- });
-
- if (0) {
- mergeIf(keyCodeToInfoTable,
- 'chrome-win', {
- 0xC0: { code: 'Quote', keyCap: '\'' },
- 0xDE: { code: 'Backslash', keyCap: '\\' },
- 0xDF: { code: 'Backquote', keyCap: '`' }
- });
- mergeIf(keyCodeToInfoTable,
- 'ie', {
- 0xC0: { code: 'Quote', keyCap: '\'' },
- 0xDE: { code: 'Backslash', keyCap: '\\' },
- 0xDF: { code: 'Backquote', keyCap: '`' }
- });
- }
- mergeIf(keyCodeToInfoTable,
- 'safari', {
- 0x03: { code: 'Enter' },
- 0x19: { code: 'Tab' }
- });
- mergeIf(keyCodeToInfoTable,
- 'ios', {
- 0x0A: { code: 'Enter', location: STANDARD }
- });
- mergeIf(keyCodeToInfoTable,
- 'safari-mac', {
- 0x5B: { code: 'OSLeft', location: LEFT },
- 0x5D: { code: 'OSRight', location: RIGHT },
- 0xE5: { code: 'KeyQ', keyCap: 'Q' }
- });
-
-
-
-
-
-
-
-
- var keyIdentifierTable = {};
- if ('cros' === os) {
- keyIdentifierTable['U+00A0'] = { code: 'ShiftLeft', location: LEFT };
- keyIdentifierTable['U+00A1'] = { code: 'ShiftRight', location: RIGHT };
- keyIdentifierTable['U+00A2'] = { code: 'ControlLeft', location: LEFT };
- keyIdentifierTable['U+00A3'] = { code: 'ControlRight', location: RIGHT };
- keyIdentifierTable['U+00A4'] = { code: 'AltLeft', location: LEFT };
- keyIdentifierTable['U+00A5'] = { code: 'AltRight', location: RIGHT };
- }
- if ('chrome-mac' === browser_os) {
- keyIdentifierTable['U+0010'] = { code: 'ContextMenu' };
- }
- if ('safari-mac' === browser_os) {
- keyIdentifierTable['U+0010'] = { code: 'ContextMenu' };
- }
- if ('ios' === os) {
-
- keyIdentifierTable['U+0010'] = { code: 'Function' };
- keyIdentifierTable['U+001C'] = { code: 'ArrowLeft' };
- keyIdentifierTable['U+001D'] = { code: 'ArrowRight' };
- keyIdentifierTable['U+001E'] = { code: 'ArrowUp' };
- keyIdentifierTable['U+001F'] = { code: 'ArrowDown' };
- keyIdentifierTable['U+0001'] = { code: 'Home' };
- keyIdentifierTable['U+0004'] = { code: 'End' };
- keyIdentifierTable['U+000B'] = { code: 'PageUp' };
- keyIdentifierTable['U+000C'] = { code: 'PageDown' };
- }
-
-
-
-
-
-
-
-
- var locationTable = [];
- locationTable[LEFT] = {
- 0x10: { code: 'ShiftLeft', location: LEFT },
- 0x11: { code: 'ControlLeft', location: LEFT },
- 0x12: { code: 'AltLeft', location: LEFT }
- };
- locationTable[RIGHT] = {
- 0x10: { code: 'ShiftRight', location: RIGHT },
- 0x11: { code: 'ControlRight', location: RIGHT },
- 0x12: { code: 'AltRight', location: RIGHT }
- };
- locationTable[NUMPAD] = {
- 0x0D: { code: 'NumpadEnter', location: NUMPAD }
- };
- mergeIf(locationTable[NUMPAD], 'moz', {
- 0x6D: { code: 'NumpadSubtract', location: NUMPAD },
- 0x6B: { code: 'NumpadAdd', location: NUMPAD }
- });
- mergeIf(locationTable[LEFT], 'moz-mac', {
- 0xE0: { code: 'OSLeft', location: LEFT }
- });
- mergeIf(locationTable[RIGHT], 'moz-mac', {
- 0xE0: { code: 'OSRight', location: RIGHT }
- });
- mergeIf(locationTable[RIGHT], 'moz-win', {
- 0x5B: { code: 'OSRight', location: RIGHT }
- });
- mergeIf(locationTable[RIGHT], 'mac', {
- 0x5D: { code: 'OSRight', location: RIGHT }
- });
- mergeIf(locationTable[NUMPAD], 'chrome-mac', {
- 0x0C: { code: 'NumLock', location: NUMPAD }
- });
- mergeIf(locationTable[NUMPAD], 'safari-mac', {
- 0x0C: { code: 'NumLock', location: NUMPAD },
- 0xBB: { code: 'NumpadAdd', location: NUMPAD },
- 0xBD: { code: 'NumpadSubtract', location: NUMPAD },
- 0xBE: { code: 'NumpadDecimal', location: NUMPAD },
- 0xBF: { code: 'NumpadDivide', location: NUMPAD }
- });
-
-
-
-
-
-
-
-
-
-
- var codeToKeyTable = {
-
- ShiftLeft: { key: 'Shift' },
- ShiftRight: { key: 'Shift' },
- ControlLeft: { key: 'Control' },
- ControlRight: { key: 'Control' },
- AltLeft: { key: 'Alt' },
- AltRight: { key: 'Alt' },
- OSLeft: { key: 'OS' },
- OSRight: { key: 'OS' },
-
- NumpadEnter: { key: 'Enter' },
- Space: { key: ' ' },
-
- Digit0: { key: '0', shiftKey: ')' },
- Digit1: { key: '1', shiftKey: '!' },
- Digit2: { key: '2', shiftKey: '@' },
- Digit3: { key: '3', shiftKey: '#' },
- Digit4: { key: '4', shiftKey: '$' },
- Digit5: { key: '5', shiftKey: '%' },
- Digit6: { key: '6', shiftKey: '^' },
- Digit7: { key: '7', shiftKey: '&' },
- Digit8: { key: '8', shiftKey: '*' },
- Digit9: { key: '9', shiftKey: '(' },
- KeyA: { key: 'a', shiftKey: 'A' },
- KeyB: { key: 'b', shiftKey: 'B' },
- KeyC: { key: 'c', shiftKey: 'C' },
- KeyD: { key: 'd', shiftKey: 'D' },
- KeyE: { key: 'e', shiftKey: 'E' },
- KeyF: { key: 'f', shiftKey: 'F' },
- KeyG: { key: 'g', shiftKey: 'G' },
- KeyH: { key: 'h', shiftKey: 'H' },
- KeyI: { key: 'i', shiftKey: 'I' },
- KeyJ: { key: 'j', shiftKey: 'J' },
- KeyK: { key: 'k', shiftKey: 'K' },
- KeyL: { key: 'l', shiftKey: 'L' },
- KeyM: { key: 'm', shiftKey: 'M' },
- KeyN: { key: 'n', shiftKey: 'N' },
- KeyO: { key: 'o', shiftKey: 'O' },
- KeyP: { key: 'p', shiftKey: 'P' },
- KeyQ: { key: 'q', shiftKey: 'Q' },
- KeyR: { key: 'r', shiftKey: 'R' },
- KeyS: { key: 's', shiftKey: 'S' },
- KeyT: { key: 't', shiftKey: 'T' },
- KeyU: { key: 'u', shiftKey: 'U' },
- KeyV: { key: 'v', shiftKey: 'V' },
- KeyW: { key: 'w', shiftKey: 'W' },
- KeyX: { key: 'x', shiftKey: 'X' },
- KeyY: { key: 'y', shiftKey: 'Y' },
- KeyZ: { key: 'z', shiftKey: 'Z' },
- Numpad0: { key: '0' },
- Numpad1: { key: '1' },
- Numpad2: { key: '2' },
- Numpad3: { key: '3' },
- Numpad4: { key: '4' },
- Numpad5: { key: '5' },
- Numpad6: { key: '6' },
- Numpad7: { key: '7' },
- Numpad8: { key: '8' },
- Numpad9: { key: '9' },
- NumpadMultiply: { key: '*' },
- NumpadAdd: { key: '+' },
- NumpadComma: { key: ',' },
- NumpadSubtract: { key: '-' },
- NumpadDecimal: { key: '.' },
- NumpadDivide: { key: '/' },
- Semicolon: { key: ';', shiftKey: ':' },
- Equal: { key: '=', shiftKey: '+' },
- Comma: { key: ',', shiftKey: '<' },
- Minus: { key: '-', shiftKey: '_' },
- Period: { key: '.', shiftKey: '>' },
- Slash: { key: '/', shiftKey: '?' },
- Backquote: { key: '`', shiftKey: '~' },
- BracketLeft: { key: '[', shiftKey: '{' },
- Backslash: { key: '\\', shiftKey: '|' },
- BracketRight: { key: ']', shiftKey: '}' },
- Quote: { key: '\'', shiftKey: '"' },
- IntlBackslash: { key: '\\', shiftKey: '|' }
- };
- mergeIf(codeToKeyTable, 'mac', {
- OSLeft: { key: 'Meta' },
- OSRight: { key: 'Meta' }
- });
-
-
- var keyFixTable = {
- Esc: 'Escape',
- Nonconvert: 'NonConvert',
- Left: 'ArrowLeft',
- Up: 'ArrowUp',
- Right: 'ArrowRight',
- Down: 'ArrowDown',
- Del: 'Delete',
- Menu: 'ContextMenu',
- MediaNextTrack: 'MediaTrackNext',
- MediaPreviousTrack: 'MediaTrackPrevious',
- SelectMedia: 'MediaSelect',
- HalfWidth: 'Hankaku',
- FullWidth: 'Zenkaku',
- RomanCharacters: 'Romaji',
- Crsel: 'CrSel',
- Exsel: 'ExSel',
- Zoom: 'ZoomToggle'
- };
-
-
-
-
-
- var codeTable = remap(keyCodeToInfoTable, 'code');
- try {
- var nativeLocation = nativeKeyboardEvent && ('location' in new KeyboardEvent(''));
- } catch (_) {}
- function keyInfoForEvent(event) {
- var keyCode = 'keyCode' in event ? event.keyCode : 'which' in event ? event.which : 0;
- var keyInfo = (function(){
- if (nativeLocation || 'keyLocation' in event) {
- var location = nativeLocation ? event.location : event.keyLocation;
- if (location && keyCode in locationTable[location]) {
- return locationTable[location][keyCode];
- }
- }
- if ('keyIdentifier' in event && event.keyIdentifier in keyIdentifierTable) {
- return keyIdentifierTable[event.keyIdentifier];
- }
- if (keyCode in keyCodeToInfoTable) {
- return keyCodeToInfoTable[keyCode];
- }
- return null;
- }());
-
- if (0) {
-
-
-
- switch (event.keyIdentifier) {
- case 'U+0010': keyInfo = { code: 'Function' }; break;
- case 'U+001C': keyInfo = { code: 'ArrowLeft' }; break;
- case 'U+001D': keyInfo = { code: 'ArrowRight' }; break;
- case 'U+001E': keyInfo = { code: 'ArrowUp' }; break;
- case 'U+001F': keyInfo = { code: 'ArrowDown' }; break;
- }
- }
- if (!keyInfo)
- return null;
- var key = (function() {
- var entry = codeToKeyTable[keyInfo.code];
- if (!entry) return keyInfo.code;
- return (event.shiftKey && 'shiftKey' in entry) ? entry.shiftKey : entry.key;
- }());
- return {
- code: keyInfo.code,
- key: key,
- location: keyInfo.location,
- keyCap: keyInfo.keyCap
- };
- }
- function queryKeyCap(code, locale) {
- code = String(code);
- if (!codeTable.hasOwnProperty(code)) return 'Undefined';
- if (locale && String(locale).toLowerCase() !== 'en-us') throw Error('Unsupported locale');
- var keyInfo = codeTable[code];
- return keyInfo.keyCap || keyInfo.code || 'Undefined';
- }
- if ('KeyboardEvent' in global && 'defineProperty' in Object) {
- (function() {
- function define(o, p, v) {
- if (p in o) return;
- Object.defineProperty(o, p, v);
- }
- define(KeyboardEvent.prototype, 'code', { get: function() {
- var keyInfo = keyInfoForEvent(this);
- return keyInfo ? keyInfo.code : '';
- }});
-
- if ('key' in KeyboardEvent.prototype) {
- var desc = Object.getOwnPropertyDescriptor(KeyboardEvent.prototype, 'key');
- Object.defineProperty(KeyboardEvent.prototype, 'key', { get: function() {
- var key = desc.get.call(this);
- return keyFixTable.hasOwnProperty(key) ? keyFixTable[key] : key;
- }});
- }
- define(KeyboardEvent.prototype, 'key', { get: function() {
- var keyInfo = keyInfoForEvent(this);
- return (keyInfo && 'key' in keyInfo) ? keyInfo.key : 'Unidentified';
- }});
- define(KeyboardEvent.prototype, 'location', { get: function() {
- var keyInfo = keyInfoForEvent(this);
- return (keyInfo && 'location' in keyInfo) ? keyInfo.location : STANDARD;
- }});
- define(KeyboardEvent.prototype, 'locale', { get: function() {
- return '';
- }});
- }());
- }
- if (!('queryKeyCap' in global.KeyboardEvent))
- global.KeyboardEvent.queryKeyCap = queryKeyCap;
-
- global.identifyKey = function(event) {
- if ('code' in event)
- return;
- var keyInfo = keyInfoForEvent(event);
- event.code = keyInfo ? keyInfo.code : '';
- event.key = (keyInfo && 'key' in keyInfo) ? keyInfo.key : 'Unidentified';
- event.location = ('location' in event) ? event.location :
- ('keyLocation' in event) ? event.keyLocation :
- (keyInfo && 'location' in keyInfo) ? keyInfo.location : STANDARD;
- event.locale = '';
- };
- } (window));
- },{}],5:[function(require,module,exports){
- var CANNON = require('cannon'),
- math = require('./src/components/math');
- module.exports = {
- 'dynamic-body': require('./src/components/body/dynamic-body'),
- 'static-body': require('./src/components/body/static-body'),
- 'constraint': require('./src/components/constraint'),
- 'system': require('./src/system/physics'),
- registerAll: function (AFRAME) {
- if (this._registered) return;
- AFRAME = AFRAME || window.AFRAME;
- math.registerAll();
- if (!AFRAME.systems.physics) AFRAME.registerSystem('physics', this.system);
- if (!AFRAME.components['dynamic-body']) AFRAME.registerComponent('dynamic-body', this['dynamic-body']);
- if (!AFRAME.components['static-body']) AFRAME.registerComponent('static-body', this['static-body']);
- if (!AFRAME.components['constraint']) AFRAME.registerComponent('constraint', this['constraint']);
- this._registered = true;
- }
- };
- window.CANNON = window.CANNON || CANNON;
- },{"./src/components/body/dynamic-body":8,"./src/components/body/static-body":9,"./src/components/constraint":10,"./src/components/math":11,"./src/system/physics":15,"cannon":17}],6:[function(require,module,exports){
- var CANNON = require('cannon');
- CANNON.shape2mesh = function(body){
- var obj = new THREE.Object3D();
- for (var l = 0; l < body.shapes.length; l++) {
- var shape = body.shapes[l];
- var mesh;
- switch(shape.type){
- case CANNON.Shape.types.SPHERE:
- var sphere_geometry = new THREE.SphereGeometry( shape.radius, 8, 8);
- mesh = new THREE.Mesh( sphere_geometry, this.currentMaterial );
- break;
- case CANNON.Shape.types.PARTICLE:
- mesh = new THREE.Mesh( this.particleGeo, this.particleMaterial );
- var s = this.settings;
- mesh.scale.set(s.particleSize,s.particleSize,s.particleSize);
- break;
- case CANNON.Shape.types.PLANE:
- var geometry = new THREE.PlaneGeometry(10, 10, 4, 4);
- mesh = new THREE.Object3D();
- var submesh = new THREE.Object3D();
- var ground = new THREE.Mesh( geometry, this.currentMaterial );
- ground.scale.set(100, 100, 100);
- submesh.add(ground);
- ground.castShadow = true;
- ground.receiveShadow = true;
- mesh.add(submesh);
- break;
- case CANNON.Shape.types.BOX:
- var box_geometry = new THREE.BoxGeometry( shape.halfExtents.x*2,
- shape.halfExtents.y*2,
- shape.halfExtents.z*2 );
- mesh = new THREE.Mesh( box_geometry, this.currentMaterial );
- break;
- case CANNON.Shape.types.CONVEXPOLYHEDRON:
- var geo = new THREE.Geometry();
-
- for (var i = 0; i < shape.vertices.length; i++) {
- var v = shape.vertices[i];
- geo.vertices.push(new THREE.Vector3(v.x, v.y, v.z));
- }
- for(var i=0; i < shape.faces.length; i++){
- var face = shape.faces[i];
-
- var a = face[0];
- for (var j = 1; j < face.length - 1; j++) {
- var b = face[j];
- var c = face[j + 1];
- geo.faces.push(new THREE.Face3(a, b, c));
- }
- }
- geo.computeBoundingSphere();
- geo.computeFaceNormals();
- mesh = new THREE.Mesh( geo, this.currentMaterial );
- break;
- case CANNON.Shape.types.HEIGHTFIELD:
- var geometry = new THREE.Geometry();
- var v0 = new CANNON.Vec3();
- var v1 = new CANNON.Vec3();
- var v2 = new CANNON.Vec3();
- for (var xi = 0; xi < shape.data.length - 1; xi++) {
- for (var yi = 0; yi < shape.data[xi].length - 1; yi++) {
- for (var k = 0; k < 2; k++) {
- shape.getConvexTrianglePillar(xi, yi, k===0);
- v0.copy(shape.pillarConvex.vertices[0]);
- v1.copy(shape.pillarConvex.vertices[1]);
- v2.copy(shape.pillarConvex.vertices[2]);
- v0.vadd(shape.pillarOffset, v0);
- v1.vadd(shape.pillarOffset, v1);
- v2.vadd(shape.pillarOffset, v2);
- geometry.vertices.push(
- new THREE.Vector3(v0.x, v0.y, v0.z),
- new THREE.Vector3(v1.x, v1.y, v1.z),
- new THREE.Vector3(v2.x, v2.y, v2.z)
- );
- var i = geometry.vertices.length - 3;
- geometry.faces.push(new THREE.Face3(i, i+1, i+2));
- }
- }
- }
- geometry.computeBoundingSphere();
- geometry.computeFaceNormals();
- mesh = new THREE.Mesh(geometry, this.currentMaterial);
- break;
- case CANNON.Shape.types.TRIMESH:
- var geometry = new THREE.Geometry();
- var v0 = new CANNON.Vec3();
- var v1 = new CANNON.Vec3();
- var v2 = new CANNON.Vec3();
- for (var i = 0; i < shape.indices.length / 3; i++) {
- shape.getTriangleVertices(i, v0, v1, v2);
- geometry.vertices.push(
- new THREE.Vector3(v0.x, v0.y, v0.z),
- new THREE.Vector3(v1.x, v1.y, v1.z),
- new THREE.Vector3(v2.x, v2.y, v2.z)
- );
- var j = geometry.vertices.length - 3;
- geometry.faces.push(new THREE.Face3(j, j+1, j+2));
- }
- geometry.computeBoundingSphere();
- geometry.computeFaceNormals();
- mesh = new THREE.Mesh(geometry, this.currentMaterial);
- break;
- default:
- throw "Visual type not recognized: "+shape.type;
- }
- mesh.receiveShadow = true;
- mesh.castShadow = true;
- if(mesh.children){
- for(var i=0; i<mesh.children.length; i++){
- mesh.children[i].castShadow = true;
- mesh.children[i].receiveShadow = true;
- if(mesh.children[i]){
- for(var j=0; j<mesh.children[i].length; j++){
- mesh.children[i].children[j].castShadow = true;
- mesh.children[i].children[j].receiveShadow = true;
- }
- }
- }
- }
- var o = body.shapeOffsets[l];
- var q = body.shapeOrientations[l];
- mesh.position.set(o.x, o.y, o.z);
- mesh.quaternion.set(q.x, q.y, q.z, q.w);
- obj.add(mesh);
- }
- return obj;
- };
- module.exports = CANNON.shape2mesh;
- },{"cannon":17}],7:[function(require,module,exports){
- var CANNON = require('cannon'),
- mesh2shape = require('three-to-cannon');
- require('../../../lib/CANNON-shape2mesh');
- module.exports = {
- schema: {
- shape: {default: 'auto', oneOf: ['auto', 'box', 'cylinder', 'sphere', 'hull', 'none']},
- cylinderAxis: {default: 'y', oneOf: ['x', 'y', 'z']},
- sphereRadius: {default: NaN}
- },
-
- init: function () {
- this.system = this.el.sceneEl.systems.physics;
- if (this.el.sceneEl.hasLoaded) {
- this.initBody();
- } else {
- this.el.sceneEl.addEventListener('loaded', this.initBody.bind(this));
- }
- },
-
- initBody: function () {
- var shape,
- el = this.el,
- data = this.data,
- pos = el.getAttribute('position');
- this.body = new CANNON.Body({
- mass: data.mass || 0,
- material: this.system.material,
- position: new CANNON.Vec3(pos.x, pos.y, pos.z),
- linearDamping: data.linearDamping,
- angularDamping: data.angularDamping
- });
-
-
-
-
-
- this.el.object3D.updateMatrixWorld(true);
- if(data.shape !== 'none') {
- var options = data.shape === 'auto' ? undefined : AFRAME.utils.extend({}, this.data, {
- type: mesh2shape.Type[data.shape.toUpperCase()]
- });
- shape = mesh2shape(this.el.object3D, options);
- if (!shape) {
- this.el.addEventListener('model-loaded', this.initBody.bind(this));
- return;
- }
- this.body.addShape(shape, shape.offset, shape.orientation);
-
- if (this.system.debug) {
- this.createWireframe(this.body, shape);
- }
- }
-
- var rot = el.getAttribute('rotation');
- this.body.quaternion.setFromEuler(
- THREE.Math.degToRad(rot.x),
- THREE.Math.degToRad(rot.y),
- THREE.Math.degToRad(rot.z),
- 'XYZ'
- ).normalize();
- this.el.body = this.body;
- this.body.el = this.el;
- this.isLoaded = true;
-
- if (this.isPlaying) {
- this._play();
- }
- this.el.emit('body-loaded', {body: this.el.body});
- },
-
- play: function () {
- if (this.isLoaded) this._play();
- },
-
- _play: function () {
- this.system.addBehavior(this, this.system.Phase.SIMULATE);
- this.system.addBody(this.body);
- if (this.wireframe) this.el.sceneEl.object3D.add(this.wireframe);
- this.syncToPhysics();
- },
-
- pause: function () {
- if (!this.isLoaded) return;
- this.system.removeBehavior(this, this.system.Phase.SIMULATE);
- this.system.removeBody(this.body);
- if (this.wireframe) this.el.sceneEl.object3D.remove(this.wireframe);
- },
-
- remove: function () {
- this.pause();
- delete this.body.el;
- delete this.body;
- delete this.el.body;
- delete this.wireframe;
- },
-
- createWireframe: function (body, shape) {
- var offset = shape.offset,
- orientation = shape.orientation,
- mesh = CANNON.shape2mesh(body).children[0];
- this.wireframe = new THREE.LineSegments(
- new THREE.EdgesGeometry(mesh.geometry),
- new THREE.LineBasicMaterial({color: 0xff0000})
- );
- if (offset) {
- this.wireframe.offset = offset.clone();
- }
- if (orientation) {
- orientation.inverse(orientation);
- this.wireframe.orientation = new THREE.Quaternion(
- orientation.x,
- orientation.y,
- orientation.z,
- orientation.w
- );
- }
- this.syncWireframe();
- },
-
- syncWireframe: function () {
- var offset,
- wireframe = this.wireframe;
- if (!this.wireframe) return;
-
-
- wireframe.quaternion.copy(this.body.quaternion);
- if (wireframe.orientation) {
- wireframe.quaternion.multiply(wireframe.orientation);
- }
-
-
- wireframe.position.copy(this.body.position);
- if (wireframe.offset) {
- offset = wireframe.offset.clone().applyQuaternion(wireframe.quaternion);
- wireframe.position.add(offset);
- }
- wireframe.updateMatrix();
- },
-
- syncToPhysics: (function () {
- var q = new THREE.Quaternion(),
- v = new THREE.Vector3();
- return function () {
- var el = this.el,
- parentEl = el.parentEl,
- body = this.body;
- if (!body) return;
- if (el.components.velocity) body.velocity.copy(el.getAttribute('velocity'));
- if (parentEl.isScene) {
- body.quaternion.copy(el.object3D.quaternion);
- body.position.copy(el.object3D.position);
- } else {
- el.object3D.getWorldQuaternion(q);
- body.quaternion.copy(q);
- el.object3D.getWorldPosition(v);
- body.position.copy(v);
- }
- if (this.wireframe) this.syncWireframe();
- };
- }()),
-
- syncFromPhysics: (function () {
- var v = new THREE.Vector3(),
- q1 = new THREE.Quaternion(),
- q2 = new THREE.Quaternion();
- return function () {
- var el = this.el,
- parentEl = el.parentEl,
- body = this.body;
- if (!body) return;
- if (parentEl.isScene) {
- el.setAttribute('quaternion', body.quaternion);
- el.setAttribute('position', body.position);
- } else {
-
- q1.copy(body.quaternion);
- parentEl.object3D.getWorldQuaternion(q2);
- q1.multiply(q2.inverse());
- el.setAttribute('quaternion', {x: q1.x, y: q1.y, z: q1.z, w: q1.w});
- v.copy(body.position);
- parentEl.object3D.worldToLocal(v);
- el.setAttribute('position', {x: v.x, y: v.y, z: v.z});
- }
- if (this.wireframe) this.syncWireframe();
- };
- }())
- };
- },{"../../../lib/CANNON-shape2mesh":6,"cannon":17,"three-to-cannon":73}],8:[function(require,module,exports){
- var Body = require('./body');
- module.exports = AFRAME.utils.extend({}, Body, {
- dependencies: ['quaternion', 'velocity'],
- schema: AFRAME.utils.extend({}, Body.schema, {
- mass: { default: 5 },
- linearDamping: { default: 0.01 },
- angularDamping: { default: 0.01 }
- }),
- step: function () {
- this.syncFromPhysics();
- }
- });
- },{"./body":7}],9:[function(require,module,exports){
- var Body = require('./body');
- module.exports = AFRAME.utils.extend({}, Body, {
- step: function () {
- this.syncToPhysics();
- }
- });
- },{"./body":7}],10:[function(require,module,exports){
- var CANNON = require('cannon');
- module.exports = {
- dependencies: ['dynamic-body'],
- multiple: true,
- schema: {
-
- type: {default: 'lock', oneOf: ['coneTwist', 'distance', 'hinge', 'lock', 'pointToPoint']},
-
- target: {type: 'selector'},
-
- maxForce: {default: 1e6, min: 0},
-
- collideConnected: {default: true},
-
- wakeUpBodies: {default: true},
-
- distance: {default: 0, min: 0},
-
- pivot: {type: 'vec3'},
- targetPivot: {type: 'vec3'},
-
- axis: {type: 'vec3', default: { x: 0, y: 0, z: 1 }},
- targetAxis: {type: 'vec3', default: { x: 0, y: 0, z: 1}}
- },
- init: function () {
- this.system = this.el.sceneEl.systems.physics;
- this.constraint = null;
- },
- remove: function () {
- if (!this.constraint) return;
- this.system.world.removeConstraint(this.constraint);
- this.constraint = null;
- },
- update: function () {
- var el = this.el,
- data = this.data;
- this.remove();
- if (!el.body || !data.target.body) {
- (el.body ? data.target : el).addEventListener('body-loaded', this.update.bind(this, {}));
- return;
- }
- this.constraint = this.createConstraint();
- this.system.world.addConstraint(this.constraint);
- },
-
- createConstraint: function () {
- var data = this.data,
- pivot = new CANNON.Vec3(data.pivot.x, data.pivot.y, data.pivot.z),
- targetPivot = new CANNON.Vec3(data.targetPivot.x, data.targetPivot.y, data.targetPivot.z),
- axis = new CANNON.Vec3(data.axis.x, data.axis.y, data.axis.z),
- targetAxis= new CANNON.Vec3(data.targetAxis.x, data.targetAxis.y, data.targetAxis.z);
- var constraint;
- switch (data.type) {
- case 'lock':
- constraint = new CANNON.LockConstraint(
- this.el.body,
- data.target.body,
- {maxForce: data.maxForce}
- );
- break;
- case 'distance':
- constraint = new CANNON.DistanceConstraint(
- this.el.body,
- data.target.body,
- data.distance,
- data.maxForce
- );
- break;
- case 'hinge':
- constraint = new CANNON.HingeConstraint(
- this.el.body,
- data.target.body, {
- pivotA: pivot,
- pivotB: targetPivot,
- axisA: axis,
- axisB: targetAxis,
- maxForce: data.maxForce
- });
- break;
- case 'coneTwist':
- constraint = new CANNON.ConeTwistConstraint(
- this.el.body,
- data.target.body, {
- pivotA: pivot,
- pivotB: targetPivot,
- axisA: axis,
- axisB: targetAxis,
- maxForce: data.maxForce
- });
- break;
- case 'pointToPoint':
- constraint = new CANNON.PointToPointConstraint(
- this.el.body,
- pivot,
- data.target.body,
- targetPivot,
- data.maxForce);
- break;
- default:
- throw new Error('[constraint] Unexpected type: ' + data.type);
- }
- constraint.collideConnected = data.collideConnected;
- return constraint;
- }
- };
- },{"cannon":17}],11:[function(require,module,exports){
- module.exports = {
- 'velocity': require('./velocity'),
- 'quaternion': require('./quaternion'),
- registerAll: function (AFRAME) {
- if (this._registered) return;
- AFRAME = AFRAME || window.AFRAME;
- if (!AFRAME.components['velocity']) AFRAME.registerComponent('velocity', this.velocity);
- if (!AFRAME.components['quaternion']) AFRAME.registerComponent('quaternion', this.quaternion);
- this._registered = true;
- }
- };
- },{"./quaternion":12,"./velocity":13}],12:[function(require,module,exports){
- module.exports = {
- schema: {type: 'vec4'},
- play: function () {
- var el = this.el,
- q = el.object3D.quaternion;
- if (el.hasAttribute('rotation')) {
- el.components.rotation.update();
- el.setAttribute('quaternion', {x: q.x, y: q.y, z: q.z, w: q.w});
- el.removeAttribute('rotation');
- this.update();
- }
- },
- update: function () {
- var data = this.data;
- this.el.object3D.quaternion.set(data.x, data.y, data.z, data.w);
- }
- };
- },{}],13:[function(require,module,exports){
- module.exports = {
- schema: {type: 'vec3'},
- init: function () {
- this.system = this.el.sceneEl.systems.physics;
- if (this.system) {
- this.system.addBehavior(this, this.system.Phase.RENDER);
- }
- },
- remove: function () {
- if (this.system) {
- this.system.removeBehavior(this, this.system.Phase.RENDER);
- }
- },
- tick: function (t, dt) {
- if (!dt) return;
- if (this.system) return;
- this.step(t, dt);
- },
- step: function (t, dt) {
- if (!dt) return;
- var physics = this.el.sceneEl.systems.physics || {data: {maxInterval: 1 / 60}},
-
- velocity = this.el.getAttribute('velocity') || {x: 0, y: 0, z: 0},
- position = this.el.getAttribute('position') || {x: 0, y: 0, z: 0};
- dt = Math.min(dt, physics.data.maxInterval * 1000);
- this.el.setAttribute('position', {
- x: position.x + velocity.x * dt / 1000,
- y: position.y + velocity.y * dt / 1000,
- z: position.z + velocity.z * dt / 1000
- });
- }
- };
- },{}],14:[function(require,module,exports){
- module.exports = {
- GRAVITY: -9.8,
- MAX_INTERVAL: 4 / 60,
- ITERATIONS: 10,
- CONTACT_MATERIAL: {
- friction: 0.01,
- restitution: 0.3,
- contactEquationStiffness: 1e8,
- contactEquationRelaxation: 3,
- frictionEquationStiffness: 1e8,
- frictionEquationRegularization: 3
- }
- };
- },{}],15:[function(require,module,exports){
- var CANNON = require('cannon'),
- CONSTANTS = require('../constants'),
- C_GRAV = CONSTANTS.GRAVITY,
- C_MAT = CONSTANTS.CONTACT_MATERIAL;
- module.exports = {
- schema: {
- gravity: { default: C_GRAV },
- iterations: { default: CONSTANTS.ITERATIONS },
- friction: { default: C_MAT.friction },
- restitution: { default: C_MAT.restitution },
- contactEquationStiffness: { default: C_MAT.contactEquationStiffness },
- contactEquationRelaxation: { default: C_MAT.contactEquationRelaxation },
- frictionEquationStiffness: { default: C_MAT.frictionEquationStiffness },
- frictionEquationRegularization: { default: C_MAT.frictionEquationRegularization },
-
-
- maxInterval: { default: 4 / 60 },
-
- debug: { default: false },
- },
-
- Phase: {
- SIMULATE: 'sim',
- RENDER: 'render'
- },
-
- init: function () {
- var data = this.data;
-
- this.debug = data.debug;
- this.children = {};
- this.children[this.Phase.SIMULATE] = [];
- this.children[this.Phase.RENDER] = [];
- this.listeners = {};
- this.world = new CANNON.World();
- this.world.quatNormalizeSkip = 0;
- this.world.quatNormalizeFast = false;
-
- this.world.solver.iterations = data.iterations;
- this.world.gravity.set(0, data.gravity, 0);
- this.world.broadphase = new CANNON.NaiveBroadphase();
- this.material = new CANNON.Material({name: 'defaultMaterial'});
- this.contactMaterial = new CANNON.ContactMaterial(this.material, this.material, {
- friction: data.friction,
- restitution: data.restitution,
- contactEquationStiffness: data.contactEquationStiffness,
- contactEquationRelaxation: data.contactEquationRelaxation,
- frictionEquationStiffness: data.frictionEquationStiffness,
- frictionEquationRegularization: data.frictionEquationRegularization
- });
- this.world.addContactMaterial(this.contactMaterial);
- },
-
- tick: function (t, dt) {
- if (!dt) return;
- this.world.step(Math.min(dt / 1000, this.data.maxInterval));
- var i;
- for (i = 0; i < this.children[this.Phase.SIMULATE].length; i++) {
- this.children[this.Phase.SIMULATE][i].step(t, dt);
- }
- for (i = 0; i < this.children[this.Phase.RENDER].length; i++) {
- this.children[this.Phase.RENDER][i].step(t, dt);
- }
- },
-
- addBody: function (body) {
- this.listeners[body.id] = function (e) { body.el.emit('collide', e); };
- body.addEventListener('collide', this.listeners[body.id]);
- this.world.addBody(body);
- },
-
- removeBody: function (body) {
- body.removeEventListener('collide', this.listeners[body.id]);
- delete this.listeners[body.id];
- this.world.removeBody(body);
- },
-
- addBehavior: function (component, phase) {
- this.children[phase].push(component);
- },
-
- removeBehavior: function (component, phase) {
- this.children[phase].splice(this.children[phase].indexOf(component), 1);
- },
-
- update: function (previousData) {
- var data = this.data;
- if (data.debug !== previousData.debug) {
- console.warn('[physics] `debug` cannot be changed dynamically.');
- }
- if (data.maxInterval !== previousData.maxInterval);
- if (data.gravity !== previousData.gravity) this.world.gravity.set(0, data.gravity, 0);
- this.contactMaterial.friction = data.friction;
- this.contactMaterial.restitution = data.restitution;
- this.contactMaterial.contactEquationStiffness = data.contactEquationStiffness;
- this.contactMaterial.contactEquationRelaxation = data.contactEquationRelaxation;
- this.contactMaterial.frictionEquationStiffness = data.frictionEquationStiffness;
- this.contactMaterial.frictionEquationRegularization = data.frictionEquationRegularization;
- }
- };
- },{"../constants":14,"cannon":17}],16:[function(require,module,exports){
- module.exports={
- "_from": "github:donmccurdy/cannon.js#v0.6.2-dev1",
- "_id": "cannon@0.6.2",
- "_inBundle": false,
- "_integrity": "sha1-kuhwtr7Hd8jqU3mcndOx2tmf0RU=",
- "_location": "/cannon",
- "_phantomChildren": {},
- "_requested": {
- "type": "git",
- "raw": "cannon@github:donmccurdy/cannon.js#v0.6.2-dev1",
- "name": "cannon",
- "escapedName": "cannon",
- "rawSpec": "github:donmccurdy/cannon.js#v0.6.2-dev1",
- "saveSpec": "github:donmccurdy/cannon.js#v0.6.2-dev1",
- "fetchSpec": null,
- "gitCommittish": "v0.6.2-dev1"
- },
- "_requiredBy": [
- "/aframe-physics-system"
- ],
- "_resolved": "github:donmccurdy/cannon.js#022e8ba53fa83abf0ad8a0e4fd08623123838a17",
- "_spec": "cannon@github:donmccurdy/cannon.js#v0.6.2-dev1",
- "_where": "/Users/donmccurdy/Documents/Projects/aframe-extras/node_modules/aframe-physics-system",
- "author": {
- "name": "Stefan Hedman",
- "email": "schteppe@gmail.com",
- "url": "http://steffe.se"
- },
- "bugs": {
- "url": "https://github.com/schteppe/cannon.js/issues"
- },
- "bundleDependencies": false,
- "dependencies": {},
- "deprecated": false,
- "description": "A lightweight 3D physics engine written in JavaScript.",
- "devDependencies": {
- "browserify": "*",
- "grunt": "~0.4.0",
- "grunt-browserify": "^2.1.4",
- "grunt-contrib-concat": "~0.1.3",
- "grunt-contrib-jshint": "~0.1.1",
- "grunt-contrib-nodeunit": "^0.4.1",
- "grunt-contrib-uglify": "^0.5.1",
- "grunt-contrib-yuidoc": "^0.5.2",
- "jshint": "latest",
- "nodeunit": "^0.9.0",
- "uglify-js": "latest"
- },
- "engines": {
- "node": "*"
- },
- "homepage": "https://github.com/schteppe/cannon.js",
- "keywords": [
- "cannon.js",
- "cannon",
- "physics",
- "engine",
- "3d"
- ],
- "licenses": [
- {
- "type": "MIT"
- }
- ],
- "main": "./src/Cannon.js",
- "name": "cannon",
- "repository": {
- "type": "git",
- "url": "git+https://github.com/schteppe/cannon.js.git"
- },
- "version": "0.6.2"
- }
- },{}],17:[function(require,module,exports){
- module.exports = {
- version : require('../package.json').version,
- AABB : require('./collision/AABB'),
- ArrayCollisionMatrix : require('./collision/ArrayCollisionMatrix'),
- Body : require('./objects/Body'),
- Box : require('./shapes/Box'),
- Broadphase : require('./collision/Broadphase'),
- Constraint : require('./constraints/Constraint'),
- ContactEquation : require('./equations/ContactEquation'),
- Narrowphase : require('./world/Narrowphase'),
- ConeTwistConstraint : require('./constraints/ConeTwistConstraint'),
- ContactMaterial : require('./material/ContactMaterial'),
- ConvexPolyhedron : require('./shapes/ConvexPolyhedron'),
- Cylinder : require('./shapes/Cylinder'),
- DistanceConstraint : require('./constraints/DistanceConstraint'),
- Equation : require('./equations/Equation'),
- EventTarget : require('./utils/EventTarget'),
- FrictionEquation : require('./equations/FrictionEquation'),
- GSSolver : require('./solver/GSSolver'),
- GridBroadphase : require('./collision/GridBroadphase'),
- Heightfield : require('./shapes/Heightfield'),
- HingeConstraint : require('./constraints/HingeConstraint'),
- LockConstraint : require('./constraints/LockConstraint'),
- Mat3 : require('./math/Mat3'),
- Material : require('./material/Material'),
- NaiveBroadphase : require('./collision/NaiveBroadphase'),
- ObjectCollisionMatrix : require('./collision/ObjectCollisionMatrix'),
- Pool : require('./utils/Pool'),
- Particle : require('./shapes/Particle'),
- Plane : require('./shapes/Plane'),
- PointToPointConstraint : require('./constraints/PointToPointConstraint'),
- Quaternion : require('./math/Quaternion'),
- Ray : require('./collision/Ray'),
- RaycastVehicle : require('./objects/RaycastVehicle'),
- RaycastResult : require('./collision/RaycastResult'),
- RigidVehicle : require('./objects/RigidVehicle'),
- RotationalEquation : require('./equations/RotationalEquation'),
- RotationalMotorEquation : require('./equations/RotationalMotorEquation'),
- SAPBroadphase : require('./collision/SAPBroadphase'),
- SPHSystem : require('./objects/SPHSystem'),
- Shape : require('./shapes/Shape'),
- Solver : require('./solver/Solver'),
- Sphere : require('./shapes/Sphere'),
- SplitSolver : require('./solver/SplitSolver'),
- Spring : require('./objects/Spring'),
- Transform : require('./math/Transform'),
- Trimesh : require('./shapes/Trimesh'),
- Vec3 : require('./math/Vec3'),
- Vec3Pool : require('./utils/Vec3Pool'),
- World : require('./world/World'),
- };
- },{"../package.json":16,"./collision/AABB":18,"./collision/ArrayCollisionMatrix":19,"./collision/Broadphase":20,"./collision/GridBroadphase":21,"./collision/NaiveBroadphase":22,"./collision/ObjectCollisionMatrix":23,"./collision/Ray":25,"./collision/RaycastResult":26,"./collision/SAPBroadphase":27,"./constraints/ConeTwistConstraint":28,"./constraints/Constraint":29,"./constraints/DistanceConstraint":30,"./constraints/HingeConstraint":31,"./constraints/LockConstraint":32,"./constraints/PointToPointConstraint":33,"./equations/ContactEquation":35,"./equations/Equation":36,"./equations/FrictionEquation":37,"./equations/RotationalEquation":38,"./equations/RotationalMotorEquation":39,"./material/ContactMaterial":40,"./material/Material":41,"./math/Mat3":43,"./math/Quaternion":44,"./math/Transform":45,"./math/Vec3":46,"./objects/Body":47,"./objects/RaycastVehicle":48,"./objects/RigidVehicle":49,"./objects/SPHSystem":50,"./objects/Spring":51,"./shapes/Box":53,"./shapes/ConvexPolyhedron":54,"./shapes/Cylinder":55,"./shapes/Heightfield":56,"./shapes/Particle":57,"./shapes/Plane":58,"./shapes/Shape":59,"./shapes/Sphere":60,"./shapes/Trimesh":61,"./solver/GSSolver":62,"./solver/Solver":63,"./solver/SplitSolver":64,"./utils/EventTarget":65,"./utils/Pool":67,"./utils/Vec3Pool":70,"./world/Narrowphase":71,"./world/World":72}],18:[function(require,module,exports){
- var Vec3 = require('../math/Vec3');
- var Utils = require('../utils/Utils');
- module.exports = AABB;
- function AABB(options){
- options = options || {};
-
- this.lowerBound = new Vec3();
- if(options.lowerBound){
- this.lowerBound.copy(options.lowerBound);
- }
-
- this.upperBound = new Vec3();
- if(options.upperBound){
- this.upperBound.copy(options.upperBound);
- }
- }
- var tmp = new Vec3();
- AABB.prototype.setFromPoints = function(points, position, quaternion, skinSize){
- var l = this.lowerBound,
- u = this.upperBound,
- q = quaternion;
-
- l.copy(points[0]);
- if(q){
- q.vmult(l, l);
- }
- u.copy(l);
- for(var i = 1; i<points.length; i++){
- var p = points[i];
- if(q){
- q.vmult(p, tmp);
- p = tmp;
- }
- if(p.x > u.x){ u.x = p.x; }
- if(p.x < l.x){ l.x = p.x; }
- if(p.y > u.y){ u.y = p.y; }
- if(p.y < l.y){ l.y = p.y; }
- if(p.z > u.z){ u.z = p.z; }
- if(p.z < l.z){ l.z = p.z; }
- }
-
- if (position) {
- position.vadd(l, l);
- position.vadd(u, u);
- }
- if(skinSize){
- l.x -= skinSize;
- l.y -= skinSize;
- l.z -= skinSize;
- u.x += skinSize;
- u.y += skinSize;
- u.z += skinSize;
- }
- return this;
- };
- AABB.prototype.copy = function(aabb){
- this.lowerBound.copy(aabb.lowerBound);
- this.upperBound.copy(aabb.upperBound);
- return this;
- };
- AABB.prototype.clone = function(){
- return new AABB().copy(this);
- };
- AABB.prototype.extend = function(aabb){
- this.lowerBound.x = Math.min(this.lowerBound.x, aabb.lowerBound.x);
- this.upperBound.x = Math.max(this.upperBound.x, aabb.upperBound.x);
- this.lowerBound.y = Math.min(this.lowerBound.y, aabb.lowerBound.y);
- this.upperBound.y = Math.max(this.upperBound.y, aabb.upperBound.y);
- this.lowerBound.z = Math.min(this.lowerBound.z, aabb.lowerBound.z);
- this.upperBound.z = Math.max(this.upperBound.z, aabb.upperBound.z);
- };
- AABB.prototype.overlaps = function(aabb){
- var l1 = this.lowerBound,
- u1 = this.upperBound,
- l2 = aabb.lowerBound,
- u2 = aabb.upperBound;
-
-
-
-
- var overlapsX = ((l2.x <= u1.x && u1.x <= u2.x) || (l1.x <= u2.x && u2.x <= u1.x));
- var overlapsY = ((l2.y <= u1.y && u1.y <= u2.y) || (l1.y <= u2.y && u2.y <= u1.y));
- var overlapsZ = ((l2.z <= u1.z && u1.z <= u2.z) || (l1.z <= u2.z && u2.z <= u1.z));
- return overlapsX && overlapsY && overlapsZ;
- };
- AABB.prototype.volume = function(){
- var l = this.lowerBound,
- u = this.upperBound;
- return (u.x - l.x) * (u.y - l.y) * (u.z - l.z);
- };
- AABB.prototype.contains = function(aabb){
- var l1 = this.lowerBound,
- u1 = this.upperBound,
- l2 = aabb.lowerBound,
- u2 = aabb.upperBound;
-
-
-
-
- return (
- (l1.x <= l2.x && u1.x >= u2.x) &&
- (l1.y <= l2.y && u1.y >= u2.y) &&
- (l1.z <= l2.z && u1.z >= u2.z)
- );
- };
- AABB.prototype.getCorners = function(a, b, c, d, e, f, g, h){
- var l = this.lowerBound,
- u = this.upperBound;
- a.copy(l);
- b.set( u.x, l.y, l.z );
- c.set( u.x, u.y, l.z );
- d.set( l.x, u.y, u.z );
- e.set( u.x, l.y, l.z );
- f.set( l.x, u.y, l.z );
- g.set( l.x, l.y, u.z );
- h.copy(u);
- };
- var transformIntoFrame_corners = [
- new Vec3(),
- new Vec3(),
- new Vec3(),
- new Vec3(),
- new Vec3(),
- new Vec3(),
- new Vec3(),
- new Vec3()
- ];
- AABB.prototype.toLocalFrame = function(frame, target){
- var corners = transformIntoFrame_corners;
- var a = corners[0];
- var b = corners[1];
- var c = corners[2];
- var d = corners[3];
- var e = corners[4];
- var f = corners[5];
- var g = corners[6];
- var h = corners[7];
-
- this.getCorners(a, b, c, d, e, f, g, h);
-
- for(var i=0; i !== 8; i++){
- var corner = corners[i];
- frame.pointToLocal(corner, corner);
- }
- return target.setFromPoints(corners);
- };
- AABB.prototype.toWorldFrame = function(frame, target){
- var corners = transformIntoFrame_corners;
- var a = corners[0];
- var b = corners[1];
- var c = corners[2];
- var d = corners[3];
- var e = corners[4];
- var f = corners[5];
- var g = corners[6];
- var h = corners[7];
-
- this.getCorners(a, b, c, d, e, f, g, h);
-
- for(var i=0; i !== 8; i++){
- var corner = corners[i];
- frame.pointToWorld(corner, corner);
- }
- return target.setFromPoints(corners);
- };
- AABB.prototype.overlapsRay = function(ray){
- var t = 0;
-
- var dirFracX = 1 / ray._direction.x;
- var dirFracY = 1 / ray._direction.y;
- var dirFracZ = 1 / ray._direction.z;
-
- var t1 = (this.lowerBound.x - ray.from.x) * dirFracX;
- var t2 = (this.upperBound.x - ray.from.x) * dirFracX;
- var t3 = (this.lowerBound.y - ray.from.y) * dirFracY;
- var t4 = (this.upperBound.y - ray.from.y) * dirFracY;
- var t5 = (this.lowerBound.z - ray.from.z) * dirFracZ;
- var t6 = (this.upperBound.z - ray.from.z) * dirFracZ;
-
-
- var tmin = Math.max(Math.max(Math.min(t1, t2), Math.min(t3, t4)), Math.min(t5, t6));
- var tmax = Math.min(Math.min(Math.max(t1, t2), Math.max(t3, t4)), Math.max(t5, t6));
-
- if (tmax < 0){
-
- return false;
- }
-
- if (tmin > tmax){
-
- return false;
- }
- return true;
- };
- },{"../math/Vec3":46,"../utils/Utils":69}],19:[function(require,module,exports){
- module.exports = ArrayCollisionMatrix;
- function ArrayCollisionMatrix() {
-
- this.matrix = [];
- }
- ArrayCollisionMatrix.prototype.get = function(i, j) {
- i = i.index;
- j = j.index;
- if (j > i) {
- var temp = j;
- j = i;
- i = temp;
- }
- return this.matrix[(i*(i + 1)>>1) + j-1];
- };
- ArrayCollisionMatrix.prototype.set = function(i, j, value) {
- i = i.index;
- j = j.index;
- if (j > i) {
- var temp = j;
- j = i;
- i = temp;
- }
- this.matrix[(i*(i + 1)>>1) + j-1] = value ? 1 : 0;
- };
- ArrayCollisionMatrix.prototype.reset = function() {
- for (var i=0, l=this.matrix.length; i!==l; i++) {
- this.matrix[i]=0;
- }
- };
- ArrayCollisionMatrix.prototype.setNumObjects = function(n) {
- this.matrix.length = n*(n-1)>>1;
- };
- },{}],20:[function(require,module,exports){
- var Body = require('../objects/Body');
- var Vec3 = require('../math/Vec3');
- var Quaternion = require('../math/Quaternion');
- var Shape = require('../shapes/Shape');
- var Plane = require('../shapes/Plane');
- module.exports = Broadphase;
- function Broadphase(){
-
- this.world = null;
-
- this.useBoundingBoxes = false;
-
- this.dirty = true;
- }
- Broadphase.prototype.collisionPairs = function(world,p1,p2){
- throw new Error("collisionPairs not implemented for this BroadPhase class!");
- };
- Broadphase.prototype.needBroadphaseCollision = function(bodyA,bodyB){
-
- if( (bodyA.collisionFilterGroup & bodyB.collisionFilterMask)===0 || (bodyB.collisionFilterGroup & bodyA.collisionFilterMask)===0){
- return false;
- }
-
- if(((bodyA.type & Body.STATIC)!==0 || bodyA.sleepState === Body.SLEEPING) &&
- ((bodyB.type & Body.STATIC)!==0 || bodyB.sleepState === Body.SLEEPING)) {
-
- return false;
- }
- return true;
- };
- Broadphase.prototype.intersectionTest = function(bodyA, bodyB, pairs1, pairs2){
- if(this.useBoundingBoxes){
- this.doBoundingBoxBroadphase(bodyA,bodyB,pairs1,pairs2);
- } else {
- this.doBoundingSphereBroadphase(bodyA,bodyB,pairs1,pairs2);
- }
- };
- var Broadphase_collisionPairs_r = new Vec3(),
- Broadphase_collisionPairs_normal = new Vec3(),
- Broadphase_collisionPairs_quat = new Quaternion(),
- Broadphase_collisionPairs_relpos = new Vec3();
- Broadphase.prototype.doBoundingSphereBroadphase = function(bodyA,bodyB,pairs1,pairs2){
- var r = Broadphase_collisionPairs_r;
- bodyB.position.vsub(bodyA.position,r);
- var boundingRadiusSum2 = Math.pow(bodyA.boundingRadius + bodyB.boundingRadius, 2);
- var norm2 = r.norm2();
- if(norm2 < boundingRadiusSum2){
- pairs1.push(bodyA);
- pairs2.push(bodyB);
- }
- };
- Broadphase.prototype.doBoundingBoxBroadphase = function(bodyA,bodyB,pairs1,pairs2){
- if(bodyA.aabbNeedsUpdate){
- bodyA.computeAABB();
- }
- if(bodyB.aabbNeedsUpdate){
- bodyB.computeAABB();
- }
-
- if(bodyA.aabb.overlaps(bodyB.aabb)){
- pairs1.push(bodyA);
- pairs2.push(bodyB);
- }
- };
- var Broadphase_makePairsUnique_temp = { keys:[] },
- Broadphase_makePairsUnique_p1 = [],
- Broadphase_makePairsUnique_p2 = [];
- Broadphase.prototype.makePairsUnique = function(pairs1,pairs2){
- var t = Broadphase_makePairsUnique_temp,
- p1 = Broadphase_makePairsUnique_p1,
- p2 = Broadphase_makePairsUnique_p2,
- N = pairs1.length;
- for(var i=0; i!==N; i++){
- p1[i] = pairs1[i];
- p2[i] = pairs2[i];
- }
- pairs1.length = 0;
- pairs2.length = 0;
- for(var i=0; i!==N; i++){
- var id1 = p1[i].id,
- id2 = p2[i].id;
- var key = id1 < id2 ? id1+","+id2 : id2+","+id1;
- t[key] = i;
- t.keys.push(key);
- }
- for(var i=0; i!==t.keys.length; i++){
- var key = t.keys.pop(),
- pairIndex = t[key];
- pairs1.push(p1[pairIndex]);
- pairs2.push(p2[pairIndex]);
- delete t[key];
- }
- };
- Broadphase.prototype.setWorld = function(world){
- };
- var bsc_dist = new Vec3();
- Broadphase.boundingSphereCheck = function(bodyA,bodyB){
- var dist = bsc_dist;
- bodyA.position.vsub(bodyB.position,dist);
- return Math.pow(bodyA.shape.boundingSphereRadius + bodyB.shape.boundingSphereRadius,2) > dist.norm2();
- };
- Broadphase.prototype.aabbQuery = function(world, aabb, result){
- console.warn('.aabbQuery is not implemented in this Broadphase subclass.');
- return [];
- };
- },{"../math/Quaternion":44,"../math/Vec3":46,"../objects/Body":47,"../shapes/Plane":58,"../shapes/Shape":59}],21:[function(require,module,exports){
- module.exports = GridBroadphase;
- var Broadphase = require('./Broadphase');
- var Vec3 = require('../math/Vec3');
- var Shape = require('../shapes/Shape');
- function GridBroadphase(aabbMin,aabbMax,nx,ny,nz){
- Broadphase.apply(this);
- this.nx = nx || 10;
- this.ny = ny || 10;
- this.nz = nz || 10;
- this.aabbMin = aabbMin || new Vec3(100,100,100);
- this.aabbMax = aabbMax || new Vec3(-100,-100,-100);
- var nbins = this.nx * this.ny * this.nz;
- if (nbins <= 0) {
- throw "GridBroadphase: Each dimension's n must be >0";
- }
- this.bins = [];
- this.binLengths = [];
- this.bins.length = nbins;
- this.binLengths.length = nbins;
- for (var i=0;i<nbins;i++) {
- this.bins[i]=[];
- this.binLengths[i]=0;
- }
- }
- GridBroadphase.prototype = new Broadphase();
- GridBroadphase.prototype.constructor = GridBroadphase;
- var GridBroadphase_collisionPairs_d = new Vec3();
- var GridBroadphase_collisionPairs_binPos = new Vec3();
- GridBroadphase.prototype.collisionPairs = function(world,pairs1,pairs2){
- var N = world.numObjects(),
- bodies = world.bodies;
- var max = this.aabbMax,
- min = this.aabbMin,
- nx = this.nx,
- ny = this.ny,
- nz = this.nz;
- var xstep = ny*nz;
- var ystep = nz;
- var zstep = 1;
- var xmax = max.x,
- ymax = max.y,
- zmax = max.z,
- xmin = min.x,
- ymin = min.y,
- zmin = min.z;
- var xmult = nx / (xmax-xmin),
- ymult = ny / (ymax-ymin),
- zmult = nz / (zmax-zmin);
- var binsizeX = (xmax - xmin) / nx,
- binsizeY = (ymax - ymin) / ny,
- binsizeZ = (zmax - zmin) / nz;
- var binRadius = Math.sqrt(binsizeX*binsizeX + binsizeY*binsizeY + binsizeZ*binsizeZ) * 0.5;
- var types = Shape.types;
- var SPHERE = types.SPHERE,
- PLANE = types.PLANE,
- BOX = types.BOX,
- COMPOUND = types.COMPOUND,
- CONVEXPOLYHEDRON = types.CONVEXPOLYHEDRON;
- var bins=this.bins,
- binLengths=this.binLengths,
- Nbins=this.bins.length;
-
- for(var i=0; i!==Nbins; i++){
- binLengths[i] = 0;
- }
- var ceil = Math.ceil;
- var min = Math.min;
- var max = Math.max;
- function addBoxToBins(x0,y0,z0,x1,y1,z1,bi) {
- var xoff0 = ((x0 - xmin) * xmult)|0,
- yoff0 = ((y0 - ymin) * ymult)|0,
- zoff0 = ((z0 - zmin) * zmult)|0,
- xoff1 = ceil((x1 - xmin) * xmult),
- yoff1 = ceil((y1 - ymin) * ymult),
- zoff1 = ceil((z1 - zmin) * zmult);
- if (xoff0 < 0) { xoff0 = 0; } else if (xoff0 >= nx) { xoff0 = nx - 1; }
- if (yoff0 < 0) { yoff0 = 0; } else if (yoff0 >= ny) { yoff0 = ny - 1; }
- if (zoff0 < 0) { zoff0 = 0; } else if (zoff0 >= nz) { zoff0 = nz - 1; }
- if (xoff1 < 0) { xoff1 = 0; } else if (xoff1 >= nx) { xoff1 = nx - 1; }
- if (yoff1 < 0) { yoff1 = 0; } else if (yoff1 >= ny) { yoff1 = ny - 1; }
- if (zoff1 < 0) { zoff1 = 0; } else if (zoff1 >= nz) { zoff1 = nz - 1; }
- xoff0 *= xstep;
- yoff0 *= ystep;
- zoff0 *= zstep;
- xoff1 *= xstep;
- yoff1 *= ystep;
- zoff1 *= zstep;
- for (var xoff = xoff0; xoff <= xoff1; xoff += xstep) {
- for (var yoff = yoff0; yoff <= yoff1; yoff += ystep) {
- for (var zoff = zoff0; zoff <= zoff1; zoff += zstep) {
- var idx = xoff+yoff+zoff;
- bins[idx][binLengths[idx]++] = bi;
- }
- }
- }
- }
-
- for(var i=0; i!==N; i++){
- var bi = bodies[i];
- var si = bi.shape;
- switch(si.type){
- case SPHERE:
-
-
- var x = bi.position.x,
- y = bi.position.y,
- z = bi.position.z;
- var r = si.radius;
- addBoxToBins(x-r, y-r, z-r, x+r, y+r, z+r, bi);
- break;
- case PLANE:
- if(si.worldNormalNeedsUpdate){
- si.computeWorldNormal(bi.quaternion);
- }
- var planeNormal = si.worldNormal;
-
-
- var xreset = xmin + binsizeX*0.5 - bi.position.x,
- yreset = ymin + binsizeY*0.5 - bi.position.y,
- zreset = zmin + binsizeZ*0.5 - bi.position.z;
- var d = GridBroadphase_collisionPairs_d;
- d.set(xreset, yreset, zreset);
- for (var xi = 0, xoff = 0; xi !== nx; xi++, xoff += xstep, d.y = yreset, d.x += binsizeX) {
- for (var yi = 0, yoff = 0; yi !== ny; yi++, yoff += ystep, d.z = zreset, d.y += binsizeY) {
- for (var zi = 0, zoff = 0; zi !== nz; zi++, zoff += zstep, d.z += binsizeZ) {
- if (d.dot(planeNormal) < binRadius) {
- var idx = xoff + yoff + zoff;
- bins[idx][binLengths[idx]++] = bi;
- }
- }
- }
- }
- break;
- default:
- if (bi.aabbNeedsUpdate) {
- bi.computeAABB();
- }
- addBoxToBins(
- bi.aabb.lowerBound.x,
- bi.aabb.lowerBound.y,
- bi.aabb.lowerBound.z,
- bi.aabb.upperBound.x,
- bi.aabb.upperBound.y,
- bi.aabb.upperBound.z,
- bi);
- break;
- }
- }
-
- for(var i=0; i!==Nbins; i++){
- var binLength = binLengths[i];
-
- if (binLength > 1) {
- var bin = bins[i];
-
- for(var xi=0; xi!==binLength; xi++){
- var bi = bin[xi];
- for(var yi=0; yi!==xi; yi++){
- var bj = bin[yi];
- if(this.needBroadphaseCollision(bi,bj)){
- this.intersectionTest(bi,bj,pairs1,pairs2);
- }
- }
- }
- }
- }
- this.makePairsUnique(pairs1,pairs2);
- };
- },{"../math/Vec3":46,"../shapes/Shape":59,"./Broadphase":20}],22:[function(require,module,exports){
- module.exports = NaiveBroadphase;
- var Broadphase = require('./Broadphase');
- var AABB = require('./AABB');
- function NaiveBroadphase(){
- Broadphase.apply(this);
- }
- NaiveBroadphase.prototype = new Broadphase();
- NaiveBroadphase.prototype.constructor = NaiveBroadphase;
- NaiveBroadphase.prototype.collisionPairs = function(world,pairs1,pairs2){
- var bodies = world.bodies,
- n = bodies.length,
- i,j,bi,bj;
-
- for(i=0; i!==n; i++){
- for(j=0; j!==i; j++){
- bi = bodies[i];
- bj = bodies[j];
- if(!this.needBroadphaseCollision(bi,bj)){
- continue;
- }
- this.intersectionTest(bi,bj,pairs1,pairs2);
- }
- }
- };
- var tmpAABB = new AABB();
- NaiveBroadphase.prototype.aabbQuery = function(world, aabb, result){
- result = result || [];
- for(var i = 0; i < world.bodies.length; i++){
- var b = world.bodies[i];
- if(b.aabbNeedsUpdate){
- b.computeAABB();
- }
-
- if(b.aabb.overlaps(aabb)){
- result.push(b);
- }
- }
- return result;
- };
- },{"./AABB":18,"./Broadphase":20}],23:[function(require,module,exports){
- module.exports = ObjectCollisionMatrix;
- function ObjectCollisionMatrix() {
-
- this.matrix = {};
- }
- ObjectCollisionMatrix.prototype.get = function(i, j) {
- i = i.id;
- j = j.id;
- if (j > i) {
- var temp = j;
- j = i;
- i = temp;
- }
- return i+'-'+j in this.matrix;
- };
- ObjectCollisionMatrix.prototype.set = function(i, j, value) {
- i = i.id;
- j = j.id;
- if (j > i) {
- var temp = j;
- j = i;
- i = temp;
- }
- if (value) {
- this.matrix[i+'-'+j] = true;
- }
- else {
- delete this.matrix[i+'-'+j];
- }
- };
- ObjectCollisionMatrix.prototype.reset = function() {
- this.matrix = {};
- };
- ObjectCollisionMatrix.prototype.setNumObjects = function(n) {
- };
- },{}],24:[function(require,module,exports){
- module.exports = OverlapKeeper;
- function OverlapKeeper() {
- this.current = [];
- this.previous = [];
- }
- OverlapKeeper.prototype.getKey = function(i, j) {
- if (j < i) {
- var temp = j;
- j = i;
- i = temp;
- }
- return (i << 16) | j;
- };
- OverlapKeeper.prototype.set = function(i, j) {
-
- var key = this.getKey(i, j);
- var current = this.current;
- var index = 0;
- while(key > current[index]){
- index++;
- }
- if(key === current[index]){
- return;
- }
- for(var j=current.length-1; j>=index; j--){
- current[j + 1] = current[j];
- }
- current[index] = key;
- };
- OverlapKeeper.prototype.tick = function() {
- var tmp = this.current;
- this.current = this.previous;
- this.previous = tmp;
- this.current.length = 0;
- };
- function unpackAndPush(array, key){
- array.push((key & 0xFFFF0000) >> 16, key & 0x0000FFFF);
- }
- OverlapKeeper.prototype.getDiff = function(additions, removals) {
- var a = this.current;
- var b = this.previous;
- var al = a.length;
- var bl = b.length;
- var j=0;
- for (var i = 0; i < al; i++) {
- var found = false;
- var keyA = a[i];
- while(keyA > b[j]){
- j++;
- }
- found = keyA === b[j];
- if(!found){
- unpackAndPush(additions, keyA);
- }
- }
- j = 0;
- for (var i = 0; i < bl; i++) {
- var found = false;
- var keyB = b[i];
- while(keyB > a[j]){
- j++;
- }
- found = a[j] === keyB;
- if(!found){
- unpackAndPush(removals, keyB);
- }
- }
- };
- },{}],25:[function(require,module,exports){
- module.exports = Ray;
- var Vec3 = require('../math/Vec3');
- var Quaternion = require('../math/Quaternion');
- var Transform = require('../math/Transform');
- var ConvexPolyhedron = require('../shapes/ConvexPolyhedron');
- var Box = require('../shapes/Box');
- var RaycastResult = require('../collision/RaycastResult');
- var Shape = require('../shapes/Shape');
- var AABB = require('../collision/AABB');
- function Ray(from, to){
-
- this.from = from ? from.clone() : new Vec3();
-
- this.to = to ? to.clone() : new Vec3();
-
- this._direction = new Vec3();
-
- this.precision = 0.0001;
-
- this.checkCollisionResponse = true;
-
- this.skipBackfaces = false;
-
- this.collisionFilterMask = -1;
-
- this.collisionFilterGroup = -1;
-
- this.mode = Ray.ANY;
-
- this.result = new RaycastResult();
-
- this.hasHit = false;
-
- this.callback = function(result){};
- }
- Ray.prototype.constructor = Ray;
- Ray.CLOSEST = 1;
- Ray.ANY = 2;
- Ray.ALL = 4;
- var tmpAABB = new AABB();
- var tmpArray = [];
- Ray.prototype.intersectWorld = function (world, options) {
- this.mode = options.mode || Ray.ANY;
- this.result = options.result || new RaycastResult();
- this.skipBackfaces = !!options.skipBackfaces;
- this.collisionFilterMask = typeof(options.collisionFilterMask) !== 'undefined' ? options.collisionFilterMask : -1;
- this.collisionFilterGroup = typeof(options.collisionFilterGroup) !== 'undefined' ? options.collisionFilterGroup : -1;
- if(options.from){
- this.from.copy(options.from);
- }
- if(options.to){
- this.to.copy(options.to);
- }
- this.callback = options.callback || function(){};
- this.hasHit = false;
- this.result.reset();
- this._updateDirection();
- this.getAABB(tmpAABB);
- tmpArray.length = 0;
- world.broadphase.aabbQuery(world, tmpAABB, tmpArray);
- this.intersectBodies(tmpArray);
- return this.hasHit;
- };
- var v1 = new Vec3(),
- v2 = new Vec3();
- Ray.pointInTriangle = pointInTriangle;
- function pointInTriangle(p, a, b, c) {
- c.vsub(a,v0);
- b.vsub(a,v1);
- p.vsub(a,v2);
- var dot00 = v0.dot( v0 );
- var dot01 = v0.dot( v1 );
- var dot02 = v0.dot( v2 );
- var dot11 = v1.dot( v1 );
- var dot12 = v1.dot( v2 );
- var u,v;
- return ( (u = dot11 * dot02 - dot01 * dot12) >= 0 ) &&
- ( (v = dot00 * dot12 - dot01 * dot02) >= 0 ) &&
- ( u + v < ( dot00 * dot11 - dot01 * dot01 ) );
- }
- var intersectBody_xi = new Vec3();
- var intersectBody_qi = new Quaternion();
- Ray.prototype.intersectBody = function (body, result) {
- if(result){
- this.result = result;
- this._updateDirection();
- }
- var checkCollisionResponse = this.checkCollisionResponse;
- if(checkCollisionResponse && !body.collisionResponse){
- return;
- }
- if((this.collisionFilterGroup & body.collisionFilterMask)===0 || (body.collisionFilterGroup & this.collisionFilterMask)===0){
- return;
- }
- var xi = intersectBody_xi;
- var qi = intersectBody_qi;
- for (var i = 0, N = body.shapes.length; i < N; i++) {
- var shape = body.shapes[i];
- if(checkCollisionResponse && !shape.collisionResponse){
- continue;
- }
- body.quaternion.mult(body.shapeOrientations[i], qi);
- body.quaternion.vmult(body.shapeOffsets[i], xi);
- xi.vadd(body.position, xi);
- this.intersectShape(
- shape,
- qi,
- xi,
- body
- );
- if(this.result._shouldStop){
- break;
- }
- }
- };
- Ray.prototype.intersectBodies = function (bodies, result) {
- if(result){
- this.result = result;
- this._updateDirection();
- }
- for ( var i = 0, l = bodies.length; !this.result._shouldStop && i < l; i ++ ) {
- this.intersectBody(bodies[i]);
- }
- };
- Ray.prototype._updateDirection = function(){
- this.to.vsub(this.from, this._direction);
- this._direction.normalize();
- };
- Ray.prototype.intersectShape = function(shape, quat, position, body){
- var from = this.from;
-
- var distance = distanceFromIntersection(from, this._direction, position);
- if ( distance > shape.boundingSphereRadius ) {
- return;
- }
- var intersectMethod = this[shape.type];
- if(intersectMethod){
- intersectMethod.call(this, shape, quat, position, body, shape);
- }
- };
- var vector = new Vec3();
- var normal = new Vec3();
- var intersectPoint = new Vec3();
- var a = new Vec3();
- var b = new Vec3();
- var c = new Vec3();
- var d = new Vec3();
- var tmpRaycastResult = new RaycastResult();
- Ray.prototype.intersectBox = function(shape, quat, position, body, reportedShape){
- return this.intersectConvex(shape.convexPolyhedronRepresentation, quat, position, body, reportedShape);
- };
- Ray.prototype[Shape.types.BOX] = Ray.prototype.intersectBox;
- Ray.prototype.intersectPlane = function(shape, quat, position, body, reportedShape){
- var from = this.from;
- var to = this.to;
- var direction = this._direction;
-
- var worldNormal = new Vec3(0, 0, 1);
- quat.vmult(worldNormal, worldNormal);
- var len = new Vec3();
- from.vsub(position, len);
- var planeToFrom = len.dot(worldNormal);
- to.vsub(position, len);
- var planeToTo = len.dot(worldNormal);
- if(planeToFrom * planeToTo > 0){
-
- return;
- }
- if(from.distanceTo(to) < planeToFrom){
- return;
- }
- var n_dot_dir = worldNormal.dot(direction);
- if (Math.abs(n_dot_dir) < this.precision) {
-
- return;
- }
- var planePointToFrom = new Vec3();
- var dir_scaled_with_t = new Vec3();
- var hitPointWorld = new Vec3();
- from.vsub(position, planePointToFrom);
- var t = -worldNormal.dot(planePointToFrom) / n_dot_dir;
- direction.scale(t, dir_scaled_with_t);
- from.vadd(dir_scaled_with_t, hitPointWorld);
- this.reportIntersection(worldNormal, hitPointWorld, reportedShape, body, -1);
- };
- Ray.prototype[Shape.types.PLANE] = Ray.prototype.intersectPlane;
- Ray.prototype.getAABB = function(result){
- var to = this.to;
- var from = this.from;
- result.lowerBound.x = Math.min(to.x, from.x);
- result.lowerBound.y = Math.min(to.y, from.y);
- result.lowerBound.z = Math.min(to.z, from.z);
- result.upperBound.x = Math.max(to.x, from.x);
- result.upperBound.y = Math.max(to.y, from.y);
- result.upperBound.z = Math.max(to.z, from.z);
- };
- var intersectConvexOptions = {
- faceList: [0]
- };
- var worldPillarOffset = new Vec3();
- var intersectHeightfield_localRay = new Ray();
- var intersectHeightfield_index = [];
- var intersectHeightfield_minMax = [];
- Ray.prototype.intersectHeightfield = function(shape, quat, position, body, reportedShape){
- var data = shape.data,
- w = shape.elementSize;
-
- var localRay = intersectHeightfield_localRay;
- localRay.from.copy(this.from);
- localRay.to.copy(this.to);
- Transform.pointToLocalFrame(position, quat, localRay.from, localRay.from);
- Transform.pointToLocalFrame(position, quat, localRay.to, localRay.to);
- localRay._updateDirection();
-
- var index = intersectHeightfield_index;
- var iMinX, iMinY, iMaxX, iMaxY;
-
- iMinX = iMinY = 0;
- iMaxX = iMaxY = shape.data.length - 1;
- var aabb = new AABB();
- localRay.getAABB(aabb);
- shape.getIndexOfPosition(aabb.lowerBound.x, aabb.lowerBound.y, index, true);
- iMinX = Math.max(iMinX, index[0]);
- iMinY = Math.max(iMinY, index[1]);
- shape.getIndexOfPosition(aabb.upperBound.x, aabb.upperBound.y, index, true);
- iMaxX = Math.min(iMaxX, index[0] + 1);
- iMaxY = Math.min(iMaxY, index[1] + 1);
- for(var i = iMinX; i < iMaxX; i++){
- for(var j = iMinY; j < iMaxY; j++){
- if(this.result._shouldStop){
- return;
- }
- shape.getAabbAtIndex(i, j, aabb);
- if(!aabb.overlapsRay(localRay)){
- continue;
- }
-
- shape.getConvexTrianglePillar(i, j, false);
- Transform.pointToWorldFrame(position, quat, shape.pillarOffset, worldPillarOffset);
- this.intersectConvex(shape.pillarConvex, quat, worldPillarOffset, body, reportedShape, intersectConvexOptions);
- if(this.result._shouldStop){
- return;
- }
-
- shape.getConvexTrianglePillar(i, j, true);
- Transform.pointToWorldFrame(position, quat, shape.pillarOffset, worldPillarOffset);
- this.intersectConvex(shape.pillarConvex, quat, worldPillarOffset, body, reportedShape, intersectConvexOptions);
- }
- }
- };
- Ray.prototype[Shape.types.HEIGHTFIELD] = Ray.prototype.intersectHeightfield;
- var Ray_intersectSphere_intersectionPoint = new Vec3();
- var Ray_intersectSphere_normal = new Vec3();
- Ray.prototype.intersectSphere = function(shape, quat, position, body, reportedShape){
- var from = this.from,
- to = this.to,
- r = shape.radius;
- var a = Math.pow(to.x - from.x, 2) + Math.pow(to.y - from.y, 2) + Math.pow(to.z - from.z, 2);
- var b = 2 * ((to.x - from.x) * (from.x - position.x) + (to.y - from.y) * (from.y - position.y) + (to.z - from.z) * (from.z - position.z));
- var c = Math.pow(from.x - position.x, 2) + Math.pow(from.y - position.y, 2) + Math.pow(from.z - position.z, 2) - Math.pow(r, 2);
- var delta = Math.pow(b, 2) - 4 * a * c;
- var intersectionPoint = Ray_intersectSphere_intersectionPoint;
- var normal = Ray_intersectSphere_normal;
- if(delta < 0){
-
- return;
- } else if(delta === 0){
-
- from.lerp(to, delta, intersectionPoint);
- intersectionPoint.vsub(position, normal);
- normal.normalize();
- this.reportIntersection(normal, intersectionPoint, reportedShape, body, -1);
- } else {
- var d1 = (- b - Math.sqrt(delta)) / (2 * a);
- var d2 = (- b + Math.sqrt(delta)) / (2 * a);
- if(d1 >= 0 && d1 <= 1){
- from.lerp(to, d1, intersectionPoint);
- intersectionPoint.vsub(position, normal);
- normal.normalize();
- this.reportIntersection(normal, intersectionPoint, reportedShape, body, -1);
- }
- if(this.result._shouldStop){
- return;
- }
- if(d2 >= 0 && d2 <= 1){
- from.lerp(to, d2, intersectionPoint);
- intersectionPoint.vsub(position, normal);
- normal.normalize();
- this.reportIntersection(normal, intersectionPoint, reportedShape, body, -1);
- }
- }
- };
- Ray.prototype[Shape.types.SPHERE] = Ray.prototype.intersectSphere;
- var intersectConvex_normal = new Vec3();
- var intersectConvex_minDistNormal = new Vec3();
- var intersectConvex_minDistIntersect = new Vec3();
- var intersectConvex_vector = new Vec3();
- Ray.prototype.intersectConvex = function intersectConvex(
- shape,
- quat,
- position,
- body,
- reportedShape,
- options
- ){
- var minDistNormal = intersectConvex_minDistNormal;
- var normal = intersectConvex_normal;
- var vector = intersectConvex_vector;
- var minDistIntersect = intersectConvex_minDistIntersect;
- var faceList = (options && options.faceList) || null;
-
- var faces = shape.faces,
- vertices = shape.vertices,
- normals = shape.faceNormals;
- var direction = this._direction;
- var from = this.from;
- var to = this.to;
- var fromToDistance = from.distanceTo(to);
- var minDist = -1;
- var Nfaces = faceList ? faceList.length : faces.length;
- var result = this.result;
- for (var j = 0; !result._shouldStop && j < Nfaces; j++) {
- var fi = faceList ? faceList[j] : j;
- var face = faces[fi];
- var faceNormal = normals[fi];
- var q = quat;
- var x = position;
-
-
-
- vector.copy(vertices[face[0]]);
- q.vmult(vector,vector);
- vector.vadd(x,vector);
-
- vector.vsub(from,vector);
-
- q.vmult(faceNormal,normal);
-
- var dot = direction.dot(normal);
-
- if ( Math.abs( dot ) < this.precision ){
- continue;
- }
-
- var scalar = normal.dot(vector) / dot;
-
- if (scalar < 0){
- continue;
- }
-
-
- direction.mult(scalar,intersectPoint);
- intersectPoint.vadd(from,intersectPoint);
-
- a.copy(vertices[face[0]]);
- q.vmult(a,a);
- x.vadd(a,a);
- for(var i = 1; !result._shouldStop && i < face.length - 1; i++){
-
- b.copy(vertices[face[i]]);
- c.copy(vertices[face[i+1]]);
- q.vmult(b,b);
- q.vmult(c,c);
- x.vadd(b,b);
- x.vadd(c,c);
- var distance = intersectPoint.distanceTo(from);
- if(!(pointInTriangle(intersectPoint, a, b, c) || pointInTriangle(intersectPoint, b, a, c)) || distance > fromToDistance){
- continue;
- }
- this.reportIntersection(normal, intersectPoint, reportedShape, body, fi);
- }
-
- }
- };
- Ray.prototype[Shape.types.CONVEXPOLYHEDRON] = Ray.prototype.intersectConvex;
- var intersectTrimesh_normal = new Vec3();
- var intersectTrimesh_localDirection = new Vec3();
- var intersectTrimesh_localFrom = new Vec3();
- var intersectTrimesh_localTo = new Vec3();
- var intersectTrimesh_worldNormal = new Vec3();
- var intersectTrimesh_worldIntersectPoint = new Vec3();
- var intersectTrimesh_localAABB = new AABB();
- var intersectTrimesh_triangles = [];
- var intersectTrimesh_treeTransform = new Transform();
- Ray.prototype.intersectTrimesh = function intersectTrimesh(
- mesh,
- quat,
- position,
- body,
- reportedShape,
- options
- ){
- var normal = intersectTrimesh_normal;
- var triangles = intersectTrimesh_triangles;
- var treeTransform = intersectTrimesh_treeTransform;
- var minDistNormal = intersectConvex_minDistNormal;
- var vector = intersectConvex_vector;
- var minDistIntersect = intersectConvex_minDistIntersect;
- var localAABB = intersectTrimesh_localAABB;
- var localDirection = intersectTrimesh_localDirection;
- var localFrom = intersectTrimesh_localFrom;
- var localTo = intersectTrimesh_localTo;
- var worldIntersectPoint = intersectTrimesh_worldIntersectPoint;
- var worldNormal = intersectTrimesh_worldNormal;
- var faceList = (options && options.faceList) || null;
-
- var indices = mesh.indices,
- vertices = mesh.vertices,
- normals = mesh.faceNormals;
- var from = this.from;
- var to = this.to;
- var direction = this._direction;
- var minDist = -1;
- treeTransform.position.copy(position);
- treeTransform.quaternion.copy(quat);
-
- Transform.vectorToLocalFrame(position, quat, direction, localDirection);
- Transform.pointToLocalFrame(position, quat, from, localFrom);
- Transform.pointToLocalFrame(position, quat, to, localTo);
- localTo.x *= mesh.scale.x;
- localTo.y *= mesh.scale.y;
- localTo.z *= mesh.scale.z;
- localFrom.x *= mesh.scale.x;
- localFrom.y *= mesh.scale.y;
- localFrom.z *= mesh.scale.z;
- localTo.vsub(localFrom, localDirection);
- localDirection.normalize();
- var fromToDistanceSquared = localFrom.distanceSquared(localTo);
- mesh.tree.rayQuery(this, treeTransform, triangles);
- for (var i = 0, N = triangles.length; !this.result._shouldStop && i !== N; i++) {
- var trianglesIndex = triangles[i];
- mesh.getNormal(trianglesIndex, normal);
-
-
-
- mesh.getVertex(indices[trianglesIndex * 3], a);
-
- a.vsub(localFrom,vector);
-
- var dot = localDirection.dot(normal);
-
-
-
-
-
- var scalar = normal.dot(vector) / dot;
-
- if (scalar < 0){
- continue;
- }
-
- localDirection.scale(scalar,intersectPoint);
- intersectPoint.vadd(localFrom,intersectPoint);
-
- mesh.getVertex(indices[trianglesIndex * 3 + 1], b);
- mesh.getVertex(indices[trianglesIndex * 3 + 2], c);
- var squaredDistance = intersectPoint.distanceSquared(localFrom);
- if(!(pointInTriangle(intersectPoint, b, a, c) || pointInTriangle(intersectPoint, a, b, c)) || squaredDistance > fromToDistanceSquared){
- continue;
- }
-
- Transform.vectorToWorldFrame(quat, normal, worldNormal);
- Transform.pointToWorldFrame(position, quat, intersectPoint, worldIntersectPoint);
- this.reportIntersection(worldNormal, worldIntersectPoint, reportedShape, body, trianglesIndex);
- }
- triangles.length = 0;
- };
- Ray.prototype[Shape.types.TRIMESH] = Ray.prototype.intersectTrimesh;
- Ray.prototype.reportIntersection = function(normal, hitPointWorld, shape, body, hitFaceIndex){
- var from = this.from;
- var to = this.to;
- var distance = from.distanceTo(hitPointWorld);
- var result = this.result;
-
- if(this.skipBackfaces && normal.dot(this._direction) > 0){
- return;
- }
- result.hitFaceIndex = typeof(hitFaceIndex) !== 'undefined' ? hitFaceIndex : -1;
- switch(this.mode){
- case Ray.ALL:
- this.hasHit = true;
- result.set(
- from,
- to,
- normal,
- hitPointWorld,
- shape,
- body,
- distance
- );
- result.hasHit = true;
- this.callback(result);
- break;
- case Ray.CLOSEST:
-
- if(distance < result.distance || !result.hasHit){
- this.hasHit = true;
- result.hasHit = true;
- result.set(
- from,
- to,
- normal,
- hitPointWorld,
- shape,
- body,
- distance
- );
- }
- break;
- case Ray.ANY:
-
- this.hasHit = true;
- result.hasHit = true;
- result.set(
- from,
- to,
- normal,
- hitPointWorld,
- shape,
- body,
- distance
- );
- result._shouldStop = true;
- break;
- }
- };
- var v0 = new Vec3(),
- intersect = new Vec3();
- function distanceFromIntersection(from, direction, position) {
-
- position.vsub(from,v0);
- var dot = v0.dot(direction);
-
- direction.mult(dot,intersect);
- intersect.vadd(from,intersect);
- var distance = position.distanceTo(intersect);
- return distance;
- }
- },{"../collision/AABB":18,"../collision/RaycastResult":26,"../math/Quaternion":44,"../math/Transform":45,"../math/Vec3":46,"../shapes/Box":53,"../shapes/ConvexPolyhedron":54,"../shapes/Shape":59}],26:[function(require,module,exports){
- var Vec3 = require('../math/Vec3');
- module.exports = RaycastResult;
- function RaycastResult(){
-
- this.rayFromWorld = new Vec3();
-
- this.rayToWorld = new Vec3();
-
- this.hitNormalWorld = new Vec3();
-
- this.hitPointWorld = new Vec3();
-
- this.hasHit = false;
-
- this.shape = null;
-
- this.body = null;
-
- this.hitFaceIndex = -1;
-
- this.distance = -1;
-
- this._shouldStop = false;
- }
- RaycastResult.prototype.reset = function () {
- this.rayFromWorld.setZero();
- this.rayToWorld.setZero();
- this.hitNormalWorld.setZero();
- this.hitPointWorld.setZero();
- this.hasHit = false;
- this.shape = null;
- this.body = null;
- this.hitFaceIndex = -1;
- this.distance = -1;
- this._shouldStop = false;
- };
- RaycastResult.prototype.abort = function(){
- this._shouldStop = true;
- };
- RaycastResult.prototype.set = function(
- rayFromWorld,
- rayToWorld,
- hitNormalWorld,
- hitPointWorld,
- shape,
- body,
- distance
- ){
- this.rayFromWorld.copy(rayFromWorld);
- this.rayToWorld.copy(rayToWorld);
- this.hitNormalWorld.copy(hitNormalWorld);
- this.hitPointWorld.copy(hitPointWorld);
- this.shape = shape;
- this.body = body;
- this.distance = distance;
- };
- },{"../math/Vec3":46}],27:[function(require,module,exports){
- var Shape = require('../shapes/Shape');
- var Broadphase = require('../collision/Broadphase');
- module.exports = SAPBroadphase;
- function SAPBroadphase(world){
- Broadphase.apply(this);
-
- this.axisList = [];
-
- this.world = null;
-
- this.axisIndex = 0;
- var axisList = this.axisList;
- this._addBodyHandler = function(e){
- axisList.push(e.body);
- };
- this._removeBodyHandler = function(e){
- var idx = axisList.indexOf(e.body);
- if(idx !== -1){
- axisList.splice(idx,1);
- }
- };
- if(world){
- this.setWorld(world);
- }
- }
- SAPBroadphase.prototype = new Broadphase();
- SAPBroadphase.prototype.setWorld = function(world){
-
- this.axisList.length = 0;
-
- for(var i=0; i<world.bodies.length; i++){
- this.axisList.push(world.bodies[i]);
- }
-
- world.removeEventListener("addBody", this._addBodyHandler);
- world.removeEventListener("removeBody", this._removeBodyHandler);
-
- world.addEventListener("addBody", this._addBodyHandler);
- world.addEventListener("removeBody", this._removeBodyHandler);
- this.world = world;
- this.dirty = true;
- };
- SAPBroadphase.insertionSortX = function(a) {
- for(var i=1,l=a.length;i<l;i++) {
- var v = a[i];
- for(var j=i - 1;j>=0;j--) {
- if(a[j].aabb.lowerBound.x <= v.aabb.lowerBound.x){
- break;
- }
- a[j+1] = a[j];
- }
- a[j+1] = v;
- }
- return a;
- };
- SAPBroadphase.insertionSortY = function(a) {
- for(var i=1,l=a.length;i<l;i++) {
- var v = a[i];
- for(var j=i - 1;j>=0;j--) {
- if(a[j].aabb.lowerBound.y <= v.aabb.lowerBound.y){
- break;
- }
- a[j+1] = a[j];
- }
- a[j+1] = v;
- }
- return a;
- };
- SAPBroadphase.insertionSortZ = function(a) {
- for(var i=1,l=a.length;i<l;i++) {
- var v = a[i];
- for(var j=i - 1;j>=0;j--) {
- if(a[j].aabb.lowerBound.z <= v.aabb.lowerBound.z){
- break;
- }
- a[j+1] = a[j];
- }
- a[j+1] = v;
- }
- return a;
- };
- SAPBroadphase.prototype.collisionPairs = function(world,p1,p2){
- var bodies = this.axisList,
- N = bodies.length,
- axisIndex = this.axisIndex,
- i, j;
- if(this.dirty){
- this.sortList();
- this.dirty = false;
- }
-
- for(i=0; i !== N; i++){
- var bi = bodies[i];
- for(j=i+1; j < N; j++){
- var bj = bodies[j];
- if(!this.needBroadphaseCollision(bi,bj)){
- continue;
- }
- if(!SAPBroadphase.checkBounds(bi,bj,axisIndex)){
- break;
- }
- this.intersectionTest(bi,bj,p1,p2);
- }
- }
- };
- SAPBroadphase.prototype.sortList = function(){
- var axisList = this.axisList;
- var axisIndex = this.axisIndex;
- var N = axisList.length;
-
- for(var i = 0; i!==N; i++){
- var bi = axisList[i];
- if(bi.aabbNeedsUpdate){
- bi.computeAABB();
- }
- }
-
- if(axisIndex === 0){
- SAPBroadphase.insertionSortX(axisList);
- } else if(axisIndex === 1){
- SAPBroadphase.insertionSortY(axisList);
- } else if(axisIndex === 2){
- SAPBroadphase.insertionSortZ(axisList);
- }
- };
- SAPBroadphase.checkBounds = function(bi, bj, axisIndex){
- var biPos;
- var bjPos;
- if(axisIndex === 0){
- biPos = bi.position.x;
- bjPos = bj.position.x;
- } else if(axisIndex === 1){
- biPos = bi.position.y;
- bjPos = bj.position.y;
- } else if(axisIndex === 2){
- biPos = bi.position.z;
- bjPos = bj.position.z;
- }
- var ri = bi.boundingRadius,
- rj = bj.boundingRadius,
- boundA1 = biPos - ri,
- boundA2 = biPos + ri,
- boundB1 = bjPos - rj,
- boundB2 = bjPos + rj;
- return boundB1 < boundA2;
- };
- SAPBroadphase.prototype.autoDetectAxis = function(){
- var sumX=0,
- sumX2=0,
- sumY=0,
- sumY2=0,
- sumZ=0,
- sumZ2=0,
- bodies = this.axisList,
- N = bodies.length,
- invN=1/N;
- for(var i=0; i!==N; i++){
- var b = bodies[i];
- var centerX = b.position.x;
- sumX += centerX;
- sumX2 += centerX*centerX;
- var centerY = b.position.y;
- sumY += centerY;
- sumY2 += centerY*centerY;
- var centerZ = b.position.z;
- sumZ += centerZ;
- sumZ2 += centerZ*centerZ;
- }
- var varianceX = sumX2 - sumX*sumX*invN,
- varianceY = sumY2 - sumY*sumY*invN,
- varianceZ = sumZ2 - sumZ*sumZ*invN;
- if(varianceX > varianceY){
- if(varianceX > varianceZ){
- this.axisIndex = 0;
- } else{
- this.axisIndex = 2;
- }
- } else if(varianceY > varianceZ){
- this.axisIndex = 1;
- } else{
- this.axisIndex = 2;
- }
- };
- SAPBroadphase.prototype.aabbQuery = function(world, aabb, result){
- result = result || [];
- if(this.dirty){
- this.sortList();
- this.dirty = false;
- }
- var axisIndex = this.axisIndex, axis = 'x';
- if(axisIndex === 1){ axis = 'y'; }
- if(axisIndex === 2){ axis = 'z'; }
- var axisList = this.axisList;
- var lower = aabb.lowerBound[axis];
- var upper = aabb.upperBound[axis];
- for(var i = 0; i < axisList.length; i++){
- var b = axisList[i];
- if(b.aabbNeedsUpdate){
- b.computeAABB();
- }
- if(b.aabb.overlaps(aabb)){
- result.push(b);
- }
- }
- return result;
- };
- },{"../collision/Broadphase":20,"../shapes/Shape":59}],28:[function(require,module,exports){
- module.exports = ConeTwistConstraint;
- var Constraint = require('./Constraint');
- var PointToPointConstraint = require('./PointToPointConstraint');
- var ConeEquation = require('../equations/ConeEquation');
- var RotationalEquation = require('../equations/RotationalEquation');
- var ContactEquation = require('../equations/ContactEquation');
- var Vec3 = require('../math/Vec3');
- function ConeTwistConstraint(bodyA, bodyB, options){
- options = options || {};
- var maxForce = typeof(options.maxForce) !== 'undefined' ? options.maxForce : 1e6;
-
- var pivotA = options.pivotA ? options.pivotA.clone() : new Vec3();
- var pivotB = options.pivotB ? options.pivotB.clone() : new Vec3();
- this.axisA = options.axisA ? options.axisA.clone() : new Vec3();
- this.axisB = options.axisB ? options.axisB.clone() : new Vec3();
- PointToPointConstraint.call(this, bodyA, pivotA, bodyB, pivotB, maxForce);
- this.collideConnected = !!options.collideConnected;
- this.angle = typeof(options.angle) !== 'undefined' ? options.angle : 0;
-
- var c = this.coneEquation = new ConeEquation(bodyA,bodyB,options);
-
- var t = this.twistEquation = new RotationalEquation(bodyA,bodyB,options);
- this.twistAngle = typeof(options.twistAngle) !== 'undefined' ? options.twistAngle : 0;
-
- c.maxForce = 0;
- c.minForce = -maxForce;
-
- t.maxForce = 0;
- t.minForce = -maxForce;
- this.equations.push(c, t);
- }
- ConeTwistConstraint.prototype = new PointToPointConstraint();
- ConeTwistConstraint.constructor = ConeTwistConstraint;
- var ConeTwistConstraint_update_tmpVec1 = new Vec3();
- var ConeTwistConstraint_update_tmpVec2 = new Vec3();
- ConeTwistConstraint.prototype.update = function(){
- var bodyA = this.bodyA,
- bodyB = this.bodyB,
- cone = this.coneEquation,
- twist = this.twistEquation;
- PointToPointConstraint.prototype.update.call(this);
-
- bodyA.vectorToWorldFrame(this.axisA, cone.axisA);
- bodyB.vectorToWorldFrame(this.axisB, cone.axisB);
-
- this.axisA.tangents(twist.axisA, twist.axisA);
- bodyA.vectorToWorldFrame(twist.axisA, twist.axisA);
- this.axisB.tangents(twist.axisB, twist.axisB);
- bodyB.vectorToWorldFrame(twist.axisB, twist.axisB);
- cone.angle = this.angle;
- twist.maxAngle = this.twistAngle;
- };
- },{"../equations/ConeEquation":34,"../equations/ContactEquation":35,"../equations/RotationalEquation":38,"../math/Vec3":46,"./Constraint":29,"./PointToPointConstraint":33}],29:[function(require,module,exports){
- module.exports = Constraint;
- var Utils = require('../utils/Utils');
- function Constraint(bodyA, bodyB, options){
- options = Utils.defaults(options,{
- collideConnected : true,
- wakeUpBodies : true,
- });
-
- this.equations = [];
-
- this.bodyA = bodyA;
-
- this.bodyB = bodyB;
-
- this.id = Constraint.idCounter++;
-
- this.collideConnected = options.collideConnected;
- if(options.wakeUpBodies){
- if(bodyA){
- bodyA.wakeUp();
- }
- if(bodyB){
- bodyB.wakeUp();
- }
- }
- }
- Constraint.prototype.update = function(){
- throw new Error("method update() not implmemented in this Constraint subclass!");
- };
- Constraint.prototype.enable = function(){
- var eqs = this.equations;
- for(var i=0; i<eqs.length; i++){
- eqs[i].enabled = true;
- }
- };
- Constraint.prototype.disable = function(){
- var eqs = this.equations;
- for(var i=0; i<eqs.length; i++){
- eqs[i].enabled = false;
- }
- };
- Constraint.idCounter = 0;
- },{"../utils/Utils":69}],30:[function(require,module,exports){
- module.exports = DistanceConstraint;
- var Constraint = require('./Constraint');
- var ContactEquation = require('../equations/ContactEquation');
- function DistanceConstraint(bodyA,bodyB,distance,maxForce){
- Constraint.call(this,bodyA,bodyB);
- if(typeof(distance)==="undefined") {
- distance = bodyA.position.distanceTo(bodyB.position);
- }
- if(typeof(maxForce)==="undefined") {
- maxForce = 1e6;
- }
-
- this.distance = distance;
-
- var eq = this.distanceEquation = new ContactEquation(bodyA, bodyB);
- this.equations.push(eq);
-
- eq.minForce = -maxForce;
- eq.maxForce = maxForce;
- }
- DistanceConstraint.prototype = new Constraint();
- DistanceConstraint.prototype.update = function(){
- var bodyA = this.bodyA;
- var bodyB = this.bodyB;
- var eq = this.distanceEquation;
- var halfDist = this.distance * 0.5;
- var normal = eq.ni;
- bodyB.position.vsub(bodyA.position, normal);
- normal.normalize();
- normal.mult(halfDist, eq.ri);
- normal.mult(-halfDist, eq.rj);
- };
- },{"../equations/ContactEquation":35,"./Constraint":29}],31:[function(require,module,exports){
- module.exports = HingeConstraint;
- var Constraint = require('./Constraint');
- var PointToPointConstraint = require('./PointToPointConstraint');
- var RotationalEquation = require('../equations/RotationalEquation');
- var RotationalMotorEquation = require('../equations/RotationalMotorEquation');
- var ContactEquation = require('../equations/ContactEquation');
- var Vec3 = require('../math/Vec3');
- function HingeConstraint(bodyA, bodyB, options){
- options = options || {};
- var maxForce = typeof(options.maxForce) !== 'undefined' ? options.maxForce : 1e6;
- var pivotA = options.pivotA ? options.pivotA.clone() : new Vec3();
- var pivotB = options.pivotB ? options.pivotB.clone() : new Vec3();
- PointToPointConstraint.call(this, bodyA, pivotA, bodyB, pivotB, maxForce);
-
- var axisA = this.axisA = options.axisA ? options.axisA.clone() : new Vec3(1,0,0);
- axisA.normalize();
-
- var axisB = this.axisB = options.axisB ? options.axisB.clone() : new Vec3(1,0,0);
- axisB.normalize();
-
- var r1 = this.rotationalEquation1 = new RotationalEquation(bodyA,bodyB,options);
-
- var r2 = this.rotationalEquation2 = new RotationalEquation(bodyA,bodyB,options);
-
- var motor = this.motorEquation = new RotationalMotorEquation(bodyA,bodyB,maxForce);
- motor.enabled = false;
-
- this.equations.push(
- r1,
- r2,
- motor
- );
- }
- HingeConstraint.prototype = new PointToPointConstraint();
- HingeConstraint.constructor = HingeConstraint;
- HingeConstraint.prototype.enableMotor = function(){
- this.motorEquation.enabled = true;
- };
- HingeConstraint.prototype.disableMotor = function(){
- this.motorEquation.enabled = false;
- };
- HingeConstraint.prototype.setMotorSpeed = function(speed){
- this.motorEquation.targetVelocity = speed;
- };
- HingeConstraint.prototype.setMotorMaxForce = function(maxForce){
- this.motorEquation.maxForce = maxForce;
- this.motorEquation.minForce = -maxForce;
- };
- var HingeConstraint_update_tmpVec1 = new Vec3();
- var HingeConstraint_update_tmpVec2 = new Vec3();
- HingeConstraint.prototype.update = function(){
- var bodyA = this.bodyA,
- bodyB = this.bodyB,
- motor = this.motorEquation,
- r1 = this.rotationalEquation1,
- r2 = this.rotationalEquation2,
- worldAxisA = HingeConstraint_update_tmpVec1,
- worldAxisB = HingeConstraint_update_tmpVec2;
- var axisA = this.axisA;
- var axisB = this.axisB;
- PointToPointConstraint.prototype.update.call(this);
-
- bodyA.quaternion.vmult(axisA, worldAxisA);
- bodyB.quaternion.vmult(axisB, worldAxisB);
- worldAxisA.tangents(r1.axisA, r2.axisA);
- r1.axisB.copy(worldAxisB);
- r2.axisB.copy(worldAxisB);
- if(this.motorEquation.enabled){
- bodyA.quaternion.vmult(this.axisA, motor.axisA);
- bodyB.quaternion.vmult(this.axisB, motor.axisB);
- }
- };
- },{"../equations/ContactEquation":35,"../equations/RotationalEquation":38,"../equations/RotationalMotorEquation":39,"../math/Vec3":46,"./Constraint":29,"./PointToPointConstraint":33}],32:[function(require,module,exports){
- module.exports = LockConstraint;
- var Constraint = require('./Constraint');
- var PointToPointConstraint = require('./PointToPointConstraint');
- var RotationalEquation = require('../equations/RotationalEquation');
- var RotationalMotorEquation = require('../equations/RotationalMotorEquation');
- var ContactEquation = require('../equations/ContactEquation');
- var Vec3 = require('../math/Vec3');
- function LockConstraint(bodyA, bodyB, options){
- options = options || {};
- var maxForce = typeof(options.maxForce) !== 'undefined' ? options.maxForce : 1e6;
-
- var pivotA = new Vec3();
- var pivotB = new Vec3();
- var halfWay = new Vec3();
- bodyA.position.vadd(bodyB.position, halfWay);
- halfWay.scale(0.5, halfWay);
- bodyB.pointToLocalFrame(halfWay, pivotB);
- bodyA.pointToLocalFrame(halfWay, pivotA);
-
- PointToPointConstraint.call(this, bodyA, pivotA, bodyB, pivotB, maxForce);
-
- this.xA = bodyA.vectorToLocalFrame(Vec3.UNIT_X);
- this.xB = bodyB.vectorToLocalFrame(Vec3.UNIT_X);
- this.yA = bodyA.vectorToLocalFrame(Vec3.UNIT_Y);
- this.yB = bodyB.vectorToLocalFrame(Vec3.UNIT_Y);
- this.zA = bodyA.vectorToLocalFrame(Vec3.UNIT_Z);
- this.zB = bodyB.vectorToLocalFrame(Vec3.UNIT_Z);
-
-
- var r1 = this.rotationalEquation1 = new RotationalEquation(bodyA,bodyB,options);
-
- var r2 = this.rotationalEquation2 = new RotationalEquation(bodyA,bodyB,options);
-
- var r3 = this.rotationalEquation3 = new RotationalEquation(bodyA,bodyB,options);
- this.equations.push(r1, r2, r3);
- }
- LockConstraint.prototype = new PointToPointConstraint();
- LockConstraint.constructor = LockConstraint;
- var LockConstraint_update_tmpVec1 = new Vec3();
- var LockConstraint_update_tmpVec2 = new Vec3();
- LockConstraint.prototype.update = function(){
- var bodyA = this.bodyA,
- bodyB = this.bodyB,
- motor = this.motorEquation,
- r1 = this.rotationalEquation1,
- r2 = this.rotationalEquation2,
- r3 = this.rotationalEquation3,
- worldAxisA = LockConstraint_update_tmpVec1,
- worldAxisB = LockConstraint_update_tmpVec2;
- PointToPointConstraint.prototype.update.call(this);
-
- bodyA.vectorToWorldFrame(this.xA, r1.axisA);
- bodyB.vectorToWorldFrame(this.yB, r1.axisB);
- bodyA.vectorToWorldFrame(this.yA, r2.axisA);
- bodyB.vectorToWorldFrame(this.zB, r2.axisB);
- bodyA.vectorToWorldFrame(this.zA, r3.axisA);
- bodyB.vectorToWorldFrame(this.xB, r3.axisB);
- };
- },{"../equations/ContactEquation":35,"../equations/RotationalEquation":38,"../equations/RotationalMotorEquation":39,"../math/Vec3":46,"./Constraint":29,"./PointToPointConstraint":33}],33:[function(require,module,exports){
- module.exports = PointToPointConstraint;
- var Constraint = require('./Constraint');
- var ContactEquation = require('../equations/ContactEquation');
- var Vec3 = require('../math/Vec3');
- function PointToPointConstraint(bodyA,pivotA,bodyB,pivotB,maxForce){
- Constraint.call(this,bodyA,bodyB);
- maxForce = typeof(maxForce) !== 'undefined' ? maxForce : 1e6;
-
- this.pivotA = pivotA ? pivotA.clone() : new Vec3();
-
- this.pivotB = pivotB ? pivotB.clone() : new Vec3();
-
- var x = this.equationX = new ContactEquation(bodyA,bodyB);
-
- var y = this.equationY = new ContactEquation(bodyA,bodyB);
-
- var z = this.equationZ = new ContactEquation(bodyA,bodyB);
-
- this.equations.push(x, y, z);
-
- x.minForce = y.minForce = z.minForce = -maxForce;
- x.maxForce = y.maxForce = z.maxForce = maxForce;
- x.ni.set(1, 0, 0);
- y.ni.set(0, 1, 0);
- z.ni.set(0, 0, 1);
- }
- PointToPointConstraint.prototype = new Constraint();
- PointToPointConstraint.prototype.update = function(){
- var bodyA = this.bodyA;
- var bodyB = this.bodyB;
- var x = this.equationX;
- var y = this.equationY;
- var z = this.equationZ;
-
- bodyA.quaternion.vmult(this.pivotA,x.ri);
- bodyB.quaternion.vmult(this.pivotB,x.rj);
- y.ri.copy(x.ri);
- y.rj.copy(x.rj);
- z.ri.copy(x.ri);
- z.rj.copy(x.rj);
- };
- },{"../equations/ContactEquation":35,"../math/Vec3":46,"./Constraint":29}],34:[function(require,module,exports){
- module.exports = ConeEquation;
- var Vec3 = require('../math/Vec3');
- var Mat3 = require('../math/Mat3');
- var Equation = require('./Equation');
- function ConeEquation(bodyA, bodyB, options){
- options = options || {};
- var maxForce = typeof(options.maxForce) !== 'undefined' ? options.maxForce : 1e6;
- Equation.call(this,bodyA,bodyB,-maxForce, maxForce);
- this.axisA = options.axisA ? options.axisA.clone() : new Vec3(1, 0, 0);
- this.axisB = options.axisB ? options.axisB.clone() : new Vec3(0, 1, 0);
-
- this.angle = typeof(options.angle) !== 'undefined' ? options.angle : 0;
- }
- ConeEquation.prototype = new Equation();
- ConeEquation.prototype.constructor = ConeEquation;
- var tmpVec1 = new Vec3();
- var tmpVec2 = new Vec3();
- ConeEquation.prototype.computeB = function(h){
- var a = this.a,
- b = this.b,
- ni = this.axisA,
- nj = this.axisB,
- nixnj = tmpVec1,
- njxni = tmpVec2,
- GA = this.jacobianElementA,
- GB = this.jacobianElementB;
-
- ni.cross(nj, nixnj);
- nj.cross(ni, njxni);
-
-
-
-
-
-
- GA.rotational.copy(njxni);
- GB.rotational.copy(nixnj);
- var g = Math.cos(this.angle) - ni.dot(nj),
- GW = this.computeGW(),
- GiMf = this.computeGiMf();
- var B = - g * a - GW * b - h * GiMf;
- return B;
- };
- },{"../math/Mat3":43,"../math/Vec3":46,"./Equation":36}],35:[function(require,module,exports){
- module.exports = ContactEquation;
- var Equation = require('./Equation');
- var Vec3 = require('../math/Vec3');
- var Mat3 = require('../math/Mat3');
- function ContactEquation(bodyA, bodyB, maxForce){
- maxForce = typeof(maxForce) !== 'undefined' ? maxForce : 1e6;
- Equation.call(this, bodyA, bodyB, 0, maxForce);
-
- this.restitution = 0.0;
-
- this.ri = new Vec3();
-
- this.rj = new Vec3();
-
- this.ni = new Vec3();
- }
- ContactEquation.prototype = new Equation();
- ContactEquation.prototype.constructor = ContactEquation;
- var ContactEquation_computeB_temp1 = new Vec3();
- var ContactEquation_computeB_temp2 = new Vec3();
- var ContactEquation_computeB_temp3 = new Vec3();
- ContactEquation.prototype.computeB = function(h){
- var a = this.a,
- b = this.b,
- bi = this.bi,
- bj = this.bj,
- ri = this.ri,
- rj = this.rj,
- rixn = ContactEquation_computeB_temp1,
- rjxn = ContactEquation_computeB_temp2,
- vi = bi.velocity,
- wi = bi.angularVelocity,
- fi = bi.force,
- taui = bi.torque,
- vj = bj.velocity,
- wj = bj.angularVelocity,
- fj = bj.force,
- tauj = bj.torque,
- penetrationVec = ContactEquation_computeB_temp3,
- GA = this.jacobianElementA,
- GB = this.jacobianElementB,
- n = this.ni;
-
- ri.cross(n,rixn);
- rj.cross(n,rjxn);
-
-
- n.negate(GA.spatial);
- rixn.negate(GA.rotational);
- GB.spatial.copy(n);
- GB.rotational.copy(rjxn);
-
- penetrationVec.copy(bj.position);
- penetrationVec.vadd(rj,penetrationVec);
- penetrationVec.vsub(bi.position,penetrationVec);
- penetrationVec.vsub(ri,penetrationVec);
- var g = n.dot(penetrationVec);
-
- var ePlusOne = this.restitution + 1;
- var GW = ePlusOne * vj.dot(n) - ePlusOne * vi.dot(n) + wj.dot(rjxn) - wi.dot(rixn);
- var GiMf = this.computeGiMf();
- var B = - g * a - GW * b - h*GiMf;
- return B;
- };
- var ContactEquation_getImpactVelocityAlongNormal_vi = new Vec3();
- var ContactEquation_getImpactVelocityAlongNormal_vj = new Vec3();
- var ContactEquation_getImpactVelocityAlongNormal_xi = new Vec3();
- var ContactEquation_getImpactVelocityAlongNormal_xj = new Vec3();
- var ContactEquation_getImpactVelocityAlongNormal_relVel = new Vec3();
- ContactEquation.prototype.getImpactVelocityAlongNormal = function(){
- var vi = ContactEquation_getImpactVelocityAlongNormal_vi;
- var vj = ContactEquation_getImpactVelocityAlongNormal_vj;
- var xi = ContactEquation_getImpactVelocityAlongNormal_xi;
- var xj = ContactEquation_getImpactVelocityAlongNormal_xj;
- var relVel = ContactEquation_getImpactVelocityAlongNormal_relVel;
- this.bi.position.vadd(this.ri, xi);
- this.bj.position.vadd(this.rj, xj);
- this.bi.getVelocityAtWorldPoint(xi, vi);
- this.bj.getVelocityAtWorldPoint(xj, vj);
- vi.vsub(vj, relVel);
- return this.ni.dot(relVel);
- };
- },{"../math/Mat3":43,"../math/Vec3":46,"./Equation":36}],36:[function(require,module,exports){
- module.exports = Equation;
- var JacobianElement = require('../math/JacobianElement'),
- Vec3 = require('../math/Vec3');
- function Equation(bi,bj,minForce,maxForce){
- this.id = Equation.id++;
-
- this.minForce = typeof(minForce)==="undefined" ? -1e6 : minForce;
-
- this.maxForce = typeof(maxForce)==="undefined" ? 1e6 : maxForce;
-
- this.bi = bi;
-
- this.bj = bj;
-
- this.a = 0.0;
-
- this.b = 0.0;
-
- this.eps = 0.0;
-
- this.jacobianElementA = new JacobianElement();
-
- this.jacobianElementB = new JacobianElement();
-
- this.enabled = true;
-
- this.multiplier = 0;
-
- this.setSpookParams(1e7,4,1/60);
- }
- Equation.prototype.constructor = Equation;
- Equation.id = 0;
- Equation.prototype.setSpookParams = function(stiffness,relaxation,timeStep){
- var d = relaxation,
- k = stiffness,
- h = timeStep;
- this.a = 4.0 / (h * (1 + 4 * d));
- this.b = (4.0 * d) / (1 + 4 * d);
- this.eps = 4.0 / (h * h * k * (1 + 4 * d));
- };
- Equation.prototype.computeB = function(a,b,h){
- var GW = this.computeGW(),
- Gq = this.computeGq(),
- GiMf = this.computeGiMf();
- return - Gq * a - GW * b - GiMf*h;
- };
- Equation.prototype.computeGq = function(){
- var GA = this.jacobianElementA,
- GB = this.jacobianElementB,
- bi = this.bi,
- bj = this.bj,
- xi = bi.position,
- xj = bj.position;
- return GA.spatial.dot(xi) + GB.spatial.dot(xj);
- };
- var zero = new Vec3();
- Equation.prototype.computeGW = function(){
- var GA = this.jacobianElementA,
- GB = this.jacobianElementB,
- bi = this.bi,
- bj = this.bj,
- vi = bi.velocity,
- vj = bj.velocity,
- wi = bi.angularVelocity,
- wj = bj.angularVelocity;
- return GA.multiplyVectors(vi,wi) + GB.multiplyVectors(vj,wj);
- };
- Equation.prototype.computeGWlambda = function(){
- var GA = this.jacobianElementA,
- GB = this.jacobianElementB,
- bi = this.bi,
- bj = this.bj,
- vi = bi.vlambda,
- vj = bj.vlambda,
- wi = bi.wlambda,
- wj = bj.wlambda;
- return GA.multiplyVectors(vi,wi) + GB.multiplyVectors(vj,wj);
- };
- var iMfi = new Vec3(),
- iMfj = new Vec3(),
- invIi_vmult_taui = new Vec3(),
- invIj_vmult_tauj = new Vec3();
- Equation.prototype.computeGiMf = function(){
- var GA = this.jacobianElementA,
- GB = this.jacobianElementB,
- bi = this.bi,
- bj = this.bj,
- fi = bi.force,
- ti = bi.torque,
- fj = bj.force,
- tj = bj.torque,
- invMassi = bi.invMassSolve,
- invMassj = bj.invMassSolve;
- fi.scale(invMassi,iMfi);
- fj.scale(invMassj,iMfj);
- bi.invInertiaWorldSolve.vmult(ti,invIi_vmult_taui);
- bj.invInertiaWorldSolve.vmult(tj,invIj_vmult_tauj);
- return GA.multiplyVectors(iMfi,invIi_vmult_taui) + GB.multiplyVectors(iMfj,invIj_vmult_tauj);
- };
- var tmp = new Vec3();
- Equation.prototype.computeGiMGt = function(){
- var GA = this.jacobianElementA,
- GB = this.jacobianElementB,
- bi = this.bi,
- bj = this.bj,
- invMassi = bi.invMassSolve,
- invMassj = bj.invMassSolve,
- invIi = bi.invInertiaWorldSolve,
- invIj = bj.invInertiaWorldSolve,
- result = invMassi + invMassj;
- invIi.vmult(GA.rotational,tmp);
- result += tmp.dot(GA.rotational);
- invIj.vmult(GB.rotational,tmp);
- result += tmp.dot(GB.rotational);
- return result;
- };
- var addToWlambda_temp = new Vec3(),
- addToWlambda_Gi = new Vec3(),
- addToWlambda_Gj = new Vec3(),
- addToWlambda_ri = new Vec3(),
- addToWlambda_rj = new Vec3(),
- addToWlambda_Mdiag = new Vec3();
- Equation.prototype.addToWlambda = function(deltalambda){
- var GA = this.jacobianElementA,
- GB = this.jacobianElementB,
- bi = this.bi,
- bj = this.bj,
- temp = addToWlambda_temp;
-
-
- bi.vlambda.addScaledVector(bi.invMassSolve * deltalambda, GA.spatial, bi.vlambda);
- bj.vlambda.addScaledVector(bj.invMassSolve * deltalambda, GB.spatial, bj.vlambda);
-
- bi.invInertiaWorldSolve.vmult(GA.rotational,temp);
- bi.wlambda.addScaledVector(deltalambda, temp, bi.wlambda);
- bj.invInertiaWorldSolve.vmult(GB.rotational,temp);
- bj.wlambda.addScaledVector(deltalambda, temp, bj.wlambda);
- };
- Equation.prototype.computeC = function(){
- return this.computeGiMGt() + this.eps;
- };
- },{"../math/JacobianElement":42,"../math/Vec3":46}],37:[function(require,module,exports){
- module.exports = FrictionEquation;
- var Equation = require('./Equation');
- var Vec3 = require('../math/Vec3');
- var Mat3 = require('../math/Mat3');
- function FrictionEquation(bodyA, bodyB, slipForce){
- Equation.call(this,bodyA, bodyB, -slipForce, slipForce);
- this.ri = new Vec3();
- this.rj = new Vec3();
- this.t = new Vec3();
- }
- FrictionEquation.prototype = new Equation();
- FrictionEquation.prototype.constructor = FrictionEquation;
- var FrictionEquation_computeB_temp1 = new Vec3();
- var FrictionEquation_computeB_temp2 = new Vec3();
- FrictionEquation.prototype.computeB = function(h){
- var a = this.a,
- b = this.b,
- bi = this.bi,
- bj = this.bj,
- ri = this.ri,
- rj = this.rj,
- rixt = FrictionEquation_computeB_temp1,
- rjxt = FrictionEquation_computeB_temp2,
- t = this.t;
-
- ri.cross(t,rixt);
- rj.cross(t,rjxt);
-
-
- var GA = this.jacobianElementA,
- GB = this.jacobianElementB;
- t.negate(GA.spatial);
- rixt.negate(GA.rotational);
- GB.spatial.copy(t);
- GB.rotational.copy(rjxt);
- var GW = this.computeGW();
- var GiMf = this.computeGiMf();
- var B = - GW * b - h * GiMf;
- return B;
- };
- },{"../math/Mat3":43,"../math/Vec3":46,"./Equation":36}],38:[function(require,module,exports){
- module.exports = RotationalEquation;
- var Vec3 = require('../math/Vec3');
- var Mat3 = require('../math/Mat3');
- var Equation = require('./Equation');
- function RotationalEquation(bodyA, bodyB, options){
- options = options || {};
- var maxForce = typeof(options.maxForce) !== 'undefined' ? options.maxForce : 1e6;
- Equation.call(this,bodyA,bodyB,-maxForce, maxForce);
- this.axisA = options.axisA ? options.axisA.clone() : new Vec3(1, 0, 0);
- this.axisB = options.axisB ? options.axisB.clone() : new Vec3(0, 1, 0);
- this.maxAngle = Math.PI / 2;
- }
- RotationalEquation.prototype = new Equation();
- RotationalEquation.prototype.constructor = RotationalEquation;
- var tmpVec1 = new Vec3();
- var tmpVec2 = new Vec3();
- RotationalEquation.prototype.computeB = function(h){
- var a = this.a,
- b = this.b,
- ni = this.axisA,
- nj = this.axisB,
- nixnj = tmpVec1,
- njxni = tmpVec2,
- GA = this.jacobianElementA,
- GB = this.jacobianElementB;
-
- ni.cross(nj, nixnj);
- nj.cross(ni, njxni);
-
-
-
-
- GA.rotational.copy(njxni);
- GB.rotational.copy(nixnj);
- var g = Math.cos(this.maxAngle) - ni.dot(nj),
- GW = this.computeGW(),
- GiMf = this.computeGiMf();
- var B = - g * a - GW * b - h * GiMf;
- return B;
- };
- },{"../math/Mat3":43,"../math/Vec3":46,"./Equation":36}],39:[function(require,module,exports){
- module.exports = RotationalMotorEquation;
- var Vec3 = require('../math/Vec3');
- var Mat3 = require('../math/Mat3');
- var Equation = require('./Equation');
- function RotationalMotorEquation(bodyA, bodyB, maxForce){
- maxForce = typeof(maxForce)!=='undefined' ? maxForce : 1e6;
- Equation.call(this,bodyA,bodyB,-maxForce,maxForce);
-
- this.axisA = new Vec3();
-
- this.axisB = new Vec3();
-
- this.targetVelocity = 0;
- }
- RotationalMotorEquation.prototype = new Equation();
- RotationalMotorEquation.prototype.constructor = RotationalMotorEquation;
- RotationalMotorEquation.prototype.computeB = function(h){
- var a = this.a,
- b = this.b,
- bi = this.bi,
- bj = this.bj,
- axisA = this.axisA,
- axisB = this.axisB,
- GA = this.jacobianElementA,
- GB = this.jacobianElementB;
-
-
-
-
-
- GA.rotational.copy(axisA);
- axisB.negate(GB.rotational);
- var GW = this.computeGW() - this.targetVelocity,
- GiMf = this.computeGiMf();
- var B = - GW * b - h * GiMf;
- return B;
- };
- },{"../math/Mat3":43,"../math/Vec3":46,"./Equation":36}],40:[function(require,module,exports){
- var Utils = require('../utils/Utils');
- module.exports = ContactMaterial;
- function ContactMaterial(m1, m2, options){
- options = Utils.defaults(options, {
- friction: 0.3,
- restitution: 0.3,
- contactEquationStiffness: 1e7,
- contactEquationRelaxation: 3,
- frictionEquationStiffness: 1e7,
- frictionEquationRelaxation: 3
- });
-
- this.id = ContactMaterial.idCounter++;
-
- this.materials = [m1, m2];
-
- this.friction = options.friction;
-
- this.restitution = options.restitution;
-
- this.contactEquationStiffness = options.contactEquationStiffness;
-
- this.contactEquationRelaxation = options.contactEquationRelaxation;
-
- this.frictionEquationStiffness = options.frictionEquationStiffness;
-
- this.frictionEquationRelaxation = options.frictionEquationRelaxation;
- }
- ContactMaterial.idCounter = 0;
- },{"../utils/Utils":69}],41:[function(require,module,exports){
- module.exports = Material;
- function Material(options){
- var name = '';
- options = options || {};
-
- if(typeof(options) === 'string'){
- name = options;
- options = {};
- } else if(typeof(options) === 'object') {
- name = '';
- }
-
- this.name = name;
-
- this.id = Material.idCounter++;
-
- this.friction = typeof(options.friction) !== 'undefined' ? options.friction : -1;
-
- this.restitution = typeof(options.restitution) !== 'undefined' ? options.restitution : -1;
- }
- Material.idCounter = 0;
- },{}],42:[function(require,module,exports){
- module.exports = JacobianElement;
- var Vec3 = require('./Vec3');
- function JacobianElement(){
-
- this.spatial = new Vec3();
-
- this.rotational = new Vec3();
- }
- JacobianElement.prototype.multiplyElement = function(element){
- return element.spatial.dot(this.spatial) + element.rotational.dot(this.rotational);
- };
- JacobianElement.prototype.multiplyVectors = function(spatial,rotational){
- return spatial.dot(this.spatial) + rotational.dot(this.rotational);
- };
- },{"./Vec3":46}],43:[function(require,module,exports){
- module.exports = Mat3;
- var Vec3 = require('./Vec3');
- function Mat3(elements){
-
- if(elements){
- this.elements = elements;
- } else {
- this.elements = [0,0,0,0,0,0,0,0,0];
- }
- }
- Mat3.prototype.identity = function(){
- var e = this.elements;
- e[0] = 1;
- e[1] = 0;
- e[2] = 0;
- e[3] = 0;
- e[4] = 1;
- e[5] = 0;
- e[6] = 0;
- e[7] = 0;
- e[8] = 1;
- };
- Mat3.prototype.setZero = function(){
- var e = this.elements;
- e[0] = 0;
- e[1] = 0;
- e[2] = 0;
- e[3] = 0;
- e[4] = 0;
- e[5] = 0;
- e[6] = 0;
- e[7] = 0;
- e[8] = 0;
- };
- Mat3.prototype.setTrace = function(vec3){
- var e = this.elements;
- e[0] = vec3.x;
- e[4] = vec3.y;
- e[8] = vec3.z;
- };
- Mat3.prototype.getTrace = function(target){
- var target = target || new Vec3();
- var e = this.elements;
- target.x = e[0];
- target.y = e[4];
- target.z = e[8];
- };
- Mat3.prototype.vmult = function(v,target){
- target = target || new Vec3();
- var e = this.elements,
- x = v.x,
- y = v.y,
- z = v.z;
- target.x = e[0]*x + e[1]*y + e[2]*z;
- target.y = e[3]*x + e[4]*y + e[5]*z;
- target.z = e[6]*x + e[7]*y + e[8]*z;
- return target;
- };
- Mat3.prototype.smult = function(s){
- for(var i=0; i<this.elements.length; i++){
- this.elements[i] *= s;
- }
- };
- Mat3.prototype.mmult = function(m,target){
- var r = target || new Mat3();
- for(var i=0; i<3; i++){
- for(var j=0; j<3; j++){
- var sum = 0.0;
- for(var k=0; k<3; k++){
- sum += m.elements[i+k*3] * this.elements[k+j*3];
- }
- r.elements[i+j*3] = sum;
- }
- }
- return r;
- };
- Mat3.prototype.scale = function(v,target){
- target = target || new Mat3();
- var e = this.elements,
- t = target.elements;
- for(var i=0; i!==3; i++){
- t[3*i + 0] = v.x * e[3*i + 0];
- t[3*i + 1] = v.y * e[3*i + 1];
- t[3*i + 2] = v.z * e[3*i + 2];
- }
- return target;
- };
- Mat3.prototype.solve = function(b,target){
- target = target || new Vec3();
-
- var nr = 3;
- var nc = 4;
- var eqns = [];
- for(var i=0; i<nr*nc; i++){
- eqns.push(0);
- }
- var i,j;
- for(i=0; i<3; i++){
- for(j=0; j<3; j++){
- eqns[i+nc*j] = this.elements[i+3*j];
- }
- }
- eqns[3+4*0] = b.x;
- eqns[3+4*1] = b.y;
- eqns[3+4*2] = b.z;
-
- var n = 3, k = n, np;
- var kp = 4;
- var p, els;
- do {
- i = k - n;
- if (eqns[i+nc*i] === 0) {
-
- for (j = i + 1; j < k; j++) {
- if (eqns[i+nc*j] !== 0) {
- np = kp;
- do {
- p = kp - np;
- eqns[p+nc*i] += eqns[p+nc*j];
- } while (--np);
- break;
- }
- }
- }
- if (eqns[i+nc*i] !== 0) {
- for (j = i + 1; j < k; j++) {
- var multiplier = eqns[i+nc*j] / eqns[i+nc*i];
- np = kp;
- do {
- p = kp - np;
- eqns[p+nc*j] = p <= i ? 0 : eqns[p+nc*j] - eqns[p+nc*i] * multiplier ;
- } while (--np);
- }
- }
- } while (--n);
-
- target.z = eqns[2*nc+3] / eqns[2*nc+2];
- target.y = (eqns[1*nc+3] - eqns[1*nc+2]*target.z) / eqns[1*nc+1];
- target.x = (eqns[0*nc+3] - eqns[0*nc+2]*target.z - eqns[0*nc+1]*target.y) / eqns[0*nc+0];
- if(isNaN(target.x) || isNaN(target.y) || isNaN(target.z) || target.x===Infinity || target.y===Infinity || target.z===Infinity){
- throw "Could not solve equation! Got x=["+target.toString()+"], b=["+b.toString()+"], A=["+this.toString()+"]";
- }
- return target;
- };
- Mat3.prototype.e = function( row , column ,value){
- if(value===undefined){
- return this.elements[column+3*row];
- } else {
-
- this.elements[column+3*row] = value;
- }
- };
- Mat3.prototype.copy = function(source){
- for(var i=0; i < source.elements.length; i++){
- this.elements[i] = source.elements[i];
- }
- return this;
- };
- Mat3.prototype.toString = function(){
- var r = "";
- var sep = ",";
- for(var i=0; i<9; i++){
- r += this.elements[i] + sep;
- }
- return r;
- };
- Mat3.prototype.reverse = function(target){
- target = target || new Mat3();
-
- var nr = 3;
- var nc = 6;
- var eqns = [];
- for(var i=0; i<nr*nc; i++){
- eqns.push(0);
- }
- var i,j;
- for(i=0; i<3; i++){
- for(j=0; j<3; j++){
- eqns[i+nc*j] = this.elements[i+3*j];
- }
- }
- eqns[3+6*0] = 1;
- eqns[3+6*1] = 0;
- eqns[3+6*2] = 0;
- eqns[4+6*0] = 0;
- eqns[4+6*1] = 1;
- eqns[4+6*2] = 0;
- eqns[5+6*0] = 0;
- eqns[5+6*1] = 0;
- eqns[5+6*2] = 1;
-
- var n = 3, k = n, np;
- var kp = nc;
- var p;
- do {
- i = k - n;
- if (eqns[i+nc*i] === 0) {
-
- for (j = i + 1; j < k; j++) {
- if (eqns[i+nc*j] !== 0) {
- np = kp;
- do {
- p = kp - np;
- eqns[p+nc*i] += eqns[p+nc*j];
- } while (--np);
- break;
- }
- }
- }
- if (eqns[i+nc*i] !== 0) {
- for (j = i + 1; j < k; j++) {
- var multiplier = eqns[i+nc*j] / eqns[i+nc*i];
- np = kp;
- do {
- p = kp - np;
- eqns[p+nc*j] = p <= i ? 0 : eqns[p+nc*j] - eqns[p+nc*i] * multiplier ;
- } while (--np);
- }
- }
- } while (--n);
-
- i = 2;
- do {
- j = i-1;
- do {
- var multiplier = eqns[i+nc*j] / eqns[i+nc*i];
- np = nc;
- do {
- p = nc - np;
- eqns[p+nc*j] = eqns[p+nc*j] - eqns[p+nc*i] * multiplier ;
- } while (--np);
- } while (j--);
- } while (--i);
-
- i = 2;
- do {
- var multiplier = 1 / eqns[i+nc*i];
- np = nc;
- do {
- p = nc - np;
- eqns[p+nc*i] = eqns[p+nc*i] * multiplier ;
- } while (--np);
- } while (i--);
- i = 2;
- do {
- j = 2;
- do {
- p = eqns[nr+j+nc*i];
- if( isNaN( p ) || p ===Infinity ){
- throw "Could not reverse! A=["+this.toString()+"]";
- }
- target.e( i , j , p );
- } while (j--);
- } while (i--);
- return target;
- };
- Mat3.prototype.setRotationFromQuaternion = function( q ) {
- var x = q.x, y = q.y, z = q.z, w = q.w,
- x2 = x + x, y2 = y + y, z2 = z + z,
- xx = x * x2, xy = x * y2, xz = x * z2,
- yy = y * y2, yz = y * z2, zz = z * z2,
- wx = w * x2, wy = w * y2, wz = w * z2,
- e = this.elements;
- e[3*0 + 0] = 1 - ( yy + zz );
- e[3*0 + 1] = xy - wz;
- e[3*0 + 2] = xz + wy;
- e[3*1 + 0] = xy + wz;
- e[3*1 + 1] = 1 - ( xx + zz );
- e[3*1 + 2] = yz - wx;
- e[3*2 + 0] = xz - wy;
- e[3*2 + 1] = yz + wx;
- e[3*2 + 2] = 1 - ( xx + yy );
- return this;
- };
- Mat3.prototype.transpose = function( target ) {
- target = target || new Mat3();
- var Mt = target.elements,
- M = this.elements;
- for(var i=0; i!==3; i++){
- for(var j=0; j!==3; j++){
- Mt[3*i + j] = M[3*j + i];
- }
- }
- return target;
- };
- },{"./Vec3":46}],44:[function(require,module,exports){
- module.exports = Quaternion;
- var Vec3 = require('./Vec3');
- function Quaternion(x,y,z,w){
-
- this.x = x!==undefined ? x : 0;
-
- this.y = y!==undefined ? y : 0;
-
- this.z = z!==undefined ? z : 0;
-
- this.w = w!==undefined ? w : 1;
- }
- Quaternion.prototype.set = function(x,y,z,w){
- this.x = x;
- this.y = y;
- this.z = z;
- this.w = w;
- return this;
- };
- Quaternion.prototype.toString = function(){
- return this.x+","+this.y+","+this.z+","+this.w;
- };
- Quaternion.prototype.toArray = function(){
- return [this.x, this.y, this.z, this.w];
- };
- Quaternion.prototype.setFromAxisAngle = function(axis,angle){
- var s = Math.sin(angle*0.5);
- this.x = axis.x * s;
- this.y = axis.y * s;
- this.z = axis.z * s;
- this.w = Math.cos(angle*0.5);
- return this;
- };
- Quaternion.prototype.toAxisAngle = function(targetAxis){
- targetAxis = targetAxis || new Vec3();
- this.normalize();
- var angle = 2 * Math.acos(this.w);
- var s = Math.sqrt(1-this.w*this.w);
- if (s < 0.001) {
-
- targetAxis.x = this.x;
- targetAxis.y = this.y;
- targetAxis.z = this.z;
- } else {
- targetAxis.x = this.x / s;
- targetAxis.y = this.y / s;
- targetAxis.z = this.z / s;
- }
- return [targetAxis,angle];
- };
- var sfv_t1 = new Vec3(),
- sfv_t2 = new Vec3();
- Quaternion.prototype.setFromVectors = function(u,v){
- if(u.isAntiparallelTo(v)){
- var t1 = sfv_t1;
- var t2 = sfv_t2;
- u.tangents(t1,t2);
- this.setFromAxisAngle(t1,Math.PI);
- } else {
- var a = u.cross(v);
- this.x = a.x;
- this.y = a.y;
- this.z = a.z;
- this.w = Math.sqrt(Math.pow(u.norm(),2) * Math.pow(v.norm(),2)) + u.dot(v);
- this.normalize();
- }
- return this;
- };
- var Quaternion_mult_va = new Vec3();
- var Quaternion_mult_vb = new Vec3();
- var Quaternion_mult_vaxvb = new Vec3();
- Quaternion.prototype.mult = function(q,target){
- target = target || new Quaternion();
- var ax = this.x, ay = this.y, az = this.z, aw = this.w,
- bx = q.x, by = q.y, bz = q.z, bw = q.w;
- target.x = ax * bw + aw * bx + ay * bz - az * by;
- target.y = ay * bw + aw * by + az * bx - ax * bz;
- target.z = az * bw + aw * bz + ax * by - ay * bx;
- target.w = aw * bw - ax * bx - ay * by - az * bz;
- return target;
- };
- Quaternion.prototype.inverse = function(target){
- var x = this.x, y = this.y, z = this.z, w = this.w;
- target = target || new Quaternion();
- this.conjugate(target);
- var inorm2 = 1/(x*x + y*y + z*z + w*w);
- target.x *= inorm2;
- target.y *= inorm2;
- target.z *= inorm2;
- target.w *= inorm2;
- return target;
- };
- Quaternion.prototype.conjugate = function(target){
- target = target || new Quaternion();
- target.x = -this.x;
- target.y = -this.y;
- target.z = -this.z;
- target.w = this.w;
- return target;
- };
- Quaternion.prototype.normalize = function(){
- var l = Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w);
- if ( l === 0 ) {
- this.x = 0;
- this.y = 0;
- this.z = 0;
- this.w = 0;
- } else {
- l = 1 / l;
- this.x *= l;
- this.y *= l;
- this.z *= l;
- this.w *= l;
- }
- return this;
- };
- Quaternion.prototype.normalizeFast = function () {
- var f = (3.0-(this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w))/2.0;
- if ( f === 0 ) {
- this.x = 0;
- this.y = 0;
- this.z = 0;
- this.w = 0;
- } else {
- this.x *= f;
- this.y *= f;
- this.z *= f;
- this.w *= f;
- }
- return this;
- };
- Quaternion.prototype.vmult = function(v,target){
- target = target || new Vec3();
- var x = v.x,
- y = v.y,
- z = v.z;
- var qx = this.x,
- qy = this.y,
- qz = this.z,
- qw = this.w;
-
- var ix = qw * x + qy * z - qz * y,
- iy = qw * y + qz * x - qx * z,
- iz = qw * z + qx * y - qy * x,
- iw = -qx * x - qy * y - qz * z;
- target.x = ix * qw + iw * -qx + iy * -qz - iz * -qy;
- target.y = iy * qw + iw * -qy + iz * -qx - ix * -qz;
- target.z = iz * qw + iw * -qz + ix * -qy - iy * -qx;
- return target;
- };
- Quaternion.prototype.copy = function(source){
- this.x = source.x;
- this.y = source.y;
- this.z = source.z;
- this.w = source.w;
- return this;
- };
- Quaternion.prototype.toEuler = function(target,order){
- order = order || "YZX";
- var heading, attitude, bank;
- var x = this.x, y = this.y, z = this.z, w = this.w;
- switch(order){
- case "YZX":
- var test = x*y + z*w;
- if (test > 0.499) {
- heading = 2 * Math.atan2(x,w);
- attitude = Math.PI/2;
- bank = 0;
- }
- if (test < -0.499) {
- heading = -2 * Math.atan2(x,w);
- attitude = - Math.PI/2;
- bank = 0;
- }
- if(isNaN(heading)){
- var sqx = x*x;
- var sqy = y*y;
- var sqz = z*z;
- heading = Math.atan2(2*y*w - 2*x*z , 1 - 2*sqy - 2*sqz);
- attitude = Math.asin(2*test);
- bank = Math.atan2(2*x*w - 2*y*z , 1 - 2*sqx - 2*sqz);
- }
- break;
- default:
- throw new Error("Euler order "+order+" not supported yet.");
- }
- target.y = heading;
- target.z = attitude;
- target.x = bank;
- };
- Quaternion.prototype.setFromEuler = function ( x, y, z, order ) {
- order = order || "XYZ";
- var c1 = Math.cos( x / 2 );
- var c2 = Math.cos( y / 2 );
- var c3 = Math.cos( z / 2 );
- var s1 = Math.sin( x / 2 );
- var s2 = Math.sin( y / 2 );
- var s3 = Math.sin( z / 2 );
- if ( order === 'XYZ' ) {
- this.x = s1 * c2 * c3 + c1 * s2 * s3;
- this.y = c1 * s2 * c3 - s1 * c2 * s3;
- this.z = c1 * c2 * s3 + s1 * s2 * c3;
- this.w = c1 * c2 * c3 - s1 * s2 * s3;
- } else if ( order === 'YXZ' ) {
- this.x = s1 * c2 * c3 + c1 * s2 * s3;
- this.y = c1 * s2 * c3 - s1 * c2 * s3;
- this.z = c1 * c2 * s3 - s1 * s2 * c3;
- this.w = c1 * c2 * c3 + s1 * s2 * s3;
- } else if ( order === 'ZXY' ) {
- this.x = s1 * c2 * c3 - c1 * s2 * s3;
- this.y = c1 * s2 * c3 + s1 * c2 * s3;
- this.z = c1 * c2 * s3 + s1 * s2 * c3;
- this.w = c1 * c2 * c3 - s1 * s2 * s3;
- } else if ( order === 'ZYX' ) {
- this.x = s1 * c2 * c3 - c1 * s2 * s3;
- this.y = c1 * s2 * c3 + s1 * c2 * s3;
- this.z = c1 * c2 * s3 - s1 * s2 * c3;
- this.w = c1 * c2 * c3 + s1 * s2 * s3;
- } else if ( order === 'YZX' ) {
- this.x = s1 * c2 * c3 + c1 * s2 * s3;
- this.y = c1 * s2 * c3 + s1 * c2 * s3;
- this.z = c1 * c2 * s3 - s1 * s2 * c3;
- this.w = c1 * c2 * c3 - s1 * s2 * s3;
- } else if ( order === 'XZY' ) {
- this.x = s1 * c2 * c3 - c1 * s2 * s3;
- this.y = c1 * s2 * c3 - s1 * c2 * s3;
- this.z = c1 * c2 * s3 + s1 * s2 * c3;
- this.w = c1 * c2 * c3 + s1 * s2 * s3;
- }
- return this;
- };
- Quaternion.prototype.clone = function(){
- return new Quaternion(this.x, this.y, this.z, this.w);
- };
- Quaternion.prototype.slerp = function (toQuat, t, target) {
- target = target || new Quaternion();
- var ax = this.x,
- ay = this.y,
- az = this.z,
- aw = this.w,
- bx = toQuat.x,
- by = toQuat.y,
- bz = toQuat.z,
- bw = toQuat.w;
- var omega, cosom, sinom, scale0, scale1;
-
- cosom = ax * bx + ay * by + az * bz + aw * bw;
-
- if ( cosom < 0.0 ) {
- cosom = -cosom;
- bx = - bx;
- by = - by;
- bz = - bz;
- bw = - bw;
- }
-
- if ( (1.0 - cosom) > 0.000001 ) {
-
- omega = Math.acos(cosom);
- sinom = Math.sin(omega);
- scale0 = Math.sin((1.0 - t) * omega) / sinom;
- scale1 = Math.sin(t * omega) / sinom;
- } else {
-
-
- scale0 = 1.0 - t;
- scale1 = t;
- }
-
- target.x = scale0 * ax + scale1 * bx;
- target.y = scale0 * ay + scale1 * by;
- target.z = scale0 * az + scale1 * bz;
- target.w = scale0 * aw + scale1 * bw;
- return target;
- };
- Quaternion.prototype.integrate = function(angularVelocity, dt, angularFactor, target){
- target = target || new Quaternion();
- var ax = angularVelocity.x * angularFactor.x,
- ay = angularVelocity.y * angularFactor.y,
- az = angularVelocity.z * angularFactor.z,
- bx = this.x,
- by = this.y,
- bz = this.z,
- bw = this.w;
- var half_dt = dt * 0.5;
- target.x += half_dt * (ax * bw + ay * bz - az * by);
- target.y += half_dt * (ay * bw + az * bx - ax * bz);
- target.z += half_dt * (az * bw + ax * by - ay * bx);
- target.w += half_dt * (- ax * bx - ay * by - az * bz);
- return target;
- };
- },{"./Vec3":46}],45:[function(require,module,exports){
- var Vec3 = require('./Vec3');
- var Quaternion = require('./Quaternion');
- module.exports = Transform;
- function Transform(options) {
- options = options || {};
-
- this.position = new Vec3();
- if(options.position){
- this.position.copy(options.position);
- }
-
- this.quaternion = new Quaternion();
- if(options.quaternion){
- this.quaternion.copy(options.quaternion);
- }
- }
- var tmpQuat = new Quaternion();
- Transform.pointToLocalFrame = function(position, quaternion, worldPoint, result){
- var result = result || new Vec3();
- worldPoint.vsub(position, result);
- quaternion.conjugate(tmpQuat);
- tmpQuat.vmult(result, result);
- return result;
- };
- Transform.prototype.pointToLocal = function(worldPoint, result){
- return Transform.pointToLocalFrame(this.position, this.quaternion, worldPoint, result);
- };
- Transform.pointToWorldFrame = function(position, quaternion, localPoint, result){
- var result = result || new Vec3();
- quaternion.vmult(localPoint, result);
- result.vadd(position, result);
- return result;
- };
- Transform.prototype.pointToWorld = function(localPoint, result){
- return Transform.pointToWorldFrame(this.position, this.quaternion, localPoint, result);
- };
- Transform.prototype.vectorToWorldFrame = function(localVector, result){
- var result = result || new Vec3();
- this.quaternion.vmult(localVector, result);
- return result;
- };
- Transform.vectorToWorldFrame = function(quaternion, localVector, result){
- quaternion.vmult(localVector, result);
- return result;
- };
- Transform.vectorToLocalFrame = function(position, quaternion, worldVector, result){
- var result = result || new Vec3();
- quaternion.w *= -1;
- quaternion.vmult(worldVector, result);
- quaternion.w *= -1;
- return result;
- };
- },{"./Quaternion":44,"./Vec3":46}],46:[function(require,module,exports){
- module.exports = Vec3;
- var Mat3 = require('./Mat3');
- function Vec3(x,y,z){
-
- this.x = x||0.0;
-
- this.y = y||0.0;
-
- this.z = z||0.0;
- }
- Vec3.ZERO = new Vec3(0, 0, 0);
- Vec3.UNIT_X = new Vec3(1, 0, 0);
- Vec3.UNIT_Y = new Vec3(0, 1, 0);
- Vec3.UNIT_Z = new Vec3(0, 0, 1);
- Vec3.prototype.cross = function(v,target){
- var vx=v.x, vy=v.y, vz=v.z, x=this.x, y=this.y, z=this.z;
- target = target || new Vec3();
- target.x = (y * vz) - (z * vy);
- target.y = (z * vx) - (x * vz);
- target.z = (x * vy) - (y * vx);
- return target;
- };
- Vec3.prototype.set = function(x,y,z){
- this.x = x;
- this.y = y;
- this.z = z;
- return this;
- };
- Vec3.prototype.setZero = function(){
- this.x = this.y = this.z = 0;
- };
- Vec3.prototype.vadd = function(v,target){
- if(target){
- target.x = v.x + this.x;
- target.y = v.y + this.y;
- target.z = v.z + this.z;
- } else {
- return new Vec3(this.x + v.x,
- this.y + v.y,
- this.z + v.z);
- }
- };
- Vec3.prototype.vsub = function(v,target){
- if(target){
- target.x = this.x - v.x;
- target.y = this.y - v.y;
- target.z = this.z - v.z;
- } else {
- return new Vec3(this.x-v.x,
- this.y-v.y,
- this.z-v.z);
- }
- };
- Vec3.prototype.crossmat = function(){
- return new Mat3([ 0, -this.z, this.y,
- this.z, 0, -this.x,
- -this.y, this.x, 0]);
- };
- Vec3.prototype.normalize = function(){
- var x=this.x, y=this.y, z=this.z;
- var n = Math.sqrt(x*x + y*y + z*z);
- if(n>0.0){
- var invN = 1/n;
- this.x *= invN;
- this.y *= invN;
- this.z *= invN;
- } else {
-
- this.x = 0;
- this.y = 0;
- this.z = 0;
- }
- return n;
- };
- Vec3.prototype.unit = function(target){
- target = target || new Vec3();
- var x=this.x, y=this.y, z=this.z;
- var ninv = Math.sqrt(x*x + y*y + z*z);
- if(ninv>0.0){
- ninv = 1.0/ninv;
- target.x = x * ninv;
- target.y = y * ninv;
- target.z = z * ninv;
- } else {
- target.x = 1;
- target.y = 0;
- target.z = 0;
- }
- return target;
- };
- Vec3.prototype.norm = function(){
- var x=this.x, y=this.y, z=this.z;
- return Math.sqrt(x*x + y*y + z*z);
- };
- Vec3.prototype.length = Vec3.prototype.norm;
- Vec3.prototype.norm2 = function(){
- return this.dot(this);
- };
- Vec3.prototype.lengthSquared = Vec3.prototype.norm2;
- Vec3.prototype.distanceTo = function(p){
- var x=this.x, y=this.y, z=this.z;
- var px=p.x, py=p.y, pz=p.z;
- return Math.sqrt((px-x)*(px-x)+
- (py-y)*(py-y)+
- (pz-z)*(pz-z));
- };
- Vec3.prototype.distanceSquared = function(p){
- var x=this.x, y=this.y, z=this.z;
- var px=p.x, py=p.y, pz=p.z;
- return (px-x)*(px-x) + (py-y)*(py-y) + (pz-z)*(pz-z);
- };
- Vec3.prototype.mult = function(scalar,target){
- target = target || new Vec3();
- var x = this.x,
- y = this.y,
- z = this.z;
- target.x = scalar * x;
- target.y = scalar * y;
- target.z = scalar * z;
- return target;
- };
- Vec3.prototype.vmul = function(vector, target){
- target = target || new Vec3();
- target.x = vector.x * this.x;
- target.y = vector.y * this.y;
- target.z = vector.z * this.z;
- return target;
- };
- Vec3.prototype.scale = Vec3.prototype.mult;
- Vec3.prototype.addScaledVector = function(scalar, vector, target){
- target = target || new Vec3();
- target.x = this.x + scalar * vector.x;
- target.y = this.y + scalar * vector.y;
- target.z = this.z + scalar * vector.z;
- return target;
- };
- Vec3.prototype.dot = function(v){
- return this.x * v.x + this.y * v.y + this.z * v.z;
- };
- Vec3.prototype.isZero = function(){
- return this.x===0 && this.y===0 && this.z===0;
- };
- Vec3.prototype.negate = function(target){
- target = target || new Vec3();
- target.x = -this.x;
- target.y = -this.y;
- target.z = -this.z;
- return target;
- };
- var Vec3_tangents_n = new Vec3();
- var Vec3_tangents_randVec = new Vec3();
- Vec3.prototype.tangents = function(t1,t2){
- var norm = this.norm();
- if(norm>0.0){
- var n = Vec3_tangents_n;
- var inorm = 1/norm;
- n.set(this.x*inorm,this.y*inorm,this.z*inorm);
- var randVec = Vec3_tangents_randVec;
- if(Math.abs(n.x) < 0.9){
- randVec.set(1,0,0);
- n.cross(randVec,t1);
- } else {
- randVec.set(0,1,0);
- n.cross(randVec,t1);
- }
- n.cross(t1,t2);
- } else {
-
- t1.set(1, 0, 0);
- t2.set(0, 1, 0);
- }
- };
- Vec3.prototype.toString = function(){
- return this.x+","+this.y+","+this.z;
- };
- Vec3.prototype.toArray = function(){
- return [this.x, this.y, this.z];
- };
- Vec3.prototype.copy = function(source){
- this.x = source.x;
- this.y = source.y;
- this.z = source.z;
- return this;
- };
- Vec3.prototype.lerp = function(v,t,target){
- var x=this.x, y=this.y, z=this.z;
- target.x = x + (v.x-x)*t;
- target.y = y + (v.y-y)*t;
- target.z = z + (v.z-z)*t;
- };
- Vec3.prototype.almostEquals = function(v,precision){
- if(precision===undefined){
- precision = 1e-6;
- }
- if( Math.abs(this.x-v.x)>precision ||
- Math.abs(this.y-v.y)>precision ||
- Math.abs(this.z-v.z)>precision){
- return false;
- }
- return true;
- };
- Vec3.prototype.almostZero = function(precision){
- if(precision===undefined){
- precision = 1e-6;
- }
- if( Math.abs(this.x)>precision ||
- Math.abs(this.y)>precision ||
- Math.abs(this.z)>precision){
- return false;
- }
- return true;
- };
- var antip_neg = new Vec3();
- Vec3.prototype.isAntiparallelTo = function(v,precision){
- this.negate(antip_neg);
- return antip_neg.almostEquals(v,precision);
- };
- Vec3.prototype.clone = function(){
- return new Vec3(this.x, this.y, this.z);
- };
- },{"./Mat3":43}],47:[function(require,module,exports){
- module.exports = Body;
- var EventTarget = require('../utils/EventTarget');
- var Shape = require('../shapes/Shape');
- var Vec3 = require('../math/Vec3');
- var Mat3 = require('../math/Mat3');
- var Quaternion = require('../math/Quaternion');
- var Material = require('../material/Material');
- var AABB = require('../collision/AABB');
- var Box = require('../shapes/Box');
- function Body(options){
- options = options || {};
- EventTarget.apply(this);
- this.id = Body.idCounter++;
-
- this.world = null;
-
- this.preStep = null;
-
- this.postStep = null;
- this.vlambda = new Vec3();
-
- this.collisionFilterGroup = typeof(options.collisionFilterGroup) === 'number' ? options.collisionFilterGroup : 1;
-
- this.collisionFilterMask = typeof(options.collisionFilterMask) === 'number' ? options.collisionFilterMask : 1;
-
- this.collisionResponse = true;
-
- this.position = new Vec3();
-
- this.previousPosition = new Vec3();
-
- this.interpolatedPosition = new Vec3();
-
- this.initPosition = new Vec3();
- if(options.position){
- this.position.copy(options.position);
- this.previousPosition.copy(options.position);
- this.interpolatedPosition.copy(options.position);
- this.initPosition.copy(options.position);
- }
-
- this.velocity = new Vec3();
- if(options.velocity){
- this.velocity.copy(options.velocity);
- }
-
- this.initVelocity = new Vec3();
-
- this.force = new Vec3();
- var mass = typeof(options.mass) === 'number' ? options.mass : 0;
-
- this.mass = mass;
-
- this.invMass = mass > 0 ? 1.0 / mass : 0;
-
- this.material = options.material || null;
-
- this.linearDamping = typeof(options.linearDamping) === 'number' ? options.linearDamping : 0.01;
-
- this.type = (mass <= 0.0 ? Body.STATIC : Body.DYNAMIC);
- if(typeof(options.type) === typeof(Body.STATIC)){
- this.type = options.type;
- }
-
- this.allowSleep = typeof(options.allowSleep) !== 'undefined' ? options.allowSleep : true;
-
- this.sleepState = 0;
-
- this.sleepSpeedLimit = typeof(options.sleepSpeedLimit) !== 'undefined' ? options.sleepSpeedLimit : 0.1;
-
- this.sleepTimeLimit = typeof(options.sleepTimeLimit) !== 'undefined' ? options.sleepTimeLimit : 1;
- this.timeLastSleepy = 0;
- this._wakeUpAfterNarrowphase = false;
-
- this.torque = new Vec3();
-
- this.quaternion = new Quaternion();
-
- this.initQuaternion = new Quaternion();
-
- this.previousQuaternion = new Quaternion();
-
- this.interpolatedQuaternion = new Quaternion();
- if(options.quaternion){
- this.quaternion.copy(options.quaternion);
- this.initQuaternion.copy(options.quaternion);
- this.previousQuaternion.copy(options.quaternion);
- this.interpolatedQuaternion.copy(options.quaternion);
- }
-
- this.angularVelocity = new Vec3();
- if(options.angularVelocity){
- this.angularVelocity.copy(options.angularVelocity);
- }
-
- this.initAngularVelocity = new Vec3();
-
- this.shapes = [];
-
- this.shapeOffsets = [];
-
- this.shapeOrientations = [];
-
- this.inertia = new Vec3();
-
- this.invInertia = new Vec3();
-
- this.invInertiaWorld = new Mat3();
- this.invMassSolve = 0;
-
- this.invInertiaSolve = new Vec3();
-
- this.invInertiaWorldSolve = new Mat3();
-
- this.fixedRotation = typeof(options.fixedRotation) !== "undefined" ? options.fixedRotation : false;
-
- this.angularDamping = typeof(options.angularDamping) !== 'undefined' ? options.angularDamping : 0.01;
-
- this.linearFactor = new Vec3(1,1,1);
- if(options.linearFactor){
- this.linearFactor.copy(options.linearFactor);
- }
-
- this.angularFactor = new Vec3(1,1,1);
- if(options.angularFactor){
- this.angularFactor.copy(options.angularFactor);
- }
-
- this.aabb = new AABB();
-
- this.aabbNeedsUpdate = true;
- this.wlambda = new Vec3();
- if(options.shape){
- this.addShape(options.shape);
- }
- this.updateMassProperties();
- }
- Body.prototype = new EventTarget();
- Body.prototype.constructor = Body;
- Body.COLLIDE_EVENT_NAME = "collide";
- Body.DYNAMIC = 1;
- Body.STATIC = 2;
- Body.KINEMATIC = 4;
- Body.AWAKE = 0;
- Body.SLEEPY = 1;
- Body.SLEEPING = 2;
- Body.idCounter = 0;
- Body.wakeupEvent = {
- type: "wakeup"
- };
- Body.prototype.wakeUp = function(){
- var s = this.sleepState;
- this.sleepState = 0;
- this._wakeUpAfterNarrowphase = false;
- if(s === Body.SLEEPING){
- this.dispatchEvent(Body.wakeupEvent);
- }
- };
- Body.prototype.sleep = function(){
- this.sleepState = Body.SLEEPING;
- this.velocity.set(0,0,0);
- this.angularVelocity.set(0,0,0);
- this._wakeUpAfterNarrowphase = false;
- };
- Body.sleepyEvent = {
- type: "sleepy"
- };
- Body.sleepEvent = {
- type: "sleep"
- };
- Body.prototype.sleepTick = function(time){
- if(this.allowSleep){
- var sleepState = this.sleepState;
- var speedSquared = this.velocity.norm2() + this.angularVelocity.norm2();
- var speedLimitSquared = Math.pow(this.sleepSpeedLimit,2);
- if(sleepState===Body.AWAKE && speedSquared < speedLimitSquared){
- this.sleepState = Body.SLEEPY;
- this.timeLastSleepy = time;
- this.dispatchEvent(Body.sleepyEvent);
- } else if(sleepState===Body.SLEEPY && speedSquared > speedLimitSquared){
- this.wakeUp();
- } else if(sleepState===Body.SLEEPY && (time - this.timeLastSleepy ) > this.sleepTimeLimit){
- this.sleep();
- this.dispatchEvent(Body.sleepEvent);
- }
- }
- };
- Body.prototype.updateSolveMassProperties = function(){
- if(this.sleepState === Body.SLEEPING || this.type === Body.KINEMATIC){
- this.invMassSolve = 0;
- this.invInertiaSolve.setZero();
- this.invInertiaWorldSolve.setZero();
- } else {
- this.invMassSolve = this.invMass;
- this.invInertiaSolve.copy(this.invInertia);
- this.invInertiaWorldSolve.copy(this.invInertiaWorld);
- }
- };
- Body.prototype.pointToLocalFrame = function(worldPoint,result){
- var result = result || new Vec3();
- worldPoint.vsub(this.position,result);
- this.quaternion.conjugate().vmult(result,result);
- return result;
- };
- Body.prototype.vectorToLocalFrame = function(worldVector, result){
- var result = result || new Vec3();
- this.quaternion.conjugate().vmult(worldVector,result);
- return result;
- };
- Body.prototype.pointToWorldFrame = function(localPoint,result){
- var result = result || new Vec3();
- this.quaternion.vmult(localPoint,result);
- result.vadd(this.position,result);
- return result;
- };
- Body.prototype.vectorToWorldFrame = function(localVector, result){
- var result = result || new Vec3();
- this.quaternion.vmult(localVector, result);
- return result;
- };
- var tmpVec = new Vec3();
- var tmpQuat = new Quaternion();
- Body.prototype.addShape = function(shape, _offset, _orientation){
- var offset = new Vec3();
- var orientation = new Quaternion();
- if(_offset){
- offset.copy(_offset);
- }
- if(_orientation){
- orientation.copy(_orientation);
- }
- this.shapes.push(shape);
- this.shapeOffsets.push(offset);
- this.shapeOrientations.push(orientation);
- this.updateMassProperties();
- this.updateBoundingRadius();
- this.aabbNeedsUpdate = true;
- shape.body = this;
- return this;
- };
- Body.prototype.updateBoundingRadius = function(){
- var shapes = this.shapes,
- shapeOffsets = this.shapeOffsets,
- N = shapes.length,
- radius = 0;
- for(var i=0; i!==N; i++){
- var shape = shapes[i];
- shape.updateBoundingSphereRadius();
- var offset = shapeOffsets[i].norm(),
- r = shape.boundingSphereRadius;
- if(offset + r > radius){
- radius = offset + r;
- }
- }
- this.boundingRadius = radius;
- };
- var computeAABB_shapeAABB = new AABB();
- Body.prototype.computeAABB = function(){
- var shapes = this.shapes,
- shapeOffsets = this.shapeOffsets,
- shapeOrientations = this.shapeOrientations,
- N = shapes.length,
- offset = tmpVec,
- orientation = tmpQuat,
- bodyQuat = this.quaternion,
- aabb = this.aabb,
- shapeAABB = computeAABB_shapeAABB;
- for(var i=0; i!==N; i++){
- var shape = shapes[i];
-
- bodyQuat.vmult(shapeOffsets[i], offset);
- offset.vadd(this.position, offset);
-
- shapeOrientations[i].mult(bodyQuat, orientation);
-
- shape.calculateWorldAABB(offset, orientation, shapeAABB.lowerBound, shapeAABB.upperBound);
- if(i === 0){
- aabb.copy(shapeAABB);
- } else {
- aabb.extend(shapeAABB);
- }
- }
- this.aabbNeedsUpdate = false;
- };
- var uiw_m1 = new Mat3(),
- uiw_m2 = new Mat3(),
- uiw_m3 = new Mat3();
- Body.prototype.updateInertiaWorld = function(force){
- var I = this.invInertia;
- if (I.x === I.y && I.y === I.z && !force) {
-
-
-
-
-
- } else {
- var m1 = uiw_m1,
- m2 = uiw_m2,
- m3 = uiw_m3;
- m1.setRotationFromQuaternion(this.quaternion);
- m1.transpose(m2);
- m1.scale(I,m1);
- m1.mmult(m2,this.invInertiaWorld);
- }
- };
- var Body_applyForce_r = new Vec3();
- var Body_applyForce_rotForce = new Vec3();
- Body.prototype.applyForce = function(force,relativePoint){
- if(this.type !== Body.DYNAMIC){
- return;
- }
-
- var rotForce = Body_applyForce_rotForce;
- relativePoint.cross(force,rotForce);
-
- this.force.vadd(force,this.force);
-
- this.torque.vadd(rotForce,this.torque);
- };
- var Body_applyLocalForce_worldForce = new Vec3();
- var Body_applyLocalForce_relativePointWorld = new Vec3();
- Body.prototype.applyLocalForce = function(localForce, localPoint){
- if(this.type !== Body.DYNAMIC){
- return;
- }
- var worldForce = Body_applyLocalForce_worldForce;
- var relativePointWorld = Body_applyLocalForce_relativePointWorld;
-
- this.vectorToWorldFrame(localForce, worldForce);
- this.vectorToWorldFrame(localPoint, relativePointWorld);
- this.applyForce(worldForce, relativePointWorld);
- };
- var Body_applyImpulse_r = new Vec3();
- var Body_applyImpulse_velo = new Vec3();
- var Body_applyImpulse_rotVelo = new Vec3();
- Body.prototype.applyImpulse = function(impulse, relativePoint){
- if(this.type !== Body.DYNAMIC){
- return;
- }
-
- var r = relativePoint;
-
- var velo = Body_applyImpulse_velo;
- velo.copy(impulse);
- velo.mult(this.invMass,velo);
-
- this.velocity.vadd(velo, this.velocity);
-
- var rotVelo = Body_applyImpulse_rotVelo;
- r.cross(impulse,rotVelo);
-
- this.invInertiaWorld.vmult(rotVelo,rotVelo);
-
- this.angularVelocity.vadd(rotVelo, this.angularVelocity);
- };
- var Body_applyLocalImpulse_worldImpulse = new Vec3();
- var Body_applyLocalImpulse_relativePoint = new Vec3();
- Body.prototype.applyLocalImpulse = function(localImpulse, localPoint){
- if(this.type !== Body.DYNAMIC){
- return;
- }
- var worldImpulse = Body_applyLocalImpulse_worldImpulse;
- var relativePointWorld = Body_applyLocalImpulse_relativePoint;
-
- this.vectorToWorldFrame(localImpulse, worldImpulse);
- this.vectorToWorldFrame(localPoint, relativePointWorld);
- this.applyImpulse(worldImpulse, relativePointWorld);
- };
- var Body_updateMassProperties_halfExtents = new Vec3();
- Body.prototype.updateMassProperties = function(){
- var halfExtents = Body_updateMassProperties_halfExtents;
- this.invMass = this.mass > 0 ? 1.0 / this.mass : 0;
- var I = this.inertia;
- var fixed = this.fixedRotation;
-
- this.computeAABB();
- halfExtents.set(
- (this.aabb.upperBound.x-this.aabb.lowerBound.x) / 2,
- (this.aabb.upperBound.y-this.aabb.lowerBound.y) / 2,
- (this.aabb.upperBound.z-this.aabb.lowerBound.z) / 2
- );
- Box.calculateInertia(halfExtents, this.mass, I);
- this.invInertia.set(
- I.x > 0 && !fixed ? 1.0 / I.x : 0,
- I.y > 0 && !fixed ? 1.0 / I.y : 0,
- I.z > 0 && !fixed ? 1.0 / I.z : 0
- );
- this.updateInertiaWorld(true);
- };
- Body.prototype.getVelocityAtWorldPoint = function(worldPoint, result){
- var r = new Vec3();
- worldPoint.vsub(this.position, r);
- this.angularVelocity.cross(r, result);
- this.velocity.vadd(result, result);
- return result;
- };
- var torque = new Vec3();
- var invI_tau_dt = new Vec3();
- var w = new Quaternion();
- var wq = new Quaternion();
- Body.prototype.integrate = function(dt, quatNormalize, quatNormalizeFast){
-
- this.previousPosition.copy(this.position);
- this.previousQuaternion.copy(this.quaternion);
- if(!(this.type === Body.DYNAMIC || this.type === Body.KINEMATIC) || this.sleepState === Body.SLEEPING){
- return;
- }
- var velo = this.velocity,
- angularVelo = this.angularVelocity,
- pos = this.position,
- force = this.force,
- torque = this.torque,
- quat = this.quaternion,
- invMass = this.invMass,
- invInertia = this.invInertiaWorld,
- linearFactor = this.linearFactor;
- var iMdt = invMass * dt;
- velo.x += force.x * iMdt * linearFactor.x;
- velo.y += force.y * iMdt * linearFactor.y;
- velo.z += force.z * iMdt * linearFactor.z;
- var e = invInertia.elements;
- var angularFactor = this.angularFactor;
- var tx = torque.x * angularFactor.x;
- var ty = torque.y * angularFactor.y;
- var tz = torque.z * angularFactor.z;
- angularVelo.x += dt * (e[0] * tx + e[1] * ty + e[2] * tz);
- angularVelo.y += dt * (e[3] * tx + e[4] * ty + e[5] * tz);
- angularVelo.z += dt * (e[6] * tx + e[7] * ty + e[8] * tz);
-
- pos.x += velo.x * dt;
- pos.y += velo.y * dt;
- pos.z += velo.z * dt;
- quat.integrate(this.angularVelocity, dt, this.angularFactor, quat);
- if(quatNormalize){
- if(quatNormalizeFast){
- quat.normalizeFast();
- } else {
- quat.normalize();
- }
- }
- this.aabbNeedsUpdate = true;
-
- this.updateInertiaWorld();
- };
- },{"../collision/AABB":18,"../material/Material":41,"../math/Mat3":43,"../math/Quaternion":44,"../math/Vec3":46,"../shapes/Box":53,"../shapes/Shape":59,"../utils/EventTarget":65}],48:[function(require,module,exports){
- var Body = require('./Body');
- var Vec3 = require('../math/Vec3');
- var Quaternion = require('../math/Quaternion');
- var RaycastResult = require('../collision/RaycastResult');
- var Ray = require('../collision/Ray');
- var WheelInfo = require('../objects/WheelInfo');
- module.exports = RaycastVehicle;
- function RaycastVehicle(options){
-
- this.chassisBody = options.chassisBody;
-
- this.wheelInfos = [];
-
- this.sliding = false;
-
- this.world = null;
-
- this.indexRightAxis = typeof(options.indexRightAxis) !== 'undefined' ? options.indexRightAxis : 1;
-
- this.indexForwardAxis = typeof(options.indexForwardAxis) !== 'undefined' ? options.indexForwardAxis : 0;
-
- this.indexUpAxis = typeof(options.indexUpAxis) !== 'undefined' ? options.indexUpAxis : 2;
- }
- var tmpVec1 = new Vec3();
- var tmpVec2 = new Vec3();
- var tmpVec3 = new Vec3();
- var tmpVec4 = new Vec3();
- var tmpVec5 = new Vec3();
- var tmpVec6 = new Vec3();
- var tmpRay = new Ray();
- RaycastVehicle.prototype.addWheel = function(options){
- options = options || {};
- var info = new WheelInfo(options);
- var index = this.wheelInfos.length;
- this.wheelInfos.push(info);
- return index;
- };
- RaycastVehicle.prototype.setSteeringValue = function(value, wheelIndex){
- var wheel = this.wheelInfos[wheelIndex];
- wheel.steering = value;
- };
- var torque = new Vec3();
- RaycastVehicle.prototype.applyEngineForce = function(value, wheelIndex){
- this.wheelInfos[wheelIndex].engineForce = value;
- };
- RaycastVehicle.prototype.setBrake = function(brake, wheelIndex){
- this.wheelInfos[wheelIndex].brake = brake;
- };
- RaycastVehicle.prototype.addToWorld = function(world){
- var constraints = this.constraints;
- world.addBody(this.chassisBody);
- var that = this;
- this.preStepCallback = function(){
- that.updateVehicle(world.dt);
- };
- world.addEventListener('preStep', this.preStepCallback);
- this.world = world;
- };
- RaycastVehicle.prototype.getVehicleAxisWorld = function(axisIndex, result){
- result.set(
- axisIndex === 0 ? 1 : 0,
- axisIndex === 1 ? 1 : 0,
- axisIndex === 2 ? 1 : 0
- );
- this.chassisBody.vectorToWorldFrame(result, result);
- };
- RaycastVehicle.prototype.updateVehicle = function(timeStep){
- var wheelInfos = this.wheelInfos;
- var numWheels = wheelInfos.length;
- var chassisBody = this.chassisBody;
- for (var i = 0; i < numWheels; i++) {
- this.updateWheelTransform(i);
- }
- this.currentVehicleSpeedKmHour = 3.6 * chassisBody.velocity.norm();
- var forwardWorld = new Vec3();
- this.getVehicleAxisWorld(this.indexForwardAxis, forwardWorld);
- if (forwardWorld.dot(chassisBody.velocity) < 0){
- this.currentVehicleSpeedKmHour *= -1;
- }
-
- for (var i = 0; i < numWheels; i++) {
- this.castRay(wheelInfos[i]);
- }
- this.updateSuspension(timeStep);
- var impulse = new Vec3();
- var relpos = new Vec3();
- for (var i = 0; i < numWheels; i++) {
-
- var wheel = wheelInfos[i];
- var suspensionForce = wheel.suspensionForce;
- if (suspensionForce > wheel.maxSuspensionForce) {
- suspensionForce = wheel.maxSuspensionForce;
- }
- wheel.raycastResult.hitNormalWorld.scale(suspensionForce * timeStep, impulse);
- wheel.raycastResult.hitPointWorld.vsub(chassisBody.position, relpos);
- chassisBody.applyImpulse(impulse, relpos);
- }
- this.updateFriction(timeStep);
- var hitNormalWorldScaledWithProj = new Vec3();
- var fwd = new Vec3();
- var vel = new Vec3();
- for (i = 0; i < numWheels; i++) {
- var wheel = wheelInfos[i];
-
-
- chassisBody.getVelocityAtWorldPoint(wheel.chassisConnectionPointWorld, vel);
-
- var m = 1;
- switch(this.indexUpAxis){
- case 1:
- m = -1;
- break;
- }
- if (wheel.isInContact) {
- this.getVehicleAxisWorld(this.indexForwardAxis, fwd);
- var proj = fwd.dot(wheel.raycastResult.hitNormalWorld);
- wheel.raycastResult.hitNormalWorld.scale(proj, hitNormalWorldScaledWithProj);
- fwd.vsub(hitNormalWorldScaledWithProj, fwd);
- var proj2 = fwd.dot(vel);
- wheel.deltaRotation = m * proj2 * timeStep / wheel.radius;
- }
- if((wheel.sliding || !wheel.isInContact) && wheel.engineForce !== 0 && wheel.useCustomSlidingRotationalSpeed){
-
- wheel.deltaRotation = (wheel.engineForce > 0 ? 1 : -1) * wheel.customSlidingRotationalSpeed * timeStep;
- }
-
- if(Math.abs(wheel.brake) > Math.abs(wheel.engineForce)){
- wheel.deltaRotation = 0;
- }
- wheel.rotation += wheel.deltaRotation;
- wheel.deltaRotation *= 0.99;
- }
- };
- RaycastVehicle.prototype.updateSuspension = function(deltaTime) {
- var chassisBody = this.chassisBody;
- var chassisMass = chassisBody.mass;
- var wheelInfos = this.wheelInfos;
- var numWheels = wheelInfos.length;
- for (var w_it = 0; w_it < numWheels; w_it++){
- var wheel = wheelInfos[w_it];
- if (wheel.isInContact){
- var force;
-
- var susp_length = wheel.suspensionRestLength;
- var current_length = wheel.suspensionLength;
- var length_diff = (susp_length - current_length);
- force = wheel.suspensionStiffness * length_diff * wheel.clippedInvContactDotSuspension;
-
- var projected_rel_vel = wheel.suspensionRelativeVelocity;
- var susp_damping;
- if (projected_rel_vel < 0) {
- susp_damping = wheel.dampingCompression;
- } else {
- susp_damping = wheel.dampingRelaxation;
- }
- force -= susp_damping * projected_rel_vel;
- wheel.suspensionForce = force * chassisMass;
- if (wheel.suspensionForce < 0) {
- wheel.suspensionForce = 0;
- }
- } else {
- wheel.suspensionForce = 0;
- }
- }
- };
- RaycastVehicle.prototype.removeFromWorld = function(world){
- var constraints = this.constraints;
- world.remove(this.chassisBody);
- world.removeEventListener('preStep', this.preStepCallback);
- this.world = null;
- };
- var castRay_rayvector = new Vec3();
- var castRay_target = new Vec3();
- RaycastVehicle.prototype.castRay = function(wheel) {
- var rayvector = castRay_rayvector;
- var target = castRay_target;
- this.updateWheelTransformWorld(wheel);
- var chassisBody = this.chassisBody;
- var depth = -1;
- var raylen = wheel.suspensionRestLength + wheel.radius;
- wheel.directionWorld.scale(raylen, rayvector);
- var source = wheel.chassisConnectionPointWorld;
- source.vadd(rayvector, target);
- var raycastResult = wheel.raycastResult;
- var param = 0;
- raycastResult.reset();
-
- var oldState = chassisBody.collisionResponse;
- chassisBody.collisionResponse = false;
-
- this.world.rayTest(source, target, raycastResult);
- chassisBody.collisionResponse = oldState;
- var object = raycastResult.body;
- wheel.raycastResult.groundObject = 0;
- if (object) {
- depth = raycastResult.distance;
- wheel.raycastResult.hitNormalWorld = raycastResult.hitNormalWorld;
- wheel.isInContact = true;
- var hitDistance = raycastResult.distance;
- wheel.suspensionLength = hitDistance - wheel.radius;
-
- var minSuspensionLength = wheel.suspensionRestLength - wheel.maxSuspensionTravel;
- var maxSuspensionLength = wheel.suspensionRestLength + wheel.maxSuspensionTravel;
- if (wheel.suspensionLength < minSuspensionLength) {
- wheel.suspensionLength = minSuspensionLength;
- }
- if (wheel.suspensionLength > maxSuspensionLength) {
- wheel.suspensionLength = maxSuspensionLength;
- wheel.raycastResult.reset();
- }
- var denominator = wheel.raycastResult.hitNormalWorld.dot(wheel.directionWorld);
- var chassis_velocity_at_contactPoint = new Vec3();
- chassisBody.getVelocityAtWorldPoint(wheel.raycastResult.hitPointWorld, chassis_velocity_at_contactPoint);
- var projVel = wheel.raycastResult.hitNormalWorld.dot( chassis_velocity_at_contactPoint );
- if (denominator >= -0.1) {
- wheel.suspensionRelativeVelocity = 0;
- wheel.clippedInvContactDotSuspension = 1 / 0.1;
- } else {
- var inv = -1 / denominator;
- wheel.suspensionRelativeVelocity = projVel * inv;
- wheel.clippedInvContactDotSuspension = inv;
- }
- } else {
-
- wheel.suspensionLength = wheel.suspensionRestLength + 0 * wheel.maxSuspensionTravel;
- wheel.suspensionRelativeVelocity = 0.0;
- wheel.directionWorld.scale(-1, wheel.raycastResult.hitNormalWorld);
- wheel.clippedInvContactDotSuspension = 1.0;
- }
- return depth;
- };
- RaycastVehicle.prototype.updateWheelTransformWorld = function(wheel){
- wheel.isInContact = false;
- var chassisBody = this.chassisBody;
- chassisBody.pointToWorldFrame(wheel.chassisConnectionPointLocal, wheel.chassisConnectionPointWorld);
- chassisBody.vectorToWorldFrame(wheel.directionLocal, wheel.directionWorld);
- chassisBody.vectorToWorldFrame(wheel.axleLocal, wheel.axleWorld);
- };
- RaycastVehicle.prototype.updateWheelTransform = function(wheelIndex){
- var up = tmpVec4;
- var right = tmpVec5;
- var fwd = tmpVec6;
- var wheel = this.wheelInfos[wheelIndex];
- this.updateWheelTransformWorld(wheel);
- wheel.directionLocal.scale(-1, up);
- right.copy(wheel.axleLocal);
- up.cross(right, fwd);
- fwd.normalize();
- right.normalize();
-
- var steering = wheel.steering;
- var steeringOrn = new Quaternion();
- steeringOrn.setFromAxisAngle(up, steering);
- var rotatingOrn = new Quaternion();
- rotatingOrn.setFromAxisAngle(right, wheel.rotation);
-
- var q = wheel.worldTransform.quaternion;
- this.chassisBody.quaternion.mult(steeringOrn, q);
- q.mult(rotatingOrn, q);
- q.normalize();
-
- var p = wheel.worldTransform.position;
- p.copy(wheel.directionWorld);
- p.scale(wheel.suspensionLength, p);
- p.vadd(wheel.chassisConnectionPointWorld, p);
- };
- var directions = [
- new Vec3(1, 0, 0),
- new Vec3(0, 1, 0),
- new Vec3(0, 0, 1)
- ];
- RaycastVehicle.prototype.getWheelTransformWorld = function(wheelIndex) {
- return this.wheelInfos[wheelIndex].worldTransform;
- };
- var updateFriction_surfNormalWS_scaled_proj = new Vec3();
- var updateFriction_axle = [];
- var updateFriction_forwardWS = [];
- var sideFrictionStiffness2 = 1;
- RaycastVehicle.prototype.updateFriction = function(timeStep) {
- var surfNormalWS_scaled_proj = updateFriction_surfNormalWS_scaled_proj;
-
- var wheelInfos = this.wheelInfos;
- var numWheels = wheelInfos.length;
- var chassisBody = this.chassisBody;
- var forwardWS = updateFriction_forwardWS;
- var axle = updateFriction_axle;
- var numWheelsOnGround = 0;
- for (var i = 0; i < numWheels; i++) {
- var wheel = wheelInfos[i];
- var groundObject = wheel.raycastResult.body;
- if (groundObject){
- numWheelsOnGround++;
- }
- wheel.sideImpulse = 0;
- wheel.forwardImpulse = 0;
- if(!forwardWS[i]){
- forwardWS[i] = new Vec3();
- }
- if(!axle[i]){
- axle[i] = new Vec3();
- }
- }
- for (var i = 0; i < numWheels; i++){
- var wheel = wheelInfos[i];
- var groundObject = wheel.raycastResult.body;
- if (groundObject) {
- var axlei = axle[i];
- var wheelTrans = this.getWheelTransformWorld(i);
-
- wheelTrans.vectorToWorldFrame(directions[this.indexRightAxis], axlei);
- var surfNormalWS = wheel.raycastResult.hitNormalWorld;
- var proj = axlei.dot(surfNormalWS);
- surfNormalWS.scale(proj, surfNormalWS_scaled_proj);
- axlei.vsub(surfNormalWS_scaled_proj, axlei);
- axlei.normalize();
- surfNormalWS.cross(axlei, forwardWS[i]);
- forwardWS[i].normalize();
- wheel.sideImpulse = resolveSingleBilateral(
- chassisBody,
- wheel.raycastResult.hitPointWorld,
- groundObject,
- wheel.raycastResult.hitPointWorld,
- axlei
- );
- wheel.sideImpulse *= sideFrictionStiffness2;
- }
- }
- var sideFactor = 1;
- var fwdFactor = 0.5;
- this.sliding = false;
- for (var i = 0; i < numWheels; i++) {
- var wheel = wheelInfos[i];
- var groundObject = wheel.raycastResult.body;
- var rollingFriction = 0;
- wheel.slipInfo = 1;
- if (groundObject) {
- var defaultRollingFrictionImpulse = 0;
- var maxImpulse = wheel.brake ? wheel.brake : defaultRollingFrictionImpulse;
-
-
- rollingFriction = calcRollingFriction(chassisBody, groundObject, wheel.raycastResult.hitPointWorld, forwardWS[i], maxImpulse);
- rollingFriction += wheel.engineForce * timeStep;
-
- var factor = maxImpulse / rollingFriction;
- wheel.slipInfo *= factor;
- }
-
- wheel.forwardImpulse = 0;
- wheel.skidInfo = 1;
- if (groundObject) {
- wheel.skidInfo = 1;
- var maximp = wheel.suspensionForce * timeStep * wheel.frictionSlip;
- var maximpSide = maximp;
- var maximpSquared = maximp * maximpSide;
- wheel.forwardImpulse = rollingFriction;
- var x = wheel.forwardImpulse * fwdFactor;
- var y = wheel.sideImpulse * sideFactor;
- var impulseSquared = x * x + y * y;
- wheel.sliding = false;
- if (impulseSquared > maximpSquared) {
- this.sliding = true;
- wheel.sliding = true;
- var factor = maximp / Math.sqrt(impulseSquared);
- wheel.skidInfo *= factor;
- }
- }
- }
- if (this.sliding) {
- for (var i = 0; i < numWheels; i++) {
- var wheel = wheelInfos[i];
- if (wheel.sideImpulse !== 0) {
- if (wheel.skidInfo < 1){
- wheel.forwardImpulse *= wheel.skidInfo;
- wheel.sideImpulse *= wheel.skidInfo;
- }
- }
- }
- }
-
- for (var i = 0; i < numWheels; i++) {
- var wheel = wheelInfos[i];
- var rel_pos = new Vec3();
- wheel.raycastResult.hitPointWorld.vsub(chassisBody.position, rel_pos);
-
-
- if (wheel.forwardImpulse !== 0) {
- var impulse = new Vec3();
- forwardWS[i].scale(wheel.forwardImpulse, impulse);
- chassisBody.applyImpulse(impulse, rel_pos);
- }
- if (wheel.sideImpulse !== 0){
- var groundObject = wheel.raycastResult.body;
- var rel_pos2 = new Vec3();
- wheel.raycastResult.hitPointWorld.vsub(groundObject.position, rel_pos2);
-
- var sideImp = new Vec3();
- axle[i].scale(wheel.sideImpulse, sideImp);
-
-
- chassisBody.vectorToLocalFrame(rel_pos, rel_pos);
- rel_pos['xyz'[this.indexUpAxis]] *= wheel.rollInfluence;
- chassisBody.vectorToWorldFrame(rel_pos, rel_pos);
- chassisBody.applyImpulse(sideImp, rel_pos);
-
- sideImp.scale(-1, sideImp);
- groundObject.applyImpulse(sideImp, rel_pos2);
- }
- }
- };
- var calcRollingFriction_vel1 = new Vec3();
- var calcRollingFriction_vel2 = new Vec3();
- var calcRollingFriction_vel = new Vec3();
- function calcRollingFriction(body0, body1, frictionPosWorld, frictionDirectionWorld, maxImpulse) {
- var j1 = 0;
- var contactPosWorld = frictionPosWorld;
-
-
- var vel1 = calcRollingFriction_vel1;
- var vel2 = calcRollingFriction_vel2;
- var vel = calcRollingFriction_vel;
-
-
- body0.getVelocityAtWorldPoint(contactPosWorld, vel1);
- body1.getVelocityAtWorldPoint(contactPosWorld, vel2);
- vel1.vsub(vel2, vel);
- var vrel = frictionDirectionWorld.dot(vel);
- var denom0 = computeImpulseDenominator(body0, frictionPosWorld, frictionDirectionWorld);
- var denom1 = computeImpulseDenominator(body1, frictionPosWorld, frictionDirectionWorld);
- var relaxation = 1;
- var jacDiagABInv = relaxation / (denom0 + denom1);
-
- j1 = -vrel * jacDiagABInv;
- if (maxImpulse < j1) {
- j1 = maxImpulse;
- }
- if (j1 < -maxImpulse) {
- j1 = -maxImpulse;
- }
- return j1;
- }
- var computeImpulseDenominator_r0 = new Vec3();
- var computeImpulseDenominator_c0 = new Vec3();
- var computeImpulseDenominator_vec = new Vec3();
- var computeImpulseDenominator_m = new Vec3();
- function computeImpulseDenominator(body, pos, normal) {
- var r0 = computeImpulseDenominator_r0;
- var c0 = computeImpulseDenominator_c0;
- var vec = computeImpulseDenominator_vec;
- var m = computeImpulseDenominator_m;
- pos.vsub(body.position, r0);
- r0.cross(normal, c0);
- body.invInertiaWorld.vmult(c0, m);
- m.cross(r0, vec);
- return body.invMass + normal.dot(vec);
- }
- var resolveSingleBilateral_vel1 = new Vec3();
- var resolveSingleBilateral_vel2 = new Vec3();
- var resolveSingleBilateral_vel = new Vec3();
- function resolveSingleBilateral(body1, pos1, body2, pos2, normal, impulse){
- var normalLenSqr = normal.norm2();
- if (normalLenSqr > 1.1){
- return 0;
- }
-
-
-
-
- var vel1 = resolveSingleBilateral_vel1;
- var vel2 = resolveSingleBilateral_vel2;
- var vel = resolveSingleBilateral_vel;
- body1.getVelocityAtWorldPoint(pos1, vel1);
- body2.getVelocityAtWorldPoint(pos2, vel2);
- vel1.vsub(vel2, vel);
- var rel_vel = normal.dot(vel);
- var contactDamping = 0.2;
- var massTerm = 1 / (body1.invMass + body2.invMass);
- var impulse = - contactDamping * rel_vel * massTerm;
- return impulse;
- }
- },{"../collision/Ray":25,"../collision/RaycastResult":26,"../math/Quaternion":44,"../math/Vec3":46,"../objects/WheelInfo":52,"./Body":47}],49:[function(require,module,exports){
- var Body = require('./Body');
- var Sphere = require('../shapes/Sphere');
- var Box = require('../shapes/Box');
- var Vec3 = require('../math/Vec3');
- var HingeConstraint = require('../constraints/HingeConstraint');
- module.exports = RigidVehicle;
- function RigidVehicle(options){
- this.wheelBodies = [];
-
- this.coordinateSystem = typeof(options.coordinateSystem)==='undefined' ? new Vec3(1, 2, 3) : options.coordinateSystem.clone();
-
- this.chassisBody = options.chassisBody;
- if(!this.chassisBody){
-
- var chassisShape = new Box(new Vec3(5, 2, 0.5));
- this.chassisBody = new Body(1, chassisShape);
- }
-
- this.constraints = [];
- this.wheelAxes = [];
- this.wheelForces = [];
- }
- RigidVehicle.prototype.addWheel = function(options){
- options = options || {};
- var wheelBody = options.body;
- if(!wheelBody){
- wheelBody = new Body(1, new Sphere(1.2));
- }
- this.wheelBodies.push(wheelBody);
- this.wheelForces.push(0);
-
- var zero = new Vec3();
- var position = typeof(options.position) !== 'undefined' ? options.position.clone() : new Vec3();
-
- var worldPosition = new Vec3();
- this.chassisBody.pointToWorldFrame(position, worldPosition);
- wheelBody.position.set(worldPosition.x, worldPosition.y, worldPosition.z);
-
- var axis = typeof(options.axis) !== 'undefined' ? options.axis.clone() : new Vec3(0, 1, 0);
- this.wheelAxes.push(axis);
- var hingeConstraint = new HingeConstraint(this.chassisBody, wheelBody, {
- pivotA: position,
- axisA: axis,
- pivotB: Vec3.ZERO,
- axisB: axis,
- collideConnected: false
- });
- this.constraints.push(hingeConstraint);
- return this.wheelBodies.length - 1;
- };
- RigidVehicle.prototype.setSteeringValue = function(value, wheelIndex){
-
- var axis = this.wheelAxes[wheelIndex];
- var c = Math.cos(value),
- s = Math.sin(value),
- x = axis.x,
- y = axis.y;
- this.constraints[wheelIndex].axisA.set(
- c*x -s*y,
- s*x +c*y,
- 0
- );
- };
- RigidVehicle.prototype.setMotorSpeed = function(value, wheelIndex){
- var hingeConstraint = this.constraints[wheelIndex];
- hingeConstraint.enableMotor();
- hingeConstraint.motorTargetVelocity = value;
- };
- RigidVehicle.prototype.disableMotor = function(wheelIndex){
- var hingeConstraint = this.constraints[wheelIndex];
- hingeConstraint.disableMotor();
- };
- var torque = new Vec3();
- RigidVehicle.prototype.setWheelForce = function(value, wheelIndex){
- this.wheelForces[wheelIndex] = value;
- };
- RigidVehicle.prototype.applyWheelForce = function(value, wheelIndex){
- var axis = this.wheelAxes[wheelIndex];
- var wheelBody = this.wheelBodies[wheelIndex];
- var bodyTorque = wheelBody.torque;
- axis.scale(value, torque);
- wheelBody.vectorToWorldFrame(torque, torque);
- bodyTorque.vadd(torque, bodyTorque);
- };
- RigidVehicle.prototype.addToWorld = function(world){
- var constraints = this.constraints;
- var bodies = this.wheelBodies.concat([this.chassisBody]);
- for (var i = 0; i < bodies.length; i++) {
- world.addBody(bodies[i]);
- }
- for (var i = 0; i < constraints.length; i++) {
- world.addConstraint(constraints[i]);
- }
- world.addEventListener('preStep', this._update.bind(this));
- };
- RigidVehicle.prototype._update = function(){
- var wheelForces = this.wheelForces;
- for (var i = 0; i < wheelForces.length; i++) {
- this.applyWheelForce(wheelForces[i], i);
- }
- };
- RigidVehicle.prototype.removeFromWorld = function(world){
- var constraints = this.constraints;
- var bodies = this.wheelBodies.concat([this.chassisBody]);
- for (var i = 0; i < bodies.length; i++) {
- world.remove(bodies[i]);
- }
- for (var i = 0; i < constraints.length; i++) {
- world.removeConstraint(constraints[i]);
- }
- };
- var worldAxis = new Vec3();
- RigidVehicle.prototype.getWheelSpeed = function(wheelIndex){
- var axis = this.wheelAxes[wheelIndex];
- var wheelBody = this.wheelBodies[wheelIndex];
- var w = wheelBody.angularVelocity;
- this.chassisBody.vectorToWorldFrame(axis, worldAxis);
- return w.dot(worldAxis);
- };
- },{"../constraints/HingeConstraint":31,"../math/Vec3":46,"../shapes/Box":53,"../shapes/Sphere":60,"./Body":47}],50:[function(require,module,exports){
- module.exports = SPHSystem;
- var Shape = require('../shapes/Shape');
- var Vec3 = require('../math/Vec3');
- var Quaternion = require('../math/Quaternion');
- var Particle = require('../shapes/Particle');
- var Body = require('../objects/Body');
- var Material = require('../material/Material');
- function SPHSystem(){
- this.particles = [];
-
-
- this.density = 1;
-
-
- this.smoothingRadius = 1;
- this.speedOfSound = 1;
-
-
- this.viscosity = 0.01;
- this.eps = 0.000001;
-
- this.pressures = [];
- this.densities = [];
- this.neighbors = [];
- }
- SPHSystem.prototype.add = function(particle){
- this.particles.push(particle);
- if(this.neighbors.length < this.particles.length){
- this.neighbors.push([]);
- }
- };
- SPHSystem.prototype.remove = function(particle){
- var idx = this.particles.indexOf(particle);
- if(idx !== -1){
- this.particles.splice(idx,1);
- if(this.neighbors.length > this.particles.length){
- this.neighbors.pop();
- }
- }
- };
- var SPHSystem_getNeighbors_dist = new Vec3();
- SPHSystem.prototype.getNeighbors = function(particle,neighbors){
- var N = this.particles.length,
- id = particle.id,
- R2 = this.smoothingRadius * this.smoothingRadius,
- dist = SPHSystem_getNeighbors_dist;
- for(var i=0; i!==N; i++){
- var p = this.particles[i];
- p.position.vsub(particle.position,dist);
- if(id!==p.id && dist.norm2() < R2){
- neighbors.push(p);
- }
- }
- };
- var SPHSystem_update_dist = new Vec3(),
- SPHSystem_update_a_pressure = new Vec3(),
- SPHSystem_update_a_visc = new Vec3(),
- SPHSystem_update_gradW = new Vec3(),
- SPHSystem_update_r_vec = new Vec3(),
- SPHSystem_update_u = new Vec3();
- SPHSystem.prototype.update = function(){
- var N = this.particles.length,
- dist = SPHSystem_update_dist,
- cs = this.speedOfSound,
- eps = this.eps;
- for(var i=0; i!==N; i++){
- var p = this.particles[i];
- var neighbors = this.neighbors[i];
-
- neighbors.length = 0;
- this.getNeighbors(p,neighbors);
- neighbors.push(this.particles[i]);
- var numNeighbors = neighbors.length;
-
- var sum = 0.0;
- for(var j=0; j!==numNeighbors; j++){
-
- p.position.vsub(neighbors[j].position, dist);
- var len = dist.norm();
- var weight = this.w(len);
- sum += neighbors[j].mass * weight;
- }
-
- this.densities[i] = sum;
- this.pressures[i] = cs * cs * (this.densities[i] - this.density);
- }
-
-
- var a_pressure= SPHSystem_update_a_pressure;
- var a_visc = SPHSystem_update_a_visc;
- var gradW = SPHSystem_update_gradW;
- var r_vec = SPHSystem_update_r_vec;
- var u = SPHSystem_update_u;
- for(var i=0; i!==N; i++){
- var particle = this.particles[i];
- a_pressure.set(0,0,0);
- a_visc.set(0,0,0);
-
- var Pij;
- var nabla;
- var Vij;
-
- var neighbors = this.neighbors[i];
- var numNeighbors = neighbors.length;
-
- for(var j=0; j!==numNeighbors; j++){
- var neighbor = neighbors[j];
-
-
- particle.position.vsub(neighbor.position,r_vec);
- var r = r_vec.norm();
-
- Pij = -neighbor.mass * (this.pressures[i] / (this.densities[i]*this.densities[i] + eps) + this.pressures[j] / (this.densities[j]*this.densities[j] + eps));
- this.gradw(r_vec, gradW);
-
- gradW.mult(Pij , gradW);
- a_pressure.vadd(gradW, a_pressure);
-
- neighbor.velocity.vsub(particle.velocity, u);
- u.mult( 1.0 / (0.0001+this.densities[i] * this.densities[j]) * this.viscosity * neighbor.mass , u );
- nabla = this.nablaw(r);
- u.mult(nabla,u);
-
- a_visc.vadd( u, a_visc );
- }
-
- a_visc.mult(particle.mass, a_visc);
- a_pressure.mult(particle.mass, a_pressure);
-
- particle.force.vadd(a_visc, particle.force);
- particle.force.vadd(a_pressure, particle.force);
- }
- };
- SPHSystem.prototype.w = function(r){
-
- var h = this.smoothingRadius;
- return 315.0/(64.0*Math.PI*Math.pow(h,9)) * Math.pow(h*h-r*r,3);
- };
- SPHSystem.prototype.gradw = function(rVec,resultVec){
- var r = rVec.norm(),
- h = this.smoothingRadius;
- rVec.mult(945.0/(32.0*Math.PI*Math.pow(h,9)) * Math.pow((h*h-r*r),2) , resultVec);
- };
- SPHSystem.prototype.nablaw = function(r){
- var h = this.smoothingRadius;
- var nabla = 945.0/(32.0*Math.PI*Math.pow(h,9)) * (h*h-r*r)*(7*r*r - 3*h*h);
- return nabla;
- };
- },{"../material/Material":41,"../math/Quaternion":44,"../math/Vec3":46,"../objects/Body":47,"../shapes/Particle":57,"../shapes/Shape":59}],51:[function(require,module,exports){
- var Vec3 = require('../math/Vec3');
- module.exports = Spring;
- function Spring(bodyA,bodyB,options){
- options = options || {};
-
- this.restLength = typeof(options.restLength) === "number" ? options.restLength : 1;
-
- this.stiffness = options.stiffness || 100;
-
- this.damping = options.damping || 1;
-
- this.bodyA = bodyA;
-
- this.bodyB = bodyB;
-
- this.localAnchorA = new Vec3();
-
- this.localAnchorB = new Vec3();
- if(options.localAnchorA){
- this.localAnchorA.copy(options.localAnchorA);
- }
- if(options.localAnchorB){
- this.localAnchorB.copy(options.localAnchorB);
- }
- if(options.worldAnchorA){
- this.setWorldAnchorA(options.worldAnchorA);
- }
- if(options.worldAnchorB){
- this.setWorldAnchorB(options.worldAnchorB);
- }
- }
- Spring.prototype.setWorldAnchorA = function(worldAnchorA){
- this.bodyA.pointToLocalFrame(worldAnchorA,this.localAnchorA);
- };
- Spring.prototype.setWorldAnchorB = function(worldAnchorB){
- this.bodyB.pointToLocalFrame(worldAnchorB,this.localAnchorB);
- };
- Spring.prototype.getWorldAnchorA = function(result){
- this.bodyA.pointToWorldFrame(this.localAnchorA,result);
- };
- Spring.prototype.getWorldAnchorB = function(result){
- this.bodyB.pointToWorldFrame(this.localAnchorB,result);
- };
- var applyForce_r = new Vec3(),
- applyForce_r_unit = new Vec3(),
- applyForce_u = new Vec3(),
- applyForce_f = new Vec3(),
- applyForce_worldAnchorA = new Vec3(),
- applyForce_worldAnchorB = new Vec3(),
- applyForce_ri = new Vec3(),
- applyForce_rj = new Vec3(),
- applyForce_ri_x_f = new Vec3(),
- applyForce_rj_x_f = new Vec3(),
- applyForce_tmp = new Vec3();
- Spring.prototype.applyForce = function(){
- var k = this.stiffness,
- d = this.damping,
- l = this.restLength,
- bodyA = this.bodyA,
- bodyB = this.bodyB,
- r = applyForce_r,
- r_unit = applyForce_r_unit,
- u = applyForce_u,
- f = applyForce_f,
- tmp = applyForce_tmp;
- var worldAnchorA = applyForce_worldAnchorA,
- worldAnchorB = applyForce_worldAnchorB,
- ri = applyForce_ri,
- rj = applyForce_rj,
- ri_x_f = applyForce_ri_x_f,
- rj_x_f = applyForce_rj_x_f;
-
- this.getWorldAnchorA(worldAnchorA);
- this.getWorldAnchorB(worldAnchorB);
-
- worldAnchorA.vsub(bodyA.position,ri);
- worldAnchorB.vsub(bodyB.position,rj);
-
- worldAnchorB.vsub(worldAnchorA,r);
- var rlen = r.norm();
- r_unit.copy(r);
- r_unit.normalize();
-
- bodyB.velocity.vsub(bodyA.velocity,u);
-
- bodyB.angularVelocity.cross(rj,tmp);
- u.vadd(tmp,u);
- bodyA.angularVelocity.cross(ri,tmp);
- u.vsub(tmp,u);
-
- r_unit.mult(-k*(rlen-l) - d*u.dot(r_unit), f);
-
- bodyA.force.vsub(f,bodyA.force);
- bodyB.force.vadd(f,bodyB.force);
-
- ri.cross(f,ri_x_f);
- rj.cross(f,rj_x_f);
- bodyA.torque.vsub(ri_x_f,bodyA.torque);
- bodyB.torque.vadd(rj_x_f,bodyB.torque);
- };
- },{"../math/Vec3":46}],52:[function(require,module,exports){
- var Vec3 = require('../math/Vec3');
- var Transform = require('../math/Transform');
- var RaycastResult = require('../collision/RaycastResult');
- var Utils = require('../utils/Utils');
- module.exports = WheelInfo;
- function WheelInfo(options){
- options = Utils.defaults(options, {
- chassisConnectionPointLocal: new Vec3(),
- chassisConnectionPointWorld: new Vec3(),
- directionLocal: new Vec3(),
- directionWorld: new Vec3(),
- axleLocal: new Vec3(),
- axleWorld: new Vec3(),
- suspensionRestLength: 1,
- suspensionMaxLength: 2,
- radius: 1,
- suspensionStiffness: 100,
- dampingCompression: 10,
- dampingRelaxation: 10,
- frictionSlip: 10000,
- steering: 0,
- rotation: 0,
- deltaRotation: 0,
- rollInfluence: 0.01,
- maxSuspensionForce: Number.MAX_VALUE,
- isFrontWheel: true,
- clippedInvContactDotSuspension: 1,
- suspensionRelativeVelocity: 0,
- suspensionForce: 0,
- skidInfo: 0,
- suspensionLength: 0,
- maxSuspensionTravel: 1,
- useCustomSlidingRotationalSpeed: false,
- customSlidingRotationalSpeed: -0.1
- });
-
- this.maxSuspensionTravel = options.maxSuspensionTravel;
-
- this.customSlidingRotationalSpeed = options.customSlidingRotationalSpeed;
-
- this.useCustomSlidingRotationalSpeed = options.useCustomSlidingRotationalSpeed;
-
- this.sliding = false;
-
- this.chassisConnectionPointLocal = options.chassisConnectionPointLocal.clone();
-
- this.chassisConnectionPointWorld = options.chassisConnectionPointWorld.clone();
-
- this.directionLocal = options.directionLocal.clone();
-
- this.directionWorld = options.directionWorld.clone();
-
- this.axleLocal = options.axleLocal.clone();
-
- this.axleWorld = options.axleWorld.clone();
-
- this.suspensionRestLength = options.suspensionRestLength;
-
- this.suspensionMaxLength = options.suspensionMaxLength;
-
- this.radius = options.radius;
-
- this.suspensionStiffness = options.suspensionStiffness;
-
- this.dampingCompression = options.dampingCompression;
-
- this.dampingRelaxation = options.dampingRelaxation;
-
- this.frictionSlip = options.frictionSlip;
-
- this.steering = 0;
-
- this.rotation = 0;
-
- this.deltaRotation = 0;
-
- this.rollInfluence = options.rollInfluence;
-
- this.maxSuspensionForce = options.maxSuspensionForce;
-
- this.engineForce = 0;
-
- this.brake = 0;
-
- this.isFrontWheel = options.isFrontWheel;
-
- this.clippedInvContactDotSuspension = 1;
-
- this.suspensionRelativeVelocity = 0;
-
- this.suspensionForce = 0;
-
- this.skidInfo = 0;
-
- this.suspensionLength = 0;
-
- this.sideImpulse = 0;
-
- this.forwardImpulse = 0;
-
- this.raycastResult = new RaycastResult();
-
- this.worldTransform = new Transform();
-
- this.isInContact = false;
- }
- var chassis_velocity_at_contactPoint = new Vec3();
- var relpos = new Vec3();
- var chassis_velocity_at_contactPoint = new Vec3();
- WheelInfo.prototype.updateWheel = function(chassis){
- var raycastResult = this.raycastResult;
- if (this.isInContact){
- var project= raycastResult.hitNormalWorld.dot(raycastResult.directionWorld);
- raycastResult.hitPointWorld.vsub(chassis.position, relpos);
- chassis.getVelocityAtWorldPoint(relpos, chassis_velocity_at_contactPoint);
- var projVel = raycastResult.hitNormalWorld.dot( chassis_velocity_at_contactPoint );
- if (project >= -0.1) {
- this.suspensionRelativeVelocity = 0.0;
- this.clippedInvContactDotSuspension = 1.0 / 0.1;
- } else {
- var inv = -1 / project;
- this.suspensionRelativeVelocity = projVel * inv;
- this.clippedInvContactDotSuspension = inv;
- }
- } else {
-
- raycastResult.suspensionLength = this.suspensionRestLength;
- this.suspensionRelativeVelocity = 0.0;
- raycastResult.directionWorld.scale(-1, raycastResult.hitNormalWorld);
- this.clippedInvContactDotSuspension = 1.0;
- }
- };
- },{"../collision/RaycastResult":26,"../math/Transform":45,"../math/Vec3":46,"../utils/Utils":69}],53:[function(require,module,exports){
- module.exports = Box;
- var Shape = require('./Shape');
- var Vec3 = require('../math/Vec3');
- var ConvexPolyhedron = require('./ConvexPolyhedron');
- function Box(halfExtents){
- Shape.call(this);
- this.type = Shape.types.BOX;
-
- this.halfExtents = halfExtents;
-
- this.convexPolyhedronRepresentation = null;
- this.updateConvexPolyhedronRepresentation();
- this.updateBoundingSphereRadius();
- }
- Box.prototype = new Shape();
- Box.prototype.constructor = Box;
- Box.prototype.updateConvexPolyhedronRepresentation = function(){
- var sx = this.halfExtents.x;
- var sy = this.halfExtents.y;
- var sz = this.halfExtents.z;
- var V = Vec3;
- var vertices = [
- new V(-sx,-sy,-sz),
- new V( sx,-sy,-sz),
- new V( sx, sy,-sz),
- new V(-sx, sy,-sz),
- new V(-sx,-sy, sz),
- new V( sx,-sy, sz),
- new V( sx, sy, sz),
- new V(-sx, sy, sz)
- ];
- var indices = [
- [3,2,1,0],
- [4,5,6,7],
- [5,4,0,1],
- [2,3,7,6],
- [0,4,7,3],
- [1,2,6,5],
- ];
- var axes = [
- new V(0, 0, 1),
- new V(0, 1, 0),
- new V(1, 0, 0)
- ];
- var h = new ConvexPolyhedron(vertices, indices);
- this.convexPolyhedronRepresentation = h;
- h.material = this.material;
- };
- Box.prototype.calculateLocalInertia = function(mass,target){
- target = target || new Vec3();
- Box.calculateInertia(this.halfExtents, mass, target);
- return target;
- };
- Box.calculateInertia = function(halfExtents,mass,target){
- var e = halfExtents;
- target.x = 1.0 / 12.0 * mass * ( 2*e.y*2*e.y + 2*e.z*2*e.z );
- target.y = 1.0 / 12.0 * mass * ( 2*e.x*2*e.x + 2*e.z*2*e.z );
- target.z = 1.0 / 12.0 * mass * ( 2*e.y*2*e.y + 2*e.x*2*e.x );
- };
- Box.prototype.getSideNormals = function(sixTargetVectors,quat){
- var sides = sixTargetVectors;
- var ex = this.halfExtents;
- sides[0].set( ex.x, 0, 0);
- sides[1].set( 0, ex.y, 0);
- sides[2].set( 0, 0, ex.z);
- sides[3].set( -ex.x, 0, 0);
- sides[4].set( 0, -ex.y, 0);
- sides[5].set( 0, 0, -ex.z);
- if(quat!==undefined){
- for(var i=0; i!==sides.length; i++){
- quat.vmult(sides[i],sides[i]);
- }
- }
- return sides;
- };
- Box.prototype.volume = function(){
- return 8.0 * this.halfExtents.x * this.halfExtents.y * this.halfExtents.z;
- };
- Box.prototype.updateBoundingSphereRadius = function(){
- this.boundingSphereRadius = this.halfExtents.norm();
- };
- var worldCornerTempPos = new Vec3();
- var worldCornerTempNeg = new Vec3();
- Box.prototype.forEachWorldCorner = function(pos,quat,callback){
- var e = this.halfExtents;
- var corners = [[ e.x, e.y, e.z],
- [ -e.x, e.y, e.z],
- [ -e.x, -e.y, e.z],
- [ -e.x, -e.y, -e.z],
- [ e.x, -e.y, -e.z],
- [ e.x, e.y, -e.z],
- [ -e.x, e.y, -e.z],
- [ e.x, -e.y, e.z]];
- for(var i=0; i<corners.length; i++){
- worldCornerTempPos.set(corners[i][0],corners[i][1],corners[i][2]);
- quat.vmult(worldCornerTempPos,worldCornerTempPos);
- pos.vadd(worldCornerTempPos,worldCornerTempPos);
- callback(worldCornerTempPos.x,
- worldCornerTempPos.y,
- worldCornerTempPos.z);
- }
- };
- var worldCornersTemp = [
- new Vec3(),
- new Vec3(),
- new Vec3(),
- new Vec3(),
- new Vec3(),
- new Vec3(),
- new Vec3(),
- new Vec3()
- ];
- Box.prototype.calculateWorldAABB = function(pos,quat,min,max){
- var e = this.halfExtents;
- worldCornersTemp[0].set(e.x, e.y, e.z);
- worldCornersTemp[1].set(-e.x, e.y, e.z);
- worldCornersTemp[2].set(-e.x, -e.y, e.z);
- worldCornersTemp[3].set(-e.x, -e.y, -e.z);
- worldCornersTemp[4].set(e.x, -e.y, -e.z);
- worldCornersTemp[5].set(e.x, e.y, -e.z);
- worldCornersTemp[6].set(-e.x, e.y, -e.z);
- worldCornersTemp[7].set(e.x, -e.y, e.z);
- var wc = worldCornersTemp[0];
- quat.vmult(wc, wc);
- pos.vadd(wc, wc);
- max.copy(wc);
- min.copy(wc);
- for(var i=1; i<8; i++){
- var wc = worldCornersTemp[i];
- quat.vmult(wc, wc);
- pos.vadd(wc, wc);
- var x = wc.x;
- var y = wc.y;
- var z = wc.z;
- if(x > max.x){
- max.x = x;
- }
- if(y > max.y){
- max.y = y;
- }
- if(z > max.z){
- max.z = z;
- }
- if(x < min.x){
- min.x = x;
- }
- if(y < min.y){
- min.y = y;
- }
- if(z < min.z){
- min.z = z;
- }
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- };
- },{"../math/Vec3":46,"./ConvexPolyhedron":54,"./Shape":59}],54:[function(require,module,exports){
- module.exports = ConvexPolyhedron;
- var Shape = require('./Shape');
- var Vec3 = require('../math/Vec3');
- var Quaternion = require('../math/Quaternion');
- var Transform = require('../math/Transform');
- function ConvexPolyhedron(points, faces, uniqueAxes) {
- var that = this;
- Shape.call(this);
- this.type = Shape.types.CONVEXPOLYHEDRON;
-
- this.vertices = points||[];
- this.worldVertices = [];
- this.worldVerticesNeedsUpdate = true;
-
- this.faces = faces||[];
-
- this.faceNormals = [];
- this.computeNormals();
- this.worldFaceNormalsNeedsUpdate = true;
- this.worldFaceNormals = [];
-
- this.uniqueEdges = [];
-
- this.uniqueAxes = uniqueAxes ? uniqueAxes.slice() : null;
- this.computeEdges();
- this.updateBoundingSphereRadius();
- }
- ConvexPolyhedron.prototype = new Shape();
- ConvexPolyhedron.prototype.constructor = ConvexPolyhedron;
- var computeEdges_tmpEdge = new Vec3();
- ConvexPolyhedron.prototype.computeEdges = function(){
- var faces = this.faces;
- var vertices = this.vertices;
- var nv = vertices.length;
- var edges = this.uniqueEdges;
- edges.length = 0;
- var edge = computeEdges_tmpEdge;
- for(var i=0; i !== faces.length; i++){
- var face = faces[i];
- var numVertices = face.length;
- for(var j = 0; j !== numVertices; j++){
- var k = ( j+1 ) % numVertices;
- vertices[face[j]].vsub(vertices[face[k]], edge);
- edge.normalize();
- var found = false;
- for(var p=0; p !== edges.length; p++){
- if (edges[p].almostEquals(edge) || edges[p].almostEquals(edge)){
- found = true;
- break;
- }
- }
- if (!found){
- edges.push(edge.clone());
- }
- }
- }
- };
- ConvexPolyhedron.prototype.computeNormals = function(){
- this.faceNormals.length = this.faces.length;
-
- for(var i=0; i<this.faces.length; i++){
-
- for(var j=0; j<this.faces[i].length; j++){
- if(!this.vertices[this.faces[i][j]]){
- throw new Error("Vertex "+this.faces[i][j]+" not found!");
- }
- }
- var n = this.faceNormals[i] || new Vec3();
- this.getFaceNormal(i,n);
- n.negate(n);
- this.faceNormals[i] = n;
- var vertex = this.vertices[this.faces[i][0]];
- if(n.dot(vertex) < 0){
- console.error(".faceNormals[" + i + "] = Vec3("+n.toString()+") looks like it points into the shape? The vertices follow. Make sure they are ordered CCW around the normal, using the right hand rule.");
- for(var j=0; j<this.faces[i].length; j++){
- console.warn(".vertices["+this.faces[i][j]+"] = Vec3("+this.vertices[this.faces[i][j]].toString()+")");
- }
- }
- }
- };
- var cb = new Vec3();
- var ab = new Vec3();
- ConvexPolyhedron.computeNormal = function ( va, vb, vc, target ) {
- vb.vsub(va,ab);
- vc.vsub(vb,cb);
- cb.cross(ab,target);
- if ( !target.isZero() ) {
- target.normalize();
- }
- };
- ConvexPolyhedron.prototype.getFaceNormal = function(i,target){
- var f = this.faces[i];
- var va = this.vertices[f[0]];
- var vb = this.vertices[f[1]];
- var vc = this.vertices[f[2]];
- return ConvexPolyhedron.computeNormal(va,vb,vc,target);
- };
- var cah_WorldNormal = new Vec3();
- ConvexPolyhedron.prototype.clipAgainstHull = function(posA,quatA,hullB,posB,quatB,separatingNormal,minDist,maxDist,result){
- var WorldNormal = cah_WorldNormal;
- var hullA = this;
- var curMaxDist = maxDist;
- var closestFaceB = -1;
- var dmax = -Number.MAX_VALUE;
- for(var face=0; face < hullB.faces.length; face++){
- WorldNormal.copy(hullB.faceNormals[face]);
- quatB.vmult(WorldNormal,WorldNormal);
-
- var d = WorldNormal.dot(separatingNormal);
- if (d > dmax){
- dmax = d;
- closestFaceB = face;
- }
- }
- var worldVertsB1 = [];
- var polyB = hullB.faces[closestFaceB];
- var numVertices = polyB.length;
- for(var e0=0; e0<numVertices; e0++){
- var b = hullB.vertices[polyB[e0]];
- var worldb = new Vec3();
- worldb.copy(b);
- quatB.vmult(worldb,worldb);
- posB.vadd(worldb,worldb);
- worldVertsB1.push(worldb);
- }
- if (closestFaceB>=0){
- this.clipFaceAgainstHull(separatingNormal,
- posA,
- quatA,
- worldVertsB1,
- minDist,
- maxDist,
- result);
- }
- };
- var fsa_faceANormalWS3 = new Vec3(),
- fsa_Worldnormal1 = new Vec3(),
- fsa_deltaC = new Vec3(),
- fsa_worldEdge0 = new Vec3(),
- fsa_worldEdge1 = new Vec3(),
- fsa_Cross = new Vec3();
- ConvexPolyhedron.prototype.findSeparatingAxis = function(hullB,posA,quatA,posB,quatB,target, faceListA, faceListB){
- var faceANormalWS3 = fsa_faceANormalWS3,
- Worldnormal1 = fsa_Worldnormal1,
- deltaC = fsa_deltaC,
- worldEdge0 = fsa_worldEdge0,
- worldEdge1 = fsa_worldEdge1,
- Cross = fsa_Cross;
- var dmin = Number.MAX_VALUE;
- var hullA = this;
- var curPlaneTests=0;
- if(!hullA.uniqueAxes){
- var numFacesA = faceListA ? faceListA.length : hullA.faces.length;
-
- for(var i=0; i<numFacesA; i++){
- var fi = faceListA ? faceListA[i] : i;
-
- faceANormalWS3.copy(hullA.faceNormals[fi]);
- quatA.vmult(faceANormalWS3,faceANormalWS3);
- var d = hullA.testSepAxis(faceANormalWS3, hullB, posA, quatA, posB, quatB);
- if(d===false){
- return false;
- }
- if(d<dmin){
- dmin = d;
- target.copy(faceANormalWS3);
- }
- }
- } else {
-
- for(var i = 0; i !== hullA.uniqueAxes.length; i++){
-
- quatA.vmult(hullA.uniqueAxes[i],faceANormalWS3);
- var d = hullA.testSepAxis(faceANormalWS3, hullB, posA, quatA, posB, quatB);
- if(d===false){
- return false;
- }
- if(d<dmin){
- dmin = d;
- target.copy(faceANormalWS3);
- }
- }
- }
- if(!hullB.uniqueAxes){
-
- var numFacesB = faceListB ? faceListB.length : hullB.faces.length;
- for(var i=0;i<numFacesB;i++){
- var fi = faceListB ? faceListB[i] : i;
- Worldnormal1.copy(hullB.faceNormals[fi]);
- quatB.vmult(Worldnormal1,Worldnormal1);
- curPlaneTests++;
- var d = hullA.testSepAxis(Worldnormal1, hullB,posA,quatA,posB,quatB);
- if(d===false){
- return false;
- }
- if(d<dmin){
- dmin = d;
- target.copy(Worldnormal1);
- }
- }
- } else {
-
- for(var i = 0; i !== hullB.uniqueAxes.length; i++){
- quatB.vmult(hullB.uniqueAxes[i],Worldnormal1);
- curPlaneTests++;
- var d = hullA.testSepAxis(Worldnormal1, hullB,posA,quatA,posB,quatB);
- if(d===false){
- return false;
- }
- if(d<dmin){
- dmin = d;
- target.copy(Worldnormal1);
- }
- }
- }
-
- for(var e0=0; e0 !== hullA.uniqueEdges.length; e0++){
-
- quatA.vmult(hullA.uniqueEdges[e0],worldEdge0);
- for(var e1=0; e1 !== hullB.uniqueEdges.length; e1++){
-
- quatB.vmult(hullB.uniqueEdges[e1], worldEdge1);
- worldEdge0.cross(worldEdge1,Cross);
- if(!Cross.almostZero()){
- Cross.normalize();
- var dist = hullA.testSepAxis(Cross, hullB, posA, quatA, posB, quatB);
- if(dist === false){
- return false;
- }
- if(dist < dmin){
- dmin = dist;
- target.copy(Cross);
- }
- }
- }
- }
- posB.vsub(posA,deltaC);
- if((deltaC.dot(target))>0.0){
- target.negate(target);
- }
- return true;
- };
- var maxminA=[], maxminB=[];
- ConvexPolyhedron.prototype.testSepAxis = function(axis, hullB, posA, quatA, posB, quatB){
- var hullA=this;
- ConvexPolyhedron.project(hullA, axis, posA, quatA, maxminA);
- ConvexPolyhedron.project(hullB, axis, posB, quatB, maxminB);
- var maxA = maxminA[0];
- var minA = maxminA[1];
- var maxB = maxminB[0];
- var minB = maxminB[1];
- if(maxA<minB || maxB<minA){
- return false;
- }
- var d0 = maxA - minB;
- var d1 = maxB - minA;
- var depth = d0<d1 ? d0:d1;
- return depth;
- };
- var cli_aabbmin = new Vec3(),
- cli_aabbmax = new Vec3();
- ConvexPolyhedron.prototype.calculateLocalInertia = function(mass,target){
-
-
- this.computeLocalAABB(cli_aabbmin,cli_aabbmax);
- var x = cli_aabbmax.x - cli_aabbmin.x,
- y = cli_aabbmax.y - cli_aabbmin.y,
- z = cli_aabbmax.z - cli_aabbmin.z;
- target.x = 1.0 / 12.0 * mass * ( 2*y*2*y + 2*z*2*z );
- target.y = 1.0 / 12.0 * mass * ( 2*x*2*x + 2*z*2*z );
- target.z = 1.0 / 12.0 * mass * ( 2*y*2*y + 2*x*2*x );
- };
- ConvexPolyhedron.prototype.getPlaneConstantOfFace = function(face_i){
- var f = this.faces[face_i];
- var n = this.faceNormals[face_i];
- var v = this.vertices[f[0]];
- var c = -n.dot(v);
- return c;
- };
- var cfah_faceANormalWS = new Vec3(),
- cfah_edge0 = new Vec3(),
- cfah_WorldEdge0 = new Vec3(),
- cfah_worldPlaneAnormal1 = new Vec3(),
- cfah_planeNormalWS1 = new Vec3(),
- cfah_worldA1 = new Vec3(),
- cfah_localPlaneNormal = new Vec3(),
- cfah_planeNormalWS = new Vec3();
- ConvexPolyhedron.prototype.clipFaceAgainstHull = function(separatingNormal, posA, quatA, worldVertsB1, minDist, maxDist,result){
- var faceANormalWS = cfah_faceANormalWS,
- edge0 = cfah_edge0,
- WorldEdge0 = cfah_WorldEdge0,
- worldPlaneAnormal1 = cfah_worldPlaneAnormal1,
- planeNormalWS1 = cfah_planeNormalWS1,
- worldA1 = cfah_worldA1,
- localPlaneNormal = cfah_localPlaneNormal,
- planeNormalWS = cfah_planeNormalWS;
- var hullA = this;
- var worldVertsB2 = [];
- var pVtxIn = worldVertsB1;
- var pVtxOut = worldVertsB2;
-
- var closestFaceA = -1;
- var dmin = Number.MAX_VALUE;
- for(var face=0; face<hullA.faces.length; face++){
- faceANormalWS.copy(hullA.faceNormals[face]);
- quatA.vmult(faceANormalWS,faceANormalWS);
-
- var d = faceANormalWS.dot(separatingNormal);
- if (d < dmin){
- dmin = d;
- closestFaceA = face;
- }
- }
- if (closestFaceA < 0){
-
- return;
- }
-
-
- var polyA = hullA.faces[closestFaceA];
- polyA.connectedFaces = [];
- for(var i=0; i<hullA.faces.length; i++){
- for(var j=0; j<hullA.faces[i].length; j++){
- if(polyA.indexOf(hullA.faces[i][j])!==-1 && i!==closestFaceA && polyA.connectedFaces.indexOf(i)===-1 ){
- polyA.connectedFaces.push(i);
- }
- }
- }
-
- var numContacts = pVtxIn.length;
- var numVerticesA = polyA.length;
- var res = [];
- for(var e0=0; e0<numVerticesA; e0++){
- var a = hullA.vertices[polyA[e0]];
- var b = hullA.vertices[polyA[(e0+1)%numVerticesA]];
- a.vsub(b,edge0);
- WorldEdge0.copy(edge0);
- quatA.vmult(WorldEdge0,WorldEdge0);
- posA.vadd(WorldEdge0,WorldEdge0);
- worldPlaneAnormal1.copy(this.faceNormals[closestFaceA]);
- quatA.vmult(worldPlaneAnormal1,worldPlaneAnormal1);
- posA.vadd(worldPlaneAnormal1,worldPlaneAnormal1);
- WorldEdge0.cross(worldPlaneAnormal1,planeNormalWS1);
- planeNormalWS1.negate(planeNormalWS1);
- worldA1.copy(a);
- quatA.vmult(worldA1,worldA1);
- posA.vadd(worldA1,worldA1);
- var planeEqWS1 = -worldA1.dot(planeNormalWS1);
- var planeEqWS;
- if(true){
- var otherFace = polyA.connectedFaces[e0];
- localPlaneNormal.copy(this.faceNormals[otherFace]);
- var localPlaneEq = this.getPlaneConstantOfFace(otherFace);
- planeNormalWS.copy(localPlaneNormal);
- quatA.vmult(planeNormalWS,planeNormalWS);
-
- var planeEqWS = localPlaneEq - planeNormalWS.dot(posA);
- } else {
- planeNormalWS.copy(planeNormalWS1);
- planeEqWS = planeEqWS1;
- }
-
- this.clipFaceAgainstPlane(pVtxIn, pVtxOut, planeNormalWS, planeEqWS);
-
- while(pVtxIn.length){
- pVtxIn.shift();
- }
- while(pVtxOut.length){
- pVtxIn.push(pVtxOut.shift());
- }
- }
-
-
- localPlaneNormal.copy(this.faceNormals[closestFaceA]);
- var localPlaneEq = this.getPlaneConstantOfFace(closestFaceA);
- planeNormalWS.copy(localPlaneNormal);
- quatA.vmult(planeNormalWS,planeNormalWS);
- var planeEqWS = localPlaneEq - planeNormalWS.dot(posA);
- for (var i=0; i<pVtxIn.length; i++){
- var depth = planeNormalWS.dot(pVtxIn[i]) + planeEqWS;
-
- if (depth <=minDist){
- console.log("clamped: depth="+depth+" to minDist="+(minDist+""));
- depth = minDist;
- }
- if (depth <=maxDist){
- var point = pVtxIn[i];
- if(depth<=0){
-
- var p = {
- point:point,
- normal:planeNormalWS,
- depth: depth,
- };
- result.push(p);
- }
- }
- }
- };
- ConvexPolyhedron.prototype.clipFaceAgainstPlane = function(inVertices,outVertices, planeNormal, planeConstant){
- var n_dot_first, n_dot_last;
- var numVerts = inVertices.length;
- if(numVerts < 2){
- return outVertices;
- }
- var firstVertex = inVertices[inVertices.length-1],
- lastVertex = inVertices[0];
- n_dot_first = planeNormal.dot(firstVertex) + planeConstant;
- for(var vi = 0; vi < numVerts; vi++){
- lastVertex = inVertices[vi];
- n_dot_last = planeNormal.dot(lastVertex) + planeConstant;
- if(n_dot_first < 0){
- if(n_dot_last < 0){
-
- var newv = new Vec3();
- newv.copy(lastVertex);
- outVertices.push(newv);
- } else {
-
- var newv = new Vec3();
- firstVertex.lerp(lastVertex,
- n_dot_first / (n_dot_first - n_dot_last),
- newv);
- outVertices.push(newv);
- }
- } else {
- if(n_dot_last<0){
-
- var newv = new Vec3();
- firstVertex.lerp(lastVertex,
- n_dot_first / (n_dot_first - n_dot_last),
- newv);
- outVertices.push(newv);
- outVertices.push(lastVertex);
- }
- }
- firstVertex = lastVertex;
- n_dot_first = n_dot_last;
- }
- return outVertices;
- };
- ConvexPolyhedron.prototype.computeWorldVertices = function(position,quat){
- var N = this.vertices.length;
- while(this.worldVertices.length < N){
- this.worldVertices.push( new Vec3() );
- }
- var verts = this.vertices,
- worldVerts = this.worldVertices;
- for(var i=0; i!==N; i++){
- quat.vmult( verts[i] , worldVerts[i] );
- position.vadd( worldVerts[i] , worldVerts[i] );
- }
- this.worldVerticesNeedsUpdate = false;
- };
- var computeLocalAABB_worldVert = new Vec3();
- ConvexPolyhedron.prototype.computeLocalAABB = function(aabbmin,aabbmax){
- var n = this.vertices.length,
- vertices = this.vertices,
- worldVert = computeLocalAABB_worldVert;
- aabbmin.set(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);
- aabbmax.set(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);
- for(var i=0; i<n; i++){
- var v = vertices[i];
- if (v.x < aabbmin.x){
- aabbmin.x = v.x;
- } else if(v.x > aabbmax.x){
- aabbmax.x = v.x;
- }
- if (v.y < aabbmin.y){
- aabbmin.y = v.y;
- } else if(v.y > aabbmax.y){
- aabbmax.y = v.y;
- }
- if (v.z < aabbmin.z){
- aabbmin.z = v.z;
- } else if(v.z > aabbmax.z){
- aabbmax.z = v.z;
- }
- }
- };
- ConvexPolyhedron.prototype.computeWorldFaceNormals = function(quat){
- var N = this.faceNormals.length;
- while(this.worldFaceNormals.length < N){
- this.worldFaceNormals.push( new Vec3() );
- }
- var normals = this.faceNormals,
- worldNormals = this.worldFaceNormals;
- for(var i=0; i!==N; i++){
- quat.vmult( normals[i] , worldNormals[i] );
- }
- this.worldFaceNormalsNeedsUpdate = false;
- };
- ConvexPolyhedron.prototype.updateBoundingSphereRadius = function(){
-
- var max2 = 0;
- var verts = this.vertices;
- for(var i=0, N=verts.length; i!==N; i++) {
- var norm2 = verts[i].norm2();
- if(norm2 > max2){
- max2 = norm2;
- }
- }
- this.boundingSphereRadius = Math.sqrt(max2);
- };
- var tempWorldVertex = new Vec3();
- ConvexPolyhedron.prototype.calculateWorldAABB = function(pos,quat,min,max){
- var n = this.vertices.length, verts = this.vertices;
- var minx,miny,minz,maxx,maxy,maxz;
- for(var i=0; i<n; i++){
- tempWorldVertex.copy(verts[i]);
- quat.vmult(tempWorldVertex,tempWorldVertex);
- pos.vadd(tempWorldVertex,tempWorldVertex);
- var v = tempWorldVertex;
- if (v.x < minx || minx===undefined){
- minx = v.x;
- } else if(v.x > maxx || maxx===undefined){
- maxx = v.x;
- }
- if (v.y < miny || miny===undefined){
- miny = v.y;
- } else if(v.y > maxy || maxy===undefined){
- maxy = v.y;
- }
- if (v.z < minz || minz===undefined){
- minz = v.z;
- } else if(v.z > maxz || maxz===undefined){
- maxz = v.z;
- }
- }
- min.set(minx,miny,minz);
- max.set(maxx,maxy,maxz);
- };
- ConvexPolyhedron.prototype.volume = function(){
- return 4.0 * Math.PI * this.boundingSphereRadius / 3.0;
- };
- ConvexPolyhedron.prototype.getAveragePointLocal = function(target){
- target = target || new Vec3();
- var n = this.vertices.length,
- verts = this.vertices;
- for(var i=0; i<n; i++){
- target.vadd(verts[i],target);
- }
- target.mult(1/n,target);
- return target;
- };
- ConvexPolyhedron.prototype.transformAllPoints = function(offset,quat){
- var n = this.vertices.length,
- verts = this.vertices;
-
- if(quat){
-
- for(var i=0; i<n; i++){
- var v = verts[i];
- quat.vmult(v,v);
- }
-
- for(var i=0; i<this.faceNormals.length; i++){
- var v = this.faceNormals[i];
- quat.vmult(v,v);
- }
-
- }
-
- if(offset){
- for(var i=0; i<n; i++){
- var v = verts[i];
- v.vadd(offset,v);
- }
- }
- };
- var ConvexPolyhedron_pointIsInside = new Vec3();
- var ConvexPolyhedron_vToP = new Vec3();
- var ConvexPolyhedron_vToPointInside = new Vec3();
- ConvexPolyhedron.prototype.pointIsInside = function(p){
- var n = this.vertices.length,
- verts = this.vertices,
- faces = this.faces,
- normals = this.faceNormals;
- var positiveResult = null;
- var N = this.faces.length;
- var pointInside = ConvexPolyhedron_pointIsInside;
- this.getAveragePointLocal(pointInside);
- for(var i=0; i<N; i++){
- var numVertices = this.faces[i].length;
- var n = normals[i];
- var v = verts[faces[i][0]];
-
- var vToP = ConvexPolyhedron_vToP;
- p.vsub(v,vToP);
- var r1 = n.dot(vToP);
- var vToPointInside = ConvexPolyhedron_vToPointInside;
- pointInside.vsub(v,vToPointInside);
- var r2 = n.dot(vToPointInside);
- if((r1<0 && r2>0) || (r1>0 && r2<0)){
- return false;
- } else {
- }
- }
-
- return positiveResult ? 1 : -1;
- };
- var project_worldVertex = new Vec3();
- var project_localAxis = new Vec3();
- var project_localOrigin = new Vec3();
- ConvexPolyhedron.project = function(hull, axis, pos, quat, result){
- var n = hull.vertices.length,
- worldVertex = project_worldVertex,
- localAxis = project_localAxis,
- max = 0,
- min = 0,
- localOrigin = project_localOrigin,
- vs = hull.vertices;
- localOrigin.setZero();
-
- Transform.vectorToLocalFrame(pos, quat, axis, localAxis);
- Transform.pointToLocalFrame(pos, quat, localOrigin, localOrigin);
- var add = localOrigin.dot(localAxis);
- min = max = vs[0].dot(localAxis);
- for(var i = 1; i < n; i++){
- var val = vs[i].dot(localAxis);
- if(val > max){
- max = val;
- }
- if(val < min){
- min = val;
- }
- }
- min -= add;
- max -= add;
- if(min > max){
-
- var temp = min;
- min = max;
- max = temp;
- }
-
- result[0] = max;
- result[1] = min;
- };
- },{"../math/Quaternion":44,"../math/Transform":45,"../math/Vec3":46,"./Shape":59}],55:[function(require,module,exports){
- module.exports = Cylinder;
- var Shape = require('./Shape');
- var Vec3 = require('../math/Vec3');
- var Quaternion = require('../math/Quaternion');
- var ConvexPolyhedron = require('./ConvexPolyhedron');
- function Cylinder( radiusTop, radiusBottom, height , numSegments ) {
- var N = numSegments,
- verts = [],
- axes = [],
- faces = [],
- bottomface = [],
- topface = [],
- cos = Math.cos,
- sin = Math.sin;
-
- verts.push(new Vec3(radiusBottom*cos(0),
- radiusBottom*sin(0),
- -height*0.5));
- bottomface.push(0);
-
- verts.push(new Vec3(radiusTop*cos(0),
- radiusTop*sin(0),
- height*0.5));
- topface.push(1);
- for(var i=0; i<N; i++){
- var theta = 2*Math.PI/N * (i+1);
- var thetaN = 2*Math.PI/N * (i+0.5);
- if(i<N-1){
-
- verts.push(new Vec3(radiusBottom*cos(theta),
- radiusBottom*sin(theta),
- -height*0.5));
- bottomface.push(2*i+2);
-
- verts.push(new Vec3(radiusTop*cos(theta),
- radiusTop*sin(theta),
- height*0.5));
- topface.push(2*i+3);
-
- faces.push([2*i+2, 2*i+3, 2*i+1,2*i]);
- } else {
- faces.push([0,1, 2*i+1, 2*i]);
- }
-
- if(N % 2 === 1 || i < N / 2){
- axes.push(new Vec3(cos(thetaN), sin(thetaN), 0));
- }
- }
- faces.push(topface);
- axes.push(new Vec3(0,0,1));
-
- var temp = [];
- for(var i=0; i<bottomface.length; i++){
- temp.push(bottomface[bottomface.length - i - 1]);
- }
- faces.push(temp);
- this.type = Shape.types.CONVEXPOLYHEDRON;
- ConvexPolyhedron.call( this, verts, faces, axes );
- }
- Cylinder.prototype = new ConvexPolyhedron();
- },{"../math/Quaternion":44,"../math/Vec3":46,"./ConvexPolyhedron":54,"./Shape":59}],56:[function(require,module,exports){
- var Shape = require('./Shape');
- var ConvexPolyhedron = require('./ConvexPolyhedron');
- var Vec3 = require('../math/Vec3');
- var Utils = require('../utils/Utils');
- module.exports = Heightfield;
- function Heightfield(data, options){
- options = Utils.defaults(options, {
- maxValue : null,
- minValue : null,
- elementSize : 1
- });
-
- this.data = data;
-
- this.maxValue = options.maxValue;
-
- this.minValue = options.minValue;
-
- this.elementSize = options.elementSize;
- if(options.minValue === null){
- this.updateMinValue();
- }
- if(options.maxValue === null){
- this.updateMaxValue();
- }
- this.cacheEnabled = true;
- Shape.call(this);
- this.pillarConvex = new ConvexPolyhedron();
- this.pillarOffset = new Vec3();
- this.type = Shape.types.HEIGHTFIELD;
- this.updateBoundingSphereRadius();
-
-
-
- this._cachedPillars = {};
- }
- Heightfield.prototype = new Shape();
- Heightfield.prototype.update = function(){
- this._cachedPillars = {};
- };
- Heightfield.prototype.updateMinValue = function(){
- var data = this.data;
- var minValue = data[0][0];
- for(var i=0; i !== data.length; i++){
- for(var j=0; j !== data[i].length; j++){
- var v = data[i][j];
- if(v < minValue){
- minValue = v;
- }
- }
- }
- this.minValue = minValue;
- };
- Heightfield.prototype.updateMaxValue = function(){
- var data = this.data;
- var maxValue = data[0][0];
- for(var i=0; i !== data.length; i++){
- for(var j=0; j !== data[i].length; j++){
- var v = data[i][j];
- if(v > maxValue){
- maxValue = v;
- }
- }
- }
- this.maxValue = maxValue;
- };
- Heightfield.prototype.setHeightValueAtIndex = function(xi, yi, value){
- var data = this.data;
- data[xi][yi] = value;
-
- this.clearCachedConvexTrianglePillar(xi, yi, false);
- if(xi > 0){
- this.clearCachedConvexTrianglePillar(xi - 1, yi, true);
- this.clearCachedConvexTrianglePillar(xi - 1, yi, false);
- }
- if(yi > 0){
- this.clearCachedConvexTrianglePillar(xi, yi - 1, true);
- this.clearCachedConvexTrianglePillar(xi, yi - 1, false);
- }
- if(yi > 0 && xi > 0){
- this.clearCachedConvexTrianglePillar(xi - 1, yi - 1, true);
- }
- };
- Heightfield.prototype.getRectMinMax = function (iMinX, iMinY, iMaxX, iMaxY, result) {
- result = result || [];
-
- var data = this.data,
- max = this.minValue;
- for(var i = iMinX; i <= iMaxX; i++){
- for(var j = iMinY; j <= iMaxY; j++){
- var height = data[i][j];
- if(height > max){
- max = height;
- }
- }
- }
- result[0] = this.minValue;
- result[1] = max;
- };
- Heightfield.prototype.getIndexOfPosition = function (x, y, result, clamp) {
-
- var w = this.elementSize;
- var data = this.data;
- var xi = Math.floor(x / w);
- var yi = Math.floor(y / w);
- result[0] = xi;
- result[1] = yi;
- if(clamp){
-
- if(xi < 0){ xi = 0; }
- if(yi < 0){ yi = 0; }
- if(xi >= data.length - 1){ xi = data.length - 1; }
- if(yi >= data[0].length - 1){ yi = data[0].length - 1; }
- }
-
- if(xi < 0 || yi < 0 || xi >= data.length-1 || yi >= data[0].length-1){
- return false;
- }
- return true;
- };
- var getHeightAt_idx = [];
- var getHeightAt_weights = new Vec3();
- var getHeightAt_a = new Vec3();
- var getHeightAt_b = new Vec3();
- var getHeightAt_c = new Vec3();
- Heightfield.prototype.getTriangleAt = function(x, y, edgeClamp, a, b, c){
- var idx = getHeightAt_idx;
- this.getIndexOfPosition(x, y, idx, edgeClamp);
- var xi = idx[0];
- var yi = idx[1];
- var data = this.data;
- if(edgeClamp){
- xi = Math.min(data.length - 2, Math.max(0, xi));
- yi = Math.min(data[0].length - 2, Math.max(0, yi));
- }
- var elementSize = this.elementSize;
- var lowerDist2 = Math.pow(x / elementSize - xi, 2) + Math.pow(y / elementSize - yi, 2);
- var upperDist2 = Math.pow(x / elementSize - (xi + 1), 2) + Math.pow(y / elementSize - (yi + 1), 2);
- var upper = lowerDist2 > upperDist2;
- this.getTriangle(xi, yi, upper, a, b, c);
- return upper;
- };
- var getNormalAt_a = new Vec3();
- var getNormalAt_b = new Vec3();
- var getNormalAt_c = new Vec3();
- var getNormalAt_e0 = new Vec3();
- var getNormalAt_e1 = new Vec3();
- Heightfield.prototype.getNormalAt = function(x, y, edgeClamp, result){
- var a = getNormalAt_a;
- var b = getNormalAt_b;
- var c = getNormalAt_c;
- var e0 = getNormalAt_e0;
- var e1 = getNormalAt_e1;
- this.getTriangleAt(x, y, edgeClamp, a, b, c);
- b.vsub(a, e0);
- c.vsub(a, e1);
- e0.cross(e1, result);
- result.normalize();
- };
- Heightfield.prototype.getAabbAtIndex = function(xi, yi, result){
- var data = this.data;
- var elementSize = this.elementSize;
- result.lowerBound.set(
- xi * elementSize,
- yi * elementSize,
- data[xi][yi]
- );
- result.upperBound.set(
- (xi + 1) * elementSize,
- (yi + 1) * elementSize,
- data[xi + 1][yi + 1]
- );
- };
- Heightfield.prototype.getHeightAt = function(x, y, edgeClamp){
- var data = this.data;
- var a = getHeightAt_a;
- var b = getHeightAt_b;
- var c = getHeightAt_c;
- var idx = getHeightAt_idx;
- this.getIndexOfPosition(x, y, idx, edgeClamp);
- var xi = idx[0];
- var yi = idx[1];
- if(edgeClamp){
- xi = Math.min(data.length - 2, Math.max(0, xi));
- yi = Math.min(data[0].length - 2, Math.max(0, yi));
- }
- var upper = this.getTriangleAt(x, y, edgeClamp, a, b, c);
- barycentricWeights(x, y, a.x, a.y, b.x, b.y, c.x, c.y, getHeightAt_weights);
- var w = getHeightAt_weights;
- if(upper){
-
- return data[xi + 1][yi + 1] * w.x + data[xi][yi + 1] * w.y + data[xi + 1][yi] * w.z;
- } else {
-
- return data[xi][yi] * w.x + data[xi + 1][yi] * w.y + data[xi][yi + 1] * w.z;
- }
- };
- function barycentricWeights(x, y, ax, ay, bx, by, cx, cy, result){
- result.x = ((by - cy) * (x - cx) + (cx - bx) * (y - cy)) / ((by - cy) * (ax - cx) + (cx - bx) * (ay - cy));
- result.y = ((cy - ay) * (x - cx) + (ax - cx) * (y - cy)) / ((by - cy) * (ax - cx) + (cx - bx) * (ay - cy));
- result.z = 1 - result.x - result.y;
- }
- Heightfield.prototype.getCacheConvexTrianglePillarKey = function(xi, yi, getUpperTriangle){
- return xi + '_' + yi + '_' + (getUpperTriangle ? 1 : 0);
- };
- Heightfield.prototype.getCachedConvexTrianglePillar = function(xi, yi, getUpperTriangle){
- return this._cachedPillars[this.getCacheConvexTrianglePillarKey(xi, yi, getUpperTriangle)];
- };
- Heightfield.prototype.setCachedConvexTrianglePillar = function(xi, yi, getUpperTriangle, convex, offset){
- this._cachedPillars[this.getCacheConvexTrianglePillarKey(xi, yi, getUpperTriangle)] = {
- convex: convex,
- offset: offset
- };
- };
- Heightfield.prototype.clearCachedConvexTrianglePillar = function(xi, yi, getUpperTriangle){
- delete this._cachedPillars[this.getCacheConvexTrianglePillarKey(xi, yi, getUpperTriangle)];
- };
- Heightfield.prototype.getTriangle = function(xi, yi, upper, a, b, c){
- var data = this.data;
- var elementSize = this.elementSize;
- if(upper){
-
- a.set(
- (xi + 1) * elementSize,
- (yi + 1) * elementSize,
- data[xi + 1][yi + 1]
- );
- b.set(
- xi * elementSize,
- (yi + 1) * elementSize,
- data[xi][yi + 1]
- );
- c.set(
- (xi + 1) * elementSize,
- yi * elementSize,
- data[xi + 1][yi]
- );
- } else {
-
- a.set(
- xi * elementSize,
- yi * elementSize,
- data[xi][yi]
- );
- b.set(
- (xi + 1) * elementSize,
- yi * elementSize,
- data[xi + 1][yi]
- );
- c.set(
- xi * elementSize,
- (yi + 1) * elementSize,
- data[xi][yi + 1]
- );
- }
- };
- Heightfield.prototype.getConvexTrianglePillar = function(xi, yi, getUpperTriangle){
- var result = this.pillarConvex;
- var offsetResult = this.pillarOffset;
- if(this.cacheEnabled){
- var data = this.getCachedConvexTrianglePillar(xi, yi, getUpperTriangle);
- if(data){
- this.pillarConvex = data.convex;
- this.pillarOffset = data.offset;
- return;
- }
- result = new ConvexPolyhedron();
- offsetResult = new Vec3();
- this.pillarConvex = result;
- this.pillarOffset = offsetResult;
- }
- var data = this.data;
- var elementSize = this.elementSize;
- var faces = result.faces;
-
- result.vertices.length = 6;
- for (var i = 0; i < 6; i++) {
- if(!result.vertices[i]){
- result.vertices[i] = new Vec3();
- }
- }
-
- faces.length = 5;
- for (var i = 0; i < 5; i++) {
- if(!faces[i]){
- faces[i] = [];
- }
- }
- var verts = result.vertices;
- var h = (Math.min(
- data[xi][yi],
- data[xi+1][yi],
- data[xi][yi+1],
- data[xi+1][yi+1]
- ) - this.minValue ) / 2 + this.minValue;
- if (!getUpperTriangle) {
-
- offsetResult.set(
- (xi + 0.25) * elementSize,
- (yi + 0.25) * elementSize,
- h
- );
-
- verts[0].set(
- -0.25 * elementSize,
- -0.25 * elementSize,
- data[xi][yi] - h
- );
- verts[1].set(
- 0.75 * elementSize,
- -0.25 * elementSize,
- data[xi + 1][yi] - h
- );
- verts[2].set(
- -0.25 * elementSize,
- 0.75 * elementSize,
- data[xi][yi + 1] - h
- );
-
- verts[3].set(
- -0.25 * elementSize,
- -0.25 * elementSize,
- -h-1
- );
- verts[4].set(
- 0.75 * elementSize,
- -0.25 * elementSize,
- -h-1
- );
- verts[5].set(
- -0.25 * elementSize,
- 0.75 * elementSize,
- -h-1
- );
-
- faces[0][0] = 0;
- faces[0][1] = 1;
- faces[0][2] = 2;
-
- faces[1][0] = 5;
- faces[1][1] = 4;
- faces[1][2] = 3;
-
- faces[2][0] = 0;
- faces[2][1] = 2;
- faces[2][2] = 5;
- faces[2][3] = 3;
-
- faces[3][0] = 1;
- faces[3][1] = 0;
- faces[3][2] = 3;
- faces[3][3] = 4;
-
- faces[4][0] = 4;
- faces[4][1] = 5;
- faces[4][2] = 2;
- faces[4][3] = 1;
- } else {
-
- offsetResult.set(
- (xi + 0.75) * elementSize,
- (yi + 0.75) * elementSize,
- h
- );
-
- verts[0].set(
- 0.25 * elementSize,
- 0.25 * elementSize,
- data[xi + 1][yi + 1] - h
- );
- verts[1].set(
- -0.75 * elementSize,
- 0.25 * elementSize,
- data[xi][yi + 1] - h
- );
- verts[2].set(
- 0.25 * elementSize,
- -0.75 * elementSize,
- data[xi + 1][yi] - h
- );
-
- verts[3].set(
- 0.25 * elementSize,
- 0.25 * elementSize,
- - h-1
- );
- verts[4].set(
- -0.75 * elementSize,
- 0.25 * elementSize,
- - h-1
- );
- verts[5].set(
- 0.25 * elementSize,
- -0.75 * elementSize,
- - h-1
- );
-
- faces[0][0] = 0;
- faces[0][1] = 1;
- faces[0][2] = 2;
-
- faces[1][0] = 5;
- faces[1][1] = 4;
- faces[1][2] = 3;
-
- faces[2][0] = 2;
- faces[2][1] = 5;
- faces[2][2] = 3;
- faces[2][3] = 0;
-
- faces[3][0] = 3;
- faces[3][1] = 4;
- faces[3][2] = 1;
- faces[3][3] = 0;
-
- faces[4][0] = 1;
- faces[4][1] = 4;
- faces[4][2] = 5;
- faces[4][3] = 2;
- }
- result.computeNormals();
- result.computeEdges();
- result.updateBoundingSphereRadius();
- this.setCachedConvexTrianglePillar(xi, yi, getUpperTriangle, result, offsetResult);
- };
- Heightfield.prototype.calculateLocalInertia = function(mass, target){
- target = target || new Vec3();
- target.set(0, 0, 0);
- return target;
- };
- Heightfield.prototype.volume = function(){
- return Number.MAX_VALUE;
- };
- Heightfield.prototype.calculateWorldAABB = function(pos, quat, min, max){
-
- min.set(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);
- max.set(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);
- };
- Heightfield.prototype.updateBoundingSphereRadius = function(){
-
- var data = this.data,
- s = this.elementSize;
- this.boundingSphereRadius = new Vec3(data.length * s, data[0].length * s, Math.max(Math.abs(this.maxValue), Math.abs(this.minValue))).norm();
- };
- Heightfield.prototype.setHeightsFromImage = function(image, scale){
- var canvas = document.createElement('canvas');
- canvas.width = image.width;
- canvas.height = image.height;
- var context = canvas.getContext('2d');
- context.drawImage(image, 0, 0);
- var imageData = context.getImageData(0, 0, image.width, image.height);
- var matrix = this.data;
- matrix.length = 0;
- this.elementSize = Math.abs(scale.x) / imageData.width;
- for(var i=0; i<imageData.height; i++){
- var row = [];
- for(var j=0; j<imageData.width; j++){
- var a = imageData.data[(i*imageData.height + j) * 4];
- var b = imageData.data[(i*imageData.height + j) * 4 + 1];
- var c = imageData.data[(i*imageData.height + j) * 4 + 2];
- var height = (a + b + c) / 4 / 255 * scale.z;
- if(scale.x < 0){
- row.push(height);
- } else {
- row.unshift(height);
- }
- }
- if(scale.y < 0){
- matrix.unshift(row);
- } else {
- matrix.push(row);
- }
- }
- this.updateMaxValue();
- this.updateMinValue();
- this.update();
- };
- },{"../math/Vec3":46,"../utils/Utils":69,"./ConvexPolyhedron":54,"./Shape":59}],57:[function(require,module,exports){
- module.exports = Particle;
- var Shape = require('./Shape');
- var Vec3 = require('../math/Vec3');
- function Particle(){
- Shape.call(this);
- this.type = Shape.types.PARTICLE;
- }
- Particle.prototype = new Shape();
- Particle.prototype.constructor = Particle;
- Particle.prototype.calculateLocalInertia = function(mass,target){
- target = target || new Vec3();
- target.set(0, 0, 0);
- return target;
- };
- Particle.prototype.volume = function(){
- return 0;
- };
- Particle.prototype.updateBoundingSphereRadius = function(){
- this.boundingSphereRadius = 0;
- };
- Particle.prototype.calculateWorldAABB = function(pos,quat,min,max){
-
- min.copy(pos);
- max.copy(pos);
- };
- },{"../math/Vec3":46,"./Shape":59}],58:[function(require,module,exports){
- module.exports = Plane;
- var Shape = require('./Shape');
- var Vec3 = require('../math/Vec3');
- function Plane(){
- Shape.call(this);
- this.type = Shape.types.PLANE;
-
- this.worldNormal = new Vec3();
- this.worldNormalNeedsUpdate = true;
- this.boundingSphereRadius = Number.MAX_VALUE;
- }
- Plane.prototype = new Shape();
- Plane.prototype.constructor = Plane;
- Plane.prototype.computeWorldNormal = function(quat){
- var n = this.worldNormal;
- n.set(0,0,1);
- quat.vmult(n,n);
- this.worldNormalNeedsUpdate = false;
- };
- Plane.prototype.calculateLocalInertia = function(mass,target){
- target = target || new Vec3();
- return target;
- };
- Plane.prototype.volume = function(){
- return Number.MAX_VALUE;
- };
- var tempNormal = new Vec3();
- Plane.prototype.calculateWorldAABB = function(pos, quat, min, max){
-
- tempNormal.set(0,0,1);
- quat.vmult(tempNormal,tempNormal);
- var maxVal = Number.MAX_VALUE;
- min.set(-maxVal, -maxVal, -maxVal);
- max.set(maxVal, maxVal, maxVal);
- if(tempNormal.x === 1){ max.x = pos.x; }
- if(tempNormal.y === 1){ max.y = pos.y; }
- if(tempNormal.z === 1){ max.z = pos.z; }
- if(tempNormal.x === -1){ min.x = pos.x; }
- if(tempNormal.y === -1){ min.y = pos.y; }
- if(tempNormal.z === -1){ min.z = pos.z; }
- };
- Plane.prototype.updateBoundingSphereRadius = function(){
- this.boundingSphereRadius = Number.MAX_VALUE;
- };
- },{"../math/Vec3":46,"./Shape":59}],59:[function(require,module,exports){
- module.exports = Shape;
- var Shape = require('./Shape');
- var Vec3 = require('../math/Vec3');
- var Quaternion = require('../math/Quaternion');
- var Material = require('../material/Material');
- function Shape(){
-
- this.id = Shape.idCounter++;
-
- this.type = 0;
-
- this.boundingSphereRadius = 0;
-
- this.collisionResponse = true;
-
- this.material = null;
-
- this.body = null;
- }
- Shape.prototype.constructor = Shape;
- Shape.prototype.updateBoundingSphereRadius = function(){
- throw "computeBoundingSphereRadius() not implemented for shape type "+this.type;
- };
- Shape.prototype.volume = function(){
- throw "volume() not implemented for shape type "+this.type;
- };
- Shape.prototype.calculateLocalInertia = function(mass,target){
- throw "calculateLocalInertia() not implemented for shape type "+this.type;
- };
- Shape.idCounter = 0;
- Shape.types = {
- SPHERE:1,
- PLANE:2,
- BOX:4,
- COMPOUND:8,
- CONVEXPOLYHEDRON:16,
- HEIGHTFIELD:32,
- PARTICLE:64,
- CYLINDER:128,
- TRIMESH:256
- };
- },{"../material/Material":41,"../math/Quaternion":44,"../math/Vec3":46,"./Shape":59}],60:[function(require,module,exports){
- module.exports = Sphere;
- var Shape = require('./Shape');
- var Vec3 = require('../math/Vec3');
- function Sphere(radius){
- Shape.call(this);
-
- this.radius = radius!==undefined ? Number(radius) : 1.0;
- this.type = Shape.types.SPHERE;
- if(this.radius < 0){
- throw new Error('The sphere radius cannot be negative.');
- }
- this.updateBoundingSphereRadius();
- }
- Sphere.prototype = new Shape();
- Sphere.prototype.constructor = Sphere;
- Sphere.prototype.calculateLocalInertia = function(mass,target){
- target = target || new Vec3();
- var I = 2.0*mass*this.radius*this.radius/5.0;
- target.x = I;
- target.y = I;
- target.z = I;
- return target;
- };
- Sphere.prototype.volume = function(){
- return 4.0 * Math.PI * this.radius / 3.0;
- };
- Sphere.prototype.updateBoundingSphereRadius = function(){
- this.boundingSphereRadius = this.radius;
- };
- Sphere.prototype.calculateWorldAABB = function(pos,quat,min,max){
- var r = this.radius;
- var axes = ['x','y','z'];
- for(var i=0; i<axes.length; i++){
- var ax = axes[i];
- min[ax] = pos[ax] - r;
- max[ax] = pos[ax] + r;
- }
- };
- },{"../math/Vec3":46,"./Shape":59}],61:[function(require,module,exports){
- module.exports = Trimesh;
- var Shape = require('./Shape');
- var Vec3 = require('../math/Vec3');
- var Quaternion = require('../math/Quaternion');
- var Transform = require('../math/Transform');
- var AABB = require('../collision/AABB');
- var Octree = require('../utils/Octree');
- function Trimesh(vertices, indices) {
- Shape.call(this);
- this.type = Shape.types.TRIMESH;
-
- this.vertices = new Float32Array(vertices);
-
- this.indices = new Int16Array(indices);
-
- this.normals = new Float32Array(indices.length);
-
- this.aabb = new AABB();
-
- this.edges = null;
-
- this.scale = new Vec3(1, 1, 1);
-
- this.tree = new Octree();
- this.updateEdges();
- this.updateNormals();
- this.updateAABB();
- this.updateBoundingSphereRadius();
- this.updateTree();
- }
- Trimesh.prototype = new Shape();
- Trimesh.prototype.constructor = Trimesh;
- var computeNormals_n = new Vec3();
- Trimesh.prototype.updateTree = function(){
- var tree = this.tree;
- tree.reset();
- tree.aabb.copy(this.aabb);
- var scale = this.scale;
- tree.aabb.lowerBound.x *= 1 / scale.x;
- tree.aabb.lowerBound.y *= 1 / scale.y;
- tree.aabb.lowerBound.z *= 1 / scale.z;
- tree.aabb.upperBound.x *= 1 / scale.x;
- tree.aabb.upperBound.y *= 1 / scale.y;
- tree.aabb.upperBound.z *= 1 / scale.z;
-
- var triangleAABB = new AABB();
- var a = new Vec3();
- var b = new Vec3();
- var c = new Vec3();
- var points = [a, b, c];
- for (var i = 0; i < this.indices.length / 3; i++) {
-
-
- var i3 = i * 3;
- this._getUnscaledVertex(this.indices[i3], a);
- this._getUnscaledVertex(this.indices[i3 + 1], b);
- this._getUnscaledVertex(this.indices[i3 + 2], c);
- triangleAABB.setFromPoints(points);
- tree.insert(triangleAABB, i);
- }
- tree.removeEmptyNodes();
- };
- var unscaledAABB = new AABB();
- Trimesh.prototype.getTrianglesInAABB = function(aabb, result){
- unscaledAABB.copy(aabb);
-
- var scale = this.scale;
- var isx = scale.x;
- var isy = scale.y;
- var isz = scale.z;
- var l = unscaledAABB.lowerBound;
- var u = unscaledAABB.upperBound;
- l.x /= isx;
- l.y /= isy;
- l.z /= isz;
- u.x /= isx;
- u.y /= isy;
- u.z /= isz;
- return this.tree.aabbQuery(unscaledAABB, result);
- };
- Trimesh.prototype.setScale = function(scale){
- var wasUniform = this.scale.x === this.scale.y === this.scale.z;
- var isUniform = scale.x === scale.y === scale.z;
- if(!(wasUniform && isUniform)){
-
- this.updateNormals();
- }
- this.scale.copy(scale);
- this.updateAABB();
- this.updateBoundingSphereRadius();
- };
- Trimesh.prototype.updateNormals = function(){
- var n = computeNormals_n;
-
- var normals = this.normals;
- for(var i=0; i < this.indices.length / 3; i++){
- var i3 = i * 3;
- var a = this.indices[i3],
- b = this.indices[i3 + 1],
- c = this.indices[i3 + 2];
- this.getVertex(a, va);
- this.getVertex(b, vb);
- this.getVertex(c, vc);
- Trimesh.computeNormal(vb, va, vc, n);
- normals[i3] = n.x;
- normals[i3 + 1] = n.y;
- normals[i3 + 2] = n.z;
- }
- };
- Trimesh.prototype.updateEdges = function(){
- var edges = {};
- var add = function(indexA, indexB){
- var key = a < b ? a + '_' + b : b + '_' + a;
- edges[key] = true;
- };
- for(var i=0; i < this.indices.length / 3; i++){
- var i3 = i * 3;
- var a = this.indices[i3],
- b = this.indices[i3 + 1],
- c = this.indices[i3 + 2];
- add(a,b);
- add(b,c);
- add(c,a);
- }
- var keys = Object.keys(edges);
- this.edges = new Int16Array(keys.length * 2);
- for (var i = 0; i < keys.length; i++) {
- var indices = keys[i].split('_');
- this.edges[2 * i] = parseInt(indices[0], 10);
- this.edges[2 * i + 1] = parseInt(indices[1], 10);
- }
- };
- Trimesh.prototype.getEdgeVertex = function(edgeIndex, firstOrSecond, vertexStore){
- var vertexIndex = this.edges[edgeIndex * 2 + (firstOrSecond ? 1 : 0)];
- this.getVertex(vertexIndex, vertexStore);
- };
- var getEdgeVector_va = new Vec3();
- var getEdgeVector_vb = new Vec3();
- Trimesh.prototype.getEdgeVector = function(edgeIndex, vectorStore){
- var va = getEdgeVector_va;
- var vb = getEdgeVector_vb;
- this.getEdgeVertex(edgeIndex, 0, va);
- this.getEdgeVertex(edgeIndex, 1, vb);
- vb.vsub(va, vectorStore);
- };
- var cb = new Vec3();
- var ab = new Vec3();
- Trimesh.computeNormal = function ( va, vb, vc, target ) {
- vb.vsub(va,ab);
- vc.vsub(vb,cb);
- cb.cross(ab,target);
- if ( !target.isZero() ) {
- target.normalize();
- }
- };
- var va = new Vec3();
- var vb = new Vec3();
- var vc = new Vec3();
- Trimesh.prototype.getVertex = function(i, out){
- var scale = this.scale;
- this._getUnscaledVertex(i, out);
- out.x *= scale.x;
- out.y *= scale.y;
- out.z *= scale.z;
- return out;
- };
- Trimesh.prototype._getUnscaledVertex = function(i, out){
- var i3 = i * 3;
- var vertices = this.vertices;
- return out.set(
- vertices[i3],
- vertices[i3 + 1],
- vertices[i3 + 2]
- );
- };
- Trimesh.prototype.getWorldVertex = function(i, pos, quat, out){
- this.getVertex(i, out);
- Transform.pointToWorldFrame(pos, quat, out, out);
- return out;
- };
- Trimesh.prototype.getTriangleVertices = function(i, a, b, c){
- var i3 = i * 3;
- this.getVertex(this.indices[i3], a);
- this.getVertex(this.indices[i3 + 1], b);
- this.getVertex(this.indices[i3 + 2], c);
- };
- Trimesh.prototype.getNormal = function(i, target){
- var i3 = i * 3;
- return target.set(
- this.normals[i3],
- this.normals[i3 + 1],
- this.normals[i3 + 2]
- );
- };
- var cli_aabb = new AABB();
- Trimesh.prototype.calculateLocalInertia = function(mass,target){
-
-
- this.computeLocalAABB(cli_aabb);
- var x = cli_aabb.upperBound.x - cli_aabb.lowerBound.x,
- y = cli_aabb.upperBound.y - cli_aabb.lowerBound.y,
- z = cli_aabb.upperBound.z - cli_aabb.lowerBound.z;
- return target.set(
- 1.0 / 12.0 * mass * ( 2*y*2*y + 2*z*2*z ),
- 1.0 / 12.0 * mass * ( 2*x*2*x + 2*z*2*z ),
- 1.0 / 12.0 * mass * ( 2*y*2*y + 2*x*2*x )
- );
- };
- var computeLocalAABB_worldVert = new Vec3();
- Trimesh.prototype.computeLocalAABB = function(aabb){
- var l = aabb.lowerBound,
- u = aabb.upperBound,
- n = this.vertices.length,
- vertices = this.vertices,
- v = computeLocalAABB_worldVert;
- this.getVertex(0, v);
- l.copy(v);
- u.copy(v);
- for(var i=0; i !== n; i++){
- this.getVertex(i, v);
- if(v.x < l.x){
- l.x = v.x;
- } else if(v.x > u.x){
- u.x = v.x;
- }
- if(v.y < l.y){
- l.y = v.y;
- } else if(v.y > u.y){
- u.y = v.y;
- }
- if(v.z < l.z){
- l.z = v.z;
- } else if(v.z > u.z){
- u.z = v.z;
- }
- }
- };
- Trimesh.prototype.updateAABB = function(){
- this.computeLocalAABB(this.aabb);
- };
- Trimesh.prototype.updateBoundingSphereRadius = function(){
-
- var max2 = 0;
- var vertices = this.vertices;
- var v = new Vec3();
- for(var i=0, N=vertices.length / 3; i !== N; i++) {
- this.getVertex(i, v);
- var norm2 = v.norm2();
- if(norm2 > max2){
- max2 = norm2;
- }
- }
- this.boundingSphereRadius = Math.sqrt(max2);
- };
- var tempWorldVertex = new Vec3();
- var calculateWorldAABB_frame = new Transform();
- var calculateWorldAABB_aabb = new AABB();
- Trimesh.prototype.calculateWorldAABB = function(pos,quat,min,max){
-
-
- var frame = calculateWorldAABB_frame;
- var result = calculateWorldAABB_aabb;
- frame.position = pos;
- frame.quaternion = quat;
- this.aabb.toWorldFrame(frame, result);
- min.copy(result.lowerBound);
- max.copy(result.upperBound);
- };
- Trimesh.prototype.volume = function(){
- return 4.0 * Math.PI * this.boundingSphereRadius / 3.0;
- };
- Trimesh.createTorus = function (radius, tube, radialSegments, tubularSegments, arc) {
- radius = radius || 1;
- tube = tube || 0.5;
- radialSegments = radialSegments || 8;
- tubularSegments = tubularSegments || 6;
- arc = arc || Math.PI * 2;
- var vertices = [];
- var indices = [];
- for ( var j = 0; j <= radialSegments; j ++ ) {
- for ( var i = 0; i <= tubularSegments; i ++ ) {
- var u = i / tubularSegments * arc;
- var v = j / radialSegments * Math.PI * 2;
- var x = ( radius + tube * Math.cos( v ) ) * Math.cos( u );
- var y = ( radius + tube * Math.cos( v ) ) * Math.sin( u );
- var z = tube * Math.sin( v );
- vertices.push( x, y, z );
- }
- }
- for ( var j = 1; j <= radialSegments; j ++ ) {
- for ( var i = 1; i <= tubularSegments; i ++ ) {
- var a = ( tubularSegments + 1 ) * j + i - 1;
- var b = ( tubularSegments + 1 ) * ( j - 1 ) + i - 1;
- var c = ( tubularSegments + 1 ) * ( j - 1 ) + i;
- var d = ( tubularSegments + 1 ) * j + i;
- indices.push(a, b, d);
- indices.push(b, c, d);
- }
- }
- return new Trimesh(vertices, indices);
- };
- },{"../collision/AABB":18,"../math/Quaternion":44,"../math/Transform":45,"../math/Vec3":46,"../utils/Octree":66,"./Shape":59}],62:[function(require,module,exports){
- module.exports = GSSolver;
- var Vec3 = require('../math/Vec3');
- var Quaternion = require('../math/Quaternion');
- var Solver = require('./Solver');
- function GSSolver(){
- Solver.call(this);
-
- this.iterations = 10;
-
- this.tolerance = 1e-7;
- }
- GSSolver.prototype = new Solver();
- var GSSolver_solve_lambda = [];
- var GSSolver_solve_invCs = [];
- var GSSolver_solve_Bs = [];
- GSSolver.prototype.solve = function(dt,world){
- var iter = 0,
- maxIter = this.iterations,
- tolSquared = this.tolerance*this.tolerance,
- equations = this.equations,
- Neq = equations.length,
- bodies = world.bodies,
- Nbodies = bodies.length,
- h = dt,
- q, B, invC, deltalambda, deltalambdaTot, GWlambda, lambdaj;
-
- if(Neq !== 0){
- for(var i=0; i!==Nbodies; i++){
- bodies[i].updateSolveMassProperties();
- }
- }
-
- var invCs = GSSolver_solve_invCs,
- Bs = GSSolver_solve_Bs,
- lambda = GSSolver_solve_lambda;
- invCs.length = Neq;
- Bs.length = Neq;
- lambda.length = Neq;
- for(var i=0; i!==Neq; i++){
- var c = equations[i];
- lambda[i] = 0.0;
- Bs[i] = c.computeB(h);
- invCs[i] = 1.0 / c.computeC();
- }
- if(Neq !== 0){
-
- for(var i=0; i!==Nbodies; i++){
- var b=bodies[i],
- vlambda=b.vlambda,
- wlambda=b.wlambda;
- vlambda.set(0,0,0);
- wlambda.set(0,0,0);
- }
-
- for(iter=0; iter!==maxIter; iter++){
-
- deltalambdaTot = 0.0;
- for(var j=0; j!==Neq; j++){
- var c = equations[j];
-
- B = Bs[j];
- invC = invCs[j];
- lambdaj = lambda[j];
- GWlambda = c.computeGWlambda();
- deltalambda = invC * ( B - GWlambda - c.eps * lambdaj );
-
- if(lambdaj + deltalambda < c.minForce){
- deltalambda = c.minForce - lambdaj;
- } else if(lambdaj + deltalambda > c.maxForce){
- deltalambda = c.maxForce - lambdaj;
- }
- lambda[j] += deltalambda;
- deltalambdaTot += deltalambda > 0.0 ? deltalambda : -deltalambda;
- c.addToWlambda(deltalambda);
- }
-
- if(deltalambdaTot*deltalambdaTot < tolSquared){
- break;
- }
- }
-
- for(var i=0; i!==Nbodies; i++){
- var b=bodies[i],
- v=b.velocity,
- w=b.angularVelocity;
- b.vlambda.vmul(b.linearFactor, b.vlambda);
- v.vadd(b.vlambda, v);
- b.wlambda.vmul(b.angularFactor, b.wlambda);
- w.vadd(b.wlambda, w);
- }
-
- var l = equations.length;
- var invDt = 1 / h;
- while(l--){
- equations[l].multiplier = lambda[l] * invDt;
- }
- }
- return iter;
- };
- },{"../math/Quaternion":44,"../math/Vec3":46,"./Solver":63}],63:[function(require,module,exports){
- module.exports = Solver;
- function Solver(){
-
- this.equations = [];
- }
- Solver.prototype.solve = function(dt,world){
-
- return 0;
- };
- Solver.prototype.addEquation = function(eq){
- if (eq.enabled) {
- this.equations.push(eq);
- }
- };
- Solver.prototype.removeEquation = function(eq){
- var eqs = this.equations;
- var i = eqs.indexOf(eq);
- if(i !== -1){
- eqs.splice(i,1);
- }
- };
- Solver.prototype.removeAllEquations = function(){
- this.equations.length = 0;
- };
- },{}],64:[function(require,module,exports){
- module.exports = SplitSolver;
- var Vec3 = require('../math/Vec3');
- var Quaternion = require('../math/Quaternion');
- var Solver = require('./Solver');
- var Body = require('../objects/Body');
- function SplitSolver(subsolver){
- Solver.call(this);
- this.iterations = 10;
- this.tolerance = 1e-7;
- this.subsolver = subsolver;
- this.nodes = [];
- this.nodePool = [];
-
- while(this.nodePool.length < 128){
- this.nodePool.push(this.createNode());
- }
- }
- SplitSolver.prototype = new Solver();
- var SplitSolver_solve_nodes = [];
- var SplitSolver_solve_nodePool = [];
- var SplitSolver_solve_eqs = [];
- var SplitSolver_solve_bds = [];
- var SplitSolver_solve_dummyWorld = {bodies:[]};
- var STATIC = Body.STATIC;
- function getUnvisitedNode(nodes){
- var Nnodes = nodes.length;
- for(var i=0; i!==Nnodes; i++){
- var node = nodes[i];
- if(!node.visited && !(node.body.type & STATIC)){
- return node;
- }
- }
- return false;
- }
- var queue = [];
- function bfs(root,visitFunc,bds,eqs){
- queue.push(root);
- root.visited = true;
- visitFunc(root,bds,eqs);
- while(queue.length) {
- var node = queue.pop();
-
- var child;
- while((child = getUnvisitedNode(node.children))) {
- child.visited = true;
- visitFunc(child,bds,eqs);
- queue.push(child);
- }
- }
- }
- function visitFunc(node,bds,eqs){
- bds.push(node.body);
- var Neqs = node.eqs.length;
- for(var i=0; i!==Neqs; i++){
- var eq = node.eqs[i];
- if(eqs.indexOf(eq) === -1){
- eqs.push(eq);
- }
- }
- }
- SplitSolver.prototype.createNode = function(){
- return { body:null, children:[], eqs:[], visited:false };
- };
- SplitSolver.prototype.solve = function(dt,world){
- var nodes=SplitSolver_solve_nodes,
- nodePool=this.nodePool,
- bodies=world.bodies,
- equations=this.equations,
- Neq=equations.length,
- Nbodies=bodies.length,
- subsolver=this.subsolver;
-
- while(nodePool.length < Nbodies){
- nodePool.push(this.createNode());
- }
- nodes.length = Nbodies;
- for (var i = 0; i < Nbodies; i++) {
- nodes[i] = nodePool[i];
- }
-
- for(var i=0; i!==Nbodies; i++){
- var node = nodes[i];
- node.body = bodies[i];
- node.children.length = 0;
- node.eqs.length = 0;
- node.visited = false;
- }
- for(var k=0; k!==Neq; k++){
- var eq=equations[k],
- i=bodies.indexOf(eq.bi),
- j=bodies.indexOf(eq.bj),
- ni=nodes[i],
- nj=nodes[j];
- ni.children.push(nj);
- ni.eqs.push(eq);
- nj.children.push(ni);
- nj.eqs.push(eq);
- }
- var child, n=0, eqs=SplitSolver_solve_eqs;
- subsolver.tolerance = this.tolerance;
- subsolver.iterations = this.iterations;
- var dummyWorld = SplitSolver_solve_dummyWorld;
- while((child = getUnvisitedNode(nodes))){
- eqs.length = 0;
- dummyWorld.bodies.length = 0;
- bfs(child, visitFunc, dummyWorld.bodies, eqs);
- var Neqs = eqs.length;
- eqs = eqs.sort(sortById);
- for(var i=0; i!==Neqs; i++){
- subsolver.addEquation(eqs[i]);
- }
- var iter = subsolver.solve(dt,dummyWorld);
- subsolver.removeAllEquations();
- n++;
- }
- return n;
- };
- function sortById(a, b){
- return b.id - a.id;
- }
- },{"../math/Quaternion":44,"../math/Vec3":46,"../objects/Body":47,"./Solver":63}],65:[function(require,module,exports){
- var EventTarget = function () {
- };
- module.exports = EventTarget;
- EventTarget.prototype = {
- constructor: EventTarget,
-
- addEventListener: function ( type, listener ) {
- if ( this._listeners === undefined ){ this._listeners = {}; }
- var listeners = this._listeners;
- if ( listeners[ type ] === undefined ) {
- listeners[ type ] = [];
- }
- if ( listeners[ type ].indexOf( listener ) === - 1 ) {
- listeners[ type ].push( listener );
- }
- return this;
- },
-
- hasEventListener: function ( type, listener ) {
- if ( this._listeners === undefined ){ return false; }
- var listeners = this._listeners;
- if ( listeners[ type ] !== undefined && listeners[ type ].indexOf( listener ) !== - 1 ) {
- return true;
- }
- return false;
- },
-
- hasAnyEventListener: function ( type ) {
- if ( this._listeners === undefined ){ return false; }
- var listeners = this._listeners;
- return ( listeners[ type ] !== undefined );
- },
-
- removeEventListener: function ( type, listener ) {
- if ( this._listeners === undefined ){ return this; }
- var listeners = this._listeners;
- if ( listeners[type] === undefined ){ return this; }
- var index = listeners[ type ].indexOf( listener );
- if ( index !== - 1 ) {
- listeners[ type ].splice( index, 1 );
- }
- return this;
- },
-
- dispatchEvent: function ( event ) {
- if ( this._listeners === undefined ){ return this; }
- var listeners = this._listeners;
- var listenerArray = listeners[ event.type ];
- if ( listenerArray !== undefined ) {
- event.target = this;
- for ( var i = 0, l = listenerArray.length; i < l; i ++ ) {
- listenerArray[ i ].call( this, event );
- }
- }
- return this;
- }
- };
- },{}],66:[function(require,module,exports){
- var AABB = require('../collision/AABB');
- var Vec3 = require('../math/Vec3');
- module.exports = Octree;
- function OctreeNode(options){
- options = options || {};
-
- this.root = options.root || null;
-
- this.aabb = options.aabb ? options.aabb.clone() : new AABB();
-
- this.data = [];
-
- this.children = [];
- }
- function Octree(aabb, options){
- options = options || {};
- options.root = null;
- options.aabb = aabb;
- OctreeNode.call(this, options);
-
- this.maxDepth = typeof(options.maxDepth) !== 'undefined' ? options.maxDepth : 8;
- }
- Octree.prototype = new OctreeNode();
- OctreeNode.prototype.reset = function(aabb, options){
- this.children.length = this.data.length = 0;
- };
- OctreeNode.prototype.insert = function(aabb, elementData, level){
- var nodeData = this.data;
- level = level || 0;
-
- if (!this.aabb.contains(aabb)){
- return false;
- }
- var children = this.children;
- if(level < (this.maxDepth || this.root.maxDepth)){
-
- var subdivided = false;
- if (!children.length){
- this.subdivide();
- subdivided = true;
- }
-
- for (var i = 0; i !== 8; i++) {
- if (children[i].insert(aabb, elementData, level + 1)){
- return true;
- }
- }
- if(subdivided){
-
- children.length = 0;
- }
- }
-
- nodeData.push(elementData);
- return true;
- };
- var halfDiagonal = new Vec3();
- OctreeNode.prototype.subdivide = function() {
- var aabb = this.aabb;
- var l = aabb.lowerBound;
- var u = aabb.upperBound;
- var children = this.children;
- children.push(
- new OctreeNode({ aabb: new AABB({ lowerBound: new Vec3(0,0,0) }) }),
- new OctreeNode({ aabb: new AABB({ lowerBound: new Vec3(1,0,0) }) }),
- new OctreeNode({ aabb: new AABB({ lowerBound: new Vec3(1,1,0) }) }),
- new OctreeNode({ aabb: new AABB({ lowerBound: new Vec3(1,1,1) }) }),
- new OctreeNode({ aabb: new AABB({ lowerBound: new Vec3(0,1,1) }) }),
- new OctreeNode({ aabb: new AABB({ lowerBound: new Vec3(0,0,1) }) }),
- new OctreeNode({ aabb: new AABB({ lowerBound: new Vec3(1,0,1) }) }),
- new OctreeNode({ aabb: new AABB({ lowerBound: new Vec3(0,1,0) }) })
- );
- u.vsub(l, halfDiagonal);
- halfDiagonal.scale(0.5, halfDiagonal);
- var root = this.root || this;
- for (var i = 0; i !== 8; i++) {
- var child = children[i];
-
- child.root = root;
-
- var lowerBound = child.aabb.lowerBound;
- lowerBound.x *= halfDiagonal.x;
- lowerBound.y *= halfDiagonal.y;
- lowerBound.z *= halfDiagonal.z;
- lowerBound.vadd(l, lowerBound);
-
- lowerBound.vadd(halfDiagonal, child.aabb.upperBound);
- }
- };
- OctreeNode.prototype.aabbQuery = function(aabb, result) {
- var nodeData = this.data;
-
-
-
-
-
-
-
-
- var children = this.children;
-
-
-
- var queue = [this];
- while (queue.length) {
- var node = queue.pop();
- if (node.aabb.overlaps(aabb)){
- Array.prototype.push.apply(result, node.data);
- }
- Array.prototype.push.apply(queue, node.children);
- }
- return result;
- };
- var tmpAABB = new AABB();
- OctreeNode.prototype.rayQuery = function(ray, treeTransform, result) {
-
-
- ray.getAABB(tmpAABB);
- tmpAABB.toLocalFrame(treeTransform, tmpAABB);
- this.aabbQuery(tmpAABB, result);
- return result;
- };
- OctreeNode.prototype.removeEmptyNodes = function() {
- var queue = [this];
- while (queue.length) {
- var node = queue.pop();
- for (var i = node.children.length - 1; i >= 0; i--) {
- if(!node.children[i].data.length){
- node.children.splice(i, 1);
- }
- }
- Array.prototype.push.apply(queue, node.children);
- }
- };
- },{"../collision/AABB":18,"../math/Vec3":46}],67:[function(require,module,exports){
- module.exports = Pool;
- function Pool(){
-
- this.objects = [];
-
- this.type = Object;
- }
- Pool.prototype.release = function(){
- var Nargs = arguments.length;
- for(var i=0; i!==Nargs; i++){
- this.objects.push(arguments[i]);
- }
- return this;
- };
- Pool.prototype.get = function(){
- if(this.objects.length===0){
- return this.constructObject();
- } else {
- return this.objects.pop();
- }
- };
- Pool.prototype.constructObject = function(){
- throw new Error("constructObject() not implemented in this Pool subclass yet!");
- };
- Pool.prototype.resize = function (size) {
- var objects = this.objects;
- while (objects.length > size) {
- objects.pop();
- }
- while (objects.length < size) {
- objects.push(this.constructObject());
- }
- return this;
- };
- },{}],68:[function(require,module,exports){
- module.exports = TupleDictionary;
- function TupleDictionary() {
-
- this.data = { keys:[] };
- }
- TupleDictionary.prototype.get = function(i, j) {
- if (i > j) {
-
- var temp = j;
- j = i;
- i = temp;
- }
- return this.data[i+'-'+j];
- };
- TupleDictionary.prototype.set = function(i, j, value) {
- if (i > j) {
- var temp = j;
- j = i;
- i = temp;
- }
- var key = i+'-'+j;
-
- if(!this.get(i,j)){
- this.data.keys.push(key);
- }
- this.data[key] = value;
- };
- TupleDictionary.prototype.reset = function() {
- var data = this.data,
- keys = data.keys;
- while(keys.length > 0){
- var key = keys.pop();
- delete data[key];
- }
- };
- },{}],69:[function(require,module,exports){
- function Utils(){}
- module.exports = Utils;
- Utils.defaults = function(options, defaults){
- options = options || {};
- for(var key in defaults){
- if(!(key in options)){
- options[key] = defaults[key];
- }
- }
- return options;
- };
- },{}],70:[function(require,module,exports){
- module.exports = Vec3Pool;
- var Vec3 = require('../math/Vec3');
- var Pool = require('./Pool');
- function Vec3Pool(){
- Pool.call(this);
- this.type = Vec3;
- }
- Vec3Pool.prototype = new Pool();
- Vec3Pool.prototype.constructObject = function(){
- return new Vec3();
- };
- },{"../math/Vec3":46,"./Pool":67}],71:[function(require,module,exports){
- module.exports = Narrowphase;
- var AABB = require('../collision/AABB');
- var Body = require('../objects/Body');
- var Shape = require('../shapes/Shape');
- var Ray = require('../collision/Ray');
- var Vec3 = require('../math/Vec3');
- var Transform = require('../math/Transform');
- var ConvexPolyhedron = require('../shapes/ConvexPolyhedron');
- var Quaternion = require('../math/Quaternion');
- var Solver = require('../solver/Solver');
- var Vec3Pool = require('../utils/Vec3Pool');
- var ContactEquation = require('../equations/ContactEquation');
- var FrictionEquation = require('../equations/FrictionEquation');
- function Narrowphase(world){
-
- this.contactPointPool = [];
- this.frictionEquationPool = [];
- this.result = [];
- this.frictionResult = [];
-
- this.v3pool = new Vec3Pool();
- this.world = world;
- this.currentContactMaterial = null;
-
- this.enableFrictionReduction = false;
- }
- Narrowphase.prototype.createContactEquation = function(bi, bj, si, sj, overrideShapeA, overrideShapeB){
- var c;
- if(this.contactPointPool.length){
- c = this.contactPointPool.pop();
- c.bi = bi;
- c.bj = bj;
- } else {
- c = new ContactEquation(bi, bj);
- }
- c.enabled = bi.collisionResponse && bj.collisionResponse && si.collisionResponse && sj.collisionResponse;
- var cm = this.currentContactMaterial;
- c.restitution = cm.restitution;
- c.setSpookParams(
- cm.contactEquationStiffness,
- cm.contactEquationRelaxation,
- this.world.dt
- );
- var matA = si.material || bi.material;
- var matB = sj.material || bj.material;
- if(matA && matB && matA.restitution >= 0 && matB.restitution >= 0){
- c.restitution = matA.restitution * matB.restitution;
- }
- c.si = overrideShapeA || si;
- c.sj = overrideShapeB || sj;
- return c;
- };
- Narrowphase.prototype.createFrictionEquationsFromContact = function(contactEquation, outArray){
- var bodyA = contactEquation.bi;
- var bodyB = contactEquation.bj;
- var shapeA = contactEquation.si;
- var shapeB = contactEquation.sj;
- var world = this.world;
- var cm = this.currentContactMaterial;
-
- var friction = cm.friction;
- var matA = shapeA.material || bodyA.material;
- var matB = shapeB.material || bodyB.material;
- if(matA && matB && matA.friction >= 0 && matB.friction >= 0){
- friction = matA.friction * matB.friction;
- }
- if(friction > 0){
-
- var mug = friction * world.gravity.length();
- var reducedMass = (bodyA.invMass + bodyB.invMass);
- if(reducedMass > 0){
- reducedMass = 1/reducedMass;
- }
- var pool = this.frictionEquationPool;
- var c1 = pool.length ? pool.pop() : new FrictionEquation(bodyA,bodyB,mug*reducedMass);
- var c2 = pool.length ? pool.pop() : new FrictionEquation(bodyA,bodyB,mug*reducedMass);
- c1.bi = c2.bi = bodyA;
- c1.bj = c2.bj = bodyB;
- c1.minForce = c2.minForce = -mug*reducedMass;
- c1.maxForce = c2.maxForce = mug*reducedMass;
-
- c1.ri.copy(contactEquation.ri);
- c1.rj.copy(contactEquation.rj);
- c2.ri.copy(contactEquation.ri);
- c2.rj.copy(contactEquation.rj);
-
- contactEquation.ni.tangents(c1.t, c2.t);
-
- c1.setSpookParams(cm.frictionEquationStiffness, cm.frictionEquationRelaxation, world.dt);
- c2.setSpookParams(cm.frictionEquationStiffness, cm.frictionEquationRelaxation, world.dt);
- c1.enabled = c2.enabled = contactEquation.enabled;
- outArray.push(c1, c2);
- return true;
- }
- return false;
- };
- var averageNormal = new Vec3();
- var averageContactPointA = new Vec3();
- var averageContactPointB = new Vec3();
- Narrowphase.prototype.createFrictionFromAverage = function(numContacts){
-
- var c = this.result[this.result.length - 1];
-
- if (!this.createFrictionEquationsFromContact(c, this.frictionResult) || numContacts === 1) {
- return;
- }
- var f1 = this.frictionResult[this.frictionResult.length - 2];
- var f2 = this.frictionResult[this.frictionResult.length - 1];
- averageNormal.setZero();
- averageContactPointA.setZero();
- averageContactPointB.setZero();
- var bodyA = c.bi;
- var bodyB = c.bj;
- for(var i=0; i!==numContacts; i++){
- c = this.result[this.result.length - 1 - i];
- if(c.bodyA !== bodyA){
- averageNormal.vadd(c.ni, averageNormal);
- averageContactPointA.vadd(c.ri, averageContactPointA);
- averageContactPointB.vadd(c.rj, averageContactPointB);
- } else {
- averageNormal.vsub(c.ni, averageNormal);
- averageContactPointA.vadd(c.rj, averageContactPointA);
- averageContactPointB.vadd(c.ri, averageContactPointB);
- }
- }
- var invNumContacts = 1 / numContacts;
- averageContactPointA.scale(invNumContacts, f1.ri);
- averageContactPointB.scale(invNumContacts, f1.rj);
- f2.ri.copy(f1.ri);
- f2.rj.copy(f1.rj);
- averageNormal.normalize();
- averageNormal.tangents(f1.t, f2.t);
-
- };
- var tmpVec1 = new Vec3();
- var tmpVec2 = new Vec3();
- var tmpQuat1 = new Quaternion();
- var tmpQuat2 = new Quaternion();
- Narrowphase.prototype.getContacts = function(p1, p2, world, result, oldcontacts, frictionResult, frictionPool){
-
- this.contactPointPool = oldcontacts;
- this.frictionEquationPool = frictionPool;
- this.result = result;
- this.frictionResult = frictionResult;
- var qi = tmpQuat1;
- var qj = tmpQuat2;
- var xi = tmpVec1;
- var xj = tmpVec2;
- for(var k=0, N=p1.length; k!==N; k++){
-
- var bi = p1[k],
- bj = p2[k];
-
- var bodyContactMaterial = null;
- if(bi.material && bj.material){
- bodyContactMaterial = world.getContactMaterial(bi.material,bj.material) || null;
- }
- var justTest = (
- (
- (bi.type & Body.KINEMATIC) && (bj.type & Body.STATIC)
- ) || (
- (bi.type & Body.STATIC) && (bj.type & Body.KINEMATIC)
- ) || (
- (bi.type & Body.KINEMATIC) && (bj.type & Body.KINEMATIC)
- )
- );
- for (var i = 0; i < bi.shapes.length; i++) {
- bi.quaternion.mult(bi.shapeOrientations[i], qi);
- bi.quaternion.vmult(bi.shapeOffsets[i], xi);
- xi.vadd(bi.position, xi);
- var si = bi.shapes[i];
- for (var j = 0; j < bj.shapes.length; j++) {
-
- bj.quaternion.mult(bj.shapeOrientations[j], qj);
- bj.quaternion.vmult(bj.shapeOffsets[j], xj);
- xj.vadd(bj.position, xj);
- var sj = bj.shapes[j];
- if(xi.distanceTo(xj) > si.boundingSphereRadius + sj.boundingSphereRadius){
- continue;
- }
-
- var shapeContactMaterial = null;
- if(si.material && sj.material){
- shapeContactMaterial = world.getContactMaterial(si.material,sj.material) || null;
- }
- this.currentContactMaterial = shapeContactMaterial || bodyContactMaterial || world.defaultContactMaterial;
-
- var resolver = this[si.type | sj.type];
- if(resolver){
- var retval = false;
- if (si.type < sj.type) {
- retval = resolver.call(this, si, sj, xi, xj, qi, qj, bi, bj, si, sj, justTest);
- } else {
- retval = resolver.call(this, sj, si, xj, xi, qj, qi, bj, bi, si, sj, justTest);
- }
- if(retval && justTest){
-
- world.shapeOverlapKeeper.set(si.id, sj.id);
- world.bodyOverlapKeeper.set(bi.id, bj.id);
- }
- }
- }
- }
- }
- };
- var numWarnings = 0;
- var maxWarnings = 10;
- function warn(msg){
- if(numWarnings > maxWarnings){
- return;
- }
- numWarnings++;
- console.warn(msg);
- }
- Narrowphase.prototype[Shape.types.BOX | Shape.types.BOX] =
- Narrowphase.prototype.boxBox = function(si,sj,xi,xj,qi,qj,bi,bj,rsi,rsj,justTest){
- si.convexPolyhedronRepresentation.material = si.material;
- sj.convexPolyhedronRepresentation.material = sj.material;
- si.convexPolyhedronRepresentation.collisionResponse = si.collisionResponse;
- sj.convexPolyhedronRepresentation.collisionResponse = sj.collisionResponse;
- return this.convexConvex(si.convexPolyhedronRepresentation,sj.convexPolyhedronRepresentation,xi,xj,qi,qj,bi,bj,si,sj,justTest);
- };
- Narrowphase.prototype[Shape.types.BOX | Shape.types.CONVEXPOLYHEDRON] =
- Narrowphase.prototype.boxConvex = function(si,sj,xi,xj,qi,qj,bi,bj,rsi,rsj,justTest){
- si.convexPolyhedronRepresentation.material = si.material;
- si.convexPolyhedronRepresentation.collisionResponse = si.collisionResponse;
- return this.convexConvex(si.convexPolyhedronRepresentation,sj,xi,xj,qi,qj,bi,bj,si,sj,justTest);
- };
- Narrowphase.prototype[Shape.types.BOX | Shape.types.PARTICLE] =
- Narrowphase.prototype.boxParticle = function(si,sj,xi,xj,qi,qj,bi,bj,rsi,rsj,justTest){
- si.convexPolyhedronRepresentation.material = si.material;
- si.convexPolyhedronRepresentation.collisionResponse = si.collisionResponse;
- return this.convexParticle(si.convexPolyhedronRepresentation,sj,xi,xj,qi,qj,bi,bj,si,sj,justTest);
- };
- Narrowphase.prototype[Shape.types.SPHERE] =
- Narrowphase.prototype.sphereSphere = function(si,sj,xi,xj,qi,qj,bi,bj,rsi,rsj,justTest){
- if(justTest){
- return xi.distanceSquared(xj) < Math.pow(si.radius + sj.radius, 2);
- }
-
- var r = this.createContactEquation(bi,bj,si,sj,rsi,rsj);
-
- xj.vsub(xi, r.ni);
- r.ni.normalize();
-
- r.ri.copy(r.ni);
- r.rj.copy(r.ni);
- r.ri.mult(si.radius, r.ri);
- r.rj.mult(-sj.radius, r.rj);
- r.ri.vadd(xi, r.ri);
- r.ri.vsub(bi.position, r.ri);
- r.rj.vadd(xj, r.rj);
- r.rj.vsub(bj.position, r.rj);
- this.result.push(r);
- this.createFrictionEquationsFromContact(r, this.frictionResult);
- };
- var planeTrimesh_normal = new Vec3();
- var planeTrimesh_relpos = new Vec3();
- var planeTrimesh_projected = new Vec3();
- Narrowphase.prototype[Shape.types.PLANE | Shape.types.TRIMESH] =
- Narrowphase.prototype.planeTrimesh = function(
- planeShape,
- trimeshShape,
- planePos,
- trimeshPos,
- planeQuat,
- trimeshQuat,
- planeBody,
- trimeshBody,
- rsi,
- rsj,
- justTest
- ){
-
- var v = new Vec3();
- var normal = planeTrimesh_normal;
- normal.set(0,0,1);
- planeQuat.vmult(normal,normal);
- for(var i=0; i<trimeshShape.vertices.length / 3; i++){
-
- trimeshShape.getVertex(i, v);
-
- var v2 = new Vec3();
- v2.copy(v);
- Transform.pointToWorldFrame(trimeshPos, trimeshQuat, v2, v);
-
- var relpos = planeTrimesh_relpos;
- v.vsub(planePos, relpos);
- var dot = normal.dot(relpos);
- if(dot <= 0.0){
- if(justTest){
- return true;
- }
- var r = this.createContactEquation(planeBody,trimeshBody,planeShape,trimeshShape,rsi,rsj);
- r.ni.copy(normal);
-
- var projected = planeTrimesh_projected;
- normal.scale(relpos.dot(normal), projected);
- v.vsub(projected,projected);
-
- r.ri.copy(projected);
- r.ri.vsub(planeBody.position, r.ri);
- r.rj.copy(v);
- r.rj.vsub(trimeshBody.position, r.rj);
-
- this.result.push(r);
- this.createFrictionEquationsFromContact(r, this.frictionResult);
- }
- }
- };
- var sphereTrimesh_normal = new Vec3();
- var sphereTrimesh_relpos = new Vec3();
- var sphereTrimesh_projected = new Vec3();
- var sphereTrimesh_v = new Vec3();
- var sphereTrimesh_v2 = new Vec3();
- var sphereTrimesh_edgeVertexA = new Vec3();
- var sphereTrimesh_edgeVertexB = new Vec3();
- var sphereTrimesh_edgeVector = new Vec3();
- var sphereTrimesh_edgeVectorUnit = new Vec3();
- var sphereTrimesh_localSpherePos = new Vec3();
- var sphereTrimesh_tmp = new Vec3();
- var sphereTrimesh_va = new Vec3();
- var sphereTrimesh_vb = new Vec3();
- var sphereTrimesh_vc = new Vec3();
- var sphereTrimesh_localSphereAABB = new AABB();
- var sphereTrimesh_triangles = [];
- Narrowphase.prototype[Shape.types.SPHERE | Shape.types.TRIMESH] =
- Narrowphase.prototype.sphereTrimesh = function (
- sphereShape,
- trimeshShape,
- spherePos,
- trimeshPos,
- sphereQuat,
- trimeshQuat,
- sphereBody,
- trimeshBody,
- rsi,
- rsj,
- justTest
- ) {
- var edgeVertexA = sphereTrimesh_edgeVertexA;
- var edgeVertexB = sphereTrimesh_edgeVertexB;
- var edgeVector = sphereTrimesh_edgeVector;
- var edgeVectorUnit = sphereTrimesh_edgeVectorUnit;
- var localSpherePos = sphereTrimesh_localSpherePos;
- var tmp = sphereTrimesh_tmp;
- var localSphereAABB = sphereTrimesh_localSphereAABB;
- var v2 = sphereTrimesh_v2;
- var relpos = sphereTrimesh_relpos;
- var triangles = sphereTrimesh_triangles;
-
- Transform.pointToLocalFrame(trimeshPos, trimeshQuat, spherePos, localSpherePos);
-
- var sphereRadius = sphereShape.radius;
- localSphereAABB.lowerBound.set(
- localSpherePos.x - sphereRadius,
- localSpherePos.y - sphereRadius,
- localSpherePos.z - sphereRadius
- );
- localSphereAABB.upperBound.set(
- localSpherePos.x + sphereRadius,
- localSpherePos.y + sphereRadius,
- localSpherePos.z + sphereRadius
- );
- trimeshShape.getTrianglesInAABB(localSphereAABB, triangles);
-
-
- var v = sphereTrimesh_v;
- var radiusSquared = sphereShape.radius * sphereShape.radius;
- for(var i=0; i<triangles.length; i++){
- for (var j = 0; j < 3; j++) {
- trimeshShape.getVertex(trimeshShape.indices[triangles[i] * 3 + j], v);
-
- v.vsub(localSpherePos, relpos);
- if(relpos.norm2() <= radiusSquared){
-
- v2.copy(v);
- Transform.pointToWorldFrame(trimeshPos, trimeshQuat, v2, v);
- v.vsub(spherePos, relpos);
- if(justTest){
- return true;
- }
- var r = this.createContactEquation(sphereBody,trimeshBody,sphereShape,trimeshShape,rsi,rsj);
- r.ni.copy(relpos);
- r.ni.normalize();
-
- r.ri.copy(r.ni);
- r.ri.scale(sphereShape.radius, r.ri);
- r.ri.vadd(spherePos, r.ri);
- r.ri.vsub(sphereBody.position, r.ri);
- r.rj.copy(v);
- r.rj.vsub(trimeshBody.position, r.rj);
-
- this.result.push(r);
- this.createFrictionEquationsFromContact(r, this.frictionResult);
- }
- }
- }
-
- for(var i=0; i<triangles.length; i++){
- for (var j = 0; j < 3; j++) {
- trimeshShape.getVertex(trimeshShape.indices[triangles[i] * 3 + j], edgeVertexA);
- trimeshShape.getVertex(trimeshShape.indices[triangles[i] * 3 + ((j+1)%3)], edgeVertexB);
- edgeVertexB.vsub(edgeVertexA, edgeVector);
-
- localSpherePos.vsub(edgeVertexB, tmp);
- var positionAlongEdgeB = tmp.dot(edgeVector);
- localSpherePos.vsub(edgeVertexA, tmp);
- var positionAlongEdgeA = tmp.dot(edgeVector);
- if(positionAlongEdgeA > 0 && positionAlongEdgeB < 0){
-
- localSpherePos.vsub(edgeVertexA, tmp);
- edgeVectorUnit.copy(edgeVector);
- edgeVectorUnit.normalize();
- positionAlongEdgeA = tmp.dot(edgeVectorUnit);
- edgeVectorUnit.scale(positionAlongEdgeA, tmp);
- tmp.vadd(edgeVertexA, tmp);
-
- var dist = tmp.distanceTo(localSpherePos);
- if(dist < sphereShape.radius){
- if(justTest){
- return true;
- }
- var r = this.createContactEquation(sphereBody, trimeshBody, sphereShape, trimeshShape,rsi,rsj);
- tmp.vsub(localSpherePos, r.ni);
- r.ni.normalize();
- r.ni.scale(sphereShape.radius, r.ri);
- Transform.pointToWorldFrame(trimeshPos, trimeshQuat, tmp, tmp);
- tmp.vsub(trimeshBody.position, r.rj);
- Transform.vectorToWorldFrame(trimeshQuat, r.ni, r.ni);
- Transform.vectorToWorldFrame(trimeshQuat, r.ri, r.ri);
- this.result.push(r);
- this.createFrictionEquationsFromContact(r, this.frictionResult);
- }
- }
- }
- }
-
- var va = sphereTrimesh_va;
- var vb = sphereTrimesh_vb;
- var vc = sphereTrimesh_vc;
- var normal = sphereTrimesh_normal;
- for(var i=0, N = triangles.length; i !== N; i++){
- trimeshShape.getTriangleVertices(triangles[i], va, vb, vc);
- trimeshShape.getNormal(triangles[i], normal);
- localSpherePos.vsub(va, tmp);
- var dist = tmp.dot(normal);
- normal.scale(dist, tmp);
- localSpherePos.vsub(tmp, tmp);
-
- dist = tmp.distanceTo(localSpherePos);
- if(Ray.pointInTriangle(tmp, va, vb, vc) && dist < sphereShape.radius){
- if(justTest){
- return true;
- }
- var r = this.createContactEquation(sphereBody, trimeshBody, sphereShape, trimeshShape,rsi,rsj);
- tmp.vsub(localSpherePos, r.ni);
- r.ni.normalize();
- r.ni.scale(sphereShape.radius, r.ri);
- Transform.pointToWorldFrame(trimeshPos, trimeshQuat, tmp, tmp);
- tmp.vsub(trimeshBody.position, r.rj);
- Transform.vectorToWorldFrame(trimeshQuat, r.ni, r.ni);
- Transform.vectorToWorldFrame(trimeshQuat, r.ri, r.ri);
- this.result.push(r);
- this.createFrictionEquationsFromContact(r, this.frictionResult);
- }
- }
- triangles.length = 0;
- };
- var point_on_plane_to_sphere = new Vec3();
- var plane_to_sphere_ortho = new Vec3();
- Narrowphase.prototype[Shape.types.SPHERE | Shape.types.PLANE] =
- Narrowphase.prototype.spherePlane = function(si,sj,xi,xj,qi,qj,bi,bj,rsi,rsj,justTest){
-
- var r = this.createContactEquation(bi,bj,si,sj,rsi,rsj);
-
- r.ni.set(0,0,1);
- qj.vmult(r.ni, r.ni);
- r.ni.negate(r.ni);
- r.ni.normalize();
-
- r.ni.mult(si.radius, r.ri);
-
- xi.vsub(xj, point_on_plane_to_sphere);
- r.ni.mult(r.ni.dot(point_on_plane_to_sphere), plane_to_sphere_ortho);
- point_on_plane_to_sphere.vsub(plane_to_sphere_ortho,r.rj);
- if(-point_on_plane_to_sphere.dot(r.ni) <= si.radius){
- if(justTest){
- return true;
- }
-
- var ri = r.ri;
- var rj = r.rj;
- ri.vadd(xi, ri);
- ri.vsub(bi.position, ri);
- rj.vadd(xj, rj);
- rj.vsub(bj.position, rj);
- this.result.push(r);
- this.createFrictionEquationsFromContact(r, this.frictionResult);
- }
- };
- var pointInPolygon_edge = new Vec3();
- var pointInPolygon_edge_x_normal = new Vec3();
- var pointInPolygon_vtp = new Vec3();
- function pointInPolygon(verts, normal, p){
- var positiveResult = null;
- var N = verts.length;
- for(var i=0; i!==N; i++){
- var v = verts[i];
-
- var edge = pointInPolygon_edge;
- verts[(i+1) % (N)].vsub(v,edge);
-
- var edge_x_normal = pointInPolygon_edge_x_normal;
-
- edge.cross(normal,edge_x_normal);
-
- var vertex_to_p = pointInPolygon_vtp;
- p.vsub(v,vertex_to_p);
-
- var r = edge_x_normal.dot(vertex_to_p);
-
- if(positiveResult===null || (r>0 && positiveResult===true) || (r<=0 && positiveResult===false)){
- if(positiveResult===null){
- positiveResult = r>0;
- }
- continue;
- } else {
- return false;
- }
- }
-
- return true;
- }
- var box_to_sphere = new Vec3();
- var sphereBox_ns = new Vec3();
- var sphereBox_ns1 = new Vec3();
- var sphereBox_ns2 = new Vec3();
- var sphereBox_sides = [new Vec3(),new Vec3(),new Vec3(),new Vec3(),new Vec3(),new Vec3()];
- var sphereBox_sphere_to_corner = new Vec3();
- var sphereBox_side_ns = new Vec3();
- var sphereBox_side_ns1 = new Vec3();
- var sphereBox_side_ns2 = new Vec3();
- Narrowphase.prototype[Shape.types.SPHERE | Shape.types.BOX] =
- Narrowphase.prototype.sphereBox = function(si,sj,xi,xj,qi,qj,bi,bj,rsi,rsj,justTest){
- var v3pool = this.v3pool;
-
- var sides = sphereBox_sides;
- xi.vsub(xj,box_to_sphere);
- sj.getSideNormals(sides,qj);
- var R = si.radius;
- var penetrating_sides = [];
-
- var found = false;
-
- var side_ns = sphereBox_side_ns;
- var side_ns1 = sphereBox_side_ns1;
- var side_ns2 = sphereBox_side_ns2;
- var side_h = null;
- var side_penetrations = 0;
- var side_dot1 = 0;
- var side_dot2 = 0;
- var side_distance = null;
- for(var idx=0,nsides=sides.length; idx!==nsides && found===false; idx++){
-
- var ns = sphereBox_ns;
- ns.copy(sides[idx]);
- var h = ns.norm();
- ns.normalize();
-
- var dot = box_to_sphere.dot(ns);
- if(dot<h+R && dot>0){
-
- var ns1 = sphereBox_ns1;
- var ns2 = sphereBox_ns2;
- ns1.copy(sides[(idx+1)%3]);
- ns2.copy(sides[(idx+2)%3]);
- var h1 = ns1.norm();
- var h2 = ns2.norm();
- ns1.normalize();
- ns2.normalize();
- var dot1 = box_to_sphere.dot(ns1);
- var dot2 = box_to_sphere.dot(ns2);
- if(dot1<h1 && dot1>-h1 && dot2<h2 && dot2>-h2){
- var dist = Math.abs(dot-h-R);
- if(side_distance===null || dist < side_distance){
- side_distance = dist;
- side_dot1 = dot1;
- side_dot2 = dot2;
- side_h = h;
- side_ns.copy(ns);
- side_ns1.copy(ns1);
- side_ns2.copy(ns2);
- side_penetrations++;
- if(justTest){
- return true;
- }
- }
- }
- }
- }
- if(side_penetrations){
- found = true;
- var r = this.createContactEquation(bi,bj,si,sj,rsi,rsj);
- side_ns.mult(-R,r.ri);
- r.ni.copy(side_ns);
- r.ni.negate(r.ni);
- side_ns.mult(side_h,side_ns);
- side_ns1.mult(side_dot1,side_ns1);
- side_ns.vadd(side_ns1,side_ns);
- side_ns2.mult(side_dot2,side_ns2);
- side_ns.vadd(side_ns2,r.rj);
-
- r.ri.vadd(xi, r.ri);
- r.ri.vsub(bi.position, r.ri);
- r.rj.vadd(xj, r.rj);
- r.rj.vsub(bj.position, r.rj);
- this.result.push(r);
- this.createFrictionEquationsFromContact(r, this.frictionResult);
- }
-
- var rj = v3pool.get();
- var sphere_to_corner = sphereBox_sphere_to_corner;
- for(var j=0; j!==2 && !found; j++){
- for(var k=0; k!==2 && !found; k++){
- for(var l=0; l!==2 && !found; l++){
- rj.set(0,0,0);
- if(j){
- rj.vadd(sides[0],rj);
- } else {
- rj.vsub(sides[0],rj);
- }
- if(k){
- rj.vadd(sides[1],rj);
- } else {
- rj.vsub(sides[1],rj);
- }
- if(l){
- rj.vadd(sides[2],rj);
- } else {
- rj.vsub(sides[2],rj);
- }
-
- xj.vadd(rj,sphere_to_corner);
- sphere_to_corner.vsub(xi,sphere_to_corner);
- if(sphere_to_corner.norm2() < R*R){
- if(justTest){
- return true;
- }
- found = true;
- var r = this.createContactEquation(bi,bj,si,sj,rsi,rsj);
- r.ri.copy(sphere_to_corner);
- r.ri.normalize();
- r.ni.copy(r.ri);
- r.ri.mult(R,r.ri);
- r.rj.copy(rj);
-
- r.ri.vadd(xi, r.ri);
- r.ri.vsub(bi.position, r.ri);
- r.rj.vadd(xj, r.rj);
- r.rj.vsub(bj.position, r.rj);
- this.result.push(r);
- this.createFrictionEquationsFromContact(r, this.frictionResult);
- }
- }
- }
- }
- v3pool.release(rj);
- rj = null;
-
- var edgeTangent = v3pool.get();
- var edgeCenter = v3pool.get();
- var r = v3pool.get();
- var orthogonal = v3pool.get();
- var dist = v3pool.get();
- var Nsides = sides.length;
- for(var j=0; j!==Nsides && !found; j++){
- for(var k=0; k!==Nsides && !found; k++){
- if(j%3 !== k%3){
-
- sides[k].cross(sides[j],edgeTangent);
- edgeTangent.normalize();
- sides[j].vadd(sides[k], edgeCenter);
- r.copy(xi);
- r.vsub(edgeCenter,r);
- r.vsub(xj,r);
- var orthonorm = r.dot(edgeTangent);
- edgeTangent.mult(orthonorm,orthogonal);
-
- var l = 0;
- while(l===j%3 || l===k%3){
- l++;
- }
-
- dist.copy(xi);
- dist.vsub(orthogonal,dist);
- dist.vsub(edgeCenter,dist);
- dist.vsub(xj,dist);
-
- var tdist = Math.abs(orthonorm);
- var ndist = dist.norm();
- if(tdist < sides[l].norm() && ndist<R){
- if(justTest){
- return true;
- }
- found = true;
- var res = this.createContactEquation(bi,bj,si,sj,rsi,rsj);
- edgeCenter.vadd(orthogonal,res.rj);
- res.rj.copy(res.rj);
- dist.negate(res.ni);
- res.ni.normalize();
- res.ri.copy(res.rj);
- res.ri.vadd(xj,res.ri);
- res.ri.vsub(xi,res.ri);
- res.ri.normalize();
- res.ri.mult(R,res.ri);
-
- res.ri.vadd(xi, res.ri);
- res.ri.vsub(bi.position, res.ri);
- res.rj.vadd(xj, res.rj);
- res.rj.vsub(bj.position, res.rj);
- this.result.push(res);
- this.createFrictionEquationsFromContact(res, this.frictionResult);
- }
- }
- }
- }
- v3pool.release(edgeTangent,edgeCenter,r,orthogonal,dist);
- };
- var convex_to_sphere = new Vec3();
- var sphereConvex_edge = new Vec3();
- var sphereConvex_edgeUnit = new Vec3();
- var sphereConvex_sphereToCorner = new Vec3();
- var sphereConvex_worldCorner = new Vec3();
- var sphereConvex_worldNormal = new Vec3();
- var sphereConvex_worldPoint = new Vec3();
- var sphereConvex_worldSpherePointClosestToPlane = new Vec3();
- var sphereConvex_penetrationVec = new Vec3();
- var sphereConvex_sphereToWorldPoint = new Vec3();
- Narrowphase.prototype[Shape.types.SPHERE | Shape.types.CONVEXPOLYHEDRON] =
- Narrowphase.prototype.sphereConvex = function(si,sj,xi,xj,qi,qj,bi,bj,rsi,rsj,justTest){
- var v3pool = this.v3pool;
- xi.vsub(xj,convex_to_sphere);
- var normals = sj.faceNormals;
- var faces = sj.faces;
- var verts = sj.vertices;
- var R = si.radius;
- var penetrating_sides = [];
-
-
-
-
- for(var i=0; i!==verts.length; i++){
- var v = verts[i];
-
- var worldCorner = sphereConvex_worldCorner;
- qj.vmult(v,worldCorner);
- xj.vadd(worldCorner,worldCorner);
- var sphere_to_corner = sphereConvex_sphereToCorner;
- worldCorner.vsub(xi, sphere_to_corner);
- if(sphere_to_corner.norm2() < R * R){
- if(justTest){
- return true;
- }
- found = true;
- var r = this.createContactEquation(bi,bj,si,sj,rsi,rsj);
- r.ri.copy(sphere_to_corner);
- r.ri.normalize();
- r.ni.copy(r.ri);
- r.ri.mult(R,r.ri);
- worldCorner.vsub(xj,r.rj);
-
- r.ri.vadd(xi, r.ri);
- r.ri.vsub(bi.position, r.ri);
-
- r.rj.vadd(xj, r.rj);
- r.rj.vsub(bj.position, r.rj);
- this.result.push(r);
- this.createFrictionEquationsFromContact(r, this.frictionResult);
- return;
- }
- }
-
- var found = false;
- for(var i=0, nfaces=faces.length; i!==nfaces && found===false; i++){
- var normal = normals[i];
- var face = faces[i];
-
- var worldNormal = sphereConvex_worldNormal;
- qj.vmult(normal,worldNormal);
-
- var worldPoint = sphereConvex_worldPoint;
- qj.vmult(verts[face[0]],worldPoint);
- worldPoint.vadd(xj,worldPoint);
-
- var worldSpherePointClosestToPlane = sphereConvex_worldSpherePointClosestToPlane;
- worldNormal.mult(-R, worldSpherePointClosestToPlane);
- xi.vadd(worldSpherePointClosestToPlane, worldSpherePointClosestToPlane);
-
- var penetrationVec = sphereConvex_penetrationVec;
- worldSpherePointClosestToPlane.vsub(worldPoint,penetrationVec);
-
- var penetration = penetrationVec.dot(worldNormal);
- var worldPointToSphere = sphereConvex_sphereToWorldPoint;
- xi.vsub(worldPoint, worldPointToSphere);
- if(penetration < 0 && worldPointToSphere.dot(worldNormal)>0){
-
- var faceVerts = [];
- for(var j=0, Nverts=face.length; j!==Nverts; j++){
- var worldVertex = v3pool.get();
- qj.vmult(verts[face[j]], worldVertex);
- xj.vadd(worldVertex,worldVertex);
- faceVerts.push(worldVertex);
- }
- if(pointInPolygon(faceVerts,worldNormal,xi)){
- if(justTest){
- return true;
- }
- found = true;
- var r = this.createContactEquation(bi,bj,si,sj,rsi,rsj);
- worldNormal.mult(-R, r.ri);
- worldNormal.negate(r.ni);
- var penetrationVec2 = v3pool.get();
- worldNormal.mult(-penetration, penetrationVec2);
- var penetrationSpherePoint = v3pool.get();
- worldNormal.mult(-R, penetrationSpherePoint);
-
- xi.vsub(xj,r.rj);
- r.rj.vadd(penetrationSpherePoint,r.rj);
- r.rj.vadd(penetrationVec2 , r.rj);
-
- r.rj.vadd(xj, r.rj);
- r.rj.vsub(bj.position, r.rj);
-
- r.ri.vadd(xi, r.ri);
- r.ri.vsub(bi.position, r.ri);
- v3pool.release(penetrationVec2);
- v3pool.release(penetrationSpherePoint);
- this.result.push(r);
- this.createFrictionEquationsFromContact(r, this.frictionResult);
-
- for(var j=0, Nfaceverts=faceVerts.length; j!==Nfaceverts; j++){
- v3pool.release(faceVerts[j]);
- }
- return;
- } else {
-
- for(var j=0; j!==face.length; j++){
-
- var v1 = v3pool.get();
- var v2 = v3pool.get();
- qj.vmult(verts[face[(j+1)%face.length]], v1);
- qj.vmult(verts[face[(j+2)%face.length]], v2);
- xj.vadd(v1, v1);
- xj.vadd(v2, v2);
-
- var edge = sphereConvex_edge;
- v2.vsub(v1,edge);
-
- var edgeUnit = sphereConvex_edgeUnit;
- edge.unit(edgeUnit);
-
- var p = v3pool.get();
- var v1_to_xi = v3pool.get();
- xi.vsub(v1, v1_to_xi);
- var dot = v1_to_xi.dot(edgeUnit);
- edgeUnit.mult(dot, p);
- p.vadd(v1, p);
-
- var xi_to_p = v3pool.get();
- p.vsub(xi, xi_to_p);
-
-
- if(dot > 0 && dot*dot<edge.norm2() && xi_to_p.norm2() < R*R){
-
- if(justTest){
- return true;
- }
- var r = this.createContactEquation(bi,bj,si,sj,rsi,rsj);
- p.vsub(xj,r.rj);
- p.vsub(xi,r.ni);
- r.ni.normalize();
- r.ni.mult(R,r.ri);
-
- r.rj.vadd(xj, r.rj);
- r.rj.vsub(bj.position, r.rj);
-
- r.ri.vadd(xi, r.ri);
- r.ri.vsub(bi.position, r.ri);
- this.result.push(r);
- this.createFrictionEquationsFromContact(r, this.frictionResult);
-
- for(var j=0, Nfaceverts=faceVerts.length; j!==Nfaceverts; j++){
- v3pool.release(faceVerts[j]);
- }
- v3pool.release(v1);
- v3pool.release(v2);
- v3pool.release(p);
- v3pool.release(xi_to_p);
- v3pool.release(v1_to_xi);
- return;
- }
- v3pool.release(v1);
- v3pool.release(v2);
- v3pool.release(p);
- v3pool.release(xi_to_p);
- v3pool.release(v1_to_xi);
- }
- }
-
- for(var j=0, Nfaceverts=faceVerts.length; j!==Nfaceverts; j++){
- v3pool.release(faceVerts[j]);
- }
- }
- }
- };
- var planeBox_normal = new Vec3();
- var plane_to_corner = new Vec3();
- Narrowphase.prototype[Shape.types.PLANE | Shape.types.BOX] =
- Narrowphase.prototype.planeBox = function(si,sj,xi,xj,qi,qj,bi,bj,rsi,rsj,justTest){
- sj.convexPolyhedronRepresentation.material = sj.material;
- sj.convexPolyhedronRepresentation.collisionResponse = sj.collisionResponse;
- sj.convexPolyhedronRepresentation.id = sj.id;
- return this.planeConvex(si,sj.convexPolyhedronRepresentation,xi,xj,qi,qj,bi,bj,si,sj,justTest);
- };
- var planeConvex_v = new Vec3();
- var planeConvex_normal = new Vec3();
- var planeConvex_relpos = new Vec3();
- var planeConvex_projected = new Vec3();
- Narrowphase.prototype[Shape.types.PLANE | Shape.types.CONVEXPOLYHEDRON] =
- Narrowphase.prototype.planeConvex = function(
- planeShape,
- convexShape,
- planePosition,
- convexPosition,
- planeQuat,
- convexQuat,
- planeBody,
- convexBody,
- si,
- sj,
- justTest
- ){
-
- var worldVertex = planeConvex_v,
- worldNormal = planeConvex_normal;
- worldNormal.set(0,0,1);
- planeQuat.vmult(worldNormal,worldNormal);
- var numContacts = 0;
- var relpos = planeConvex_relpos;
- for(var i = 0; i !== convexShape.vertices.length; i++){
-
- worldVertex.copy(convexShape.vertices[i]);
- convexQuat.vmult(worldVertex, worldVertex);
- convexPosition.vadd(worldVertex, worldVertex);
- worldVertex.vsub(planePosition, relpos);
- var dot = worldNormal.dot(relpos);
- if(dot <= 0.0){
- if(justTest){
- return true;
- }
- var r = this.createContactEquation(planeBody, convexBody, planeShape, convexShape, si, sj);
-
- var projected = planeConvex_projected;
- worldNormal.mult(worldNormal.dot(relpos),projected);
- worldVertex.vsub(projected, projected);
- projected.vsub(planePosition, r.ri);
- r.ni.copy(worldNormal);
-
- worldVertex.vsub(convexPosition, r.rj);
-
- r.ri.vadd(planePosition, r.ri);
- r.ri.vsub(planeBody.position, r.ri);
- r.rj.vadd(convexPosition, r.rj);
- r.rj.vsub(convexBody.position, r.rj);
- this.result.push(r);
- numContacts++;
- if(!this.enableFrictionReduction){
- this.createFrictionEquationsFromContact(r, this.frictionResult);
- }
- }
- }
- if(this.enableFrictionReduction && numContacts){
- this.createFrictionFromAverage(numContacts);
- }
- };
- var convexConvex_sepAxis = new Vec3();
- var convexConvex_q = new Vec3();
- Narrowphase.prototype[Shape.types.CONVEXPOLYHEDRON] =
- Narrowphase.prototype.convexConvex = function(si,sj,xi,xj,qi,qj,bi,bj,rsi,rsj,justTest,faceListA,faceListB){
- var sepAxis = convexConvex_sepAxis;
- if(xi.distanceTo(xj) > si.boundingSphereRadius + sj.boundingSphereRadius){
- return;
- }
- if(si.findSeparatingAxis(sj,xi,qi,xj,qj,sepAxis,faceListA,faceListB)){
- var res = [];
- var q = convexConvex_q;
- si.clipAgainstHull(xi,qi,sj,xj,qj,sepAxis,-100,100,res);
- var numContacts = 0;
- for(var j = 0; j !== res.length; j++){
- if(justTest){
- return true;
- }
- var r = this.createContactEquation(bi,bj,si,sj,rsi,rsj),
- ri = r.ri,
- rj = r.rj;
- sepAxis.negate(r.ni);
- res[j].normal.negate(q);
- q.mult(res[j].depth, q);
- res[j].point.vadd(q, ri);
- rj.copy(res[j].point);
-
- ri.vsub(xi,ri);
- rj.vsub(xj,rj);
-
- ri.vadd(xi, ri);
- ri.vsub(bi.position, ri);
- rj.vadd(xj, rj);
- rj.vsub(bj.position, rj);
- this.result.push(r);
- numContacts++;
- if(!this.enableFrictionReduction){
- this.createFrictionEquationsFromContact(r, this.frictionResult);
- }
- }
- if(this.enableFrictionReduction && numContacts){
- this.createFrictionFromAverage(numContacts);
- }
- }
- };
- var particlePlane_normal = new Vec3();
- var particlePlane_relpos = new Vec3();
- var particlePlane_projected = new Vec3();
- Narrowphase.prototype[Shape.types.PLANE | Shape.types.PARTICLE] =
- Narrowphase.prototype.planeParticle = function(sj,si,xj,xi,qj,qi,bj,bi,rsi,rsj,justTest){
- var normal = particlePlane_normal;
- normal.set(0,0,1);
- bj.quaternion.vmult(normal,normal);
- var relpos = particlePlane_relpos;
- xi.vsub(bj.position,relpos);
- var dot = normal.dot(relpos);
- if(dot <= 0.0){
- if(justTest){
- return true;
- }
- var r = this.createContactEquation(bi,bj,si,sj,rsi,rsj);
- r.ni.copy(normal);
- r.ni.negate(r.ni);
- r.ri.set(0,0,0);
-
- var projected = particlePlane_projected;
- normal.mult(normal.dot(xi),projected);
- xi.vsub(projected,projected);
-
-
- r.rj.copy(projected);
- this.result.push(r);
- this.createFrictionEquationsFromContact(r, this.frictionResult);
- }
- };
- var particleSphere_normal = new Vec3();
- Narrowphase.prototype[Shape.types.PARTICLE | Shape.types.SPHERE] =
- Narrowphase.prototype.sphereParticle = function(sj,si,xj,xi,qj,qi,bj,bi,rsi,rsj,justTest){
-
- var normal = particleSphere_normal;
- normal.set(0,0,1);
- xi.vsub(xj,normal);
- var lengthSquared = normal.norm2();
- if(lengthSquared <= sj.radius * sj.radius){
- if(justTest){
- return true;
- }
- var r = this.createContactEquation(bi,bj,si,sj,rsi,rsj);
- normal.normalize();
- r.rj.copy(normal);
- r.rj.mult(sj.radius,r.rj);
- r.ni.copy(normal);
- r.ni.negate(r.ni);
- r.ri.set(0,0,0);
- this.result.push(r);
- this.createFrictionEquationsFromContact(r, this.frictionResult);
- }
- };
- var cqj = new Quaternion();
- var convexParticle_local = new Vec3();
- var convexParticle_normal = new Vec3();
- var convexParticle_penetratedFaceNormal = new Vec3();
- var convexParticle_vertexToParticle = new Vec3();
- var convexParticle_worldPenetrationVec = new Vec3();
- Narrowphase.prototype[Shape.types.PARTICLE | Shape.types.CONVEXPOLYHEDRON] =
- Narrowphase.prototype.convexParticle = function(sj,si,xj,xi,qj,qi,bj,bi,rsi,rsj,justTest){
- var penetratedFaceIndex = -1;
- var penetratedFaceNormal = convexParticle_penetratedFaceNormal;
- var worldPenetrationVec = convexParticle_worldPenetrationVec;
- var minPenetration = null;
- var numDetectedFaces = 0;
-
- var local = convexParticle_local;
- local.copy(xi);
- local.vsub(xj,local);
- qj.conjugate(cqj);
- cqj.vmult(local,local);
- if(sj.pointIsInside(local)){
- if(sj.worldVerticesNeedsUpdate){
- sj.computeWorldVertices(xj,qj);
- }
- if(sj.worldFaceNormalsNeedsUpdate){
- sj.computeWorldFaceNormals(qj);
- }
-
- for(var i=0,nfaces=sj.faces.length; i!==nfaces; i++){
-
- var verts = [ sj.worldVertices[ sj.faces[i][0] ] ];
- var normal = sj.worldFaceNormals[i];
-
- xi.vsub(verts[0],convexParticle_vertexToParticle);
- var penetration = -normal.dot(convexParticle_vertexToParticle);
- if(minPenetration===null || Math.abs(penetration)<Math.abs(minPenetration)){
- if(justTest){
- return true;
- }
- minPenetration = penetration;
- penetratedFaceIndex = i;
- penetratedFaceNormal.copy(normal);
- numDetectedFaces++;
- }
- }
- if(penetratedFaceIndex!==-1){
-
- var r = this.createContactEquation(bi,bj,si,sj,rsi,rsj);
- penetratedFaceNormal.mult(minPenetration, worldPenetrationVec);
-
- worldPenetrationVec.vadd(xi,worldPenetrationVec);
- worldPenetrationVec.vsub(xj,worldPenetrationVec);
- r.rj.copy(worldPenetrationVec);
-
-
-
- penetratedFaceNormal.negate( r.ni );
- r.ri.set(0,0,0);
- var ri = r.ri,
- rj = r.rj;
-
- ri.vadd(xi, ri);
- ri.vsub(bi.position, ri);
- rj.vadd(xj, rj);
- rj.vsub(bj.position, rj);
- this.result.push(r);
- this.createFrictionEquationsFromContact(r, this.frictionResult);
- } else {
- console.warn("Point found inside convex, but did not find penetrating face!");
- }
- }
- };
- Narrowphase.prototype[Shape.types.BOX | Shape.types.HEIGHTFIELD] =
- Narrowphase.prototype.boxHeightfield = function (si,sj,xi,xj,qi,qj,bi,bj,rsi,rsj,justTest){
- si.convexPolyhedronRepresentation.material = si.material;
- si.convexPolyhedronRepresentation.collisionResponse = si.collisionResponse;
- return this.convexHeightfield(si.convexPolyhedronRepresentation,sj,xi,xj,qi,qj,bi,bj,si,sj,justTest);
- };
- var convexHeightfield_tmp1 = new Vec3();
- var convexHeightfield_tmp2 = new Vec3();
- var convexHeightfield_faceList = [0];
- Narrowphase.prototype[Shape.types.CONVEXPOLYHEDRON | Shape.types.HEIGHTFIELD] =
- Narrowphase.prototype.convexHeightfield = function (
- convexShape,
- hfShape,
- convexPos,
- hfPos,
- convexQuat,
- hfQuat,
- convexBody,
- hfBody,
- rsi,
- rsj,
- justTest
- ){
- var data = hfShape.data,
- w = hfShape.elementSize,
- radius = convexShape.boundingSphereRadius,
- worldPillarOffset = convexHeightfield_tmp2,
- faceList = convexHeightfield_faceList;
-
- var localConvexPos = convexHeightfield_tmp1;
- Transform.pointToLocalFrame(hfPos, hfQuat, convexPos, localConvexPos);
-
- var iMinX = Math.floor((localConvexPos.x - radius) / w) - 1,
- iMaxX = Math.ceil((localConvexPos.x + radius) / w) + 1,
- iMinY = Math.floor((localConvexPos.y - radius) / w) - 1,
- iMaxY = Math.ceil((localConvexPos.y + radius) / w) + 1;
-
- if(iMaxX < 0 || iMaxY < 0 || iMinX > data.length || iMinY > data[0].length){
- return;
- }
-
- if(iMinX < 0){ iMinX = 0; }
- if(iMaxX < 0){ iMaxX = 0; }
- if(iMinY < 0){ iMinY = 0; }
- if(iMaxY < 0){ iMaxY = 0; }
- if(iMinX >= data.length){ iMinX = data.length - 1; }
- if(iMaxX >= data.length){ iMaxX = data.length - 1; }
- if(iMaxY >= data[0].length){ iMaxY = data[0].length - 1; }
- if(iMinY >= data[0].length){ iMinY = data[0].length - 1; }
- var minMax = [];
- hfShape.getRectMinMax(iMinX, iMinY, iMaxX, iMaxY, minMax);
- var min = minMax[0];
- var max = minMax[1];
-
- if(localConvexPos.z - radius > max || localConvexPos.z + radius < min){
- return;
- }
- for(var i = iMinX; i < iMaxX; i++){
- for(var j = iMinY; j < iMaxY; j++){
- var intersecting = false;
-
- hfShape.getConvexTrianglePillar(i, j, false);
- Transform.pointToWorldFrame(hfPos, hfQuat, hfShape.pillarOffset, worldPillarOffset);
- if (convexPos.distanceTo(worldPillarOffset) < hfShape.pillarConvex.boundingSphereRadius + convexShape.boundingSphereRadius) {
- intersecting = this.convexConvex(convexShape, hfShape.pillarConvex, convexPos, worldPillarOffset, convexQuat, hfQuat, convexBody, hfBody, null, null, justTest, faceList, null);
- }
- if(justTest && intersecting){
- return true;
- }
-
- hfShape.getConvexTrianglePillar(i, j, true);
- Transform.pointToWorldFrame(hfPos, hfQuat, hfShape.pillarOffset, worldPillarOffset);
- if (convexPos.distanceTo(worldPillarOffset) < hfShape.pillarConvex.boundingSphereRadius + convexShape.boundingSphereRadius) {
- intersecting = this.convexConvex(convexShape, hfShape.pillarConvex, convexPos, worldPillarOffset, convexQuat, hfQuat, convexBody, hfBody, null, null, justTest, faceList, null);
- }
- if(justTest && intersecting){
- return true;
- }
- }
- }
- };
- var sphereHeightfield_tmp1 = new Vec3();
- var sphereHeightfield_tmp2 = new Vec3();
- Narrowphase.prototype[Shape.types.SPHERE | Shape.types.HEIGHTFIELD] =
- Narrowphase.prototype.sphereHeightfield = function (
- sphereShape,
- hfShape,
- spherePos,
- hfPos,
- sphereQuat,
- hfQuat,
- sphereBody,
- hfBody,
- rsi,
- rsj,
- justTest
- ){
- var data = hfShape.data,
- radius = sphereShape.radius,
- w = hfShape.elementSize,
- worldPillarOffset = sphereHeightfield_tmp2;
-
- var localSpherePos = sphereHeightfield_tmp1;
- Transform.pointToLocalFrame(hfPos, hfQuat, spherePos, localSpherePos);
-
- var iMinX = Math.floor((localSpherePos.x - radius) / w) - 1,
- iMaxX = Math.ceil((localSpherePos.x + radius) / w) + 1,
- iMinY = Math.floor((localSpherePos.y - radius) / w) - 1,
- iMaxY = Math.ceil((localSpherePos.y + radius) / w) + 1;
-
- if(iMaxX < 0 || iMaxY < 0 || iMinX > data.length || iMaxY > data[0].length){
- return;
- }
-
- if(iMinX < 0){ iMinX = 0; }
- if(iMaxX < 0){ iMaxX = 0; }
- if(iMinY < 0){ iMinY = 0; }
- if(iMaxY < 0){ iMaxY = 0; }
- if(iMinX >= data.length){ iMinX = data.length - 1; }
- if(iMaxX >= data.length){ iMaxX = data.length - 1; }
- if(iMaxY >= data[0].length){ iMaxY = data[0].length - 1; }
- if(iMinY >= data[0].length){ iMinY = data[0].length - 1; }
- var minMax = [];
- hfShape.getRectMinMax(iMinX, iMinY, iMaxX, iMaxY, minMax);
- var min = minMax[0];
- var max = minMax[1];
-
- if(localSpherePos.z - radius > max || localSpherePos.z + radius < min){
- return;
- }
- var result = this.result;
- for(var i = iMinX; i < iMaxX; i++){
- for(var j = iMinY; j < iMaxY; j++){
- var numContactsBefore = result.length;
- var intersecting = false;
-
- hfShape.getConvexTrianglePillar(i, j, false);
- Transform.pointToWorldFrame(hfPos, hfQuat, hfShape.pillarOffset, worldPillarOffset);
- if (spherePos.distanceTo(worldPillarOffset) < hfShape.pillarConvex.boundingSphereRadius + sphereShape.boundingSphereRadius) {
- intersecting = this.sphereConvex(sphereShape, hfShape.pillarConvex, spherePos, worldPillarOffset, sphereQuat, hfQuat, sphereBody, hfBody, sphereShape, hfShape, justTest);
- }
- if(justTest && intersecting){
- return true;
- }
-
- hfShape.getConvexTrianglePillar(i, j, true);
- Transform.pointToWorldFrame(hfPos, hfQuat, hfShape.pillarOffset, worldPillarOffset);
- if (spherePos.distanceTo(worldPillarOffset) < hfShape.pillarConvex.boundingSphereRadius + sphereShape.boundingSphereRadius) {
- intersecting = this.sphereConvex(sphereShape, hfShape.pillarConvex, spherePos, worldPillarOffset, sphereQuat, hfQuat, sphereBody, hfBody, sphereShape, hfShape, justTest);
- }
- if(justTest && intersecting){
- return true;
- }
- var numContacts = result.length - numContactsBefore;
- if(numContacts > 2){
- return;
- }
-
- }
- }
- };
- },{"../collision/AABB":18,"../collision/Ray":25,"../equations/ContactEquation":35,"../equations/FrictionEquation":37,"../math/Quaternion":44,"../math/Transform":45,"../math/Vec3":46,"../objects/Body":47,"../shapes/ConvexPolyhedron":54,"../shapes/Shape":59,"../solver/Solver":63,"../utils/Vec3Pool":70}],72:[function(require,module,exports){
- module.exports = World;
- var Shape = require('../shapes/Shape');
- var Vec3 = require('../math/Vec3');
- var Quaternion = require('../math/Quaternion');
- var GSSolver = require('../solver/GSSolver');
- var ContactEquation = require('../equations/ContactEquation');
- var FrictionEquation = require('../equations/FrictionEquation');
- var Narrowphase = require('./Narrowphase');
- var EventTarget = require('../utils/EventTarget');
- var ArrayCollisionMatrix = require('../collision/ArrayCollisionMatrix');
- var OverlapKeeper = require('../collision/OverlapKeeper');
- var Material = require('../material/Material');
- var ContactMaterial = require('../material/ContactMaterial');
- var Body = require('../objects/Body');
- var TupleDictionary = require('../utils/TupleDictionary');
- var RaycastResult = require('../collision/RaycastResult');
- var AABB = require('../collision/AABB');
- var Ray = require('../collision/Ray');
- var NaiveBroadphase = require('../collision/NaiveBroadphase');
- function World(options){
- options = options || {};
- EventTarget.apply(this);
-
- this.dt = -1;
-
- this.allowSleep = !!options.allowSleep;
-
- this.contacts = [];
- this.frictionEquations = [];
-
- this.quatNormalizeSkip = options.quatNormalizeSkip !== undefined ? options.quatNormalizeSkip : 0;
-
- this.quatNormalizeFast = options.quatNormalizeFast !== undefined ? options.quatNormalizeFast : false;
-
- this.time = 0.0;
-
- this.stepnumber = 0;
-
- this.default_dt = 1/60;
- this.nextId = 0;
-
- this.gravity = new Vec3();
- if(options.gravity){
- this.gravity.copy(options.gravity);
- }
-
- this.broadphase = options.broadphase !== undefined ? options.broadphase : new NaiveBroadphase();
-
- this.bodies = [];
-
- this.solver = options.solver !== undefined ? options.solver : new GSSolver();
-
- this.constraints = [];
-
- this.narrowphase = new Narrowphase(this);
-
- this.collisionMatrix = new ArrayCollisionMatrix();
-
- this.collisionMatrixPrevious = new ArrayCollisionMatrix();
- this.bodyOverlapKeeper = new OverlapKeeper();
- this.shapeOverlapKeeper = new OverlapKeeper();
-
- this.materials = [];
-
- this.contactmaterials = [];
-
- this.contactMaterialTable = new TupleDictionary();
- this.defaultMaterial = new Material("default");
-
- this.defaultContactMaterial = new ContactMaterial(this.defaultMaterial, this.defaultMaterial, { friction: 0.3, restitution: 0.0 });
-
- this.doProfiling = false;
-
- this.profile = {
- solve:0,
- makeContactConstraints:0,
- broadphase:0,
- integrate:0,
- narrowphase:0,
- };
-
- this.accumulator = 0;
-
- this.subsystems = [];
-
- this.addBodyEvent = {
- type:"addBody",
- body : null
- };
-
- this.removeBodyEvent = {
- type:"removeBody",
- body : null
- };
- this.idToBodyMap = {};
- this.broadphase.setWorld(this);
- }
- World.prototype = new EventTarget();
- var tmpAABB1 = new AABB();
- var tmpArray1 = [];
- var tmpRay = new Ray();
- World.prototype.getContactMaterial = function(m1,m2){
- return this.contactMaterialTable.get(m1.id,m2.id);
- };
- World.prototype.numObjects = function(){
- return this.bodies.length;
- };
- World.prototype.collisionMatrixTick = function(){
- var temp = this.collisionMatrixPrevious;
- this.collisionMatrixPrevious = this.collisionMatrix;
- this.collisionMatrix = temp;
- this.collisionMatrix.reset();
- this.bodyOverlapKeeper.tick();
- this.shapeOverlapKeeper.tick();
- };
- World.prototype.add = World.prototype.addBody = function(body){
- if(this.bodies.indexOf(body) !== -1){
- return;
- }
- body.index = this.bodies.length;
- this.bodies.push(body);
- body.world = this;
- body.initPosition.copy(body.position);
- body.initVelocity.copy(body.velocity);
- body.timeLastSleepy = this.time;
- if(body instanceof Body){
- body.initAngularVelocity.copy(body.angularVelocity);
- body.initQuaternion.copy(body.quaternion);
- }
- this.collisionMatrix.setNumObjects(this.bodies.length);
- this.addBodyEvent.body = body;
- this.idToBodyMap[body.id] = body;
- this.dispatchEvent(this.addBodyEvent);
- };
- World.prototype.addConstraint = function(c){
- this.constraints.push(c);
- };
- World.prototype.removeConstraint = function(c){
- var idx = this.constraints.indexOf(c);
- if(idx!==-1){
- this.constraints.splice(idx,1);
- }
- };
- World.prototype.rayTest = function(from, to, result){
- if(result instanceof RaycastResult){
-
- this.raycastClosest(from, to, {
- skipBackfaces: true
- }, result);
- } else {
-
- this.raycastAll(from, to, {
- skipBackfaces: true
- }, result);
- }
- };
- World.prototype.raycastAll = function(from, to, options, callback){
- options.mode = Ray.ALL;
- options.from = from;
- options.to = to;
- options.callback = callback;
- return tmpRay.intersectWorld(this, options);
- };
- World.prototype.raycastAny = function(from, to, options, result){
- options.mode = Ray.ANY;
- options.from = from;
- options.to = to;
- options.result = result;
- return tmpRay.intersectWorld(this, options);
- };
- World.prototype.raycastClosest = function(from, to, options, result){
- options.mode = Ray.CLOSEST;
- options.from = from;
- options.to = to;
- options.result = result;
- return tmpRay.intersectWorld(this, options);
- };
- World.prototype.remove = function(body){
- body.world = null;
- var n = this.bodies.length - 1,
- bodies = this.bodies,
- idx = bodies.indexOf(body);
- if(idx !== -1){
- bodies.splice(idx, 1);
-
- for(var i=0; i!==bodies.length; i++){
- bodies[i].index = i;
- }
- this.collisionMatrix.setNumObjects(n);
- this.removeBodyEvent.body = body;
- delete this.idToBodyMap[body.id];
- this.dispatchEvent(this.removeBodyEvent);
- }
- };
- World.prototype.removeBody = World.prototype.remove;
- World.prototype.getBodyById = function(id){
- return this.idToBodyMap[id];
- };
- World.prototype.getShapeById = function(id){
- var bodies = this.bodies;
- for(var i=0, bl = bodies.length; i<bl; i++){
- var shapes = bodies[i].shapes;
- for (var j = 0, sl = shapes.length; j < sl; j++) {
- var shape = shapes[j];
- if(shape.id === id){
- return shape;
- }
- }
- }
- };
- World.prototype.addMaterial = function(m){
- this.materials.push(m);
- };
- World.prototype.addContactMaterial = function(cmat) {
-
- this.contactmaterials.push(cmat);
-
- this.contactMaterialTable.set(cmat.materials[0].id,cmat.materials[1].id,cmat);
- };
- if(typeof performance === 'undefined'){
- performance = {};
- }
- if(!performance.now){
- var nowOffset = Date.now();
- if (performance.timing && performance.timing.navigationStart){
- nowOffset = performance.timing.navigationStart;
- }
- performance.now = function(){
- return Date.now() - nowOffset;
- };
- }
- var step_tmp1 = new Vec3();
- World.prototype.step = function(dt, timeSinceLastCalled, maxSubSteps){
- maxSubSteps = maxSubSteps || 10;
- timeSinceLastCalled = timeSinceLastCalled || 0;
- if(timeSinceLastCalled === 0){
- this.internalStep(dt);
-
- this.time += dt;
- } else {
- this.accumulator += timeSinceLastCalled;
- var substeps = 0;
- while (this.accumulator >= dt && substeps < maxSubSteps) {
-
- this.internalStep(dt);
- this.accumulator -= dt;
- substeps++;
- }
- var t = (this.accumulator % dt) / dt;
- for(var j=0; j !== this.bodies.length; j++){
- var b = this.bodies[j];
- b.previousPosition.lerp(b.position, t, b.interpolatedPosition);
- b.previousQuaternion.slerp(b.quaternion, t, b.interpolatedQuaternion);
- b.previousQuaternion.normalize();
- }
- this.time += timeSinceLastCalled;
- }
- };
- var
-
- World_step_postStepEvent = {type:"postStep"},
-
- World_step_preStepEvent = {type:"preStep"},
- World_step_collideEvent = {type:Body.COLLIDE_EVENT_NAME, body:null, contact:null },
- World_step_oldContacts = [],
- World_step_frictionEquationPool = [],
- World_step_p1 = [],
- World_step_p2 = [],
- World_step_gvec = new Vec3(),
- World_step_vi = new Vec3(),
- World_step_vj = new Vec3(),
- World_step_wi = new Vec3(),
- World_step_wj = new Vec3(),
- World_step_t1 = new Vec3(),
- World_step_t2 = new Vec3(),
- World_step_rixn = new Vec3(),
- World_step_rjxn = new Vec3(),
- World_step_step_q = new Quaternion(),
- World_step_step_w = new Quaternion(),
- World_step_step_wq = new Quaternion(),
- invI_tau_dt = new Vec3();
- World.prototype.internalStep = function(dt){
- this.dt = dt;
- var world = this,
- that = this,
- contacts = this.contacts,
- p1 = World_step_p1,
- p2 = World_step_p2,
- N = this.numObjects(),
- bodies = this.bodies,
- solver = this.solver,
- gravity = this.gravity,
- doProfiling = this.doProfiling,
- profile = this.profile,
- DYNAMIC = Body.DYNAMIC,
- profilingStart,
- constraints = this.constraints,
- frictionEquationPool = World_step_frictionEquationPool,
- gnorm = gravity.norm(),
- gx = gravity.x,
- gy = gravity.y,
- gz = gravity.z,
- i=0;
- if(doProfiling){
- profilingStart = performance.now();
- }
-
- for(i=0; i!==N; i++){
- var bi = bodies[i];
- if(bi.type === DYNAMIC){
- var f = bi.force, m = bi.mass;
- f.x += m*gx;
- f.y += m*gy;
- f.z += m*gz;
- }
- }
-
- for(var i=0, Nsubsystems=this.subsystems.length; i!==Nsubsystems; i++){
- this.subsystems[i].update();
- }
-
- if(doProfiling){ profilingStart = performance.now(); }
- p1.length = 0;
- p2.length = 0;
- this.broadphase.collisionPairs(this,p1,p2);
- if(doProfiling){ profile.broadphase = performance.now() - profilingStart; }
-
- var Nconstraints = constraints.length;
- for(i=0; i!==Nconstraints; i++){
- var c = constraints[i];
- if(!c.collideConnected){
- for(var j = p1.length-1; j>=0; j-=1){
- if( (c.bodyA === p1[j] && c.bodyB === p2[j]) ||
- (c.bodyB === p1[j] && c.bodyA === p2[j])){
- p1.splice(j, 1);
- p2.splice(j, 1);
- }
- }
- }
- }
- this.collisionMatrixTick();
-
- if(doProfiling){ profilingStart = performance.now(); }
- var oldcontacts = World_step_oldContacts;
- var NoldContacts = contacts.length;
- for(i=0; i!==NoldContacts; i++){
- oldcontacts.push(contacts[i]);
- }
- contacts.length = 0;
-
- var NoldFrictionEquations = this.frictionEquations.length;
- for(i=0; i!==NoldFrictionEquations; i++){
- frictionEquationPool.push(this.frictionEquations[i]);
- }
- this.frictionEquations.length = 0;
- this.narrowphase.getContacts(
- p1,
- p2,
- this,
- contacts,
- oldcontacts,
- this.frictionEquations,
- frictionEquationPool
- );
- if(doProfiling){
- profile.narrowphase = performance.now() - profilingStart;
- }
-
- if(doProfiling){
- profilingStart = performance.now();
- }
-
- for (var i = 0; i < this.frictionEquations.length; i++) {
- solver.addEquation(this.frictionEquations[i]);
- }
- var ncontacts = contacts.length;
- for(var k=0; k!==ncontacts; k++){
-
- var c = contacts[k];
-
- var bi = c.bi,
- bj = c.bj,
- si = c.si,
- sj = c.sj;
-
- var cm;
- if(bi.material && bj.material){
- cm = this.getContactMaterial(bi.material,bj.material) || this.defaultContactMaterial;
- } else {
- cm = this.defaultContactMaterial;
- }
-
- var mu = cm.friction;
-
-
- if(bi.material && bj.material){
- if(bi.material.friction >= 0 && bj.material.friction >= 0){
- mu = bi.material.friction * bj.material.friction;
- }
- if(bi.material.restitution >= 0 && bj.material.restitution >= 0){
- c.restitution = bi.material.restitution * bj.material.restitution;
- }
- }
-
-
-
-
-
- solver.addEquation(c);
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- if( bi.allowSleep &&
- bi.type === Body.DYNAMIC &&
- bi.sleepState === Body.SLEEPING &&
- bj.sleepState === Body.AWAKE &&
- bj.type !== Body.STATIC
- ){
- var speedSquaredB = bj.velocity.norm2() + bj.angularVelocity.norm2();
- var speedLimitSquaredB = Math.pow(bj.sleepSpeedLimit,2);
- if(speedSquaredB >= speedLimitSquaredB*2){
- bi._wakeUpAfterNarrowphase = true;
- }
- }
- if( bj.allowSleep &&
- bj.type === Body.DYNAMIC &&
- bj.sleepState === Body.SLEEPING &&
- bi.sleepState === Body.AWAKE &&
- bi.type !== Body.STATIC
- ){
- var speedSquaredA = bi.velocity.norm2() + bi.angularVelocity.norm2();
- var speedLimitSquaredA = Math.pow(bi.sleepSpeedLimit,2);
- if(speedSquaredA >= speedLimitSquaredA*2){
- bj._wakeUpAfterNarrowphase = true;
- }
- }
-
- this.collisionMatrix.set(bi, bj, true);
- if (!this.collisionMatrixPrevious.get(bi, bj)) {
-
-
- World_step_collideEvent.body = bj;
- World_step_collideEvent.contact = c;
- bi.dispatchEvent(World_step_collideEvent);
- World_step_collideEvent.body = bi;
- bj.dispatchEvent(World_step_collideEvent);
- }
- this.bodyOverlapKeeper.set(bi.id, bj.id);
- this.shapeOverlapKeeper.set(si.id, sj.id);
- }
- this.emitContactEvents();
- if(doProfiling){
- profile.makeContactConstraints = performance.now() - profilingStart;
- profilingStart = performance.now();
- }
-
- for(i=0; i!==N; i++){
- var bi = bodies[i];
- if(bi._wakeUpAfterNarrowphase){
- bi.wakeUp();
- bi._wakeUpAfterNarrowphase = false;
- }
- }
-
- var Nconstraints = constraints.length;
- for(i=0; i!==Nconstraints; i++){
- var c = constraints[i];
- c.update();
- for(var j=0, Neq=c.equations.length; j!==Neq; j++){
- var eq = c.equations[j];
- solver.addEquation(eq);
- }
- }
-
- solver.solve(dt,this);
- if(doProfiling){
- profile.solve = performance.now() - profilingStart;
- }
-
- solver.removeAllEquations();
-
- var pow = Math.pow;
- for(i=0; i!==N; i++){
- var bi = bodies[i];
- if(bi.type & DYNAMIC){
- var ld = pow(1.0 - bi.linearDamping,dt);
- var v = bi.velocity;
- v.mult(ld,v);
- var av = bi.angularVelocity;
- if(av){
- var ad = pow(1.0 - bi.angularDamping,dt);
- av.mult(ad,av);
- }
- }
- }
- this.dispatchEvent(World_step_preStepEvent);
-
- for(i=0; i!==N; i++){
- var bi = bodies[i];
- if(bi.preStep){
- bi.preStep.call(bi);
- }
- }
-
-
-
- if(doProfiling){
- profilingStart = performance.now();
- }
- var stepnumber = this.stepnumber;
- var quatNormalize = stepnumber % (this.quatNormalizeSkip + 1) === 0;
- var quatNormalizeFast = this.quatNormalizeFast;
- for(i=0; i!==N; i++){
- bodies[i].integrate(dt, quatNormalize, quatNormalizeFast);
- }
- this.clearForces();
- this.broadphase.dirty = true;
- if(doProfiling){
- profile.integrate = performance.now() - profilingStart;
- }
-
- this.time += dt;
- this.stepnumber += 1;
- this.dispatchEvent(World_step_postStepEvent);
-
- for(i=0; i!==N; i++){
- var bi = bodies[i];
- var postStep = bi.postStep;
- if(postStep){
- postStep.call(bi);
- }
- }
-
- if(this.allowSleep){
- for(i=0; i!==N; i++){
- bodies[i].sleepTick(this.time);
- }
- }
- };
- World.prototype.emitContactEvents = (function(){
- var additions = [];
- var removals = [];
- var beginContactEvent = {
- type: 'beginContact',
- bodyA: null,
- bodyB: null
- };
- var endContactEvent = {
- type: 'endContact',
- bodyA: null,
- bodyB: null
- };
- var beginShapeContactEvent = {
- type: 'beginShapeContact',
- bodyA: null,
- bodyB: null,
- shapeA: null,
- shapeB: null
- };
- var endShapeContactEvent = {
- type: 'endShapeContact',
- bodyA: null,
- bodyB: null,
- shapeA: null,
- shapeB: null
- };
- return function(){
- var hasBeginContact = this.hasAnyEventListener('beginContact');
- var hasEndContact = this.hasAnyEventListener('endContact');
- if(hasBeginContact || hasEndContact){
- this.bodyOverlapKeeper.getDiff(additions, removals);
- }
- if(hasBeginContact){
- for (var i = 0, l = additions.length; i < l; i += 2) {
- beginContactEvent.bodyA = this.getBodyById(additions[i]);
- beginContactEvent.bodyB = this.getBodyById(additions[i+1]);
- this.dispatchEvent(beginContactEvent);
- }
- beginContactEvent.bodyA = beginContactEvent.bodyB = null;
- }
- if(hasEndContact){
- for (var i = 0, l = removals.length; i < l; i += 2) {
- endContactEvent.bodyA = this.getBodyById(removals[i]);
- endContactEvent.bodyB = this.getBodyById(removals[i+1]);
- this.dispatchEvent(endContactEvent);
- }
- endContactEvent.bodyA = endContactEvent.bodyB = null;
- }
- additions.length = removals.length = 0;
- var hasBeginShapeContact = this.hasAnyEventListener('beginShapeContact');
- var hasEndShapeContact = this.hasAnyEventListener('endShapeContact');
- if(hasBeginShapeContact || hasEndShapeContact){
- this.shapeOverlapKeeper.getDiff(additions, removals);
- }
- if(hasBeginShapeContact){
- for (var i = 0, l = additions.length; i < l; i += 2) {
- var shapeA = this.getShapeById(additions[i]);
- var shapeB = this.getShapeById(additions[i+1]);
- beginShapeContactEvent.shapeA = shapeA;
- beginShapeContactEvent.shapeB = shapeB;
- beginShapeContactEvent.bodyA = shapeA.body;
- beginShapeContactEvent.bodyB = shapeB.body;
- this.dispatchEvent(beginShapeContactEvent);
- }
- beginShapeContactEvent.bodyA = beginShapeContactEvent.bodyB = beginShapeContactEvent.shapeA = beginShapeContactEvent.shapeB = null;
- }
- if(hasEndShapeContact){
- for (var i = 0, l = removals.length; i < l; i += 2) {
- var shapeA = this.getShapeById(removals[i]);
- var shapeB = this.getShapeById(removals[i+1]);
- endShapeContactEvent.shapeA = shapeA;
- endShapeContactEvent.shapeB = shapeB;
- endShapeContactEvent.bodyA = shapeA.body;
- endShapeContactEvent.bodyB = shapeB.body;
- this.dispatchEvent(endShapeContactEvent);
- }
- endShapeContactEvent.bodyA = endShapeContactEvent.bodyB = endShapeContactEvent.shapeA = endShapeContactEvent.shapeB = null;
- }
- };
- })();
- World.prototype.clearForces = function(){
- var bodies = this.bodies;
- var N = bodies.length;
- for(var i=0; i !== N; i++){
- var b = bodies[i],
- force = b.force,
- tau = b.torque;
- b.force.set(0,0,0);
- b.torque.set(0,0,0);
- }
- };
- },{"../collision/AABB":18,"../collision/ArrayCollisionMatrix":19,"../collision/NaiveBroadphase":22,"../collision/OverlapKeeper":24,"../collision/Ray":25,"../collision/RaycastResult":26,"../equations/ContactEquation":35,"../equations/FrictionEquation":37,"../material/ContactMaterial":40,"../material/Material":41,"../math/Quaternion":44,"../math/Vec3":46,"../objects/Body":47,"../shapes/Shape":59,"../solver/GSSolver":62,"../utils/EventTarget":65,"../utils/TupleDictionary":68,"./Narrowphase":71}],73:[function(require,module,exports){
- var CANNON = require('cannon'),
- quickhull = require('./lib/THREE.quickhull');
- var PI_2 = Math.PI / 2;
- var Type = {
- BOX: 'Box',
- CYLINDER: 'Cylinder',
- SPHERE: 'Sphere',
- HULL: 'ConvexPolyhedron',
- MESH: 'Trimesh'
- };
- module.exports = CANNON.mesh2shape = function (object, options) {
- options = options || {};
- var geometry;
- if (options.type === Type.BOX) {
- return createBoundingBoxShape(object);
- } else if (options.type === Type.CYLINDER) {
- return createBoundingCylinderShape(object, options);
- } else if (options.type === Type.SPHERE) {
- return createBoundingSphereShape(object, options);
- } else if (options.type === Type.HULL) {
- return createConvexPolyhedron(object);
- } else if (options.type === Type.MESH) {
- geometry = getGeometry(object);
- return geometry ? createTrimeshShape(geometry) : null;
- } else if (options.type) {
- throw new Error('[CANNON.mesh2shape] Invalid type "%s".', options.type);
- }
- geometry = getGeometry(object);
- if (!geometry) return null;
- var type = geometry.metadata
- ? geometry.metadata.type
- : geometry.type;
- switch (type) {
- case 'BoxGeometry':
- case 'BoxBufferGeometry':
- return createBoxShape(geometry);
- case 'CylinderGeometry':
- case 'CylinderBufferGeometry':
- return createCylinderShape(geometry);
- case 'PlaneGeometry':
- case 'PlaneBufferGeometry':
- return createPlaneShape(geometry);
- case 'SphereGeometry':
- case 'SphereBufferGeometry':
- return createSphereShape(geometry);
- case 'TubeGeometry':
- case 'Geometry':
- case 'BufferGeometry':
- return createBoundingBoxShape(object);
- default:
- console.warn('Unrecognized geometry: "%s". Using bounding box as shape.', geometry.type);
- return createBoxShape(geometry);
- }
- };
- CANNON.mesh2shape.Type = Type;
-
- function createBoxShape (geometry) {
- var vertices = getVertices(geometry);
- if (!vertices.length) return null;
- geometry.computeBoundingBox();
- var box = geometry.boundingBox;
- return new CANNON.Box(new CANNON.Vec3(
- (box.max.x - box.min.x) / 2,
- (box.max.y - box.min.y) / 2,
- (box.max.z - box.min.z) / 2
- ));
- }
- function createBoundingBoxShape (object) {
- var shape, localPosition, worldPosition,
- box = new THREE.Box3();
- box.setFromObject(object);
- if (!isFinite(box.min.lengthSq())) return null;
- shape = new CANNON.Box(new CANNON.Vec3(
- (box.max.x - box.min.x) / 2,
- (box.max.y - box.min.y) / 2,
- (box.max.z - box.min.z) / 2
- ));
- object.updateMatrixWorld();
- worldPosition = new THREE.Vector3();
- worldPosition.setFromMatrixPosition(object.matrixWorld);
- localPosition = box.translate(worldPosition.negate()).getCenter();
- if (localPosition.lengthSq()) {
- shape.offset = localPosition;
- }
- return shape;
- }
- function createConvexPolyhedron (object) {
- var i, vertices, faces, hull,
- eps = 1e-4,
- geometry = getGeometry(object);
- if (!geometry || !geometry.vertices.length) return null;
-
- for (i = 0; i < geometry.vertices.length; i++) {
- geometry.vertices[i].x += (Math.random() - 0.5) * eps;
- geometry.vertices[i].y += (Math.random() - 0.5) * eps;
- geometry.vertices[i].z += (Math.random() - 0.5) * eps;
- }
-
- hull = quickhull(geometry);
-
- vertices = new Array(hull.vertices.length);
- for (i = 0; i < hull.vertices.length; i++) {
- vertices[i] = new CANNON.Vec3(hull.vertices[i].x, hull.vertices[i].y, hull.vertices[i].z);
- }
-
- faces = new Array(hull.faces.length);
- for (i = 0; i < hull.faces.length; i++) {
- faces[i] = [hull.faces[i].a, hull.faces[i].b, hull.faces[i].c];
- }
- return new CANNON.ConvexPolyhedron(vertices, faces);
- }
- function createCylinderShape (geometry) {
- var shape,
- params = geometry.metadata
- ? geometry.metadata.parameters
- : geometry.parameters;
- shape = new CANNON.Cylinder(
- params.radiusTop,
- params.radiusBottom,
- params.height,
- params.radialSegments
- );
-
- shape._type = CANNON.Shape.types.CYLINDER;
- shape.radiusTop = params.radiusTop;
- shape.radiusBottom = params.radiusBottom;
- shape.height = params.height;
- shape.numSegments = params.radialSegments;
- shape.orientation = new CANNON.Quaternion();
- shape.orientation.setFromEuler(THREE.Math.degToRad(-90), 0, 0, 'XYZ').normalize();
- return shape;
- }
- function createBoundingCylinderShape (object, options) {
- var shape, height, radius,
- box = new THREE.Box3(),
- axes = ['x', 'y', 'z'],
- majorAxis = options.cylinderAxis || 'y',
- minorAxes = axes.splice(axes.indexOf(majorAxis), 1) && axes;
- box.setFromObject(object);
- if (!isFinite(box.min.lengthSq())) return null;
-
- height = box.max[majorAxis] - box.min[majorAxis];
- radius = 0.5 * Math.max(
- box.max[minorAxes[0]] - box.min[minorAxes[0]],
- box.max[minorAxes[1]] - box.min[minorAxes[1]]
- );
-
- shape = new CANNON.Cylinder(radius, radius, height, 12);
-
- shape._type = CANNON.Shape.types.CYLINDER;
- shape.radiusTop = radius;
- shape.radiusBottom = radius;
- shape.height = height;
- shape.numSegments = 12;
- shape.orientation = new CANNON.Quaternion();
- shape.orientation.setFromEuler(
- majorAxis === 'y' ? PI_2 : 0,
- majorAxis === 'z' ? PI_2 : 0,
- 0,
- 'XYZ'
- ).normalize();
- return shape;
- }
- function createPlaneShape (geometry) {
- geometry.computeBoundingBox();
- var box = geometry.boundingBox;
- return new CANNON.Box(new CANNON.Vec3(
- (box.max.x - box.min.x) / 2 || 0.1,
- (box.max.y - box.min.y) / 2 || 0.1,
- (box.max.z - box.min.z) / 2 || 0.1
- ));
- }
- function createSphereShape (geometry) {
- var params = geometry.metadata
- ? geometry.metadata.parameters
- : geometry.parameters;
- return new CANNON.Sphere(params.radius);
- }
- function createBoundingSphereShape (object, options) {
- if (options.sphereRadius) {
- return new CANNON.Sphere(options.sphereRadius);
- }
- var geometry = getGeometry(object);
- if (!geometry) return null;
- geometry.computeBoundingSphere();
- return new CANNON.Sphere(geometry.boundingSphere.radius);
- }
- function createTrimeshShape (geometry) {
- var indices,
- vertices = getVertices(geometry);
- if (!vertices.length) return null;
- indices = Object.keys(vertices).map(Number);
- return new CANNON.Trimesh(vertices, indices);
- }
- function getGeometry (object) {
- var matrix, mesh,
- meshes = getMeshes(object),
- tmp = new THREE.Geometry(),
- combined = new THREE.Geometry();
- if (meshes.length === 0) return null;
-
- if (meshes.length === 1) {
- var position = new THREE.Vector3(),
- quaternion = new THREE.Quaternion(),
- scale = new THREE.Vector3();
- if (meshes[0].geometry.isBufferGeometry) {
- if (meshes[0].geometry.attributes.position) {
- tmp.fromBufferGeometry(meshes[0].geometry);
- }
- } else {
- tmp = meshes[0].geometry.clone();
- }
- tmp.metadata = meshes[0].geometry.metadata;
- meshes[0].updateMatrixWorld();
- meshes[0].matrixWorld.decompose(position, quaternion, scale);
- return tmp.scale(scale.x, scale.y, scale.z);
- }
-
- while ((mesh = meshes.pop())) {
- mesh.updateMatrixWorld();
- if (mesh.geometry.isBufferGeometry) {
- tmp.fromBufferGeometry(mesh.geometry);
- combined.merge(tmp, mesh.matrixWorld);
- } else {
- combined.merge(mesh.geometry, mesh.matrixWorld);
- }
- }
- matrix = new THREE.Matrix4();
- matrix.scale(object.scale);
- combined.applyMatrix(matrix);
- return combined;
- }
- function getVertices (geometry) {
- if (!geometry.attributes) {
- geometry = new THREE.BufferGeometry().fromGeometry(geometry);
- }
- return (geometry.attributes.position || {}).array || [];
- }
- function getMeshes (object) {
- var meshes = [];
- object.traverse(function (o) {
- if (o.type === 'Mesh') {
- meshes.push(o);
- }
- });
- return meshes;
- }
- },{"./lib/THREE.quickhull":74,"cannon":17}],74:[function(require,module,exports){
- module.exports = (function(){
- var faces = [],
- faceStack = [],
- i, NUM_POINTS, extremes,
- max = 0,
- dcur, current, j, v0, v1, v2, v3,
- N, D;
- var ab, ac, ax,
- suba, subb, normal,
- diff, subaA, subaB, subC;
- function reset(){
- ab = new THREE.Vector3(),
- ac = new THREE.Vector3(),
- ax = new THREE.Vector3(),
- suba = new THREE.Vector3(),
- subb = new THREE.Vector3(),
- normal = new THREE.Vector3(),
- diff = new THREE.Vector3(),
- subaA = new THREE.Vector3(),
- subaB = new THREE.Vector3(),
- subC = new THREE.Vector3();
- }
-
- function process( points ){
-
- while( faceStack.length > 0 ){
- cull( faceStack.shift(), points );
- }
- }
- var norm = function(){
- var ca = new THREE.Vector3(),
- ba = new THREE.Vector3(),
- N = new THREE.Vector3();
- return function( a, b, c ){
- ca.subVectors( c, a );
- ba.subVectors( b, a );
- N.crossVectors( ca, ba );
- return N.normalize();
- }
- }();
- function getNormal( face, points ){
- if( face.normal !== undefined ) return face.normal;
- var p0 = points[face[0]],
- p1 = points[face[1]],
- p2 = points[face[2]];
- ab.subVectors( p1, p0 );
- ac.subVectors( p2, p0 );
- normal.crossVectors( ac, ab );
- normal.normalize();
- return face.normal = normal.clone();
- }
- function assignPoints( face, pointset, points ){
-
- var p0 = points[face[0]],
- dots = [], apex,
- norm = getNormal( face, points );
-
- pointset.sort( function( aItem, bItem ){
- dots[aItem.x/3] = dots[aItem.x/3] !== undefined ? dots[aItem.x/3] : norm.dot( suba.subVectors( aItem, p0 ));
- dots[bItem.x/3] = dots[bItem.x/3] !== undefined ? dots[bItem.x/3] : norm.dot( subb.subVectors( bItem, p0 ));
- return dots[aItem.x/3] - dots[bItem.x/3] ;
- });
-
- var index = pointset.length;
- if( index === 1 ) dots[pointset[0].x/3] = norm.dot( suba.subVectors( pointset[0], p0 ));
- while( index-- > 0 && dots[pointset[index].x/3] > 0 )
- var point;
- if( index + 1 < pointset.length && dots[pointset[index+1].x/3] > 0 ){
- face.visiblePoints = pointset.splice( index + 1 );
- }
- }
- function cull( face, points ){
- var i = faces.length,
- dot, visibleFace, currentFace,
- visibleFaces = [face];
- var apex = points.indexOf( face.visiblePoints.pop() );
-
- while( i-- > 0 ){
- currentFace = faces[i];
- if( currentFace !== face ){
-
- dot = getNormal( currentFace, points ).dot( diff.subVectors( points[apex], points[currentFace[0]] ));
- if( dot > 0 ){
- visibleFaces.push( currentFace );
- }
- }
- }
- var index, neighbouringIndex, vertex;
-
-
-
-
-
-
-
-
-
- var j = i = visibleFaces.length;
- var isDistinct = false,
- hasOneVisibleFace = i === 1,
- cull = [],
- perimeter = [],
- edgeIndex = 0, compareFace, nextIndex,
- a, b;
- var allPoints = [];
- var originFace = [visibleFaces[0][0], visibleFaces[0][1], visibleFaces[0][1], visibleFaces[0][2], visibleFaces[0][2], visibleFaces[0][0]];
- if( visibleFaces.length === 1 ){
- currentFace = visibleFaces[0];
- perimeter = [currentFace[0], currentFace[1], currentFace[1], currentFace[2], currentFace[2], currentFace[0]];
-
- if( faceStack.indexOf( currentFace ) > -1 ){
- faceStack.splice( faceStack.indexOf( currentFace ), 1 );
- }
- if( currentFace.visiblePoints ) allPoints = allPoints.concat( currentFace.visiblePoints );
- faces.splice( faces.indexOf( currentFace ), 1 );
- }else{
- while( i-- > 0 ){
- currentFace = visibleFaces[i];
-
- if( faceStack.indexOf( currentFace ) > -1 ){
- faceStack.splice( faceStack.indexOf( currentFace ), 1 );
- }
- if( currentFace.visiblePoints ) allPoints = allPoints.concat( currentFace.visiblePoints );
- faces.splice( faces.indexOf( currentFace ), 1 );
- var isSharedEdge;
- cEdgeIndex = 0;
- while( cEdgeIndex < 3 ){
- isSharedEdge = false;
- j = visibleFaces.length;
- a = currentFace[cEdgeIndex]
- b = currentFace[(cEdgeIndex+1)%3];
- while( j-- > 0 && !isSharedEdge ){
- compareFace = visibleFaces[j];
- edgeIndex = 0;
-
- if( compareFace !== currentFace ){
- while( edgeIndex < 3 && !isSharedEdge ){
- nextIndex = ( edgeIndex + 1 );
- isSharedEdge = ( compareFace[edgeIndex] === a && compareFace[nextIndex%3] === b ) ||
- ( compareFace[edgeIndex] === b && compareFace[nextIndex%3] === a );
- edgeIndex++;
- }
- }
- }
- if( !isSharedEdge || hasOneVisibleFace ){
- perimeter.push( a );
- perimeter.push( b );
- }
- cEdgeIndex++;
- }
- }
- }
-
- i = 0;
- var l = perimeter.length/2;
- var f;
- while( i < l ){
- f = [ perimeter[i*2+1], apex, perimeter[i*2] ];
- assignPoints( f, allPoints, points );
- faces.push( f )
- if( f.visiblePoints !== undefined )faceStack.push( f );
- i++;
- }
- }
- var distSqPointSegment = function(){
- var ab = new THREE.Vector3(),
- ac = new THREE.Vector3(),
- bc = new THREE.Vector3();
- return function( a, b, c ){
- ab.subVectors( b, a );
- ac.subVectors( c, a );
- bc.subVectors( c, b );
- var e = ac.dot(ab);
- if (e < 0.0) return ac.dot( ac );
- var f = ab.dot( ab );
- if (e >= f) return bc.dot( bc );
- return ac.dot( ac ) - e * e / f;
- }
- }();
- return function( geometry ){
- reset();
- points = geometry.vertices;
- faces = [],
- faceStack = [],
- i = NUM_POINTS = points.length,
- extremes = points.slice( 0, 6 ),
- max = 0;
-
- while( i-- > 0 ){
- if( points[i].x < extremes[0].x ) extremes[0] = points[i];
- if( points[i].x > extremes[1].x ) extremes[1] = points[i];
- if( points[i].y < extremes[2].y ) extremes[2] = points[i];
- if( points[i].y < extremes[3].y ) extremes[3] = points[i];
- if( points[i].z < extremes[4].z ) extremes[4] = points[i];
- if( points[i].z < extremes[5].z ) extremes[5] = points[i];
- }
-
- j = i = 6;
- while( i-- > 0 ){
- j = i - 1;
- while( j-- > 0 ){
- if( max < (dcur = extremes[i].distanceToSquared( extremes[j] )) ){
- max = dcur;
- v0 = extremes[ i ];
- v1 = extremes[ j ];
- }
- }
- }
-
- i = 6;
- max = 0;
- while( i-- > 0 ){
- dcur = distSqPointSegment( v0, v1, extremes[i]);
- if( max < dcur ){
- max = dcur;
- v2 = extremes[ i ];
- }
- }
-
- N = norm(v0, v1, v2);
- D = N.dot( v0 );
- max = 0;
- i = NUM_POINTS;
- while( i-- > 0 ){
- dcur = Math.abs( points[i].dot( N ) - D );
- if( max < dcur ){
- max = dcur;
- v3 = points[i];
- }
- }
- var v0Index = points.indexOf( v0 ),
- v1Index = points.indexOf( v1 ),
- v2Index = points.indexOf( v2 ),
- v3Index = points.indexOf( v3 );
-
-
- var tetrahedron =[
- [ v2Index, v1Index, v0Index ],
- [ v1Index, v3Index, v0Index ],
- [ v2Index, v3Index, v1Index ],
- [ v0Index, v3Index, v2Index ],
- ];
- subaA.subVectors( v1, v0 ).normalize();
- subaB.subVectors( v2, v0 ).normalize();
- subC.subVectors ( v3, v0 ).normalize();
- var sign = subC.dot( new THREE.Vector3().crossVectors( subaB, subaA ));
-
- if( sign < 0 ){
- tetrahedron[0].reverse();
- tetrahedron[1].reverse();
- tetrahedron[2].reverse();
- tetrahedron[3].reverse();
- }
-
- var pointsCloned = points.slice();
- pointsCloned.splice( pointsCloned.indexOf( v0 ), 1 );
- pointsCloned.splice( pointsCloned.indexOf( v1 ), 1 );
- pointsCloned.splice( pointsCloned.indexOf( v2 ), 1 );
- pointsCloned.splice( pointsCloned.indexOf( v3 ), 1 );
- var i = tetrahedron.length;
- while( i-- > 0 ){
- assignPoints( tetrahedron[i], pointsCloned, points );
- if( tetrahedron[i].visiblePoints !== undefined ){
- faceStack.push( tetrahedron[i] );
- }
- faces.push( tetrahedron[i] );
- }
- process( points );
-
- var ll = faces.length;
- while( ll-- > 0 ){
- geometry.faces[ll] = new THREE.Face3( faces[ll][2], faces[ll][1], faces[ll][0], faces[ll].normal )
- }
- geometry.normalsNeedUpdate = true;
- return geometry;
- }
- }())
- },{}],75:[function(require,module,exports){
- var EPS = 0.1;
- module.exports = {
- schema: {
- enabled: {default: true},
- mode: {default: 'teleport', oneOf: ['teleport', 'animate']},
- animateSpeed: {default: 3.0}
- },
- init: function () {
- this.active = true;
- this.checkpoint = null;
- this.offset = new THREE.Vector3();
- this.position = new THREE.Vector3();
- this.targetPosition = new THREE.Vector3();
- },
- play: function () { this.active = true; },
- pause: function () { this.active = false; },
- setCheckpoint: function (checkpoint) {
- var el = this.el;
- if (!this.active) return;
- if (this.checkpoint === checkpoint) return;
- if (this.checkpoint) {
- el.emit('navigation-end', {checkpoint: this.checkpoint});
- }
- this.checkpoint = checkpoint;
- this.sync();
-
- if (this.position.distanceTo(this.targetPosition) < EPS) {
- this.checkpoint = null;
- return;
- }
- el.emit('navigation-start', {checkpoint: checkpoint});
- if (this.data.mode === 'teleport') {
- this.el.setAttribute('position', this.targetPosition);
- this.checkpoint = null;
- el.emit('navigation-end', {checkpoint: checkpoint});
- }
- },
- isVelocityActive: function () {
- return !!(this.active && this.checkpoint);
- },
- getVelocity: function () {
- if (!this.active) return;
- var data = this.data,
- offset = this.offset,
- position = this.position,
- targetPosition = this.targetPosition,
- checkpoint = this.checkpoint;
- this.sync();
- if (position.distanceTo(targetPosition) < EPS) {
- this.checkpoint = null;
- this.el.emit('navigation-end', {checkpoint: checkpoint});
- return offset.set(0, 0, 0);
- }
- offset.setLength(data.animateSpeed);
- return offset;
- },
- sync: function () {
- var offset = this.offset,
- position = this.position,
- targetPosition = this.targetPosition;
- position.copy(this.el.getAttribute('position'));
- targetPosition.copy(this.checkpoint.object3D.getWorldPosition());
- targetPosition.add(this.checkpoint.components.checkpoint.getOffset());
- offset.copy(targetPosition).sub(position);
- }
- };
- },{}],76:[function(require,module,exports){
- var GamepadButton = require('../../lib/GamepadButton'),
- GamepadButtonEvent = require('../../lib/GamepadButtonEvent');
- var JOYSTICK_EPS = 0.2;
- module.exports = {
-
- GamepadButton: GamepadButton,
-
- schema: {
-
- controller: { default: 0, oneOf: [0, 1, 2, 3] },
-
- enabled: { default: true },
-
- debug: { default: false }
- },
-
-
- init: function () {
- var scene = this.el.sceneEl;
- this.prevTime = window.performance.now();
-
- this.buttons = {};
- scene.addBehavior(this);
- },
-
- update: function () { this.tick(); },
-
- tick: function () {
- this.updateButtonState();
- },
-
- remove: function () { },
-
- isVelocityActive: function () {
- if (!this.data.enabled || !this.isConnected()) return false;
- var dpad = this.getDpad(),
- joystick0 = this.getJoystick(0),
- inputX = dpad.x || joystick0.x,
- inputY = dpad.y || joystick0.y;
- return Math.abs(inputX) > JOYSTICK_EPS || Math.abs(inputY) > JOYSTICK_EPS;
- },
- getVelocityDelta: function () {
- var dpad = this.getDpad(),
- joystick0 = this.getJoystick(0),
- inputX = dpad.x || joystick0.x,
- inputY = dpad.y || joystick0.y,
- dVelocity = new THREE.Vector3();
- if (Math.abs(inputX) > JOYSTICK_EPS) {
- dVelocity.x += inputX;
- }
- if (Math.abs(inputY) > JOYSTICK_EPS) {
- dVelocity.z += inputY;
- }
- return dVelocity;
- },
-
- isRotationActive: function () {
- if (!this.data.enabled || !this.isConnected()) return false;
- var joystick1 = this.getJoystick(1);
- return Math.abs(joystick1.x) > JOYSTICK_EPS || Math.abs(joystick1.y) > JOYSTICK_EPS;
- },
- getRotationDelta: function () {
- var lookVector = this.getJoystick(1);
- if (Math.abs(lookVector.x) <= JOYSTICK_EPS) lookVector.x = 0;
- if (Math.abs(lookVector.y) <= JOYSTICK_EPS) lookVector.y = 0;
- return lookVector;
- },
-
- updateButtonState: function () {
- var gamepad = this.getGamepad();
- if (this.data.enabled && gamepad) {
-
- for (var i = 0; i < gamepad.buttons.length; i++) {
- if (gamepad.buttons[i].pressed && !this.buttons[i]) {
- this.emit(new GamepadButtonEvent('gamepadbuttondown', i, gamepad.buttons[i]));
- } else if (!gamepad.buttons[i].pressed && this.buttons[i]) {
- this.emit(new GamepadButtonEvent('gamepadbuttonup', i, gamepad.buttons[i]));
- }
- this.buttons[i] = gamepad.buttons[i].pressed;
- }
- } else if (Object.keys(this.buttons)) {
-
- this.buttons = {};
- }
- },
- emit: function (event) {
-
- this.el.emit(event.type, event);
-
- this.el.emit(
- event.type + ':' + event.index,
- new GamepadButtonEvent(event.type, event.index, event)
- );
- },
-
-
- getGamepad: function () {
- var localGamepad = navigator.getGamepads
- && navigator.getGamepads()[this.data.controller],
- proxyControls = this.el.sceneEl.components['proxy-controls'],
- proxyGamepad = proxyControls && proxyControls.isConnected()
- && proxyControls.getGamepad(this.data.controller);
- return proxyGamepad || localGamepad;
- },
-
- getButton: function (index) {
- return this.getGamepad().buttons[index];
- },
-
- getAxis: function (index) {
- return this.getGamepad().axes[index];
- },
-
- getJoystick: function (index) {
- var gamepad = this.getGamepad();
- switch (index) {
- case 0: return new THREE.Vector2(gamepad.axes[0], gamepad.axes[1]);
- case 1: return new THREE.Vector2(gamepad.axes[2], gamepad.axes[3]);
- default: throw new Error('Unexpected joystick index "%d".', index);
- }
- },
-
- getDpad: function () {
- var gamepad = this.getGamepad();
- if (!gamepad.buttons[GamepadButton.DPAD_RIGHT]) {
- return new THREE.Vector2();
- }
- return new THREE.Vector2(
- (gamepad.buttons[GamepadButton.DPAD_RIGHT].pressed ? 1 : 0)
- + (gamepad.buttons[GamepadButton.DPAD_LEFT].pressed ? -1 : 0),
- (gamepad.buttons[GamepadButton.DPAD_UP].pressed ? -1 : 0)
- + (gamepad.buttons[GamepadButton.DPAD_DOWN].pressed ? 1 : 0)
- );
- },
-
- isConnected: function () {
- var gamepad = this.getGamepad();
- return !!(gamepad && gamepad.connected);
- },
-
- getID: function () {
- return this.getGamepad().id;
- }
- };
- },{"../../lib/GamepadButton":2,"../../lib/GamepadButtonEvent":3}],77:[function(require,module,exports){
- var radToDeg = THREE.Math.radToDeg,
- isMobile = AFRAME.utils.device.isMobile();
- module.exports = {
- schema: {
- enabled: {default: true},
- standing: {default: true}
- },
- init: function () {
- this.isPositionCalibrated = false;
- this.dolly = new THREE.Object3D();
- this.hmdEuler = new THREE.Euler();
- this.previousHMDPosition = new THREE.Vector3();
- this.deltaHMDPosition = new THREE.Vector3();
- this.vrControls = new THREE.VRControls(this.dolly);
- this.rotation = new THREE.Vector3();
- },
- update: function () {
- var data = this.data;
- var vrControls = this.vrControls;
- vrControls.standing = data.standing;
- vrControls.update();
- },
- tick: function () {
- this.vrControls.update();
- },
- remove: function () {
- this.vrControls.dispose();
- },
- isRotationActive: function () {
- var hmdEuler = this.hmdEuler;
- if (!this.data.enabled || !(this.el.sceneEl.is('vr-mode') || isMobile)) {
- return false;
- }
- hmdEuler.setFromQuaternion(this.dolly.quaternion, 'YXZ');
- return !isNullVector(hmdEuler);
- },
- getRotation: function () {
- var hmdEuler = this.hmdEuler;
- return this.rotation.set(
- radToDeg(hmdEuler.x),
- radToDeg(hmdEuler.y),
- radToDeg(hmdEuler.z)
- );
- },
- isVelocityActive: function () {
- var deltaHMDPosition = this.deltaHMDPosition;
- var previousHMDPosition = this.previousHMDPosition;
- var currentHMDPosition = this.calculateHMDPosition();
- this.isPositionCalibrated = this.isPositionCalibrated || !isNullVector(previousHMDPosition);
- if (!this.data.enabled || !this.el.sceneEl.is('vr-mode') || isMobile) {
- return false;
- }
- deltaHMDPosition.copy(currentHMDPosition).sub(previousHMDPosition);
- previousHMDPosition.copy(currentHMDPosition);
- return this.isPositionCalibrated && !isNullVector(deltaHMDPosition);
- },
- getPositionDelta: function () {
- return this.deltaHMDPosition;
- },
- calculateHMDPosition: function () {
- var dolly = this.dolly;
- var position = new THREE.Vector3();
- dolly.updateMatrix();
- position.setFromMatrixPosition(dolly.matrix);
- return position;
- }
- };
- function isNullVector (vector) {
- return vector.x === 0 && vector.y === 0 && vector.z === 0;
- }
- },{}],78:[function(require,module,exports){
- var physics = require('aframe-physics-system');
- module.exports = {
- 'checkpoint-controls': require('./checkpoint-controls'),
- 'gamepad-controls': require('./gamepad-controls'),
- 'hmd-controls': require('./hmd-controls'),
- 'keyboard-controls': require('./keyboard-controls'),
- 'mouse-controls': require('./mouse-controls'),
- 'touch-controls': require('./touch-controls'),
- 'universal-controls': require('./universal-controls'),
- registerAll: function (AFRAME) {
- if (this._registered) return;
- AFRAME = AFRAME || window.AFRAME;
- physics.registerAll();
- if (!AFRAME.components['checkpoint-controls']) AFRAME.registerComponent('checkpoint-controls', this['checkpoint-controls']);
- if (!AFRAME.components['gamepad-controls']) AFRAME.registerComponent('gamepad-controls', this['gamepad-controls']);
- if (!AFRAME.components['hmd-controls']) AFRAME.registerComponent('hmd-controls', this['hmd-controls']);
- if (!AFRAME.components['keyboard-controls']) AFRAME.registerComponent('keyboard-controls', this['keyboard-controls']);
- if (!AFRAME.components['mouse-controls']) AFRAME.registerComponent('mouse-controls', this['mouse-controls']);
- if (!AFRAME.components['touch-controls']) AFRAME.registerComponent('touch-controls', this['touch-controls']);
- if (!AFRAME.components['universal-controls']) AFRAME.registerComponent('universal-controls', this['universal-controls']);
- this._registered = true;
- }
- };
- },{"./checkpoint-controls":75,"./gamepad-controls":76,"./hmd-controls":77,"./keyboard-controls":79,"./mouse-controls":80,"./touch-controls":81,"./universal-controls":82,"aframe-physics-system":5}],79:[function(require,module,exports){
- require('../../lib/keyboard.polyfill');
- var MAX_DELTA = 0.2,
- PROXY_FLAG = '__keyboard-controls-proxy';
- var KeyboardEvent = window.KeyboardEvent;
- module.exports = {
- schema: {
- enabled: { default: true },
- debug: { default: false }
- },
- init: function () {
- this.dVelocity = new THREE.Vector3();
- this.localKeys = {};
- this.listeners = {
- keydown: this.onKeyDown.bind(this),
- keyup: this.onKeyUp.bind(this),
- blur: this.onBlur.bind(this)
- };
- this.attachEventListeners();
- },
-
- isVelocityActive: function () {
- return this.data.enabled && !!Object.keys(this.getKeys()).length;
- },
- getVelocityDelta: function () {
- var data = this.data,
- keys = this.getKeys();
- this.dVelocity.set(0, 0, 0);
- if (data.enabled) {
- if (keys.KeyW || keys.ArrowUp) { this.dVelocity.z -= 1; }
- if (keys.KeyA || keys.ArrowLeft) { this.dVelocity.x -= 1; }
- if (keys.KeyS || keys.ArrowDown) { this.dVelocity.z += 1; }
- if (keys.KeyD || keys.ArrowRight) { this.dVelocity.x += 1; }
- }
- return this.dVelocity.clone();
- },
-
- play: function () {
- this.attachEventListeners();
- },
- pause: function () {
- this.removeEventListeners();
- },
- remove: function () {
- this.pause();
- },
- attachEventListeners: function () {
- window.addEventListener('keydown', this.listeners.keydown, false);
- window.addEventListener('keyup', this.listeners.keyup, false);
- window.addEventListener('blur', this.listeners.blur, false);
- },
- removeEventListeners: function () {
- window.removeEventListener('keydown', this.listeners.keydown);
- window.removeEventListener('keyup', this.listeners.keyup);
- window.removeEventListener('blur', this.listeners.blur);
- },
- onKeyDown: function (event) {
- if (AFRAME.utils.shouldCaptureKeyEvent(event)) {
- this.localKeys[event.code] = true;
- this.emit(event);
- }
- },
- onKeyUp: function (event) {
- if (AFRAME.utils.shouldCaptureKeyEvent(event)) {
- delete this.localKeys[event.code];
- this.emit(event);
- }
- },
- onBlur: function () {
- for (var code in this.localKeys) {
- if (this.localKeys.hasOwnProperty(code)) {
- delete this.localKeys[code];
- }
- }
- },
- emit: function (event) {
-
-
-
- if (PROXY_FLAG in event) {
-
- this.el.emit(event.type, event);
- }
-
- this.el.emit(event.type + ':' + event.code, new KeyboardEvent(event.type, event));
- if (this.data.debug) console.log(event.type + ':' + event.code);
- },
-
- isPressed: function (code) {
- return code in this.getKeys();
- },
- getKeys: function () {
- if (this.isProxied()) {
- return this.el.sceneEl.components['proxy-controls'].getKeyboard();
- }
- return this.localKeys;
- },
- isProxied: function () {
- var proxyControls = this.el.sceneEl.components['proxy-controls'];
- return proxyControls && proxyControls.isConnected();
- }
- };
- },{"../../lib/keyboard.polyfill":4}],80:[function(require,module,exports){
- document.exitPointerLock = document.exitPointerLock || document.mozExitPointerLock;
- module.exports = {
- schema: {
- enabled: { default: true },
- pointerlockEnabled: { default: true },
- sensitivity: { default: 1 / 25 }
- },
- init: function () {
- this.mouseDown = false;
- this.pointerLocked = false;
- this.lookVector = new THREE.Vector2();
- this.bindMethods();
- },
- update: function (previousData) {
- var data = this.data;
- if (previousData.pointerlockEnabled && !data.pointerlockEnabled && this.pointerLocked) {
- document.exitPointerLock();
- }
- },
- play: function () {
- this.addEventListeners();
- },
- pause: function () {
- this.removeEventListeners();
- this.lookVector.set(0, 0);
- },
- remove: function () {
- this.pause();
- },
- bindMethods: function () {
- this.onMouseDown = this.onMouseDown.bind(this);
- this.onMouseMove = this.onMouseMove.bind(this);
- this.onMouseUp = this.onMouseUp.bind(this);
- this.onMouseUp = this.onMouseUp.bind(this);
- this.onPointerLockChange = this.onPointerLockChange.bind(this);
- this.onPointerLockChange = this.onPointerLockChange.bind(this);
- this.onPointerLockChange = this.onPointerLockChange.bind(this);
- },
- addEventListeners: function () {
- var sceneEl = this.el.sceneEl;
- var canvasEl = sceneEl.canvas;
- var data = this.data;
- if (!canvasEl) {
- sceneEl.addEventListener('render-target-loaded', this.addEventListeners.bind(this));
- return;
- }
- canvasEl.addEventListener('mousedown', this.onMouseDown, false);
- canvasEl.addEventListener('mousemove', this.onMouseMove, false);
- canvasEl.addEventListener('mouseup', this.onMouseUp, false);
- canvasEl.addEventListener('mouseout', this.onMouseUp, false);
- if (data.pointerlockEnabled) {
- document.addEventListener('pointerlockchange', this.onPointerLockChange, false);
- document.addEventListener('mozpointerlockchange', this.onPointerLockChange, false);
- document.addEventListener('pointerlockerror', this.onPointerLockError, false);
- }
- },
- removeEventListeners: function () {
- var canvasEl = this.el.sceneEl && this.el.sceneEl.canvas;
- if (canvasEl) {
- canvasEl.removeEventListener('mousedown', this.onMouseDown, false);
- canvasEl.removeEventListener('mousemove', this.onMouseMove, false);
- canvasEl.removeEventListener('mouseup', this.onMouseUp, false);
- canvasEl.removeEventListener('mouseout', this.onMouseUp, false);
- }
- document.removeEventListener('pointerlockchange', this.onPointerLockChange, false);
- document.removeEventListener('mozpointerlockchange', this.onPointerLockChange, false);
- document.removeEventListener('pointerlockerror', this.onPointerLockError, false);
- },
- isRotationActive: function () {
- return this.data.enabled && (this.mouseDown || this.pointerLocked);
- },
-
- getRotationDelta: function () {
- var dRotation = this.lookVector.clone().multiplyScalar(this.data.sensitivity);
- this.lookVector.set(0, 0);
- return dRotation;
- },
- onMouseMove: function (event) {
- var previousMouseEvent = this.previousMouseEvent;
- if (!this.data.enabled || !(this.mouseDown || this.pointerLocked)) {
- return;
- }
- var movementX = event.movementX || event.mozMovementX || 0;
- var movementY = event.movementY || event.mozMovementY || 0;
- if (!this.pointerLocked) {
- movementX = event.screenX - previousMouseEvent.screenX;
- movementY = event.screenY - previousMouseEvent.screenY;
- }
- this.lookVector.x += movementX;
- this.lookVector.y += movementY;
- this.previousMouseEvent = event;
- },
- onMouseDown: function (event) {
- var canvasEl = this.el.sceneEl.canvas,
- isEditing = (AFRAME.INSPECTOR || {}).opened;
- this.mouseDown = true;
- this.previousMouseEvent = event;
- if (this.data.pointerlockEnabled && !this.pointerLocked && !isEditing) {
- if (canvasEl.requestPointerLock) {
- canvasEl.requestPointerLock();
- } else if (canvasEl.mozRequestPointerLock) {
- canvasEl.mozRequestPointerLock();
- }
- }
- },
- onMouseUp: function () {
- this.mouseDown = false;
- },
- onPointerLockChange: function () {
- this.pointerLocked = !!(document.pointerLockElement || document.mozPointerLockElement);
- },
- onPointerLockError: function () {
- this.pointerLocked = false;
- }
- };
- },{}],81:[function(require,module,exports){
- module.exports = {
- schema: {
- enabled: { default: true }
- },
- init: function () {
- this.dVelocity = new THREE.Vector3();
- this.bindMethods();
- },
- play: function () {
- this.addEventListeners();
- },
- pause: function () {
- this.removeEventListeners();
- this.dVelocity.set(0, 0, 0);
- },
- remove: function () {
- this.pause();
- },
- addEventListeners: function () {
- var sceneEl = this.el.sceneEl;
- var canvasEl = sceneEl.canvas;
- if (!canvasEl) {
- sceneEl.addEventListener('render-target-loaded', this.addEventListeners.bind(this));
- return;
- }
- canvasEl.addEventListener('touchstart', this.onTouchStart);
- canvasEl.addEventListener('touchend', this.onTouchEnd);
- },
- removeEventListeners: function () {
- var canvasEl = this.el.sceneEl && this.el.sceneEl.canvas;
- if (!canvasEl) { return; }
- canvasEl.removeEventListener('touchstart', this.onTouchStart);
- canvasEl.removeEventListener('touchend', this.onTouchEnd);
- },
- isVelocityActive: function () {
- return this.data.enabled && this.isMoving;
- },
- getVelocityDelta: function () {
- this.dVelocity.z = this.isMoving ? -1 : 0;
- return this.dVelocity.clone();
- },
- bindMethods: function () {
- this.onTouchStart = this.onTouchStart.bind(this);
- this.onTouchEnd = this.onTouchEnd.bind(this);
- },
- onTouchStart: function (e) {
- this.isMoving = true;
- e.preventDefault();
- },
- onTouchEnd: function (e) {
- this.isMoving = false;
- e.preventDefault();
- }
- };
- },{}],82:[function(require,module,exports){
- var COMPONENT_SUFFIX = '-controls',
- MAX_DELTA = 0.2,
- PI_2 = Math.PI / 2;
- module.exports = {
-
- dependencies: ['velocity', 'rotation'],
- schema: {
- enabled: { default: true },
- movementEnabled: { default: true },
- movementControls: { default: ['gamepad', 'keyboard', 'touch', 'hmd'] },
- rotationEnabled: { default: true },
- rotationControls: { default: ['hmd', 'gamepad', 'mouse'] },
- movementSpeed: { default: 5 },
- movementEasing: { default: 15 },
- movementEasingY: { default: 0 },
- movementAcceleration: { default: 80 },
- rotationSensitivity: { default: 0.05 },
- fly: { default: false },
- },
-
- init: function () {
- var rotation = this.el.getAttribute('rotation');
- if (this.el.hasAttribute('look-controls') && this.data.rotationEnabled) {
- console.error('[universal-controls] The `universal-controls` component is a replacement '
- + 'for `look-controls`, and cannot be used in combination with it.');
- }
-
- this.velocity = new THREE.Vector3();
-
- this.pitch = new THREE.Object3D();
- this.pitch.rotation.x = THREE.Math.degToRad(rotation.x);
- this.yaw = new THREE.Object3D();
- this.yaw.position.y = 10;
- this.yaw.rotation.y = THREE.Math.degToRad(rotation.y);
- this.yaw.add(this.pitch);
- this.heading = new THREE.Euler(0, 0, 0, 'YXZ');
- if (this.el.sceneEl.hasLoaded) {
- this.injectControls();
- } else {
- this.el.sceneEl.addEventListener('loaded', this.injectControls.bind(this));
- }
- },
- update: function () {
- if (this.el.sceneEl.hasLoaded) {
- this.injectControls();
- }
- },
- injectControls: function () {
- var i, name,
- data = this.data;
- for (i = 0; i < data.movementControls.length; i++) {
- name = data.movementControls[i] + COMPONENT_SUFFIX;
- if (!this.el.components[name]) {
- this.el.setAttribute(name, '');
- }
- }
- for (i = 0; i < data.rotationControls.length; i++) {
- name = data.rotationControls[i] + COMPONENT_SUFFIX;
- if (!this.el.components[name]) {
- this.el.setAttribute(name, '');
- }
- }
- },
-
- tick: function (t, dt) {
- if (!dt) { return; }
-
- if (this.data.rotationEnabled) this.updateRotation(dt);
-
- if (this.data.movementEnabled && dt / 1000 > MAX_DELTA) {
- this.velocity.set(0, 0, 0);
- this.el.setAttribute('velocity', this.velocity);
- } else {
- this.updateVelocity(dt);
- }
- },
-
- updateRotation: function (dt) {
- var control, dRotation,
- data = this.data;
- for (var i = 0, l = data.rotationControls.length; i < l; i++) {
- control = this.el.components[data.rotationControls[i] + COMPONENT_SUFFIX];
- if (control && control.isRotationActive()) {
- if (control.getRotationDelta) {
- dRotation = control.getRotationDelta(dt);
- dRotation.multiplyScalar(data.rotationSensitivity);
- this.yaw.rotation.y -= dRotation.x;
- this.pitch.rotation.x -= dRotation.y;
- this.pitch.rotation.x = Math.max(-PI_2, Math.min(PI_2, this.pitch.rotation.x));
- this.el.setAttribute('rotation', {
- x: THREE.Math.radToDeg(this.pitch.rotation.x),
- y: THREE.Math.radToDeg(this.yaw.rotation.y),
- z: 0
- });
- } else if (control.getRotation) {
- this.el.setAttribute('rotation', control.getRotation());
- } else {
- throw new Error('Incompatible rotation controls: %s', data.rotationControls[i]);
- }
- break;
- }
- }
- },
-
- updateVelocity: function (dt) {
- var control, dVelocity,
- velocity = this.velocity,
- data = this.data;
- if (data.movementEnabled) {
- for (var i = 0, l = data.movementControls.length; i < l; i++) {
- control = this.el.components[data.movementControls[i] + COMPONENT_SUFFIX];
- if (control && control.isVelocityActive()) {
- if (control.getVelocityDelta) {
- dVelocity = control.getVelocityDelta(dt);
- } else if (control.getVelocity) {
- this.el.setAttribute('velocity', control.getVelocity());
- return;
- } else if (control.getPositionDelta) {
- velocity.copy(control.getPositionDelta(dt).multiplyScalar(1000 / dt));
- this.el.setAttribute('velocity', velocity);
- return;
- } else {
- throw new Error('Incompatible movement controls: ', data.movementControls[i]);
- }
- break;
- }
- }
- }
- velocity.copy(this.el.getAttribute('velocity'));
- velocity.x -= velocity.x * data.movementEasing * dt / 1000;
- velocity.y -= velocity.y * data.movementEasingY * dt / 1000;
- velocity.z -= velocity.z * data.movementEasing * dt / 1000;
- if (dVelocity && data.movementEnabled) {
-
- if (dVelocity.length() > 1) {
- dVelocity.setLength(this.data.movementAcceleration * dt / 1000);
- } else {
- dVelocity.multiplyScalar(this.data.movementAcceleration * dt / 1000);
- }
-
- var rotation = this.el.getAttribute('rotation');
- if (rotation) {
- this.heading.set(
- data.fly ? THREE.Math.degToRad(rotation.x) : 0,
- THREE.Math.degToRad(rotation.y),
- 0
- );
- dVelocity.applyEuler(this.heading);
- }
- velocity.add(dVelocity);
-
-
-
-
-
-
-
- }
- this.el.setAttribute('velocity', velocity);
- }
- };
- },{}]},{},[1]);
|