Physics_AF.cpp 197 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014
  1. /*
  2. ===========================================================================
  3. Doom 3 BFG Edition GPL Source Code
  4. Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
  5. This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
  6. Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation, either version 3 of the License, or
  9. (at your option) any later version.
  10. Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
  16. In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
  17. If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
  18. ===========================================================================
  19. */
  20. #pragma hdrstop
  21. #include "../../idlib/precompiled.h"
  22. #include "../Game_local.h"
  23. CLASS_DECLARATION( idPhysics_Base, idPhysics_AF )
  24. END_CLASS
  25. const float ERROR_REDUCTION = 0.5f;
  26. const float ERROR_REDUCTION_MAX = 256.0f;
  27. const float LIMIT_ERROR_REDUCTION = 0.3f;
  28. const float LCP_EPSILON = 1e-7f;
  29. const float LIMIT_LCP_EPSILON = 1e-4f;
  30. const float CONTACT_LCP_EPSILON = 1e-6f;
  31. const float CENTER_OF_MASS_EPSILON = 1e-4f;
  32. const float NO_MOVE_TIME = 1.0f;
  33. const float NO_MOVE_TRANSLATION_TOLERANCE = 10.0f;
  34. const float NO_MOVE_ROTATION_TOLERANCE = 10.0f;
  35. const float MIN_MOVE_TIME = -1.0f;
  36. const float MAX_MOVE_TIME = -1.0f;
  37. const float IMPULSE_THRESHOLD = 500.0f;
  38. const float SUSPEND_LINEAR_VELOCITY = 10.0f;
  39. const float SUSPEND_ANGULAR_VELOCITY = 15.0f;
  40. const float SUSPEND_LINEAR_ACCELERATION = 20.0f;
  41. const float SUSPEND_ANGULAR_ACCELERATION = 30.0f;
  42. const idVec6 vec6_lcp_epsilon = idVec6( LCP_EPSILON, LCP_EPSILON, LCP_EPSILON,
  43. LCP_EPSILON, LCP_EPSILON, LCP_EPSILON );
  44. #define AF_TIMINGS
  45. #ifdef AF_TIMINGS
  46. static int lastTimerReset = 0;
  47. static int numArticulatedFigures = 0;
  48. static idTimer timer_total, timer_pc, timer_ac, timer_collision, timer_lcp;
  49. #endif
  50. //===============================================================
  51. //
  52. // idAFConstraint
  53. //
  54. //===============================================================
  55. /*
  56. ================
  57. idAFConstraint::idAFConstraint
  58. ================
  59. */
  60. idAFConstraint::idAFConstraint() {
  61. type = CONSTRAINT_INVALID;
  62. name = "noname";
  63. body1 = NULL;
  64. body2 = NULL;
  65. physics = NULL;
  66. lo.Zero( 6 );
  67. lo.SubVec6(0) = -vec6_infinity;
  68. hi.Zero( 6 );
  69. hi.SubVec6(0) = vec6_infinity;
  70. e.SetSize( 6 );
  71. e.SubVec6(0) = vec6_lcp_epsilon;
  72. boxConstraint = NULL;
  73. boxIndex[0] = -1;
  74. boxIndex[1] = -1;
  75. boxIndex[2] = -1;
  76. boxIndex[3] = -1;
  77. boxIndex[4] = -1;
  78. boxIndex[5] = -1;
  79. firstIndex = 0;
  80. memset( &fl, 0, sizeof( fl ) );
  81. }
  82. /*
  83. ================
  84. idAFConstraint::~idAFConstraint
  85. ================
  86. */
  87. idAFConstraint::~idAFConstraint() {
  88. }
  89. /*
  90. ================
  91. idAFConstraint::SetBody1
  92. ================
  93. */
  94. void idAFConstraint::SetBody1( idAFBody *body ) {
  95. if ( body1 != body) {
  96. body1 = body;
  97. if ( physics ) {
  98. physics->SetChanged();
  99. }
  100. }
  101. }
  102. /*
  103. ================
  104. idAFConstraint::SetBody2
  105. ================
  106. */
  107. void idAFConstraint::SetBody2( idAFBody *body ) {
  108. if ( body2 != body ) {
  109. body2 = body;
  110. if ( physics ) {
  111. physics->SetChanged();
  112. }
  113. }
  114. }
  115. /*
  116. ================
  117. idAFConstraint::GetMultiplier
  118. ================
  119. */
  120. const idVecX &idAFConstraint::GetMultiplier() {
  121. return lm;
  122. }
  123. /*
  124. ================
  125. idAFConstraint::Evaluate
  126. ================
  127. */
  128. void idAFConstraint::Evaluate( float invTimeStep ) {
  129. assert( 0 );
  130. }
  131. /*
  132. ================
  133. idAFConstraint::ApplyFriction
  134. ================
  135. */
  136. void idAFConstraint::ApplyFriction( float invTimeStep ) {
  137. }
  138. /*
  139. ================
  140. idAFConstraint::GetForce
  141. ================
  142. */
  143. void idAFConstraint::GetForce( idAFBody *body, idVec6 &force ) {
  144. idVecX v;
  145. v.SetData( 6, VECX_ALLOCA( 6 ) );
  146. if ( body == body1 ) {
  147. J1.TransposeMultiply( v, lm );
  148. }
  149. else if ( body == body2 ) {
  150. J2.TransposeMultiply( v, lm );
  151. }
  152. else {
  153. v.Zero();
  154. }
  155. force[0] = v[0]; force[1] = v[1]; force[2] = v[2]; force[3] = v[3]; force[4] = v[4]; force[5] = v[5];
  156. }
  157. /*
  158. ================
  159. idAFConstraint::Translate
  160. ================
  161. */
  162. void idAFConstraint::Translate( const idVec3 &translation ) {
  163. assert( 0 );
  164. }
  165. /*
  166. ================
  167. idAFConstraint::Rotate
  168. ================
  169. */
  170. void idAFConstraint::Rotate( const idRotation &rotation ) {
  171. assert( 0 );
  172. }
  173. /*
  174. ================
  175. idAFConstraint::GetCenter
  176. ================
  177. */
  178. void idAFConstraint::GetCenter( idVec3 &center ) {
  179. center.Zero();
  180. }
  181. /*
  182. ================
  183. idAFConstraint::DebugDraw
  184. ================
  185. */
  186. void idAFConstraint::DebugDraw() {
  187. }
  188. /*
  189. ================
  190. idAFConstraint::InitSize
  191. ================
  192. */
  193. void idAFConstraint::InitSize( int size ) {
  194. J1.Zero( size, 6 );
  195. J2.Zero( size, 6 );
  196. c1.Zero( size );
  197. c2.Zero( size );
  198. s.Zero( size );
  199. lm.Zero( size );
  200. }
  201. /*
  202. ================
  203. idAFConstraint::Save
  204. ================
  205. */
  206. void idAFConstraint::Save( idSaveGame *saveFile ) const {
  207. saveFile->WriteInt( type );
  208. }
  209. /*
  210. ================
  211. idAFConstraint::Restore
  212. ================
  213. */
  214. void idAFConstraint::Restore( idRestoreGame *saveFile ) {
  215. constraintType_t t;
  216. saveFile->ReadInt( (int &)t );
  217. assert( t == type );
  218. }
  219. //===============================================================
  220. //
  221. // idAFConstraint_Fixed
  222. //
  223. //===============================================================
  224. /*
  225. ================
  226. idAFConstraint_Fixed::idAFConstraint_Fixed
  227. ================
  228. */
  229. idAFConstraint_Fixed::idAFConstraint_Fixed( const idStr &name, idAFBody *body1, idAFBody *body2 ) {
  230. assert( body1 );
  231. type = CONSTRAINT_FIXED;
  232. this->name = name;
  233. this->body1 = body1;
  234. this->body2 = body2;
  235. InitSize( 6 );
  236. fl.allowPrimary = true;
  237. fl.noCollision = true;
  238. InitOffset();
  239. }
  240. /*
  241. ================
  242. idAFConstraint_Fixed::InitOffset
  243. ================
  244. */
  245. void idAFConstraint_Fixed::InitOffset() {
  246. if ( body2 ) {
  247. offset = ( body1->GetWorldOrigin() - body2->GetWorldOrigin() ) * body2->GetWorldAxis().Transpose();
  248. relAxis = body1->GetWorldAxis() * body2->GetWorldAxis().Transpose();
  249. }
  250. else {
  251. offset = body1->GetWorldOrigin();
  252. relAxis = body1->GetWorldAxis();
  253. }
  254. }
  255. /*
  256. ================
  257. idAFConstraint_Fixed::SetBody1
  258. ================
  259. */
  260. void idAFConstraint_Fixed::SetBody1( idAFBody *body ) {
  261. if ( body1 != body) {
  262. body1 = body;
  263. InitOffset();
  264. if ( physics ) {
  265. physics->SetChanged();
  266. }
  267. }
  268. }
  269. /*
  270. ================
  271. idAFConstraint_Fixed::SetBody2
  272. ================
  273. */
  274. void idAFConstraint_Fixed::SetBody2( idAFBody *body ) {
  275. if ( body2 != body ) {
  276. body2 = body;
  277. InitOffset();
  278. if ( physics ) {
  279. physics->SetChanged();
  280. }
  281. }
  282. }
  283. /*
  284. ================
  285. idAFConstraint_Fixed::Evaluate
  286. ================
  287. */
  288. void idAFConstraint_Fixed::Evaluate( float invTimeStep ) {
  289. idVec3 ofs, a2;
  290. idMat3 ax;
  291. idRotation r;
  292. idAFBody *master;
  293. master = body2 ? body2 : physics->GetMasterBody();
  294. if ( master ) {
  295. a2 = offset * master->GetWorldAxis();
  296. ofs = a2 + master->GetWorldOrigin();
  297. ax = relAxis * master->GetWorldAxis();
  298. }
  299. else {
  300. a2.Zero();
  301. ofs = offset;
  302. ax = relAxis;
  303. }
  304. J1.Set( mat3_identity, mat3_zero,
  305. mat3_zero, mat3_identity );
  306. if ( body2 ) {
  307. J2.Set( -mat3_identity, SkewSymmetric( a2 ),
  308. mat3_zero, -mat3_identity );
  309. }
  310. else {
  311. J2.Zero( 6, 6 );
  312. }
  313. c1.SubVec3(0) = -( invTimeStep * ERROR_REDUCTION ) * ( ofs - body1->GetWorldOrigin() );
  314. r = ( body1->GetWorldAxis().Transpose() * ax ).ToRotation();
  315. c1.SubVec3(1) = -( invTimeStep * ERROR_REDUCTION ) * ( r.GetVec() * -(float) DEG2RAD( r.GetAngle() ) );
  316. c1.Clamp( -ERROR_REDUCTION_MAX, ERROR_REDUCTION_MAX );
  317. }
  318. /*
  319. ================
  320. idAFConstraint_Fixed::ApplyFriction
  321. ================
  322. */
  323. void idAFConstraint_Fixed::ApplyFriction( float invTimeStep ) {
  324. // no friction
  325. }
  326. /*
  327. ================
  328. idAFConstraint_Fixed::Translate
  329. ================
  330. */
  331. void idAFConstraint_Fixed::Translate( const idVec3 &translation ) {
  332. if ( !body2 ) {
  333. offset += translation;
  334. }
  335. }
  336. /*
  337. ================
  338. idAFConstraint_Fixed::Rotate
  339. ================
  340. */
  341. void idAFConstraint_Fixed::Rotate( const idRotation &rotation ) {
  342. if ( !body2 ) {
  343. offset *= rotation;
  344. relAxis *= rotation.ToMat3();
  345. }
  346. }
  347. /*
  348. ================
  349. idAFConstraint_Fixed::GetCenter
  350. ================
  351. */
  352. void idAFConstraint_Fixed::GetCenter( idVec3 &center ) {
  353. center = body1->GetWorldOrigin();
  354. }
  355. /*
  356. ================
  357. idAFConstraint_Fixed::DebugDraw
  358. ================
  359. */
  360. void idAFConstraint_Fixed::DebugDraw() {
  361. idAFBody *master;
  362. master = body2 ? body2 : physics->GetMasterBody();
  363. if ( master ) {
  364. gameRenderWorld->DebugLine( colorRed, body1->GetWorldOrigin(), master->GetWorldOrigin() );
  365. }
  366. else {
  367. gameRenderWorld->DebugLine( colorRed, body1->GetWorldOrigin(), vec3_origin );
  368. }
  369. }
  370. /*
  371. ================
  372. idAFConstraint_Fixed::Save
  373. ================
  374. */
  375. void idAFConstraint_Fixed::Save( idSaveGame *saveFile ) const {
  376. idAFConstraint::Save( saveFile );
  377. saveFile->WriteVec3( offset );
  378. saveFile->WriteMat3( relAxis );
  379. }
  380. /*
  381. ================
  382. idAFConstraint_Fixed::Restore
  383. ================
  384. */
  385. void idAFConstraint_Fixed::Restore( idRestoreGame *saveFile ) {
  386. idAFConstraint::Restore( saveFile );
  387. saveFile->ReadVec3( offset );
  388. saveFile->ReadMat3( relAxis );
  389. }
  390. //===============================================================
  391. //
  392. // idAFConstraint_BallAndSocketJoint
  393. //
  394. //===============================================================
  395. /*
  396. ================
  397. idAFConstraint_BallAndSocketJoint::idAFConstraint_BallAndSocketJoint
  398. ================
  399. */
  400. idAFConstraint_BallAndSocketJoint::idAFConstraint_BallAndSocketJoint( const idStr &name, idAFBody *body1, idAFBody *body2 ) {
  401. assert( body1 );
  402. type = CONSTRAINT_BALLANDSOCKETJOINT;
  403. this->name = name;
  404. this->body1 = body1;
  405. this->body2 = body2;
  406. InitSize( 3 );
  407. coneLimit = NULL;
  408. pyramidLimit = NULL;
  409. friction = 0.0f;
  410. fc = NULL;
  411. fl.allowPrimary = true;
  412. fl.noCollision = true;
  413. }
  414. /*
  415. ================
  416. idAFConstraint_BallAndSocketJoint::~idAFConstraint_BallAndSocketJoint
  417. ================
  418. */
  419. idAFConstraint_BallAndSocketJoint::~idAFConstraint_BallAndSocketJoint() {
  420. if ( coneLimit ) {
  421. delete coneLimit;
  422. }
  423. if ( pyramidLimit ) {
  424. delete pyramidLimit;
  425. }
  426. }
  427. /*
  428. ================
  429. idAFConstraint_BallAndSocketJoint::SetAnchor
  430. ================
  431. */
  432. void idAFConstraint_BallAndSocketJoint::SetAnchor( const idVec3 &worldPosition ) {
  433. // get anchor relative to center of mass of body1
  434. anchor1 = ( worldPosition - body1->GetWorldOrigin() ) * body1->GetWorldAxis().Transpose();
  435. if ( body2 ) {
  436. // get anchor relative to center of mass of body2
  437. anchor2 = ( worldPosition - body2->GetWorldOrigin() ) * body2->GetWorldAxis().Transpose();
  438. }
  439. else {
  440. anchor2 = worldPosition;
  441. }
  442. if ( coneLimit ) {
  443. coneLimit->SetAnchor( anchor2 );
  444. }
  445. if ( pyramidLimit ) {
  446. pyramidLimit->SetAnchor( anchor2 );
  447. }
  448. }
  449. /*
  450. ================
  451. idAFConstraint_BallAndSocketJoint::GetAnchor
  452. ================
  453. */
  454. idVec3 idAFConstraint_BallAndSocketJoint::GetAnchor() const {
  455. if ( body2 ) {
  456. return body2->GetWorldOrigin() + body2->GetWorldAxis() * anchor2;
  457. }
  458. return anchor2;
  459. }
  460. /*
  461. ================
  462. idAFConstraint_BallAndSocketJoint::SetNoLimit
  463. ================
  464. */
  465. void idAFConstraint_BallAndSocketJoint::SetNoLimit() {
  466. if ( coneLimit ) {
  467. delete coneLimit;
  468. coneLimit = NULL;
  469. }
  470. if ( pyramidLimit ) {
  471. delete pyramidLimit;
  472. pyramidLimit = NULL;
  473. }
  474. }
  475. /*
  476. ================
  477. idAFConstraint_BallAndSocketJoint::SetConeLimit
  478. ================
  479. */
  480. void idAFConstraint_BallAndSocketJoint::SetConeLimit( const idVec3 &coneAxis, const float coneAngle, const idVec3 &body1Axis ) {
  481. if ( pyramidLimit ) {
  482. delete pyramidLimit;
  483. pyramidLimit = NULL;
  484. }
  485. if ( !coneLimit ) {
  486. coneLimit = new (TAG_PHYSICS_AF) idAFConstraint_ConeLimit;
  487. coneLimit->SetPhysics( physics );
  488. }
  489. if ( body2 ) {
  490. coneLimit->Setup( body1, body2, anchor2, coneAxis * body2->GetWorldAxis().Transpose(), coneAngle, body1Axis * body1->GetWorldAxis().Transpose() );
  491. }
  492. else {
  493. coneLimit->Setup( body1, body2, anchor2, coneAxis, coneAngle, body1Axis * body1->GetWorldAxis().Transpose() );
  494. }
  495. }
  496. /*
  497. ================
  498. idAFConstraint_BallAndSocketJoint::SetPyramidLimit
  499. ================
  500. */
  501. void idAFConstraint_BallAndSocketJoint::SetPyramidLimit( const idVec3 &pyramidAxis, const idVec3 &baseAxis,
  502. const float angle1, const float angle2, const idVec3 &body1Axis ) {
  503. if ( coneLimit ) {
  504. delete coneLimit;
  505. coneLimit = NULL;
  506. }
  507. if ( !pyramidLimit ) {
  508. pyramidLimit = new (TAG_PHYSICS_AF) idAFConstraint_PyramidLimit;
  509. pyramidLimit->SetPhysics( physics );
  510. }
  511. if ( body2 ) {
  512. pyramidLimit->Setup( body1, body2, anchor2, pyramidAxis * body2->GetWorldAxis().Transpose(),
  513. baseAxis * body2->GetWorldAxis().Transpose(), angle1, angle2,
  514. body1Axis * body1->GetWorldAxis().Transpose() );
  515. }
  516. else {
  517. pyramidLimit->Setup( body1, body2, anchor2, pyramidAxis, baseAxis, angle1, angle2,
  518. body1Axis * body1->GetWorldAxis().Transpose() );
  519. }
  520. }
  521. /*
  522. ================
  523. idAFConstraint_BallAndSocketJoint::SetLimitEpsilon
  524. ================
  525. */
  526. void idAFConstraint_BallAndSocketJoint::SetLimitEpsilon( const float e ) {
  527. if ( coneLimit ) {
  528. coneLimit->SetEpsilon( e );
  529. }
  530. if ( pyramidLimit ) {
  531. pyramidLimit->SetEpsilon( e );
  532. }
  533. }
  534. /*
  535. ================
  536. idAFConstraint_BallAndSocketJoint::GetFriction
  537. ================
  538. */
  539. float idAFConstraint_BallAndSocketJoint::GetFriction() const {
  540. if ( af_forceFriction.GetFloat() > 0.0f ) {
  541. return af_forceFriction.GetFloat();
  542. }
  543. return friction * physics->GetJointFrictionScale();
  544. }
  545. /*
  546. ================
  547. idAFConstraint_BallAndSocketJoint::Evaluate
  548. ================
  549. */
  550. void idAFConstraint_BallAndSocketJoint::Evaluate( float invTimeStep ) {
  551. idVec3 a1, a2;
  552. idAFBody *master;
  553. master = body2 ? body2 : physics->GetMasterBody();
  554. a1 = anchor1 * body1->GetWorldAxis();
  555. if ( master ) {
  556. a2 = anchor2 * master->GetWorldAxis();
  557. c1.SubVec3(0) = -( invTimeStep * ERROR_REDUCTION ) * ( a2 + master->GetWorldOrigin() - ( a1 + body1->GetWorldOrigin() ) );
  558. }
  559. else {
  560. c1.SubVec3(0) = -( invTimeStep * ERROR_REDUCTION ) * ( anchor2 - ( a1 + body1->GetWorldOrigin() ) );
  561. }
  562. c1.Clamp( -ERROR_REDUCTION_MAX, ERROR_REDUCTION_MAX );
  563. J1.Set( mat3_identity, -SkewSymmetric( a1 ) );
  564. if ( body2 ) {
  565. J2.Set( -mat3_identity, SkewSymmetric( a2 ) );
  566. }
  567. else {
  568. J2.Zero( 3, 6 );
  569. }
  570. if ( coneLimit ) {
  571. coneLimit->Add( physics, invTimeStep );
  572. }
  573. else if ( pyramidLimit ) {
  574. pyramidLimit->Add( physics, invTimeStep );
  575. }
  576. }
  577. /*
  578. ================
  579. idAFConstraint_BallAndSocketJoint::ApplyFriction
  580. ================
  581. */
  582. void idAFConstraint_BallAndSocketJoint::ApplyFriction( float invTimeStep ) {
  583. idVec3 angular;
  584. float invMass, currentFriction;
  585. currentFriction = GetFriction();
  586. if ( currentFriction <= 0.0f ) {
  587. return;
  588. }
  589. if ( af_useImpulseFriction.GetBool() || af_useJointImpulseFriction.GetBool() ) {
  590. angular = body1->GetAngularVelocity();
  591. invMass = body1->GetInverseMass();
  592. if ( body2 ) {
  593. angular -= body2->GetAngularVelocity();
  594. invMass += body2->GetInverseMass();
  595. }
  596. angular *= currentFriction / invMass;
  597. body1->SetAngularVelocity( body1->GetAngularVelocity() - angular * body1->GetInverseMass() );
  598. if ( body2 ) {
  599. body2->SetAngularVelocity( body2->GetAngularVelocity() + angular * body2->GetInverseMass() );
  600. }
  601. }
  602. else {
  603. if ( !fc ) {
  604. fc = new (TAG_PHYSICS_AF) idAFConstraint_BallAndSocketJointFriction;
  605. fc->Setup( this );
  606. }
  607. fc->Add( physics, invTimeStep );
  608. }
  609. }
  610. /*
  611. ================
  612. idAFConstraint_BallAndSocketJoint::GetForce
  613. ================
  614. */
  615. void idAFConstraint_BallAndSocketJoint::GetForce( idAFBody *body, idVec6 &force ) {
  616. idAFConstraint::GetForce( body, force );
  617. // FIXME: add limit force
  618. }
  619. /*
  620. ================
  621. idAFConstraint_BallAndSocketJoint::Translate
  622. ================
  623. */
  624. void idAFConstraint_BallAndSocketJoint::Translate( const idVec3 &translation ) {
  625. if ( !body2 ) {
  626. anchor2 += translation;
  627. }
  628. if ( coneLimit ) {
  629. coneLimit->Translate( translation );
  630. }
  631. else if ( pyramidLimit ) {
  632. pyramidLimit->Translate( translation );
  633. }
  634. }
  635. /*
  636. ================
  637. idAFConstraint_BallAndSocketJoint::Rotate
  638. ================
  639. */
  640. void idAFConstraint_BallAndSocketJoint::Rotate( const idRotation &rotation ) {
  641. if ( !body2 ) {
  642. anchor2 *= rotation;
  643. }
  644. if ( coneLimit ) {
  645. coneLimit->Rotate( rotation );
  646. }
  647. else if ( pyramidLimit ) {
  648. pyramidLimit->Rotate( rotation );
  649. }
  650. }
  651. /*
  652. ================
  653. idAFConstraint_BallAndSocketJoint::GetCenter
  654. ================
  655. */
  656. void idAFConstraint_BallAndSocketJoint::GetCenter( idVec3 &center ) {
  657. center = body1->GetWorldOrigin() + anchor1 * body1->GetWorldAxis();
  658. }
  659. /*
  660. ================
  661. idAFConstraint_BallAndSocketJoint::DebugDraw
  662. ================
  663. */
  664. void idAFConstraint_BallAndSocketJoint::DebugDraw() {
  665. idVec3 a1 = body1->GetWorldOrigin() + anchor1 * body1->GetWorldAxis();
  666. gameRenderWorld->DebugLine( colorBlue, a1 - idVec3( 5, 0, 0 ), a1 + idVec3( 5, 0, 0 ) );
  667. gameRenderWorld->DebugLine( colorBlue, a1 - idVec3( 0, 5, 0 ), a1 + idVec3( 0, 5, 0 ) );
  668. gameRenderWorld->DebugLine( colorBlue, a1 - idVec3( 0, 0, 5 ), a1 + idVec3( 0, 0, 5 ) );
  669. if ( af_showLimits.GetBool() ) {
  670. if ( coneLimit ) {
  671. coneLimit->DebugDraw();
  672. }
  673. if ( pyramidLimit ) {
  674. pyramidLimit->DebugDraw();
  675. }
  676. }
  677. }
  678. /*
  679. ================
  680. idAFConstraint_BallAndSocketJoint::Save
  681. ================
  682. */
  683. void idAFConstraint_BallAndSocketJoint::Save( idSaveGame *saveFile ) const {
  684. idAFConstraint::Save( saveFile );
  685. saveFile->WriteVec3( anchor1 );
  686. saveFile->WriteVec3( anchor2 );
  687. saveFile->WriteFloat( friction );
  688. if ( coneLimit ) {
  689. coneLimit->Save( saveFile );
  690. }
  691. if ( pyramidLimit ) {
  692. pyramidLimit->Save( saveFile );
  693. }
  694. }
  695. /*
  696. ================
  697. idAFConstraint_BallAndSocketJoint::Restore
  698. ================
  699. */
  700. void idAFConstraint_BallAndSocketJoint::Restore( idRestoreGame *saveFile ) {
  701. idAFConstraint::Restore( saveFile );
  702. saveFile->ReadVec3( anchor1 );
  703. saveFile->ReadVec3( anchor2 );
  704. saveFile->ReadFloat( friction );
  705. if ( coneLimit ) {
  706. coneLimit->Restore( saveFile );
  707. }
  708. if ( pyramidLimit ) {
  709. pyramidLimit->Restore( saveFile );
  710. }
  711. }
  712. //===============================================================
  713. //
  714. // idAFConstraint_BallAndSocketJointFriction
  715. //
  716. //===============================================================
  717. /*
  718. ================
  719. idAFConstraint_BallAndSocketJointFriction::idAFConstraint_BallAndSocketJointFriction
  720. ================
  721. */
  722. idAFConstraint_BallAndSocketJointFriction::idAFConstraint_BallAndSocketJointFriction() {
  723. type = CONSTRAINT_FRICTION;
  724. name = "ballAndSocketJointFriction";
  725. InitSize( 3 );
  726. joint = NULL;
  727. fl.allowPrimary = false;
  728. fl.frameConstraint = true;
  729. }
  730. /*
  731. ================
  732. idAFConstraint_BallAndSocketJointFriction::Setup
  733. ================
  734. */
  735. void idAFConstraint_BallAndSocketJointFriction::Setup( idAFConstraint_BallAndSocketJoint *bsj ) {
  736. this->joint = bsj;
  737. body1 = bsj->GetBody1();
  738. body2 = bsj->GetBody2();
  739. }
  740. /*
  741. ================
  742. idAFConstraint_BallAndSocketJointFriction::Evaluate
  743. ================
  744. */
  745. void idAFConstraint_BallAndSocketJointFriction::Evaluate( float invTimeStep ) {
  746. // do nothing
  747. }
  748. /*
  749. ================
  750. idAFConstraint_BallAndSocketJointFriction::ApplyFriction
  751. ================
  752. */
  753. void idAFConstraint_BallAndSocketJointFriction::ApplyFriction( float invTimeStep ) {
  754. // do nothing
  755. }
  756. /*
  757. ================
  758. idAFConstraint_BallAndSocketJointFriction::Add
  759. ================
  760. */
  761. bool idAFConstraint_BallAndSocketJointFriction::Add( idPhysics_AF *phys, float invTimeStep ) {
  762. float f;
  763. physics = phys;
  764. f = joint->GetFriction() * joint->GetMultiplier().Length();
  765. if ( f == 0.0f ) {
  766. return false;
  767. }
  768. lo[0] = lo[1] = lo[2] = -f;
  769. hi[0] = hi[1] = hi[2] = f;
  770. J1.Zero( 3, 6 );
  771. J1[0][3] = J1[1][4] = J1[2][5] = 1.0f;
  772. if ( body2 ) {
  773. J2.Zero( 3, 6 );
  774. J2[0][3] = J2[1][4] = J2[2][5] = 1.0f;
  775. }
  776. physics->AddFrameConstraint( this );
  777. return true;
  778. }
  779. /*
  780. ================
  781. idAFConstraint_BallAndSocketJointFriction::Translate
  782. ================
  783. */
  784. void idAFConstraint_BallAndSocketJointFriction::Translate( const idVec3 &translation ) {
  785. }
  786. /*
  787. ================
  788. idAFConstraint_BallAndSocketJointFriction::Rotate
  789. ================
  790. */
  791. void idAFConstraint_BallAndSocketJointFriction::Rotate( const idRotation &rotation ) {
  792. }
  793. //===============================================================
  794. //
  795. // idAFConstraint_UniversalJoint
  796. //
  797. //===============================================================
  798. /*
  799. ================
  800. idAFConstraint_UniversalJoint::idAFConstraint_UniversalJoint
  801. ================
  802. */
  803. idAFConstraint_UniversalJoint::idAFConstraint_UniversalJoint( const idStr &name, idAFBody *body1, idAFBody *body2 ) {
  804. assert( body1 );
  805. type = CONSTRAINT_UNIVERSALJOINT;
  806. this->name = name;
  807. this->body1 = body1;
  808. this->body2 = body2;
  809. InitSize( 4 );
  810. coneLimit = NULL;
  811. pyramidLimit = NULL;
  812. friction = 0.0f;
  813. fc = NULL;
  814. fl.allowPrimary = true;
  815. fl.noCollision = true;
  816. }
  817. /*
  818. ================
  819. idAFConstraint_UniversalJoint::~idAFConstraint_UniversalJoint
  820. ================
  821. */
  822. idAFConstraint_UniversalJoint::~idAFConstraint_UniversalJoint() {
  823. if ( coneLimit ) {
  824. delete coneLimit;
  825. }
  826. if ( pyramidLimit ) {
  827. delete pyramidLimit;
  828. }
  829. if ( fc ) {
  830. delete fc;
  831. }
  832. }
  833. /*
  834. ================
  835. idAFConstraint_UniversalJoint::SetAnchor
  836. ================
  837. */
  838. void idAFConstraint_UniversalJoint::SetAnchor( const idVec3 &worldPosition ) {
  839. // get anchor relative to center of mass of body1
  840. anchor1 = ( worldPosition - body1->GetWorldOrigin() ) * body1->GetWorldAxis().Transpose();
  841. if ( body2 ) {
  842. // get anchor relative to center of mass of body2
  843. anchor2 = ( worldPosition - body2->GetWorldOrigin() ) * body2->GetWorldAxis().Transpose();
  844. }
  845. else {
  846. anchor2 = worldPosition;
  847. }
  848. if ( coneLimit ) {
  849. coneLimit->SetAnchor( anchor2 );
  850. }
  851. if ( pyramidLimit ) {
  852. pyramidLimit->SetAnchor( anchor2 );
  853. }
  854. }
  855. /*
  856. ================
  857. idAFConstraint_UniversalJoint::GetAnchor
  858. ================
  859. */
  860. idVec3 idAFConstraint_UniversalJoint::GetAnchor() const {
  861. if ( body2 ) {
  862. return body2->GetWorldOrigin() + body2->GetWorldAxis() * anchor2;
  863. }
  864. return anchor2;
  865. }
  866. /*
  867. ================
  868. idAFConstraint_UniversalJoint::SetShafts
  869. ================
  870. */
  871. void idAFConstraint_UniversalJoint::SetShafts( const idVec3 &cardanShaft1, const idVec3 &cardanShaft2 ) {
  872. idVec3 cardanAxis;
  873. float l;
  874. shaft1 = cardanShaft1;
  875. l = shaft1.Normalize();
  876. assert( l != 0.0f );
  877. shaft2 = cardanShaft2;
  878. l = shaft2.Normalize();
  879. assert( l != 0.0f );
  880. // the cardan axis is a vector orthogonal to both cardan shafts
  881. cardanAxis = shaft1.Cross( shaft2 );
  882. if ( cardanAxis.Normalize() == 0.0f ) {
  883. idVec3 vecY;
  884. shaft1.OrthogonalBasis( cardanAxis, vecY );
  885. cardanAxis.Normalize();
  886. }
  887. shaft1 *= body1->GetWorldAxis().Transpose();
  888. axis1 = cardanAxis * body1->GetWorldAxis().Transpose();
  889. if ( body2 ) {
  890. shaft2 *= body2->GetWorldAxis().Transpose();
  891. axis2 = cardanAxis * body2->GetWorldAxis().Transpose();
  892. }
  893. else {
  894. axis2 = cardanAxis;
  895. }
  896. if ( coneLimit ) {
  897. coneLimit->SetBody1Axis( shaft1 );
  898. }
  899. if ( pyramidLimit ) {
  900. pyramidLimit->SetBody1Axis( shaft1 );
  901. }
  902. }
  903. /*
  904. ================
  905. idAFConstraint_UniversalJoint::SetNoLimit
  906. ================
  907. */
  908. void idAFConstraint_UniversalJoint::SetNoLimit() {
  909. if ( coneLimit ) {
  910. delete coneLimit;
  911. coneLimit = NULL;
  912. }
  913. if ( pyramidLimit ) {
  914. delete pyramidLimit;
  915. pyramidLimit = NULL;
  916. }
  917. }
  918. /*
  919. ================
  920. idAFConstraint_UniversalJoint::SetConeLimit
  921. ================
  922. */
  923. void idAFConstraint_UniversalJoint::SetConeLimit( const idVec3 &coneAxis, const float coneAngle ) {
  924. if ( pyramidLimit ) {
  925. delete pyramidLimit;
  926. pyramidLimit = NULL;
  927. }
  928. if ( !coneLimit ) {
  929. coneLimit = new (TAG_PHYSICS_AF) idAFConstraint_ConeLimit;
  930. coneLimit->SetPhysics( physics );
  931. }
  932. if ( body2 ) {
  933. coneLimit->Setup( body1, body2, anchor2, coneAxis * body2->GetWorldAxis().Transpose(), coneAngle, shaft1 );
  934. }
  935. else {
  936. coneLimit->Setup( body1, body2, anchor2, coneAxis, coneAngle, shaft1 );
  937. }
  938. }
  939. /*
  940. ================
  941. idAFConstraint_UniversalJoint::SetPyramidLimit
  942. ================
  943. */
  944. void idAFConstraint_UniversalJoint::SetPyramidLimit( const idVec3 &pyramidAxis, const idVec3 &baseAxis,
  945. const float angle1, const float angle2 ) {
  946. if ( coneLimit ) {
  947. delete coneLimit;
  948. coneLimit = NULL;
  949. }
  950. if ( !pyramidLimit ) {
  951. pyramidLimit = new (TAG_PHYSICS_AF) idAFConstraint_PyramidLimit;
  952. pyramidLimit->SetPhysics( physics );
  953. }
  954. if ( body2 ) {
  955. pyramidLimit->Setup( body1, body2, anchor2, pyramidAxis * body2->GetWorldAxis().Transpose(),
  956. baseAxis * body2->GetWorldAxis().Transpose(), angle1, angle2, shaft1 );
  957. }
  958. else {
  959. pyramidLimit->Setup( body1, body2, anchor2, pyramidAxis, baseAxis, angle1, angle2, shaft1 );
  960. }
  961. }
  962. /*
  963. ================
  964. idAFConstraint_UniversalJoint::SetLimitEpsilon
  965. ================
  966. */
  967. void idAFConstraint_UniversalJoint::SetLimitEpsilon( const float e ) {
  968. if ( coneLimit ) {
  969. coneLimit->SetEpsilon( e );
  970. }
  971. if ( pyramidLimit ) {
  972. pyramidLimit->SetEpsilon( e );
  973. }
  974. }
  975. /*
  976. ================
  977. idAFConstraint_UniversalJoint::GetFriction
  978. ================
  979. */
  980. float idAFConstraint_UniversalJoint::GetFriction() const {
  981. if ( af_forceFriction.GetFloat() > 0.0f ) {
  982. return af_forceFriction.GetFloat();
  983. }
  984. return friction * physics->GetJointFrictionScale();
  985. }
  986. /*
  987. ================
  988. idAFConstraint_UniversalJoint::Evaluate
  989. NOTE: this joint is homokinetic
  990. ================
  991. */
  992. void idAFConstraint_UniversalJoint::Evaluate( float invTimeStep ) {
  993. idVec3 a1, a2, s1, s2, d1, d2, v;
  994. idAFBody *master;
  995. master = body2 ? body2 : physics->GetMasterBody();
  996. a1 = anchor1 * body1->GetWorldAxis();
  997. s1 = shaft1 * body1->GetWorldAxis();
  998. d1 = s1.Cross( axis1 * body1->GetWorldAxis() );
  999. if ( master ) {
  1000. a2 = anchor2 * master->GetWorldAxis();
  1001. s2 = shaft2 * master->GetWorldAxis();
  1002. d2 = axis2 * master->GetWorldAxis();
  1003. c1.SubVec3(0) = -( invTimeStep * ERROR_REDUCTION ) * ( a2 + master->GetWorldOrigin() - ( a1 + body1->GetWorldOrigin() ) );
  1004. }
  1005. else {
  1006. a2 = anchor2;
  1007. s2 = shaft2;
  1008. d2 = axis2;
  1009. c1.SubVec3(0) = -( invTimeStep * ERROR_REDUCTION ) * ( a2 - ( a1 + body1->GetWorldOrigin() ) );
  1010. }
  1011. J1.Set( mat3_identity, -SkewSymmetric( a1 ),
  1012. mat3_zero, idMat3( s1[0], s1[1], s1[2],
  1013. 0.0f, 0.0f, 0.0f,
  1014. 0.0f, 0.0f, 0.0f ) );
  1015. J1.SetSize( 4, 6 );
  1016. if ( body2 ) {
  1017. J2.Set( -mat3_identity, SkewSymmetric( a2 ),
  1018. mat3_zero, idMat3( s2[0], s2[1], s2[2],
  1019. 0.0f, 0.0f, 0.0f,
  1020. 0.0f, 0.0f, 0.0f ) );
  1021. J2.SetSize( 4, 6 );
  1022. }
  1023. else {
  1024. J2.Zero( 4, 6 );
  1025. }
  1026. v = s1.Cross( s2 );
  1027. if ( v.Normalize() != 0.0f ) {
  1028. idMat3 m1, m2;
  1029. m1[0] = s1;
  1030. m1[1] = v;
  1031. m1[2] = v.Cross( m1[0] );
  1032. m2[0] = -s2;
  1033. m2[1] = v;
  1034. m2[2] = v.Cross( m2[0] );
  1035. d2 *= m2.Transpose() * m1;
  1036. }
  1037. c1[3] = -( invTimeStep * ERROR_REDUCTION ) * ( d1 * d2 );
  1038. c1.Clamp( -ERROR_REDUCTION_MAX, ERROR_REDUCTION_MAX );
  1039. if ( coneLimit ) {
  1040. coneLimit->Add( physics, invTimeStep );
  1041. }
  1042. else if ( pyramidLimit ) {
  1043. pyramidLimit->Add( physics, invTimeStep );
  1044. }
  1045. }
  1046. /*
  1047. ================
  1048. idAFConstraint_UniversalJoint::ApplyFriction
  1049. ================
  1050. */
  1051. void idAFConstraint_UniversalJoint::ApplyFriction( float invTimeStep ) {
  1052. idVec3 angular;
  1053. float invMass, currentFriction;
  1054. currentFriction = GetFriction();
  1055. if ( currentFriction <= 0.0f ) {
  1056. return;
  1057. }
  1058. if ( af_useImpulseFriction.GetBool() || af_useJointImpulseFriction.GetBool() ) {
  1059. angular = body1->GetAngularVelocity();
  1060. invMass = body1->GetInverseMass();
  1061. if ( body2 ) {
  1062. angular -= body2->GetAngularVelocity();
  1063. invMass += body2->GetInverseMass();
  1064. }
  1065. angular *= currentFriction / invMass;
  1066. body1->SetAngularVelocity( body1->GetAngularVelocity() - angular * body1->GetInverseMass() );
  1067. if ( body2 ) {
  1068. body2->SetAngularVelocity( body2->GetAngularVelocity() + angular * body2->GetInverseMass() );
  1069. }
  1070. }
  1071. else {
  1072. if ( !fc ) {
  1073. fc = new (TAG_PHYSICS_AF) idAFConstraint_UniversalJointFriction;
  1074. fc->Setup( this );
  1075. }
  1076. fc->Add( physics, invTimeStep );
  1077. }
  1078. }
  1079. /*
  1080. ================
  1081. idAFConstraint_UniversalJoint::GetForce
  1082. ================
  1083. */
  1084. void idAFConstraint_UniversalJoint::GetForce( idAFBody *body, idVec6 &force ) {
  1085. idAFConstraint::GetForce( body, force );
  1086. // FIXME: add limit force
  1087. }
  1088. /*
  1089. ================
  1090. idAFConstraint_UniversalJoint::Translate
  1091. ================
  1092. */
  1093. void idAFConstraint_UniversalJoint::Translate( const idVec3 &translation ) {
  1094. if ( !body2 ) {
  1095. anchor2 += translation;
  1096. }
  1097. if ( coneLimit ) {
  1098. coneLimit->Translate( translation );
  1099. }
  1100. else if ( pyramidLimit ) {
  1101. pyramidLimit->Translate( translation );
  1102. }
  1103. }
  1104. /*
  1105. ================
  1106. idAFConstraint_UniversalJoint::Rotate
  1107. ================
  1108. */
  1109. void idAFConstraint_UniversalJoint::Rotate( const idRotation &rotation ) {
  1110. if ( !body2 ) {
  1111. anchor2 *= rotation;
  1112. shaft2 *= rotation.ToMat3();
  1113. axis2 *= rotation.ToMat3();
  1114. }
  1115. if ( coneLimit ) {
  1116. coneLimit->Rotate( rotation );
  1117. }
  1118. else if ( pyramidLimit ) {
  1119. pyramidLimit->Rotate( rotation );
  1120. }
  1121. }
  1122. /*
  1123. ================
  1124. idAFConstraint_UniversalJoint::GetCenter
  1125. ================
  1126. */
  1127. void idAFConstraint_UniversalJoint::GetCenter( idVec3 &center ) {
  1128. center = body1->GetWorldOrigin() + anchor1 * body1->GetWorldAxis();
  1129. }
  1130. /*
  1131. ================
  1132. idAFConstraint_UniversalJoint::DebugDraw
  1133. ================
  1134. */
  1135. void idAFConstraint_UniversalJoint::DebugDraw() {
  1136. idVec3 a1, a2, s1, s2, d1, d2, v;
  1137. idAFBody *master;
  1138. master = body2 ? body2 : physics->GetMasterBody();
  1139. a1 = body1->GetWorldOrigin() + anchor1 * body1->GetWorldAxis();
  1140. s1 = shaft1 * body1->GetWorldAxis();
  1141. d1 = axis1 * body1->GetWorldAxis();
  1142. if ( master ) {
  1143. a2 = master->GetWorldOrigin() + anchor2 * master->GetWorldAxis();
  1144. s2 = shaft2 * master->GetWorldAxis();
  1145. d2 = axis2 * master->GetWorldAxis();
  1146. }
  1147. else {
  1148. a2 = anchor2;
  1149. s2 = shaft2;
  1150. d2 = axis2;
  1151. }
  1152. v = s1.Cross( s2 );
  1153. if ( v.Normalize() != 0.0f ) {
  1154. idMat3 m1, m2;
  1155. m1[0] = s1;
  1156. m1[1] = v;
  1157. m1[2] = v.Cross( m1[0] );
  1158. m2[0] = -s2;
  1159. m2[1] = v;
  1160. m2[2] = v.Cross( m2[0] );
  1161. d2 *= m2.Transpose() * m1;
  1162. }
  1163. gameRenderWorld->DebugArrow( colorCyan, a1, a1 + s1 * 5.0f, 1.0f );
  1164. gameRenderWorld->DebugArrow( colorBlue, a2, a2 + s2 * 5.0f, 1.0f );
  1165. gameRenderWorld->DebugLine( colorGreen, a1, a1 + d1 * 5.0f );
  1166. gameRenderWorld->DebugLine( colorGreen, a2, a2 + d2 * 5.0f );
  1167. if ( af_showLimits.GetBool() ) {
  1168. if ( coneLimit ) {
  1169. coneLimit->DebugDraw();
  1170. }
  1171. if ( pyramidLimit ) {
  1172. pyramidLimit->DebugDraw();
  1173. }
  1174. }
  1175. }
  1176. /*
  1177. ================
  1178. idAFConstraint_UniversalJoint::Save
  1179. ================
  1180. */
  1181. void idAFConstraint_UniversalJoint::Save( idSaveGame *saveFile ) const {
  1182. idAFConstraint::Save( saveFile );
  1183. saveFile->WriteVec3( anchor1 );
  1184. saveFile->WriteVec3( anchor2 );
  1185. saveFile->WriteVec3( shaft1 );
  1186. saveFile->WriteVec3( shaft2 );
  1187. saveFile->WriteVec3( axis1 );
  1188. saveFile->WriteVec3( axis2 );
  1189. saveFile->WriteFloat( friction );
  1190. if ( coneLimit ) {
  1191. coneLimit->Save( saveFile );
  1192. }
  1193. if ( pyramidLimit ) {
  1194. pyramidLimit->Save( saveFile );
  1195. }
  1196. }
  1197. /*
  1198. ================
  1199. idAFConstraint_UniversalJoint::Restore
  1200. ================
  1201. */
  1202. void idAFConstraint_UniversalJoint::Restore( idRestoreGame *saveFile ) {
  1203. idAFConstraint::Restore( saveFile );
  1204. saveFile->ReadVec3( anchor1 );
  1205. saveFile->ReadVec3( anchor2 );
  1206. saveFile->ReadVec3( shaft1 );
  1207. saveFile->ReadVec3( shaft2 );
  1208. saveFile->ReadVec3( axis1 );
  1209. saveFile->ReadVec3( axis2 );
  1210. saveFile->ReadFloat( friction );
  1211. if ( coneLimit ) {
  1212. coneLimit->Restore( saveFile );
  1213. }
  1214. if ( pyramidLimit ) {
  1215. pyramidLimit->Restore( saveFile );
  1216. }
  1217. }
  1218. //===============================================================
  1219. //
  1220. // idAFConstraint_UniversalJointFriction
  1221. //
  1222. //===============================================================
  1223. /*
  1224. ================
  1225. idAFConstraint_UniversalJointFriction::idAFConstraint_UniversalJointFriction
  1226. ================
  1227. */
  1228. idAFConstraint_UniversalJointFriction::idAFConstraint_UniversalJointFriction() {
  1229. type = CONSTRAINT_FRICTION;
  1230. name = "universalJointFriction";
  1231. InitSize( 2 );
  1232. joint = NULL;
  1233. fl.allowPrimary = false;
  1234. fl.frameConstraint = true;
  1235. }
  1236. /*
  1237. ================
  1238. idAFConstraint_UniversalJointFriction::Setup
  1239. ================
  1240. */
  1241. void idAFConstraint_UniversalJointFriction::Setup( idAFConstraint_UniversalJoint *uj ) {
  1242. this->joint = uj;
  1243. body1 = uj->GetBody1();
  1244. body2 = uj->GetBody2();
  1245. }
  1246. /*
  1247. ================
  1248. idAFConstraint_UniversalJointFriction::Evaluate
  1249. ================
  1250. */
  1251. void idAFConstraint_UniversalJointFriction::Evaluate( float invTimeStep ) {
  1252. // do nothing
  1253. }
  1254. /*
  1255. ================
  1256. idAFConstraint_UniversalJointFriction::ApplyFriction
  1257. ================
  1258. */
  1259. void idAFConstraint_UniversalJointFriction::ApplyFriction( float invTimeStep ) {
  1260. // do nothing
  1261. }
  1262. /*
  1263. ================
  1264. idAFConstraint_UniversalJointFriction::Add
  1265. ================
  1266. */
  1267. bool idAFConstraint_UniversalJointFriction::Add( idPhysics_AF *phys, float invTimeStep ) {
  1268. idVec3 s1, s2, dir1, dir2;
  1269. float f;
  1270. physics = phys;
  1271. f = joint->GetFriction() * joint->GetMultiplier().Length();
  1272. if ( f == 0.0f ) {
  1273. return false;
  1274. }
  1275. lo[0] = lo[1] = -f;
  1276. hi[0] = hi[1] = f;
  1277. joint->GetShafts( s1, s2 );
  1278. s1 *= body1->GetWorldAxis();
  1279. s1.NormalVectors( dir1, dir2 );
  1280. J1.SetSize( 2, 6 );
  1281. J1.SubVec6(0).SubVec3(0).Zero();
  1282. J1.SubVec6(0).SubVec3(1) = dir1;
  1283. J1.SubVec6(1).SubVec3(0).Zero();
  1284. J1.SubVec6(1).SubVec3(1) = dir2;
  1285. if ( body2 ) {
  1286. J2.SetSize( 2, 6 );
  1287. J2.SubVec6(0).SubVec3(0).Zero();
  1288. J2.SubVec6(0).SubVec3(1) = -dir1;
  1289. J2.SubVec6(1).SubVec3(0).Zero();
  1290. J2.SubVec6(1).SubVec3(1) = -dir2;
  1291. }
  1292. physics->AddFrameConstraint( this );
  1293. return true;
  1294. }
  1295. /*
  1296. ================
  1297. idAFConstraint_UniversalJointFriction::Translate
  1298. ================
  1299. */
  1300. void idAFConstraint_UniversalJointFriction::Translate( const idVec3 &translation ) {
  1301. }
  1302. /*
  1303. ================
  1304. idAFConstraint_UniversalJointFriction::Rotate
  1305. ================
  1306. */
  1307. void idAFConstraint_UniversalJointFriction::Rotate( const idRotation &rotation ) {
  1308. }
  1309. //===============================================================
  1310. //
  1311. // idAFConstraint_CylindricalJoint
  1312. //
  1313. //===============================================================
  1314. /*
  1315. ================
  1316. idAFConstraint_CylindricalJoint::idAFConstraint_CylindricalJoint
  1317. ================
  1318. */
  1319. idAFConstraint_CylindricalJoint::idAFConstraint_CylindricalJoint( const idStr &name, idAFBody *body1, idAFBody *body2 ) {
  1320. assert( 0 ); // FIXME: implement
  1321. }
  1322. /*
  1323. ================
  1324. idAFConstraint_CylindricalJoint::Evaluate
  1325. ================
  1326. */
  1327. void idAFConstraint_CylindricalJoint::Evaluate( float invTimeStep ) {
  1328. assert( 0 ); // FIXME: implement
  1329. }
  1330. /*
  1331. ================
  1332. idAFConstraint_CylindricalJoint::ApplyFriction
  1333. ================
  1334. */
  1335. void idAFConstraint_CylindricalJoint::ApplyFriction( float invTimeStep ) {
  1336. assert( 0 ); // FIXME: implement
  1337. }
  1338. /*
  1339. ================
  1340. idAFConstraint_CylindricalJoint::Translate
  1341. ================
  1342. */
  1343. void idAFConstraint_CylindricalJoint::Translate( const idVec3 &translation ) {
  1344. assert( 0 ); // FIXME: implement
  1345. }
  1346. /*
  1347. ================
  1348. idAFConstraint_CylindricalJoint::Rotate
  1349. ================
  1350. */
  1351. void idAFConstraint_CylindricalJoint::Rotate( const idRotation &rotation ) {
  1352. assert( 0 ); // FIXME: implement
  1353. }
  1354. /*
  1355. ================
  1356. idAFConstraint_CylindricalJoint::DebugDraw
  1357. ================
  1358. */
  1359. void idAFConstraint_CylindricalJoint::DebugDraw() {
  1360. assert( 0 ); // FIXME: implement
  1361. }
  1362. //===============================================================
  1363. //
  1364. // idAFConstraint_Hinge
  1365. //
  1366. //===============================================================
  1367. /*
  1368. ================
  1369. idAFConstraint_Hinge::idAFConstraint_Hinge
  1370. ================
  1371. */
  1372. idAFConstraint_Hinge::idAFConstraint_Hinge( const idStr &name, idAFBody *body1, idAFBody *body2 ) {
  1373. assert( body1 );
  1374. type = CONSTRAINT_HINGE;
  1375. this->name = name;
  1376. this->body1 = body1;
  1377. this->body2 = body2;
  1378. InitSize( 5 );
  1379. coneLimit = NULL;
  1380. steering = NULL;
  1381. friction = 0.0f;
  1382. fc = NULL;
  1383. fl.allowPrimary = true;
  1384. fl.noCollision = true;
  1385. initialAxis = body1->GetWorldAxis();
  1386. if ( body2 ) {
  1387. initialAxis *= body2->GetWorldAxis().Transpose();
  1388. }
  1389. }
  1390. /*
  1391. ================
  1392. idAFConstraint_Hinge::~idAFConstraint_Hinge
  1393. ================
  1394. */
  1395. idAFConstraint_Hinge::~idAFConstraint_Hinge() {
  1396. if ( coneLimit ) {
  1397. delete coneLimit;
  1398. }
  1399. if ( fc ) {
  1400. delete fc;
  1401. }
  1402. if ( steering ) {
  1403. delete steering;
  1404. }
  1405. }
  1406. /*
  1407. ================
  1408. idAFConstraint_Hinge::SetAnchor
  1409. ================
  1410. */
  1411. void idAFConstraint_Hinge::SetAnchor( const idVec3 &worldPosition ) {
  1412. // get anchor relative to center of mass of body1
  1413. anchor1 = ( worldPosition - body1->GetWorldOrigin() ) * body1->GetWorldAxis().Transpose();
  1414. if ( body2 ) {
  1415. // get anchor relative to center of mass of body2
  1416. anchor2 = ( worldPosition - body2->GetWorldOrigin() ) * body2->GetWorldAxis().Transpose();
  1417. }
  1418. else {
  1419. anchor2 = worldPosition;
  1420. }
  1421. if ( coneLimit ) {
  1422. coneLimit->SetAnchor( anchor2 );
  1423. }
  1424. }
  1425. /*
  1426. ================
  1427. idAFConstraint_Hinge::GetAnchor
  1428. ================
  1429. */
  1430. idVec3 idAFConstraint_Hinge::GetAnchor() const {
  1431. if ( body2 ) {
  1432. return body2->GetWorldOrigin() + body2->GetWorldAxis() * anchor2;
  1433. }
  1434. return anchor2;
  1435. }
  1436. /*
  1437. ================
  1438. idAFConstraint_Hinge::SetAxis
  1439. ================
  1440. */
  1441. void idAFConstraint_Hinge::SetAxis( const idVec3 &axis ) {
  1442. idVec3 normAxis;
  1443. normAxis = axis;
  1444. normAxis.Normalize();
  1445. // get axis relative to body1
  1446. axis1 = normAxis * body1->GetWorldAxis().Transpose();
  1447. if ( body2 ) {
  1448. // get axis relative to body2
  1449. axis2 = normAxis * body2->GetWorldAxis().Transpose();
  1450. }
  1451. else {
  1452. axis2 = normAxis;
  1453. }
  1454. }
  1455. /*
  1456. ================
  1457. idAFConstraint_Hinge::GetAxis
  1458. ================
  1459. */
  1460. idVec3 idAFConstraint_Hinge::GetAxis() const {
  1461. if ( body2 ) {
  1462. return axis2 * body2->GetWorldAxis();
  1463. }
  1464. return axis2;
  1465. }
  1466. /*
  1467. ================
  1468. idAFConstraint_Hinge::SetNoLimit
  1469. ================
  1470. */
  1471. void idAFConstraint_Hinge::SetNoLimit() {
  1472. if ( coneLimit ) {
  1473. delete coneLimit;
  1474. coneLimit = NULL;
  1475. }
  1476. }
  1477. /*
  1478. ================
  1479. idAFConstraint_Hinge::SetLimit
  1480. ================
  1481. */
  1482. void idAFConstraint_Hinge::SetLimit( const idVec3 &axis, const float angle, const idVec3 &body1Axis ) {
  1483. if ( !coneLimit ) {
  1484. coneLimit = new (TAG_PHYSICS_AF) idAFConstraint_ConeLimit;
  1485. coneLimit->SetPhysics( physics );
  1486. }
  1487. if ( body2 ) {
  1488. coneLimit->Setup( body1, body2, anchor2, axis * body2->GetWorldAxis().Transpose(), angle, body1Axis * body1->GetWorldAxis().Transpose() );
  1489. }
  1490. else {
  1491. coneLimit->Setup( body1, body2, anchor2, axis, angle, body1Axis * body1->GetWorldAxis().Transpose() );
  1492. }
  1493. }
  1494. /*
  1495. ================
  1496. idAFConstraint_Hinge::SetLimitEpsilon
  1497. ================
  1498. */
  1499. void idAFConstraint_Hinge::SetLimitEpsilon( const float e ) {
  1500. if ( coneLimit ) {
  1501. coneLimit->SetEpsilon( e );
  1502. }
  1503. }
  1504. /*
  1505. ================
  1506. idAFConstraint_Hinge::GetFriction
  1507. ================
  1508. */
  1509. float idAFConstraint_Hinge::GetFriction() const {
  1510. if ( af_forceFriction.GetFloat() > 0.0f ) {
  1511. return af_forceFriction.GetFloat();
  1512. }
  1513. return friction * physics->GetJointFrictionScale();
  1514. }
  1515. /*
  1516. ================
  1517. idAFConstraint_Hinge::GetAngle
  1518. ================
  1519. */
  1520. float idAFConstraint_Hinge::GetAngle() const {
  1521. idMat3 axis;
  1522. idRotation rotation;
  1523. float angle;
  1524. axis = body1->GetWorldAxis() * body2->GetWorldAxis().Transpose() * initialAxis.Transpose();
  1525. rotation = axis.ToRotation();
  1526. angle = rotation.GetAngle();
  1527. if ( rotation.GetVec() * axis1 < 0.0f ) {
  1528. return -angle;
  1529. }
  1530. return angle;
  1531. }
  1532. /*
  1533. ================
  1534. idAFConstraint_Hinge::SetSteerAngle
  1535. ================
  1536. */
  1537. void idAFConstraint_Hinge::SetSteerAngle( const float degrees ) {
  1538. if ( coneLimit ) {
  1539. delete coneLimit;
  1540. coneLimit = NULL;
  1541. }
  1542. if ( !steering ) {
  1543. steering = new (TAG_PHYSICS_AF) idAFConstraint_HingeSteering();
  1544. steering->Setup( this );
  1545. }
  1546. steering->SetSteerAngle( degrees );
  1547. }
  1548. /*
  1549. ================
  1550. idAFConstraint_Hinge::SetSteerSpeed
  1551. ================
  1552. */
  1553. void idAFConstraint_Hinge::SetSteerSpeed( const float speed ) {
  1554. if ( steering ) {
  1555. steering->SetSteerSpeed( speed );
  1556. }
  1557. }
  1558. /*
  1559. ================
  1560. idAFConstraint_Hinge::Evaluate
  1561. ================
  1562. */
  1563. void idAFConstraint_Hinge::Evaluate( float invTimeStep ) {
  1564. idVec3 a1, a2;
  1565. idVec3 x1, x2, cross;
  1566. idVec3 vecX, vecY;
  1567. idAFBody *master;
  1568. master = body2 ? body2 : physics->GetMasterBody();
  1569. x1 = axis1 * body1->GetWorldAxis(); // axis in body1 space
  1570. x1.OrthogonalBasis( vecX, vecY ); // basis for axis in body1 space
  1571. a1 = anchor1 * body1->GetWorldAxis(); // anchor in body1 space
  1572. if ( master ) {
  1573. a2 = anchor2 * master->GetWorldAxis(); // anchor in master space
  1574. x2 = axis2 * master->GetWorldAxis();
  1575. c1.SubVec3(0) = -( invTimeStep * ERROR_REDUCTION ) * ( a2 + master->GetWorldOrigin() - ( a1 + body1->GetWorldOrigin() ) );
  1576. }
  1577. else {
  1578. a2 = anchor2;
  1579. x2 = axis2;
  1580. c1.SubVec3(0) = -( invTimeStep * ERROR_REDUCTION ) * ( a2 - ( a1 + body1->GetWorldOrigin() ) );
  1581. }
  1582. J1.Set( mat3_identity, -SkewSymmetric( a1 ),
  1583. mat3_zero, idMat3( vecX[0], vecX[1], vecX[2],
  1584. vecY[0], vecY[1], vecY[2],
  1585. 0.0f, 0.0f, 0.0f ) );
  1586. J1.SetSize( 5, 6 );
  1587. if ( body2 ) {
  1588. J2.Set( -mat3_identity, SkewSymmetric( a2 ),
  1589. mat3_zero, idMat3( -vecX[0], -vecX[1], -vecX[2],
  1590. -vecY[0], -vecY[1], -vecY[2],
  1591. 0.0f, 0.0f, 0.0f ) );
  1592. J2.SetSize( 5, 6 );
  1593. }
  1594. else {
  1595. J2.Zero( 5, 6 );
  1596. }
  1597. cross = x1.Cross( x2 );
  1598. c1[3] = -( invTimeStep * ERROR_REDUCTION ) * ( cross * vecX );
  1599. c1[4] = -( invTimeStep * ERROR_REDUCTION ) * ( cross * vecY );
  1600. c1.Clamp( -ERROR_REDUCTION_MAX, ERROR_REDUCTION_MAX );
  1601. if ( steering ) {
  1602. steering->Add( physics, invTimeStep );
  1603. }
  1604. else if ( coneLimit ) {
  1605. coneLimit->Add( physics, invTimeStep );
  1606. }
  1607. }
  1608. /*
  1609. ================
  1610. idAFConstraint_Hinge::ApplyFriction
  1611. ================
  1612. */
  1613. void idAFConstraint_Hinge::ApplyFriction( float invTimeStep ) {
  1614. idVec3 angular;
  1615. float invMass, currentFriction;
  1616. currentFriction = GetFriction();
  1617. if ( currentFriction <= 0.0f ) {
  1618. return;
  1619. }
  1620. if ( af_useImpulseFriction.GetBool() || af_useJointImpulseFriction.GetBool() ) {
  1621. angular = body1->GetAngularVelocity();
  1622. invMass = body1->GetInverseMass();
  1623. if ( body2 ) {
  1624. angular -= body2->GetAngularVelocity();
  1625. invMass += body2->GetInverseMass();
  1626. }
  1627. angular *= currentFriction / invMass;
  1628. body1->SetAngularVelocity( body1->GetAngularVelocity() - angular * body1->GetInverseMass() );
  1629. if ( body2 ) {
  1630. body2->SetAngularVelocity( body2->GetAngularVelocity() + angular * body2->GetInverseMass() );
  1631. }
  1632. }
  1633. else {
  1634. if ( !fc ) {
  1635. fc = new (TAG_PHYSICS_AF) idAFConstraint_HingeFriction;
  1636. fc->Setup( this );
  1637. }
  1638. fc->Add( physics, invTimeStep );
  1639. }
  1640. }
  1641. /*
  1642. ================
  1643. idAFConstraint_Hinge::GetForce
  1644. ================
  1645. */
  1646. void idAFConstraint_Hinge::GetForce( idAFBody *body, idVec6 &force ) {
  1647. idAFConstraint::GetForce( body, force );
  1648. // FIXME: add limit force
  1649. }
  1650. /*
  1651. ================
  1652. idAFConstraint_Hinge::Translate
  1653. ================
  1654. */
  1655. void idAFConstraint_Hinge::Translate( const idVec3 &translation ) {
  1656. if ( !body2 ) {
  1657. anchor2 += translation;
  1658. }
  1659. if ( coneLimit ) {
  1660. coneLimit->Translate( translation );
  1661. }
  1662. }
  1663. /*
  1664. ================
  1665. idAFConstraint_Hinge::Rotate
  1666. ================
  1667. */
  1668. void idAFConstraint_Hinge::Rotate( const idRotation &rotation ) {
  1669. if ( !body2 ) {
  1670. anchor2 *= rotation;
  1671. axis2 *= rotation.ToMat3();
  1672. }
  1673. if ( coneLimit ) {
  1674. coneLimit->Rotate( rotation );
  1675. }
  1676. }
  1677. /*
  1678. ================
  1679. idAFConstraint_Hinge::GetCenter
  1680. ================
  1681. */
  1682. void idAFConstraint_Hinge::GetCenter( idVec3 &center ) {
  1683. center = body1->GetWorldOrigin() + anchor1 * body1->GetWorldAxis();
  1684. }
  1685. /*
  1686. ================
  1687. idAFConstraint_Hinge::DebugDraw
  1688. ================
  1689. */
  1690. void idAFConstraint_Hinge::DebugDraw() {
  1691. idVec3 vecX, vecY;
  1692. idVec3 a1 = body1->GetWorldOrigin() + anchor1 * body1->GetWorldAxis();
  1693. idVec3 x1 = axis1 * body1->GetWorldAxis();
  1694. x1.OrthogonalBasis( vecX, vecY );
  1695. gameRenderWorld->DebugArrow( colorBlue, a1 - 4.0f * x1, a1 + 4.0f * x1, 1 );
  1696. gameRenderWorld->DebugLine( colorBlue, a1 - 2.0f * vecX, a1 + 2.0f * vecX );
  1697. gameRenderWorld->DebugLine( colorBlue, a1 - 2.0f * vecY, a1 + 2.0f * vecY );
  1698. if ( af_showLimits.GetBool() ) {
  1699. if ( coneLimit ) {
  1700. coneLimit->DebugDraw();
  1701. }
  1702. }
  1703. }
  1704. /*
  1705. ================
  1706. idAFConstraint_Hinge::Save
  1707. ================
  1708. */
  1709. void idAFConstraint_Hinge::Save( idSaveGame *saveFile ) const {
  1710. idAFConstraint::Save( saveFile );
  1711. saveFile->WriteVec3( anchor1 );
  1712. saveFile->WriteVec3( anchor2 );
  1713. saveFile->WriteVec3( axis1 );
  1714. saveFile->WriteVec3( axis2 );
  1715. saveFile->WriteMat3( initialAxis );
  1716. saveFile->WriteFloat( friction );
  1717. if ( coneLimit ) {
  1718. saveFile->WriteBool( true );
  1719. coneLimit->Save( saveFile );
  1720. } else {
  1721. saveFile->WriteBool( false );
  1722. }
  1723. if ( steering ) {
  1724. saveFile->WriteBool( true );
  1725. steering->Save( saveFile );
  1726. } else {
  1727. saveFile->WriteBool( false );
  1728. }
  1729. if ( fc ) {
  1730. saveFile->WriteBool( true );
  1731. fc->Save( saveFile );
  1732. } else {
  1733. saveFile->WriteBool( false );
  1734. }
  1735. }
  1736. /*
  1737. ================
  1738. idAFConstraint_Hinge::Restore
  1739. ================
  1740. */
  1741. void idAFConstraint_Hinge::Restore( idRestoreGame *saveFile ) {
  1742. bool b;
  1743. idAFConstraint::Restore( saveFile );
  1744. saveFile->ReadVec3( anchor1 );
  1745. saveFile->ReadVec3( anchor2 );
  1746. saveFile->ReadVec3( axis1 );
  1747. saveFile->ReadVec3( axis2 );
  1748. saveFile->ReadMat3( initialAxis );
  1749. saveFile->ReadFloat( friction );
  1750. saveFile->ReadBool( b );
  1751. if ( b ) {
  1752. if ( !coneLimit ) {
  1753. coneLimit = new (TAG_PHYSICS_AF) idAFConstraint_ConeLimit;
  1754. }
  1755. coneLimit->SetPhysics( physics );
  1756. coneLimit->Restore( saveFile );
  1757. }
  1758. saveFile->ReadBool( b );
  1759. if ( b ) {
  1760. if ( !steering ) {
  1761. steering = new (TAG_PHYSICS_AF) idAFConstraint_HingeSteering;
  1762. }
  1763. steering->Setup( this );
  1764. steering->Restore( saveFile );
  1765. }
  1766. saveFile->ReadBool( b );
  1767. if ( b ) {
  1768. if ( !fc ) {
  1769. fc = new (TAG_PHYSICS_AF) idAFConstraint_HingeFriction;
  1770. }
  1771. fc->Setup( this );
  1772. fc->Restore( saveFile );
  1773. }
  1774. }
  1775. //===============================================================
  1776. //
  1777. // idAFConstraint_HingeFriction
  1778. //
  1779. //===============================================================
  1780. /*
  1781. ================
  1782. idAFConstraint_HingeFriction::idAFConstraint_HingeFriction
  1783. ================
  1784. */
  1785. idAFConstraint_HingeFriction::idAFConstraint_HingeFriction() {
  1786. type = CONSTRAINT_FRICTION;
  1787. name = "hingeFriction";
  1788. InitSize( 1 );
  1789. hinge = NULL;
  1790. fl.allowPrimary = false;
  1791. fl.frameConstraint = true;
  1792. }
  1793. /*
  1794. ================
  1795. idAFConstraint_HingeFriction::Setup
  1796. ================
  1797. */
  1798. void idAFConstraint_HingeFriction::Setup( idAFConstraint_Hinge *h ) {
  1799. this->hinge = h;
  1800. body1 = h->GetBody1();
  1801. body2 = h->GetBody2();
  1802. }
  1803. /*
  1804. ================
  1805. idAFConstraint_HingeFriction::Evaluate
  1806. ================
  1807. */
  1808. void idAFConstraint_HingeFriction::Evaluate( float invTimeStep ) {
  1809. // do nothing
  1810. }
  1811. /*
  1812. ================
  1813. idAFConstraint_HingeFriction::ApplyFriction
  1814. ================
  1815. */
  1816. void idAFConstraint_HingeFriction::ApplyFriction( float invTimeStep ) {
  1817. // do nothing
  1818. }
  1819. /*
  1820. ================
  1821. idAFConstraint_HingeFriction::Add
  1822. ================
  1823. */
  1824. bool idAFConstraint_HingeFriction::Add( idPhysics_AF *phys, float invTimeStep ) {
  1825. idVec3 a1, a2;
  1826. float f;
  1827. physics = phys;
  1828. f = hinge->GetFriction() * hinge->GetMultiplier().Length();
  1829. if ( f == 0.0f ) {
  1830. return false;
  1831. }
  1832. lo[0] = -f;
  1833. hi[0] = f;
  1834. hinge->GetAxis( a1, a2 );
  1835. a1 *= body1->GetWorldAxis();
  1836. J1.SetSize( 1, 6 );
  1837. J1.SubVec6(0).SubVec3(0).Zero();
  1838. J1.SubVec6(0).SubVec3(1) = a1;
  1839. if ( body2 ) {
  1840. a2 *= body2->GetWorldAxis();
  1841. J2.SetSize( 1, 6 );
  1842. J2.SubVec6(0).SubVec3(0).Zero();
  1843. J2.SubVec6(0).SubVec3(1) = -a2;
  1844. }
  1845. physics->AddFrameConstraint( this );
  1846. return true;
  1847. }
  1848. /*
  1849. ================
  1850. idAFConstraint_HingeFriction::Translate
  1851. ================
  1852. */
  1853. void idAFConstraint_HingeFriction::Translate( const idVec3 &translation ) {
  1854. }
  1855. /*
  1856. ================
  1857. idAFConstraint_HingeFriction::Rotate
  1858. ================
  1859. */
  1860. void idAFConstraint_HingeFriction::Rotate( const idRotation &rotation ) {
  1861. }
  1862. //===============================================================
  1863. //
  1864. // idAFConstraint_HingeSteering
  1865. //
  1866. //===============================================================
  1867. /*
  1868. ================
  1869. idAFConstraint_HingeSteering::idAFConstraint_HingeSteering
  1870. ================
  1871. */
  1872. idAFConstraint_HingeSteering::idAFConstraint_HingeSteering() {
  1873. type = CONSTRAINT_HINGESTEERING;
  1874. name = "hingeFriction";
  1875. InitSize( 1 );
  1876. hinge = NULL;
  1877. fl.allowPrimary = false;
  1878. fl.frameConstraint = true;
  1879. steerSpeed = 0.0f;
  1880. epsilon = LCP_EPSILON;
  1881. }
  1882. /*
  1883. ================
  1884. idAFConstraint_HingeSteering::Save
  1885. ================
  1886. */
  1887. void idAFConstraint_HingeSteering::Save( idSaveGame *saveFile ) const {
  1888. saveFile->WriteFloat(steerAngle);
  1889. saveFile->WriteFloat(steerSpeed);
  1890. saveFile->WriteFloat(epsilon);
  1891. }
  1892. /*
  1893. ================
  1894. idAFConstraint_HingeSteering::Restore
  1895. ================
  1896. */
  1897. void idAFConstraint_HingeSteering::Restore( idRestoreGame *saveFile ) {
  1898. saveFile->ReadFloat(steerAngle);
  1899. saveFile->ReadFloat(steerSpeed);
  1900. saveFile->ReadFloat(epsilon);
  1901. }
  1902. /*
  1903. ================
  1904. idAFConstraint_HingeSteering::Setup
  1905. ================
  1906. */
  1907. void idAFConstraint_HingeSteering::Setup( idAFConstraint_Hinge *h ) {
  1908. this->hinge = h;
  1909. body1 = h->GetBody1();
  1910. body2 = h->GetBody2();
  1911. }
  1912. /*
  1913. ================
  1914. idAFConstraint_HingeSteering::Evaluate
  1915. ================
  1916. */
  1917. void idAFConstraint_HingeSteering::Evaluate( float invTimeStep ) {
  1918. // do nothing
  1919. }
  1920. /*
  1921. ================
  1922. idAFConstraint_HingeSteering::ApplyFriction
  1923. ================
  1924. */
  1925. void idAFConstraint_HingeSteering::ApplyFriction( float invTimeStep ) {
  1926. // do nothing
  1927. }
  1928. /*
  1929. ================
  1930. idAFConstraint_HingeSteering::Add
  1931. ================
  1932. */
  1933. bool idAFConstraint_HingeSteering::Add( idPhysics_AF *phys, float invTimeStep ) {
  1934. float angle, speed;
  1935. idVec3 a1, a2;
  1936. physics = phys;
  1937. hinge->GetAxis( a1, a2 );
  1938. angle = hinge->GetAngle();
  1939. a1 *= body1->GetWorldAxis();
  1940. J1.SetSize( 1, 6 );
  1941. J1.SubVec6(0).SubVec3(0).Zero();
  1942. J1.SubVec6(0).SubVec3(1) = a1;
  1943. if ( body2 ) {
  1944. a2 *= body2->GetWorldAxis();
  1945. J2.SetSize( 1, 6 );
  1946. J2.SubVec6(0).SubVec3(0).Zero();
  1947. J2.SubVec6(0).SubVec3(1) = -a2;
  1948. }
  1949. speed = steerAngle - angle;
  1950. if ( steerSpeed != 0.0f ) {
  1951. if ( speed > steerSpeed ) {
  1952. speed = steerSpeed;
  1953. }
  1954. else if ( speed < -steerSpeed ) {
  1955. speed = -steerSpeed;
  1956. }
  1957. }
  1958. c1[0] = DEG2RAD( speed ) * invTimeStep;
  1959. physics->AddFrameConstraint( this );
  1960. return true;
  1961. }
  1962. /*
  1963. ================
  1964. idAFConstraint_HingeSteering::Translate
  1965. ================
  1966. */
  1967. void idAFConstraint_HingeSteering::Translate( const idVec3 &translation ) {
  1968. }
  1969. /*
  1970. ================
  1971. idAFConstraint_HingeSteering::Rotate
  1972. ================
  1973. */
  1974. void idAFConstraint_HingeSteering::Rotate( const idRotation &rotation ) {
  1975. }
  1976. //===============================================================
  1977. //
  1978. // idAFConstraint_Slider
  1979. //
  1980. //===============================================================
  1981. /*
  1982. ================
  1983. idAFConstraint_Slider::idAFConstraint_Slider
  1984. ================
  1985. */
  1986. idAFConstraint_Slider::idAFConstraint_Slider( const idStr &name, idAFBody *body1, idAFBody *body2 ) {
  1987. assert( body1 );
  1988. type = CONSTRAINT_SLIDER;
  1989. this->name = name;
  1990. this->body1 = body1;
  1991. this->body2 = body2;
  1992. InitSize( 5 );
  1993. fl.allowPrimary = true;
  1994. fl.noCollision = true;
  1995. if ( body2 ) {
  1996. offset = ( body1->GetWorldOrigin() - body2->GetWorldOrigin() ) * body1->GetWorldAxis().Transpose();
  1997. relAxis = body1->GetWorldAxis() * body2->GetWorldAxis().Transpose();
  1998. }
  1999. else {
  2000. offset = body1->GetWorldOrigin();
  2001. relAxis = body1->GetWorldAxis();
  2002. }
  2003. }
  2004. /*
  2005. ================
  2006. idAFConstraint_Slider::SetAxis
  2007. ================
  2008. */
  2009. void idAFConstraint_Slider::SetAxis( const idVec3 &ax ) {
  2010. idVec3 normAxis;
  2011. // get normalized axis relative to body1
  2012. normAxis = ax;
  2013. normAxis.Normalize();
  2014. if ( body2 ) {
  2015. axis = normAxis * body2->GetWorldAxis().Transpose();
  2016. }
  2017. else {
  2018. axis = normAxis;
  2019. }
  2020. }
  2021. /*
  2022. ================
  2023. idAFConstraint_Slider::Evaluate
  2024. ================
  2025. */
  2026. void idAFConstraint_Slider::Evaluate( float invTimeStep ) {
  2027. idVec3 vecX, vecY, ofs;
  2028. idRotation r;
  2029. idAFBody *master;
  2030. master = body2 ? body2 : physics->GetMasterBody();
  2031. if ( master ) {
  2032. (axis * master->GetWorldAxis()).OrthogonalBasis( vecX, vecY );
  2033. ofs = master->GetWorldOrigin() + master->GetWorldAxis() * offset - body1->GetWorldOrigin();
  2034. r = ( body1->GetWorldAxis().Transpose() * (relAxis * master->GetWorldAxis()) ).ToRotation();
  2035. }
  2036. else {
  2037. axis.OrthogonalBasis( vecX, vecY );
  2038. ofs = offset - body1->GetWorldOrigin();
  2039. r = ( body1->GetWorldAxis().Transpose() * relAxis ).ToRotation();
  2040. }
  2041. J1.Set( mat3_zero, mat3_identity,
  2042. idMat3( vecX, vecY, vec3_origin ), mat3_zero );
  2043. J1.SetSize( 5, 6 );
  2044. if ( body2 ) {
  2045. J2.Set( mat3_zero, -mat3_identity,
  2046. idMat3( -vecX, -vecY, vec3_origin ), mat3_zero );
  2047. J2.SetSize( 5, 6 );
  2048. }
  2049. else {
  2050. J2.Zero( 5, 6 );
  2051. }
  2052. c1.SubVec3(0) = -( invTimeStep * ERROR_REDUCTION ) * ( r.GetVec() * - (float) DEG2RAD( r.GetAngle() ) );
  2053. c1[3] = -( invTimeStep * ERROR_REDUCTION ) * ( vecX * ofs );
  2054. c1[4] = -( invTimeStep * ERROR_REDUCTION ) * ( vecY * ofs );
  2055. c1.Clamp( -ERROR_REDUCTION_MAX, ERROR_REDUCTION_MAX );
  2056. }
  2057. /*
  2058. ================
  2059. idAFConstraint_Slider::ApplyFriction
  2060. ================
  2061. */
  2062. void idAFConstraint_Slider::ApplyFriction( float invTimeStep ) {
  2063. // no friction
  2064. }
  2065. /*
  2066. ================
  2067. idAFConstraint_Slider::Translate
  2068. ================
  2069. */
  2070. void idAFConstraint_Slider::Translate( const idVec3 &translation ) {
  2071. if ( !body2 ) {
  2072. offset += translation;
  2073. }
  2074. }
  2075. /*
  2076. ================
  2077. idAFConstraint_Slider::Rotate
  2078. ================
  2079. */
  2080. void idAFConstraint_Slider::Rotate( const idRotation &rotation ) {
  2081. if ( !body2 ) {
  2082. offset *= rotation;
  2083. }
  2084. }
  2085. /*
  2086. ================
  2087. idAFConstraint_Slider::GetCenter
  2088. ================
  2089. */
  2090. void idAFConstraint_Slider::GetCenter( idVec3 &center ) {
  2091. idAFBody *master;
  2092. master = body2 ? body2 : physics->GetMasterBody();
  2093. if ( master ) {
  2094. center = master->GetWorldOrigin() + master->GetWorldAxis() * offset - body1->GetWorldOrigin();
  2095. }
  2096. else {
  2097. center = offset - body1->GetWorldOrigin();
  2098. }
  2099. }
  2100. /*
  2101. ================
  2102. idAFConstraint_Slider::DebugDraw
  2103. ================
  2104. */
  2105. void idAFConstraint_Slider::DebugDraw() {
  2106. idVec3 ofs;
  2107. idAFBody *master;
  2108. master = body2 ? body2 : physics->GetMasterBody();
  2109. if ( master ) {
  2110. ofs = master->GetWorldOrigin() + master->GetWorldAxis() * offset - body1->GetWorldOrigin();
  2111. }
  2112. else {
  2113. ofs = offset - body1->GetWorldOrigin();
  2114. }
  2115. gameRenderWorld->DebugLine( colorGreen, ofs, ofs + axis * body1->GetWorldAxis() );
  2116. }
  2117. /*
  2118. ================
  2119. idAFConstraint_Slider::Save
  2120. ================
  2121. */
  2122. void idAFConstraint_Slider::Save( idSaveGame *saveFile ) const {
  2123. idAFConstraint::Save( saveFile );
  2124. saveFile->WriteVec3( axis );
  2125. saveFile->WriteVec3( offset );
  2126. saveFile->WriteMat3( relAxis );
  2127. }
  2128. /*
  2129. ================
  2130. idAFConstraint_Slider::Restore
  2131. ================
  2132. */
  2133. void idAFConstraint_Slider::Restore( idRestoreGame *saveFile ) {
  2134. idAFConstraint::Restore( saveFile );
  2135. saveFile->ReadVec3( axis );
  2136. saveFile->ReadVec3( offset );
  2137. saveFile->ReadMat3( relAxis );
  2138. }
  2139. //===============================================================
  2140. //
  2141. // idAFConstraint_Line
  2142. //
  2143. //===============================================================
  2144. /*
  2145. ================
  2146. idAFConstraint_Line::idAFConstraint_Line
  2147. ================
  2148. */
  2149. idAFConstraint_Line::idAFConstraint_Line( const idStr &name, idAFBody *body1, idAFBody *body2 ) {
  2150. assert( 0 ); // FIXME: implement
  2151. }
  2152. /*
  2153. ================
  2154. idAFConstraint_Line::Evaluate
  2155. ================
  2156. */
  2157. void idAFConstraint_Line::Evaluate( float invTimeStep ) {
  2158. assert( 0 ); // FIXME: implement
  2159. }
  2160. /*
  2161. ================
  2162. idAFConstraint_Line::ApplyFriction
  2163. ================
  2164. */
  2165. void idAFConstraint_Line::ApplyFriction( float invTimeStep ) {
  2166. assert( 0 ); // FIXME: implement
  2167. }
  2168. /*
  2169. ================
  2170. idAFConstraint_Line::Translate
  2171. ================
  2172. */
  2173. void idAFConstraint_Line::Translate( const idVec3 &translation ) {
  2174. assert( 0 ); // FIXME: implement
  2175. }
  2176. /*
  2177. ================
  2178. idAFConstraint_Line::Rotate
  2179. ================
  2180. */
  2181. void idAFConstraint_Line::Rotate( const idRotation &rotation ) {
  2182. assert( 0 ); // FIXME: implement
  2183. }
  2184. /*
  2185. ================
  2186. idAFConstraint_Line::DebugDraw
  2187. ================
  2188. */
  2189. void idAFConstraint_Line::DebugDraw() {
  2190. assert( 0 ); // FIXME: implement
  2191. }
  2192. //===============================================================
  2193. //
  2194. // idAFConstraint_Plane
  2195. //
  2196. //===============================================================
  2197. /*
  2198. ================
  2199. idAFConstraint_Plane::idAFConstraint_Plane
  2200. ================
  2201. */
  2202. idAFConstraint_Plane::idAFConstraint_Plane( const idStr &name, idAFBody *body1, idAFBody *body2 ) {
  2203. assert( body1 );
  2204. type = CONSTRAINT_PLANE;
  2205. this->name = name;
  2206. this->body1 = body1;
  2207. this->body2 = body2;
  2208. InitSize( 1 );
  2209. fl.allowPrimary = true;
  2210. fl.noCollision = true;
  2211. }
  2212. /*
  2213. ================
  2214. idAFConstraint_Plane::SetPlane
  2215. ================
  2216. */
  2217. void idAFConstraint_Plane::SetPlane( const idVec3 &normal, const idVec3 &anchor ) {
  2218. // get anchor relative to center of mass of body1
  2219. anchor1 = ( anchor - body1->GetWorldOrigin() ) * body1->GetWorldAxis().Transpose();
  2220. if ( body2 ) {
  2221. // get anchor relative to center of mass of body2
  2222. anchor2 = ( anchor - body2->GetWorldOrigin() ) * body2->GetWorldAxis().Transpose();
  2223. planeNormal = normal * body2->GetWorldAxis().Transpose();
  2224. }
  2225. else {
  2226. anchor2 = anchor;
  2227. planeNormal = normal;
  2228. }
  2229. }
  2230. /*
  2231. ================
  2232. idAFConstraint_Plane::Evaluate
  2233. ================
  2234. */
  2235. void idAFConstraint_Plane::Evaluate( float invTimeStep ) {
  2236. idVec3 a1, a2, normal, p;
  2237. idVec6 v;
  2238. idAFBody *master;
  2239. master = body2 ? body2 : physics->GetMasterBody();
  2240. a1 = body1->GetWorldOrigin() + anchor1 * body1->GetWorldAxis();
  2241. if ( master ) {
  2242. a2 = master->GetWorldOrigin() + anchor2 * master->GetWorldAxis();
  2243. normal = planeNormal * master->GetWorldAxis();
  2244. }
  2245. else {
  2246. a2 = anchor2;
  2247. normal = planeNormal;
  2248. }
  2249. p = a1 - body1->GetWorldOrigin();
  2250. v.SubVec3(0) = normal;
  2251. v.SubVec3(1) = p.Cross( normal );
  2252. J1.Set( 1, 6, v.ToFloatPtr() );
  2253. if ( body2 ) {
  2254. p = a1 - body2->GetWorldOrigin();
  2255. v.SubVec3(0) = -normal;
  2256. v.SubVec3(1) = p.Cross( -normal );
  2257. J2.Set( 1, 6, v.ToFloatPtr() );
  2258. }
  2259. c1[0] = -( invTimeStep * ERROR_REDUCTION ) * (a1 * normal - a2 * normal);
  2260. c1.Clamp( -ERROR_REDUCTION_MAX, ERROR_REDUCTION_MAX );
  2261. }
  2262. /*
  2263. ================
  2264. idAFConstraint_Plane::ApplyFriction
  2265. ================
  2266. */
  2267. void idAFConstraint_Plane::ApplyFriction( float invTimeStep ) {
  2268. // no friction
  2269. }
  2270. /*
  2271. ================
  2272. idAFConstraint_Plane::Translate
  2273. ================
  2274. */
  2275. void idAFConstraint_Plane::Translate( const idVec3 &translation ) {
  2276. if ( !body2 ) {
  2277. anchor2 += translation;
  2278. }
  2279. }
  2280. /*
  2281. ================
  2282. idAFConstraint_Plane::Rotate
  2283. ================
  2284. */
  2285. void idAFConstraint_Plane::Rotate( const idRotation &rotation ) {
  2286. if ( !body2 ) {
  2287. anchor2 *= rotation;
  2288. planeNormal *= rotation.ToMat3();
  2289. }
  2290. }
  2291. /*
  2292. ================
  2293. idAFConstraint_Plane::DebugDraw
  2294. ================
  2295. */
  2296. void idAFConstraint_Plane::DebugDraw() {
  2297. idVec3 a1, normal, right, up;
  2298. idAFBody *master;
  2299. master = body2 ? body2 : physics->GetMasterBody();
  2300. a1 = body1->GetWorldOrigin() + anchor1 * body1->GetWorldAxis();
  2301. if ( master ) {
  2302. normal = planeNormal * master->GetWorldAxis();
  2303. }
  2304. else {
  2305. normal = planeNormal;
  2306. }
  2307. normal.NormalVectors( right, up );
  2308. normal *= 4.0f;
  2309. right *= 4.0f;
  2310. up *= 4.0f;
  2311. gameRenderWorld->DebugLine( colorCyan, a1 - right, a1 + right );
  2312. gameRenderWorld->DebugLine( colorCyan, a1 - up, a1 + up );
  2313. gameRenderWorld->DebugArrow( colorCyan, a1, a1 + normal, 1 );
  2314. }
  2315. /*
  2316. ================
  2317. idAFConstraint_Plane::Save
  2318. ================
  2319. */
  2320. void idAFConstraint_Plane::Save( idSaveGame *saveFile ) const {
  2321. idAFConstraint::Save( saveFile );
  2322. saveFile->WriteVec3( anchor1 );
  2323. saveFile->WriteVec3( anchor2 );
  2324. saveFile->WriteVec3( planeNormal );
  2325. }
  2326. /*
  2327. ================
  2328. idAFConstraint_Plane::Restore
  2329. ================
  2330. */
  2331. void idAFConstraint_Plane::Restore( idRestoreGame *saveFile ) {
  2332. idAFConstraint::Restore( saveFile );
  2333. saveFile->ReadVec3( anchor1 );
  2334. saveFile->ReadVec3( anchor2 );
  2335. saveFile->ReadVec3( planeNormal );
  2336. }
  2337. //===============================================================
  2338. //
  2339. // idAFConstraint_Spring
  2340. //
  2341. //===============================================================
  2342. /*
  2343. ================
  2344. idAFConstraint_Spring::idAFConstraint_Spring
  2345. ================
  2346. */
  2347. idAFConstraint_Spring::idAFConstraint_Spring( const idStr &name, idAFBody *body1, idAFBody *body2 ) {
  2348. assert( body1 );
  2349. type = CONSTRAINT_SPRING;
  2350. this->name = name;
  2351. this->body1 = body1;
  2352. this->body2 = body2;
  2353. InitSize( 1 );
  2354. fl.allowPrimary = false;
  2355. kstretch = kcompress = damping = 1.0f;
  2356. minLength = maxLength = restLength = 0.0f;
  2357. }
  2358. /*
  2359. ================
  2360. idAFConstraint_Spring::SetAnchor
  2361. ================
  2362. */
  2363. void idAFConstraint_Spring::SetAnchor( const idVec3 &worldAnchor1, const idVec3 &worldAnchor2 ) {
  2364. // get anchor relative to center of mass of body1
  2365. anchor1 = ( worldAnchor1 - body1->GetWorldOrigin() ) * body1->GetWorldAxis().Transpose();
  2366. if ( body2 ) {
  2367. // get anchor relative to center of mass of body2
  2368. anchor2 = ( worldAnchor2 - body2->GetWorldOrigin() ) * body2->GetWorldAxis().Transpose();
  2369. }
  2370. else {
  2371. anchor2 = worldAnchor2;
  2372. }
  2373. }
  2374. /*
  2375. ================
  2376. idAFConstraint_Spring::SetSpring
  2377. ================
  2378. */
  2379. void idAFConstraint_Spring::SetSpring( const float stretch, const float compress, const float damping, const float restLength ) {
  2380. assert( stretch >= 0.0f && compress >= 0.0f && restLength >= 0.0f );
  2381. this->kstretch = stretch;
  2382. this->kcompress = compress;
  2383. this->damping = damping;
  2384. this->restLength = restLength;
  2385. }
  2386. /*
  2387. ================
  2388. idAFConstraint_Spring::SetLimit
  2389. ================
  2390. */
  2391. void idAFConstraint_Spring::SetLimit( const float minLength, const float maxLength ) {
  2392. assert( minLength >= 0.0f && maxLength >= 0.0f && maxLength >= minLength );
  2393. this->minLength = minLength;
  2394. this->maxLength = maxLength;
  2395. }
  2396. /*
  2397. ================
  2398. idAFConstraint_Spring::Evaluate
  2399. ================
  2400. */
  2401. void idAFConstraint_Spring::Evaluate( float invTimeStep ) {
  2402. idVec3 a1, a2, velocity1, velocity2, force;
  2403. idVec6 v1, v2;
  2404. float d, dampingForce, length, error;
  2405. bool limit;
  2406. idAFBody *master;
  2407. master = body2 ? body2 : physics->GetMasterBody();
  2408. a1 = body1->GetWorldOrigin() + anchor1 * body1->GetWorldAxis();
  2409. velocity1 = body1->GetPointVelocity( a1 );
  2410. if ( master ) {
  2411. a2 = master->GetWorldOrigin() + anchor2 * master->GetWorldAxis();
  2412. velocity2 = master->GetPointVelocity( a2 );
  2413. }
  2414. else {
  2415. a2 = anchor2;
  2416. velocity2.Zero();
  2417. }
  2418. force = a2 - a1;
  2419. d = force * force;
  2420. if ( d != 0.0f ) {
  2421. dampingForce = damping * idMath::Fabs( (velocity2 - velocity1) * force ) / d;
  2422. }
  2423. else {
  2424. dampingForce = 0.0f;
  2425. }
  2426. length = force.Normalize();
  2427. if ( length > restLength ) {
  2428. if ( kstretch > 0.0f ) {
  2429. idVec3 springForce = force * ( Square( length - restLength ) * kstretch - dampingForce );
  2430. body1->AddForce( a1, springForce );
  2431. if ( master ) {
  2432. master->AddForce( a2, -springForce );
  2433. }
  2434. }
  2435. }
  2436. else {
  2437. if ( kcompress > 0.0f ) {
  2438. idVec3 springForce = force * -( Square( restLength - length ) * kcompress - dampingForce );
  2439. body1->AddForce( a1, springForce );
  2440. if ( master ) {
  2441. master->AddForce( a2, -springForce );
  2442. }
  2443. }
  2444. }
  2445. // check for spring limits
  2446. if ( length < minLength ) {
  2447. force = -force;
  2448. error = minLength - length;
  2449. limit = true;
  2450. }
  2451. else if ( maxLength > 0.0f && length > maxLength ) {
  2452. error = length - maxLength;
  2453. limit = true;
  2454. }
  2455. else {
  2456. error = 0.0f;
  2457. limit = false;
  2458. }
  2459. if ( limit ) {
  2460. a1 -= body1->GetWorldOrigin();
  2461. v1.SubVec3(0) = force;
  2462. v1.SubVec3(1) = a1.Cross( force );
  2463. J1.Set( 1, 6, v1.ToFloatPtr() );
  2464. if ( body2 ) {
  2465. a2 -= body2->GetWorldOrigin();
  2466. v2.SubVec3(0) = -force;
  2467. v2.SubVec3(1) = a2.Cross( -force );
  2468. J2.Set( 1, 6, v2.ToFloatPtr() );
  2469. }
  2470. c1[0] = -( invTimeStep * ERROR_REDUCTION ) * error;
  2471. lo[0] = 0.0f;
  2472. }
  2473. else {
  2474. J1.Zero( 0, 0 );
  2475. J2.Zero( 0, 0 );
  2476. }
  2477. c1.Clamp( -ERROR_REDUCTION_MAX, ERROR_REDUCTION_MAX );
  2478. }
  2479. /*
  2480. ================
  2481. idAFConstraint_Spring::ApplyFriction
  2482. ================
  2483. */
  2484. void idAFConstraint_Spring::ApplyFriction( float invTimeStep ) {
  2485. // no friction
  2486. }
  2487. /*
  2488. ================
  2489. idAFConstraint_Spring::Translate
  2490. ================
  2491. */
  2492. void idAFConstraint_Spring::Translate( const idVec3 &translation ) {
  2493. if ( !body2 ) {
  2494. anchor2 += translation;
  2495. }
  2496. }
  2497. /*
  2498. ================
  2499. idAFConstraint_Spring::Rotate
  2500. ================
  2501. */
  2502. void idAFConstraint_Spring::Rotate( const idRotation &rotation ) {
  2503. if ( !body2 ) {
  2504. anchor2 *= rotation;
  2505. }
  2506. }
  2507. /*
  2508. ================
  2509. idAFConstraint_Spring::GetCenter
  2510. ================
  2511. */
  2512. void idAFConstraint_Spring::GetCenter( idVec3 &center ) {
  2513. idAFBody *master;
  2514. idVec3 a1, a2;
  2515. master = body2 ? body2 : physics->GetMasterBody();
  2516. a1 = body1->GetWorldOrigin() + anchor1 * body1->GetWorldAxis();
  2517. if ( master ) {
  2518. a2 = master->GetWorldOrigin() + anchor2 * master->GetWorldAxis();
  2519. }
  2520. else {
  2521. a2 = anchor2;
  2522. }
  2523. center = ( a1 + a2 ) * 0.5f;
  2524. }
  2525. /*
  2526. ================
  2527. idAFConstraint_Spring::DebugDraw
  2528. ================
  2529. */
  2530. void idAFConstraint_Spring::DebugDraw() {
  2531. idAFBody *master;
  2532. float length;
  2533. idVec3 a1, a2, dir, mid, p;
  2534. master = body2 ? body2 : physics->GetMasterBody();
  2535. a1 = body1->GetWorldOrigin() + anchor1 * body1->GetWorldAxis();
  2536. if ( master ) {
  2537. a2 = master->GetWorldOrigin() + anchor2 * master->GetWorldAxis();
  2538. }
  2539. else {
  2540. a2 = anchor2;
  2541. }
  2542. dir = a2 - a1;
  2543. mid = a1 + 0.5f * dir;
  2544. length = dir.Normalize();
  2545. // draw spring
  2546. gameRenderWorld->DebugLine( colorGreen, a1, a2 );
  2547. // draw rest length
  2548. p = restLength * 0.5f * dir;
  2549. gameRenderWorld->DebugCircle( colorWhite, mid + p, dir, 1.0f, 10 );
  2550. gameRenderWorld->DebugCircle( colorWhite, mid - p, dir, 1.0f, 10 );
  2551. if ( restLength > length ) {
  2552. gameRenderWorld->DebugLine( colorWhite, a2, mid + p );
  2553. gameRenderWorld->DebugLine( colorWhite, a1, mid - p );
  2554. }
  2555. if ( minLength > 0.0f ) {
  2556. // draw min length
  2557. gameRenderWorld->DebugCircle( colorBlue, mid + minLength * 0.5f * dir, dir, 2.0f, 10 );
  2558. gameRenderWorld->DebugCircle( colorBlue, mid - minLength * 0.5f * dir, dir, 2.0f, 10 );
  2559. }
  2560. if ( maxLength > 0.0f ) {
  2561. // draw max length
  2562. gameRenderWorld->DebugCircle( colorRed, mid + maxLength * 0.5f * dir, dir, 2.0f, 10 );
  2563. gameRenderWorld->DebugCircle( colorRed, mid - maxLength * 0.5f * dir, dir, 2.0f, 10 );
  2564. }
  2565. }
  2566. /*
  2567. ================
  2568. idAFConstraint_Spring::Save
  2569. ================
  2570. */
  2571. void idAFConstraint_Spring::Save( idSaveGame *saveFile ) const {
  2572. idAFConstraint::Save( saveFile );
  2573. saveFile->WriteVec3( anchor1 );
  2574. saveFile->WriteVec3( anchor2 );
  2575. saveFile->WriteFloat( kstretch );
  2576. saveFile->WriteFloat( kcompress );
  2577. saveFile->WriteFloat( damping );
  2578. saveFile->WriteFloat( restLength );
  2579. saveFile->WriteFloat( minLength );
  2580. saveFile->WriteFloat( maxLength );
  2581. }
  2582. /*
  2583. ================
  2584. idAFConstraint_Spring::Restore
  2585. ================
  2586. */
  2587. void idAFConstraint_Spring::Restore( idRestoreGame *saveFile ) {
  2588. idAFConstraint::Restore( saveFile );
  2589. saveFile->ReadVec3( anchor1 );
  2590. saveFile->ReadVec3( anchor2 );
  2591. saveFile->ReadFloat( kstretch );
  2592. saveFile->ReadFloat( kcompress );
  2593. saveFile->ReadFloat( damping );
  2594. saveFile->ReadFloat( restLength );
  2595. saveFile->ReadFloat( minLength );
  2596. saveFile->ReadFloat( maxLength );
  2597. }
  2598. //===============================================================
  2599. //
  2600. // idAFConstraint_Contact
  2601. //
  2602. //===============================================================
  2603. /*
  2604. ================
  2605. idAFConstraint_Contact::idAFConstraint_Contact
  2606. ================
  2607. */
  2608. idAFConstraint_Contact::idAFConstraint_Contact() {
  2609. name = "contact";
  2610. type = CONSTRAINT_CONTACT;
  2611. InitSize( 1 );
  2612. fc = NULL;
  2613. fl.allowPrimary = false;
  2614. fl.frameConstraint = true;
  2615. }
  2616. /*
  2617. ================
  2618. idAFConstraint_Contact::~idAFConstraint_Contact
  2619. ================
  2620. */
  2621. idAFConstraint_Contact::~idAFConstraint_Contact() {
  2622. if ( fc ) {
  2623. delete fc;
  2624. }
  2625. }
  2626. /*
  2627. ================
  2628. idAFConstraint_Contact::Setup
  2629. ================
  2630. */
  2631. void idAFConstraint_Contact::Setup( idAFBody *b1, idAFBody *b2, contactInfo_t &c ) {
  2632. idVec3 p;
  2633. idVec6 v;
  2634. float vel;
  2635. float minBounceVelocity = 2.0f;
  2636. assert( b1 );
  2637. body1 = b1;
  2638. body2 = b2;
  2639. contact = c;
  2640. p = c.point - body1->GetWorldOrigin();
  2641. v.SubVec3(0) = c.normal;
  2642. v.SubVec3(1) = p.Cross( c.normal );
  2643. J1.Set( 1, 6, v.ToFloatPtr() );
  2644. vel = v.SubVec3(0) * body1->GetLinearVelocity() + v.SubVec3(1) * body1->GetAngularVelocity();
  2645. if ( body2 ) {
  2646. p = c.point - body2->GetWorldOrigin();
  2647. v.SubVec3(0) = -c.normal;
  2648. v.SubVec3(1) = p.Cross( -c.normal );
  2649. J2.Set( 1, 6, v.ToFloatPtr() );
  2650. vel += v.SubVec3(0) * body2->GetLinearVelocity() + v.SubVec3(1) * body2->GetAngularVelocity();
  2651. c2[0] = 0.0f;
  2652. }
  2653. if ( body1->GetBouncyness() > 0.0f && -vel > minBounceVelocity ) {
  2654. c1[0] = body1->GetBouncyness() * vel;
  2655. }
  2656. else {
  2657. c1[0] = 0.0f;
  2658. }
  2659. e[0] = CONTACT_LCP_EPSILON;
  2660. lo[0] = 0.0f;
  2661. hi[0] = idMath::INFINITY;
  2662. boxConstraint = NULL;
  2663. boxIndex[0] = -1;
  2664. }
  2665. /*
  2666. ================
  2667. idAFConstraint_Contact::Evaluate
  2668. ================
  2669. */
  2670. void idAFConstraint_Contact::Evaluate( float invTimeStep ) {
  2671. // do nothing
  2672. }
  2673. /*
  2674. ================
  2675. idAFConstraint_Contact::ApplyFriction
  2676. ================
  2677. */
  2678. void idAFConstraint_Contact::ApplyFriction( float invTimeStep ) {
  2679. idVec3 r, velocity, normal, dir1, dir2;
  2680. float friction, magnitude, forceNumerator, forceDenominator;
  2681. idVecX impulse, dv;
  2682. if ( !body1 ) {
  2683. return;
  2684. }
  2685. friction = body1->GetContactFriction();
  2686. if ( body2 && body2->GetContactFriction() < friction ) {
  2687. friction = body2->GetContactFriction();
  2688. }
  2689. friction *= physics->GetContactFrictionScale();
  2690. if ( friction <= 0.0f ) {
  2691. return;
  2692. }
  2693. // seperate friction per contact is silly but it's fast and often looks close enough
  2694. if ( af_useImpulseFriction.GetBool() ) {
  2695. impulse.SetData( 6, VECX_ALLOCA( 6 ) );
  2696. dv.SetData( 6, VECX_ALLOCA( 6 ) );
  2697. // calculate velocity in the contact plane
  2698. r = contact.point - body1->GetWorldOrigin();
  2699. velocity = body1->GetLinearVelocity() + body1->GetAngularVelocity().Cross( r );
  2700. velocity -= contact.normal * velocity * contact.normal;
  2701. // get normalized direction of friction and magnitude of velocity
  2702. normal = -velocity;
  2703. magnitude = normal.Normalize();
  2704. forceNumerator = friction * magnitude;
  2705. forceDenominator = body1->GetInverseMass() + ( ( body1->GetInverseWorldInertia() * r.Cross( normal ) ).Cross( r ) * normal );
  2706. impulse.SubVec3(0) = (forceNumerator / forceDenominator) * normal;
  2707. impulse.SubVec3(1) = r.Cross( impulse.SubVec3(0) );
  2708. body1->InverseWorldSpatialInertiaMultiply( dv, impulse.ToFloatPtr() );
  2709. // modify velocity with friction force
  2710. body1->SetLinearVelocity( body1->GetLinearVelocity() + dv.SubVec3(0) );
  2711. body1->SetAngularVelocity( body1->GetAngularVelocity() + dv.SubVec3(1) );
  2712. }
  2713. else {
  2714. if ( !fc ) {
  2715. fc = new (TAG_PHYSICS_AF) idAFConstraint_ContactFriction;
  2716. }
  2717. // call setup each frame because contact constraints are re-used for different bodies
  2718. fc->Setup( this );
  2719. fc->Add( physics, invTimeStep );
  2720. }
  2721. }
  2722. /*
  2723. ================
  2724. idAFConstraint_Contact::Translate
  2725. ================
  2726. */
  2727. void idAFConstraint_Contact::Translate( const idVec3 &translation ) {
  2728. assert( 0 ); // contact should never be translated
  2729. }
  2730. /*
  2731. ================
  2732. idAFConstraint_Contact::Rotate
  2733. ================
  2734. */
  2735. void idAFConstraint_Contact::Rotate( const idRotation &rotation ) {
  2736. assert( 0 ); // contact should never be rotated
  2737. }
  2738. /*
  2739. ================
  2740. idAFConstraint_Contact::GetCenter
  2741. ================
  2742. */
  2743. void idAFConstraint_Contact::GetCenter( idVec3 &center ) {
  2744. center = contact.point;
  2745. }
  2746. /*
  2747. ================
  2748. idAFConstraint_Contact::DebugDraw
  2749. ================
  2750. */
  2751. void idAFConstraint_Contact::DebugDraw() {
  2752. idVec3 x, y;
  2753. contact.normal.NormalVectors( x, y );
  2754. gameRenderWorld->DebugLine( colorWhite, contact.point, contact.point + 6.0f * contact.normal );
  2755. gameRenderWorld->DebugLine( colorWhite, contact.point - 2.0f * x, contact.point + 2.0f * x );
  2756. gameRenderWorld->DebugLine( colorWhite, contact.point - 2.0f * y, contact.point + 2.0f * y );
  2757. }
  2758. //===============================================================
  2759. //
  2760. // idAFConstraint_ContactFriction
  2761. //
  2762. //===============================================================
  2763. /*
  2764. ================
  2765. idAFConstraint_ContactFriction::idAFConstraint_ContactFriction
  2766. ================
  2767. */
  2768. idAFConstraint_ContactFriction::idAFConstraint_ContactFriction() {
  2769. type = CONSTRAINT_FRICTION;
  2770. name = "contactFriction";
  2771. InitSize( 2 );
  2772. cc = NULL;
  2773. fl.allowPrimary = false;
  2774. fl.frameConstraint = true;
  2775. }
  2776. /*
  2777. ================
  2778. idAFConstraint_ContactFriction::Setup
  2779. ================
  2780. */
  2781. void idAFConstraint_ContactFriction::Setup( idAFConstraint_Contact *cc ) {
  2782. this->cc = cc;
  2783. body1 = cc->GetBody1();
  2784. body2 = cc->GetBody2();
  2785. }
  2786. /*
  2787. ================
  2788. idAFConstraint_ContactFriction::Evaluate
  2789. ================
  2790. */
  2791. void idAFConstraint_ContactFriction::Evaluate( float invTimeStep ) {
  2792. // do nothing
  2793. }
  2794. /*
  2795. ================
  2796. idAFConstraint_ContactFriction::ApplyFriction
  2797. ================
  2798. */
  2799. void idAFConstraint_ContactFriction::ApplyFriction( float invTimeStep ) {
  2800. // do nothing
  2801. }
  2802. /*
  2803. ================
  2804. idAFConstraint_ContactFriction::Add
  2805. ================
  2806. */
  2807. bool idAFConstraint_ContactFriction::Add( idPhysics_AF *phys, float invTimeStep ) {
  2808. idVec3 r, dir1, dir2;
  2809. float friction;
  2810. int newRow;
  2811. physics = phys;
  2812. friction = body1->GetContactFriction() * physics->GetContactFrictionScale();
  2813. // if the body only has friction in one direction
  2814. if ( body1->GetFrictionDirection( dir1 ) ) {
  2815. // project the friction direction into the contact plane
  2816. dir1 -= dir1 * cc->GetContact().normal * dir1;
  2817. dir1.Normalize();
  2818. r = cc->GetContact().point - body1->GetWorldOrigin();
  2819. J1.SetSize( 1, 6 );
  2820. J1.SubVec6(0).SubVec3(0) = dir1;
  2821. J1.SubVec6(0).SubVec3(1) = r.Cross( dir1 );
  2822. c1.SetSize( 1 );
  2823. c1[0] = 0.0f;
  2824. if ( body2 ) {
  2825. r = cc->GetContact().point - body2->GetWorldOrigin();
  2826. J2.SetSize( 1, 6 );
  2827. J2.SubVec6(0).SubVec3(0) = -dir1;
  2828. J2.SubVec6(0).SubVec3(1) = r.Cross( -dir1 );
  2829. c2.SetSize( 1 );
  2830. c2[0] = 0.0f;
  2831. }
  2832. lo[0] = -friction;
  2833. hi[0] = friction;
  2834. boxConstraint = cc;
  2835. boxIndex[0] = 0;
  2836. }
  2837. else {
  2838. // get two friction directions orthogonal to contact normal
  2839. cc->GetContact().normal.NormalVectors( dir1, dir2 );
  2840. r = cc->GetContact().point - body1->GetWorldOrigin();
  2841. J1.SetSize( 2, 6 );
  2842. J1.SubVec6(0).SubVec3(0) = dir1;
  2843. J1.SubVec6(0).SubVec3(1) = r.Cross( dir1 );
  2844. J1.SubVec6(1).SubVec3(0) = dir2;
  2845. J1.SubVec6(1).SubVec3(1) = r.Cross( dir2 );
  2846. c1.SetSize( 2 );
  2847. c1[0] = c1[1] = 0.0f;
  2848. if ( body2 ) {
  2849. r = cc->GetContact().point - body2->GetWorldOrigin();
  2850. J2.SetSize( 2, 6 );
  2851. J2.SubVec6(0).SubVec3(0) = -dir1;
  2852. J2.SubVec6(0).SubVec3(1) = r.Cross( -dir1 );
  2853. J2.SubVec6(1).SubVec3(0) = -dir2;
  2854. J2.SubVec6(1).SubVec3(1) = r.Cross( -dir2 );
  2855. c2.SetSize( 2 );
  2856. c2[0] = c2[1] = 0.0f;
  2857. if ( body2->GetContactFriction() < friction ) {
  2858. friction = body2->GetContactFriction();
  2859. }
  2860. }
  2861. lo[0] = -friction;
  2862. hi[0] = friction;
  2863. boxConstraint = cc;
  2864. boxIndex[0] = 0;
  2865. lo[1] = -friction;
  2866. hi[1] = friction;
  2867. boxIndex[1] = 0;
  2868. }
  2869. if ( body1->GetContactMotorDirection( dir1 ) && body1->GetContactMotorForce() > 0.0f ) {
  2870. // project the motor force direction into the contact plane
  2871. dir1 -= dir1 * cc->GetContact().normal * dir1;
  2872. dir1.Normalize();
  2873. r = cc->GetContact().point - body1->GetWorldOrigin();
  2874. newRow = J1.GetNumRows();
  2875. J1.ChangeSize( newRow+1, J1.GetNumColumns() );
  2876. J1.SubVec6(newRow).SubVec3(0) = -dir1;
  2877. J1.SubVec6(newRow).SubVec3(1) = r.Cross( -dir1 );
  2878. c1.ChangeSize( newRow+1 );
  2879. c1[newRow] = body1->GetContactMotorVelocity();
  2880. if ( body2 ) {
  2881. r = cc->GetContact().point - body2->GetWorldOrigin();
  2882. J2.ChangeSize( newRow+1, J2.GetNumColumns() );
  2883. J2.SubVec6(newRow).SubVec3(0) = -dir1;
  2884. J2.SubVec6(newRow).SubVec3(1) = r.Cross( -dir1 );
  2885. c2.ChangeSize( newRow+1 );
  2886. c2[newRow] = 0.0f;
  2887. }
  2888. lo[newRow] = -body1->GetContactMotorForce();
  2889. hi[newRow] = body1->GetContactMotorForce();
  2890. boxIndex[newRow] = -1;
  2891. }
  2892. physics->AddFrameConstraint( this );
  2893. return true;
  2894. }
  2895. /*
  2896. ================
  2897. idAFConstraint_ContactFriction::Translate
  2898. ================
  2899. */
  2900. void idAFConstraint_ContactFriction::Translate( const idVec3 &translation ) {
  2901. }
  2902. /*
  2903. ================
  2904. idAFConstraint_ContactFriction::Rotate
  2905. ================
  2906. */
  2907. void idAFConstraint_ContactFriction::Rotate( const idRotation &rotation ) {
  2908. }
  2909. /*
  2910. ================
  2911. idAFConstraint_ContactFriction::DebugDraw
  2912. ================
  2913. */
  2914. void idAFConstraint_ContactFriction::DebugDraw() {
  2915. }
  2916. //===============================================================
  2917. //
  2918. // idAFConstraint_ConeLimit
  2919. //
  2920. //===============================================================
  2921. /*
  2922. ================
  2923. idAFConstraint_ConeLimit::idAFConstraint_ConeLimit
  2924. ================
  2925. */
  2926. idAFConstraint_ConeLimit::idAFConstraint_ConeLimit() {
  2927. type = CONSTRAINT_CONELIMIT;
  2928. name = "coneLimit";
  2929. InitSize( 1 );
  2930. fl.allowPrimary = false;
  2931. fl.frameConstraint = true;
  2932. }
  2933. /*
  2934. ================
  2935. idAFConstraint_ConeLimit::Setup
  2936. the coneAnchor is the top of the cone in body2 space
  2937. the coneAxis is the axis of the cone in body2 space
  2938. the coneAngle is the angle the cone hull makes at the top
  2939. the body1Axis is the axis in body1 space that should stay within the cone
  2940. ================
  2941. */
  2942. void idAFConstraint_ConeLimit::Setup( idAFBody *b1, idAFBody *b2, const idVec3 &coneAnchor, const idVec3 &coneAxis, const float coneAngle, const idVec3 &body1Axis ) {
  2943. this->body1 = b1;
  2944. this->body2 = b2;
  2945. this->coneAxis = coneAxis;
  2946. this->coneAxis.Normalize();
  2947. this->coneAnchor = coneAnchor;
  2948. this->body1Axis = body1Axis;
  2949. this->body1Axis.Normalize();
  2950. this->cosAngle = (float) cos( DEG2RAD( coneAngle * 0.5f ) );
  2951. this->sinHalfAngle = (float) sin( DEG2RAD( coneAngle * 0.25f ) );
  2952. this->cosHalfAngle = (float) cos( DEG2RAD( coneAngle * 0.25f ) );
  2953. }
  2954. /*
  2955. ================
  2956. idAFConstraint_ConeLimit::SetAnchor
  2957. ================
  2958. */
  2959. void idAFConstraint_ConeLimit::SetAnchor( const idVec3 &coneAnchor ) {
  2960. this->coneAnchor = coneAnchor;
  2961. }
  2962. /*
  2963. ================
  2964. idAFConstraint_ConeLimit::SetBody1Axis
  2965. ================
  2966. */
  2967. void idAFConstraint_ConeLimit::SetBody1Axis( const idVec3 &body1Axis ) {
  2968. this->body1Axis = body1Axis;
  2969. }
  2970. /*
  2971. ================
  2972. idAFConstraint_ConeLimit::Evaluate
  2973. ================
  2974. */
  2975. void idAFConstraint_ConeLimit::Evaluate( float invTimeStep ) {
  2976. // do nothing
  2977. }
  2978. /*
  2979. ================
  2980. idAFConstraint_ConeLimit::ApplyFriction
  2981. ================
  2982. */
  2983. void idAFConstraint_ConeLimit::ApplyFriction( float invTimeStep ) {
  2984. }
  2985. /*
  2986. ================
  2987. idAFConstraint_ConeLimit::Add
  2988. ================
  2989. */
  2990. bool idAFConstraint_ConeLimit::Add( idPhysics_AF *phys, float invTimeStep ) {
  2991. float a;
  2992. idVec6 J1row, J2row;
  2993. idVec3 ax, anchor, body1ax, normal, coneVector, p1, p2;
  2994. idQuat q;
  2995. idAFBody *master;
  2996. if ( af_skipLimits.GetBool() ) {
  2997. lm.Zero(); // constraint exerts no force
  2998. return false;
  2999. }
  3000. physics = phys;
  3001. master = body2 ? body2 : physics->GetMasterBody();
  3002. if ( master ) {
  3003. ax = coneAxis * master->GetWorldAxis();
  3004. anchor = master->GetWorldOrigin() + coneAnchor * master->GetWorldAxis();
  3005. }
  3006. else {
  3007. ax = coneAxis;
  3008. anchor = coneAnchor;
  3009. }
  3010. body1ax = body1Axis * body1->GetWorldAxis();
  3011. a = ax * body1ax;
  3012. // if the body1 axis is inside the cone
  3013. if ( a > cosAngle ) {
  3014. lm.Zero(); // constraint exerts no force
  3015. return false;
  3016. }
  3017. // calculate the inward cone normal for the position the body1 axis went outside the cone
  3018. normal = body1ax.Cross( ax );
  3019. normal.Normalize();
  3020. q.x = normal.x * sinHalfAngle;
  3021. q.y = normal.y * sinHalfAngle;
  3022. q.z = normal.z * sinHalfAngle;
  3023. q.w = cosHalfAngle;
  3024. coneVector = ax * q.ToMat3();
  3025. normal = coneVector.Cross( ax ).Cross( coneVector );
  3026. normal.Normalize();
  3027. p1 = anchor + 32.0f * coneVector - body1->GetWorldOrigin();
  3028. J1row.SubVec3(0) = normal;
  3029. J1row.SubVec3(1) = p1.Cross( normal );
  3030. J1.Set( 1, 6, J1row.ToFloatPtr() );
  3031. c1[0] = (invTimeStep * LIMIT_ERROR_REDUCTION) * ( normal * (32.0f * body1ax) );
  3032. if ( body2 ) {
  3033. p2 = anchor + 32.0f * coneVector - master->GetWorldOrigin();
  3034. J2row.SubVec3(0) = -normal;
  3035. J2row.SubVec3(1) = p2.Cross( -normal );
  3036. J2.Set( 1, 6, J2row.ToFloatPtr() );
  3037. c2[0] = 0.0f;
  3038. }
  3039. lo[0] = 0.0f;
  3040. e[0] = LIMIT_LCP_EPSILON;
  3041. physics->AddFrameConstraint( this );
  3042. return true;
  3043. }
  3044. /*
  3045. ================
  3046. idAFConstraint_ConeLimit::Translate
  3047. ================
  3048. */
  3049. void idAFConstraint_ConeLimit::Translate( const idVec3 &translation ) {
  3050. if ( !body2 ) {
  3051. coneAnchor += translation;
  3052. }
  3053. }
  3054. /*
  3055. ================
  3056. idAFConstraint_ConeLimit::Rotate
  3057. ================
  3058. */
  3059. void idAFConstraint_ConeLimit::Rotate( const idRotation &rotation ) {
  3060. if ( !body2 ) {
  3061. coneAnchor *= rotation;
  3062. coneAxis *= rotation.ToMat3();
  3063. }
  3064. }
  3065. /*
  3066. ================
  3067. idAFConstraint_ConeLimit::DebugDraw
  3068. ================
  3069. */
  3070. void idAFConstraint_ConeLimit::DebugDraw() {
  3071. idVec3 ax, anchor, x, y, z, start, end;
  3072. float sinAngle, a, size = 10.0f;
  3073. idAFBody *master;
  3074. master = body2 ? body2 : physics->GetMasterBody();
  3075. if ( master ) {
  3076. ax = coneAxis * master->GetWorldAxis();
  3077. anchor = master->GetWorldOrigin() + coneAnchor * master->GetWorldAxis();
  3078. }
  3079. else {
  3080. ax = coneAxis;
  3081. anchor = coneAnchor;
  3082. }
  3083. // draw body1 axis
  3084. gameRenderWorld->DebugLine( colorGreen, anchor, anchor + size * (body1Axis * body1->GetWorldAxis()) );
  3085. // draw cone
  3086. ax.NormalVectors( x, y );
  3087. sinAngle = idMath::Sqrt( 1.0f - cosAngle * cosAngle );
  3088. x *= size * sinAngle;
  3089. y *= size * sinAngle;
  3090. z = anchor + ax * size * cosAngle;
  3091. start = x + z;
  3092. for ( a = 0.0f; a < 360.0f; a += 45.0f ) {
  3093. end = x * (float) cos( DEG2RAD(a + 45.0f) ) + y * (float) sin( DEG2RAD(a + 45.0f) ) + z;
  3094. gameRenderWorld->DebugLine( colorMagenta, anchor, start );
  3095. gameRenderWorld->DebugLine( colorMagenta, start, end );
  3096. start = end;
  3097. }
  3098. }
  3099. /*
  3100. ================
  3101. idAFConstraint_ConeLimit::Save
  3102. ================
  3103. */
  3104. void idAFConstraint_ConeLimit::Save( idSaveGame *saveFile ) const {
  3105. idAFConstraint::Save( saveFile );
  3106. saveFile->WriteVec3( coneAnchor );
  3107. saveFile->WriteVec3( coneAxis );
  3108. saveFile->WriteVec3( body1Axis );
  3109. saveFile->WriteFloat( cosAngle );
  3110. saveFile->WriteFloat( sinHalfAngle );
  3111. saveFile->WriteFloat( cosHalfAngle );
  3112. saveFile->WriteFloat( epsilon );
  3113. }
  3114. /*
  3115. ================
  3116. idAFConstraint_ConeLimit::Restore
  3117. ================
  3118. */
  3119. void idAFConstraint_ConeLimit::Restore( idRestoreGame *saveFile ) {
  3120. idAFConstraint::Restore( saveFile );
  3121. saveFile->ReadVec3( coneAnchor );
  3122. saveFile->ReadVec3( coneAxis );
  3123. saveFile->ReadVec3( body1Axis );
  3124. saveFile->ReadFloat( cosAngle );
  3125. saveFile->ReadFloat( sinHalfAngle );
  3126. saveFile->ReadFloat( cosHalfAngle );
  3127. saveFile->ReadFloat( epsilon );
  3128. }
  3129. //===============================================================
  3130. //
  3131. // idAFConstraint_PyramidLimit
  3132. //
  3133. //===============================================================
  3134. /*
  3135. ================
  3136. idAFConstraint_PyramidLimit::idAFConstraint_PyramidLimit
  3137. ================
  3138. */
  3139. idAFConstraint_PyramidLimit::idAFConstraint_PyramidLimit() {
  3140. type = CONSTRAINT_PYRAMIDLIMIT;
  3141. name = "pyramidLimit";
  3142. InitSize( 1 );
  3143. fl.allowPrimary = false;
  3144. fl.frameConstraint = true;
  3145. }
  3146. /*
  3147. ================
  3148. idAFConstraint_PyramidLimit::Setup
  3149. ================
  3150. */
  3151. void idAFConstraint_PyramidLimit::Setup( idAFBody *b1, idAFBody *b2, const idVec3 &pyramidAnchor,
  3152. const idVec3 &pyramidAxis, const idVec3 &baseAxis,
  3153. const float pyramidAngle1, const float pyramidAngle2, const idVec3 &body1Axis ) {
  3154. body1 = b1;
  3155. body2 = b2;
  3156. // setup the base and make sure the basis is orthonormal
  3157. pyramidBasis[2] = pyramidAxis;
  3158. pyramidBasis[2].Normalize();
  3159. pyramidBasis[0] = baseAxis;
  3160. pyramidBasis[0] -= pyramidBasis[2] * baseAxis * pyramidBasis[2];
  3161. pyramidBasis[0].Normalize();
  3162. pyramidBasis[1] = pyramidBasis[0].Cross( pyramidBasis[2] );
  3163. // pyramid top
  3164. this->pyramidAnchor = pyramidAnchor;
  3165. // angles
  3166. cosAngle[0] = (float) cos( DEG2RAD( pyramidAngle1 * 0.5f ) );
  3167. cosAngle[1] = (float) cos( DEG2RAD( pyramidAngle2 * 0.5f ) );
  3168. sinHalfAngle[0] = (float) sin( DEG2RAD( pyramidAngle1 * 0.25f ) );
  3169. sinHalfAngle[1] = (float) sin( DEG2RAD( pyramidAngle2 * 0.25f ) );
  3170. cosHalfAngle[0] = (float) cos( DEG2RAD( pyramidAngle1 * 0.25f ) );
  3171. cosHalfAngle[1] = (float) cos( DEG2RAD( pyramidAngle2 * 0.25f ) );
  3172. this->body1Axis = body1Axis;
  3173. }
  3174. /*
  3175. ================
  3176. idAFConstraint_PyramidLimit::SetAnchor
  3177. ================
  3178. */
  3179. void idAFConstraint_PyramidLimit::SetAnchor( const idVec3 &pyramidAnchor ) {
  3180. this->pyramidAnchor = pyramidAnchor;
  3181. }
  3182. /*
  3183. ================
  3184. idAFConstraint_PyramidLimit::SetBody1Axis
  3185. ================
  3186. */
  3187. void idAFConstraint_PyramidLimit::SetBody1Axis( const idVec3 &body1Axis ) {
  3188. this->body1Axis = body1Axis;
  3189. }
  3190. /*
  3191. ================
  3192. idAFConstraint_PyramidLimit::Evaluate
  3193. ================
  3194. */
  3195. void idAFConstraint_PyramidLimit::Evaluate( float invTimeStep ) {
  3196. // do nothing
  3197. }
  3198. /*
  3199. ================
  3200. idAFConstraint_PyramidLimit::ApplyFriction
  3201. ================
  3202. */
  3203. void idAFConstraint_PyramidLimit::ApplyFriction( float invTimeStep ) {
  3204. }
  3205. /*
  3206. ================
  3207. idAFConstraint_PyramidLimit::Add
  3208. ================
  3209. */
  3210. bool idAFConstraint_PyramidLimit::Add( idPhysics_AF *phys, float invTimeStep ) {
  3211. int i;
  3212. float a[2];
  3213. idVec6 J1row, J2row;
  3214. idMat3 worldBase;
  3215. idVec3 anchor, body1ax, ax[2], v, normal, pyramidVector, p1, p2;
  3216. idQuat q;
  3217. idAFBody *master;
  3218. if ( af_skipLimits.GetBool() ) {
  3219. lm.Zero(); // constraint exerts no force
  3220. return false;
  3221. }
  3222. physics = phys;
  3223. master = body2 ? body2 : physics->GetMasterBody();
  3224. if ( master ) {
  3225. worldBase[0] = pyramidBasis[0] * master->GetWorldAxis();
  3226. worldBase[1] = pyramidBasis[1] * master->GetWorldAxis();
  3227. worldBase[2] = pyramidBasis[2] * master->GetWorldAxis();
  3228. anchor = master->GetWorldOrigin() + pyramidAnchor * master->GetWorldAxis();
  3229. }
  3230. else {
  3231. worldBase = pyramidBasis;
  3232. anchor = pyramidAnchor;
  3233. }
  3234. body1ax = body1Axis * body1->GetWorldAxis();
  3235. for ( i = 0; i < 2; i++ ) {
  3236. ax[i] = body1ax - worldBase[!i] * body1ax * worldBase[!i];
  3237. ax[i].Normalize();
  3238. a[i] = worldBase[2] * ax[i];
  3239. }
  3240. // if the body1 axis is inside the pyramid
  3241. if ( a[0] > cosAngle[0] && a[1] > cosAngle[1] ) {
  3242. lm.Zero(); // constraint exerts no force
  3243. return false;
  3244. }
  3245. // calculate the inward pyramid normal for the position the body1 axis went outside the pyramid
  3246. pyramidVector = worldBase[2];
  3247. for ( i = 0; i < 2; i++ ) {
  3248. if ( a[i] <= cosAngle[i] ) {
  3249. v = ax[i].Cross( worldBase[2] );
  3250. v.Normalize();
  3251. q.x = v.x * sinHalfAngle[i];
  3252. q.y = v.y * sinHalfAngle[i];
  3253. q.z = v.z * sinHalfAngle[i];
  3254. q.w = cosHalfAngle[i];
  3255. pyramidVector *= q.ToMat3();
  3256. }
  3257. }
  3258. normal = pyramidVector.Cross( worldBase[2] ).Cross( pyramidVector );
  3259. normal.Normalize();
  3260. p1 = anchor + 32.0f * pyramidVector - body1->GetWorldOrigin();
  3261. J1row.SubVec3(0) = normal;
  3262. J1row.SubVec3(1) = p1.Cross( normal );
  3263. J1.Set( 1, 6, J1row.ToFloatPtr() );
  3264. c1[0] = (invTimeStep * LIMIT_ERROR_REDUCTION) * ( normal * (32.0f * body1ax) );
  3265. if ( body2 ) {
  3266. p2 = anchor + 32.0f * pyramidVector - master->GetWorldOrigin();
  3267. J2row.SubVec3(0) = -normal;
  3268. J2row.SubVec3(1) = p2.Cross( -normal );
  3269. J2.Set( 1, 6, J2row.ToFloatPtr() );
  3270. c2[0] = 0.0f;
  3271. }
  3272. lo[0] = 0.0f;
  3273. e[0] = LIMIT_LCP_EPSILON;
  3274. physics->AddFrameConstraint( this );
  3275. return true;
  3276. }
  3277. /*
  3278. ================
  3279. idAFConstraint_PyramidLimit::Translate
  3280. ================
  3281. */
  3282. void idAFConstraint_PyramidLimit::Translate( const idVec3 &translation ) {
  3283. if ( !body2 ) {
  3284. pyramidAnchor += translation;
  3285. }
  3286. }
  3287. /*
  3288. ================
  3289. idAFConstraint_PyramidLimit::Rotate
  3290. ================
  3291. */
  3292. void idAFConstraint_PyramidLimit::Rotate( const idRotation &rotation ) {
  3293. if ( !body2 ) {
  3294. pyramidAnchor *= rotation;
  3295. pyramidBasis[0] *= rotation.ToMat3();
  3296. pyramidBasis[1] *= rotation.ToMat3();
  3297. pyramidBasis[2] *= rotation.ToMat3();
  3298. }
  3299. }
  3300. /*
  3301. ================
  3302. idAFConstraint_PyramidLimit::DebugDraw
  3303. ================
  3304. */
  3305. void idAFConstraint_PyramidLimit::DebugDraw() {
  3306. int i;
  3307. float size = 10.0f;
  3308. idVec3 anchor, dir, p[4];
  3309. idMat3 worldBase, m[2];
  3310. idQuat q;
  3311. idAFBody *master;
  3312. master = body2 ? body2 : physics->GetMasterBody();
  3313. if ( master ) {
  3314. worldBase[0] = pyramidBasis[0] * master->GetWorldAxis();
  3315. worldBase[1] = pyramidBasis[1] * master->GetWorldAxis();
  3316. worldBase[2] = pyramidBasis[2] * master->GetWorldAxis();
  3317. anchor = master->GetWorldOrigin() + pyramidAnchor * master->GetWorldAxis();
  3318. }
  3319. else {
  3320. worldBase = pyramidBasis;
  3321. anchor = pyramidAnchor;
  3322. }
  3323. // draw body1 axis
  3324. gameRenderWorld->DebugLine( colorGreen, anchor, anchor + size * (body1Axis * body1->GetWorldAxis()) );
  3325. // draw the pyramid
  3326. for ( i = 0; i < 2; i++ ) {
  3327. q.x = worldBase[!i].x * sinHalfAngle[i];
  3328. q.y = worldBase[!i].y * sinHalfAngle[i];
  3329. q.z = worldBase[!i].z * sinHalfAngle[i];
  3330. q.w = cosHalfAngle[i];
  3331. m[i] = q.ToMat3();
  3332. }
  3333. dir = worldBase[2] * size;
  3334. p[0] = anchor + m[0] * (m[1] * dir);
  3335. p[1] = anchor + m[0] * (m[1].Transpose() * dir);
  3336. p[2] = anchor + m[0].Transpose() * (m[1].Transpose() * dir);
  3337. p[3] = anchor + m[0].Transpose() * (m[1] * dir);
  3338. for ( i = 0; i < 4; i++ ) {
  3339. gameRenderWorld->DebugLine( colorMagenta, anchor, p[i] );
  3340. gameRenderWorld->DebugLine( colorMagenta, p[i], p[(i+1)&3] );
  3341. }
  3342. }
  3343. /*
  3344. ================
  3345. idAFConstraint_PyramidLimit::Save
  3346. ================
  3347. */
  3348. void idAFConstraint_PyramidLimit::Save( idSaveGame *saveFile ) const {
  3349. idAFConstraint::Save( saveFile );
  3350. saveFile->WriteVec3( pyramidAnchor );
  3351. saveFile->WriteMat3( pyramidBasis );
  3352. saveFile->WriteVec3( body1Axis );
  3353. saveFile->WriteFloat( cosAngle[0] );
  3354. saveFile->WriteFloat( cosAngle[1] );
  3355. saveFile->WriteFloat( sinHalfAngle[0] );
  3356. saveFile->WriteFloat( sinHalfAngle[1] );
  3357. saveFile->WriteFloat( cosHalfAngle[0] );
  3358. saveFile->WriteFloat( cosHalfAngle[1] );
  3359. saveFile->WriteFloat( epsilon );
  3360. }
  3361. /*
  3362. ================
  3363. idAFConstraint_PyramidLimit::Restore
  3364. ================
  3365. */
  3366. void idAFConstraint_PyramidLimit::Restore( idRestoreGame *saveFile ) {
  3367. idAFConstraint::Restore( saveFile );
  3368. saveFile->ReadVec3( pyramidAnchor );
  3369. saveFile->ReadMat3( pyramidBasis );
  3370. saveFile->ReadVec3( body1Axis );
  3371. saveFile->ReadFloat( cosAngle[0] );
  3372. saveFile->ReadFloat( cosAngle[1] );
  3373. saveFile->ReadFloat( sinHalfAngle[0] );
  3374. saveFile->ReadFloat( sinHalfAngle[1] );
  3375. saveFile->ReadFloat( cosHalfAngle[0] );
  3376. saveFile->ReadFloat( cosHalfAngle[1] );
  3377. saveFile->ReadFloat( epsilon );
  3378. }
  3379. //===============================================================
  3380. //
  3381. // idAFConstraint_Suspension
  3382. //
  3383. //===============================================================
  3384. /*
  3385. ================
  3386. idAFConstraint_Suspension::idAFConstraint_Suspension
  3387. ================
  3388. */
  3389. idAFConstraint_Suspension::idAFConstraint_Suspension() {
  3390. type = CONSTRAINT_SUSPENSION;
  3391. name = "suspension";
  3392. InitSize( 3 );
  3393. fl.allowPrimary = false;
  3394. fl.frameConstraint = true;
  3395. localOrigin.Zero();
  3396. localAxis.Identity();
  3397. suspensionUp = 0.0f;
  3398. suspensionDown = 0.0f;
  3399. suspensionKCompress = 0.0f;
  3400. suspensionDamping = 0.0f;
  3401. steerAngle = 0.0f;
  3402. friction = 2.0f;
  3403. motorEnabled = false;
  3404. motorForce = 0.0f;
  3405. motorVelocity = 0.0f;
  3406. wheelModel = NULL;
  3407. memset( &trace, 0, sizeof( trace ) );
  3408. epsilon = LCP_EPSILON;
  3409. }
  3410. /*
  3411. ================
  3412. idAFConstraint_Suspension::Setup
  3413. ================
  3414. */
  3415. void idAFConstraint_Suspension::Setup( const char *name, idAFBody *body, const idVec3 &origin, const idMat3 &axis, idClipModel *clipModel ) {
  3416. this->name = name;
  3417. body1 = body;
  3418. body2 = NULL;
  3419. localOrigin = ( origin - body->GetWorldOrigin() ) * body->GetWorldAxis().Transpose();
  3420. localAxis = axis * body->GetWorldAxis().Transpose();
  3421. wheelModel = clipModel;
  3422. }
  3423. /*
  3424. ================
  3425. idAFConstraint_Suspension::SetSuspension
  3426. ================
  3427. */
  3428. void idAFConstraint_Suspension::SetSuspension( const float up, const float down, const float k, const float d, const float f ) {
  3429. suspensionUp = up;
  3430. suspensionDown = down;
  3431. suspensionKCompress = k;
  3432. suspensionDamping = d;
  3433. friction = f;
  3434. }
  3435. /*
  3436. ================
  3437. idAFConstraint_Suspension::GetWheelOrigin
  3438. ================
  3439. */
  3440. const idVec3 idAFConstraint_Suspension::GetWheelOrigin() const {
  3441. return body1->GetWorldOrigin() + wheelOffset * body1->GetWorldAxis();
  3442. }
  3443. /*
  3444. ================
  3445. idAFConstraint_Suspension::Evaluate
  3446. ================
  3447. */
  3448. void idAFConstraint_Suspension::Evaluate( float invTimeStep ) {
  3449. float velocity, suspensionLength, springLength, compression, dampingForce, springForce;
  3450. idVec3 origin, start, end, vel1, vel2, springDir, r, frictionDir, motorDir;
  3451. idMat3 axis;
  3452. idRotation rotation;
  3453. axis = localAxis * body1->GetWorldAxis();
  3454. origin = body1->GetWorldOrigin() + localOrigin * body1->GetWorldAxis();
  3455. start = origin + suspensionUp * axis[2];
  3456. end = origin - suspensionDown * axis[2];
  3457. rotation.SetVec( axis[2] );
  3458. rotation.SetAngle( steerAngle );
  3459. axis *= rotation.ToMat3();
  3460. gameLocal.clip.Translation( trace, start, end, wheelModel, axis, MASK_SOLID, NULL );
  3461. wheelOffset = ( trace.endpos - body1->GetWorldOrigin() ) * body1->GetWorldAxis().Transpose();
  3462. if ( trace.fraction >= 1.0f ) {
  3463. J1.SetSize( 0, 6 );
  3464. if ( body2 ) {
  3465. J2.SetSize( 0, 6 );
  3466. }
  3467. return;
  3468. }
  3469. // calculate and add spring force
  3470. vel1 = body1->GetPointVelocity( start );
  3471. if ( body2 ) {
  3472. vel2 = body2->GetPointVelocity( trace.c.point );
  3473. } else {
  3474. vel2.Zero();
  3475. }
  3476. suspensionLength = suspensionUp + suspensionDown;
  3477. springDir = trace.endpos - start;
  3478. springLength = trace.fraction * suspensionLength;
  3479. dampingForce = suspensionDamping * idMath::Fabs( ( vel2 - vel1 ) * springDir ) / ( 1.0f + springLength * springLength );
  3480. compression = suspensionLength - springLength;
  3481. springForce = compression * compression * suspensionKCompress - dampingForce;
  3482. r = trace.c.point - body1->GetWorldOrigin();
  3483. J1.SetSize( 2, 6 );
  3484. J1.SubVec6(0).SubVec3(0) = trace.c.normal;
  3485. J1.SubVec6(0).SubVec3(1) = r.Cross( trace.c.normal );
  3486. c1.SetSize( 2 );
  3487. c1[0] = 0.0f;
  3488. velocity = J1.SubVec6(0).SubVec3(0) * body1->GetLinearVelocity() + J1.SubVec6(0).SubVec3(1) * body1->GetAngularVelocity();
  3489. if ( body2 ) {
  3490. r = trace.c.point - body2->GetWorldOrigin();
  3491. J2.SetSize( 2, 6 );
  3492. J2.SubVec6(0).SubVec3(0) = -trace.c.normal;
  3493. J2.SubVec6(0).SubVec3(1) = r.Cross( -trace.c.normal );
  3494. c2.SetSize( 2 );
  3495. c2[0] = 0.0f;
  3496. velocity += J2.SubVec6(0).SubVec3(0) * body2->GetLinearVelocity() + J2.SubVec6(0).SubVec3(1) * body2->GetAngularVelocity();
  3497. }
  3498. c1[0] = -compression; // + 0.5f * -velocity;
  3499. e[0] = 1e-4f;
  3500. lo[0] = 0.0f;
  3501. hi[0] = springForce;
  3502. boxConstraint = NULL;
  3503. boxIndex[0] = -1;
  3504. // project the friction direction into the contact plane
  3505. frictionDir = axis[1] - axis[1] * trace.c.normal * axis[1];
  3506. frictionDir.Normalize();
  3507. r = trace.c.point - body1->GetWorldOrigin();
  3508. J1.SubVec6(1).SubVec3(0) = frictionDir;
  3509. J1.SubVec6(1).SubVec3(1) = r.Cross( frictionDir );
  3510. c1[1] = 0.0f;
  3511. if ( body2 ) {
  3512. r = trace.c.point - body2->GetWorldOrigin();
  3513. J2.SubVec6(1).SubVec3(0) = -frictionDir;
  3514. J2.SubVec6(1).SubVec3(1) = r.Cross( -frictionDir );
  3515. c2[1] = 0.0f;
  3516. }
  3517. lo[1] = -friction * physics->GetContactFrictionScale();
  3518. hi[1] = friction * physics->GetContactFrictionScale();
  3519. boxConstraint = this;
  3520. boxIndex[1] = 0;
  3521. if ( motorEnabled ) {
  3522. // project the motor force direction into the contact plane
  3523. motorDir = axis[0] - axis[0] * trace.c.normal * axis[0];
  3524. motorDir.Normalize();
  3525. r = trace.c.point - body1->GetWorldOrigin();
  3526. J1.ChangeSize( 3, J1.GetNumColumns() );
  3527. J1.SubVec6(2).SubVec3(0) = -motorDir;
  3528. J1.SubVec6(2).SubVec3(1) = r.Cross( -motorDir );
  3529. c1.ChangeSize( 3 );
  3530. c1[2] = motorVelocity;
  3531. if ( body2 ) {
  3532. r = trace.c.point - body2->GetWorldOrigin();
  3533. J2.ChangeSize( 3, J2.GetNumColumns() );
  3534. J2.SubVec6(2).SubVec3(0) = -motorDir;
  3535. J2.SubVec6(2).SubVec3(1) = r.Cross( -motorDir );
  3536. c2.ChangeSize( 3 );
  3537. c2[2] = 0.0f;
  3538. }
  3539. lo[2] = -motorForce;
  3540. hi[2] = motorForce;
  3541. boxIndex[2] = -1;
  3542. }
  3543. }
  3544. /*
  3545. ================
  3546. idAFConstraint_Suspension::ApplyFriction
  3547. ================
  3548. */
  3549. void idAFConstraint_Suspension::ApplyFriction( float invTimeStep ) {
  3550. // do nothing
  3551. }
  3552. /*
  3553. ================
  3554. idAFConstraint_Suspension::Translate
  3555. ================
  3556. */
  3557. void idAFConstraint_Suspension::Translate( const idVec3 &translation ) {
  3558. }
  3559. /*
  3560. ================
  3561. idAFConstraint_Suspension::Rotate
  3562. ================
  3563. */
  3564. void idAFConstraint_Suspension::Rotate( const idRotation &rotation ) {
  3565. }
  3566. /*
  3567. ================
  3568. idAFConstraint_Suspension::DebugDraw
  3569. ================
  3570. */
  3571. void idAFConstraint_Suspension::DebugDraw() {
  3572. idVec3 origin;
  3573. idMat3 axis;
  3574. idRotation rotation;
  3575. axis = localAxis * body1->GetWorldAxis();
  3576. rotation.SetVec( axis[2] );
  3577. rotation.SetAngle( steerAngle );
  3578. axis *= rotation.ToMat3();
  3579. if ( trace.fraction < 1.0f ) {
  3580. origin = trace.c.point;
  3581. gameRenderWorld->DebugLine( colorWhite, origin, origin + 6.0f * axis[2] );
  3582. gameRenderWorld->DebugLine( colorWhite, origin - 4.0f * axis[0], origin + 4.0f * axis[0] );
  3583. gameRenderWorld->DebugLine( colorWhite, origin - 2.0f * axis[1], origin + 2.0f * axis[1] );
  3584. }
  3585. }
  3586. //===============================================================
  3587. //
  3588. // idAFBody
  3589. //
  3590. //===============================================================
  3591. /*
  3592. ================
  3593. idAFBody::idAFBody
  3594. ================
  3595. */
  3596. idAFBody::idAFBody() {
  3597. Init();
  3598. }
  3599. /*
  3600. ================
  3601. idAFBody::idAFBody
  3602. ================
  3603. */
  3604. idAFBody::idAFBody( const idStr &name, idClipModel *clipModel, float density ) {
  3605. assert( clipModel );
  3606. assert( clipModel->IsTraceModel() );
  3607. Init();
  3608. this->name = name;
  3609. this->clipModel = NULL;
  3610. SetClipModel( clipModel );
  3611. SetDensity( density );
  3612. current->worldOrigin = clipModel->GetOrigin();
  3613. current->worldAxis = clipModel->GetAxis();
  3614. *next = *current;
  3615. }
  3616. /*
  3617. ================
  3618. idAFBody::~idAFBody
  3619. ================
  3620. */
  3621. idAFBody::~idAFBody() {
  3622. delete clipModel;
  3623. }
  3624. /*
  3625. ================
  3626. idAFBody::Init
  3627. ================
  3628. */
  3629. void idAFBody::Init() {
  3630. name = "noname";
  3631. parent = NULL;
  3632. clipModel = NULL;
  3633. primaryConstraint = NULL;
  3634. tree = NULL;
  3635. linearFriction = -1.0f;
  3636. angularFriction = -1.0f;
  3637. contactFriction = -1.0f;
  3638. bouncyness = -1.0f;
  3639. clipMask = 0;
  3640. frictionDir = vec3_zero;
  3641. contactMotorDir = vec3_zero;
  3642. contactMotorVelocity = 0.0f;
  3643. contactMotorForce = 0.0f;
  3644. mass = 1.0f;
  3645. invMass = 1.0f;
  3646. centerOfMass = vec3_zero;
  3647. inertiaTensor = mat3_identity;
  3648. inverseInertiaTensor = mat3_identity;
  3649. current = &state[0];
  3650. next = &state[1];
  3651. current->worldOrigin = vec3_zero;
  3652. current->worldAxis = mat3_identity;
  3653. current->spatialVelocity = vec6_zero;
  3654. current->externalForce = vec6_zero;
  3655. *next = *current;
  3656. saved = *current;
  3657. atRestOrigin = vec3_zero;
  3658. atRestAxis = mat3_identity;
  3659. s.Zero( 6 );
  3660. totalForce.Zero( 6 );
  3661. auxForce.Zero( 6 );
  3662. acceleration.Zero( 6 );
  3663. response = NULL;
  3664. responseIndex = NULL;
  3665. numResponses = 0;
  3666. maxAuxiliaryIndex = 0;
  3667. maxSubTreeAuxiliaryIndex = 0;
  3668. memset( &fl, 0, sizeof( fl ) );
  3669. fl.selfCollision = true;
  3670. fl.isZero = true;
  3671. }
  3672. /*
  3673. ================
  3674. idAFBody::SetClipModel
  3675. ================
  3676. */
  3677. void idAFBody::SetClipModel( idClipModel *clipModel ) {
  3678. if ( this->clipModel && this->clipModel != clipModel ) {
  3679. delete this->clipModel;
  3680. }
  3681. this->clipModel = clipModel;
  3682. }
  3683. /*
  3684. ================
  3685. idAFBody::SetFriction
  3686. ================
  3687. */
  3688. void idAFBody::SetFriction( float linear, float angular, float contact ) {
  3689. if ( linear < 0.0f || linear > 1.0f ||
  3690. angular < 0.0f || angular > 1.0f ||
  3691. contact < 0.0f ) {
  3692. gameLocal.Warning( "idAFBody::SetFriction: friction out of range, linear = %.1f, angular = %.1f, contact = %.1f", linear, angular, contact );
  3693. return;
  3694. }
  3695. linearFriction = linear;
  3696. angularFriction = angular;
  3697. contactFriction = contact;
  3698. }
  3699. /*
  3700. ================
  3701. idAFBody::SetBouncyness
  3702. ================
  3703. */
  3704. void idAFBody::SetBouncyness( float bounce ) {
  3705. if ( bounce < 0.0f || bounce > 1.0f ) {
  3706. gameLocal.Warning( "idAFBody::SetBouncyness: bouncyness out of range, bounce = %.1f", bounce );
  3707. return;
  3708. }
  3709. bouncyness = bounce;
  3710. }
  3711. /*
  3712. ================
  3713. idAFBody::SetDensity
  3714. ================
  3715. */
  3716. void idAFBody::SetDensity( float density, const idMat3 &inertiaScale ) {
  3717. // get the body mass properties
  3718. clipModel->GetMassProperties( density, mass, centerOfMass, inertiaTensor );
  3719. // make sure we have a valid mass
  3720. if ( mass <= 0.0f || IEEE_FLT_IS_NAN( mass ) ) {
  3721. gameLocal.Warning( "idAFBody::SetDensity: invalid mass for body '%s'", name.c_str() );
  3722. mass = 1.0f;
  3723. centerOfMass.Zero();
  3724. inertiaTensor.Identity();
  3725. }
  3726. // make sure the center of mass is at the body origin
  3727. if ( !centerOfMass.Compare( vec3_origin, CENTER_OF_MASS_EPSILON ) ) {
  3728. gameLocal.Warning( "idAFBody::SetDentity: center of mass not at origin for body '%s'", name.c_str() );
  3729. }
  3730. centerOfMass.Zero();
  3731. // calculate the inverse mass and inverse inertia tensor
  3732. invMass = 1.0f / mass;
  3733. if ( inertiaScale != mat3_identity ) {
  3734. inertiaTensor *= inertiaScale;
  3735. }
  3736. if ( inertiaTensor.IsDiagonal( 1e-3f ) ) {
  3737. inertiaTensor[0][1] = inertiaTensor[0][2] = 0.0f;
  3738. inertiaTensor[1][0] = inertiaTensor[1][2] = 0.0f;
  3739. inertiaTensor[2][0] = inertiaTensor[2][1] = 0.0f;
  3740. inverseInertiaTensor.Identity();
  3741. inverseInertiaTensor[0][0] = 1.0f / inertiaTensor[0][0];
  3742. inverseInertiaTensor[1][1] = 1.0f / inertiaTensor[1][1];
  3743. inverseInertiaTensor[2][2] = 1.0f / inertiaTensor[2][2];
  3744. }
  3745. else {
  3746. inverseInertiaTensor = inertiaTensor.Inverse();
  3747. }
  3748. }
  3749. /*
  3750. ================
  3751. idAFBody::SetFrictionDirection
  3752. ================
  3753. */
  3754. void idAFBody::SetFrictionDirection( const idVec3 &dir ) {
  3755. frictionDir = dir * current->worldAxis.Transpose();
  3756. fl.useFrictionDir = true;
  3757. }
  3758. /*
  3759. ================
  3760. idAFBody::GetFrictionDirection
  3761. ================
  3762. */
  3763. bool idAFBody::GetFrictionDirection( idVec3 &dir ) const {
  3764. if ( fl.useFrictionDir ) {
  3765. dir = frictionDir * current->worldAxis;
  3766. return true;
  3767. }
  3768. return false;
  3769. }
  3770. /*
  3771. ================
  3772. idAFBody::SetContactMotorDirection
  3773. ================
  3774. */
  3775. void idAFBody::SetContactMotorDirection( const idVec3 &dir ) {
  3776. contactMotorDir = dir * current->worldAxis.Transpose();
  3777. fl.useContactMotorDir = true;
  3778. }
  3779. /*
  3780. ================
  3781. idAFBody::GetContactMotorDirection
  3782. ================
  3783. */
  3784. bool idAFBody::GetContactMotorDirection( idVec3 &dir ) const {
  3785. if ( fl.useContactMotorDir ) {
  3786. dir = contactMotorDir * current->worldAxis;
  3787. return true;
  3788. }
  3789. return false;
  3790. }
  3791. /*
  3792. ================
  3793. idAFBody::GetPointVelocity
  3794. ================
  3795. */
  3796. idVec3 idAFBody::GetPointVelocity( const idVec3 &point ) const {
  3797. idVec3 r = point - current->worldOrigin;
  3798. return current->spatialVelocity.SubVec3(0) + current->spatialVelocity.SubVec3(1).Cross( r );
  3799. }
  3800. /*
  3801. ================
  3802. idAFBody::AddForce
  3803. ================
  3804. */
  3805. void idAFBody::AddForce( const idVec3 &point, const idVec3 &force ) {
  3806. current->externalForce.SubVec3(0) += force;
  3807. current->externalForce.SubVec3(1) += (point - current->worldOrigin).Cross( force );
  3808. }
  3809. /*
  3810. ================
  3811. idAFBody::InverseWorldSpatialInertiaMultiply
  3812. dst = this->inverseWorldSpatialInertia * v;
  3813. ================
  3814. */
  3815. ID_INLINE void idAFBody::InverseWorldSpatialInertiaMultiply( idVecX &dst, const float *v ) const {
  3816. const float *mPtr = inverseWorldSpatialInertia.ToFloatPtr();
  3817. const float *vPtr = v;
  3818. float *dstPtr = dst.ToFloatPtr();
  3819. if ( fl.spatialInertiaSparse ) {
  3820. dstPtr[0] = mPtr[0*6+0] * vPtr[0];
  3821. dstPtr[1] = mPtr[1*6+1] * vPtr[1];
  3822. dstPtr[2] = mPtr[2*6+2] * vPtr[2];
  3823. dstPtr[3] = mPtr[3*6+3] * vPtr[3] + mPtr[3*6+4] * vPtr[4] + mPtr[3*6+5] * vPtr[5];
  3824. dstPtr[4] = mPtr[4*6+3] * vPtr[3] + mPtr[4*6+4] * vPtr[4] + mPtr[4*6+5] * vPtr[5];
  3825. dstPtr[5] = mPtr[5*6+3] * vPtr[3] + mPtr[5*6+4] * vPtr[4] + mPtr[5*6+5] * vPtr[5];
  3826. } else {
  3827. gameLocal.Warning( "spatial inertia is not sparse for body %s", name.c_str() );
  3828. }
  3829. }
  3830. /*
  3831. ================
  3832. idAFBody::Save
  3833. ================
  3834. */
  3835. void idAFBody::Save( idSaveGame *saveFile ) {
  3836. saveFile->WriteFloat( linearFriction );
  3837. saveFile->WriteFloat( angularFriction );
  3838. saveFile->WriteFloat( contactFriction );
  3839. saveFile->WriteFloat( bouncyness );
  3840. saveFile->WriteInt( clipMask );
  3841. saveFile->WriteVec3( frictionDir );
  3842. saveFile->WriteVec3( contactMotorDir );
  3843. saveFile->WriteFloat( contactMotorVelocity );
  3844. saveFile->WriteFloat( contactMotorForce );
  3845. saveFile->WriteFloat( mass );
  3846. saveFile->WriteFloat( invMass );
  3847. saveFile->WriteVec3( centerOfMass );
  3848. saveFile->WriteMat3( inertiaTensor );
  3849. saveFile->WriteMat3( inverseInertiaTensor );
  3850. saveFile->WriteVec3( current->worldOrigin );
  3851. saveFile->WriteMat3( current->worldAxis );
  3852. saveFile->WriteVec6( current->spatialVelocity );
  3853. saveFile->WriteVec6( current->externalForce );
  3854. saveFile->WriteVec3( atRestOrigin );
  3855. saveFile->WriteMat3( atRestAxis );
  3856. }
  3857. /*
  3858. ================
  3859. idAFBody::Restore
  3860. ================
  3861. */
  3862. void idAFBody::Restore( idRestoreGame *saveFile ) {
  3863. saveFile->ReadFloat( linearFriction );
  3864. saveFile->ReadFloat( angularFriction );
  3865. saveFile->ReadFloat( contactFriction );
  3866. saveFile->ReadFloat( bouncyness );
  3867. saveFile->ReadInt( clipMask );
  3868. saveFile->ReadVec3( frictionDir );
  3869. saveFile->ReadVec3( contactMotorDir );
  3870. saveFile->ReadFloat( contactMotorVelocity );
  3871. saveFile->ReadFloat( contactMotorForce );
  3872. saveFile->ReadFloat( mass );
  3873. saveFile->ReadFloat( invMass );
  3874. saveFile->ReadVec3( centerOfMass );
  3875. saveFile->ReadMat3( inertiaTensor );
  3876. saveFile->ReadMat3( inverseInertiaTensor );
  3877. saveFile->ReadVec3( current->worldOrigin );
  3878. saveFile->ReadMat3( current->worldAxis );
  3879. saveFile->ReadVec6( current->spatialVelocity );
  3880. saveFile->ReadVec6( current->externalForce );
  3881. saveFile->ReadVec3( atRestOrigin );
  3882. saveFile->ReadMat3( atRestAxis );
  3883. }
  3884. //===============================================================
  3885. // M
  3886. // idAFTree MrE
  3887. // E
  3888. //===============================================================
  3889. /*
  3890. ================
  3891. idAFTree::Factor
  3892. factor matrix for the primary constraints in the tree
  3893. ================
  3894. */
  3895. void idAFTree::Factor() const {
  3896. int i, j;
  3897. idAFBody *body;
  3898. idAFConstraint *child = NULL;
  3899. idMatX childI;
  3900. childI.SetData( 6, 6, MATX_ALLOCA( 6 * 6 ) );
  3901. // from the leaves up towards the root
  3902. for ( i = sortedBodies.Num() - 1; i >= 0; i-- ) {
  3903. body = sortedBodies[i];
  3904. if ( body->children.Num() ) {
  3905. for ( j = 0; j < body->children.Num(); j++ ) {
  3906. child = body->children[j]->primaryConstraint;
  3907. // child->I = - child->body1->J.Transpose() * child->body1->I * child->body1->J;
  3908. childI.SetSize( child->J1.GetNumRows(), child->J1.GetNumRows() );
  3909. child->body1->J.TransposeMultiply( child->body1->I ).Multiply( childI, child->body1->J );
  3910. childI.Negate();
  3911. child->invI = childI;
  3912. if ( !child->invI.InverseFastSelf() ) {
  3913. gameLocal.Warning( "idAFTree::Factor: couldn't invert %dx%d matrix for constraint '%s'",
  3914. child->invI.GetNumRows(), child->invI.GetNumColumns(), child->GetName().c_str() );
  3915. }
  3916. child->J = child->invI * child->J;
  3917. body->I -= child->J.TransposeMultiply( childI ) * child->J;
  3918. }
  3919. body->invI = body->I;
  3920. if ( !body->invI.InverseFastSelf() && child != NULL ) {
  3921. gameLocal.Warning( "idAFTree::Factor: couldn't invert %dx%d matrix for body %s",
  3922. child->invI.GetNumRows(), child->invI.GetNumColumns(), body->GetName().c_str() );
  3923. }
  3924. if ( body->primaryConstraint ) {
  3925. body->J = body->invI * body->J;
  3926. }
  3927. }
  3928. else if ( body->primaryConstraint ) {
  3929. body->J = body->inverseWorldSpatialInertia * body->J;
  3930. }
  3931. }
  3932. }
  3933. /*
  3934. ================
  3935. idAFTree::Solve
  3936. solve for primary constraints in the tree
  3937. ================
  3938. */
  3939. void idAFTree::Solve( int auxiliaryIndex ) const {
  3940. int i, j;
  3941. idAFBody *body, *child;
  3942. idAFConstraint *primaryConstraint;
  3943. // from the leaves up towards the root
  3944. for ( i = sortedBodies.Num() - 1; i >= 0; i-- ) {
  3945. body = sortedBodies[i];
  3946. for ( j = 0; j < body->children.Num(); j++ ) {
  3947. child = body->children[j];
  3948. primaryConstraint = child->primaryConstraint;
  3949. if ( !child->fl.isZero ) {
  3950. child->J.TransposeMultiplySub( primaryConstraint->s, child->s );
  3951. primaryConstraint->fl.isZero = false;
  3952. }
  3953. if ( !primaryConstraint->fl.isZero ) {
  3954. primaryConstraint->J.TransposeMultiplySub( body->s, primaryConstraint->s );
  3955. body->fl.isZero = false;
  3956. }
  3957. }
  3958. }
  3959. bool useSymmetry = af_useSymmetry.GetBool();
  3960. // from the root down towards the leaves
  3961. for ( i = 0; i < sortedBodies.Num(); i++ ) {
  3962. body = sortedBodies[i];
  3963. primaryConstraint = body->primaryConstraint;
  3964. if ( primaryConstraint ) {
  3965. if ( useSymmetry && body->parent->maxSubTreeAuxiliaryIndex < auxiliaryIndex ) {
  3966. continue;
  3967. }
  3968. if ( !primaryConstraint->fl.isZero ) {
  3969. primaryConstraint->s = primaryConstraint->invI * primaryConstraint->s;
  3970. }
  3971. primaryConstraint->J.MultiplySub( primaryConstraint->s, primaryConstraint->body2->s );
  3972. primaryConstraint->lm = primaryConstraint->s;
  3973. if ( useSymmetry && body->maxSubTreeAuxiliaryIndex < auxiliaryIndex ) {
  3974. continue;
  3975. }
  3976. if ( body->children.Num() ) {
  3977. if ( !body->fl.isZero ) {
  3978. body->s = body->invI * body->s;
  3979. }
  3980. body->J.MultiplySub( body->s, primaryConstraint->s );
  3981. }
  3982. } else if ( body->children.Num() ) {
  3983. body->s = body->invI * body->s;
  3984. }
  3985. }
  3986. }
  3987. /*
  3988. ================
  3989. idAFTree::Response
  3990. calculate body forces in the tree in response to a constraint force
  3991. ================
  3992. */
  3993. void idAFTree::Response( const idAFConstraint *constraint, int row, int auxiliaryIndex ) const {
  3994. int i, j;
  3995. idAFBody *body;
  3996. idAFConstraint *child, *primaryConstraint;
  3997. idVecX v;
  3998. // if a single body don't waste time because there aren't any primary constraints
  3999. if ( sortedBodies.Num() == 1 ) {
  4000. body = constraint->body1;
  4001. if ( body->tree == this ) {
  4002. body->GetResponseForce( body->numResponses ) = constraint->J1.SubVec6( row );
  4003. body->responseIndex[body->numResponses++] = auxiliaryIndex;
  4004. }
  4005. else {
  4006. body = constraint->body2;
  4007. body->GetResponseForce( body->numResponses ) = constraint->J2.SubVec6( row );
  4008. body->responseIndex[body->numResponses++] = auxiliaryIndex;
  4009. }
  4010. return;
  4011. }
  4012. v.SetData( 6, VECX_ALLOCA( 6 ) );
  4013. // initialize right hand side to zero
  4014. for ( i = 0; i < sortedBodies.Num(); i++ ) {
  4015. body = sortedBodies[i];
  4016. primaryConstraint = body->primaryConstraint;
  4017. if ( primaryConstraint ) {
  4018. primaryConstraint->s.Zero();
  4019. primaryConstraint->fl.isZero = true;
  4020. }
  4021. body->s.Zero();
  4022. body->fl.isZero = true;
  4023. body->GetResponseForce( body->numResponses ).Zero();
  4024. }
  4025. // set right hand side for first constrained body
  4026. body = constraint->body1;
  4027. if ( body->tree == this ) {
  4028. body->InverseWorldSpatialInertiaMultiply( v, constraint->J1[row] );
  4029. primaryConstraint = body->primaryConstraint;
  4030. if ( primaryConstraint ) {
  4031. primaryConstraint->J1.Multiply( primaryConstraint->s, v );
  4032. primaryConstraint->fl.isZero = false;
  4033. }
  4034. for ( i = 0; i < body->children.Num(); i++ ) {
  4035. child = body->children[i]->primaryConstraint;
  4036. child->J2.Multiply( child->s, v );
  4037. child->fl.isZero = false;
  4038. }
  4039. body->GetResponseForce( body->numResponses ) = constraint->J1.SubVec6( row );
  4040. }
  4041. // set right hand side for second constrained body
  4042. body = constraint->body2;
  4043. if ( body && body->tree == this ) {
  4044. body->InverseWorldSpatialInertiaMultiply( v, constraint->J2[row] );
  4045. primaryConstraint = body->primaryConstraint;
  4046. if ( primaryConstraint ) {
  4047. primaryConstraint->J1.MultiplyAdd( primaryConstraint->s, v );
  4048. primaryConstraint->fl.isZero = false;
  4049. }
  4050. for ( i = 0; i < body->children.Num(); i++ ) {
  4051. child = body->children[i]->primaryConstraint;
  4052. child->J2.MultiplyAdd( child->s, v );
  4053. child->fl.isZero = false;
  4054. }
  4055. body->GetResponseForce( body->numResponses ) = constraint->J2.SubVec6( row );
  4056. }
  4057. // solve for primary constraints
  4058. Solve( auxiliaryIndex );
  4059. bool useSymmetry = af_useSymmetry.GetBool();
  4060. // store body forces in response to the constraint force
  4061. idVecX force;
  4062. for ( i = 0; i < sortedBodies.Num(); i++ ) {
  4063. body = sortedBodies[i];
  4064. if ( useSymmetry && body->maxAuxiliaryIndex < auxiliaryIndex ) {
  4065. continue;
  4066. }
  4067. force.SetData( 6, body->response + body->numResponses * 8 );
  4068. // add forces of all primary constraints acting on this body
  4069. primaryConstraint = body->primaryConstraint;
  4070. if ( primaryConstraint ) {
  4071. primaryConstraint->J1.TransposeMultiplyAdd( force, primaryConstraint->lm );
  4072. }
  4073. for ( j = 0; j < body->children.Num(); j++ ) {
  4074. child = body->children[j]->primaryConstraint;
  4075. child->J2.TransposeMultiplyAdd( force, child->lm );
  4076. }
  4077. body->responseIndex[body->numResponses++] = auxiliaryIndex;
  4078. }
  4079. }
  4080. /*
  4081. ================
  4082. idAFTree::CalculateForces
  4083. calculate forces on the bodies in the tree
  4084. ================
  4085. */
  4086. void idAFTree::CalculateForces( float timeStep ) const {
  4087. int i, j;
  4088. float invStep;
  4089. idAFBody *body;
  4090. idAFConstraint *child, *c, *primaryConstraint;
  4091. // forces on bodies
  4092. for ( i = 0; i < sortedBodies.Num(); i++ ) {
  4093. body = sortedBodies[i];
  4094. body->totalForce.SubVec6(0) = body->current->externalForce + body->auxForce.SubVec6(0);
  4095. }
  4096. // if a single body don't waste time because there aren't any primary constraints
  4097. if ( sortedBodies.Num() == 1 ) {
  4098. return;
  4099. }
  4100. invStep = 1.0f / timeStep;
  4101. // initialize right hand side
  4102. for ( i = 0; i < sortedBodies.Num(); i++ ) {
  4103. body = sortedBodies[i];
  4104. body->InverseWorldSpatialInertiaMultiply( body->acceleration, body->totalForce.ToFloatPtr() );
  4105. body->acceleration.SubVec6(0) += body->current->spatialVelocity * invStep;
  4106. primaryConstraint = body->primaryConstraint;
  4107. if ( primaryConstraint ) {
  4108. // b = ( J * acc + c )
  4109. c = primaryConstraint;
  4110. c->s = c->J1 * c->body1->acceleration + c->J2 * c->body2->acceleration + invStep * ( c->c1 + c->c2 );
  4111. c->fl.isZero = false;
  4112. }
  4113. body->s.Zero();
  4114. body->fl.isZero = true;
  4115. }
  4116. // solve for primary constraints
  4117. Solve();
  4118. // calculate forces on bodies after applying primary constraints
  4119. for ( i = 0; i < sortedBodies.Num(); i++ ) {
  4120. body = sortedBodies[i];
  4121. // add forces of all primary constraints acting on this body
  4122. primaryConstraint = body->primaryConstraint;
  4123. if ( primaryConstraint ) {
  4124. primaryConstraint->J1.TransposeMultiplyAdd( body->totalForce, primaryConstraint->lm );
  4125. }
  4126. for ( j = 0; j < body->children.Num(); j++ ) {
  4127. child = body->children[j]->primaryConstraint;
  4128. child->J2.TransposeMultiplyAdd( body->totalForce, child->lm );
  4129. }
  4130. }
  4131. }
  4132. /*
  4133. ================
  4134. idAFTree::SetMaxSubTreeAuxiliaryIndex
  4135. ================
  4136. */
  4137. void idAFTree::SetMaxSubTreeAuxiliaryIndex() {
  4138. int i, j;
  4139. idAFBody *body, *child;
  4140. // from the leaves up towards the root
  4141. for ( i = sortedBodies.Num() - 1; i >= 0; i-- ) {
  4142. body = sortedBodies[i];
  4143. body->maxSubTreeAuxiliaryIndex = body->maxAuxiliaryIndex;
  4144. for ( j = 0; j < body->children.Num(); j++ ) {
  4145. child = body->children[j];
  4146. if ( child->maxSubTreeAuxiliaryIndex > body->maxSubTreeAuxiliaryIndex ) {
  4147. body->maxSubTreeAuxiliaryIndex = child->maxSubTreeAuxiliaryIndex;
  4148. }
  4149. }
  4150. }
  4151. }
  4152. /*
  4153. ================
  4154. idAFTree::SortBodies_r
  4155. ================
  4156. */
  4157. void idAFTree::SortBodies_r( idList<idAFBody*>&sortedList, idAFBody *body ) {
  4158. int i;
  4159. for ( i = 0; i < body->children.Num(); i++ ) {
  4160. sortedList.Append( body->children[i] );
  4161. }
  4162. for ( i = 0; i < body->children.Num(); i++ ) {
  4163. SortBodies_r( sortedList, body->children[i] );
  4164. }
  4165. }
  4166. /*
  4167. ================
  4168. idAFTree::SortBodies
  4169. sort body list to make sure parents come first
  4170. ================
  4171. */
  4172. void idAFTree::SortBodies() {
  4173. int i;
  4174. idAFBody *body;
  4175. // find the root
  4176. for ( i = 0; i < sortedBodies.Num(); i++ ) {
  4177. if ( !sortedBodies[i]->parent ) {
  4178. break;
  4179. }
  4180. }
  4181. if ( i >= sortedBodies.Num() ) {
  4182. gameLocal.Error( "Articulated figure tree has no root." );
  4183. }
  4184. body = sortedBodies[i];
  4185. sortedBodies.Clear();
  4186. sortedBodies.Append( body );
  4187. SortBodies_r( sortedBodies, body );
  4188. }
  4189. /*
  4190. ================
  4191. idAFTree::DebugDraw
  4192. ================
  4193. */
  4194. void idAFTree::DebugDraw( const idVec4 &color ) const {
  4195. int i;
  4196. idAFBody *body;
  4197. for ( i = 1; i < sortedBodies.Num(); i++ ) {
  4198. body = sortedBodies[i];
  4199. gameRenderWorld->DebugArrow( color, body->parent->current->worldOrigin, body->current->worldOrigin, 1 );
  4200. }
  4201. }
  4202. //===============================================================
  4203. // M
  4204. // idPhysics_AF MrE
  4205. // E
  4206. //===============================================================
  4207. /*
  4208. ================
  4209. idPhysics_AF::EvaluateConstraints
  4210. ================
  4211. */
  4212. void idPhysics_AF::EvaluateConstraints( float timeStep ) {
  4213. int i;
  4214. float invTimeStep;
  4215. idAFBody *body;
  4216. idAFConstraint *c;
  4217. invTimeStep = 1.0f / timeStep;
  4218. // setup the constraint equations for the current position and orientation of the bodies
  4219. for ( i = 0; i < primaryConstraints.Num(); i++ ) {
  4220. c = primaryConstraints[i];
  4221. c->Evaluate( invTimeStep );
  4222. c->J = c->J2;
  4223. }
  4224. for ( i = 0; i < auxiliaryConstraints.Num(); i++ ) {
  4225. auxiliaryConstraints[i]->Evaluate( invTimeStep );
  4226. }
  4227. // add contact constraints to the list with frame constraints
  4228. for ( i = 0; i < contactConstraints.Num(); i++ ) {
  4229. AddFrameConstraint( contactConstraints[i] );
  4230. }
  4231. // setup body primary constraint matrix
  4232. for ( i = 0; i < bodies.Num(); i++ ) {
  4233. body = bodies[i];
  4234. if ( body->primaryConstraint ) {
  4235. body->J = body->primaryConstraint->J1.Transpose();
  4236. }
  4237. }
  4238. }
  4239. /*
  4240. ================
  4241. idPhysics_AF::EvaluateBodies
  4242. ================
  4243. */
  4244. void idPhysics_AF::EvaluateBodies( float timeStep ) {
  4245. int i;
  4246. idAFBody *body;
  4247. idMat3 axis;
  4248. for ( i = 0; i < bodies.Num(); i++ ) {
  4249. body = bodies[i];
  4250. // we transpose the axis before using it because idMat3 is column-major
  4251. axis = body->current->worldAxis.Transpose();
  4252. // if the center of mass is at the body point of reference
  4253. if ( body->centerOfMass.Compare( vec3_origin, CENTER_OF_MASS_EPSILON ) ) {
  4254. // spatial inertia in world space
  4255. body->I.Set( body->mass * mat3_identity, mat3_zero,
  4256. mat3_zero, axis * body->inertiaTensor * axis.Transpose() );
  4257. // inverse spatial inertia in world space
  4258. body->inverseWorldSpatialInertia.Set( body->invMass * mat3_identity, mat3_zero,
  4259. mat3_zero, axis * body->inverseInertiaTensor * axis.Transpose() );
  4260. body->fl.spatialInertiaSparse = true;
  4261. }
  4262. else {
  4263. idMat3 massMoment = body->mass * SkewSymmetric( body->centerOfMass );
  4264. // spatial inertia in world space
  4265. body->I.Set( body->mass * mat3_identity, massMoment,
  4266. massMoment.Transpose(), axis * body->inertiaTensor * axis.Transpose() );
  4267. // inverse spatial inertia in world space
  4268. body->inverseWorldSpatialInertia = body->I.InverseFast();
  4269. body->fl.spatialInertiaSparse = false;
  4270. }
  4271. // initialize auxiliary constraint force to zero
  4272. body->auxForce.Zero();
  4273. }
  4274. }
  4275. /*
  4276. ================
  4277. idPhysics_AF::AddFrameConstraints
  4278. ================
  4279. */
  4280. void idPhysics_AF::AddFrameConstraints() {
  4281. int i;
  4282. // add frame constraints to auxiliary constraints
  4283. for ( i = 0; i < frameConstraints.Num(); i++ ) {
  4284. auxiliaryConstraints.Append( frameConstraints[i] );
  4285. }
  4286. }
  4287. /*
  4288. ================
  4289. idPhysics_AF::RemoveFrameConstraints
  4290. ================
  4291. */
  4292. void idPhysics_AF::RemoveFrameConstraints() {
  4293. // remove all the frame constraints from the auxiliary constraints
  4294. auxiliaryConstraints.SetNum( auxiliaryConstraints.Num() - frameConstraints.Num() );
  4295. frameConstraints.SetNum( 0 );
  4296. }
  4297. /*
  4298. ================
  4299. idPhysics_AF::ApplyFriction
  4300. ================
  4301. */
  4302. void idPhysics_AF::ApplyFriction( float timeStep, float endTimeMSec ) {
  4303. int i;
  4304. float invTimeStep;
  4305. if ( af_skipFriction.GetBool() ) {
  4306. return;
  4307. }
  4308. if ( jointFrictionDentStart < MS2SEC( endTimeMSec ) && jointFrictionDentEnd > MS2SEC( endTimeMSec ) ) {
  4309. float halfTime = ( jointFrictionDentEnd - jointFrictionDentStart ) * 0.5f;
  4310. if ( jointFrictionDentStart + halfTime > MS2SEC( endTimeMSec ) ) {
  4311. jointFrictionDentScale = 1.0f - ( 1.0f - jointFrictionDent ) * ( MS2SEC( endTimeMSec ) - jointFrictionDentStart ) / halfTime;
  4312. } else {
  4313. jointFrictionDentScale = jointFrictionDent + ( 1.0f - jointFrictionDent ) * ( MS2SEC( endTimeMSec ) - jointFrictionDentStart - halfTime ) / halfTime;
  4314. }
  4315. } else {
  4316. jointFrictionDentScale = 0.0f;
  4317. }
  4318. if ( contactFrictionDentStart < MS2SEC( endTimeMSec ) && contactFrictionDentEnd > MS2SEC( endTimeMSec ) ) {
  4319. float halfTime = ( contactFrictionDentEnd - contactFrictionDentStart ) * 0.5f;
  4320. if ( contactFrictionDentStart + halfTime > MS2SEC( endTimeMSec ) ) {
  4321. contactFrictionDentScale = 1.0f - ( 1.0f - contactFrictionDent ) * ( MS2SEC( endTimeMSec ) - contactFrictionDentStart ) / halfTime;
  4322. } else {
  4323. contactFrictionDentScale = contactFrictionDent + ( 1.0f - contactFrictionDent ) * ( MS2SEC( endTimeMSec ) - contactFrictionDentStart - halfTime ) / halfTime;
  4324. }
  4325. } else {
  4326. contactFrictionDentScale = 0.0f;
  4327. }
  4328. invTimeStep = 1.0f / timeStep;
  4329. for ( i = 0; i < primaryConstraints.Num(); i++ ) {
  4330. primaryConstraints[i]->ApplyFriction( invTimeStep );
  4331. }
  4332. for ( i = 0; i < auxiliaryConstraints.Num(); i++ ) {
  4333. auxiliaryConstraints[i]->ApplyFriction( invTimeStep );
  4334. }
  4335. for ( i = 0; i < frameConstraints.Num(); i++ ) {
  4336. frameConstraints[i]->ApplyFriction( invTimeStep );
  4337. }
  4338. }
  4339. /*
  4340. ================
  4341. idPhysics_AF::PrimaryFactor
  4342. ================
  4343. */
  4344. void idPhysics_AF::PrimaryFactor() {
  4345. int i;
  4346. for ( i = 0; i < trees.Num(); i++ ) {
  4347. trees[i]->Factor();
  4348. }
  4349. }
  4350. /*
  4351. ================
  4352. idPhysics_AF::PrimaryForces
  4353. ================
  4354. */
  4355. void idPhysics_AF::PrimaryForces( float timeStep ) {
  4356. int i;
  4357. for ( i = 0; i < trees.Num(); i++ ) {
  4358. trees[i]->CalculateForces( timeStep );
  4359. }
  4360. }
  4361. /*
  4362. ================
  4363. idPhysics_AF::AuxiliaryForces
  4364. ================
  4365. */
  4366. void idPhysics_AF::AuxiliaryForces( float timeStep ) {
  4367. int i, j, k, l, n, m, s, numAuxConstraints, *index, *boxIndex;
  4368. float *ptr, *j1, *j2, *dstPtr, *forcePtr;
  4369. float invStep, u;
  4370. idAFBody *body;
  4371. idAFConstraint *constraint;
  4372. idVecX tmp;
  4373. idMatX jmk;
  4374. idVecX rhs, w, lm, lo, hi;
  4375. // get the number of one dimensional auxiliary constraints
  4376. for ( numAuxConstraints = 0, i = 0; i < auxiliaryConstraints.Num(); i++ ) {
  4377. numAuxConstraints += auxiliaryConstraints[i]->J1.GetNumRows();
  4378. }
  4379. if ( numAuxConstraints == 0 ) {
  4380. return;
  4381. }
  4382. // allocate memory to store the body response to auxiliary constraint forces
  4383. forcePtr = (float *) _alloca16( bodies.Num() * numAuxConstraints * 8 * sizeof( float ) );
  4384. index = (int *) _alloca16( bodies.Num() * numAuxConstraints * sizeof( int ) );
  4385. for ( i = 0; i < bodies.Num(); i++ ) {
  4386. body = bodies[i];
  4387. body->response = forcePtr;
  4388. body->responseIndex = index;
  4389. body->numResponses = 0;
  4390. body->maxAuxiliaryIndex = 0;
  4391. forcePtr += numAuxConstraints * 8;
  4392. index += numAuxConstraints;
  4393. }
  4394. // set on each body the largest index of an auxiliary constraint constraining the body
  4395. if ( af_useSymmetry.GetBool() ) {
  4396. for ( k = 0, i = 0; i < auxiliaryConstraints.Num(); i++ ) {
  4397. constraint = auxiliaryConstraints[i];
  4398. for ( j = 0; j < constraint->J1.GetNumRows(); j++, k++ ) {
  4399. if ( k > constraint->body1->maxAuxiliaryIndex ) {
  4400. constraint->body1->maxAuxiliaryIndex = k;
  4401. }
  4402. if ( constraint->body2 && k > constraint->body2->maxAuxiliaryIndex ) {
  4403. constraint->body2->maxAuxiliaryIndex = k;
  4404. }
  4405. }
  4406. }
  4407. for ( i = 0; i < trees.Num(); i++ ) {
  4408. trees[i]->SetMaxSubTreeAuxiliaryIndex();
  4409. }
  4410. }
  4411. // calculate forces of primary constraints in response to the auxiliary constraint forces
  4412. for ( k = 0, i = 0; i < auxiliaryConstraints.Num(); i++ ) {
  4413. constraint = auxiliaryConstraints[i];
  4414. for ( j = 0; j < constraint->J1.GetNumRows(); j++, k++ ) {
  4415. // calculate body forces in the tree in response to the constraint force
  4416. constraint->body1->tree->Response( constraint, j, k );
  4417. // if there is a second body which is part of a different tree
  4418. if ( constraint->body2 && constraint->body2->tree != constraint->body1->tree ) {
  4419. // calculate body forces in the second tree in response to the constraint force
  4420. constraint->body2->tree->Response( constraint, j, k );
  4421. }
  4422. }
  4423. }
  4424. // NOTE: the rows are 16 byte padded
  4425. jmk.SetData( numAuxConstraints, ((numAuxConstraints+3)&~3), MATX_ALLOCA( numAuxConstraints * ((numAuxConstraints+3)&~3) ) );
  4426. tmp.SetData( 6, VECX_ALLOCA( 6 ) );
  4427. // create constraint matrix for auxiliary constraints using a mass matrix adjusted for the primary constraints
  4428. for ( k = 0, i = 0; i < auxiliaryConstraints.Num(); i++ ) {
  4429. constraint = auxiliaryConstraints[i];
  4430. for ( j = 0; j < constraint->J1.GetNumRows(); j++, k++ ) {
  4431. constraint->body1->InverseWorldSpatialInertiaMultiply( tmp, constraint->J1[j] );
  4432. j1 = tmp.ToFloatPtr();
  4433. ptr = constraint->body1->response;
  4434. index = constraint->body1->responseIndex;
  4435. dstPtr = jmk[k];
  4436. s = af_useSymmetry.GetBool() ? k + 1 : numAuxConstraints;
  4437. for ( l = n = 0, m = index[n]; n < constraint->body1->numResponses && m < s; n++, m = index[n] ) {
  4438. while( l < m ) {
  4439. dstPtr[l++] = 0.0f;
  4440. }
  4441. dstPtr[l++] = j1[0] * ptr[0] + j1[1] * ptr[1] + j1[2] * ptr[2] +
  4442. j1[3] * ptr[3] + j1[4] * ptr[4] + j1[5] * ptr[5];
  4443. ptr += 8;
  4444. }
  4445. while( l < s ) {
  4446. dstPtr[l++] = 0.0f;
  4447. }
  4448. if ( constraint->body2 ) {
  4449. constraint->body2->InverseWorldSpatialInertiaMultiply( tmp, constraint->J2[j] );
  4450. j2 = tmp.ToFloatPtr();
  4451. ptr = constraint->body2->response;
  4452. index = constraint->body2->responseIndex;
  4453. for ( n = 0, m = index[n]; n < constraint->body2->numResponses && m < s; n++, m = index[n] ) {
  4454. dstPtr[m] += j2[0] * ptr[0] + j2[1] * ptr[1] + j2[2] * ptr[2] +
  4455. j2[3] * ptr[3] + j2[4] * ptr[4] + j2[5] * ptr[5];
  4456. ptr += 8;
  4457. }
  4458. }
  4459. }
  4460. }
  4461. if ( af_useSymmetry.GetBool() ) {
  4462. n = jmk.GetNumColumns();
  4463. for ( i = 0; i < numAuxConstraints; i++ ) {
  4464. ptr = jmk.ToFloatPtr() + ( i + 1 ) * n + i;
  4465. dstPtr = jmk.ToFloatPtr() + i * n + i + 1;
  4466. for ( j = i+1; j < numAuxConstraints; j++ ) {
  4467. *dstPtr++ = *ptr;
  4468. ptr += n;
  4469. }
  4470. }
  4471. }
  4472. invStep = 1.0f / timeStep;
  4473. // calculate body acceleration
  4474. for ( i = 0; i < bodies.Num(); i++ ) {
  4475. body = bodies[i];
  4476. body->InverseWorldSpatialInertiaMultiply( body->acceleration, body->totalForce.ToFloatPtr() );
  4477. body->acceleration.SubVec6(0) += body->current->spatialVelocity * invStep;
  4478. }
  4479. rhs.SetData( numAuxConstraints, VECX_ALLOCA( numAuxConstraints ) );
  4480. lo.SetData( numAuxConstraints, VECX_ALLOCA( numAuxConstraints ) );
  4481. hi.SetData( numAuxConstraints, VECX_ALLOCA( numAuxConstraints ) );
  4482. lm.SetData( numAuxConstraints, VECX_ALLOCA( numAuxConstraints ) );
  4483. boxIndex = (int *) _alloca16( numAuxConstraints * sizeof( int ) );
  4484. // set first index for special box constrained variables
  4485. for ( k = 0, i = 0; i < auxiliaryConstraints.Num(); i++ ) {
  4486. auxiliaryConstraints[i]->firstIndex = k;
  4487. k += auxiliaryConstraints[i]->J1.GetNumRows();
  4488. }
  4489. // initialize right hand side and low and high bounds for auxiliary constraints
  4490. for ( k = 0, i = 0; i < auxiliaryConstraints.Num(); i++ ) {
  4491. constraint = auxiliaryConstraints[i];
  4492. n = k;
  4493. for ( j = 0; j < constraint->J1.GetNumRows(); j++, k++ ) {
  4494. j1 = constraint->J1[j];
  4495. ptr = constraint->body1->acceleration.ToFloatPtr();
  4496. rhs[k] = j1[0] * ptr[0] + j1[1] * ptr[1] + j1[2] * ptr[2] + j1[3] * ptr[3] + j1[4] * ptr[4] + j1[5] * ptr[5];
  4497. rhs[k] += constraint->c1[j] * invStep;
  4498. if ( constraint->body2 ) {
  4499. j2 = constraint->J2[j];
  4500. ptr = constraint->body2->acceleration.ToFloatPtr();
  4501. rhs[k] += j2[0] * ptr[0] + j2[1] * ptr[1] + j2[2] * ptr[2] + j2[3] * ptr[3] + j2[4] * ptr[4] + j2[5] * ptr[5];
  4502. rhs[k] += constraint->c2[j] * invStep;
  4503. }
  4504. rhs[k] = -rhs[k];
  4505. lo[k] = constraint->lo[j];
  4506. hi[k] = constraint->hi[j];
  4507. if ( constraint->boxIndex[j] >= 0 ) {
  4508. if ( constraint->boxConstraint->fl.isPrimary ) {
  4509. gameLocal.Error( "cannot reference primary constraints for the box index" );
  4510. }
  4511. boxIndex[k] = constraint->boxConstraint->firstIndex + constraint->boxIndex[j];
  4512. }
  4513. else {
  4514. boxIndex[k] = -1;
  4515. }
  4516. jmk[k][k] += constraint->e[j] * invStep;
  4517. }
  4518. }
  4519. #ifdef AF_TIMINGS
  4520. timer_lcp.Start();
  4521. #endif
  4522. // calculate lagrange multipliers for auxiliary constraints
  4523. if ( !lcp->Solve( jmk, lm, rhs, lo, hi, boxIndex ) ) {
  4524. return; // bad monkey!
  4525. }
  4526. #ifdef AF_TIMINGS
  4527. timer_lcp.Stop();
  4528. #endif
  4529. // calculate auxiliary constraint forces
  4530. for ( k = 0, i = 0; i < auxiliaryConstraints.Num(); i++ ) {
  4531. constraint = auxiliaryConstraints[i];
  4532. for ( j = 0; j < constraint->J1.GetNumRows(); j++, k++ ) {
  4533. constraint->lm[j] = u = lm[k];
  4534. j1 = constraint->J1[j];
  4535. ptr = constraint->body1->auxForce.ToFloatPtr();
  4536. ptr[0] += j1[0] * u; ptr[1] += j1[1] * u; ptr[2] += j1[2] * u;
  4537. ptr[3] += j1[3] * u; ptr[4] += j1[4] * u; ptr[5] += j1[5] * u;
  4538. if ( constraint->body2 ) {
  4539. j2 = constraint->J2[j];
  4540. ptr = constraint->body2->auxForce.ToFloatPtr();
  4541. ptr[0] += j2[0] * u; ptr[1] += j2[1] * u; ptr[2] += j2[2] * u;
  4542. ptr[3] += j2[3] * u; ptr[4] += j2[4] * u; ptr[5] += j2[5] * u;
  4543. }
  4544. }
  4545. }
  4546. // recalculate primary constraint forces in response to auxiliary constraint forces
  4547. PrimaryForces( timeStep );
  4548. // clear pointers pointing to stack space so tools don't get confused
  4549. for ( i = 0; i < bodies.Num(); i++ ) {
  4550. body = bodies[i];
  4551. body->response = NULL;
  4552. body->responseIndex = NULL;
  4553. }
  4554. }
  4555. /*
  4556. ================
  4557. idPhysics_AF::VerifyContactConstraints
  4558. ================
  4559. */
  4560. void idPhysics_AF::VerifyContactConstraints() {
  4561. #if 0
  4562. int i;
  4563. float impulseNumerator, impulseDenominator;
  4564. idVec3 r, velocity, normalVelocity, normal, impulse;
  4565. idAFBody *body;
  4566. for ( i = 0; i < contactConstraints.Num(); i++ ) {
  4567. body = contactConstraints[i]->body1;
  4568. const contactInfo_t &contact = contactConstraints[i]->GetContact();
  4569. r = contact.point - body->GetCenterOfMass();
  4570. // calculate velocity at contact point
  4571. velocity = body->GetLinearVelocity() + body->GetAngularVelocity().Cross( r );
  4572. // velocity along normal vector
  4573. normalVelocity = ( velocity * contact.normal ) * contact.normal;
  4574. // if moving towards the surface at the contact point
  4575. if ( normalVelocity * contact.normal < 0.0f ) {
  4576. // calculate impulse
  4577. normal = -normalVelocity;
  4578. impulseNumerator = normal.Normalize();
  4579. impulseDenominator = body->GetInverseMass() + ( ( body->GetInverseWorldInertia() * r.Cross( normal ) ).Cross( r ) * normal );
  4580. impulse = (impulseNumerator / impulseDenominator) * normal * 1.0001f;
  4581. // apply impulse
  4582. body->SetLinearVelocity( body->GetLinearVelocity() + impulse );
  4583. body->SetAngularVelocity( body->GetAngularVelocity() + r.Cross( impulse ) );
  4584. }
  4585. }
  4586. #else
  4587. int i;
  4588. idAFBody *body;
  4589. idVec3 normal;
  4590. for ( i = 0; i < contactConstraints.Num(); i++ ) {
  4591. body = contactConstraints[i]->body1;
  4592. normal = contactConstraints[i]->GetContact().normal;
  4593. if ( normal * body->next->spatialVelocity.SubVec3(0) <= 0.0f ) {
  4594. body->next->spatialVelocity.SubVec3(0) -= 1.0001f * (normal * body->next->spatialVelocity.SubVec3(0)) * normal;
  4595. }
  4596. body = contactConstraints[i]->body2;
  4597. if ( !body ) {
  4598. continue;
  4599. }
  4600. normal = -normal;
  4601. if ( normal * body->next->spatialVelocity.SubVec3(0) <= 0.0f ) {
  4602. body->next->spatialVelocity.SubVec3(0) -= 1.0001f * (normal * body->next->spatialVelocity.SubVec3(0)) * normal;
  4603. }
  4604. }
  4605. #endif
  4606. }
  4607. /*
  4608. ================
  4609. idPhysics_AF::Evolve
  4610. ================
  4611. */
  4612. void idPhysics_AF::Evolve( float timeStep ) {
  4613. int i;
  4614. float angle;
  4615. idVec3 vec;
  4616. idAFBody *body;
  4617. idVec6 force;
  4618. idRotation rotation;
  4619. float vSqr, maxLinearVelocity, maxAngularVelocity;
  4620. maxLinearVelocity = af_maxLinearVelocity.GetFloat() / timeStep;
  4621. maxAngularVelocity = af_maxAngularVelocity.GetFloat() / timeStep;
  4622. for ( i = 0; i < bodies.Num(); i++ ) {
  4623. body = bodies[i];
  4624. // calculate the spatial velocity for the next physics state
  4625. body->InverseWorldSpatialInertiaMultiply( body->acceleration, body->totalForce.ToFloatPtr() );
  4626. body->next->spatialVelocity = body->current->spatialVelocity + timeStep * body->acceleration.SubVec6(0);
  4627. if ( maxLinearVelocity > 0.0f ) {
  4628. // cap the linear velocity
  4629. vSqr = body->next->spatialVelocity.SubVec3(0).LengthSqr();
  4630. if ( vSqr > Square( maxLinearVelocity ) ) {
  4631. body->next->spatialVelocity.SubVec3(0) *= idMath::InvSqrt( vSqr ) * maxLinearVelocity;
  4632. }
  4633. }
  4634. if ( maxAngularVelocity > 0.0f ) {
  4635. // cap the angular velocity
  4636. vSqr = body->next->spatialVelocity.SubVec3(1).LengthSqr();
  4637. if ( vSqr > Square( maxAngularVelocity ) ) {
  4638. body->next->spatialVelocity.SubVec3(1) *= idMath::InvSqrt( vSqr ) * maxAngularVelocity;
  4639. }
  4640. }
  4641. }
  4642. // make absolutely sure all contact constraints are satisfied
  4643. VerifyContactConstraints();
  4644. // calculate the position of the bodies for the next physics state
  4645. for ( i = 0; i < bodies.Num(); i++ ) {
  4646. body = bodies[i];
  4647. // translate world origin
  4648. body->next->worldOrigin = body->current->worldOrigin + timeStep * body->next->spatialVelocity.SubVec3( 0 );
  4649. // convert angular velocity to a rotation matrix
  4650. vec = body->next->spatialVelocity.SubVec3( 1 );
  4651. angle = -timeStep * (float) RAD2DEG( vec.Normalize() );
  4652. rotation = idRotation( vec3_origin, vec, angle );
  4653. rotation.Normalize180();
  4654. // rotate world axis
  4655. body->next->worldAxis = body->current->worldAxis * rotation.ToMat3();
  4656. body->next->worldAxis.OrthoNormalizeSelf();
  4657. // linear and angular friction
  4658. body->next->spatialVelocity.SubVec3(0) -= body->linearFriction * body->next->spatialVelocity.SubVec3(0);
  4659. body->next->spatialVelocity.SubVec3(1) -= body->angularFriction * body->next->spatialVelocity.SubVec3(1);
  4660. }
  4661. }
  4662. /*
  4663. ================
  4664. idPhysics_AF::CollisionImpulse
  4665. apply impulse to the colliding bodies
  4666. the current state of the body should be set to the moment of impact
  4667. this is silly as it doesn't take the AF structure into account
  4668. ================
  4669. */
  4670. bool idPhysics_AF::CollisionImpulse( float timeStep, idAFBody *body, trace_t &collision ) {
  4671. idVec3 r, velocity, impulse;
  4672. idMat3 inverseWorldInertiaTensor;
  4673. float impulseNumerator, impulseDenominator;
  4674. impactInfo_t info;
  4675. idEntity *ent;
  4676. ent = gameLocal.entities[collision.c.entityNum];
  4677. if ( ent == self ) {
  4678. return false;
  4679. }
  4680. // get info from other entity involved
  4681. ent->GetImpactInfo( self, collision.c.id, collision.c.point, &info );
  4682. // collision point relative to the body center of mass
  4683. r = collision.c.point - (body->current->worldOrigin + body->centerOfMass * body->current->worldAxis);
  4684. // the velocity at the collision point
  4685. velocity = body->current->spatialVelocity.SubVec3(0) + body->current->spatialVelocity.SubVec3(1).Cross(r);
  4686. // subtract velocity of other entity
  4687. velocity -= info.velocity;
  4688. // never stick
  4689. if ( velocity * collision.c.normal > 0.0f ) {
  4690. velocity = collision.c.normal;
  4691. }
  4692. inverseWorldInertiaTensor = body->current->worldAxis.Transpose() * body->inverseInertiaTensor * body->current->worldAxis;
  4693. impulseNumerator = -( 1.0f + body->bouncyness ) * ( velocity * collision.c.normal );
  4694. impulseDenominator = body->invMass + ( ( inverseWorldInertiaTensor * r.Cross( collision.c.normal ) ).Cross( r ) * collision.c.normal );
  4695. if ( info.invMass ) {
  4696. impulseDenominator += info.invMass + ( ( info.invInertiaTensor * info.position.Cross( collision.c.normal ) ).Cross( info.position ) * collision.c.normal );
  4697. }
  4698. impulse = (impulseNumerator / impulseDenominator) * collision.c.normal;
  4699. // apply impact to other entity
  4700. ent->ApplyImpulse( self, collision.c.id, collision.c.point, -impulse );
  4701. // callback to self to let the entity know about the impact
  4702. return self->Collide( collision, velocity );
  4703. }
  4704. /*
  4705. ================
  4706. idPhysics_AF::ApplyCollisions
  4707. ================
  4708. */
  4709. bool idPhysics_AF::ApplyCollisions( float timeStep ) {
  4710. int i;
  4711. for ( i = 0; i < collisions.Num(); i++ ) {
  4712. if ( CollisionImpulse( timeStep, collisions[i].body, collisions[i].trace ) ) {
  4713. return true;
  4714. }
  4715. }
  4716. return false;
  4717. }
  4718. /*
  4719. ================
  4720. idPhysics_AF::SetupCollisionForBody
  4721. ================
  4722. */
  4723. idEntity *idPhysics_AF::SetupCollisionForBody( idAFBody *body ) const {
  4724. int i;
  4725. idAFBody *b;
  4726. idEntity *passEntity;
  4727. passEntity = NULL;
  4728. if ( !selfCollision || !body->fl.selfCollision || af_skipSelfCollision.GetBool() ) {
  4729. // disable all bodies
  4730. for ( i = 0; i < bodies.Num(); i++ ) {
  4731. bodies[i]->clipModel->Disable();
  4732. }
  4733. // don't collide with world collision model if attached to the world
  4734. for ( i = 0; i < body->constraints.Num(); i++ ) {
  4735. if ( !body->constraints[i]->fl.noCollision ) {
  4736. continue;
  4737. }
  4738. // if this constraint attaches the body to the world
  4739. if ( body->constraints[i]->body2 == NULL ) {
  4740. // don't collide with the world collision model
  4741. passEntity = gameLocal.world;
  4742. }
  4743. }
  4744. } else {
  4745. // enable all bodies that have self collision
  4746. for ( i = 0; i < bodies.Num(); i++ ) {
  4747. if ( bodies[i]->fl.selfCollision ) {
  4748. bodies[i]->clipModel->Enable();
  4749. } else {
  4750. bodies[i]->clipModel->Disable();
  4751. }
  4752. }
  4753. // don't let the body collide with itself
  4754. body->clipModel->Disable();
  4755. // disable any bodies attached with constraints
  4756. for ( i = 0; i < body->constraints.Num(); i++ ) {
  4757. if ( !body->constraints[i]->fl.noCollision ) {
  4758. continue;
  4759. }
  4760. // if this constraint attaches the body to the world
  4761. if ( body->constraints[i]->body2 == NULL ) {
  4762. // don't collide with the world collision model
  4763. passEntity = gameLocal.world;
  4764. } else {
  4765. if ( body->constraints[i]->body1 == body ) {
  4766. b = body->constraints[i]->body2;
  4767. } else if ( body->constraints[i]->body2 == body ) {
  4768. b = body->constraints[i]->body1;
  4769. } else {
  4770. continue;
  4771. }
  4772. // don't collide with this body
  4773. b->clipModel->Disable();
  4774. }
  4775. }
  4776. }
  4777. return passEntity;
  4778. }
  4779. /*
  4780. ================
  4781. idPhysics_AF::CheckForCollisions
  4782. check for collisions between the current and next state
  4783. if there is a collision the next state is set to the state at the moment of impact
  4784. assumes all bodies are linked for collision detection and relinks all bodies after moving them
  4785. ================
  4786. */
  4787. void idPhysics_AF::CheckForCollisions( float timeStep ) {
  4788. // #define TEST_COLLISION_DETECTION
  4789. int i, index;
  4790. idAFBody *body;
  4791. idMat3 axis;
  4792. idRotation rotation;
  4793. trace_t collision;
  4794. idEntity *passEntity;
  4795. // clear list with collisions
  4796. collisions.SetNum( 0 );
  4797. if ( !enableCollision ) {
  4798. return;
  4799. }
  4800. for ( i = 0; i < bodies.Num(); i++ ) {
  4801. body = bodies[i];
  4802. if ( body->clipMask != 0 ) {
  4803. passEntity = SetupCollisionForBody( body );
  4804. #ifdef TEST_COLLISION_DETECTION
  4805. bool startsolid = false;
  4806. if ( gameLocal.clip.Contents( body->current->worldOrigin, body->clipModel,
  4807. body->current->worldAxis, body->clipMask, passEntity ) ) {
  4808. startsolid = true;
  4809. }
  4810. #endif
  4811. TransposeMultiply( body->current->worldAxis, body->next->worldAxis, axis );
  4812. rotation = axis.ToRotation();
  4813. rotation.SetOrigin( body->current->worldOrigin );
  4814. // if there was a collision
  4815. if ( gameLocal.clip.Motion( collision, body->current->worldOrigin, body->next->worldOrigin, rotation,
  4816. body->clipModel, body->current->worldAxis, body->clipMask, passEntity ) ) {
  4817. // set the next state to the state at the moment of impact
  4818. body->next->worldOrigin = collision.endpos;
  4819. body->next->worldAxis = collision.endAxis;
  4820. // add collision to the list
  4821. index = collisions.Num();
  4822. collisions.SetNum( index + 1 );
  4823. collisions[index].trace = collision;
  4824. collisions[index].body = body;
  4825. }
  4826. #ifdef TEST_COLLISION_DETECTION
  4827. if ( gameLocal.clip.Contents( body->next->worldOrigin, body->clipModel,
  4828. body->next->worldAxis, body->clipMask, passEntity ) ) {
  4829. if ( !startsolid ) {
  4830. int bah = 1;
  4831. }
  4832. }
  4833. #endif
  4834. }
  4835. body->clipModel->Link( gameLocal.clip, self, body->clipModel->GetId(), body->next->worldOrigin, body->next->worldAxis );
  4836. }
  4837. }
  4838. /*
  4839. ================
  4840. idPhysics_AF::EvaluateContacts
  4841. ================
  4842. */
  4843. bool idPhysics_AF::EvaluateContacts() {
  4844. int i, j, k, numContacts, numBodyContacts;
  4845. idAFBody *body;
  4846. contactInfo_t contactInfo[10];
  4847. idEntity *passEntity;
  4848. idVecX dir( 6, VECX_ALLOCA( 6 ) );
  4849. // evaluate bodies
  4850. EvaluateBodies( current.lastTimeStep );
  4851. // remove all existing contacts
  4852. ClearContacts();
  4853. contactBodies.SetNum( 0 );
  4854. if ( !enableCollision ) {
  4855. return false;
  4856. }
  4857. // find all the contacts
  4858. for ( i = 0; i < bodies.Num(); i++ ) {
  4859. body = bodies[i];
  4860. if ( body->clipMask == 0 ) {
  4861. continue;
  4862. }
  4863. passEntity = SetupCollisionForBody( body );
  4864. body->InverseWorldSpatialInertiaMultiply( dir, body->current->externalForce.ToFloatPtr() );
  4865. dir.SubVec6(0) = body->current->spatialVelocity + current.lastTimeStep * dir.SubVec6(0);
  4866. dir.SubVec3(0).Normalize();
  4867. dir.SubVec3(1).Normalize();
  4868. numContacts = gameLocal.clip.Contacts( contactInfo, 10, body->current->worldOrigin, dir.SubVec6(0), 2.0f, //CONTACT_EPSILON,
  4869. body->clipModel, body->current->worldAxis, body->clipMask, passEntity );
  4870. #if 1
  4871. // merge nearby contacts between the same bodies
  4872. // and assure there are at most three planar contacts between any pair of bodies
  4873. for ( j = 0; j < numContacts; j++ ) {
  4874. numBodyContacts = 0;
  4875. for ( k = 0; k < contacts.Num(); k++ ) {
  4876. if ( contacts[k].entityNum == contactInfo[j].entityNum ) {
  4877. if ( ( contacts[k].id == i && contactInfo[j].id == contactBodies[k] ) ||
  4878. ( contactBodies[k] == i && contacts[k].id == contactInfo[j].id ) ) {
  4879. if ( ( contacts[k].point - contactInfo[j].point ).LengthSqr() < Square( 2.0f ) ) {
  4880. break;
  4881. }
  4882. if ( idMath::Fabs( contacts[k].normal * contactInfo[j].normal ) > 0.9f ) {
  4883. numBodyContacts++;
  4884. }
  4885. }
  4886. }
  4887. }
  4888. if ( k >= contacts.Num() && numBodyContacts < 3 ) {
  4889. contacts.Append( contactInfo[j] );
  4890. contactBodies.Append( i );
  4891. }
  4892. }
  4893. #else
  4894. for ( j = 0; j < numContacts; j++ ) {
  4895. contacts.Append( contactInfo[j] );
  4896. contactBodies.Append( i );
  4897. }
  4898. #endif
  4899. }
  4900. AddContactEntitiesForContacts();
  4901. return ( contacts.Num() != 0 );
  4902. }
  4903. /*
  4904. ================
  4905. idPhysics_AF::SetupContactConstraints
  4906. ================
  4907. */
  4908. void idPhysics_AF::SetupContactConstraints() {
  4909. int i;
  4910. // make sure enough contact constraints are allocated
  4911. contactConstraints.AssureSizeAlloc( contacts.Num(), idListNewElement<idAFConstraint_Contact> );
  4912. contactConstraints.SetNum( contacts.Num() );
  4913. // setup contact constraints
  4914. for ( i = 0; i < contacts.Num(); i++ ) {
  4915. // add contact constraint
  4916. contactConstraints[i]->physics = this;
  4917. if ( contacts[i].entityNum == self->entityNumber ) {
  4918. contactConstraints[i]->Setup( bodies[contactBodies[i]], bodies[ contacts[i].id ], contacts[i] );
  4919. }
  4920. else {
  4921. contactConstraints[i]->Setup( bodies[contactBodies[i]], NULL, contacts[i] );
  4922. }
  4923. }
  4924. }
  4925. /*
  4926. ================
  4927. idPhysics_AF::ApplyContactForces
  4928. ================
  4929. */
  4930. void idPhysics_AF::ApplyContactForces() {
  4931. #if 0
  4932. int i;
  4933. idEntity *ent;
  4934. idVec3 force;
  4935. for ( i = 0; i < contactConstraints.Num(); i++ ) {
  4936. if ( contactConstraints[i]->body2 != NULL ) {
  4937. continue;
  4938. }
  4939. const contactInfo_t &contact = contactConstraints[i]->GetContact();
  4940. ent = gameLocal.entities[contact.entityNum];
  4941. if ( !ent ) {
  4942. continue;
  4943. }
  4944. force.Zero();
  4945. ent->AddForce( self, contact.id, contact.point, force );
  4946. }
  4947. #endif
  4948. }
  4949. /*
  4950. ================
  4951. idPhysics_AF::ClearExternalForce
  4952. ================
  4953. */
  4954. void idPhysics_AF::ClearExternalForce() {
  4955. int i;
  4956. idAFBody *body;
  4957. for ( i = 0; i < bodies.Num(); i++ ) {
  4958. body = bodies[i];
  4959. // clear external force
  4960. body->current->externalForce.Zero();
  4961. body->next->externalForce.Zero();
  4962. }
  4963. }
  4964. /*
  4965. ================
  4966. idPhysics_AF::AddGravity
  4967. ================
  4968. */
  4969. void idPhysics_AF::AddGravity() {
  4970. int i;
  4971. idAFBody *body;
  4972. for ( i = 0; i < bodies.Num(); i++ ) {
  4973. body = bodies[i];
  4974. // add gravitational force
  4975. body->current->externalForce.SubVec3( 0 ) += body->mass * gravityVector;
  4976. }
  4977. }
  4978. /*
  4979. ================
  4980. idPhysics_AF::SwapStates
  4981. ================
  4982. */
  4983. void idPhysics_AF::SwapStates() {
  4984. int i;
  4985. idAFBody *body;
  4986. AFBodyPState_t *swap;
  4987. for ( i = 0; i < bodies.Num(); i++ ) {
  4988. body = bodies[i];
  4989. // swap the current and next state for next simulation step
  4990. swap = body->current;
  4991. body->current = body->next;
  4992. body->next = swap;
  4993. }
  4994. }
  4995. /*
  4996. ================
  4997. idPhysics_AF::UpdateClipModels
  4998. ================
  4999. */
  5000. void idPhysics_AF::UpdateClipModels() {
  5001. int i;
  5002. idAFBody *body;
  5003. for ( i = 0; i < bodies.Num(); i++ ) {
  5004. body = bodies[i];
  5005. body->clipModel->Link( gameLocal.clip, self, body->clipModel->GetId(), body->current->worldOrigin, body->current->worldAxis );
  5006. }
  5007. }
  5008. /*
  5009. ================
  5010. idPhysics_AF::SetSuspendSpeed
  5011. ================
  5012. */
  5013. void idPhysics_AF::SetSuspendSpeed( const idVec2 &velocity, const idVec2 &acceleration ) {
  5014. this->suspendVelocity = velocity;
  5015. this->suspendAcceleration = acceleration;
  5016. }
  5017. /*
  5018. ================
  5019. idPhysics_AF::SetSuspendTime
  5020. ================
  5021. */
  5022. void idPhysics_AF::SetSuspendTime( const float minTime, const float maxTime ) {
  5023. this->minMoveTime = minTime;
  5024. this->maxMoveTime = maxTime;
  5025. }
  5026. /*
  5027. ================
  5028. idPhysics_AF::SetSuspendTolerance
  5029. ================
  5030. */
  5031. void idPhysics_AF::SetSuspendTolerance( const float noMoveTime, const float noMoveTranslation, const float noMoveRotation ) {
  5032. this->noMoveTime = noMoveTime;
  5033. this->noMoveTranslation = noMoveTranslation;
  5034. this->noMoveRotation = noMoveRotation;
  5035. }
  5036. /*
  5037. ================
  5038. idPhysics_AF::SetTimeScaleRamp
  5039. ================
  5040. */
  5041. void idPhysics_AF::SetTimeScaleRamp( const float start, const float end ) {
  5042. timeScaleRampStart = start;
  5043. timeScaleRampEnd = end;
  5044. }
  5045. /*
  5046. ================
  5047. idPhysics_AF::SetJointFrictionDent
  5048. ================
  5049. */
  5050. void idPhysics_AF::SetJointFrictionDent( const float dent, const float start, const float end ) {
  5051. jointFrictionDent = dent;
  5052. jointFrictionDentStart = start;
  5053. jointFrictionDentEnd = end;
  5054. }
  5055. /*
  5056. ================
  5057. idPhysics_AF::GetJointFrictionScale
  5058. ================
  5059. */
  5060. float idPhysics_AF::GetJointFrictionScale() const {
  5061. if ( jointFrictionDentScale > 0.0f ) {
  5062. return jointFrictionDentScale;
  5063. } else if ( jointFrictionScale > 0.0f ) {
  5064. return jointFrictionScale;
  5065. } else if ( af_jointFrictionScale.GetFloat() > 0.0f ) {
  5066. return af_jointFrictionScale.GetFloat();
  5067. }
  5068. return 1.0f;
  5069. }
  5070. /*
  5071. ================
  5072. idPhysics_AF::SetContactFrictionDent
  5073. ================
  5074. */
  5075. void idPhysics_AF::SetContactFrictionDent( const float dent, const float start, const float end ) {
  5076. contactFrictionDent = dent;
  5077. contactFrictionDentStart = start;
  5078. contactFrictionDentEnd = end;
  5079. }
  5080. /*
  5081. ================
  5082. idPhysics_AF::GetContactFrictionScale
  5083. ================
  5084. */
  5085. float idPhysics_AF::GetContactFrictionScale() const {
  5086. if ( contactFrictionDentScale > 0.0f ) {
  5087. return contactFrictionDentScale;
  5088. } else if ( contactFrictionScale > 0.0f ) {
  5089. return contactFrictionScale;
  5090. } else if ( af_contactFrictionScale.GetFloat() > 0.0f ) {
  5091. return af_contactFrictionScale.GetFloat();
  5092. }
  5093. return 1.0f;
  5094. }
  5095. /*
  5096. ================
  5097. idPhysics_AF::TestIfAtRest
  5098. ================
  5099. */
  5100. bool idPhysics_AF::TestIfAtRest( float timeStep ) {
  5101. int i;
  5102. float translationSqr, maxTranslationSqr, rotation, maxRotation;
  5103. idAFBody *body;
  5104. if ( current.atRest >= 0 ) {
  5105. return true;
  5106. }
  5107. current.activateTime += timeStep;
  5108. // if the simulation should never be suspended before a certaint amount of time passed
  5109. if ( minMoveTime > 0.0f && current.activateTime < minMoveTime ) {
  5110. return false;
  5111. }
  5112. // if the simulation should always be suspended after a certain amount time passed
  5113. if ( maxMoveTime > 0.0f && current.activateTime > maxMoveTime ) {
  5114. return true;
  5115. }
  5116. // test if all bodies hardly moved over a period of time
  5117. if ( current.noMoveTime == 0.0f ) {
  5118. for ( i = 0; i < bodies.Num(); i++ ) {
  5119. body = bodies[i];
  5120. body->atRestOrigin = body->current->worldOrigin;
  5121. body->atRestAxis = body->current->worldAxis;
  5122. }
  5123. current.noMoveTime += timeStep;
  5124. }
  5125. else if ( current.noMoveTime > noMoveTime ) {
  5126. current.noMoveTime = 0.0f;
  5127. maxTranslationSqr = 0.0f;
  5128. maxRotation = 0.0f;
  5129. for ( i = 0; i < bodies.Num(); i++ ) {
  5130. body = bodies[i];
  5131. translationSqr = ( body->current->worldOrigin - body->atRestOrigin ).LengthSqr();
  5132. if ( translationSqr > maxTranslationSqr ) {
  5133. maxTranslationSqr = translationSqr;
  5134. }
  5135. rotation = ( body->atRestAxis.Transpose() * body->current->worldAxis ).ToRotation().GetAngle();
  5136. if ( rotation > maxRotation ) {
  5137. maxRotation = rotation;
  5138. }
  5139. }
  5140. if ( maxTranslationSqr < Square( noMoveTranslation ) && maxRotation < noMoveRotation ) {
  5141. // hardly moved over a period of time so the articulated figure may come to rest
  5142. return true;
  5143. }
  5144. } else {
  5145. current.noMoveTime += timeStep;
  5146. }
  5147. // test if the velocity or acceleration of any body is still too large to come to rest
  5148. for ( i = 0; i < bodies.Num(); i++ ) {
  5149. body = bodies[i];
  5150. if ( body->current->spatialVelocity.SubVec3(0).LengthSqr() > Square( suspendVelocity[0] ) ) {
  5151. return false;
  5152. }
  5153. if ( body->current->spatialVelocity.SubVec3(1).LengthSqr() > Square( suspendVelocity[1] ) ) {
  5154. return false;
  5155. }
  5156. if ( body->acceleration.SubVec3(0).LengthSqr() > Square( suspendAcceleration[0] ) ) {
  5157. return false;
  5158. }
  5159. if ( body->acceleration.SubVec3(1).LengthSqr() > Square( suspendAcceleration[1] ) ) {
  5160. return false;
  5161. }
  5162. }
  5163. // all bodies have a velocity and acceleration small enough to come to rest
  5164. return true;
  5165. }
  5166. /*
  5167. ================
  5168. idPhysics_AF::Rest
  5169. ================
  5170. */
  5171. void idPhysics_AF::Rest() {
  5172. int i;
  5173. current.atRest = gameLocal.time;
  5174. for ( i = 0; i < bodies.Num(); i++ ) {
  5175. bodies[i]->current->spatialVelocity.Zero();
  5176. bodies[i]->current->externalForce.Zero();
  5177. }
  5178. self->BecomeInactive( TH_PHYSICS );
  5179. }
  5180. /*
  5181. ================
  5182. idPhysics_AF::Activate
  5183. ================
  5184. */
  5185. void idPhysics_AF::Activate() {
  5186. // if the articulated figure was at rest
  5187. if ( current.atRest >= 0 ) {
  5188. // normally gravity is added at the end of a simulation frame
  5189. // if the figure was at rest add gravity here so it is applied this simulation frame
  5190. AddGravity();
  5191. // reset the active time for the max move time
  5192. current.activateTime = 0.0f;
  5193. }
  5194. current.atRest = -1;
  5195. current.noMoveTime = 0.0f;
  5196. self->BecomeActive( TH_PHYSICS );
  5197. }
  5198. /*
  5199. ================
  5200. idPhysics_AF::PutToRest
  5201. put to rest untill something collides with this physics object
  5202. ================
  5203. */
  5204. void idPhysics_AF::PutToRest() {
  5205. Rest();
  5206. }
  5207. /*
  5208. ================
  5209. idPhysics_AF::EnableImpact
  5210. ================
  5211. */
  5212. void idPhysics_AF::EnableImpact() {
  5213. noImpact = false;
  5214. }
  5215. /*
  5216. ================
  5217. idPhysics_AF::DisableImpact
  5218. ================
  5219. */
  5220. void idPhysics_AF::DisableImpact() {
  5221. noImpact = true;
  5222. }
  5223. /*
  5224. ================
  5225. idPhysics_AF::AddPushVelocity
  5226. ================
  5227. */
  5228. void idPhysics_AF::AddPushVelocity( const idVec6 &pushVelocity ) {
  5229. int i;
  5230. if ( pushVelocity != vec6_origin ) {
  5231. for ( i = 0; i < bodies.Num(); i++ ) {
  5232. bodies[i]->current->spatialVelocity += pushVelocity;
  5233. }
  5234. }
  5235. }
  5236. /*
  5237. ================
  5238. idPhysics_AF::SetClipModel
  5239. ================
  5240. */
  5241. void idPhysics_AF::SetClipModel( idClipModel *model, float density, int id, bool freeOld ) {
  5242. }
  5243. /*
  5244. ================
  5245. idPhysics_AF::GetClipModel
  5246. ================
  5247. */
  5248. idClipModel *idPhysics_AF::GetClipModel( int id ) const {
  5249. if ( id >= 0 && id < bodies.Num() ) {
  5250. return bodies[id]->GetClipModel();
  5251. }
  5252. return NULL;
  5253. }
  5254. /*
  5255. ================
  5256. idPhysics_AF::GetNumClipModels
  5257. ================
  5258. */
  5259. int idPhysics_AF::GetNumClipModels() const {
  5260. return bodies.Num();
  5261. }
  5262. /*
  5263. ================
  5264. idPhysics_AF::SetMass
  5265. ================
  5266. */
  5267. void idPhysics_AF::SetMass( float mass, int id ) {
  5268. if ( id >= 0 && id < bodies.Num() ) {
  5269. }
  5270. else {
  5271. forceTotalMass = mass;
  5272. }
  5273. SetChanged();
  5274. }
  5275. /*
  5276. ================
  5277. idPhysics_AF::GetMass
  5278. ================
  5279. */
  5280. float idPhysics_AF::GetMass( int id ) const {
  5281. if ( id >= 0 && id < bodies.Num() ) {
  5282. return bodies[id]->mass;
  5283. }
  5284. return totalMass;
  5285. }
  5286. /*
  5287. ================
  5288. idPhysics_AF::SetContents
  5289. ================
  5290. */
  5291. void idPhysics_AF::SetContents( int contents, int id ) {
  5292. int i;
  5293. if ( id >= 0 && id < bodies.Num() ) {
  5294. bodies[id]->GetClipModel()->SetContents( contents );
  5295. }
  5296. else {
  5297. for ( i = 0; i < bodies.Num(); i++ ) {
  5298. bodies[i]->GetClipModel()->SetContents( contents );
  5299. }
  5300. }
  5301. }
  5302. /*
  5303. ================
  5304. idPhysics_AF::GetContents
  5305. ================
  5306. */
  5307. int idPhysics_AF::GetContents( int id ) const {
  5308. int i, contents;
  5309. if ( id >= 0 && id < bodies.Num() ) {
  5310. return bodies[id]->GetClipModel()->GetContents();
  5311. }
  5312. else {
  5313. contents = 0;
  5314. for ( i = 0; i < bodies.Num(); i++ ) {
  5315. contents |= bodies[i]->GetClipModel()->GetContents();
  5316. }
  5317. return contents;
  5318. }
  5319. }
  5320. /*
  5321. ================
  5322. idPhysics_AF::GetBounds
  5323. ================
  5324. */
  5325. const idBounds &idPhysics_AF::GetBounds( int id ) const {
  5326. int i;
  5327. static idBounds relBounds;
  5328. if ( id >= 0 && id < bodies.Num() ) {
  5329. return bodies[id]->GetClipModel()->GetBounds();
  5330. }
  5331. else if ( !bodies.Num() ) {
  5332. relBounds.Zero();
  5333. return relBounds;
  5334. }
  5335. else {
  5336. relBounds = bodies[0]->GetClipModel()->GetBounds();
  5337. for ( i = 1; i < bodies.Num(); i++ ) {
  5338. idBounds bounds;
  5339. idVec3 origin = ( bodies[i]->GetWorldOrigin() - bodies[0]->GetWorldOrigin() ) * bodies[0]->GetWorldAxis().Transpose();
  5340. idMat3 axis = bodies[i]->GetWorldAxis() * bodies[0]->GetWorldAxis().Transpose();
  5341. bounds.FromTransformedBounds( bodies[i]->GetClipModel()->GetBounds(), origin, axis );
  5342. relBounds += bounds;
  5343. }
  5344. return relBounds;
  5345. }
  5346. }
  5347. /*
  5348. ================
  5349. idPhysics_AF::GetAbsBounds
  5350. ================
  5351. */
  5352. const idBounds &idPhysics_AF::GetAbsBounds( int id ) const {
  5353. int i;
  5354. static idBounds absBounds;
  5355. if ( id >= 0 && id < bodies.Num() ) {
  5356. return bodies[id]->GetClipModel()->GetAbsBounds();
  5357. }
  5358. else if ( !bodies.Num() ) {
  5359. absBounds.Zero();
  5360. return absBounds;
  5361. }
  5362. else {
  5363. absBounds = bodies[0]->GetClipModel()->GetAbsBounds();
  5364. for ( i = 1; i < bodies.Num(); i++ ) {
  5365. absBounds += bodies[i]->GetClipModel()->GetAbsBounds();
  5366. }
  5367. return absBounds;
  5368. }
  5369. }
  5370. /*
  5371. ================
  5372. idPhysics_AF::Evaluate
  5373. ================
  5374. */
  5375. bool idPhysics_AF::Evaluate( int timeStepMSec, int endTimeMSec ) {
  5376. float timeStep;
  5377. if ( timeScaleRampStart < MS2SEC( endTimeMSec ) && timeScaleRampEnd > MS2SEC( endTimeMSec ) ) {
  5378. timeStep = MS2SEC( timeStepMSec ) * ( MS2SEC( endTimeMSec ) - timeScaleRampStart ) / ( timeScaleRampEnd - timeScaleRampStart );
  5379. } else if ( af_timeScale.GetFloat() != 1.0f ) {
  5380. timeStep = MS2SEC( timeStepMSec ) * af_timeScale.GetFloat();
  5381. } else {
  5382. timeStep = MS2SEC( timeStepMSec ) * timeScale;
  5383. }
  5384. current.lastTimeStep = timeStep;
  5385. // if the articulated figure changed
  5386. if ( changedAF || ( linearTime != af_useLinearTime.GetBool() ) ) {
  5387. BuildTrees();
  5388. changedAF = false;
  5389. linearTime = af_useLinearTime.GetBool();
  5390. }
  5391. // get the new master position
  5392. if ( masterBody ) {
  5393. idVec3 masterOrigin;
  5394. idMat3 masterAxis;
  5395. self->GetMasterPosition( masterOrigin, masterAxis );
  5396. if ( current.atRest >= 0 && ( masterBody->current->worldOrigin != masterOrigin || masterBody->current->worldAxis != masterAxis ) ) {
  5397. Activate();
  5398. }
  5399. masterBody->current->worldOrigin = masterOrigin;
  5400. masterBody->current->worldAxis = masterAxis;
  5401. }
  5402. // if the simulation is suspended because the figure is at rest
  5403. if ( current.atRest >= 0 || timeStep <= 0.0f ) {
  5404. DebugDraw();
  5405. return false;
  5406. }
  5407. // move the af velocity into the frame of a pusher
  5408. AddPushVelocity( -current.pushVelocity );
  5409. #ifdef AF_TIMINGS
  5410. timer_total.Start();
  5411. #endif
  5412. #ifdef AF_TIMINGS
  5413. timer_collision.Start();
  5414. #endif
  5415. // evaluate contacts
  5416. EvaluateContacts();
  5417. // setup contact constraints
  5418. SetupContactConstraints();
  5419. #ifdef AF_TIMINGS
  5420. timer_collision.Stop();
  5421. #endif
  5422. // evaluate constraint equations
  5423. EvaluateConstraints( timeStep );
  5424. // apply friction
  5425. ApplyFriction( timeStep, endTimeMSec );
  5426. // add frame constraints
  5427. AddFrameConstraints();
  5428. #ifdef AF_TIMINGS
  5429. int i, numPrimary = 0, numAuxiliary = 0;
  5430. for ( i = 0; i < primaryConstraints.Num(); i++ ) {
  5431. numPrimary += primaryConstraints[i]->J1.GetNumRows();
  5432. }
  5433. for ( i = 0; i < auxiliaryConstraints.Num(); i++ ) {
  5434. numAuxiliary += auxiliaryConstraints[i]->J1.GetNumRows();
  5435. }
  5436. timer_pc.Start();
  5437. #endif
  5438. // factor matrices for primary constraints
  5439. PrimaryFactor();
  5440. // calculate forces on bodies after applying primary constraints
  5441. PrimaryForces( timeStep );
  5442. #ifdef AF_TIMINGS
  5443. timer_pc.Stop();
  5444. timer_ac.Start();
  5445. #endif
  5446. // calculate and apply auxiliary constraint forces
  5447. AuxiliaryForces( timeStep );
  5448. #ifdef AF_TIMINGS
  5449. timer_ac.Stop();
  5450. #endif
  5451. // evolve current state to next state
  5452. Evolve( timeStep );
  5453. // debug graphics
  5454. DebugDraw();
  5455. // clear external forces on all bodies
  5456. ClearExternalForce();
  5457. // apply contact force to other entities
  5458. ApplyContactForces();
  5459. // remove all frame constraints
  5460. RemoveFrameConstraints();
  5461. #ifdef AF_TIMINGS
  5462. timer_collision.Start();
  5463. #endif
  5464. // check for collisions between current and next state
  5465. CheckForCollisions( timeStep );
  5466. #ifdef AF_TIMINGS
  5467. timer_collision.Stop();
  5468. #endif
  5469. // swap the current and next state
  5470. SwapStates();
  5471. // make sure all clip models are disabled in case they were enabled for self collision
  5472. if ( selfCollision && !af_skipSelfCollision.GetBool() ) {
  5473. DisableClip();
  5474. }
  5475. // apply collision impulses
  5476. if ( ApplyCollisions( timeStep ) ) {
  5477. current.atRest = gameLocal.time;
  5478. comeToRest = true;
  5479. }
  5480. // test if the simulation can be suspended because the whole figure is at rest
  5481. if ( comeToRest && TestIfAtRest( timeStep ) ) {
  5482. Rest();
  5483. } else {
  5484. ActivateContactEntities();
  5485. }
  5486. // add gravitational force
  5487. AddGravity();
  5488. // move the af velocity back into the world frame
  5489. AddPushVelocity( current.pushVelocity );
  5490. current.pushVelocity.Zero();
  5491. if ( IsOutsideWorld() ) {
  5492. gameLocal.Warning( "articulated figure moved outside world bounds for entity '%s' type '%s' at (%s)",
  5493. self->name.c_str(), self->GetType()->classname, bodies[0]->current->worldOrigin.ToString(0) );
  5494. Rest();
  5495. }
  5496. #ifdef AF_TIMINGS
  5497. timer_total.Stop();
  5498. if ( af_showTimings.GetInteger() == 1 ) {
  5499. gameLocal.Printf( "%12s: t %1.4f pc %2d, %1.4f ac %2d %1.4f lcp %1.4f cd %1.4f\n",
  5500. self->name.c_str(),
  5501. timer_total.Milliseconds(),
  5502. numPrimary, timer_pc.Milliseconds(),
  5503. numAuxiliary, timer_ac.Milliseconds() - timer_lcp.Milliseconds(),
  5504. timer_lcp.Milliseconds(), timer_collision.Milliseconds() );
  5505. }
  5506. else if ( af_showTimings.GetInteger() == 2 ) {
  5507. numArticulatedFigures++;
  5508. if ( endTimeMSec > lastTimerReset ) {
  5509. gameLocal.Printf( "af %d: t %1.4f pc %2d, %1.4f ac %2d %1.4f lcp %1.4f cd %1.4f\n",
  5510. numArticulatedFigures,
  5511. timer_total.Milliseconds(),
  5512. numPrimary, timer_pc.Milliseconds(),
  5513. numAuxiliary, timer_ac.Milliseconds() - timer_lcp.Milliseconds(),
  5514. timer_lcp.Milliseconds(), timer_collision.Milliseconds() );
  5515. }
  5516. }
  5517. if ( endTimeMSec > lastTimerReset ) {
  5518. lastTimerReset = endTimeMSec;
  5519. numArticulatedFigures = 0;
  5520. timer_total.Clear();
  5521. timer_pc.Clear();
  5522. timer_ac.Clear();
  5523. timer_collision.Clear();
  5524. timer_lcp.Clear();
  5525. }
  5526. #endif
  5527. return true;
  5528. }
  5529. /*
  5530. ================
  5531. idPhysics_AF::UpdateTime
  5532. ================
  5533. */
  5534. void idPhysics_AF::UpdateTime( int endTimeMSec ) {
  5535. }
  5536. /*
  5537. ================
  5538. idPhysics_AF::GetTime
  5539. ================
  5540. */
  5541. int idPhysics_AF::GetTime() const {
  5542. return gameLocal.time;
  5543. }
  5544. /*
  5545. ================
  5546. DrawTraceModelSilhouette
  5547. ================
  5548. */
  5549. void DrawTraceModelSilhouette( const idVec3 &projectionOrigin, const idClipModel *clipModel ) {
  5550. int i, numSilEdges;
  5551. int silEdges[MAX_TRACEMODEL_EDGES];
  5552. idVec3 v1, v2;
  5553. const idTraceModel *trm = clipModel->GetTraceModel();
  5554. const idVec3 &origin = clipModel->GetOrigin();
  5555. const idMat3 &axis = clipModel->GetAxis();
  5556. numSilEdges = trm->GetProjectionSilhouetteEdges( ( projectionOrigin - origin ) * axis.Transpose(), silEdges );
  5557. for ( i = 0; i < numSilEdges; i++ ) {
  5558. v1 = trm->verts[ trm->edges[ abs(silEdges[i]) ].v[ INT32_SIGNBITSET( silEdges[i] ) ] ];
  5559. v2 = trm->verts[ trm->edges[ abs(silEdges[i]) ].v[ INT32_SIGNBITNOTSET( silEdges[i] ) ] ];
  5560. gameRenderWorld->DebugArrow( colorRed, origin + v1 * axis, origin + v2 * axis, 1 );
  5561. }
  5562. }
  5563. /*
  5564. ================
  5565. idPhysics_AF::DebugDraw
  5566. ================
  5567. */
  5568. void idPhysics_AF::DebugDraw() {
  5569. int i;
  5570. idAFBody *body, *highlightBody = NULL, *constrainedBody1 = NULL, *constrainedBody2 = NULL;
  5571. idAFConstraint *constraint;
  5572. idVec3 center;
  5573. idMat3 axis;
  5574. if ( af_highlightConstraint.GetString()[0] ) {
  5575. constraint = GetConstraint( af_highlightConstraint.GetString() );
  5576. if ( constraint ) {
  5577. constraint->GetCenter( center );
  5578. axis = gameLocal.GetLocalPlayer()->viewAngles.ToMat3();
  5579. gameRenderWorld->DebugCone( colorYellow, center, (axis[2] - axis[1]) * 4.0f, 0.0f, 1.0f, 0 );
  5580. if ( af_showConstrainedBodies.GetBool() ) {
  5581. cvarSystem->SetCVarString( "cm_drawColor", colorCyan.ToString( 0 ) );
  5582. constrainedBody1 = constraint->body1;
  5583. if ( constrainedBody1 ) {
  5584. collisionModelManager->DrawModel( constrainedBody1->clipModel->Handle(), constrainedBody1->clipModel->GetOrigin(),
  5585. constrainedBody1->clipModel->GetAxis(), vec3_origin, 0.0f );
  5586. }
  5587. cvarSystem->SetCVarString( "cm_drawColor", colorBlue.ToString( 0 ) );
  5588. constrainedBody2 = constraint->body2;
  5589. if ( constrainedBody2 ) {
  5590. collisionModelManager->DrawModel( constrainedBody2->clipModel->Handle(), constrainedBody2->clipModel->GetOrigin(),
  5591. constrainedBody2->clipModel->GetAxis(), vec3_origin, 0.0f );
  5592. }
  5593. cvarSystem->SetCVarString( "cm_drawColor", colorRed.ToString( 0 ) );
  5594. }
  5595. }
  5596. }
  5597. if ( af_highlightBody.GetString()[0] ) {
  5598. highlightBody = GetBody( af_highlightBody.GetString() );
  5599. if ( highlightBody ) {
  5600. cvarSystem->SetCVarString( "cm_drawColor", colorYellow.ToString( 0 ) );
  5601. collisionModelManager->DrawModel( highlightBody->clipModel->Handle(), highlightBody->clipModel->GetOrigin(),
  5602. highlightBody->clipModel->GetAxis(), vec3_origin, 0.0f );
  5603. cvarSystem->SetCVarString( "cm_drawColor", colorRed.ToString( 0 ) );
  5604. }
  5605. }
  5606. if ( af_showBodies.GetBool() ) {
  5607. for ( i = 0; i < bodies.Num(); i++ ) {
  5608. body = bodies[i];
  5609. if ( body == constrainedBody1 || body == constrainedBody2 ) {
  5610. continue;
  5611. }
  5612. if ( body == highlightBody ) {
  5613. continue;
  5614. }
  5615. collisionModelManager->DrawModel( body->clipModel->Handle(), body->clipModel->GetOrigin(),
  5616. body->clipModel->GetAxis(), vec3_origin, 0.0f );
  5617. //DrawTraceModelSilhouette( gameLocal.GetLocalPlayer()->GetEyePosition(), body->clipModel );
  5618. }
  5619. }
  5620. if ( af_showBodyNames.GetBool() ) {
  5621. for ( i = 0; i < bodies.Num(); i++ ) {
  5622. body = bodies[i];
  5623. gameRenderWorld->DrawText( body->GetName().c_str(), body->GetWorldOrigin(), 0.08f, colorCyan, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1 );
  5624. }
  5625. }
  5626. if ( af_showMass.GetBool() ) {
  5627. for ( i = 0; i < bodies.Num(); i++ ) {
  5628. body = bodies[i];
  5629. gameRenderWorld->DrawText( va( "\n%1.2f", 1.0f / body->GetInverseMass() ), body->GetWorldOrigin(), 0.08f, colorCyan, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1 );
  5630. }
  5631. }
  5632. if ( af_showTotalMass.GetBool() ) {
  5633. axis = gameLocal.GetLocalPlayer()->viewAngles.ToMat3();
  5634. gameRenderWorld->DrawText( va( "\n%1.2f", totalMass ), bodies[0]->GetWorldOrigin() + axis[2] * 8.0f, 0.15f, colorCyan, axis, 1 );
  5635. }
  5636. if ( af_showInertia.GetBool() ) {
  5637. for ( i = 0; i < bodies.Num(); i++ ) {
  5638. body = bodies[i];
  5639. idMat3 &I = body->inertiaTensor;
  5640. gameRenderWorld->DrawText( va( "\n\n\n( %.1f %.1f %.1f )\n( %.1f %.1f %.1f )\n( %.1f %.1f %.1f )",
  5641. I[0].x, I[0].y, I[0].z,
  5642. I[1].x, I[1].y, I[1].z,
  5643. I[2].x, I[2].y, I[2].z ),
  5644. body->GetWorldOrigin(), 0.05f, colorCyan, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1 );
  5645. }
  5646. }
  5647. if ( af_showVelocity.GetBool() ) {
  5648. for ( i = 0; i < bodies.Num(); i++ ) {
  5649. DrawVelocity( bodies[i]->clipModel->GetId(), 0.1f, 4.0f );
  5650. }
  5651. }
  5652. if ( af_showConstraints.GetBool() ) {
  5653. for ( i = 0; i < primaryConstraints.Num(); i++ ) {
  5654. constraint = primaryConstraints[i];
  5655. constraint->DebugDraw();
  5656. }
  5657. if ( !af_showPrimaryOnly.GetBool() ) {
  5658. for ( i = 0; i < auxiliaryConstraints.Num(); i++ ) {
  5659. constraint = auxiliaryConstraints[i];
  5660. constraint->DebugDraw();
  5661. }
  5662. }
  5663. }
  5664. if ( af_showConstraintNames.GetBool() ) {
  5665. for ( i = 0; i < primaryConstraints.Num(); i++ ) {
  5666. constraint = primaryConstraints[i];
  5667. constraint->GetCenter( center );
  5668. gameRenderWorld->DrawText( constraint->GetName().c_str(), center, 0.08f, colorCyan, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1 );
  5669. }
  5670. if ( !af_showPrimaryOnly.GetBool() ) {
  5671. for ( i = 0; i < auxiliaryConstraints.Num(); i++ ) {
  5672. constraint = auxiliaryConstraints[i];
  5673. constraint->GetCenter( center );
  5674. gameRenderWorld->DrawText( constraint->GetName().c_str(), center, 0.08f, colorCyan, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1 );
  5675. }
  5676. }
  5677. }
  5678. if ( af_showTrees.GetBool() || ( af_showActive.GetBool() && current.atRest < 0 ) ) {
  5679. for ( i = 0; i < trees.Num(); i++ ) {
  5680. trees[i]->DebugDraw( idStr::ColorForIndex( i+3 ) );
  5681. }
  5682. }
  5683. }
  5684. /*
  5685. ================
  5686. idPhysics_AF::idPhysics_AF
  5687. ================
  5688. */
  5689. idPhysics_AF::idPhysics_AF() {
  5690. trees.Clear();
  5691. bodies.Clear();
  5692. constraints.Clear();
  5693. primaryConstraints.Clear();
  5694. auxiliaryConstraints.Clear();
  5695. frameConstraints.Clear();
  5696. contacts.Clear();
  5697. collisions.Clear();
  5698. changedAF = true;
  5699. masterBody = NULL;
  5700. lcp = idLCP::AllocSymmetric();
  5701. memset( &current, 0, sizeof( current ) );
  5702. current.atRest = -1;
  5703. current.lastTimeStep = 0.0f;
  5704. saved = current;
  5705. linearFriction = 0.005f;
  5706. angularFriction = 0.005f;
  5707. contactFriction = 0.8f;
  5708. bouncyness = 0.4f;
  5709. totalMass = 0.0f;
  5710. forceTotalMass = -1.0f;
  5711. suspendVelocity.Set( SUSPEND_LINEAR_VELOCITY, SUSPEND_ANGULAR_VELOCITY );
  5712. suspendAcceleration.Set( SUSPEND_LINEAR_ACCELERATION, SUSPEND_LINEAR_ACCELERATION );
  5713. noMoveTime = NO_MOVE_TIME;
  5714. noMoveTranslation = NO_MOVE_TRANSLATION_TOLERANCE;
  5715. noMoveRotation = NO_MOVE_ROTATION_TOLERANCE;
  5716. minMoveTime = MIN_MOVE_TIME;
  5717. maxMoveTime = MAX_MOVE_TIME;
  5718. impulseThreshold = IMPULSE_THRESHOLD;
  5719. timeScale = 1.0f;
  5720. timeScaleRampStart = 0.0f;
  5721. timeScaleRampEnd = 0.0f;
  5722. jointFrictionScale = 0.0f;
  5723. jointFrictionDent = 0.0f;
  5724. jointFrictionDentStart = 0.0f;
  5725. jointFrictionDentEnd = 0.0f;
  5726. jointFrictionDentScale = 0.0f;
  5727. contactFrictionScale = 0.0f;
  5728. contactFrictionDent = 0.0f;
  5729. contactFrictionDentStart = 0.0f;
  5730. contactFrictionDentEnd = 0.0f;
  5731. contactFrictionDentScale = 0.0f;
  5732. enableCollision = true;
  5733. selfCollision = true;
  5734. comeToRest = true;
  5735. linearTime = true;
  5736. noImpact = false;
  5737. worldConstraintsLocked = false;
  5738. forcePushable = false;
  5739. #ifdef AF_TIMINGS
  5740. lastTimerReset = 0;
  5741. #endif
  5742. }
  5743. /*
  5744. ================
  5745. idPhysics_AF::~idPhysics_AF
  5746. ================
  5747. */
  5748. idPhysics_AF::~idPhysics_AF() {
  5749. int i;
  5750. trees.DeleteContents( true );
  5751. for ( i = 0; i < bodies.Num(); i++ ) {
  5752. delete bodies[i];
  5753. }
  5754. for ( i = 0; i < constraints.Num(); i++ ) {
  5755. delete constraints[i];
  5756. }
  5757. contactConstraints.SetNum( contactConstraints.NumAllocated() );
  5758. for ( i = 0; i < contactConstraints.Num(); i++ ) {
  5759. delete contactConstraints[i];
  5760. }
  5761. delete lcp;
  5762. if ( masterBody ) {
  5763. delete masterBody;
  5764. }
  5765. }
  5766. /*
  5767. ================
  5768. idPhysics_AF_SavePState
  5769. ================
  5770. */
  5771. void idPhysics_AF_SavePState( idSaveGame *saveFile, const AFPState_t &state ) {
  5772. saveFile->WriteInt( state.atRest );
  5773. saveFile->WriteFloat( state.noMoveTime );
  5774. saveFile->WriteFloat( state.activateTime );
  5775. saveFile->WriteFloat( state.lastTimeStep );
  5776. saveFile->WriteVec6( state.pushVelocity );
  5777. }
  5778. /*
  5779. ================
  5780. idPhysics_AF_RestorePState
  5781. ================
  5782. */
  5783. void idPhysics_AF_RestorePState( idRestoreGame *saveFile, AFPState_t &state ) {
  5784. saveFile->ReadInt( state.atRest );
  5785. saveFile->ReadFloat( state.noMoveTime );
  5786. saveFile->ReadFloat( state.activateTime );
  5787. saveFile->ReadFloat( state.lastTimeStep );
  5788. saveFile->ReadVec6( state.pushVelocity );
  5789. }
  5790. /*
  5791. ================
  5792. idPhysics_AF::Save
  5793. ================
  5794. */
  5795. void idPhysics_AF::Save( idSaveGame *saveFile ) const {
  5796. int i;
  5797. // the articulated figure structure is handled by the owner
  5798. idPhysics_AF_SavePState( saveFile, current );
  5799. idPhysics_AF_SavePState( saveFile, saved );
  5800. saveFile->WriteInt( bodies.Num() );
  5801. for ( i = 0; i < bodies.Num(); i++ ) {
  5802. bodies[i]->Save( saveFile );
  5803. }
  5804. if ( masterBody ) {
  5805. saveFile->WriteBool( true );
  5806. masterBody->Save( saveFile );
  5807. } else {
  5808. saveFile->WriteBool( false );
  5809. }
  5810. saveFile->WriteInt( constraints.Num() );
  5811. for ( i = 0; i < constraints.Num(); i++ ) {
  5812. constraints[i]->Save( saveFile );
  5813. }
  5814. saveFile->WriteBool( changedAF );
  5815. saveFile->WriteFloat( linearFriction );
  5816. saveFile->WriteFloat( angularFriction );
  5817. saveFile->WriteFloat( contactFriction );
  5818. saveFile->WriteFloat( bouncyness );
  5819. saveFile->WriteFloat( totalMass );
  5820. saveFile->WriteFloat( forceTotalMass );
  5821. saveFile->WriteVec2( suspendVelocity );
  5822. saveFile->WriteVec2( suspendAcceleration );
  5823. saveFile->WriteFloat( noMoveTime );
  5824. saveFile->WriteFloat( noMoveTranslation );
  5825. saveFile->WriteFloat( noMoveRotation );
  5826. saveFile->WriteFloat( minMoveTime );
  5827. saveFile->WriteFloat( maxMoveTime );
  5828. saveFile->WriteFloat( impulseThreshold );
  5829. saveFile->WriteFloat( timeScale );
  5830. saveFile->WriteFloat( timeScaleRampStart );
  5831. saveFile->WriteFloat( timeScaleRampEnd );
  5832. saveFile->WriteFloat( jointFrictionScale );
  5833. saveFile->WriteFloat( jointFrictionDent );
  5834. saveFile->WriteFloat( jointFrictionDentStart );
  5835. saveFile->WriteFloat( jointFrictionDentEnd );
  5836. saveFile->WriteFloat( jointFrictionDentScale );
  5837. saveFile->WriteFloat( contactFrictionScale );
  5838. saveFile->WriteFloat( contactFrictionDent );
  5839. saveFile->WriteFloat( contactFrictionDentStart );
  5840. saveFile->WriteFloat( contactFrictionDentEnd );
  5841. saveFile->WriteFloat( contactFrictionDentScale );
  5842. saveFile->WriteBool( enableCollision );
  5843. saveFile->WriteBool( selfCollision );
  5844. saveFile->WriteBool( comeToRest );
  5845. saveFile->WriteBool( linearTime );
  5846. saveFile->WriteBool( noImpact );
  5847. saveFile->WriteBool( worldConstraintsLocked );
  5848. saveFile->WriteBool( forcePushable );
  5849. }
  5850. /*
  5851. ================
  5852. idPhysics_AF::Restore
  5853. ================
  5854. */
  5855. void idPhysics_AF::Restore( idRestoreGame *saveFile ) {
  5856. int i, num;
  5857. bool hasMaster;
  5858. // the articulated figure structure should have already been restored
  5859. idPhysics_AF_RestorePState( saveFile, current );
  5860. idPhysics_AF_RestorePState( saveFile, saved );
  5861. saveFile->ReadInt( num );
  5862. assert( num == bodies.Num() );
  5863. for ( i = 0; i < bodies.Num(); i++ ) {
  5864. bodies[i]->Restore( saveFile );
  5865. }
  5866. saveFile->ReadBool( hasMaster );
  5867. if ( hasMaster ) {
  5868. masterBody = new (TAG_PHYSICS_AF) idAFBody();
  5869. masterBody->Restore( saveFile );
  5870. }
  5871. saveFile->ReadInt( num );
  5872. assert( num == constraints.Num() );
  5873. for ( i = 0; i < constraints.Num(); i++ ) {
  5874. constraints[i]->Restore( saveFile );
  5875. }
  5876. saveFile->ReadBool( changedAF );
  5877. saveFile->ReadFloat( linearFriction );
  5878. saveFile->ReadFloat( angularFriction );
  5879. saveFile->ReadFloat( contactFriction );
  5880. saveFile->ReadFloat( bouncyness );
  5881. saveFile->ReadFloat( totalMass );
  5882. saveFile->ReadFloat( forceTotalMass );
  5883. saveFile->ReadVec2( suspendVelocity );
  5884. saveFile->ReadVec2( suspendAcceleration );
  5885. saveFile->ReadFloat( noMoveTime );
  5886. saveFile->ReadFloat( noMoveTranslation );
  5887. saveFile->ReadFloat( noMoveRotation );
  5888. saveFile->ReadFloat( minMoveTime );
  5889. saveFile->ReadFloat( maxMoveTime );
  5890. saveFile->ReadFloat( impulseThreshold );
  5891. saveFile->ReadFloat( timeScale );
  5892. saveFile->ReadFloat( timeScaleRampStart );
  5893. saveFile->ReadFloat( timeScaleRampEnd );
  5894. saveFile->ReadFloat( jointFrictionScale );
  5895. saveFile->ReadFloat( jointFrictionDent );
  5896. saveFile->ReadFloat( jointFrictionDentStart );
  5897. saveFile->ReadFloat( jointFrictionDentEnd );
  5898. saveFile->ReadFloat( jointFrictionDentScale );
  5899. saveFile->ReadFloat( contactFrictionScale );
  5900. saveFile->ReadFloat( contactFrictionDent );
  5901. saveFile->ReadFloat( contactFrictionDentStart );
  5902. saveFile->ReadFloat( contactFrictionDentEnd );
  5903. saveFile->ReadFloat( contactFrictionDentScale );
  5904. saveFile->ReadBool( enableCollision );
  5905. saveFile->ReadBool( selfCollision );
  5906. saveFile->ReadBool( comeToRest );
  5907. saveFile->ReadBool( linearTime );
  5908. saveFile->ReadBool( noImpact );
  5909. saveFile->ReadBool( worldConstraintsLocked );
  5910. saveFile->ReadBool( forcePushable );
  5911. changedAF = true;
  5912. UpdateClipModels();
  5913. }
  5914. /*
  5915. ================
  5916. idPhysics_AF::IsClosedLoop
  5917. ================
  5918. */
  5919. bool idPhysics_AF::IsClosedLoop( const idAFBody *body1, const idAFBody *body2 ) const {
  5920. const idAFBody *b1, *b2;
  5921. for ( b1 = body1; b1->parent; b1 = b1->parent ) {
  5922. }
  5923. for ( b2 = body2; b2->parent; b2 = b2->parent ) {
  5924. }
  5925. return ( b1 == b2 );
  5926. }
  5927. /*
  5928. ================
  5929. idPhysics_AF::BuildTrees
  5930. ================
  5931. */
  5932. void idPhysics_AF::BuildTrees() {
  5933. int i;
  5934. float scale;
  5935. idAFBody *b;
  5936. idAFConstraint *c;
  5937. idAFTree *tree;
  5938. primaryConstraints.Clear();
  5939. auxiliaryConstraints.Clear();
  5940. trees.DeleteContents( true );
  5941. totalMass = 0.0f;
  5942. for ( i = 0; i < bodies.Num(); i++ ) {
  5943. b = bodies[i];
  5944. b->parent = NULL;
  5945. b->primaryConstraint = NULL;
  5946. b->constraints.SetNum( 0 );
  5947. b->children.Clear();
  5948. b->tree = NULL;
  5949. totalMass += b->mass;
  5950. }
  5951. if ( forceTotalMass > 0.0f ) {
  5952. scale = forceTotalMass / totalMass;
  5953. for ( i = 0; i < bodies.Num(); i++ ) {
  5954. b = bodies[i];
  5955. b->mass *= scale;
  5956. b->invMass = 1.0f / b->mass;
  5957. b->inertiaTensor *= scale;
  5958. b->inverseInertiaTensor = b->inertiaTensor.Inverse();
  5959. }
  5960. totalMass = forceTotalMass;
  5961. }
  5962. if ( af_useLinearTime.GetBool() ) {
  5963. for ( i = 0; i < constraints.Num(); i++ ) {
  5964. c = constraints[i];
  5965. c->body1->constraints.Append( c );
  5966. if ( c->body2 ) {
  5967. c->body2->constraints.Append( c );
  5968. }
  5969. // only bilateral constraints between two non-world bodies that do not
  5970. // create loops can be used as primary constraints
  5971. if ( !c->body1->primaryConstraint && c->fl.allowPrimary && c->body2 != NULL && !IsClosedLoop( c->body1, c->body2 ) ) {
  5972. c->body1->primaryConstraint = c;
  5973. c->body1->parent = c->body2;
  5974. c->body2->children.Append( c->body1 );
  5975. c->fl.isPrimary = true;
  5976. c->firstIndex = 0;
  5977. primaryConstraints.Append( c );
  5978. } else {
  5979. c->fl.isPrimary = false;
  5980. auxiliaryConstraints.Append( c );
  5981. }
  5982. }
  5983. // create trees for all parent bodies
  5984. for ( i = 0; i < bodies.Num(); i++ ) {
  5985. if ( !bodies[i]->parent ) {
  5986. tree = new (TAG_PHYSICS_AF) idAFTree();
  5987. tree->sortedBodies.Clear();
  5988. tree->sortedBodies.Append( bodies[i] );
  5989. bodies[i]->tree = tree;
  5990. trees.Append( tree );
  5991. }
  5992. }
  5993. // add each child body to the appropriate tree
  5994. for ( i = 0; i < bodies.Num(); i++ ) {
  5995. if ( bodies[i]->parent ) {
  5996. for ( b = bodies[i]->parent; !b->tree; b = b->parent ) {
  5997. }
  5998. b->tree->sortedBodies.Append( bodies[i] );
  5999. bodies[i]->tree = b->tree;
  6000. }
  6001. }
  6002. if ( trees.Num() > 1 ) {
  6003. gameLocal.Warning( "Articulated figure has multiple seperate tree structures for entity '%s' type '%s'.",
  6004. self->name.c_str(), self->GetType()->classname );
  6005. }
  6006. // sort bodies in each tree to make sure parents come first
  6007. for ( i = 0; i < trees.Num(); i++ ) {
  6008. trees[i]->SortBodies();
  6009. }
  6010. } else {
  6011. // create a tree for each body
  6012. for ( i = 0; i < bodies.Num(); i++ ) {
  6013. tree = new (TAG_PHYSICS_AF) idAFTree();
  6014. tree->sortedBodies.Clear();
  6015. tree->sortedBodies.Append( bodies[i] );
  6016. bodies[i]->tree = tree;
  6017. trees.Append( tree );
  6018. }
  6019. for ( i = 0; i < constraints.Num(); i++ ) {
  6020. c = constraints[i];
  6021. c->body1->constraints.Append( c );
  6022. if ( c->body2 ) {
  6023. c->body2->constraints.Append( c );
  6024. }
  6025. c->fl.isPrimary = false;
  6026. auxiliaryConstraints.Append( c );
  6027. }
  6028. }
  6029. }
  6030. /*
  6031. ================
  6032. idPhysics_AF::AddBody
  6033. bodies get an id in the order they are added starting at zero
  6034. as such the first body added will get id zero
  6035. ================
  6036. */
  6037. int idPhysics_AF::AddBody( idAFBody *body ) {
  6038. int id = 0;
  6039. if ( body->clipModel == NULL ) {
  6040. gameLocal.Error( "idPhysics_AF::AddBody: body '%s' has no clip model.", body->name.c_str() );
  6041. return 0;
  6042. }
  6043. if ( bodies.Find( body ) ) {
  6044. gameLocal.Error( "idPhysics_AF::AddBody: body '%s' added twice.", body->name.c_str() );
  6045. }
  6046. if ( GetBody( body->name ) ) {
  6047. gameLocal.Error( "idPhysics_AF::AddBody: a body with the name '%s' already exists.", body->name.c_str() );
  6048. }
  6049. id = bodies.Num();
  6050. body->clipModel->SetId( id );
  6051. if ( body->linearFriction < 0.0f ) {
  6052. body->linearFriction = linearFriction;
  6053. body->angularFriction = angularFriction;
  6054. body->contactFriction = contactFriction;
  6055. }
  6056. if ( body->bouncyness < 0.0f ) {
  6057. body->bouncyness = bouncyness;
  6058. }
  6059. if ( !body->fl.clipMaskSet ) {
  6060. body->clipMask = clipMask;
  6061. }
  6062. bodies.Append( body );
  6063. changedAF = true;
  6064. return id;
  6065. }
  6066. /*
  6067. ================
  6068. idPhysics_AF::AddConstraint
  6069. ================
  6070. */
  6071. void idPhysics_AF::AddConstraint( idAFConstraint *constraint ) {
  6072. if ( constraints.Find( constraint ) ) {
  6073. gameLocal.Error( "idPhysics_AF::AddConstraint: constraint '%s' added twice.", constraint->name.c_str() );
  6074. }
  6075. if ( GetConstraint( constraint->name ) ) {
  6076. gameLocal.Error( "idPhysics_AF::AddConstraint: a constraint with the name '%s' already exists.", constraint->name.c_str() );
  6077. }
  6078. if ( !constraint->body1 ) {
  6079. gameLocal.Error( "idPhysics_AF::AddConstraint: body1 == NULL on constraint '%s'.", constraint->name.c_str() );
  6080. }
  6081. if ( !bodies.Find( constraint->body1 ) ) {
  6082. gameLocal.Error( "idPhysics_AF::AddConstraint: body1 of constraint '%s' is not part of the articulated figure.", constraint->name.c_str() );
  6083. }
  6084. if ( constraint->body2 && !bodies.Find( constraint->body2 ) ) {
  6085. gameLocal.Error( "idPhysics_AF::AddConstraint: body2 of constraint '%s' is not part of the articulated figure.", constraint->name.c_str() );
  6086. }
  6087. if ( constraint->body1 == constraint->body2 ) {
  6088. gameLocal.Error( "idPhysics_AF::AddConstraint: body1 and body2 of constraint '%s' are the same.", constraint->name.c_str() );
  6089. }
  6090. constraints.Append( constraint );
  6091. constraint->physics = this;
  6092. changedAF = true;
  6093. }
  6094. /*
  6095. ================
  6096. idPhysics_AF::AddFrameConstraint
  6097. ================
  6098. */
  6099. void idPhysics_AF::AddFrameConstraint( idAFConstraint *constraint ) {
  6100. frameConstraints.Append( constraint );
  6101. constraint->physics = this;
  6102. }
  6103. /*
  6104. ================
  6105. idPhysics_AF::ForceBodyId
  6106. ================
  6107. */
  6108. void idPhysics_AF::ForceBodyId( idAFBody *body, int newId ) {
  6109. int id;
  6110. id = bodies.FindIndex( body );
  6111. if ( id == -1 ) {
  6112. gameLocal.Error( "ForceBodyId: body '%s' is not part of the articulated figure.\n", body->name.c_str() );
  6113. }
  6114. if ( id != newId ) {
  6115. idAFBody *b = bodies[newId];
  6116. bodies[newId] = bodies[id];
  6117. bodies[id] = b;
  6118. changedAF = true;
  6119. }
  6120. }
  6121. /*
  6122. ================
  6123. idPhysics_AF::GetBodyId
  6124. ================
  6125. */
  6126. int idPhysics_AF::GetBodyId( idAFBody *body ) const {
  6127. int id;
  6128. id = bodies.FindIndex( body );
  6129. if ( id == -1 && body ) {
  6130. gameLocal.Error( "GetBodyId: body '%s' is not part of the articulated figure.\n", body->name.c_str() );
  6131. }
  6132. return id;
  6133. }
  6134. /*
  6135. ================
  6136. idPhysics_AF::GetBodyId
  6137. ================
  6138. */
  6139. int idPhysics_AF::GetBodyId( const char *bodyName ) const {
  6140. int i;
  6141. for ( i = 0; i < bodies.Num(); i++ ) {
  6142. if ( !bodies[i]->name.Icmp( bodyName ) ) {
  6143. return i;
  6144. }
  6145. }
  6146. gameLocal.Error( "GetBodyId: no body with the name '%s' is not part of the articulated figure.\n", bodyName );
  6147. return 0;
  6148. }
  6149. /*
  6150. ================
  6151. idPhysics_AF::GetConstraintId
  6152. ================
  6153. */
  6154. int idPhysics_AF::GetConstraintId( idAFConstraint *constraint ) const {
  6155. int id;
  6156. id = constraints.FindIndex( constraint );
  6157. if ( id == -1 && constraint ) {
  6158. gameLocal.Error( "GetConstraintId: constraint '%s' is not part of the articulated figure.\n", constraint->name.c_str() );
  6159. }
  6160. return id;
  6161. }
  6162. /*
  6163. ================
  6164. idPhysics_AF::GetConstraintId
  6165. ================
  6166. */
  6167. int idPhysics_AF::GetConstraintId( const char *constraintName ) const {
  6168. int i;
  6169. for ( i = 0; i < constraints.Num(); i++ ) {
  6170. if ( constraints[i]->name.Icmp( constraintName ) == 0 ) {
  6171. return i;
  6172. }
  6173. }
  6174. gameLocal.Error( "GetConstraintId: no constraint with the name '%s' is not part of the articulated figure.\n", constraintName );
  6175. return 0;
  6176. }
  6177. /*
  6178. ================
  6179. idPhysics_AF::GetNumBodies
  6180. ================
  6181. */
  6182. int idPhysics_AF::GetNumBodies() const {
  6183. return bodies.Num();
  6184. }
  6185. /*
  6186. ================
  6187. idPhysics_AF::GetNumConstraints
  6188. ================
  6189. */
  6190. int idPhysics_AF::GetNumConstraints() const {
  6191. return constraints.Num();
  6192. }
  6193. /*
  6194. ================
  6195. idPhysics_AF::GetBody
  6196. ================
  6197. */
  6198. idAFBody *idPhysics_AF::GetBody( const char *bodyName ) const {
  6199. int i;
  6200. for ( i = 0; i < bodies.Num(); i++ ) {
  6201. if ( !bodies[i]->name.Icmp( bodyName ) ) {
  6202. return bodies[i];
  6203. }
  6204. }
  6205. return NULL;
  6206. }
  6207. /*
  6208. ================
  6209. idPhysics_AF::GetBody
  6210. ================
  6211. */
  6212. idAFBody *idPhysics_AF::GetBody( const int id ) const {
  6213. if ( id < 0 || id >= bodies.Num() ) {
  6214. gameLocal.Error( "GetBody: no body with id %d exists\n", id );
  6215. return NULL;
  6216. }
  6217. return bodies[id];
  6218. }
  6219. /*
  6220. ================
  6221. idPhysics_AF::GetConstraint
  6222. ================
  6223. */
  6224. idAFConstraint *idPhysics_AF::GetConstraint( const char *constraintName ) const {
  6225. int i;
  6226. for ( i = 0; i < constraints.Num(); i++ ) {
  6227. if ( constraints[i]->name.Icmp( constraintName ) == 0 ) {
  6228. return constraints[i];
  6229. }
  6230. }
  6231. return NULL;
  6232. }
  6233. /*
  6234. ================
  6235. idPhysics_AF::GetConstraint
  6236. ================
  6237. */
  6238. idAFConstraint *idPhysics_AF::GetConstraint( const int id ) const {
  6239. if ( id < 0 || id >= constraints.Num() ) {
  6240. gameLocal.Error( "GetConstraint: no constraint with id %d exists\n", id );
  6241. return NULL;
  6242. }
  6243. return constraints[id];
  6244. }
  6245. /*
  6246. ================
  6247. idPhysics_AF::DeleteBody
  6248. ================
  6249. */
  6250. void idPhysics_AF::DeleteBody( const char *bodyName ) {
  6251. int i;
  6252. // find the body with the given name
  6253. for ( i = 0; i < bodies.Num(); i++ ) {
  6254. if ( !bodies[i]->name.Icmp( bodyName ) ) {
  6255. break;
  6256. }
  6257. }
  6258. if ( i >= bodies.Num() ) {
  6259. gameLocal.Warning( "DeleteBody: no body found in the articulated figure with the name '%s' for entity '%s' type '%s'.",
  6260. bodyName, self->name.c_str(), self->GetType()->classname );
  6261. return;
  6262. }
  6263. DeleteBody( i );
  6264. }
  6265. /*
  6266. ================
  6267. idPhysics_AF::DeleteBody
  6268. ================
  6269. */
  6270. void idPhysics_AF::DeleteBody( const int id ) {
  6271. int j;
  6272. if ( id < 0 || id > bodies.Num() ) {
  6273. gameLocal.Error( "DeleteBody: no body with id %d.", id );
  6274. return;
  6275. }
  6276. // remove any constraints attached to this body
  6277. for ( j = 0; j < constraints.Num(); j++ ) {
  6278. if ( constraints[j]->body1 == bodies[id] || constraints[j]->body2 == bodies[id] ) {
  6279. delete constraints[j];
  6280. constraints.RemoveIndex( j );
  6281. j--;
  6282. }
  6283. }
  6284. // remove the body
  6285. delete bodies[id];
  6286. bodies.RemoveIndex( id );
  6287. // set new body ids
  6288. for ( j = 0; j < bodies.Num(); j++ ) {
  6289. bodies[j]->clipModel->SetId( j );
  6290. }
  6291. changedAF = true;
  6292. }
  6293. /*
  6294. ================
  6295. idPhysics_AF::DeleteConstraint
  6296. ================
  6297. */
  6298. void idPhysics_AF::DeleteConstraint( const char *constraintName ) {
  6299. int i;
  6300. // find the constraint with the given name
  6301. for ( i = 0; i < constraints.Num(); i++ ) {
  6302. if ( !constraints[i]->name.Icmp( constraintName ) ) {
  6303. break;
  6304. }
  6305. }
  6306. if ( i >= constraints.Num() ) {
  6307. gameLocal.Warning( "DeleteConstraint: no constriant found in the articulated figure with the name '%s' for entity '%s' type '%s'.",
  6308. constraintName, self->name.c_str(), self->GetType()->classname );
  6309. return;
  6310. }
  6311. DeleteConstraint( i );
  6312. }
  6313. /*
  6314. ================
  6315. idPhysics_AF::DeleteConstraint
  6316. ================
  6317. */
  6318. void idPhysics_AF::DeleteConstraint( const int id ) {
  6319. if ( id < 0 || id >= constraints.Num() ) {
  6320. gameLocal.Error( "DeleteConstraint: no constraint with id %d.", id );
  6321. return;
  6322. }
  6323. // remove the constraint
  6324. delete constraints[id];
  6325. constraints.RemoveIndex( id );
  6326. changedAF = true;
  6327. }
  6328. /*
  6329. ================
  6330. idPhysics_AF::GetBodyContactConstraints
  6331. ================
  6332. */
  6333. int idPhysics_AF::GetBodyContactConstraints( const int id, idAFConstraint_Contact *contacts[], int maxContacts ) const {
  6334. int i, numContacts;
  6335. idAFBody *body;
  6336. idAFConstraint_Contact *contact;
  6337. if ( id < 0 || id >= bodies.Num() || maxContacts <= 0 ) {
  6338. return 0;
  6339. }
  6340. numContacts = 0;
  6341. body = bodies[id];
  6342. for ( i = 0; i < contactConstraints.Num(); i++ ) {
  6343. contact = contactConstraints[i];
  6344. if ( contact->body1 == body || contact->body2 == body ) {
  6345. contacts[numContacts++] = contact;
  6346. if ( numContacts >= maxContacts ) {
  6347. return numContacts;
  6348. }
  6349. }
  6350. }
  6351. return numContacts;
  6352. }
  6353. /*
  6354. ================
  6355. idPhysics_AF::SetDefaultFriction
  6356. ================
  6357. */
  6358. void idPhysics_AF::SetDefaultFriction( float linear, float angular, float contact ) {
  6359. if ( linear < 0.0f || linear > 1.0f ||
  6360. angular < 0.0f || angular > 1.0f ||
  6361. contact < 0.0f || contact > 1.0f ) {
  6362. return;
  6363. }
  6364. linearFriction = linear;
  6365. angularFriction = angular;
  6366. contactFriction = contact;
  6367. }
  6368. /*
  6369. ================
  6370. idPhysics_AF::GetImpactInfo
  6371. ================
  6372. */
  6373. void idPhysics_AF::GetImpactInfo( const int id, const idVec3 &point, impactInfo_t *info ) const {
  6374. if ( id < 0 || id >= bodies.Num() ) {
  6375. memset( info, 0, sizeof( *info ) );
  6376. return;
  6377. }
  6378. info->invMass = 1.0f / bodies[id]->mass;
  6379. info->invInertiaTensor = bodies[id]->current->worldAxis.Transpose() * bodies[id]->inverseInertiaTensor * bodies[id]->current->worldAxis;
  6380. info->position = point - bodies[id]->current->worldOrigin;
  6381. info->velocity = bodies[id]->current->spatialVelocity.SubVec3(0) + bodies[id]->current->spatialVelocity.SubVec3(1).Cross( info->position );
  6382. }
  6383. /*
  6384. ================
  6385. idPhysics_AF::ApplyImpulse
  6386. ================
  6387. */
  6388. void idPhysics_AF::ApplyImpulse( const int id, const idVec3 &point, const idVec3 &impulse ) {
  6389. if ( id < 0 || id >= bodies.Num() ) {
  6390. return;
  6391. }
  6392. if ( noImpact || impulse.LengthSqr() < Square( impulseThreshold ) ) {
  6393. return;
  6394. }
  6395. const float maxImpulse = 100000.0f;
  6396. const float maxRotation = 100000.0f;
  6397. idMat3 invWorldInertiaTensor = bodies[id]->current->worldAxis.Transpose() * bodies[id]->inverseInertiaTensor * bodies[id]->current->worldAxis;
  6398. bodies[id]->current->spatialVelocity.SubVec3(0) += bodies[id]->invMass * impulse.Truncate( maxImpulse );
  6399. bodies[id]->current->spatialVelocity.SubVec3(1) += invWorldInertiaTensor * (point - bodies[id]->current->worldOrigin).Cross( impulse ).Truncate( maxRotation );
  6400. Activate();
  6401. }
  6402. /*
  6403. ================
  6404. idPhysics_AF::AddForce
  6405. ================
  6406. */
  6407. void idPhysics_AF::AddForce( const int id, const idVec3 &point, const idVec3 &force ) {
  6408. if ( noImpact ) {
  6409. return;
  6410. }
  6411. if ( id < 0 || id >= bodies.Num() ) {
  6412. return;
  6413. }
  6414. bodies[id]->current->externalForce.SubVec3( 0 ) += force;
  6415. bodies[id]->current->externalForce.SubVec3( 1 ) += (point - bodies[id]->current->worldOrigin).Cross( force );
  6416. Activate();
  6417. }
  6418. /*
  6419. ================
  6420. idPhysics_AF::IsAtRest
  6421. ================
  6422. */
  6423. bool idPhysics_AF::IsAtRest() const {
  6424. return current.atRest >= 0;
  6425. }
  6426. /*
  6427. ================
  6428. idPhysics_AF::GetRestStartTime
  6429. ================
  6430. */
  6431. int idPhysics_AF::GetRestStartTime() const {
  6432. return current.atRest;
  6433. }
  6434. /*
  6435. ================
  6436. idPhysics_AF::IsPushable
  6437. ================
  6438. */
  6439. bool idPhysics_AF::IsPushable() const {
  6440. return ( !noImpact && ( masterBody == NULL || forcePushable ) );
  6441. }
  6442. /*
  6443. ================
  6444. idPhysics_AF::SaveState
  6445. ================
  6446. */
  6447. void idPhysics_AF::SaveState() {
  6448. int i;
  6449. saved = current;
  6450. for ( i = 0; i < bodies.Num(); i++ ) {
  6451. memcpy( &bodies[i]->saved, bodies[i]->current, sizeof( AFBodyPState_t ) );
  6452. }
  6453. }
  6454. /*
  6455. ================
  6456. idPhysics_AF::RestoreState
  6457. ================
  6458. */
  6459. void idPhysics_AF::RestoreState() {
  6460. int i;
  6461. current = saved;
  6462. for ( i = 0; i < bodies.Num(); i++ ) {
  6463. *(bodies[i]->current) = bodies[i]->saved;
  6464. }
  6465. EvaluateContacts();
  6466. }
  6467. /*
  6468. ================
  6469. idPhysics_AF::SetOrigin
  6470. ================
  6471. */
  6472. void idPhysics_AF::SetOrigin( const idVec3 &newOrigin, int id ) {
  6473. if ( masterBody ) {
  6474. Translate( masterBody->current->worldOrigin + masterBody->current->worldAxis * newOrigin - bodies[0]->current->worldOrigin );
  6475. } else {
  6476. Translate( newOrigin - bodies[0]->current->worldOrigin );
  6477. }
  6478. }
  6479. /*
  6480. ================
  6481. idPhysics_AF::SetAxis
  6482. ================
  6483. */
  6484. void idPhysics_AF::SetAxis( const idMat3 &newAxis, int id ) {
  6485. idMat3 axis;
  6486. idRotation rotation;
  6487. if ( masterBody ) {
  6488. axis = bodies[0]->current->worldAxis.Transpose() * ( newAxis * masterBody->current->worldAxis );
  6489. } else {
  6490. axis = bodies[0]->current->worldAxis.Transpose() * newAxis;
  6491. }
  6492. rotation = axis.ToRotation();
  6493. rotation.SetOrigin( bodies[0]->current->worldOrigin );
  6494. Rotate( rotation );
  6495. }
  6496. /*
  6497. ================
  6498. idPhysics_AF::Translate
  6499. ================
  6500. */
  6501. void idPhysics_AF::Translate( const idVec3 &translation, int id ) {
  6502. int i;
  6503. idAFBody *body;
  6504. if ( !worldConstraintsLocked ) {
  6505. // translate constraints attached to the world
  6506. for ( i = 0; i < constraints.Num(); i++ ) {
  6507. constraints[i]->Translate( translation );
  6508. }
  6509. }
  6510. // translate all the bodies
  6511. for ( i = 0; i < bodies.Num(); i++ ) {
  6512. body = bodies[i];
  6513. body->current->worldOrigin += translation;
  6514. }
  6515. Activate();
  6516. UpdateClipModels();
  6517. }
  6518. /*
  6519. ================
  6520. idPhysics_AF::Rotate
  6521. ================
  6522. */
  6523. void idPhysics_AF::Rotate( const idRotation &rotation, int id ) {
  6524. int i;
  6525. idAFBody *body;
  6526. if ( !worldConstraintsLocked ) {
  6527. // rotate constraints attached to the world
  6528. for ( i = 0; i < constraints.Num(); i++ ) {
  6529. constraints[i]->Rotate( rotation );
  6530. }
  6531. }
  6532. // rotate all the bodies
  6533. for ( i = 0; i < bodies.Num(); i++ ) {
  6534. body = bodies[i];
  6535. body->current->worldOrigin *= rotation;
  6536. body->current->worldAxis *= rotation.ToMat3();
  6537. }
  6538. Activate();
  6539. UpdateClipModels();
  6540. }
  6541. /*
  6542. ================
  6543. idPhysics_AF::GetOrigin
  6544. ================
  6545. */
  6546. const idVec3 &idPhysics_AF::GetOrigin( int id ) const {
  6547. if ( id < 0 || id >= bodies.Num() ) {
  6548. return vec3_origin;
  6549. }
  6550. else {
  6551. return bodies[id]->current->worldOrigin;
  6552. }
  6553. }
  6554. /*
  6555. ================
  6556. idPhysics_AF::GetAxis
  6557. ================
  6558. */
  6559. const idMat3 &idPhysics_AF::GetAxis( int id ) const {
  6560. if ( id < 0 || id >= bodies.Num() ) {
  6561. return mat3_identity;
  6562. }
  6563. else {
  6564. return bodies[id]->current->worldAxis;
  6565. }
  6566. }
  6567. /*
  6568. ================
  6569. idPhysics_AF::SetLinearVelocity
  6570. ================
  6571. */
  6572. void idPhysics_AF::SetLinearVelocity( const idVec3 &newLinearVelocity, int id ) {
  6573. if ( id < 0 || id >= bodies.Num() ) {
  6574. return;
  6575. }
  6576. bodies[id]->current->spatialVelocity.SubVec3( 0 ) = newLinearVelocity;
  6577. Activate();
  6578. }
  6579. /*
  6580. ================
  6581. idPhysics_AF::SetAngularVelocity
  6582. ================
  6583. */
  6584. void idPhysics_AF::SetAngularVelocity( const idVec3 &newAngularVelocity, int id ) {
  6585. if ( id < 0 || id >= bodies.Num() ) {
  6586. return;
  6587. }
  6588. bodies[id]->current->spatialVelocity.SubVec3( 1 ) = newAngularVelocity;
  6589. Activate();
  6590. }
  6591. /*
  6592. ================
  6593. idPhysics_AF::GetLinearVelocity
  6594. ================
  6595. */
  6596. const idVec3 &idPhysics_AF::GetLinearVelocity( int id ) const {
  6597. if ( id < 0 || id >= bodies.Num() ) {
  6598. return vec3_origin;
  6599. }
  6600. else {
  6601. return bodies[id]->current->spatialVelocity.SubVec3( 0 );
  6602. }
  6603. }
  6604. /*
  6605. ================
  6606. idPhysics_AF::GetAngularVelocity
  6607. ================
  6608. */
  6609. const idVec3 &idPhysics_AF::GetAngularVelocity( int id ) const {
  6610. if ( id < 0 || id >= bodies.Num() ) {
  6611. return vec3_origin;
  6612. }
  6613. else {
  6614. return bodies[id]->current->spatialVelocity.SubVec3( 1 );
  6615. }
  6616. }
  6617. /*
  6618. ================
  6619. idPhysics_AF::ClipTranslation
  6620. ================
  6621. */
  6622. void idPhysics_AF::ClipTranslation( trace_t &results, const idVec3 &translation, const idClipModel *model ) const {
  6623. int i;
  6624. idAFBody *body;
  6625. trace_t bodyResults;
  6626. results.fraction = 1.0f;
  6627. for ( i = 0; i < bodies.Num(); i++ ) {
  6628. body = bodies[i];
  6629. if ( body->clipModel->IsTraceModel() ) {
  6630. if ( model ) {
  6631. gameLocal.clip.TranslationModel( bodyResults, body->current->worldOrigin, body->current->worldOrigin + translation,
  6632. body->clipModel, body->current->worldAxis, body->clipMask,
  6633. model->Handle(), model->GetOrigin(), model->GetAxis() );
  6634. }
  6635. else {
  6636. gameLocal.clip.Translation( bodyResults, body->current->worldOrigin, body->current->worldOrigin + translation,
  6637. body->clipModel, body->current->worldAxis, body->clipMask, self );
  6638. }
  6639. if ( bodyResults.fraction < results.fraction ) {
  6640. results = bodyResults;
  6641. }
  6642. }
  6643. }
  6644. results.endpos = bodies[0]->current->worldOrigin + results.fraction * translation;
  6645. results.endAxis = bodies[0]->current->worldAxis;
  6646. }
  6647. /*
  6648. ================
  6649. idPhysics_AF::ClipRotation
  6650. ================
  6651. */
  6652. void idPhysics_AF::ClipRotation( trace_t &results, const idRotation &rotation, const idClipModel *model ) const {
  6653. int i;
  6654. idAFBody *body;
  6655. trace_t bodyResults;
  6656. idRotation partialRotation;
  6657. results.fraction = 1.0f;
  6658. for ( i = 0; i < bodies.Num(); i++ ) {
  6659. body = bodies[i];
  6660. if ( body->clipModel->IsTraceModel() ) {
  6661. if ( model ) {
  6662. gameLocal.clip.RotationModel( bodyResults, body->current->worldOrigin, rotation,
  6663. body->clipModel, body->current->worldAxis, body->clipMask,
  6664. model->Handle(), model->GetOrigin(), model->GetAxis() );
  6665. }
  6666. else {
  6667. gameLocal.clip.Rotation( bodyResults, body->current->worldOrigin, rotation,
  6668. body->clipModel, body->current->worldAxis, body->clipMask, self );
  6669. }
  6670. if ( bodyResults.fraction < results.fraction ) {
  6671. results = bodyResults;
  6672. }
  6673. }
  6674. }
  6675. partialRotation = rotation * results.fraction;
  6676. results.endpos = bodies[0]->current->worldOrigin * partialRotation;
  6677. results.endAxis = bodies[0]->current->worldAxis * partialRotation.ToMat3();
  6678. }
  6679. /*
  6680. ================
  6681. idPhysics_AF::ClipContents
  6682. ================
  6683. */
  6684. int idPhysics_AF::ClipContents( const idClipModel *model ) const {
  6685. int i, contents;
  6686. idAFBody *body;
  6687. contents = 0;
  6688. for ( i = 0; i < bodies.Num(); i++ ) {
  6689. body = bodies[i];
  6690. if ( body->clipModel->IsTraceModel() ) {
  6691. if ( model ) {
  6692. contents |= gameLocal.clip.ContentsModel( body->current->worldOrigin,
  6693. body->clipModel, body->current->worldAxis, -1,
  6694. model->Handle(), model->GetOrigin(), model->GetAxis() );
  6695. }
  6696. else {
  6697. contents |= gameLocal.clip.Contents( body->current->worldOrigin,
  6698. body->clipModel, body->current->worldAxis, -1, NULL );
  6699. }
  6700. }
  6701. }
  6702. return contents;
  6703. }
  6704. /*
  6705. ================
  6706. idPhysics_AF::DisableClip
  6707. ================
  6708. */
  6709. void idPhysics_AF::DisableClip() {
  6710. int i;
  6711. for ( i = 0; i < bodies.Num(); i++ ) {
  6712. bodies[i]->clipModel->Disable();
  6713. }
  6714. }
  6715. /*
  6716. ================
  6717. idPhysics_AF::EnableClip
  6718. ================
  6719. */
  6720. void idPhysics_AF::EnableClip() {
  6721. int i;
  6722. for ( i = 0; i < bodies.Num(); i++ ) {
  6723. bodies[i]->clipModel->Enable();
  6724. }
  6725. }
  6726. /*
  6727. ================
  6728. idPhysics_AF::UnlinkClip
  6729. ================
  6730. */
  6731. void idPhysics_AF::UnlinkClip() {
  6732. int i;
  6733. for ( i = 0; i < bodies.Num(); i++ ) {
  6734. bodies[i]->clipModel->Unlink();
  6735. }
  6736. }
  6737. /*
  6738. ================
  6739. idPhysics_AF::LinkClip
  6740. ================
  6741. */
  6742. void idPhysics_AF::LinkClip() {
  6743. UpdateClipModels();
  6744. }
  6745. /*
  6746. ================
  6747. idPhysics_AF::SetPushed
  6748. ================
  6749. */
  6750. void idPhysics_AF::SetPushed( int deltaTime ) {
  6751. idAFBody *body;
  6752. idRotation rotation;
  6753. if ( bodies.Num() ) {
  6754. body = bodies[0];
  6755. rotation = ( body->saved.worldAxis.Transpose() * body->current->worldAxis ).ToRotation();
  6756. // velocity with which the af is pushed
  6757. current.pushVelocity.SubVec3(0) += ( body->current->worldOrigin - body->saved.worldOrigin ) / ( deltaTime * idMath::M_MS2SEC );
  6758. current.pushVelocity.SubVec3(1) += rotation.GetVec() * -DEG2RAD( rotation.GetAngle() ) / ( deltaTime * idMath::M_MS2SEC );
  6759. }
  6760. }
  6761. /*
  6762. ================
  6763. idPhysics_AF::GetPushedLinearVelocity
  6764. ================
  6765. */
  6766. const idVec3 &idPhysics_AF::GetPushedLinearVelocity( const int id ) const {
  6767. return current.pushVelocity.SubVec3(0);
  6768. }
  6769. /*
  6770. ================
  6771. idPhysics_AF::GetPushedAngularVelocity
  6772. ================
  6773. */
  6774. const idVec3 &idPhysics_AF::GetPushedAngularVelocity( const int id ) const {
  6775. return current.pushVelocity.SubVec3(1);
  6776. }
  6777. /*
  6778. ================
  6779. idPhysics_AF::SetMaster
  6780. the binding is orientated based on the constraints being used
  6781. ================
  6782. */
  6783. void idPhysics_AF::SetMaster( idEntity *master, const bool orientated ) {
  6784. int i;
  6785. idVec3 masterOrigin;
  6786. idMat3 masterAxis;
  6787. idRotation rotation;
  6788. if ( master ) {
  6789. self->GetMasterPosition( masterOrigin, masterAxis );
  6790. if ( !masterBody ) {
  6791. masterBody = new (TAG_PHYSICS_AF) idAFBody();
  6792. // translate and rotate all the constraints with body2 == NULL from world space to master space
  6793. rotation = masterAxis.Transpose().ToRotation();
  6794. for ( i = 0; i < constraints.Num(); i++ ) {
  6795. if ( constraints[i]->GetBody2() == NULL ) {
  6796. constraints[i]->Translate( -masterOrigin );
  6797. constraints[i]->Rotate( rotation );
  6798. }
  6799. }
  6800. Activate();
  6801. }
  6802. masterBody->current->worldOrigin = masterOrigin;
  6803. masterBody->current->worldAxis = masterAxis;
  6804. }
  6805. else {
  6806. if ( masterBody ) {
  6807. // translate and rotate all the constraints with body2 == NULL from master space to world space
  6808. rotation = masterBody->current->worldAxis.ToRotation();
  6809. for ( i = 0; i < constraints.Num(); i++ ) {
  6810. if ( constraints[i]->GetBody2() == NULL ) {
  6811. constraints[i]->Rotate( rotation );
  6812. constraints[i]->Translate( masterBody->current->worldOrigin );
  6813. }
  6814. }
  6815. delete masterBody;
  6816. masterBody = NULL;
  6817. Activate();
  6818. }
  6819. }
  6820. }
  6821. const float AF_VELOCITY_MAX = 16000;
  6822. const int AF_VELOCITY_TOTAL_BITS = 16;
  6823. const int AF_VELOCITY_EXPONENT_BITS = idMath::BitsForInteger( idMath::BitsForFloat( AF_VELOCITY_MAX ) ) + 1;
  6824. const int AF_VELOCITY_MANTISSA_BITS = AF_VELOCITY_TOTAL_BITS - 1 - AF_VELOCITY_EXPONENT_BITS;
  6825. const float AF_FORCE_MAX = 1e20f;
  6826. const int AF_FORCE_TOTAL_BITS = 16;
  6827. const int AF_FORCE_EXPONENT_BITS = idMath::BitsForInteger( idMath::BitsForFloat( AF_FORCE_MAX ) ) + 1;
  6828. const int AF_FORCE_MANTISSA_BITS = AF_FORCE_TOTAL_BITS - 1 - AF_FORCE_EXPONENT_BITS;
  6829. /*
  6830. ================
  6831. idPhysics_AF::WriteToSnapshot
  6832. ================
  6833. */
  6834. void idPhysics_AF::WriteToSnapshot( idBitMsg &msg ) const {
  6835. int i;
  6836. idCQuat quat;
  6837. msg.WriteLong( current.atRest );
  6838. msg.WriteFloat( current.noMoveTime );
  6839. msg.WriteFloat( current.activateTime );
  6840. msg.WriteDeltaFloat( 0.0f, current.pushVelocity[0], AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS );
  6841. msg.WriteDeltaFloat( 0.0f, current.pushVelocity[1], AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS );
  6842. msg.WriteDeltaFloat( 0.0f, current.pushVelocity[2], AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS );
  6843. msg.WriteDeltaFloat( 0.0f, current.pushVelocity[3], AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS );
  6844. msg.WriteDeltaFloat( 0.0f, current.pushVelocity[4], AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS );
  6845. msg.WriteDeltaFloat( 0.0f, current.pushVelocity[5], AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS );
  6846. msg.WriteByte( bodies.Num() );
  6847. for ( i = 0; i < bodies.Num(); i++ ) {
  6848. AFBodyPState_t *state = bodies[i]->current;
  6849. quat = state->worldAxis.ToCQuat();
  6850. msg.WriteFloat( state->worldOrigin[0] );
  6851. msg.WriteFloat( state->worldOrigin[1] );
  6852. msg.WriteFloat( state->worldOrigin[2] );
  6853. msg.WriteFloat( quat.x );
  6854. msg.WriteFloat( quat.y );
  6855. msg.WriteFloat( quat.z );
  6856. msg.WriteDeltaFloat( 0.0f, state->spatialVelocity[0], AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS );
  6857. msg.WriteDeltaFloat( 0.0f, state->spatialVelocity[1], AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS );
  6858. msg.WriteDeltaFloat( 0.0f, state->spatialVelocity[2], AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS );
  6859. msg.WriteDeltaFloat( 0.0f, state->spatialVelocity[3], AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS );
  6860. msg.WriteDeltaFloat( 0.0f, state->spatialVelocity[4], AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS );
  6861. msg.WriteDeltaFloat( 0.0f, state->spatialVelocity[5], AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS );
  6862. /* msg.WriteDeltaFloat( 0.0f, state->externalForce[0], AF_FORCE_EXPONENT_BITS, AF_FORCE_MANTISSA_BITS );
  6863. msg.WriteDeltaFloat( 0.0f, state->externalForce[1], AF_FORCE_EXPONENT_BITS, AF_FORCE_MANTISSA_BITS );
  6864. msg.WriteDeltaFloat( 0.0f, state->externalForce[2], AF_FORCE_EXPONENT_BITS, AF_FORCE_MANTISSA_BITS );
  6865. msg.WriteDeltaFloat( 0.0f, state->externalForce[3], AF_FORCE_EXPONENT_BITS, AF_FORCE_MANTISSA_BITS );
  6866. msg.WriteDeltaFloat( 0.0f, state->externalForce[4], AF_FORCE_EXPONENT_BITS, AF_FORCE_MANTISSA_BITS );
  6867. msg.WriteDeltaFloat( 0.0f, state->externalForce[5], AF_FORCE_EXPONENT_BITS, AF_FORCE_MANTISSA_BITS );
  6868. */
  6869. }
  6870. }
  6871. /*
  6872. ================
  6873. idPhysics_AF::ReadFromSnapshot
  6874. ================
  6875. */
  6876. void idPhysics_AF::ReadFromSnapshot( const idBitMsg &msg ) {
  6877. int i, num;
  6878. idCQuat quat;
  6879. current.atRest = msg.ReadLong();
  6880. current.noMoveTime = msg.ReadFloat();
  6881. current.activateTime = msg.ReadFloat();
  6882. current.pushVelocity[0] = msg.ReadDeltaFloat( 0.0f, AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS );
  6883. current.pushVelocity[1] = msg.ReadDeltaFloat( 0.0f, AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS );
  6884. current.pushVelocity[2] = msg.ReadDeltaFloat( 0.0f, AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS );
  6885. current.pushVelocity[3] = msg.ReadDeltaFloat( 0.0f, AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS );
  6886. current.pushVelocity[4] = msg.ReadDeltaFloat( 0.0f, AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS );
  6887. current.pushVelocity[5] = msg.ReadDeltaFloat( 0.0f, AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS );
  6888. num = msg.ReadByte();
  6889. assert( num == bodies.Num() );
  6890. for ( i = 0; i < bodies.Num(); i++ ) {
  6891. AFBodyPState_t *state = bodies[i]->current;
  6892. state->worldOrigin[0] = msg.ReadFloat();
  6893. state->worldOrigin[1] = msg.ReadFloat();
  6894. state->worldOrigin[2] = msg.ReadFloat();
  6895. quat.x = msg.ReadFloat();
  6896. quat.y = msg.ReadFloat();
  6897. quat.z = msg.ReadFloat();
  6898. state->spatialVelocity[0] = msg.ReadDeltaFloat( 0.0f, AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS );
  6899. state->spatialVelocity[1] = msg.ReadDeltaFloat( 0.0f, AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS );
  6900. state->spatialVelocity[2] = msg.ReadDeltaFloat( 0.0f, AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS );
  6901. state->spatialVelocity[3] = msg.ReadDeltaFloat( 0.0f, AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS );
  6902. state->spatialVelocity[4] = msg.ReadDeltaFloat( 0.0f, AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS );
  6903. state->spatialVelocity[5] = msg.ReadDeltaFloat( 0.0f, AF_VELOCITY_EXPONENT_BITS, AF_VELOCITY_MANTISSA_BITS );
  6904. /* state->externalForce[0] = msg.ReadDeltaFloat( 0.0f, AF_FORCE_EXPONENT_BITS, AF_FORCE_MANTISSA_BITS );
  6905. state->externalForce[1] = msg.ReadDeltaFloat( 0.0f, AF_FORCE_EXPONENT_BITS, AF_FORCE_MANTISSA_BITS );
  6906. state->externalForce[2] = msg.ReadDeltaFloat( 0.0f, AF_FORCE_EXPONENT_BITS, AF_FORCE_MANTISSA_BITS );
  6907. state->externalForce[3] = msg.ReadDeltaFloat( 0.0f, AF_FORCE_EXPONENT_BITS, AF_FORCE_MANTISSA_BITS );
  6908. state->externalForce[4] = msg.ReadDeltaFloat( 0.0f, AF_FORCE_EXPONENT_BITS, AF_FORCE_MANTISSA_BITS );
  6909. state->externalForce[5] = msg.ReadDeltaFloat( 0.0f, AF_FORCE_EXPONENT_BITS, AF_FORCE_MANTISSA_BITS );
  6910. */
  6911. state->worldAxis = quat.ToMat3();
  6912. }
  6913. UpdateClipModels();
  6914. }