Matrix.cpp 244 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103
  1. /*
  2. ===========================================================================
  3. Doom 3 GPL Source Code
  4. Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
  5. This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
  6. Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
  16. In addition, the Doom 3 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 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. #include "../precompiled.h"
  21. #pragma hdrstop
  22. //===============================================================
  23. //
  24. // idMat2
  25. //
  26. //===============================================================
  27. idMat2 mat2_zero( idVec2( 0, 0 ), idVec2( 0, 0 ) );
  28. idMat2 mat2_identity( idVec2( 1, 0 ), idVec2( 0, 1 ) );
  29. /*
  30. ============
  31. idMat2::InverseSelf
  32. ============
  33. */
  34. bool idMat2::InverseSelf( void ) {
  35. // 2+4 = 6 multiplications
  36. // 1 division
  37. double det, invDet, a;
  38. det = mat[0][0] * mat[1][1] - mat[0][1] * mat[1][0];
  39. if ( idMath::Fabs( det ) < MATRIX_INVERSE_EPSILON ) {
  40. return false;
  41. }
  42. invDet = 1.0f / det;
  43. a = mat[0][0];
  44. mat[0][0] = mat[1][1] * invDet;
  45. mat[0][1] = - mat[0][1] * invDet;
  46. mat[1][0] = - mat[1][0] * invDet;
  47. mat[1][1] = a * invDet;
  48. return true;
  49. }
  50. /*
  51. ============
  52. idMat2::InverseFastSelf
  53. ============
  54. */
  55. bool idMat2::InverseFastSelf( void ) {
  56. #if 1
  57. // 2+4 = 6 multiplications
  58. // 1 division
  59. double det, invDet, a;
  60. det = mat[0][0] * mat[1][1] - mat[0][1] * mat[1][0];
  61. if ( idMath::Fabs( det ) < MATRIX_INVERSE_EPSILON ) {
  62. return false;
  63. }
  64. invDet = 1.0f / det;
  65. a = mat[0][0];
  66. mat[0][0] = mat[1][1] * invDet;
  67. mat[0][1] = - mat[0][1] * invDet;
  68. mat[1][0] = - mat[1][0] * invDet;
  69. mat[1][1] = a * invDet;
  70. return true;
  71. #else
  72. // 2*4 = 8 multiplications
  73. // 2 division
  74. float *mat = reinterpret_cast<float *>(this);
  75. double d, di;
  76. float s;
  77. di = mat[0];
  78. s = di;
  79. mat[0*2+0] = d = 1.0f / di;
  80. mat[0*2+1] *= d;
  81. d = -d;
  82. mat[1*2+0] *= d;
  83. d = mat[1*2+0] * di;
  84. mat[1*2+1] += mat[0*2+1] * d;
  85. di = mat[1*2+1];
  86. s *= di;
  87. mat[1*2+1] = d = 1.0f / di;
  88. mat[1*2+0] *= d;
  89. d = -d;
  90. mat[0*2+1] *= d;
  91. d = mat[0*2+1] * di;
  92. mat[0*2+0] += mat[1*2+0] * d;
  93. return ( s != 0.0f && !FLOAT_IS_NAN( s ) );
  94. #endif
  95. }
  96. /*
  97. =============
  98. idMat2::ToString
  99. =============
  100. */
  101. const char *idMat2::ToString( int precision ) const {
  102. return idStr::FloatArrayToString( ToFloatPtr(), GetDimension(), precision );
  103. }
  104. //===============================================================
  105. //
  106. // idMat3
  107. //
  108. //===============================================================
  109. idMat3 mat3_zero( idVec3( 0, 0, 0 ), idVec3( 0, 0, 0 ), idVec3( 0, 0, 0 ) );
  110. idMat3 mat3_identity( idVec3( 1, 0, 0 ), idVec3( 0, 1, 0 ), idVec3( 0, 0, 1 ) );
  111. /*
  112. ============
  113. idMat3::ToAngles
  114. ============
  115. */
  116. idAngles idMat3::ToAngles( void ) const {
  117. idAngles angles;
  118. double theta;
  119. double cp;
  120. float sp;
  121. sp = mat[ 0 ][ 2 ];
  122. // cap off our sin value so that we don't get any NANs
  123. if ( sp > 1.0f ) {
  124. sp = 1.0f;
  125. } else if ( sp < -1.0f ) {
  126. sp = -1.0f;
  127. }
  128. theta = -asin( sp );
  129. cp = cos( theta );
  130. if ( cp > 8192.0f * idMath::FLT_EPSILON ) {
  131. angles.pitch = RAD2DEG( theta );
  132. angles.yaw = RAD2DEG( atan2( mat[ 0 ][ 1 ], mat[ 0 ][ 0 ] ) );
  133. angles.roll = RAD2DEG( atan2( mat[ 1 ][ 2 ], mat[ 2 ][ 2 ] ) );
  134. } else {
  135. angles.pitch = RAD2DEG( theta );
  136. angles.yaw = RAD2DEG( -atan2( mat[ 1 ][ 0 ], mat[ 1 ][ 1 ] ) );
  137. angles.roll = 0;
  138. }
  139. return angles;
  140. }
  141. /*
  142. ============
  143. idMat3::ToQuat
  144. ============
  145. */
  146. idQuat idMat3::ToQuat( void ) const {
  147. idQuat q;
  148. float trace;
  149. float s;
  150. float t;
  151. int i;
  152. int j;
  153. int k;
  154. static int next[ 3 ] = { 1, 2, 0 };
  155. trace = mat[ 0 ][ 0 ] + mat[ 1 ][ 1 ] + mat[ 2 ][ 2 ];
  156. if ( trace > 0.0f ) {
  157. t = trace + 1.0f;
  158. s = idMath::InvSqrt( t ) * 0.5f;
  159. q[3] = s * t;
  160. q[0] = ( mat[ 2 ][ 1 ] - mat[ 1 ][ 2 ] ) * s;
  161. q[1] = ( mat[ 0 ][ 2 ] - mat[ 2 ][ 0 ] ) * s;
  162. q[2] = ( mat[ 1 ][ 0 ] - mat[ 0 ][ 1 ] ) * s;
  163. } else {
  164. i = 0;
  165. if ( mat[ 1 ][ 1 ] > mat[ 0 ][ 0 ] ) {
  166. i = 1;
  167. }
  168. if ( mat[ 2 ][ 2 ] > mat[ i ][ i ] ) {
  169. i = 2;
  170. }
  171. j = next[ i ];
  172. k = next[ j ];
  173. t = ( mat[ i ][ i ] - ( mat[ j ][ j ] + mat[ k ][ k ] ) ) + 1.0f;
  174. s = idMath::InvSqrt( t ) * 0.5f;
  175. q[i] = s * t;
  176. q[3] = ( mat[ k ][ j ] - mat[ j ][ k ] ) * s;
  177. q[j] = ( mat[ j ][ i ] + mat[ i ][ j ] ) * s;
  178. q[k] = ( mat[ k ][ i ] + mat[ i ][ k ] ) * s;
  179. }
  180. return q;
  181. }
  182. /*
  183. ============
  184. idMat3::ToCQuat
  185. ============
  186. */
  187. idCQuat idMat3::ToCQuat( void ) const {
  188. idQuat q = ToQuat();
  189. if ( q.w < 0.0f ) {
  190. return idCQuat( -q.x, -q.y, -q.z );
  191. }
  192. return idCQuat( q.x, q.y, q.z );
  193. }
  194. /*
  195. ============
  196. idMat3::ToRotation
  197. ============
  198. */
  199. idRotation idMat3::ToRotation( void ) const {
  200. idRotation r;
  201. float trace;
  202. float s;
  203. float t;
  204. int i;
  205. int j;
  206. int k;
  207. static int next[ 3 ] = { 1, 2, 0 };
  208. trace = mat[ 0 ][ 0 ] + mat[ 1 ][ 1 ] + mat[ 2 ][ 2 ];
  209. if ( trace > 0.0f ) {
  210. t = trace + 1.0f;
  211. s = idMath::InvSqrt( t ) * 0.5f;
  212. r.angle = s * t;
  213. r.vec[0] = ( mat[ 2 ][ 1 ] - mat[ 1 ][ 2 ] ) * s;
  214. r.vec[1] = ( mat[ 0 ][ 2 ] - mat[ 2 ][ 0 ] ) * s;
  215. r.vec[2] = ( mat[ 1 ][ 0 ] - mat[ 0 ][ 1 ] ) * s;
  216. } else {
  217. i = 0;
  218. if ( mat[ 1 ][ 1 ] > mat[ 0 ][ 0 ] ) {
  219. i = 1;
  220. }
  221. if ( mat[ 2 ][ 2 ] > mat[ i ][ i ] ) {
  222. i = 2;
  223. }
  224. j = next[ i ];
  225. k = next[ j ];
  226. t = ( mat[ i ][ i ] - ( mat[ j ][ j ] + mat[ k ][ k ] ) ) + 1.0f;
  227. s = idMath::InvSqrt( t ) * 0.5f;
  228. r.vec[i] = s * t;
  229. r.angle = ( mat[ k ][ j ] - mat[ j ][ k ] ) * s;
  230. r.vec[j] = ( mat[ j ][ i ] + mat[ i ][ j ] ) * s;
  231. r.vec[k] = ( mat[ k ][ i ] + mat[ i ][ k ] ) * s;
  232. }
  233. r.angle = idMath::ACos( r.angle );
  234. if ( idMath::Fabs( r.angle ) < 1e-10f ) {
  235. r.vec.Set( 0.0f, 0.0f, 1.0f );
  236. r.angle = 0.0f;
  237. } else {
  238. //vec *= (1.0f / sin( angle ));
  239. r.vec.Normalize();
  240. r.vec.FixDegenerateNormal();
  241. r.angle *= 2.0f * idMath::M_RAD2DEG;
  242. }
  243. r.origin.Zero();
  244. r.axis = *this;
  245. r.axisValid = true;
  246. return r;
  247. }
  248. /*
  249. =================
  250. idMat3::ToAngularVelocity
  251. =================
  252. */
  253. idVec3 idMat3::ToAngularVelocity( void ) const {
  254. idRotation rotation = ToRotation();
  255. return rotation.GetVec() * DEG2RAD( rotation.GetAngle() );
  256. }
  257. /*
  258. ============
  259. idMat3::Determinant
  260. ============
  261. */
  262. float idMat3::Determinant( void ) const {
  263. float det2_12_01 = mat[1][0] * mat[2][1] - mat[1][1] * mat[2][0];
  264. float det2_12_02 = mat[1][0] * mat[2][2] - mat[1][2] * mat[2][0];
  265. float det2_12_12 = mat[1][1] * mat[2][2] - mat[1][2] * mat[2][1];
  266. return mat[0][0] * det2_12_12 - mat[0][1] * det2_12_02 + mat[0][2] * det2_12_01;
  267. }
  268. /*
  269. ============
  270. idMat3::InverseSelf
  271. ============
  272. */
  273. bool idMat3::InverseSelf( void ) {
  274. // 18+3+9 = 30 multiplications
  275. // 1 division
  276. idMat3 inverse;
  277. double det, invDet;
  278. inverse[0][0] = mat[1][1] * mat[2][2] - mat[1][2] * mat[2][1];
  279. inverse[1][0] = mat[1][2] * mat[2][0] - mat[1][0] * mat[2][2];
  280. inverse[2][0] = mat[1][0] * mat[2][1] - mat[1][1] * mat[2][0];
  281. det = mat[0][0] * inverse[0][0] + mat[0][1] * inverse[1][0] + mat[0][2] * inverse[2][0];
  282. if ( idMath::Fabs( det ) < MATRIX_INVERSE_EPSILON ) {
  283. return false;
  284. }
  285. invDet = 1.0f / det;
  286. inverse[0][1] = mat[0][2] * mat[2][1] - mat[0][1] * mat[2][2];
  287. inverse[0][2] = mat[0][1] * mat[1][2] - mat[0][2] * mat[1][1];
  288. inverse[1][1] = mat[0][0] * mat[2][2] - mat[0][2] * mat[2][0];
  289. inverse[1][2] = mat[0][2] * mat[1][0] - mat[0][0] * mat[1][2];
  290. inverse[2][1] = mat[0][1] * mat[2][0] - mat[0][0] * mat[2][1];
  291. inverse[2][2] = mat[0][0] * mat[1][1] - mat[0][1] * mat[1][0];
  292. mat[0][0] = inverse[0][0] * invDet;
  293. mat[0][1] = inverse[0][1] * invDet;
  294. mat[0][2] = inverse[0][2] * invDet;
  295. mat[1][0] = inverse[1][0] * invDet;
  296. mat[1][1] = inverse[1][1] * invDet;
  297. mat[1][2] = inverse[1][2] * invDet;
  298. mat[2][0] = inverse[2][0] * invDet;
  299. mat[2][1] = inverse[2][1] * invDet;
  300. mat[2][2] = inverse[2][2] * invDet;
  301. return true;
  302. }
  303. /*
  304. ============
  305. idMat3::InverseFastSelf
  306. ============
  307. */
  308. bool idMat3::InverseFastSelf( void ) {
  309. #if 1
  310. // 18+3+9 = 30 multiplications
  311. // 1 division
  312. idMat3 inverse;
  313. double det, invDet;
  314. inverse[0][0] = mat[1][1] * mat[2][2] - mat[1][2] * mat[2][1];
  315. inverse[1][0] = mat[1][2] * mat[2][0] - mat[1][0] * mat[2][2];
  316. inverse[2][0] = mat[1][0] * mat[2][1] - mat[1][1] * mat[2][0];
  317. det = mat[0][0] * inverse[0][0] + mat[0][1] * inverse[1][0] + mat[0][2] * inverse[2][0];
  318. if ( idMath::Fabs( det ) < MATRIX_INVERSE_EPSILON ) {
  319. return false;
  320. }
  321. invDet = 1.0f / det;
  322. inverse[0][1] = mat[0][2] * mat[2][1] - mat[0][1] * mat[2][2];
  323. inverse[0][2] = mat[0][1] * mat[1][2] - mat[0][2] * mat[1][1];
  324. inverse[1][1] = mat[0][0] * mat[2][2] - mat[0][2] * mat[2][0];
  325. inverse[1][2] = mat[0][2] * mat[1][0] - mat[0][0] * mat[1][2];
  326. inverse[2][1] = mat[0][1] * mat[2][0] - mat[0][0] * mat[2][1];
  327. inverse[2][2] = mat[0][0] * mat[1][1] - mat[0][1] * mat[1][0];
  328. mat[0][0] = inverse[0][0] * invDet;
  329. mat[0][1] = inverse[0][1] * invDet;
  330. mat[0][2] = inverse[0][2] * invDet;
  331. mat[1][0] = inverse[1][0] * invDet;
  332. mat[1][1] = inverse[1][1] * invDet;
  333. mat[1][2] = inverse[1][2] * invDet;
  334. mat[2][0] = inverse[2][0] * invDet;
  335. mat[2][1] = inverse[2][1] * invDet;
  336. mat[2][2] = inverse[2][2] * invDet;
  337. return true;
  338. #elif 0
  339. // 3*10 = 30 multiplications
  340. // 3 divisions
  341. float *mat = reinterpret_cast<float *>(this);
  342. float s;
  343. double d, di;
  344. di = mat[0];
  345. s = di;
  346. mat[0] = d = 1.0f / di;
  347. mat[1] *= d;
  348. mat[2] *= d;
  349. d = -d;
  350. mat[3] *= d;
  351. mat[6] *= d;
  352. d = mat[3] * di;
  353. mat[4] += mat[1] * d;
  354. mat[5] += mat[2] * d;
  355. d = mat[6] * di;
  356. mat[7] += mat[1] * d;
  357. mat[8] += mat[2] * d;
  358. di = mat[4];
  359. s *= di;
  360. mat[4] = d = 1.0f / di;
  361. mat[3] *= d;
  362. mat[5] *= d;
  363. d = -d;
  364. mat[1] *= d;
  365. mat[7] *= d;
  366. d = mat[1] * di;
  367. mat[0] += mat[3] * d;
  368. mat[2] += mat[5] * d;
  369. d = mat[7] * di;
  370. mat[6] += mat[3] * d;
  371. mat[8] += mat[5] * d;
  372. di = mat[8];
  373. s *= di;
  374. mat[8] = d = 1.0f / di;
  375. mat[6] *= d;
  376. mat[7] *= d;
  377. d = -d;
  378. mat[2] *= d;
  379. mat[5] *= d;
  380. d = mat[2] * di;
  381. mat[0] += mat[6] * d;
  382. mat[1] += mat[7] * d;
  383. d = mat[5] * di;
  384. mat[3] += mat[6] * d;
  385. mat[4] += mat[7] * d;
  386. return ( s != 0.0f && !FLOAT_IS_NAN( s ) );
  387. #else
  388. // 4*2+4*4 = 24 multiplications
  389. // 2*1 = 2 divisions
  390. idMat2 r0;
  391. float r1[2], r2[2], r3;
  392. float det, invDet;
  393. float *mat = reinterpret_cast<float *>(this);
  394. // r0 = m0.Inverse(); // 2x2
  395. det = mat[0*3+0] * mat[1*3+1] - mat[0*3+1] * mat[1*3+0];
  396. if ( idMath::Fabs( det ) < MATRIX_INVERSE_EPSILON ) {
  397. return false;
  398. }
  399. invDet = 1.0f / det;
  400. r0[0][0] = mat[1*3+1] * invDet;
  401. r0[0][1] = - mat[0*3+1] * invDet;
  402. r0[1][0] = - mat[1*3+0] * invDet;
  403. r0[1][1] = mat[0*3+0] * invDet;
  404. // r1 = r0 * m1; // 2x1 = 2x2 * 2x1
  405. r1[0] = r0[0][0] * mat[0*3+2] + r0[0][1] * mat[1*3+2];
  406. r1[1] = r0[1][0] * mat[0*3+2] + r0[1][1] * mat[1*3+2];
  407. // r2 = m2 * r1; // 1x1 = 1x2 * 2x1
  408. r2[0] = mat[2*3+0] * r1[0] + mat[2*3+1] * r1[1];
  409. // r3 = r2 - m3; // 1x1 = 1x1 - 1x1
  410. r3 = r2[0] - mat[2*3+2];
  411. // r3.InverseSelf();
  412. if ( idMath::Fabs( r3 ) < MATRIX_INVERSE_EPSILON ) {
  413. return false;
  414. }
  415. r3 = 1.0f / r3;
  416. // r2 = m2 * r0; // 1x2 = 1x2 * 2x2
  417. r2[0] = mat[2*3+0] * r0[0][0] + mat[2*3+1] * r0[1][0];
  418. r2[1] = mat[2*3+0] * r0[0][1] + mat[2*3+1] * r0[1][1];
  419. // m2 = r3 * r2; // 1x2 = 1x1 * 1x2
  420. mat[2*3+0] = r3 * r2[0];
  421. mat[2*3+1] = r3 * r2[1];
  422. // m0 = r0 - r1 * m2; // 2x2 - 2x1 * 1x2
  423. mat[0*3+0] = r0[0][0] - r1[0] * mat[2*3+0];
  424. mat[0*3+1] = r0[0][1] - r1[0] * mat[2*3+1];
  425. mat[1*3+0] = r0[1][0] - r1[1] * mat[2*3+0];
  426. mat[1*3+1] = r0[1][1] - r1[1] * mat[2*3+1];
  427. // m1 = r1 * r3; // 2x1 = 2x1 * 1x1
  428. mat[0*3+2] = r1[0] * r3;
  429. mat[1*3+2] = r1[1] * r3;
  430. // m3 = -r3;
  431. mat[2*3+2] = -r3;
  432. return true;
  433. #endif
  434. }
  435. /*
  436. ============
  437. idMat3::InertiaTranslate
  438. ============
  439. */
  440. idMat3 idMat3::InertiaTranslate( const float mass, const idVec3 &centerOfMass, const idVec3 &translation ) const {
  441. idMat3 m;
  442. idVec3 newCenter;
  443. newCenter = centerOfMass + translation;
  444. m[0][0] = mass * ( ( centerOfMass[1] * centerOfMass[1] + centerOfMass[2] * centerOfMass[2] )
  445. - ( newCenter[1] * newCenter[1] + newCenter[2] * newCenter[2] ) );
  446. m[1][1] = mass * ( ( centerOfMass[0] * centerOfMass[0] + centerOfMass[2] * centerOfMass[2] )
  447. - ( newCenter[0] * newCenter[0] + newCenter[2] * newCenter[2] ) );
  448. m[2][2] = mass * ( ( centerOfMass[0] * centerOfMass[0] + centerOfMass[1] * centerOfMass[1] )
  449. - ( newCenter[0] * newCenter[0] + newCenter[1] * newCenter[1] ) );
  450. m[0][1] = m[1][0] = mass * ( newCenter[0] * newCenter[1] - centerOfMass[0] * centerOfMass[1] );
  451. m[1][2] = m[2][1] = mass * ( newCenter[1] * newCenter[2] - centerOfMass[1] * centerOfMass[2] );
  452. m[0][2] = m[2][0] = mass * ( newCenter[0] * newCenter[2] - centerOfMass[0] * centerOfMass[2] );
  453. return (*this) + m;
  454. }
  455. /*
  456. ============
  457. idMat3::InertiaTranslateSelf
  458. ============
  459. */
  460. idMat3 &idMat3::InertiaTranslateSelf( const float mass, const idVec3 &centerOfMass, const idVec3 &translation ) {
  461. idMat3 m;
  462. idVec3 newCenter;
  463. newCenter = centerOfMass + translation;
  464. m[0][0] = mass * ( ( centerOfMass[1] * centerOfMass[1] + centerOfMass[2] * centerOfMass[2] )
  465. - ( newCenter[1] * newCenter[1] + newCenter[2] * newCenter[2] ) );
  466. m[1][1] = mass * ( ( centerOfMass[0] * centerOfMass[0] + centerOfMass[2] * centerOfMass[2] )
  467. - ( newCenter[0] * newCenter[0] + newCenter[2] * newCenter[2] ) );
  468. m[2][2] = mass * ( ( centerOfMass[0] * centerOfMass[0] + centerOfMass[1] * centerOfMass[1] )
  469. - ( newCenter[0] * newCenter[0] + newCenter[1] * newCenter[1] ) );
  470. m[0][1] = m[1][0] = mass * ( newCenter[0] * newCenter[1] - centerOfMass[0] * centerOfMass[1] );
  471. m[1][2] = m[2][1] = mass * ( newCenter[1] * newCenter[2] - centerOfMass[1] * centerOfMass[2] );
  472. m[0][2] = m[2][0] = mass * ( newCenter[0] * newCenter[2] - centerOfMass[0] * centerOfMass[2] );
  473. (*this) += m;
  474. return (*this);
  475. }
  476. /*
  477. ============
  478. idMat3::InertiaRotate
  479. ============
  480. */
  481. idMat3 idMat3::InertiaRotate( const idMat3 &rotation ) const {
  482. // NOTE: the rotation matrix is stored column-major
  483. return rotation.Transpose() * (*this) * rotation;
  484. }
  485. /*
  486. ============
  487. idMat3::InertiaRotateSelf
  488. ============
  489. */
  490. idMat3 &idMat3::InertiaRotateSelf( const idMat3 &rotation ) {
  491. // NOTE: the rotation matrix is stored column-major
  492. *this = rotation.Transpose() * (*this) * rotation;
  493. return *this;
  494. }
  495. /*
  496. =============
  497. idMat3::ToString
  498. =============
  499. */
  500. const char *idMat3::ToString( int precision ) const {
  501. return idStr::FloatArrayToString( ToFloatPtr(), GetDimension(), precision );
  502. }
  503. //===============================================================
  504. //
  505. // idMat4
  506. //
  507. //===============================================================
  508. idMat4 mat4_zero( idVec4( 0, 0, 0, 0 ), idVec4( 0, 0, 0, 0 ), idVec4( 0, 0, 0, 0 ), idVec4( 0, 0, 0, 0 ) );
  509. idMat4 mat4_identity( idVec4( 1, 0, 0, 0 ), idVec4( 0, 1, 0, 0 ), idVec4( 0, 0, 1, 0 ), idVec4( 0, 0, 0, 1 ) );
  510. /*
  511. ============
  512. idMat4::Transpose
  513. ============
  514. */
  515. idMat4 idMat4::Transpose( void ) const {
  516. idMat4 transpose;
  517. int i, j;
  518. for( i = 0; i < 4; i++ ) {
  519. for( j = 0; j < 4; j++ ) {
  520. transpose[ i ][ j ] = mat[ j ][ i ];
  521. }
  522. }
  523. return transpose;
  524. }
  525. /*
  526. ============
  527. idMat4::TransposeSelf
  528. ============
  529. */
  530. idMat4 &idMat4::TransposeSelf( void ) {
  531. float temp;
  532. int i, j;
  533. for( i = 0; i < 4; i++ ) {
  534. for( j = i + 1; j < 4; j++ ) {
  535. temp = mat[ i ][ j ];
  536. mat[ i ][ j ] = mat[ j ][ i ];
  537. mat[ j ][ i ] = temp;
  538. }
  539. }
  540. return *this;
  541. }
  542. /*
  543. ============
  544. idMat4::Determinant
  545. ============
  546. */
  547. float idMat4::Determinant( void ) const {
  548. // 2x2 sub-determinants
  549. float det2_01_01 = mat[0][0] * mat[1][1] - mat[0][1] * mat[1][0];
  550. float det2_01_02 = mat[0][0] * mat[1][2] - mat[0][2] * mat[1][0];
  551. float det2_01_03 = mat[0][0] * mat[1][3] - mat[0][3] * mat[1][0];
  552. float det2_01_12 = mat[0][1] * mat[1][2] - mat[0][2] * mat[1][1];
  553. float det2_01_13 = mat[0][1] * mat[1][3] - mat[0][3] * mat[1][1];
  554. float det2_01_23 = mat[0][2] * mat[1][3] - mat[0][3] * mat[1][2];
  555. // 3x3 sub-determinants
  556. float det3_201_012 = mat[2][0] * det2_01_12 - mat[2][1] * det2_01_02 + mat[2][2] * det2_01_01;
  557. float det3_201_013 = mat[2][0] * det2_01_13 - mat[2][1] * det2_01_03 + mat[2][3] * det2_01_01;
  558. float det3_201_023 = mat[2][0] * det2_01_23 - mat[2][2] * det2_01_03 + mat[2][3] * det2_01_02;
  559. float det3_201_123 = mat[2][1] * det2_01_23 - mat[2][2] * det2_01_13 + mat[2][3] * det2_01_12;
  560. return ( - det3_201_123 * mat[3][0] + det3_201_023 * mat[3][1] - det3_201_013 * mat[3][2] + det3_201_012 * mat[3][3] );
  561. }
  562. /*
  563. ============
  564. idMat4::InverseSelf
  565. ============
  566. */
  567. bool idMat4::InverseSelf( void ) {
  568. // 84+4+16 = 104 multiplications
  569. // 1 division
  570. double det, invDet;
  571. // 2x2 sub-determinants required to calculate 4x4 determinant
  572. float det2_01_01 = mat[0][0] * mat[1][1] - mat[0][1] * mat[1][0];
  573. float det2_01_02 = mat[0][0] * mat[1][2] - mat[0][2] * mat[1][0];
  574. float det2_01_03 = mat[0][0] * mat[1][3] - mat[0][3] * mat[1][0];
  575. float det2_01_12 = mat[0][1] * mat[1][2] - mat[0][2] * mat[1][1];
  576. float det2_01_13 = mat[0][1] * mat[1][3] - mat[0][3] * mat[1][1];
  577. float det2_01_23 = mat[0][2] * mat[1][3] - mat[0][3] * mat[1][2];
  578. // 3x3 sub-determinants required to calculate 4x4 determinant
  579. float det3_201_012 = mat[2][0] * det2_01_12 - mat[2][1] * det2_01_02 + mat[2][2] * det2_01_01;
  580. float det3_201_013 = mat[2][0] * det2_01_13 - mat[2][1] * det2_01_03 + mat[2][3] * det2_01_01;
  581. float det3_201_023 = mat[2][0] * det2_01_23 - mat[2][2] * det2_01_03 + mat[2][3] * det2_01_02;
  582. float det3_201_123 = mat[2][1] * det2_01_23 - mat[2][2] * det2_01_13 + mat[2][3] * det2_01_12;
  583. det = ( - det3_201_123 * mat[3][0] + det3_201_023 * mat[3][1] - det3_201_013 * mat[3][2] + det3_201_012 * mat[3][3] );
  584. if ( idMath::Fabs( det ) < MATRIX_INVERSE_EPSILON ) {
  585. return false;
  586. }
  587. invDet = 1.0f / det;
  588. // remaining 2x2 sub-determinants
  589. float det2_03_01 = mat[0][0] * mat[3][1] - mat[0][1] * mat[3][0];
  590. float det2_03_02 = mat[0][0] * mat[3][2] - mat[0][2] * mat[3][0];
  591. float det2_03_03 = mat[0][0] * mat[3][3] - mat[0][3] * mat[3][0];
  592. float det2_03_12 = mat[0][1] * mat[3][2] - mat[0][2] * mat[3][1];
  593. float det2_03_13 = mat[0][1] * mat[3][3] - mat[0][3] * mat[3][1];
  594. float det2_03_23 = mat[0][2] * mat[3][3] - mat[0][3] * mat[3][2];
  595. float det2_13_01 = mat[1][0] * mat[3][1] - mat[1][1] * mat[3][0];
  596. float det2_13_02 = mat[1][0] * mat[3][2] - mat[1][2] * mat[3][0];
  597. float det2_13_03 = mat[1][0] * mat[3][3] - mat[1][3] * mat[3][0];
  598. float det2_13_12 = mat[1][1] * mat[3][2] - mat[1][2] * mat[3][1];
  599. float det2_13_13 = mat[1][1] * mat[3][3] - mat[1][3] * mat[3][1];
  600. float det2_13_23 = mat[1][2] * mat[3][3] - mat[1][3] * mat[3][2];
  601. // remaining 3x3 sub-determinants
  602. float det3_203_012 = mat[2][0] * det2_03_12 - mat[2][1] * det2_03_02 + mat[2][2] * det2_03_01;
  603. float det3_203_013 = mat[2][0] * det2_03_13 - mat[2][1] * det2_03_03 + mat[2][3] * det2_03_01;
  604. float det3_203_023 = mat[2][0] * det2_03_23 - mat[2][2] * det2_03_03 + mat[2][3] * det2_03_02;
  605. float det3_203_123 = mat[2][1] * det2_03_23 - mat[2][2] * det2_03_13 + mat[2][3] * det2_03_12;
  606. float det3_213_012 = mat[2][0] * det2_13_12 - mat[2][1] * det2_13_02 + mat[2][2] * det2_13_01;
  607. float det3_213_013 = mat[2][0] * det2_13_13 - mat[2][1] * det2_13_03 + mat[2][3] * det2_13_01;
  608. float det3_213_023 = mat[2][0] * det2_13_23 - mat[2][2] * det2_13_03 + mat[2][3] * det2_13_02;
  609. float det3_213_123 = mat[2][1] * det2_13_23 - mat[2][2] * det2_13_13 + mat[2][3] * det2_13_12;
  610. float det3_301_012 = mat[3][0] * det2_01_12 - mat[3][1] * det2_01_02 + mat[3][2] * det2_01_01;
  611. float det3_301_013 = mat[3][0] * det2_01_13 - mat[3][1] * det2_01_03 + mat[3][3] * det2_01_01;
  612. float det3_301_023 = mat[3][0] * det2_01_23 - mat[3][2] * det2_01_03 + mat[3][3] * det2_01_02;
  613. float det3_301_123 = mat[3][1] * det2_01_23 - mat[3][2] * det2_01_13 + mat[3][3] * det2_01_12;
  614. mat[0][0] = - det3_213_123 * invDet;
  615. mat[1][0] = + det3_213_023 * invDet;
  616. mat[2][0] = - det3_213_013 * invDet;
  617. mat[3][0] = + det3_213_012 * invDet;
  618. mat[0][1] = + det3_203_123 * invDet;
  619. mat[1][1] = - det3_203_023 * invDet;
  620. mat[2][1] = + det3_203_013 * invDet;
  621. mat[3][1] = - det3_203_012 * invDet;
  622. mat[0][2] = + det3_301_123 * invDet;
  623. mat[1][2] = - det3_301_023 * invDet;
  624. mat[2][2] = + det3_301_013 * invDet;
  625. mat[3][2] = - det3_301_012 * invDet;
  626. mat[0][3] = - det3_201_123 * invDet;
  627. mat[1][3] = + det3_201_023 * invDet;
  628. mat[2][3] = - det3_201_013 * invDet;
  629. mat[3][3] = + det3_201_012 * invDet;
  630. return true;
  631. }
  632. /*
  633. ============
  634. idMat4::InverseFastSelf
  635. ============
  636. */
  637. bool idMat4::InverseFastSelf( void ) {
  638. #if 0
  639. // 84+4+16 = 104 multiplications
  640. // 1 division
  641. double det, invDet;
  642. // 2x2 sub-determinants required to calculate 4x4 determinant
  643. float det2_01_01 = mat[0][0] * mat[1][1] - mat[0][1] * mat[1][0];
  644. float det2_01_02 = mat[0][0] * mat[1][2] - mat[0][2] * mat[1][0];
  645. float det2_01_03 = mat[0][0] * mat[1][3] - mat[0][3] * mat[1][0];
  646. float det2_01_12 = mat[0][1] * mat[1][2] - mat[0][2] * mat[1][1];
  647. float det2_01_13 = mat[0][1] * mat[1][3] - mat[0][3] * mat[1][1];
  648. float det2_01_23 = mat[0][2] * mat[1][3] - mat[0][3] * mat[1][2];
  649. // 3x3 sub-determinants required to calculate 4x4 determinant
  650. float det3_201_012 = mat[2][0] * det2_01_12 - mat[2][1] * det2_01_02 + mat[2][2] * det2_01_01;
  651. float det3_201_013 = mat[2][0] * det2_01_13 - mat[2][1] * det2_01_03 + mat[2][3] * det2_01_01;
  652. float det3_201_023 = mat[2][0] * det2_01_23 - mat[2][2] * det2_01_03 + mat[2][3] * det2_01_02;
  653. float det3_201_123 = mat[2][1] * det2_01_23 - mat[2][2] * det2_01_13 + mat[2][3] * det2_01_12;
  654. det = ( - det3_201_123 * mat[3][0] + det3_201_023 * mat[3][1] - det3_201_013 * mat[3][2] + det3_201_012 * mat[3][3] );
  655. if ( idMath::Fabs( det ) < MATRIX_INVERSE_EPSILON ) {
  656. return false;
  657. }
  658. invDet = 1.0f / det;
  659. // remaining 2x2 sub-determinants
  660. float det2_03_01 = mat[0][0] * mat[3][1] - mat[0][1] * mat[3][0];
  661. float det2_03_02 = mat[0][0] * mat[3][2] - mat[0][2] * mat[3][0];
  662. float det2_03_03 = mat[0][0] * mat[3][3] - mat[0][3] * mat[3][0];
  663. float det2_03_12 = mat[0][1] * mat[3][2] - mat[0][2] * mat[3][1];
  664. float det2_03_13 = mat[0][1] * mat[3][3] - mat[0][3] * mat[3][1];
  665. float det2_03_23 = mat[0][2] * mat[3][3] - mat[0][3] * mat[3][2];
  666. float det2_13_01 = mat[1][0] * mat[3][1] - mat[1][1] * mat[3][0];
  667. float det2_13_02 = mat[1][0] * mat[3][2] - mat[1][2] * mat[3][0];
  668. float det2_13_03 = mat[1][0] * mat[3][3] - mat[1][3] * mat[3][0];
  669. float det2_13_12 = mat[1][1] * mat[3][2] - mat[1][2] * mat[3][1];
  670. float det2_13_13 = mat[1][1] * mat[3][3] - mat[1][3] * mat[3][1];
  671. float det2_13_23 = mat[1][2] * mat[3][3] - mat[1][3] * mat[3][2];
  672. // remaining 3x3 sub-determinants
  673. float det3_203_012 = mat[2][0] * det2_03_12 - mat[2][1] * det2_03_02 + mat[2][2] * det2_03_01;
  674. float det3_203_013 = mat[2][0] * det2_03_13 - mat[2][1] * det2_03_03 + mat[2][3] * det2_03_01;
  675. float det3_203_023 = mat[2][0] * det2_03_23 - mat[2][2] * det2_03_03 + mat[2][3] * det2_03_02;
  676. float det3_203_123 = mat[2][1] * det2_03_23 - mat[2][2] * det2_03_13 + mat[2][3] * det2_03_12;
  677. float det3_213_012 = mat[2][0] * det2_13_12 - mat[2][1] * det2_13_02 + mat[2][2] * det2_13_01;
  678. float det3_213_013 = mat[2][0] * det2_13_13 - mat[2][1] * det2_13_03 + mat[2][3] * det2_13_01;
  679. float det3_213_023 = mat[2][0] * det2_13_23 - mat[2][2] * det2_13_03 + mat[2][3] * det2_13_02;
  680. float det3_213_123 = mat[2][1] * det2_13_23 - mat[2][2] * det2_13_13 + mat[2][3] * det2_13_12;
  681. float det3_301_012 = mat[3][0] * det2_01_12 - mat[3][1] * det2_01_02 + mat[3][2] * det2_01_01;
  682. float det3_301_013 = mat[3][0] * det2_01_13 - mat[3][1] * det2_01_03 + mat[3][3] * det2_01_01;
  683. float det3_301_023 = mat[3][0] * det2_01_23 - mat[3][2] * det2_01_03 + mat[3][3] * det2_01_02;
  684. float det3_301_123 = mat[3][1] * det2_01_23 - mat[3][2] * det2_01_13 + mat[3][3] * det2_01_12;
  685. mat[0][0] = - det3_213_123 * invDet;
  686. mat[1][0] = + det3_213_023 * invDet;
  687. mat[2][0] = - det3_213_013 * invDet;
  688. mat[3][0] = + det3_213_012 * invDet;
  689. mat[0][1] = + det3_203_123 * invDet;
  690. mat[1][1] = - det3_203_023 * invDet;
  691. mat[2][1] = + det3_203_013 * invDet;
  692. mat[3][1] = - det3_203_012 * invDet;
  693. mat[0][2] = + det3_301_123 * invDet;
  694. mat[1][2] = - det3_301_023 * invDet;
  695. mat[2][2] = + det3_301_013 * invDet;
  696. mat[3][2] = - det3_301_012 * invDet;
  697. mat[0][3] = - det3_201_123 * invDet;
  698. mat[1][3] = + det3_201_023 * invDet;
  699. mat[2][3] = - det3_201_013 * invDet;
  700. mat[3][3] = + det3_201_012 * invDet;
  701. return true;
  702. #elif 0
  703. // 4*18 = 72 multiplications
  704. // 4 divisions
  705. float *mat = reinterpret_cast<float *>(this);
  706. float s;
  707. double d, di;
  708. di = mat[0];
  709. s = di;
  710. mat[0] = d = 1.0f / di;
  711. mat[1] *= d;
  712. mat[2] *= d;
  713. mat[3] *= d;
  714. d = -d;
  715. mat[4] *= d;
  716. mat[8] *= d;
  717. mat[12] *= d;
  718. d = mat[4] * di;
  719. mat[5] += mat[1] * d;
  720. mat[6] += mat[2] * d;
  721. mat[7] += mat[3] * d;
  722. d = mat[8] * di;
  723. mat[9] += mat[1] * d;
  724. mat[10] += mat[2] * d;
  725. mat[11] += mat[3] * d;
  726. d = mat[12] * di;
  727. mat[13] += mat[1] * d;
  728. mat[14] += mat[2] * d;
  729. mat[15] += mat[3] * d;
  730. di = mat[5];
  731. s *= di;
  732. mat[5] = d = 1.0f / di;
  733. mat[4] *= d;
  734. mat[6] *= d;
  735. mat[7] *= d;
  736. d = -d;
  737. mat[1] *= d;
  738. mat[9] *= d;
  739. mat[13] *= d;
  740. d = mat[1] * di;
  741. mat[0] += mat[4] * d;
  742. mat[2] += mat[6] * d;
  743. mat[3] += mat[7] * d;
  744. d = mat[9] * di;
  745. mat[8] += mat[4] * d;
  746. mat[10] += mat[6] * d;
  747. mat[11] += mat[7] * d;
  748. d = mat[13] * di;
  749. mat[12] += mat[4] * d;
  750. mat[14] += mat[6] * d;
  751. mat[15] += mat[7] * d;
  752. di = mat[10];
  753. s *= di;
  754. mat[10] = d = 1.0f / di;
  755. mat[8] *= d;
  756. mat[9] *= d;
  757. mat[11] *= d;
  758. d = -d;
  759. mat[2] *= d;
  760. mat[6] *= d;
  761. mat[14] *= d;
  762. d = mat[2] * di;
  763. mat[0] += mat[8] * d;
  764. mat[1] += mat[9] * d;
  765. mat[3] += mat[11] * d;
  766. d = mat[6] * di;
  767. mat[4] += mat[8] * d;
  768. mat[5] += mat[9] * d;
  769. mat[7] += mat[11] * d;
  770. d = mat[14] * di;
  771. mat[12] += mat[8] * d;
  772. mat[13] += mat[9] * d;
  773. mat[15] += mat[11] * d;
  774. di = mat[15];
  775. s *= di;
  776. mat[15] = d = 1.0f / di;
  777. mat[12] *= d;
  778. mat[13] *= d;
  779. mat[14] *= d;
  780. d = -d;
  781. mat[3] *= d;
  782. mat[7] *= d;
  783. mat[11] *= d;
  784. d = mat[3] * di;
  785. mat[0] += mat[12] * d;
  786. mat[1] += mat[13] * d;
  787. mat[2] += mat[14] * d;
  788. d = mat[7] * di;
  789. mat[4] += mat[12] * d;
  790. mat[5] += mat[13] * d;
  791. mat[6] += mat[14] * d;
  792. d = mat[11] * di;
  793. mat[8] += mat[12] * d;
  794. mat[9] += mat[13] * d;
  795. mat[10] += mat[14] * d;
  796. return ( s != 0.0f && !FLOAT_IS_NAN( s ) );
  797. #else
  798. // 6*8+2*6 = 60 multiplications
  799. // 2*1 = 2 divisions
  800. idMat2 r0, r1, r2, r3;
  801. float a, det, invDet;
  802. float *mat = reinterpret_cast<float *>(this);
  803. // r0 = m0.Inverse();
  804. det = mat[0*4+0] * mat[1*4+1] - mat[0*4+1] * mat[1*4+0];
  805. if ( idMath::Fabs( det ) < MATRIX_INVERSE_EPSILON ) {
  806. return false;
  807. }
  808. invDet = 1.0f / det;
  809. r0[0][0] = mat[1*4+1] * invDet;
  810. r0[0][1] = - mat[0*4+1] * invDet;
  811. r0[1][0] = - mat[1*4+0] * invDet;
  812. r0[1][1] = mat[0*4+0] * invDet;
  813. // r1 = r0 * m1;
  814. r1[0][0] = r0[0][0] * mat[0*4+2] + r0[0][1] * mat[1*4+2];
  815. r1[0][1] = r0[0][0] * mat[0*4+3] + r0[0][1] * mat[1*4+3];
  816. r1[1][0] = r0[1][0] * mat[0*4+2] + r0[1][1] * mat[1*4+2];
  817. r1[1][1] = r0[1][0] * mat[0*4+3] + r0[1][1] * mat[1*4+3];
  818. // r2 = m2 * r1;
  819. r2[0][0] = mat[2*4+0] * r1[0][0] + mat[2*4+1] * r1[1][0];
  820. r2[0][1] = mat[2*4+0] * r1[0][1] + mat[2*4+1] * r1[1][1];
  821. r2[1][0] = mat[3*4+0] * r1[0][0] + mat[3*4+1] * r1[1][0];
  822. r2[1][1] = mat[3*4+0] * r1[0][1] + mat[3*4+1] * r1[1][1];
  823. // r3 = r2 - m3;
  824. r3[0][0] = r2[0][0] - mat[2*4+2];
  825. r3[0][1] = r2[0][1] - mat[2*4+3];
  826. r3[1][0] = r2[1][0] - mat[3*4+2];
  827. r3[1][1] = r2[1][1] - mat[3*4+3];
  828. // r3.InverseSelf();
  829. det = r3[0][0] * r3[1][1] - r3[0][1] * r3[1][0];
  830. if ( idMath::Fabs( det ) < MATRIX_INVERSE_EPSILON ) {
  831. return false;
  832. }
  833. invDet = 1.0f / det;
  834. a = r3[0][0];
  835. r3[0][0] = r3[1][1] * invDet;
  836. r3[0][1] = - r3[0][1] * invDet;
  837. r3[1][0] = - r3[1][0] * invDet;
  838. r3[1][1] = a * invDet;
  839. // r2 = m2 * r0;
  840. r2[0][0] = mat[2*4+0] * r0[0][0] + mat[2*4+1] * r0[1][0];
  841. r2[0][1] = mat[2*4+0] * r0[0][1] + mat[2*4+1] * r0[1][1];
  842. r2[1][0] = mat[3*4+0] * r0[0][0] + mat[3*4+1] * r0[1][0];
  843. r2[1][1] = mat[3*4+0] * r0[0][1] + mat[3*4+1] * r0[1][1];
  844. // m2 = r3 * r2;
  845. mat[2*4+0] = r3[0][0] * r2[0][0] + r3[0][1] * r2[1][0];
  846. mat[2*4+1] = r3[0][0] * r2[0][1] + r3[0][1] * r2[1][1];
  847. mat[3*4+0] = r3[1][0] * r2[0][0] + r3[1][1] * r2[1][0];
  848. mat[3*4+1] = r3[1][0] * r2[0][1] + r3[1][1] * r2[1][1];
  849. // m0 = r0 - r1 * m2;
  850. mat[0*4+0] = r0[0][0] - r1[0][0] * mat[2*4+0] - r1[0][1] * mat[3*4+0];
  851. mat[0*4+1] = r0[0][1] - r1[0][0] * mat[2*4+1] - r1[0][1] * mat[3*4+1];
  852. mat[1*4+0] = r0[1][0] - r1[1][0] * mat[2*4+0] - r1[1][1] * mat[3*4+0];
  853. mat[1*4+1] = r0[1][1] - r1[1][0] * mat[2*4+1] - r1[1][1] * mat[3*4+1];
  854. // m1 = r1 * r3;
  855. mat[0*4+2] = r1[0][0] * r3[0][0] + r1[0][1] * r3[1][0];
  856. mat[0*4+3] = r1[0][0] * r3[0][1] + r1[0][1] * r3[1][1];
  857. mat[1*4+2] = r1[1][0] * r3[0][0] + r1[1][1] * r3[1][0];
  858. mat[1*4+3] = r1[1][0] * r3[0][1] + r1[1][1] * r3[1][1];
  859. // m3 = -r3;
  860. mat[2*4+2] = -r3[0][0];
  861. mat[2*4+3] = -r3[0][1];
  862. mat[3*4+2] = -r3[1][0];
  863. mat[3*4+3] = -r3[1][1];
  864. return true;
  865. #endif
  866. }
  867. /*
  868. =============
  869. idMat4::ToString
  870. =============
  871. */
  872. const char *idMat4::ToString( int precision ) const {
  873. return idStr::FloatArrayToString( ToFloatPtr(), GetDimension(), precision );
  874. }
  875. //===============================================================
  876. //
  877. // idMat5
  878. //
  879. //===============================================================
  880. idMat5 mat5_zero( idVec5( 0, 0, 0, 0, 0 ), idVec5( 0, 0, 0, 0, 0 ), idVec5( 0, 0, 0, 0, 0 ), idVec5( 0, 0, 0, 0, 0 ), idVec5( 0, 0, 0, 0, 0 ) );
  881. idMat5 mat5_identity( idVec5( 1, 0, 0, 0, 0 ), idVec5( 0, 1, 0, 0, 0 ), idVec5( 0, 0, 1, 0, 0 ), idVec5( 0, 0, 0, 1, 0 ), idVec5( 0, 0, 0, 0, 1 ) );
  882. /*
  883. ============
  884. idMat5::Transpose
  885. ============
  886. */
  887. idMat5 idMat5::Transpose( void ) const {
  888. idMat5 transpose;
  889. int i, j;
  890. for( i = 0; i < 5; i++ ) {
  891. for( j = 0; j < 5; j++ ) {
  892. transpose[ i ][ j ] = mat[ j ][ i ];
  893. }
  894. }
  895. return transpose;
  896. }
  897. /*
  898. ============
  899. idMat5::TransposeSelf
  900. ============
  901. */
  902. idMat5 &idMat5::TransposeSelf( void ) {
  903. float temp;
  904. int i, j;
  905. for( i = 0; i < 5; i++ ) {
  906. for( j = i + 1; j < 5; j++ ) {
  907. temp = mat[ i ][ j ];
  908. mat[ i ][ j ] = mat[ j ][ i ];
  909. mat[ j ][ i ] = temp;
  910. }
  911. }
  912. return *this;
  913. }
  914. /*
  915. ============
  916. idMat5::Determinant
  917. ============
  918. */
  919. float idMat5::Determinant( void ) const {
  920. // 2x2 sub-determinants required to calculate 5x5 determinant
  921. float det2_34_01 = mat[3][0] * mat[4][1] - mat[3][1] * mat[4][0];
  922. float det2_34_02 = mat[3][0] * mat[4][2] - mat[3][2] * mat[4][0];
  923. float det2_34_03 = mat[3][0] * mat[4][3] - mat[3][3] * mat[4][0];
  924. float det2_34_04 = mat[3][0] * mat[4][4] - mat[3][4] * mat[4][0];
  925. float det2_34_12 = mat[3][1] * mat[4][2] - mat[3][2] * mat[4][1];
  926. float det2_34_13 = mat[3][1] * mat[4][3] - mat[3][3] * mat[4][1];
  927. float det2_34_14 = mat[3][1] * mat[4][4] - mat[3][4] * mat[4][1];
  928. float det2_34_23 = mat[3][2] * mat[4][3] - mat[3][3] * mat[4][2];
  929. float det2_34_24 = mat[3][2] * mat[4][4] - mat[3][4] * mat[4][2];
  930. float det2_34_34 = mat[3][3] * mat[4][4] - mat[3][4] * mat[4][3];
  931. // 3x3 sub-determinants required to calculate 5x5 determinant
  932. float det3_234_012 = mat[2][0] * det2_34_12 - mat[2][1] * det2_34_02 + mat[2][2] * det2_34_01;
  933. float det3_234_013 = mat[2][0] * det2_34_13 - mat[2][1] * det2_34_03 + mat[2][3] * det2_34_01;
  934. float det3_234_014 = mat[2][0] * det2_34_14 - mat[2][1] * det2_34_04 + mat[2][4] * det2_34_01;
  935. float det3_234_023 = mat[2][0] * det2_34_23 - mat[2][2] * det2_34_03 + mat[2][3] * det2_34_02;
  936. float det3_234_024 = mat[2][0] * det2_34_24 - mat[2][2] * det2_34_04 + mat[2][4] * det2_34_02;
  937. float det3_234_034 = mat[2][0] * det2_34_34 - mat[2][3] * det2_34_04 + mat[2][4] * det2_34_03;
  938. float det3_234_123 = mat[2][1] * det2_34_23 - mat[2][2] * det2_34_13 + mat[2][3] * det2_34_12;
  939. float det3_234_124 = mat[2][1] * det2_34_24 - mat[2][2] * det2_34_14 + mat[2][4] * det2_34_12;
  940. float det3_234_134 = mat[2][1] * det2_34_34 - mat[2][3] * det2_34_14 + mat[2][4] * det2_34_13;
  941. float det3_234_234 = mat[2][2] * det2_34_34 - mat[2][3] * det2_34_24 + mat[2][4] * det2_34_23;
  942. // 4x4 sub-determinants required to calculate 5x5 determinant
  943. float det4_1234_0123 = mat[1][0] * det3_234_123 - mat[1][1] * det3_234_023 + mat[1][2] * det3_234_013 - mat[1][3] * det3_234_012;
  944. float det4_1234_0124 = mat[1][0] * det3_234_124 - mat[1][1] * det3_234_024 + mat[1][2] * det3_234_014 - mat[1][4] * det3_234_012;
  945. float det4_1234_0134 = mat[1][0] * det3_234_134 - mat[1][1] * det3_234_034 + mat[1][3] * det3_234_014 - mat[1][4] * det3_234_013;
  946. float det4_1234_0234 = mat[1][0] * det3_234_234 - mat[1][2] * det3_234_034 + mat[1][3] * det3_234_024 - mat[1][4] * det3_234_023;
  947. float det4_1234_1234 = mat[1][1] * det3_234_234 - mat[1][2] * det3_234_134 + mat[1][3] * det3_234_124 - mat[1][4] * det3_234_123;
  948. // determinant of 5x5 matrix
  949. return mat[0][0] * det4_1234_1234 - mat[0][1] * det4_1234_0234 + mat[0][2] * det4_1234_0134 - mat[0][3] * det4_1234_0124 + mat[0][4] * det4_1234_0123;
  950. }
  951. /*
  952. ============
  953. idMat5::InverseSelf
  954. ============
  955. */
  956. bool idMat5::InverseSelf( void ) {
  957. // 280+5+25 = 310 multiplications
  958. // 1 division
  959. double det, invDet;
  960. // 2x2 sub-determinants required to calculate 5x5 determinant
  961. float det2_34_01 = mat[3][0] * mat[4][1] - mat[3][1] * mat[4][0];
  962. float det2_34_02 = mat[3][0] * mat[4][2] - mat[3][2] * mat[4][0];
  963. float det2_34_03 = mat[3][0] * mat[4][3] - mat[3][3] * mat[4][0];
  964. float det2_34_04 = mat[3][0] * mat[4][4] - mat[3][4] * mat[4][0];
  965. float det2_34_12 = mat[3][1] * mat[4][2] - mat[3][2] * mat[4][1];
  966. float det2_34_13 = mat[3][1] * mat[4][3] - mat[3][3] * mat[4][1];
  967. float det2_34_14 = mat[3][1] * mat[4][4] - mat[3][4] * mat[4][1];
  968. float det2_34_23 = mat[3][2] * mat[4][3] - mat[3][3] * mat[4][2];
  969. float det2_34_24 = mat[3][2] * mat[4][4] - mat[3][4] * mat[4][2];
  970. float det2_34_34 = mat[3][3] * mat[4][4] - mat[3][4] * mat[4][3];
  971. // 3x3 sub-determinants required to calculate 5x5 determinant
  972. float det3_234_012 = mat[2][0] * det2_34_12 - mat[2][1] * det2_34_02 + mat[2][2] * det2_34_01;
  973. float det3_234_013 = mat[2][0] * det2_34_13 - mat[2][1] * det2_34_03 + mat[2][3] * det2_34_01;
  974. float det3_234_014 = mat[2][0] * det2_34_14 - mat[2][1] * det2_34_04 + mat[2][4] * det2_34_01;
  975. float det3_234_023 = mat[2][0] * det2_34_23 - mat[2][2] * det2_34_03 + mat[2][3] * det2_34_02;
  976. float det3_234_024 = mat[2][0] * det2_34_24 - mat[2][2] * det2_34_04 + mat[2][4] * det2_34_02;
  977. float det3_234_034 = mat[2][0] * det2_34_34 - mat[2][3] * det2_34_04 + mat[2][4] * det2_34_03;
  978. float det3_234_123 = mat[2][1] * det2_34_23 - mat[2][2] * det2_34_13 + mat[2][3] * det2_34_12;
  979. float det3_234_124 = mat[2][1] * det2_34_24 - mat[2][2] * det2_34_14 + mat[2][4] * det2_34_12;
  980. float det3_234_134 = mat[2][1] * det2_34_34 - mat[2][3] * det2_34_14 + mat[2][4] * det2_34_13;
  981. float det3_234_234 = mat[2][2] * det2_34_34 - mat[2][3] * det2_34_24 + mat[2][4] * det2_34_23;
  982. // 4x4 sub-determinants required to calculate 5x5 determinant
  983. float det4_1234_0123 = mat[1][0] * det3_234_123 - mat[1][1] * det3_234_023 + mat[1][2] * det3_234_013 - mat[1][3] * det3_234_012;
  984. float det4_1234_0124 = mat[1][0] * det3_234_124 - mat[1][1] * det3_234_024 + mat[1][2] * det3_234_014 - mat[1][4] * det3_234_012;
  985. float det4_1234_0134 = mat[1][0] * det3_234_134 - mat[1][1] * det3_234_034 + mat[1][3] * det3_234_014 - mat[1][4] * det3_234_013;
  986. float det4_1234_0234 = mat[1][0] * det3_234_234 - mat[1][2] * det3_234_034 + mat[1][3] * det3_234_024 - mat[1][4] * det3_234_023;
  987. float det4_1234_1234 = mat[1][1] * det3_234_234 - mat[1][2] * det3_234_134 + mat[1][3] * det3_234_124 - mat[1][4] * det3_234_123;
  988. // determinant of 5x5 matrix
  989. det = mat[0][0] * det4_1234_1234 - mat[0][1] * det4_1234_0234 + mat[0][2] * det4_1234_0134 - mat[0][3] * det4_1234_0124 + mat[0][4] * det4_1234_0123;
  990. if( idMath::Fabs( det ) < MATRIX_INVERSE_EPSILON ) {
  991. return false;
  992. }
  993. invDet = 1.0f / det;
  994. // remaining 2x2 sub-determinants
  995. float det2_23_01 = mat[2][0] * mat[3][1] - mat[2][1] * mat[3][0];
  996. float det2_23_02 = mat[2][0] * mat[3][2] - mat[2][2] * mat[3][0];
  997. float det2_23_03 = mat[2][0] * mat[3][3] - mat[2][3] * mat[3][0];
  998. float det2_23_04 = mat[2][0] * mat[3][4] - mat[2][4] * mat[3][0];
  999. float det2_23_12 = mat[2][1] * mat[3][2] - mat[2][2] * mat[3][1];
  1000. float det2_23_13 = mat[2][1] * mat[3][3] - mat[2][3] * mat[3][1];
  1001. float det2_23_14 = mat[2][1] * mat[3][4] - mat[2][4] * mat[3][1];
  1002. float det2_23_23 = mat[2][2] * mat[3][3] - mat[2][3] * mat[3][2];
  1003. float det2_23_24 = mat[2][2] * mat[3][4] - mat[2][4] * mat[3][2];
  1004. float det2_23_34 = mat[2][3] * mat[3][4] - mat[2][4] * mat[3][3];
  1005. float det2_24_01 = mat[2][0] * mat[4][1] - mat[2][1] * mat[4][0];
  1006. float det2_24_02 = mat[2][0] * mat[4][2] - mat[2][2] * mat[4][0];
  1007. float det2_24_03 = mat[2][0] * mat[4][3] - mat[2][3] * mat[4][0];
  1008. float det2_24_04 = mat[2][0] * mat[4][4] - mat[2][4] * mat[4][0];
  1009. float det2_24_12 = mat[2][1] * mat[4][2] - mat[2][2] * mat[4][1];
  1010. float det2_24_13 = mat[2][1] * mat[4][3] - mat[2][3] * mat[4][1];
  1011. float det2_24_14 = mat[2][1] * mat[4][4] - mat[2][4] * mat[4][1];
  1012. float det2_24_23 = mat[2][2] * mat[4][3] - mat[2][3] * mat[4][2];
  1013. float det2_24_24 = mat[2][2] * mat[4][4] - mat[2][4] * mat[4][2];
  1014. float det2_24_34 = mat[2][3] * mat[4][4] - mat[2][4] * mat[4][3];
  1015. // remaining 3x3 sub-determinants
  1016. float det3_123_012 = mat[1][0] * det2_23_12 - mat[1][1] * det2_23_02 + mat[1][2] * det2_23_01;
  1017. float det3_123_013 = mat[1][0] * det2_23_13 - mat[1][1] * det2_23_03 + mat[1][3] * det2_23_01;
  1018. float det3_123_014 = mat[1][0] * det2_23_14 - mat[1][1] * det2_23_04 + mat[1][4] * det2_23_01;
  1019. float det3_123_023 = mat[1][0] * det2_23_23 - mat[1][2] * det2_23_03 + mat[1][3] * det2_23_02;
  1020. float det3_123_024 = mat[1][0] * det2_23_24 - mat[1][2] * det2_23_04 + mat[1][4] * det2_23_02;
  1021. float det3_123_034 = mat[1][0] * det2_23_34 - mat[1][3] * det2_23_04 + mat[1][4] * det2_23_03;
  1022. float det3_123_123 = mat[1][1] * det2_23_23 - mat[1][2] * det2_23_13 + mat[1][3] * det2_23_12;
  1023. float det3_123_124 = mat[1][1] * det2_23_24 - mat[1][2] * det2_23_14 + mat[1][4] * det2_23_12;
  1024. float det3_123_134 = mat[1][1] * det2_23_34 - mat[1][3] * det2_23_14 + mat[1][4] * det2_23_13;
  1025. float det3_123_234 = mat[1][2] * det2_23_34 - mat[1][3] * det2_23_24 + mat[1][4] * det2_23_23;
  1026. float det3_124_012 = mat[1][0] * det2_24_12 - mat[1][1] * det2_24_02 + mat[1][2] * det2_24_01;
  1027. float det3_124_013 = mat[1][0] * det2_24_13 - mat[1][1] * det2_24_03 + mat[1][3] * det2_24_01;
  1028. float det3_124_014 = mat[1][0] * det2_24_14 - mat[1][1] * det2_24_04 + mat[1][4] * det2_24_01;
  1029. float det3_124_023 = mat[1][0] * det2_24_23 - mat[1][2] * det2_24_03 + mat[1][3] * det2_24_02;
  1030. float det3_124_024 = mat[1][0] * det2_24_24 - mat[1][2] * det2_24_04 + mat[1][4] * det2_24_02;
  1031. float det3_124_034 = mat[1][0] * det2_24_34 - mat[1][3] * det2_24_04 + mat[1][4] * det2_24_03;
  1032. float det3_124_123 = mat[1][1] * det2_24_23 - mat[1][2] * det2_24_13 + mat[1][3] * det2_24_12;
  1033. float det3_124_124 = mat[1][1] * det2_24_24 - mat[1][2] * det2_24_14 + mat[1][4] * det2_24_12;
  1034. float det3_124_134 = mat[1][1] * det2_24_34 - mat[1][3] * det2_24_14 + mat[1][4] * det2_24_13;
  1035. float det3_124_234 = mat[1][2] * det2_24_34 - mat[1][3] * det2_24_24 + mat[1][4] * det2_24_23;
  1036. float det3_134_012 = mat[1][0] * det2_34_12 - mat[1][1] * det2_34_02 + mat[1][2] * det2_34_01;
  1037. float det3_134_013 = mat[1][0] * det2_34_13 - mat[1][1] * det2_34_03 + mat[1][3] * det2_34_01;
  1038. float det3_134_014 = mat[1][0] * det2_34_14 - mat[1][1] * det2_34_04 + mat[1][4] * det2_34_01;
  1039. float det3_134_023 = mat[1][0] * det2_34_23 - mat[1][2] * det2_34_03 + mat[1][3] * det2_34_02;
  1040. float det3_134_024 = mat[1][0] * det2_34_24 - mat[1][2] * det2_34_04 + mat[1][4] * det2_34_02;
  1041. float det3_134_034 = mat[1][0] * det2_34_34 - mat[1][3] * det2_34_04 + mat[1][4] * det2_34_03;
  1042. float det3_134_123 = mat[1][1] * det2_34_23 - mat[1][2] * det2_34_13 + mat[1][3] * det2_34_12;
  1043. float det3_134_124 = mat[1][1] * det2_34_24 - mat[1][2] * det2_34_14 + mat[1][4] * det2_34_12;
  1044. float det3_134_134 = mat[1][1] * det2_34_34 - mat[1][3] * det2_34_14 + mat[1][4] * det2_34_13;
  1045. float det3_134_234 = mat[1][2] * det2_34_34 - mat[1][3] * det2_34_24 + mat[1][4] * det2_34_23;
  1046. // remaining 4x4 sub-determinants
  1047. float det4_0123_0123 = mat[0][0] * det3_123_123 - mat[0][1] * det3_123_023 + mat[0][2] * det3_123_013 - mat[0][3] * det3_123_012;
  1048. float det4_0123_0124 = mat[0][0] * det3_123_124 - mat[0][1] * det3_123_024 + mat[0][2] * det3_123_014 - mat[0][4] * det3_123_012;
  1049. float det4_0123_0134 = mat[0][0] * det3_123_134 - mat[0][1] * det3_123_034 + mat[0][3] * det3_123_014 - mat[0][4] * det3_123_013;
  1050. float det4_0123_0234 = mat[0][0] * det3_123_234 - mat[0][2] * det3_123_034 + mat[0][3] * det3_123_024 - mat[0][4] * det3_123_023;
  1051. float det4_0123_1234 = mat[0][1] * det3_123_234 - mat[0][2] * det3_123_134 + mat[0][3] * det3_123_124 - mat[0][4] * det3_123_123;
  1052. float det4_0124_0123 = mat[0][0] * det3_124_123 - mat[0][1] * det3_124_023 + mat[0][2] * det3_124_013 - mat[0][3] * det3_124_012;
  1053. float det4_0124_0124 = mat[0][0] * det3_124_124 - mat[0][1] * det3_124_024 + mat[0][2] * det3_124_014 - mat[0][4] * det3_124_012;
  1054. float det4_0124_0134 = mat[0][0] * det3_124_134 - mat[0][1] * det3_124_034 + mat[0][3] * det3_124_014 - mat[0][4] * det3_124_013;
  1055. float det4_0124_0234 = mat[0][0] * det3_124_234 - mat[0][2] * det3_124_034 + mat[0][3] * det3_124_024 - mat[0][4] * det3_124_023;
  1056. float det4_0124_1234 = mat[0][1] * det3_124_234 - mat[0][2] * det3_124_134 + mat[0][3] * det3_124_124 - mat[0][4] * det3_124_123;
  1057. float det4_0134_0123 = mat[0][0] * det3_134_123 - mat[0][1] * det3_134_023 + mat[0][2] * det3_134_013 - mat[0][3] * det3_134_012;
  1058. float det4_0134_0124 = mat[0][0] * det3_134_124 - mat[0][1] * det3_134_024 + mat[0][2] * det3_134_014 - mat[0][4] * det3_134_012;
  1059. float det4_0134_0134 = mat[0][0] * det3_134_134 - mat[0][1] * det3_134_034 + mat[0][3] * det3_134_014 - mat[0][4] * det3_134_013;
  1060. float det4_0134_0234 = mat[0][0] * det3_134_234 - mat[0][2] * det3_134_034 + mat[0][3] * det3_134_024 - mat[0][4] * det3_134_023;
  1061. float det4_0134_1234 = mat[0][1] * det3_134_234 - mat[0][2] * det3_134_134 + mat[0][3] * det3_134_124 - mat[0][4] * det3_134_123;
  1062. float det4_0234_0123 = mat[0][0] * det3_234_123 - mat[0][1] * det3_234_023 + mat[0][2] * det3_234_013 - mat[0][3] * det3_234_012;
  1063. float det4_0234_0124 = mat[0][0] * det3_234_124 - mat[0][1] * det3_234_024 + mat[0][2] * det3_234_014 - mat[0][4] * det3_234_012;
  1064. float det4_0234_0134 = mat[0][0] * det3_234_134 - mat[0][1] * det3_234_034 + mat[0][3] * det3_234_014 - mat[0][4] * det3_234_013;
  1065. float det4_0234_0234 = mat[0][0] * det3_234_234 - mat[0][2] * det3_234_034 + mat[0][3] * det3_234_024 - mat[0][4] * det3_234_023;
  1066. float det4_0234_1234 = mat[0][1] * det3_234_234 - mat[0][2] * det3_234_134 + mat[0][3] * det3_234_124 - mat[0][4] * det3_234_123;
  1067. mat[0][0] = det4_1234_1234 * invDet;
  1068. mat[0][1] = -det4_0234_1234 * invDet;
  1069. mat[0][2] = det4_0134_1234 * invDet;
  1070. mat[0][3] = -det4_0124_1234 * invDet;
  1071. mat[0][4] = det4_0123_1234 * invDet;
  1072. mat[1][0] = -det4_1234_0234 * invDet;
  1073. mat[1][1] = det4_0234_0234 * invDet;
  1074. mat[1][2] = -det4_0134_0234 * invDet;
  1075. mat[1][3] = det4_0124_0234 * invDet;
  1076. mat[1][4] = -det4_0123_0234 * invDet;
  1077. mat[2][0] = det4_1234_0134 * invDet;
  1078. mat[2][1] = -det4_0234_0134 * invDet;
  1079. mat[2][2] = det4_0134_0134 * invDet;
  1080. mat[2][3] = -det4_0124_0134 * invDet;
  1081. mat[2][4] = det4_0123_0134 * invDet;
  1082. mat[3][0] = -det4_1234_0124 * invDet;
  1083. mat[3][1] = det4_0234_0124 * invDet;
  1084. mat[3][2] = -det4_0134_0124 * invDet;
  1085. mat[3][3] = det4_0124_0124 * invDet;
  1086. mat[3][4] = -det4_0123_0124 * invDet;
  1087. mat[4][0] = det4_1234_0123 * invDet;
  1088. mat[4][1] = -det4_0234_0123 * invDet;
  1089. mat[4][2] = det4_0134_0123 * invDet;
  1090. mat[4][3] = -det4_0124_0123 * invDet;
  1091. mat[4][4] = det4_0123_0123 * invDet;
  1092. return true;
  1093. }
  1094. /*
  1095. ============
  1096. idMat5::InverseFastSelf
  1097. ============
  1098. */
  1099. bool idMat5::InverseFastSelf( void ) {
  1100. #if 0
  1101. // 280+5+25 = 310 multiplications
  1102. // 1 division
  1103. double det, invDet;
  1104. // 2x2 sub-determinants required to calculate 5x5 determinant
  1105. float det2_34_01 = mat[3][0] * mat[4][1] - mat[3][1] * mat[4][0];
  1106. float det2_34_02 = mat[3][0] * mat[4][2] - mat[3][2] * mat[4][0];
  1107. float det2_34_03 = mat[3][0] * mat[4][3] - mat[3][3] * mat[4][0];
  1108. float det2_34_04 = mat[3][0] * mat[4][4] - mat[3][4] * mat[4][0];
  1109. float det2_34_12 = mat[3][1] * mat[4][2] - mat[3][2] * mat[4][1];
  1110. float det2_34_13 = mat[3][1] * mat[4][3] - mat[3][3] * mat[4][1];
  1111. float det2_34_14 = mat[3][1] * mat[4][4] - mat[3][4] * mat[4][1];
  1112. float det2_34_23 = mat[3][2] * mat[4][3] - mat[3][3] * mat[4][2];
  1113. float det2_34_24 = mat[3][2] * mat[4][4] - mat[3][4] * mat[4][2];
  1114. float det2_34_34 = mat[3][3] * mat[4][4] - mat[3][4] * mat[4][3];
  1115. // 3x3 sub-determinants required to calculate 5x5 determinant
  1116. float det3_234_012 = mat[2][0] * det2_34_12 - mat[2][1] * det2_34_02 + mat[2][2] * det2_34_01;
  1117. float det3_234_013 = mat[2][0] * det2_34_13 - mat[2][1] * det2_34_03 + mat[2][3] * det2_34_01;
  1118. float det3_234_014 = mat[2][0] * det2_34_14 - mat[2][1] * det2_34_04 + mat[2][4] * det2_34_01;
  1119. float det3_234_023 = mat[2][0] * det2_34_23 - mat[2][2] * det2_34_03 + mat[2][3] * det2_34_02;
  1120. float det3_234_024 = mat[2][0] * det2_34_24 - mat[2][2] * det2_34_04 + mat[2][4] * det2_34_02;
  1121. float det3_234_034 = mat[2][0] * det2_34_34 - mat[2][3] * det2_34_04 + mat[2][4] * det2_34_03;
  1122. float det3_234_123 = mat[2][1] * det2_34_23 - mat[2][2] * det2_34_13 + mat[2][3] * det2_34_12;
  1123. float det3_234_124 = mat[2][1] * det2_34_24 - mat[2][2] * det2_34_14 + mat[2][4] * det2_34_12;
  1124. float det3_234_134 = mat[2][1] * det2_34_34 - mat[2][3] * det2_34_14 + mat[2][4] * det2_34_13;
  1125. float det3_234_234 = mat[2][2] * det2_34_34 - mat[2][3] * det2_34_24 + mat[2][4] * det2_34_23;
  1126. // 4x4 sub-determinants required to calculate 5x5 determinant
  1127. float det4_1234_0123 = mat[1][0] * det3_234_123 - mat[1][1] * det3_234_023 + mat[1][2] * det3_234_013 - mat[1][3] * det3_234_012;
  1128. float det4_1234_0124 = mat[1][0] * det3_234_124 - mat[1][1] * det3_234_024 + mat[1][2] * det3_234_014 - mat[1][4] * det3_234_012;
  1129. float det4_1234_0134 = mat[1][0] * det3_234_134 - mat[1][1] * det3_234_034 + mat[1][3] * det3_234_014 - mat[1][4] * det3_234_013;
  1130. float det4_1234_0234 = mat[1][0] * det3_234_234 - mat[1][2] * det3_234_034 + mat[1][3] * det3_234_024 - mat[1][4] * det3_234_023;
  1131. float det4_1234_1234 = mat[1][1] * det3_234_234 - mat[1][2] * det3_234_134 + mat[1][3] * det3_234_124 - mat[1][4] * det3_234_123;
  1132. // determinant of 5x5 matrix
  1133. det = mat[0][0] * det4_1234_1234 - mat[0][1] * det4_1234_0234 + mat[0][2] * det4_1234_0134 - mat[0][3] * det4_1234_0124 + mat[0][4] * det4_1234_0123;
  1134. if( idMath::Fabs( det ) < MATRIX_INVERSE_EPSILON ) {
  1135. return false;
  1136. }
  1137. invDet = 1.0f / det;
  1138. // remaining 2x2 sub-determinants
  1139. float det2_23_01 = mat[2][0] * mat[3][1] - mat[2][1] * mat[3][0];
  1140. float det2_23_02 = mat[2][0] * mat[3][2] - mat[2][2] * mat[3][0];
  1141. float det2_23_03 = mat[2][0] * mat[3][3] - mat[2][3] * mat[3][0];
  1142. float det2_23_04 = mat[2][0] * mat[3][4] - mat[2][4] * mat[3][0];
  1143. float det2_23_12 = mat[2][1] * mat[3][2] - mat[2][2] * mat[3][1];
  1144. float det2_23_13 = mat[2][1] * mat[3][3] - mat[2][3] * mat[3][1];
  1145. float det2_23_14 = mat[2][1] * mat[3][4] - mat[2][4] * mat[3][1];
  1146. float det2_23_23 = mat[2][2] * mat[3][3] - mat[2][3] * mat[3][2];
  1147. float det2_23_24 = mat[2][2] * mat[3][4] - mat[2][4] * mat[3][2];
  1148. float det2_23_34 = mat[2][3] * mat[3][4] - mat[2][4] * mat[3][3];
  1149. float det2_24_01 = mat[2][0] * mat[4][1] - mat[2][1] * mat[4][0];
  1150. float det2_24_02 = mat[2][0] * mat[4][2] - mat[2][2] * mat[4][0];
  1151. float det2_24_03 = mat[2][0] * mat[4][3] - mat[2][3] * mat[4][0];
  1152. float det2_24_04 = mat[2][0] * mat[4][4] - mat[2][4] * mat[4][0];
  1153. float det2_24_12 = mat[2][1] * mat[4][2] - mat[2][2] * mat[4][1];
  1154. float det2_24_13 = mat[2][1] * mat[4][3] - mat[2][3] * mat[4][1];
  1155. float det2_24_14 = mat[2][1] * mat[4][4] - mat[2][4] * mat[4][1];
  1156. float det2_24_23 = mat[2][2] * mat[4][3] - mat[2][3] * mat[4][2];
  1157. float det2_24_24 = mat[2][2] * mat[4][4] - mat[2][4] * mat[4][2];
  1158. float det2_24_34 = mat[2][3] * mat[4][4] - mat[2][4] * mat[4][3];
  1159. // remaining 3x3 sub-determinants
  1160. float det3_123_012 = mat[1][0] * det2_23_12 - mat[1][1] * det2_23_02 + mat[1][2] * det2_23_01;
  1161. float det3_123_013 = mat[1][0] * det2_23_13 - mat[1][1] * det2_23_03 + mat[1][3] * det2_23_01;
  1162. float det3_123_014 = mat[1][0] * det2_23_14 - mat[1][1] * det2_23_04 + mat[1][4] * det2_23_01;
  1163. float det3_123_023 = mat[1][0] * det2_23_23 - mat[1][2] * det2_23_03 + mat[1][3] * det2_23_02;
  1164. float det3_123_024 = mat[1][0] * det2_23_24 - mat[1][2] * det2_23_04 + mat[1][4] * det2_23_02;
  1165. float det3_123_034 = mat[1][0] * det2_23_34 - mat[1][3] * det2_23_04 + mat[1][4] * det2_23_03;
  1166. float det3_123_123 = mat[1][1] * det2_23_23 - mat[1][2] * det2_23_13 + mat[1][3] * det2_23_12;
  1167. float det3_123_124 = mat[1][1] * det2_23_24 - mat[1][2] * det2_23_14 + mat[1][4] * det2_23_12;
  1168. float det3_123_134 = mat[1][1] * det2_23_34 - mat[1][3] * det2_23_14 + mat[1][4] * det2_23_13;
  1169. float det3_123_234 = mat[1][2] * det2_23_34 - mat[1][3] * det2_23_24 + mat[1][4] * det2_23_23;
  1170. float det3_124_012 = mat[1][0] * det2_24_12 - mat[1][1] * det2_24_02 + mat[1][2] * det2_24_01;
  1171. float det3_124_013 = mat[1][0] * det2_24_13 - mat[1][1] * det2_24_03 + mat[1][3] * det2_24_01;
  1172. float det3_124_014 = mat[1][0] * det2_24_14 - mat[1][1] * det2_24_04 + mat[1][4] * det2_24_01;
  1173. float det3_124_023 = mat[1][0] * det2_24_23 - mat[1][2] * det2_24_03 + mat[1][3] * det2_24_02;
  1174. float det3_124_024 = mat[1][0] * det2_24_24 - mat[1][2] * det2_24_04 + mat[1][4] * det2_24_02;
  1175. float det3_124_034 = mat[1][0] * det2_24_34 - mat[1][3] * det2_24_04 + mat[1][4] * det2_24_03;
  1176. float det3_124_123 = mat[1][1] * det2_24_23 - mat[1][2] * det2_24_13 + mat[1][3] * det2_24_12;
  1177. float det3_124_124 = mat[1][1] * det2_24_24 - mat[1][2] * det2_24_14 + mat[1][4] * det2_24_12;
  1178. float det3_124_134 = mat[1][1] * det2_24_34 - mat[1][3] * det2_24_14 + mat[1][4] * det2_24_13;
  1179. float det3_124_234 = mat[1][2] * det2_24_34 - mat[1][3] * det2_24_24 + mat[1][4] * det2_24_23;
  1180. float det3_134_012 = mat[1][0] * det2_34_12 - mat[1][1] * det2_34_02 + mat[1][2] * det2_34_01;
  1181. float det3_134_013 = mat[1][0] * det2_34_13 - mat[1][1] * det2_34_03 + mat[1][3] * det2_34_01;
  1182. float det3_134_014 = mat[1][0] * det2_34_14 - mat[1][1] * det2_34_04 + mat[1][4] * det2_34_01;
  1183. float det3_134_023 = mat[1][0] * det2_34_23 - mat[1][2] * det2_34_03 + mat[1][3] * det2_34_02;
  1184. float det3_134_024 = mat[1][0] * det2_34_24 - mat[1][2] * det2_34_04 + mat[1][4] * det2_34_02;
  1185. float det3_134_034 = mat[1][0] * det2_34_34 - mat[1][3] * det2_34_04 + mat[1][4] * det2_34_03;
  1186. float det3_134_123 = mat[1][1] * det2_34_23 - mat[1][2] * det2_34_13 + mat[1][3] * det2_34_12;
  1187. float det3_134_124 = mat[1][1] * det2_34_24 - mat[1][2] * det2_34_14 + mat[1][4] * det2_34_12;
  1188. float det3_134_134 = mat[1][1] * det2_34_34 - mat[1][3] * det2_34_14 + mat[1][4] * det2_34_13;
  1189. float det3_134_234 = mat[1][2] * det2_34_34 - mat[1][3] * det2_34_24 + mat[1][4] * det2_34_23;
  1190. // remaining 4x4 sub-determinants
  1191. float det4_0123_0123 = mat[0][0] * det3_123_123 - mat[0][1] * det3_123_023 + mat[0][2] * det3_123_013 - mat[0][3] * det3_123_012;
  1192. float det4_0123_0124 = mat[0][0] * det3_123_124 - mat[0][1] * det3_123_024 + mat[0][2] * det3_123_014 - mat[0][4] * det3_123_012;
  1193. float det4_0123_0134 = mat[0][0] * det3_123_134 - mat[0][1] * det3_123_034 + mat[0][3] * det3_123_014 - mat[0][4] * det3_123_013;
  1194. float det4_0123_0234 = mat[0][0] * det3_123_234 - mat[0][2] * det3_123_034 + mat[0][3] * det3_123_024 - mat[0][4] * det3_123_023;
  1195. float det4_0123_1234 = mat[0][1] * det3_123_234 - mat[0][2] * det3_123_134 + mat[0][3] * det3_123_124 - mat[0][4] * det3_123_123;
  1196. float det4_0124_0123 = mat[0][0] * det3_124_123 - mat[0][1] * det3_124_023 + mat[0][2] * det3_124_013 - mat[0][3] * det3_124_012;
  1197. float det4_0124_0124 = mat[0][0] * det3_124_124 - mat[0][1] * det3_124_024 + mat[0][2] * det3_124_014 - mat[0][4] * det3_124_012;
  1198. float det4_0124_0134 = mat[0][0] * det3_124_134 - mat[0][1] * det3_124_034 + mat[0][3] * det3_124_014 - mat[0][4] * det3_124_013;
  1199. float det4_0124_0234 = mat[0][0] * det3_124_234 - mat[0][2] * det3_124_034 + mat[0][3] * det3_124_024 - mat[0][4] * det3_124_023;
  1200. float det4_0124_1234 = mat[0][1] * det3_124_234 - mat[0][2] * det3_124_134 + mat[0][3] * det3_124_124 - mat[0][4] * det3_124_123;
  1201. float det4_0134_0123 = mat[0][0] * det3_134_123 - mat[0][1] * det3_134_023 + mat[0][2] * det3_134_013 - mat[0][3] * det3_134_012;
  1202. float det4_0134_0124 = mat[0][0] * det3_134_124 - mat[0][1] * det3_134_024 + mat[0][2] * det3_134_014 - mat[0][4] * det3_134_012;
  1203. float det4_0134_0134 = mat[0][0] * det3_134_134 - mat[0][1] * det3_134_034 + mat[0][3] * det3_134_014 - mat[0][4] * det3_134_013;
  1204. float det4_0134_0234 = mat[0][0] * det3_134_234 - mat[0][2] * det3_134_034 + mat[0][3] * det3_134_024 - mat[0][4] * det3_134_023;
  1205. float det4_0134_1234 = mat[0][1] * det3_134_234 - mat[0][2] * det3_134_134 + mat[0][3] * det3_134_124 - mat[0][4] * det3_134_123;
  1206. float det4_0234_0123 = mat[0][0] * det3_234_123 - mat[0][1] * det3_234_023 + mat[0][2] * det3_234_013 - mat[0][3] * det3_234_012;
  1207. float det4_0234_0124 = mat[0][0] * det3_234_124 - mat[0][1] * det3_234_024 + mat[0][2] * det3_234_014 - mat[0][4] * det3_234_012;
  1208. float det4_0234_0134 = mat[0][0] * det3_234_134 - mat[0][1] * det3_234_034 + mat[0][3] * det3_234_014 - mat[0][4] * det3_234_013;
  1209. float det4_0234_0234 = mat[0][0] * det3_234_234 - mat[0][2] * det3_234_034 + mat[0][3] * det3_234_024 - mat[0][4] * det3_234_023;
  1210. float det4_0234_1234 = mat[0][1] * det3_234_234 - mat[0][2] * det3_234_134 + mat[0][3] * det3_234_124 - mat[0][4] * det3_234_123;
  1211. mat[0][0] = det4_1234_1234 * invDet;
  1212. mat[0][1] = -det4_0234_1234 * invDet;
  1213. mat[0][2] = det4_0134_1234 * invDet;
  1214. mat[0][3] = -det4_0124_1234 * invDet;
  1215. mat[0][4] = det4_0123_1234 * invDet;
  1216. mat[1][0] = -det4_1234_0234 * invDet;
  1217. mat[1][1] = det4_0234_0234 * invDet;
  1218. mat[1][2] = -det4_0134_0234 * invDet;
  1219. mat[1][3] = det4_0124_0234 * invDet;
  1220. mat[1][4] = -det4_0123_0234 * invDet;
  1221. mat[2][0] = det4_1234_0134 * invDet;
  1222. mat[2][1] = -det4_0234_0134 * invDet;
  1223. mat[2][2] = det4_0134_0134 * invDet;
  1224. mat[2][3] = -det4_0124_0134 * invDet;
  1225. mat[2][4] = det4_0123_0134 * invDet;
  1226. mat[3][0] = -det4_1234_0124 * invDet;
  1227. mat[3][1] = det4_0234_0124 * invDet;
  1228. mat[3][2] = -det4_0134_0124 * invDet;
  1229. mat[3][3] = det4_0124_0124 * invDet;
  1230. mat[3][4] = -det4_0123_0124 * invDet;
  1231. mat[4][0] = det4_1234_0123 * invDet;
  1232. mat[4][1] = -det4_0234_0123 * invDet;
  1233. mat[4][2] = det4_0134_0123 * invDet;
  1234. mat[4][3] = -det4_0124_0123 * invDet;
  1235. mat[4][4] = det4_0123_0123 * invDet;
  1236. return true;
  1237. #elif 0
  1238. // 5*28 = 140 multiplications
  1239. // 5 divisions
  1240. float *mat = reinterpret_cast<float *>(this);
  1241. float s;
  1242. double d, di;
  1243. di = mat[0];
  1244. s = di;
  1245. mat[0] = d = 1.0f / di;
  1246. mat[1] *= d;
  1247. mat[2] *= d;
  1248. mat[3] *= d;
  1249. mat[4] *= d;
  1250. d = -d;
  1251. mat[5] *= d;
  1252. mat[10] *= d;
  1253. mat[15] *= d;
  1254. mat[20] *= d;
  1255. d = mat[5] * di;
  1256. mat[6] += mat[1] * d;
  1257. mat[7] += mat[2] * d;
  1258. mat[8] += mat[3] * d;
  1259. mat[9] += mat[4] * d;
  1260. d = mat[10] * di;
  1261. mat[11] += mat[1] * d;
  1262. mat[12] += mat[2] * d;
  1263. mat[13] += mat[3] * d;
  1264. mat[14] += mat[4] * d;
  1265. d = mat[15] * di;
  1266. mat[16] += mat[1] * d;
  1267. mat[17] += mat[2] * d;
  1268. mat[18] += mat[3] * d;
  1269. mat[19] += mat[4] * d;
  1270. d = mat[20] * di;
  1271. mat[21] += mat[1] * d;
  1272. mat[22] += mat[2] * d;
  1273. mat[23] += mat[3] * d;
  1274. mat[24] += mat[4] * d;
  1275. di = mat[6];
  1276. s *= di;
  1277. mat[6] = d = 1.0f / di;
  1278. mat[5] *= d;
  1279. mat[7] *= d;
  1280. mat[8] *= d;
  1281. mat[9] *= d;
  1282. d = -d;
  1283. mat[1] *= d;
  1284. mat[11] *= d;
  1285. mat[16] *= d;
  1286. mat[21] *= d;
  1287. d = mat[1] * di;
  1288. mat[0] += mat[5] * d;
  1289. mat[2] += mat[7] * d;
  1290. mat[3] += mat[8] * d;
  1291. mat[4] += mat[9] * d;
  1292. d = mat[11] * di;
  1293. mat[10] += mat[5] * d;
  1294. mat[12] += mat[7] * d;
  1295. mat[13] += mat[8] * d;
  1296. mat[14] += mat[9] * d;
  1297. d = mat[16] * di;
  1298. mat[15] += mat[5] * d;
  1299. mat[17] += mat[7] * d;
  1300. mat[18] += mat[8] * d;
  1301. mat[19] += mat[9] * d;
  1302. d = mat[21] * di;
  1303. mat[20] += mat[5] * d;
  1304. mat[22] += mat[7] * d;
  1305. mat[23] += mat[8] * d;
  1306. mat[24] += mat[9] * d;
  1307. di = mat[12];
  1308. s *= di;
  1309. mat[12] = d = 1.0f / di;
  1310. mat[10] *= d;
  1311. mat[11] *= d;
  1312. mat[13] *= d;
  1313. mat[14] *= d;
  1314. d = -d;
  1315. mat[2] *= d;
  1316. mat[7] *= d;
  1317. mat[17] *= d;
  1318. mat[22] *= d;
  1319. d = mat[2] * di;
  1320. mat[0] += mat[10] * d;
  1321. mat[1] += mat[11] * d;
  1322. mat[3] += mat[13] * d;
  1323. mat[4] += mat[14] * d;
  1324. d = mat[7] * di;
  1325. mat[5] += mat[10] * d;
  1326. mat[6] += mat[11] * d;
  1327. mat[8] += mat[13] * d;
  1328. mat[9] += mat[14] * d;
  1329. d = mat[17] * di;
  1330. mat[15] += mat[10] * d;
  1331. mat[16] += mat[11] * d;
  1332. mat[18] += mat[13] * d;
  1333. mat[19] += mat[14] * d;
  1334. d = mat[22] * di;
  1335. mat[20] += mat[10] * d;
  1336. mat[21] += mat[11] * d;
  1337. mat[23] += mat[13] * d;
  1338. mat[24] += mat[14] * d;
  1339. di = mat[18];
  1340. s *= di;
  1341. mat[18] = d = 1.0f / di;
  1342. mat[15] *= d;
  1343. mat[16] *= d;
  1344. mat[17] *= d;
  1345. mat[19] *= d;
  1346. d = -d;
  1347. mat[3] *= d;
  1348. mat[8] *= d;
  1349. mat[13] *= d;
  1350. mat[23] *= d;
  1351. d = mat[3] * di;
  1352. mat[0] += mat[15] * d;
  1353. mat[1] += mat[16] * d;
  1354. mat[2] += mat[17] * d;
  1355. mat[4] += mat[19] * d;
  1356. d = mat[8] * di;
  1357. mat[5] += mat[15] * d;
  1358. mat[6] += mat[16] * d;
  1359. mat[7] += mat[17] * d;
  1360. mat[9] += mat[19] * d;
  1361. d = mat[13] * di;
  1362. mat[10] += mat[15] * d;
  1363. mat[11] += mat[16] * d;
  1364. mat[12] += mat[17] * d;
  1365. mat[14] += mat[19] * d;
  1366. d = mat[23] * di;
  1367. mat[20] += mat[15] * d;
  1368. mat[21] += mat[16] * d;
  1369. mat[22] += mat[17] * d;
  1370. mat[24] += mat[19] * d;
  1371. di = mat[24];
  1372. s *= di;
  1373. mat[24] = d = 1.0f / di;
  1374. mat[20] *= d;
  1375. mat[21] *= d;
  1376. mat[22] *= d;
  1377. mat[23] *= d;
  1378. d = -d;
  1379. mat[4] *= d;
  1380. mat[9] *= d;
  1381. mat[14] *= d;
  1382. mat[19] *= d;
  1383. d = mat[4] * di;
  1384. mat[0] += mat[20] * d;
  1385. mat[1] += mat[21] * d;
  1386. mat[2] += mat[22] * d;
  1387. mat[3] += mat[23] * d;
  1388. d = mat[9] * di;
  1389. mat[5] += mat[20] * d;
  1390. mat[6] += mat[21] * d;
  1391. mat[7] += mat[22] * d;
  1392. mat[8] += mat[23] * d;
  1393. d = mat[14] * di;
  1394. mat[10] += mat[20] * d;
  1395. mat[11] += mat[21] * d;
  1396. mat[12] += mat[22] * d;
  1397. mat[13] += mat[23] * d;
  1398. d = mat[19] * di;
  1399. mat[15] += mat[20] * d;
  1400. mat[16] += mat[21] * d;
  1401. mat[17] += mat[22] * d;
  1402. mat[18] += mat[23] * d;
  1403. return ( s != 0.0f && !FLOAT_IS_NAN( s ) );
  1404. #else
  1405. // 86+30+6 = 122 multiplications
  1406. // 2*1 = 2 divisions
  1407. idMat3 r0, r1, r2, r3;
  1408. float c0, c1, c2, det, invDet;
  1409. float *mat = reinterpret_cast<float *>(this);
  1410. // r0 = m0.Inverse(); // 3x3
  1411. c0 = mat[1*5+1] * mat[2*5+2] - mat[1*5+2] * mat[2*5+1];
  1412. c1 = mat[1*5+2] * mat[2*5+0] - mat[1*5+0] * mat[2*5+2];
  1413. c2 = mat[1*5+0] * mat[2*5+1] - mat[1*5+1] * mat[2*5+0];
  1414. det = mat[0*5+0] * c0 + mat[0*5+1] * c1 + mat[0*5+2] * c2;
  1415. if ( idMath::Fabs( det ) < MATRIX_INVERSE_EPSILON ) {
  1416. return false;
  1417. }
  1418. invDet = 1.0f / det;
  1419. r0[0][0] = c0 * invDet;
  1420. r0[0][1] = ( mat[0*5+2] * mat[2*5+1] - mat[0*5+1] * mat[2*5+2] ) * invDet;
  1421. r0[0][2] = ( mat[0*5+1] * mat[1*5+2] - mat[0*5+2] * mat[1*5+1] ) * invDet;
  1422. r0[1][0] = c1 * invDet;
  1423. r0[1][1] = ( mat[0*5+0] * mat[2*5+2] - mat[0*5+2] * mat[2*5+0] ) * invDet;
  1424. r0[1][2] = ( mat[0*5+2] * mat[1*5+0] - mat[0*5+0] * mat[1*5+2] ) * invDet;
  1425. r0[2][0] = c2 * invDet;
  1426. r0[2][1] = ( mat[0*5+1] * mat[2*5+0] - mat[0*5+0] * mat[2*5+1] ) * invDet;
  1427. r0[2][2] = ( mat[0*5+0] * mat[1*5+1] - mat[0*5+1] * mat[1*5+0] ) * invDet;
  1428. // r1 = r0 * m1; // 3x2 = 3x3 * 3x2
  1429. r1[0][0] = r0[0][0] * mat[0*5+3] + r0[0][1] * mat[1*5+3] + r0[0][2] * mat[2*5+3];
  1430. r1[0][1] = r0[0][0] * mat[0*5+4] + r0[0][1] * mat[1*5+4] + r0[0][2] * mat[2*5+4];
  1431. r1[1][0] = r0[1][0] * mat[0*5+3] + r0[1][1] * mat[1*5+3] + r0[1][2] * mat[2*5+3];
  1432. r1[1][1] = r0[1][0] * mat[0*5+4] + r0[1][1] * mat[1*5+4] + r0[1][2] * mat[2*5+4];
  1433. r1[2][0] = r0[2][0] * mat[0*5+3] + r0[2][1] * mat[1*5+3] + r0[2][2] * mat[2*5+3];
  1434. r1[2][1] = r0[2][0] * mat[0*5+4] + r0[2][1] * mat[1*5+4] + r0[2][2] * mat[2*5+4];
  1435. // r2 = m2 * r1; // 2x2 = 2x3 * 3x2
  1436. r2[0][0] = mat[3*5+0] * r1[0][0] + mat[3*5+1] * r1[1][0] + mat[3*5+2] * r1[2][0];
  1437. r2[0][1] = mat[3*5+0] * r1[0][1] + mat[3*5+1] * r1[1][1] + mat[3*5+2] * r1[2][1];
  1438. r2[1][0] = mat[4*5+0] * r1[0][0] + mat[4*5+1] * r1[1][0] + mat[4*5+2] * r1[2][0];
  1439. r2[1][1] = mat[4*5+0] * r1[0][1] + mat[4*5+1] * r1[1][1] + mat[4*5+2] * r1[2][1];
  1440. // r3 = r2 - m3; // 2x2 = 2x2 - 2x2
  1441. r3[0][0] = r2[0][0] - mat[3*5+3];
  1442. r3[0][1] = r2[0][1] - mat[3*5+4];
  1443. r3[1][0] = r2[1][0] - mat[4*5+3];
  1444. r3[1][1] = r2[1][1] - mat[4*5+4];
  1445. // r3.InverseSelf(); // 2x2
  1446. det = r3[0][0] * r3[1][1] - r3[0][1] * r3[1][0];
  1447. if ( idMath::Fabs( det ) < MATRIX_INVERSE_EPSILON ) {
  1448. return false;
  1449. }
  1450. invDet = 1.0f / det;
  1451. c0 = r3[0][0];
  1452. r3[0][0] = r3[1][1] * invDet;
  1453. r3[0][1] = - r3[0][1] * invDet;
  1454. r3[1][0] = - r3[1][0] * invDet;
  1455. r3[1][1] = c0 * invDet;
  1456. // r2 = m2 * r0; // 2x3 = 2x3 * 3x3
  1457. r2[0][0] = mat[3*5+0] * r0[0][0] + mat[3*5+1] * r0[1][0] + mat[3*5+2] * r0[2][0];
  1458. r2[0][1] = mat[3*5+0] * r0[0][1] + mat[3*5+1] * r0[1][1] + mat[3*5+2] * r0[2][1];
  1459. r2[0][2] = mat[3*5+0] * r0[0][2] + mat[3*5+1] * r0[1][2] + mat[3*5+2] * r0[2][2];
  1460. r2[1][0] = mat[4*5+0] * r0[0][0] + mat[4*5+1] * r0[1][0] + mat[4*5+2] * r0[2][0];
  1461. r2[1][1] = mat[4*5+0] * r0[0][1] + mat[4*5+1] * r0[1][1] + mat[4*5+2] * r0[2][1];
  1462. r2[1][2] = mat[4*5+0] * r0[0][2] + mat[4*5+1] * r0[1][2] + mat[4*5+2] * r0[2][2];
  1463. // m2 = r3 * r2; // 2x3 = 2x2 * 2x3
  1464. mat[3*5+0] = r3[0][0] * r2[0][0] + r3[0][1] * r2[1][0];
  1465. mat[3*5+1] = r3[0][0] * r2[0][1] + r3[0][1] * r2[1][1];
  1466. mat[3*5+2] = r3[0][0] * r2[0][2] + r3[0][1] * r2[1][2];
  1467. mat[4*5+0] = r3[1][0] * r2[0][0] + r3[1][1] * r2[1][0];
  1468. mat[4*5+1] = r3[1][0] * r2[0][1] + r3[1][1] * r2[1][1];
  1469. mat[4*5+2] = r3[1][0] * r2[0][2] + r3[1][1] * r2[1][2];
  1470. // m0 = r0 - r1 * m2; // 3x3 = 3x3 - 3x2 * 2x3
  1471. mat[0*5+0] = r0[0][0] - r1[0][0] * mat[3*5+0] - r1[0][1] * mat[4*5+0];
  1472. mat[0*5+1] = r0[0][1] - r1[0][0] * mat[3*5+1] - r1[0][1] * mat[4*5+1];
  1473. mat[0*5+2] = r0[0][2] - r1[0][0] * mat[3*5+2] - r1[0][1] * mat[4*5+2];
  1474. mat[1*5+0] = r0[1][0] - r1[1][0] * mat[3*5+0] - r1[1][1] * mat[4*5+0];
  1475. mat[1*5+1] = r0[1][1] - r1[1][0] * mat[3*5+1] - r1[1][1] * mat[4*5+1];
  1476. mat[1*5+2] = r0[1][2] - r1[1][0] * mat[3*5+2] - r1[1][1] * mat[4*5+2];
  1477. mat[2*5+0] = r0[2][0] - r1[2][0] * mat[3*5+0] - r1[2][1] * mat[4*5+0];
  1478. mat[2*5+1] = r0[2][1] - r1[2][0] * mat[3*5+1] - r1[2][1] * mat[4*5+1];
  1479. mat[2*5+2] = r0[2][2] - r1[2][0] * mat[3*5+2] - r1[2][1] * mat[4*5+2];
  1480. // m1 = r1 * r3; // 3x2 = 3x2 * 2x2
  1481. mat[0*5+3] = r1[0][0] * r3[0][0] + r1[0][1] * r3[1][0];
  1482. mat[0*5+4] = r1[0][0] * r3[0][1] + r1[0][1] * r3[1][1];
  1483. mat[1*5+3] = r1[1][0] * r3[0][0] + r1[1][1] * r3[1][0];
  1484. mat[1*5+4] = r1[1][0] * r3[0][1] + r1[1][1] * r3[1][1];
  1485. mat[2*5+3] = r1[2][0] * r3[0][0] + r1[2][1] * r3[1][0];
  1486. mat[2*5+4] = r1[2][0] * r3[0][1] + r1[2][1] * r3[1][1];
  1487. // m3 = -r3; // 2x2 = - 2x2
  1488. mat[3*5+3] = -r3[0][0];
  1489. mat[3*5+4] = -r3[0][1];
  1490. mat[4*5+3] = -r3[1][0];
  1491. mat[4*5+4] = -r3[1][1];
  1492. return true;
  1493. #endif
  1494. }
  1495. /*
  1496. =============
  1497. idMat5::ToString
  1498. =============
  1499. */
  1500. const char *idMat5::ToString( int precision ) const {
  1501. return idStr::FloatArrayToString( ToFloatPtr(), GetDimension(), precision );
  1502. }
  1503. //===============================================================
  1504. //
  1505. // idMat6
  1506. //
  1507. //===============================================================
  1508. idMat6 mat6_zero( idVec6( 0, 0, 0, 0, 0, 0 ), idVec6( 0, 0, 0, 0, 0, 0 ), idVec6( 0, 0, 0, 0, 0, 0 ), idVec6( 0, 0, 0, 0, 0, 0 ), idVec6( 0, 0, 0, 0, 0, 0 ), idVec6( 0, 0, 0, 0, 0, 0 ) );
  1509. idMat6 mat6_identity( idVec6( 1, 0, 0, 0, 0, 0 ), idVec6( 0, 1, 0, 0, 0, 0 ), idVec6( 0, 0, 1, 0, 0, 0 ), idVec6( 0, 0, 0, 1, 0, 0 ), idVec6( 0, 0, 0, 0, 1, 0 ), idVec6( 0, 0, 0, 0, 0, 1 ) );
  1510. /*
  1511. ============
  1512. idMat6::Transpose
  1513. ============
  1514. */
  1515. idMat6 idMat6::Transpose( void ) const {
  1516. idMat6 transpose;
  1517. int i, j;
  1518. for( i = 0; i < 6; i++ ) {
  1519. for( j = 0; j < 6; j++ ) {
  1520. transpose[ i ][ j ] = mat[ j ][ i ];
  1521. }
  1522. }
  1523. return transpose;
  1524. }
  1525. /*
  1526. ============
  1527. idMat6::TransposeSelf
  1528. ============
  1529. */
  1530. idMat6 &idMat6::TransposeSelf( void ) {
  1531. float temp;
  1532. int i, j;
  1533. for( i = 0; i < 6; i++ ) {
  1534. for( j = i + 1; j < 6; j++ ) {
  1535. temp = mat[ i ][ j ];
  1536. mat[ i ][ j ] = mat[ j ][ i ];
  1537. mat[ j ][ i ] = temp;
  1538. }
  1539. }
  1540. return *this;
  1541. }
  1542. /*
  1543. ============
  1544. idMat6::Determinant
  1545. ============
  1546. */
  1547. float idMat6::Determinant( void ) const {
  1548. // 2x2 sub-determinants required to calculate 6x6 determinant
  1549. float det2_45_01 = mat[4][0] * mat[5][1] - mat[4][1] * mat[5][0];
  1550. float det2_45_02 = mat[4][0] * mat[5][2] - mat[4][2] * mat[5][0];
  1551. float det2_45_03 = mat[4][0] * mat[5][3] - mat[4][3] * mat[5][0];
  1552. float det2_45_04 = mat[4][0] * mat[5][4] - mat[4][4] * mat[5][0];
  1553. float det2_45_05 = mat[4][0] * mat[5][5] - mat[4][5] * mat[5][0];
  1554. float det2_45_12 = mat[4][1] * mat[5][2] - mat[4][2] * mat[5][1];
  1555. float det2_45_13 = mat[4][1] * mat[5][3] - mat[4][3] * mat[5][1];
  1556. float det2_45_14 = mat[4][1] * mat[5][4] - mat[4][4] * mat[5][1];
  1557. float det2_45_15 = mat[4][1] * mat[5][5] - mat[4][5] * mat[5][1];
  1558. float det2_45_23 = mat[4][2] * mat[5][3] - mat[4][3] * mat[5][2];
  1559. float det2_45_24 = mat[4][2] * mat[5][4] - mat[4][4] * mat[5][2];
  1560. float det2_45_25 = mat[4][2] * mat[5][5] - mat[4][5] * mat[5][2];
  1561. float det2_45_34 = mat[4][3] * mat[5][4] - mat[4][4] * mat[5][3];
  1562. float det2_45_35 = mat[4][3] * mat[5][5] - mat[4][5] * mat[5][3];
  1563. float det2_45_45 = mat[4][4] * mat[5][5] - mat[4][5] * mat[5][4];
  1564. // 3x3 sub-determinants required to calculate 6x6 determinant
  1565. float det3_345_012 = mat[3][0] * det2_45_12 - mat[3][1] * det2_45_02 + mat[3][2] * det2_45_01;
  1566. float det3_345_013 = mat[3][0] * det2_45_13 - mat[3][1] * det2_45_03 + mat[3][3] * det2_45_01;
  1567. float det3_345_014 = mat[3][0] * det2_45_14 - mat[3][1] * det2_45_04 + mat[3][4] * det2_45_01;
  1568. float det3_345_015 = mat[3][0] * det2_45_15 - mat[3][1] * det2_45_05 + mat[3][5] * det2_45_01;
  1569. float det3_345_023 = mat[3][0] * det2_45_23 - mat[3][2] * det2_45_03 + mat[3][3] * det2_45_02;
  1570. float det3_345_024 = mat[3][0] * det2_45_24 - mat[3][2] * det2_45_04 + mat[3][4] * det2_45_02;
  1571. float det3_345_025 = mat[3][0] * det2_45_25 - mat[3][2] * det2_45_05 + mat[3][5] * det2_45_02;
  1572. float det3_345_034 = mat[3][0] * det2_45_34 - mat[3][3] * det2_45_04 + mat[3][4] * det2_45_03;
  1573. float det3_345_035 = mat[3][0] * det2_45_35 - mat[3][3] * det2_45_05 + mat[3][5] * det2_45_03;
  1574. float det3_345_045 = mat[3][0] * det2_45_45 - mat[3][4] * det2_45_05 + mat[3][5] * det2_45_04;
  1575. float det3_345_123 = mat[3][1] * det2_45_23 - mat[3][2] * det2_45_13 + mat[3][3] * det2_45_12;
  1576. float det3_345_124 = mat[3][1] * det2_45_24 - mat[3][2] * det2_45_14 + mat[3][4] * det2_45_12;
  1577. float det3_345_125 = mat[3][1] * det2_45_25 - mat[3][2] * det2_45_15 + mat[3][5] * det2_45_12;
  1578. float det3_345_134 = mat[3][1] * det2_45_34 - mat[3][3] * det2_45_14 + mat[3][4] * det2_45_13;
  1579. float det3_345_135 = mat[3][1] * det2_45_35 - mat[3][3] * det2_45_15 + mat[3][5] * det2_45_13;
  1580. float det3_345_145 = mat[3][1] * det2_45_45 - mat[3][4] * det2_45_15 + mat[3][5] * det2_45_14;
  1581. float det3_345_234 = mat[3][2] * det2_45_34 - mat[3][3] * det2_45_24 + mat[3][4] * det2_45_23;
  1582. float det3_345_235 = mat[3][2] * det2_45_35 - mat[3][3] * det2_45_25 + mat[3][5] * det2_45_23;
  1583. float det3_345_245 = mat[3][2] * det2_45_45 - mat[3][4] * det2_45_25 + mat[3][5] * det2_45_24;
  1584. float det3_345_345 = mat[3][3] * det2_45_45 - mat[3][4] * det2_45_35 + mat[3][5] * det2_45_34;
  1585. // 4x4 sub-determinants required to calculate 6x6 determinant
  1586. float det4_2345_0123 = mat[2][0] * det3_345_123 - mat[2][1] * det3_345_023 + mat[2][2] * det3_345_013 - mat[2][3] * det3_345_012;
  1587. float det4_2345_0124 = mat[2][0] * det3_345_124 - mat[2][1] * det3_345_024 + mat[2][2] * det3_345_014 - mat[2][4] * det3_345_012;
  1588. float det4_2345_0125 = mat[2][0] * det3_345_125 - mat[2][1] * det3_345_025 + mat[2][2] * det3_345_015 - mat[2][5] * det3_345_012;
  1589. float det4_2345_0134 = mat[2][0] * det3_345_134 - mat[2][1] * det3_345_034 + mat[2][3] * det3_345_014 - mat[2][4] * det3_345_013;
  1590. float det4_2345_0135 = mat[2][0] * det3_345_135 - mat[2][1] * det3_345_035 + mat[2][3] * det3_345_015 - mat[2][5] * det3_345_013;
  1591. float det4_2345_0145 = mat[2][0] * det3_345_145 - mat[2][1] * det3_345_045 + mat[2][4] * det3_345_015 - mat[2][5] * det3_345_014;
  1592. float det4_2345_0234 = mat[2][0] * det3_345_234 - mat[2][2] * det3_345_034 + mat[2][3] * det3_345_024 - mat[2][4] * det3_345_023;
  1593. float det4_2345_0235 = mat[2][0] * det3_345_235 - mat[2][2] * det3_345_035 + mat[2][3] * det3_345_025 - mat[2][5] * det3_345_023;
  1594. float det4_2345_0245 = mat[2][0] * det3_345_245 - mat[2][2] * det3_345_045 + mat[2][4] * det3_345_025 - mat[2][5] * det3_345_024;
  1595. float det4_2345_0345 = mat[2][0] * det3_345_345 - mat[2][3] * det3_345_045 + mat[2][4] * det3_345_035 - mat[2][5] * det3_345_034;
  1596. float det4_2345_1234 = mat[2][1] * det3_345_234 - mat[2][2] * det3_345_134 + mat[2][3] * det3_345_124 - mat[2][4] * det3_345_123;
  1597. float det4_2345_1235 = mat[2][1] * det3_345_235 - mat[2][2] * det3_345_135 + mat[2][3] * det3_345_125 - mat[2][5] * det3_345_123;
  1598. float det4_2345_1245 = mat[2][1] * det3_345_245 - mat[2][2] * det3_345_145 + mat[2][4] * det3_345_125 - mat[2][5] * det3_345_124;
  1599. float det4_2345_1345 = mat[2][1] * det3_345_345 - mat[2][3] * det3_345_145 + mat[2][4] * det3_345_135 - mat[2][5] * det3_345_134;
  1600. float det4_2345_2345 = mat[2][2] * det3_345_345 - mat[2][3] * det3_345_245 + mat[2][4] * det3_345_235 - mat[2][5] * det3_345_234;
  1601. // 5x5 sub-determinants required to calculate 6x6 determinant
  1602. float det5_12345_01234 = mat[1][0] * det4_2345_1234 - mat[1][1] * det4_2345_0234 + mat[1][2] * det4_2345_0134 - mat[1][3] * det4_2345_0124 + mat[1][4] * det4_2345_0123;
  1603. float det5_12345_01235 = mat[1][0] * det4_2345_1235 - mat[1][1] * det4_2345_0235 + mat[1][2] * det4_2345_0135 - mat[1][3] * det4_2345_0125 + mat[1][5] * det4_2345_0123;
  1604. float det5_12345_01245 = mat[1][0] * det4_2345_1245 - mat[1][1] * det4_2345_0245 + mat[1][2] * det4_2345_0145 - mat[1][4] * det4_2345_0125 + mat[1][5] * det4_2345_0124;
  1605. float det5_12345_01345 = mat[1][0] * det4_2345_1345 - mat[1][1] * det4_2345_0345 + mat[1][3] * det4_2345_0145 - mat[1][4] * det4_2345_0135 + mat[1][5] * det4_2345_0134;
  1606. float det5_12345_02345 = mat[1][0] * det4_2345_2345 - mat[1][2] * det4_2345_0345 + mat[1][3] * det4_2345_0245 - mat[1][4] * det4_2345_0235 + mat[1][5] * det4_2345_0234;
  1607. float det5_12345_12345 = mat[1][1] * det4_2345_2345 - mat[1][2] * det4_2345_1345 + mat[1][3] * det4_2345_1245 - mat[1][4] * det4_2345_1235 + mat[1][5] * det4_2345_1234;
  1608. // determinant of 6x6 matrix
  1609. return mat[0][0] * det5_12345_12345 - mat[0][1] * det5_12345_02345 + mat[0][2] * det5_12345_01345 -
  1610. mat[0][3] * det5_12345_01245 + mat[0][4] * det5_12345_01235 - mat[0][5] * det5_12345_01234;
  1611. }
  1612. /*
  1613. ============
  1614. idMat6::InverseSelf
  1615. ============
  1616. */
  1617. bool idMat6::InverseSelf( void ) {
  1618. // 810+6+36 = 852 multiplications
  1619. // 1 division
  1620. double det, invDet;
  1621. // 2x2 sub-determinants required to calculate 6x6 determinant
  1622. float det2_45_01 = mat[4][0] * mat[5][1] - mat[4][1] * mat[5][0];
  1623. float det2_45_02 = mat[4][0] * mat[5][2] - mat[4][2] * mat[5][0];
  1624. float det2_45_03 = mat[4][0] * mat[5][3] - mat[4][3] * mat[5][0];
  1625. float det2_45_04 = mat[4][0] * mat[5][4] - mat[4][4] * mat[5][0];
  1626. float det2_45_05 = mat[4][0] * mat[5][5] - mat[4][5] * mat[5][0];
  1627. float det2_45_12 = mat[4][1] * mat[5][2] - mat[4][2] * mat[5][1];
  1628. float det2_45_13 = mat[4][1] * mat[5][3] - mat[4][3] * mat[5][1];
  1629. float det2_45_14 = mat[4][1] * mat[5][4] - mat[4][4] * mat[5][1];
  1630. float det2_45_15 = mat[4][1] * mat[5][5] - mat[4][5] * mat[5][1];
  1631. float det2_45_23 = mat[4][2] * mat[5][3] - mat[4][3] * mat[5][2];
  1632. float det2_45_24 = mat[4][2] * mat[5][4] - mat[4][4] * mat[5][2];
  1633. float det2_45_25 = mat[4][2] * mat[5][5] - mat[4][5] * mat[5][2];
  1634. float det2_45_34 = mat[4][3] * mat[5][4] - mat[4][4] * mat[5][3];
  1635. float det2_45_35 = mat[4][3] * mat[5][5] - mat[4][5] * mat[5][3];
  1636. float det2_45_45 = mat[4][4] * mat[5][5] - mat[4][5] * mat[5][4];
  1637. // 3x3 sub-determinants required to calculate 6x6 determinant
  1638. float det3_345_012 = mat[3][0] * det2_45_12 - mat[3][1] * det2_45_02 + mat[3][2] * det2_45_01;
  1639. float det3_345_013 = mat[3][0] * det2_45_13 - mat[3][1] * det2_45_03 + mat[3][3] * det2_45_01;
  1640. float det3_345_014 = mat[3][0] * det2_45_14 - mat[3][1] * det2_45_04 + mat[3][4] * det2_45_01;
  1641. float det3_345_015 = mat[3][0] * det2_45_15 - mat[3][1] * det2_45_05 + mat[3][5] * det2_45_01;
  1642. float det3_345_023 = mat[3][0] * det2_45_23 - mat[3][2] * det2_45_03 + mat[3][3] * det2_45_02;
  1643. float det3_345_024 = mat[3][0] * det2_45_24 - mat[3][2] * det2_45_04 + mat[3][4] * det2_45_02;
  1644. float det3_345_025 = mat[3][0] * det2_45_25 - mat[3][2] * det2_45_05 + mat[3][5] * det2_45_02;
  1645. float det3_345_034 = mat[3][0] * det2_45_34 - mat[3][3] * det2_45_04 + mat[3][4] * det2_45_03;
  1646. float det3_345_035 = mat[3][0] * det2_45_35 - mat[3][3] * det2_45_05 + mat[3][5] * det2_45_03;
  1647. float det3_345_045 = mat[3][0] * det2_45_45 - mat[3][4] * det2_45_05 + mat[3][5] * det2_45_04;
  1648. float det3_345_123 = mat[3][1] * det2_45_23 - mat[3][2] * det2_45_13 + mat[3][3] * det2_45_12;
  1649. float det3_345_124 = mat[3][1] * det2_45_24 - mat[3][2] * det2_45_14 + mat[3][4] * det2_45_12;
  1650. float det3_345_125 = mat[3][1] * det2_45_25 - mat[3][2] * det2_45_15 + mat[3][5] * det2_45_12;
  1651. float det3_345_134 = mat[3][1] * det2_45_34 - mat[3][3] * det2_45_14 + mat[3][4] * det2_45_13;
  1652. float det3_345_135 = mat[3][1] * det2_45_35 - mat[3][3] * det2_45_15 + mat[3][5] * det2_45_13;
  1653. float det3_345_145 = mat[3][1] * det2_45_45 - mat[3][4] * det2_45_15 + mat[3][5] * det2_45_14;
  1654. float det3_345_234 = mat[3][2] * det2_45_34 - mat[3][3] * det2_45_24 + mat[3][4] * det2_45_23;
  1655. float det3_345_235 = mat[3][2] * det2_45_35 - mat[3][3] * det2_45_25 + mat[3][5] * det2_45_23;
  1656. float det3_345_245 = mat[3][2] * det2_45_45 - mat[3][4] * det2_45_25 + mat[3][5] * det2_45_24;
  1657. float det3_345_345 = mat[3][3] * det2_45_45 - mat[3][4] * det2_45_35 + mat[3][5] * det2_45_34;
  1658. // 4x4 sub-determinants required to calculate 6x6 determinant
  1659. float det4_2345_0123 = mat[2][0] * det3_345_123 - mat[2][1] * det3_345_023 + mat[2][2] * det3_345_013 - mat[2][3] * det3_345_012;
  1660. float det4_2345_0124 = mat[2][0] * det3_345_124 - mat[2][1] * det3_345_024 + mat[2][2] * det3_345_014 - mat[2][4] * det3_345_012;
  1661. float det4_2345_0125 = mat[2][0] * det3_345_125 - mat[2][1] * det3_345_025 + mat[2][2] * det3_345_015 - mat[2][5] * det3_345_012;
  1662. float det4_2345_0134 = mat[2][0] * det3_345_134 - mat[2][1] * det3_345_034 + mat[2][3] * det3_345_014 - mat[2][4] * det3_345_013;
  1663. float det4_2345_0135 = mat[2][0] * det3_345_135 - mat[2][1] * det3_345_035 + mat[2][3] * det3_345_015 - mat[2][5] * det3_345_013;
  1664. float det4_2345_0145 = mat[2][0] * det3_345_145 - mat[2][1] * det3_345_045 + mat[2][4] * det3_345_015 - mat[2][5] * det3_345_014;
  1665. float det4_2345_0234 = mat[2][0] * det3_345_234 - mat[2][2] * det3_345_034 + mat[2][3] * det3_345_024 - mat[2][4] * det3_345_023;
  1666. float det4_2345_0235 = mat[2][0] * det3_345_235 - mat[2][2] * det3_345_035 + mat[2][3] * det3_345_025 - mat[2][5] * det3_345_023;
  1667. float det4_2345_0245 = mat[2][0] * det3_345_245 - mat[2][2] * det3_345_045 + mat[2][4] * det3_345_025 - mat[2][5] * det3_345_024;
  1668. float det4_2345_0345 = mat[2][0] * det3_345_345 - mat[2][3] * det3_345_045 + mat[2][4] * det3_345_035 - mat[2][5] * det3_345_034;
  1669. float det4_2345_1234 = mat[2][1] * det3_345_234 - mat[2][2] * det3_345_134 + mat[2][3] * det3_345_124 - mat[2][4] * det3_345_123;
  1670. float det4_2345_1235 = mat[2][1] * det3_345_235 - mat[2][2] * det3_345_135 + mat[2][3] * det3_345_125 - mat[2][5] * det3_345_123;
  1671. float det4_2345_1245 = mat[2][1] * det3_345_245 - mat[2][2] * det3_345_145 + mat[2][4] * det3_345_125 - mat[2][5] * det3_345_124;
  1672. float det4_2345_1345 = mat[2][1] * det3_345_345 - mat[2][3] * det3_345_145 + mat[2][4] * det3_345_135 - mat[2][5] * det3_345_134;
  1673. float det4_2345_2345 = mat[2][2] * det3_345_345 - mat[2][3] * det3_345_245 + mat[2][4] * det3_345_235 - mat[2][5] * det3_345_234;
  1674. // 5x5 sub-determinants required to calculate 6x6 determinant
  1675. float det5_12345_01234 = mat[1][0] * det4_2345_1234 - mat[1][1] * det4_2345_0234 + mat[1][2] * det4_2345_0134 - mat[1][3] * det4_2345_0124 + mat[1][4] * det4_2345_0123;
  1676. float det5_12345_01235 = mat[1][0] * det4_2345_1235 - mat[1][1] * det4_2345_0235 + mat[1][2] * det4_2345_0135 - mat[1][3] * det4_2345_0125 + mat[1][5] * det4_2345_0123;
  1677. float det5_12345_01245 = mat[1][0] * det4_2345_1245 - mat[1][1] * det4_2345_0245 + mat[1][2] * det4_2345_0145 - mat[1][4] * det4_2345_0125 + mat[1][5] * det4_2345_0124;
  1678. float det5_12345_01345 = mat[1][0] * det4_2345_1345 - mat[1][1] * det4_2345_0345 + mat[1][3] * det4_2345_0145 - mat[1][4] * det4_2345_0135 + mat[1][5] * det4_2345_0134;
  1679. float det5_12345_02345 = mat[1][0] * det4_2345_2345 - mat[1][2] * det4_2345_0345 + mat[1][3] * det4_2345_0245 - mat[1][4] * det4_2345_0235 + mat[1][5] * det4_2345_0234;
  1680. float det5_12345_12345 = mat[1][1] * det4_2345_2345 - mat[1][2] * det4_2345_1345 + mat[1][3] * det4_2345_1245 - mat[1][4] * det4_2345_1235 + mat[1][5] * det4_2345_1234;
  1681. // determinant of 6x6 matrix
  1682. det = mat[0][0] * det5_12345_12345 - mat[0][1] * det5_12345_02345 + mat[0][2] * det5_12345_01345 -
  1683. mat[0][3] * det5_12345_01245 + mat[0][4] * det5_12345_01235 - mat[0][5] * det5_12345_01234;
  1684. if ( idMath::Fabs( det ) < MATRIX_INVERSE_EPSILON ) {
  1685. return false;
  1686. }
  1687. invDet = 1.0f / det;
  1688. // remaining 2x2 sub-determinants
  1689. float det2_34_01 = mat[3][0] * mat[4][1] - mat[3][1] * mat[4][0];
  1690. float det2_34_02 = mat[3][0] * mat[4][2] - mat[3][2] * mat[4][0];
  1691. float det2_34_03 = mat[3][0] * mat[4][3] - mat[3][3] * mat[4][0];
  1692. float det2_34_04 = mat[3][0] * mat[4][4] - mat[3][4] * mat[4][0];
  1693. float det2_34_05 = mat[3][0] * mat[4][5] - mat[3][5] * mat[4][0];
  1694. float det2_34_12 = mat[3][1] * mat[4][2] - mat[3][2] * mat[4][1];
  1695. float det2_34_13 = mat[3][1] * mat[4][3] - mat[3][3] * mat[4][1];
  1696. float det2_34_14 = mat[3][1] * mat[4][4] - mat[3][4] * mat[4][1];
  1697. float det2_34_15 = mat[3][1] * mat[4][5] - mat[3][5] * mat[4][1];
  1698. float det2_34_23 = mat[3][2] * mat[4][3] - mat[3][3] * mat[4][2];
  1699. float det2_34_24 = mat[3][2] * mat[4][4] - mat[3][4] * mat[4][2];
  1700. float det2_34_25 = mat[3][2] * mat[4][5] - mat[3][5] * mat[4][2];
  1701. float det2_34_34 = mat[3][3] * mat[4][4] - mat[3][4] * mat[4][3];
  1702. float det2_34_35 = mat[3][3] * mat[4][5] - mat[3][5] * mat[4][3];
  1703. float det2_34_45 = mat[3][4] * mat[4][5] - mat[3][5] * mat[4][4];
  1704. float det2_35_01 = mat[3][0] * mat[5][1] - mat[3][1] * mat[5][0];
  1705. float det2_35_02 = mat[3][0] * mat[5][2] - mat[3][2] * mat[5][0];
  1706. float det2_35_03 = mat[3][0] * mat[5][3] - mat[3][3] * mat[5][0];
  1707. float det2_35_04 = mat[3][0] * mat[5][4] - mat[3][4] * mat[5][0];
  1708. float det2_35_05 = mat[3][0] * mat[5][5] - mat[3][5] * mat[5][0];
  1709. float det2_35_12 = mat[3][1] * mat[5][2] - mat[3][2] * mat[5][1];
  1710. float det2_35_13 = mat[3][1] * mat[5][3] - mat[3][3] * mat[5][1];
  1711. float det2_35_14 = mat[3][1] * mat[5][4] - mat[3][4] * mat[5][1];
  1712. float det2_35_15 = mat[3][1] * mat[5][5] - mat[3][5] * mat[5][1];
  1713. float det2_35_23 = mat[3][2] * mat[5][3] - mat[3][3] * mat[5][2];
  1714. float det2_35_24 = mat[3][2] * mat[5][4] - mat[3][4] * mat[5][2];
  1715. float det2_35_25 = mat[3][2] * mat[5][5] - mat[3][5] * mat[5][2];
  1716. float det2_35_34 = mat[3][3] * mat[5][4] - mat[3][4] * mat[5][3];
  1717. float det2_35_35 = mat[3][3] * mat[5][5] - mat[3][5] * mat[5][3];
  1718. float det2_35_45 = mat[3][4] * mat[5][5] - mat[3][5] * mat[5][4];
  1719. // remaining 3x3 sub-determinants
  1720. float det3_234_012 = mat[2][0] * det2_34_12 - mat[2][1] * det2_34_02 + mat[2][2] * det2_34_01;
  1721. float det3_234_013 = mat[2][0] * det2_34_13 - mat[2][1] * det2_34_03 + mat[2][3] * det2_34_01;
  1722. float det3_234_014 = mat[2][0] * det2_34_14 - mat[2][1] * det2_34_04 + mat[2][4] * det2_34_01;
  1723. float det3_234_015 = mat[2][0] * det2_34_15 - mat[2][1] * det2_34_05 + mat[2][5] * det2_34_01;
  1724. float det3_234_023 = mat[2][0] * det2_34_23 - mat[2][2] * det2_34_03 + mat[2][3] * det2_34_02;
  1725. float det3_234_024 = mat[2][0] * det2_34_24 - mat[2][2] * det2_34_04 + mat[2][4] * det2_34_02;
  1726. float det3_234_025 = mat[2][0] * det2_34_25 - mat[2][2] * det2_34_05 + mat[2][5] * det2_34_02;
  1727. float det3_234_034 = mat[2][0] * det2_34_34 - mat[2][3] * det2_34_04 + mat[2][4] * det2_34_03;
  1728. float det3_234_035 = mat[2][0] * det2_34_35 - mat[2][3] * det2_34_05 + mat[2][5] * det2_34_03;
  1729. float det3_234_045 = mat[2][0] * det2_34_45 - mat[2][4] * det2_34_05 + mat[2][5] * det2_34_04;
  1730. float det3_234_123 = mat[2][1] * det2_34_23 - mat[2][2] * det2_34_13 + mat[2][3] * det2_34_12;
  1731. float det3_234_124 = mat[2][1] * det2_34_24 - mat[2][2] * det2_34_14 + mat[2][4] * det2_34_12;
  1732. float det3_234_125 = mat[2][1] * det2_34_25 - mat[2][2] * det2_34_15 + mat[2][5] * det2_34_12;
  1733. float det3_234_134 = mat[2][1] * det2_34_34 - mat[2][3] * det2_34_14 + mat[2][4] * det2_34_13;
  1734. float det3_234_135 = mat[2][1] * det2_34_35 - mat[2][3] * det2_34_15 + mat[2][5] * det2_34_13;
  1735. float det3_234_145 = mat[2][1] * det2_34_45 - mat[2][4] * det2_34_15 + mat[2][5] * det2_34_14;
  1736. float det3_234_234 = mat[2][2] * det2_34_34 - mat[2][3] * det2_34_24 + mat[2][4] * det2_34_23;
  1737. float det3_234_235 = mat[2][2] * det2_34_35 - mat[2][3] * det2_34_25 + mat[2][5] * det2_34_23;
  1738. float det3_234_245 = mat[2][2] * det2_34_45 - mat[2][4] * det2_34_25 + mat[2][5] * det2_34_24;
  1739. float det3_234_345 = mat[2][3] * det2_34_45 - mat[2][4] * det2_34_35 + mat[2][5] * det2_34_34;
  1740. float det3_235_012 = mat[2][0] * det2_35_12 - mat[2][1] * det2_35_02 + mat[2][2] * det2_35_01;
  1741. float det3_235_013 = mat[2][0] * det2_35_13 - mat[2][1] * det2_35_03 + mat[2][3] * det2_35_01;
  1742. float det3_235_014 = mat[2][0] * det2_35_14 - mat[2][1] * det2_35_04 + mat[2][4] * det2_35_01;
  1743. float det3_235_015 = mat[2][0] * det2_35_15 - mat[2][1] * det2_35_05 + mat[2][5] * det2_35_01;
  1744. float det3_235_023 = mat[2][0] * det2_35_23 - mat[2][2] * det2_35_03 + mat[2][3] * det2_35_02;
  1745. float det3_235_024 = mat[2][0] * det2_35_24 - mat[2][2] * det2_35_04 + mat[2][4] * det2_35_02;
  1746. float det3_235_025 = mat[2][0] * det2_35_25 - mat[2][2] * det2_35_05 + mat[2][5] * det2_35_02;
  1747. float det3_235_034 = mat[2][0] * det2_35_34 - mat[2][3] * det2_35_04 + mat[2][4] * det2_35_03;
  1748. float det3_235_035 = mat[2][0] * det2_35_35 - mat[2][3] * det2_35_05 + mat[2][5] * det2_35_03;
  1749. float det3_235_045 = mat[2][0] * det2_35_45 - mat[2][4] * det2_35_05 + mat[2][5] * det2_35_04;
  1750. float det3_235_123 = mat[2][1] * det2_35_23 - mat[2][2] * det2_35_13 + mat[2][3] * det2_35_12;
  1751. float det3_235_124 = mat[2][1] * det2_35_24 - mat[2][2] * det2_35_14 + mat[2][4] * det2_35_12;
  1752. float det3_235_125 = mat[2][1] * det2_35_25 - mat[2][2] * det2_35_15 + mat[2][5] * det2_35_12;
  1753. float det3_235_134 = mat[2][1] * det2_35_34 - mat[2][3] * det2_35_14 + mat[2][4] * det2_35_13;
  1754. float det3_235_135 = mat[2][1] * det2_35_35 - mat[2][3] * det2_35_15 + mat[2][5] * det2_35_13;
  1755. float det3_235_145 = mat[2][1] * det2_35_45 - mat[2][4] * det2_35_15 + mat[2][5] * det2_35_14;
  1756. float det3_235_234 = mat[2][2] * det2_35_34 - mat[2][3] * det2_35_24 + mat[2][4] * det2_35_23;
  1757. float det3_235_235 = mat[2][2] * det2_35_35 - mat[2][3] * det2_35_25 + mat[2][5] * det2_35_23;
  1758. float det3_235_245 = mat[2][2] * det2_35_45 - mat[2][4] * det2_35_25 + mat[2][5] * det2_35_24;
  1759. float det3_235_345 = mat[2][3] * det2_35_45 - mat[2][4] * det2_35_35 + mat[2][5] * det2_35_34;
  1760. float det3_245_012 = mat[2][0] * det2_45_12 - mat[2][1] * det2_45_02 + mat[2][2] * det2_45_01;
  1761. float det3_245_013 = mat[2][0] * det2_45_13 - mat[2][1] * det2_45_03 + mat[2][3] * det2_45_01;
  1762. float det3_245_014 = mat[2][0] * det2_45_14 - mat[2][1] * det2_45_04 + mat[2][4] * det2_45_01;
  1763. float det3_245_015 = mat[2][0] * det2_45_15 - mat[2][1] * det2_45_05 + mat[2][5] * det2_45_01;
  1764. float det3_245_023 = mat[2][0] * det2_45_23 - mat[2][2] * det2_45_03 + mat[2][3] * det2_45_02;
  1765. float det3_245_024 = mat[2][0] * det2_45_24 - mat[2][2] * det2_45_04 + mat[2][4] * det2_45_02;
  1766. float det3_245_025 = mat[2][0] * det2_45_25 - mat[2][2] * det2_45_05 + mat[2][5] * det2_45_02;
  1767. float det3_245_034 = mat[2][0] * det2_45_34 - mat[2][3] * det2_45_04 + mat[2][4] * det2_45_03;
  1768. float det3_245_035 = mat[2][0] * det2_45_35 - mat[2][3] * det2_45_05 + mat[2][5] * det2_45_03;
  1769. float det3_245_045 = mat[2][0] * det2_45_45 - mat[2][4] * det2_45_05 + mat[2][5] * det2_45_04;
  1770. float det3_245_123 = mat[2][1] * det2_45_23 - mat[2][2] * det2_45_13 + mat[2][3] * det2_45_12;
  1771. float det3_245_124 = mat[2][1] * det2_45_24 - mat[2][2] * det2_45_14 + mat[2][4] * det2_45_12;
  1772. float det3_245_125 = mat[2][1] * det2_45_25 - mat[2][2] * det2_45_15 + mat[2][5] * det2_45_12;
  1773. float det3_245_134 = mat[2][1] * det2_45_34 - mat[2][3] * det2_45_14 + mat[2][4] * det2_45_13;
  1774. float det3_245_135 = mat[2][1] * det2_45_35 - mat[2][3] * det2_45_15 + mat[2][5] * det2_45_13;
  1775. float det3_245_145 = mat[2][1] * det2_45_45 - mat[2][4] * det2_45_15 + mat[2][5] * det2_45_14;
  1776. float det3_245_234 = mat[2][2] * det2_45_34 - mat[2][3] * det2_45_24 + mat[2][4] * det2_45_23;
  1777. float det3_245_235 = mat[2][2] * det2_45_35 - mat[2][3] * det2_45_25 + mat[2][5] * det2_45_23;
  1778. float det3_245_245 = mat[2][2] * det2_45_45 - mat[2][4] * det2_45_25 + mat[2][5] * det2_45_24;
  1779. float det3_245_345 = mat[2][3] * det2_45_45 - mat[2][4] * det2_45_35 + mat[2][5] * det2_45_34;
  1780. // remaining 4x4 sub-determinants
  1781. float det4_1234_0123 = mat[1][0] * det3_234_123 - mat[1][1] * det3_234_023 + mat[1][2] * det3_234_013 - mat[1][3] * det3_234_012;
  1782. float det4_1234_0124 = mat[1][0] * det3_234_124 - mat[1][1] * det3_234_024 + mat[1][2] * det3_234_014 - mat[1][4] * det3_234_012;
  1783. float det4_1234_0125 = mat[1][0] * det3_234_125 - mat[1][1] * det3_234_025 + mat[1][2] * det3_234_015 - mat[1][5] * det3_234_012;
  1784. float det4_1234_0134 = mat[1][0] * det3_234_134 - mat[1][1] * det3_234_034 + mat[1][3] * det3_234_014 - mat[1][4] * det3_234_013;
  1785. float det4_1234_0135 = mat[1][0] * det3_234_135 - mat[1][1] * det3_234_035 + mat[1][3] * det3_234_015 - mat[1][5] * det3_234_013;
  1786. float det4_1234_0145 = mat[1][0] * det3_234_145 - mat[1][1] * det3_234_045 + mat[1][4] * det3_234_015 - mat[1][5] * det3_234_014;
  1787. float det4_1234_0234 = mat[1][0] * det3_234_234 - mat[1][2] * det3_234_034 + mat[1][3] * det3_234_024 - mat[1][4] * det3_234_023;
  1788. float det4_1234_0235 = mat[1][0] * det3_234_235 - mat[1][2] * det3_234_035 + mat[1][3] * det3_234_025 - mat[1][5] * det3_234_023;
  1789. float det4_1234_0245 = mat[1][0] * det3_234_245 - mat[1][2] * det3_234_045 + mat[1][4] * det3_234_025 - mat[1][5] * det3_234_024;
  1790. float det4_1234_0345 = mat[1][0] * det3_234_345 - mat[1][3] * det3_234_045 + mat[1][4] * det3_234_035 - mat[1][5] * det3_234_034;
  1791. float det4_1234_1234 = mat[1][1] * det3_234_234 - mat[1][2] * det3_234_134 + mat[1][3] * det3_234_124 - mat[1][4] * det3_234_123;
  1792. float det4_1234_1235 = mat[1][1] * det3_234_235 - mat[1][2] * det3_234_135 + mat[1][3] * det3_234_125 - mat[1][5] * det3_234_123;
  1793. float det4_1234_1245 = mat[1][1] * det3_234_245 - mat[1][2] * det3_234_145 + mat[1][4] * det3_234_125 - mat[1][5] * det3_234_124;
  1794. float det4_1234_1345 = mat[1][1] * det3_234_345 - mat[1][3] * det3_234_145 + mat[1][4] * det3_234_135 - mat[1][5] * det3_234_134;
  1795. float det4_1234_2345 = mat[1][2] * det3_234_345 - mat[1][3] * det3_234_245 + mat[1][4] * det3_234_235 - mat[1][5] * det3_234_234;
  1796. float det4_1235_0123 = mat[1][0] * det3_235_123 - mat[1][1] * det3_235_023 + mat[1][2] * det3_235_013 - mat[1][3] * det3_235_012;
  1797. float det4_1235_0124 = mat[1][0] * det3_235_124 - mat[1][1] * det3_235_024 + mat[1][2] * det3_235_014 - mat[1][4] * det3_235_012;
  1798. float det4_1235_0125 = mat[1][0] * det3_235_125 - mat[1][1] * det3_235_025 + mat[1][2] * det3_235_015 - mat[1][5] * det3_235_012;
  1799. float det4_1235_0134 = mat[1][0] * det3_235_134 - mat[1][1] * det3_235_034 + mat[1][3] * det3_235_014 - mat[1][4] * det3_235_013;
  1800. float det4_1235_0135 = mat[1][0] * det3_235_135 - mat[1][1] * det3_235_035 + mat[1][3] * det3_235_015 - mat[1][5] * det3_235_013;
  1801. float det4_1235_0145 = mat[1][0] * det3_235_145 - mat[1][1] * det3_235_045 + mat[1][4] * det3_235_015 - mat[1][5] * det3_235_014;
  1802. float det4_1235_0234 = mat[1][0] * det3_235_234 - mat[1][2] * det3_235_034 + mat[1][3] * det3_235_024 - mat[1][4] * det3_235_023;
  1803. float det4_1235_0235 = mat[1][0] * det3_235_235 - mat[1][2] * det3_235_035 + mat[1][3] * det3_235_025 - mat[1][5] * det3_235_023;
  1804. float det4_1235_0245 = mat[1][0] * det3_235_245 - mat[1][2] * det3_235_045 + mat[1][4] * det3_235_025 - mat[1][5] * det3_235_024;
  1805. float det4_1235_0345 = mat[1][0] * det3_235_345 - mat[1][3] * det3_235_045 + mat[1][4] * det3_235_035 - mat[1][5] * det3_235_034;
  1806. float det4_1235_1234 = mat[1][1] * det3_235_234 - mat[1][2] * det3_235_134 + mat[1][3] * det3_235_124 - mat[1][4] * det3_235_123;
  1807. float det4_1235_1235 = mat[1][1] * det3_235_235 - mat[1][2] * det3_235_135 + mat[1][3] * det3_235_125 - mat[1][5] * det3_235_123;
  1808. float det4_1235_1245 = mat[1][1] * det3_235_245 - mat[1][2] * det3_235_145 + mat[1][4] * det3_235_125 - mat[1][5] * det3_235_124;
  1809. float det4_1235_1345 = mat[1][1] * det3_235_345 - mat[1][3] * det3_235_145 + mat[1][4] * det3_235_135 - mat[1][5] * det3_235_134;
  1810. float det4_1235_2345 = mat[1][2] * det3_235_345 - mat[1][3] * det3_235_245 + mat[1][4] * det3_235_235 - mat[1][5] * det3_235_234;
  1811. float det4_1245_0123 = mat[1][0] * det3_245_123 - mat[1][1] * det3_245_023 + mat[1][2] * det3_245_013 - mat[1][3] * det3_245_012;
  1812. float det4_1245_0124 = mat[1][0] * det3_245_124 - mat[1][1] * det3_245_024 + mat[1][2] * det3_245_014 - mat[1][4] * det3_245_012;
  1813. float det4_1245_0125 = mat[1][0] * det3_245_125 - mat[1][1] * det3_245_025 + mat[1][2] * det3_245_015 - mat[1][5] * det3_245_012;
  1814. float det4_1245_0134 = mat[1][0] * det3_245_134 - mat[1][1] * det3_245_034 + mat[1][3] * det3_245_014 - mat[1][4] * det3_245_013;
  1815. float det4_1245_0135 = mat[1][0] * det3_245_135 - mat[1][1] * det3_245_035 + mat[1][3] * det3_245_015 - mat[1][5] * det3_245_013;
  1816. float det4_1245_0145 = mat[1][0] * det3_245_145 - mat[1][1] * det3_245_045 + mat[1][4] * det3_245_015 - mat[1][5] * det3_245_014;
  1817. float det4_1245_0234 = mat[1][0] * det3_245_234 - mat[1][2] * det3_245_034 + mat[1][3] * det3_245_024 - mat[1][4] * det3_245_023;
  1818. float det4_1245_0235 = mat[1][0] * det3_245_235 - mat[1][2] * det3_245_035 + mat[1][3] * det3_245_025 - mat[1][5] * det3_245_023;
  1819. float det4_1245_0245 = mat[1][0] * det3_245_245 - mat[1][2] * det3_245_045 + mat[1][4] * det3_245_025 - mat[1][5] * det3_245_024;
  1820. float det4_1245_0345 = mat[1][0] * det3_245_345 - mat[1][3] * det3_245_045 + mat[1][4] * det3_245_035 - mat[1][5] * det3_245_034;
  1821. float det4_1245_1234 = mat[1][1] * det3_245_234 - mat[1][2] * det3_245_134 + mat[1][3] * det3_245_124 - mat[1][4] * det3_245_123;
  1822. float det4_1245_1235 = mat[1][1] * det3_245_235 - mat[1][2] * det3_245_135 + mat[1][3] * det3_245_125 - mat[1][5] * det3_245_123;
  1823. float det4_1245_1245 = mat[1][1] * det3_245_245 - mat[1][2] * det3_245_145 + mat[1][4] * det3_245_125 - mat[1][5] * det3_245_124;
  1824. float det4_1245_1345 = mat[1][1] * det3_245_345 - mat[1][3] * det3_245_145 + mat[1][4] * det3_245_135 - mat[1][5] * det3_245_134;
  1825. float det4_1245_2345 = mat[1][2] * det3_245_345 - mat[1][3] * det3_245_245 + mat[1][4] * det3_245_235 - mat[1][5] * det3_245_234;
  1826. float det4_1345_0123 = mat[1][0] * det3_345_123 - mat[1][1] * det3_345_023 + mat[1][2] * det3_345_013 - mat[1][3] * det3_345_012;
  1827. float det4_1345_0124 = mat[1][0] * det3_345_124 - mat[1][1] * det3_345_024 + mat[1][2] * det3_345_014 - mat[1][4] * det3_345_012;
  1828. float det4_1345_0125 = mat[1][0] * det3_345_125 - mat[1][1] * det3_345_025 + mat[1][2] * det3_345_015 - mat[1][5] * det3_345_012;
  1829. float det4_1345_0134 = mat[1][0] * det3_345_134 - mat[1][1] * det3_345_034 + mat[1][3] * det3_345_014 - mat[1][4] * det3_345_013;
  1830. float det4_1345_0135 = mat[1][0] * det3_345_135 - mat[1][1] * det3_345_035 + mat[1][3] * det3_345_015 - mat[1][5] * det3_345_013;
  1831. float det4_1345_0145 = mat[1][0] * det3_345_145 - mat[1][1] * det3_345_045 + mat[1][4] * det3_345_015 - mat[1][5] * det3_345_014;
  1832. float det4_1345_0234 = mat[1][0] * det3_345_234 - mat[1][2] * det3_345_034 + mat[1][3] * det3_345_024 - mat[1][4] * det3_345_023;
  1833. float det4_1345_0235 = mat[1][0] * det3_345_235 - mat[1][2] * det3_345_035 + mat[1][3] * det3_345_025 - mat[1][5] * det3_345_023;
  1834. float det4_1345_0245 = mat[1][0] * det3_345_245 - mat[1][2] * det3_345_045 + mat[1][4] * det3_345_025 - mat[1][5] * det3_345_024;
  1835. float det4_1345_0345 = mat[1][0] * det3_345_345 - mat[1][3] * det3_345_045 + mat[1][4] * det3_345_035 - mat[1][5] * det3_345_034;
  1836. float det4_1345_1234 = mat[1][1] * det3_345_234 - mat[1][2] * det3_345_134 + mat[1][3] * det3_345_124 - mat[1][4] * det3_345_123;
  1837. float det4_1345_1235 = mat[1][1] * det3_345_235 - mat[1][2] * det3_345_135 + mat[1][3] * det3_345_125 - mat[1][5] * det3_345_123;
  1838. float det4_1345_1245 = mat[1][1] * det3_345_245 - mat[1][2] * det3_345_145 + mat[1][4] * det3_345_125 - mat[1][5] * det3_345_124;
  1839. float det4_1345_1345 = mat[1][1] * det3_345_345 - mat[1][3] * det3_345_145 + mat[1][4] * det3_345_135 - mat[1][5] * det3_345_134;
  1840. float det4_1345_2345 = mat[1][2] * det3_345_345 - mat[1][3] * det3_345_245 + mat[1][4] * det3_345_235 - mat[1][5] * det3_345_234;
  1841. // remaining 5x5 sub-determinants
  1842. float det5_01234_01234 = mat[0][0] * det4_1234_1234 - mat[0][1] * det4_1234_0234 + mat[0][2] * det4_1234_0134 - mat[0][3] * det4_1234_0124 + mat[0][4] * det4_1234_0123;
  1843. float det5_01234_01235 = mat[0][0] * det4_1234_1235 - mat[0][1] * det4_1234_0235 + mat[0][2] * det4_1234_0135 - mat[0][3] * det4_1234_0125 + mat[0][5] * det4_1234_0123;
  1844. float det5_01234_01245 = mat[0][0] * det4_1234_1245 - mat[0][1] * det4_1234_0245 + mat[0][2] * det4_1234_0145 - mat[0][4] * det4_1234_0125 + mat[0][5] * det4_1234_0124;
  1845. float det5_01234_01345 = mat[0][0] * det4_1234_1345 - mat[0][1] * det4_1234_0345 + mat[0][3] * det4_1234_0145 - mat[0][4] * det4_1234_0135 + mat[0][5] * det4_1234_0134;
  1846. float det5_01234_02345 = mat[0][0] * det4_1234_2345 - mat[0][2] * det4_1234_0345 + mat[0][3] * det4_1234_0245 - mat[0][4] * det4_1234_0235 + mat[0][5] * det4_1234_0234;
  1847. float det5_01234_12345 = mat[0][1] * det4_1234_2345 - mat[0][2] * det4_1234_1345 + mat[0][3] * det4_1234_1245 - mat[0][4] * det4_1234_1235 + mat[0][5] * det4_1234_1234;
  1848. float det5_01235_01234 = mat[0][0] * det4_1235_1234 - mat[0][1] * det4_1235_0234 + mat[0][2] * det4_1235_0134 - mat[0][3] * det4_1235_0124 + mat[0][4] * det4_1235_0123;
  1849. float det5_01235_01235 = mat[0][0] * det4_1235_1235 - mat[0][1] * det4_1235_0235 + mat[0][2] * det4_1235_0135 - mat[0][3] * det4_1235_0125 + mat[0][5] * det4_1235_0123;
  1850. float det5_01235_01245 = mat[0][0] * det4_1235_1245 - mat[0][1] * det4_1235_0245 + mat[0][2] * det4_1235_0145 - mat[0][4] * det4_1235_0125 + mat[0][5] * det4_1235_0124;
  1851. float det5_01235_01345 = mat[0][0] * det4_1235_1345 - mat[0][1] * det4_1235_0345 + mat[0][3] * det4_1235_0145 - mat[0][4] * det4_1235_0135 + mat[0][5] * det4_1235_0134;
  1852. float det5_01235_02345 = mat[0][0] * det4_1235_2345 - mat[0][2] * det4_1235_0345 + mat[0][3] * det4_1235_0245 - mat[0][4] * det4_1235_0235 + mat[0][5] * det4_1235_0234;
  1853. float det5_01235_12345 = mat[0][1] * det4_1235_2345 - mat[0][2] * det4_1235_1345 + mat[0][3] * det4_1235_1245 - mat[0][4] * det4_1235_1235 + mat[0][5] * det4_1235_1234;
  1854. float det5_01245_01234 = mat[0][0] * det4_1245_1234 - mat[0][1] * det4_1245_0234 + mat[0][2] * det4_1245_0134 - mat[0][3] * det4_1245_0124 + mat[0][4] * det4_1245_0123;
  1855. float det5_01245_01235 = mat[0][0] * det4_1245_1235 - mat[0][1] * det4_1245_0235 + mat[0][2] * det4_1245_0135 - mat[0][3] * det4_1245_0125 + mat[0][5] * det4_1245_0123;
  1856. float det5_01245_01245 = mat[0][0] * det4_1245_1245 - mat[0][1] * det4_1245_0245 + mat[0][2] * det4_1245_0145 - mat[0][4] * det4_1245_0125 + mat[0][5] * det4_1245_0124;
  1857. float det5_01245_01345 = mat[0][0] * det4_1245_1345 - mat[0][1] * det4_1245_0345 + mat[0][3] * det4_1245_0145 - mat[0][4] * det4_1245_0135 + mat[0][5] * det4_1245_0134;
  1858. float det5_01245_02345 = mat[0][0] * det4_1245_2345 - mat[0][2] * det4_1245_0345 + mat[0][3] * det4_1245_0245 - mat[0][4] * det4_1245_0235 + mat[0][5] * det4_1245_0234;
  1859. float det5_01245_12345 = mat[0][1] * det4_1245_2345 - mat[0][2] * det4_1245_1345 + mat[0][3] * det4_1245_1245 - mat[0][4] * det4_1245_1235 + mat[0][5] * det4_1245_1234;
  1860. float det5_01345_01234 = mat[0][0] * det4_1345_1234 - mat[0][1] * det4_1345_0234 + mat[0][2] * det4_1345_0134 - mat[0][3] * det4_1345_0124 + mat[0][4] * det4_1345_0123;
  1861. float det5_01345_01235 = mat[0][0] * det4_1345_1235 - mat[0][1] * det4_1345_0235 + mat[0][2] * det4_1345_0135 - mat[0][3] * det4_1345_0125 + mat[0][5] * det4_1345_0123;
  1862. float det5_01345_01245 = mat[0][0] * det4_1345_1245 - mat[0][1] * det4_1345_0245 + mat[0][2] * det4_1345_0145 - mat[0][4] * det4_1345_0125 + mat[0][5] * det4_1345_0124;
  1863. float det5_01345_01345 = mat[0][0] * det4_1345_1345 - mat[0][1] * det4_1345_0345 + mat[0][3] * det4_1345_0145 - mat[0][4] * det4_1345_0135 + mat[0][5] * det4_1345_0134;
  1864. float det5_01345_02345 = mat[0][0] * det4_1345_2345 - mat[0][2] * det4_1345_0345 + mat[0][3] * det4_1345_0245 - mat[0][4] * det4_1345_0235 + mat[0][5] * det4_1345_0234;
  1865. float det5_01345_12345 = mat[0][1] * det4_1345_2345 - mat[0][2] * det4_1345_1345 + mat[0][3] * det4_1345_1245 - mat[0][4] * det4_1345_1235 + mat[0][5] * det4_1345_1234;
  1866. float det5_02345_01234 = mat[0][0] * det4_2345_1234 - mat[0][1] * det4_2345_0234 + mat[0][2] * det4_2345_0134 - mat[0][3] * det4_2345_0124 + mat[0][4] * det4_2345_0123;
  1867. float det5_02345_01235 = mat[0][0] * det4_2345_1235 - mat[0][1] * det4_2345_0235 + mat[0][2] * det4_2345_0135 - mat[0][3] * det4_2345_0125 + mat[0][5] * det4_2345_0123;
  1868. float det5_02345_01245 = mat[0][0] * det4_2345_1245 - mat[0][1] * det4_2345_0245 + mat[0][2] * det4_2345_0145 - mat[0][4] * det4_2345_0125 + mat[0][5] * det4_2345_0124;
  1869. float det5_02345_01345 = mat[0][0] * det4_2345_1345 - mat[0][1] * det4_2345_0345 + mat[0][3] * det4_2345_0145 - mat[0][4] * det4_2345_0135 + mat[0][5] * det4_2345_0134;
  1870. float det5_02345_02345 = mat[0][0] * det4_2345_2345 - mat[0][2] * det4_2345_0345 + mat[0][3] * det4_2345_0245 - mat[0][4] * det4_2345_0235 + mat[0][5] * det4_2345_0234;
  1871. float det5_02345_12345 = mat[0][1] * det4_2345_2345 - mat[0][2] * det4_2345_1345 + mat[0][3] * det4_2345_1245 - mat[0][4] * det4_2345_1235 + mat[0][5] * det4_2345_1234;
  1872. mat[0][0] = det5_12345_12345 * invDet;
  1873. mat[0][1] = -det5_02345_12345 * invDet;
  1874. mat[0][2] = det5_01345_12345 * invDet;
  1875. mat[0][3] = -det5_01245_12345 * invDet;
  1876. mat[0][4] = det5_01235_12345 * invDet;
  1877. mat[0][5] = -det5_01234_12345 * invDet;
  1878. mat[1][0] = -det5_12345_02345 * invDet;
  1879. mat[1][1] = det5_02345_02345 * invDet;
  1880. mat[1][2] = -det5_01345_02345 * invDet;
  1881. mat[1][3] = det5_01245_02345 * invDet;
  1882. mat[1][4] = -det5_01235_02345 * invDet;
  1883. mat[1][5] = det5_01234_02345 * invDet;
  1884. mat[2][0] = det5_12345_01345 * invDet;
  1885. mat[2][1] = -det5_02345_01345 * invDet;
  1886. mat[2][2] = det5_01345_01345 * invDet;
  1887. mat[2][3] = -det5_01245_01345 * invDet;
  1888. mat[2][4] = det5_01235_01345 * invDet;
  1889. mat[2][5] = -det5_01234_01345 * invDet;
  1890. mat[3][0] = -det5_12345_01245 * invDet;
  1891. mat[3][1] = det5_02345_01245 * invDet;
  1892. mat[3][2] = -det5_01345_01245 * invDet;
  1893. mat[3][3] = det5_01245_01245 * invDet;
  1894. mat[3][4] = -det5_01235_01245 * invDet;
  1895. mat[3][5] = det5_01234_01245 * invDet;
  1896. mat[4][0] = det5_12345_01235 * invDet;
  1897. mat[4][1] = -det5_02345_01235 * invDet;
  1898. mat[4][2] = det5_01345_01235 * invDet;
  1899. mat[4][3] = -det5_01245_01235 * invDet;
  1900. mat[4][4] = det5_01235_01235 * invDet;
  1901. mat[4][5] = -det5_01234_01235 * invDet;
  1902. mat[5][0] = -det5_12345_01234 * invDet;
  1903. mat[5][1] = det5_02345_01234 * invDet;
  1904. mat[5][2] = -det5_01345_01234 * invDet;
  1905. mat[5][3] = det5_01245_01234 * invDet;
  1906. mat[5][4] = -det5_01235_01234 * invDet;
  1907. mat[5][5] = det5_01234_01234 * invDet;
  1908. return true;
  1909. }
  1910. /*
  1911. ============
  1912. idMat6::InverseFastSelf
  1913. ============
  1914. */
  1915. bool idMat6::InverseFastSelf( void ) {
  1916. #if 0
  1917. // 810+6+36 = 852 multiplications
  1918. // 1 division
  1919. double det, invDet;
  1920. // 2x2 sub-determinants required to calculate 6x6 determinant
  1921. float det2_45_01 = mat[4][0] * mat[5][1] - mat[4][1] * mat[5][0];
  1922. float det2_45_02 = mat[4][0] * mat[5][2] - mat[4][2] * mat[5][0];
  1923. float det2_45_03 = mat[4][0] * mat[5][3] - mat[4][3] * mat[5][0];
  1924. float det2_45_04 = mat[4][0] * mat[5][4] - mat[4][4] * mat[5][0];
  1925. float det2_45_05 = mat[4][0] * mat[5][5] - mat[4][5] * mat[5][0];
  1926. float det2_45_12 = mat[4][1] * mat[5][2] - mat[4][2] * mat[5][1];
  1927. float det2_45_13 = mat[4][1] * mat[5][3] - mat[4][3] * mat[5][1];
  1928. float det2_45_14 = mat[4][1] * mat[5][4] - mat[4][4] * mat[5][1];
  1929. float det2_45_15 = mat[4][1] * mat[5][5] - mat[4][5] * mat[5][1];
  1930. float det2_45_23 = mat[4][2] * mat[5][3] - mat[4][3] * mat[5][2];
  1931. float det2_45_24 = mat[4][2] * mat[5][4] - mat[4][4] * mat[5][2];
  1932. float det2_45_25 = mat[4][2] * mat[5][5] - mat[4][5] * mat[5][2];
  1933. float det2_45_34 = mat[4][3] * mat[5][4] - mat[4][4] * mat[5][3];
  1934. float det2_45_35 = mat[4][3] * mat[5][5] - mat[4][5] * mat[5][3];
  1935. float det2_45_45 = mat[4][4] * mat[5][5] - mat[4][5] * mat[5][4];
  1936. // 3x3 sub-determinants required to calculate 6x6 determinant
  1937. float det3_345_012 = mat[3][0] * det2_45_12 - mat[3][1] * det2_45_02 + mat[3][2] * det2_45_01;
  1938. float det3_345_013 = mat[3][0] * det2_45_13 - mat[3][1] * det2_45_03 + mat[3][3] * det2_45_01;
  1939. float det3_345_014 = mat[3][0] * det2_45_14 - mat[3][1] * det2_45_04 + mat[3][4] * det2_45_01;
  1940. float det3_345_015 = mat[3][0] * det2_45_15 - mat[3][1] * det2_45_05 + mat[3][5] * det2_45_01;
  1941. float det3_345_023 = mat[3][0] * det2_45_23 - mat[3][2] * det2_45_03 + mat[3][3] * det2_45_02;
  1942. float det3_345_024 = mat[3][0] * det2_45_24 - mat[3][2] * det2_45_04 + mat[3][4] * det2_45_02;
  1943. float det3_345_025 = mat[3][0] * det2_45_25 - mat[3][2] * det2_45_05 + mat[3][5] * det2_45_02;
  1944. float det3_345_034 = mat[3][0] * det2_45_34 - mat[3][3] * det2_45_04 + mat[3][4] * det2_45_03;
  1945. float det3_345_035 = mat[3][0] * det2_45_35 - mat[3][3] * det2_45_05 + mat[3][5] * det2_45_03;
  1946. float det3_345_045 = mat[3][0] * det2_45_45 - mat[3][4] * det2_45_05 + mat[3][5] * det2_45_04;
  1947. float det3_345_123 = mat[3][1] * det2_45_23 - mat[3][2] * det2_45_13 + mat[3][3] * det2_45_12;
  1948. float det3_345_124 = mat[3][1] * det2_45_24 - mat[3][2] * det2_45_14 + mat[3][4] * det2_45_12;
  1949. float det3_345_125 = mat[3][1] * det2_45_25 - mat[3][2] * det2_45_15 + mat[3][5] * det2_45_12;
  1950. float det3_345_134 = mat[3][1] * det2_45_34 - mat[3][3] * det2_45_14 + mat[3][4] * det2_45_13;
  1951. float det3_345_135 = mat[3][1] * det2_45_35 - mat[3][3] * det2_45_15 + mat[3][5] * det2_45_13;
  1952. float det3_345_145 = mat[3][1] * det2_45_45 - mat[3][4] * det2_45_15 + mat[3][5] * det2_45_14;
  1953. float det3_345_234 = mat[3][2] * det2_45_34 - mat[3][3] * det2_45_24 + mat[3][4] * det2_45_23;
  1954. float det3_345_235 = mat[3][2] * det2_45_35 - mat[3][3] * det2_45_25 + mat[3][5] * det2_45_23;
  1955. float det3_345_245 = mat[3][2] * det2_45_45 - mat[3][4] * det2_45_25 + mat[3][5] * det2_45_24;
  1956. float det3_345_345 = mat[3][3] * det2_45_45 - mat[3][4] * det2_45_35 + mat[3][5] * det2_45_34;
  1957. // 4x4 sub-determinants required to calculate 6x6 determinant
  1958. float det4_2345_0123 = mat[2][0] * det3_345_123 - mat[2][1] * det3_345_023 + mat[2][2] * det3_345_013 - mat[2][3] * det3_345_012;
  1959. float det4_2345_0124 = mat[2][0] * det3_345_124 - mat[2][1] * det3_345_024 + mat[2][2] * det3_345_014 - mat[2][4] * det3_345_012;
  1960. float det4_2345_0125 = mat[2][0] * det3_345_125 - mat[2][1] * det3_345_025 + mat[2][2] * det3_345_015 - mat[2][5] * det3_345_012;
  1961. float det4_2345_0134 = mat[2][0] * det3_345_134 - mat[2][1] * det3_345_034 + mat[2][3] * det3_345_014 - mat[2][4] * det3_345_013;
  1962. float det4_2345_0135 = mat[2][0] * det3_345_135 - mat[2][1] * det3_345_035 + mat[2][3] * det3_345_015 - mat[2][5] * det3_345_013;
  1963. float det4_2345_0145 = mat[2][0] * det3_345_145 - mat[2][1] * det3_345_045 + mat[2][4] * det3_345_015 - mat[2][5] * det3_345_014;
  1964. float det4_2345_0234 = mat[2][0] * det3_345_234 - mat[2][2] * det3_345_034 + mat[2][3] * det3_345_024 - mat[2][4] * det3_345_023;
  1965. float det4_2345_0235 = mat[2][0] * det3_345_235 - mat[2][2] * det3_345_035 + mat[2][3] * det3_345_025 - mat[2][5] * det3_345_023;
  1966. float det4_2345_0245 = mat[2][0] * det3_345_245 - mat[2][2] * det3_345_045 + mat[2][4] * det3_345_025 - mat[2][5] * det3_345_024;
  1967. float det4_2345_0345 = mat[2][0] * det3_345_345 - mat[2][3] * det3_345_045 + mat[2][4] * det3_345_035 - mat[2][5] * det3_345_034;
  1968. float det4_2345_1234 = mat[2][1] * det3_345_234 - mat[2][2] * det3_345_134 + mat[2][3] * det3_345_124 - mat[2][4] * det3_345_123;
  1969. float det4_2345_1235 = mat[2][1] * det3_345_235 - mat[2][2] * det3_345_135 + mat[2][3] * det3_345_125 - mat[2][5] * det3_345_123;
  1970. float det4_2345_1245 = mat[2][1] * det3_345_245 - mat[2][2] * det3_345_145 + mat[2][4] * det3_345_125 - mat[2][5] * det3_345_124;
  1971. float det4_2345_1345 = mat[2][1] * det3_345_345 - mat[2][3] * det3_345_145 + mat[2][4] * det3_345_135 - mat[2][5] * det3_345_134;
  1972. float det4_2345_2345 = mat[2][2] * det3_345_345 - mat[2][3] * det3_345_245 + mat[2][4] * det3_345_235 - mat[2][5] * det3_345_234;
  1973. // 5x5 sub-determinants required to calculate 6x6 determinant
  1974. float det5_12345_01234 = mat[1][0] * det4_2345_1234 - mat[1][1] * det4_2345_0234 + mat[1][2] * det4_2345_0134 - mat[1][3] * det4_2345_0124 + mat[1][4] * det4_2345_0123;
  1975. float det5_12345_01235 = mat[1][0] * det4_2345_1235 - mat[1][1] * det4_2345_0235 + mat[1][2] * det4_2345_0135 - mat[1][3] * det4_2345_0125 + mat[1][5] * det4_2345_0123;
  1976. float det5_12345_01245 = mat[1][0] * det4_2345_1245 - mat[1][1] * det4_2345_0245 + mat[1][2] * det4_2345_0145 - mat[1][4] * det4_2345_0125 + mat[1][5] * det4_2345_0124;
  1977. float det5_12345_01345 = mat[1][0] * det4_2345_1345 - mat[1][1] * det4_2345_0345 + mat[1][3] * det4_2345_0145 - mat[1][4] * det4_2345_0135 + mat[1][5] * det4_2345_0134;
  1978. float det5_12345_02345 = mat[1][0] * det4_2345_2345 - mat[1][2] * det4_2345_0345 + mat[1][3] * det4_2345_0245 - mat[1][4] * det4_2345_0235 + mat[1][5] * det4_2345_0234;
  1979. float det5_12345_12345 = mat[1][1] * det4_2345_2345 - mat[1][2] * det4_2345_1345 + mat[1][3] * det4_2345_1245 - mat[1][4] * det4_2345_1235 + mat[1][5] * det4_2345_1234;
  1980. // determinant of 6x6 matrix
  1981. det = mat[0][0] * det5_12345_12345 - mat[0][1] * det5_12345_02345 + mat[0][2] * det5_12345_01345 -
  1982. mat[0][3] * det5_12345_01245 + mat[0][4] * det5_12345_01235 - mat[0][5] * det5_12345_01234;
  1983. if ( idMath::Fabs( det ) < MATRIX_INVERSE_EPSILON ) {
  1984. return false;
  1985. }
  1986. invDet = 1.0f / det;
  1987. // remaining 2x2 sub-determinants
  1988. float det2_34_01 = mat[3][0] * mat[4][1] - mat[3][1] * mat[4][0];
  1989. float det2_34_02 = mat[3][0] * mat[4][2] - mat[3][2] * mat[4][0];
  1990. float det2_34_03 = mat[3][0] * mat[4][3] - mat[3][3] * mat[4][0];
  1991. float det2_34_04 = mat[3][0] * mat[4][4] - mat[3][4] * mat[4][0];
  1992. float det2_34_05 = mat[3][0] * mat[4][5] - mat[3][5] * mat[4][0];
  1993. float det2_34_12 = mat[3][1] * mat[4][2] - mat[3][2] * mat[4][1];
  1994. float det2_34_13 = mat[3][1] * mat[4][3] - mat[3][3] * mat[4][1];
  1995. float det2_34_14 = mat[3][1] * mat[4][4] - mat[3][4] * mat[4][1];
  1996. float det2_34_15 = mat[3][1] * mat[4][5] - mat[3][5] * mat[4][1];
  1997. float det2_34_23 = mat[3][2] * mat[4][3] - mat[3][3] * mat[4][2];
  1998. float det2_34_24 = mat[3][2] * mat[4][4] - mat[3][4] * mat[4][2];
  1999. float det2_34_25 = mat[3][2] * mat[4][5] - mat[3][5] * mat[4][2];
  2000. float det2_34_34 = mat[3][3] * mat[4][4] - mat[3][4] * mat[4][3];
  2001. float det2_34_35 = mat[3][3] * mat[4][5] - mat[3][5] * mat[4][3];
  2002. float det2_34_45 = mat[3][4] * mat[4][5] - mat[3][5] * mat[4][4];
  2003. float det2_35_01 = mat[3][0] * mat[5][1] - mat[3][1] * mat[5][0];
  2004. float det2_35_02 = mat[3][0] * mat[5][2] - mat[3][2] * mat[5][0];
  2005. float det2_35_03 = mat[3][0] * mat[5][3] - mat[3][3] * mat[5][0];
  2006. float det2_35_04 = mat[3][0] * mat[5][4] - mat[3][4] * mat[5][0];
  2007. float det2_35_05 = mat[3][0] * mat[5][5] - mat[3][5] * mat[5][0];
  2008. float det2_35_12 = mat[3][1] * mat[5][2] - mat[3][2] * mat[5][1];
  2009. float det2_35_13 = mat[3][1] * mat[5][3] - mat[3][3] * mat[5][1];
  2010. float det2_35_14 = mat[3][1] * mat[5][4] - mat[3][4] * mat[5][1];
  2011. float det2_35_15 = mat[3][1] * mat[5][5] - mat[3][5] * mat[5][1];
  2012. float det2_35_23 = mat[3][2] * mat[5][3] - mat[3][3] * mat[5][2];
  2013. float det2_35_24 = mat[3][2] * mat[5][4] - mat[3][4] * mat[5][2];
  2014. float det2_35_25 = mat[3][2] * mat[5][5] - mat[3][5] * mat[5][2];
  2015. float det2_35_34 = mat[3][3] * mat[5][4] - mat[3][4] * mat[5][3];
  2016. float det2_35_35 = mat[3][3] * mat[5][5] - mat[3][5] * mat[5][3];
  2017. float det2_35_45 = mat[3][4] * mat[5][5] - mat[3][5] * mat[5][4];
  2018. // remaining 3x3 sub-determinants
  2019. float det3_234_012 = mat[2][0] * det2_34_12 - mat[2][1] * det2_34_02 + mat[2][2] * det2_34_01;
  2020. float det3_234_013 = mat[2][0] * det2_34_13 - mat[2][1] * det2_34_03 + mat[2][3] * det2_34_01;
  2021. float det3_234_014 = mat[2][0] * det2_34_14 - mat[2][1] * det2_34_04 + mat[2][4] * det2_34_01;
  2022. float det3_234_015 = mat[2][0] * det2_34_15 - mat[2][1] * det2_34_05 + mat[2][5] * det2_34_01;
  2023. float det3_234_023 = mat[2][0] * det2_34_23 - mat[2][2] * det2_34_03 + mat[2][3] * det2_34_02;
  2024. float det3_234_024 = mat[2][0] * det2_34_24 - mat[2][2] * det2_34_04 + mat[2][4] * det2_34_02;
  2025. float det3_234_025 = mat[2][0] * det2_34_25 - mat[2][2] * det2_34_05 + mat[2][5] * det2_34_02;
  2026. float det3_234_034 = mat[2][0] * det2_34_34 - mat[2][3] * det2_34_04 + mat[2][4] * det2_34_03;
  2027. float det3_234_035 = mat[2][0] * det2_34_35 - mat[2][3] * det2_34_05 + mat[2][5] * det2_34_03;
  2028. float det3_234_045 = mat[2][0] * det2_34_45 - mat[2][4] * det2_34_05 + mat[2][5] * det2_34_04;
  2029. float det3_234_123 = mat[2][1] * det2_34_23 - mat[2][2] * det2_34_13 + mat[2][3] * det2_34_12;
  2030. float det3_234_124 = mat[2][1] * det2_34_24 - mat[2][2] * det2_34_14 + mat[2][4] * det2_34_12;
  2031. float det3_234_125 = mat[2][1] * det2_34_25 - mat[2][2] * det2_34_15 + mat[2][5] * det2_34_12;
  2032. float det3_234_134 = mat[2][1] * det2_34_34 - mat[2][3] * det2_34_14 + mat[2][4] * det2_34_13;
  2033. float det3_234_135 = mat[2][1] * det2_34_35 - mat[2][3] * det2_34_15 + mat[2][5] * det2_34_13;
  2034. float det3_234_145 = mat[2][1] * det2_34_45 - mat[2][4] * det2_34_15 + mat[2][5] * det2_34_14;
  2035. float det3_234_234 = mat[2][2] * det2_34_34 - mat[2][3] * det2_34_24 + mat[2][4] * det2_34_23;
  2036. float det3_234_235 = mat[2][2] * det2_34_35 - mat[2][3] * det2_34_25 + mat[2][5] * det2_34_23;
  2037. float det3_234_245 = mat[2][2] * det2_34_45 - mat[2][4] * det2_34_25 + mat[2][5] * det2_34_24;
  2038. float det3_234_345 = mat[2][3] * det2_34_45 - mat[2][4] * det2_34_35 + mat[2][5] * det2_34_34;
  2039. float det3_235_012 = mat[2][0] * det2_35_12 - mat[2][1] * det2_35_02 + mat[2][2] * det2_35_01;
  2040. float det3_235_013 = mat[2][0] * det2_35_13 - mat[2][1] * det2_35_03 + mat[2][3] * det2_35_01;
  2041. float det3_235_014 = mat[2][0] * det2_35_14 - mat[2][1] * det2_35_04 + mat[2][4] * det2_35_01;
  2042. float det3_235_015 = mat[2][0] * det2_35_15 - mat[2][1] * det2_35_05 + mat[2][5] * det2_35_01;
  2043. float det3_235_023 = mat[2][0] * det2_35_23 - mat[2][2] * det2_35_03 + mat[2][3] * det2_35_02;
  2044. float det3_235_024 = mat[2][0] * det2_35_24 - mat[2][2] * det2_35_04 + mat[2][4] * det2_35_02;
  2045. float det3_235_025 = mat[2][0] * det2_35_25 - mat[2][2] * det2_35_05 + mat[2][5] * det2_35_02;
  2046. float det3_235_034 = mat[2][0] * det2_35_34 - mat[2][3] * det2_35_04 + mat[2][4] * det2_35_03;
  2047. float det3_235_035 = mat[2][0] * det2_35_35 - mat[2][3] * det2_35_05 + mat[2][5] * det2_35_03;
  2048. float det3_235_045 = mat[2][0] * det2_35_45 - mat[2][4] * det2_35_05 + mat[2][5] * det2_35_04;
  2049. float det3_235_123 = mat[2][1] * det2_35_23 - mat[2][2] * det2_35_13 + mat[2][3] * det2_35_12;
  2050. float det3_235_124 = mat[2][1] * det2_35_24 - mat[2][2] * det2_35_14 + mat[2][4] * det2_35_12;
  2051. float det3_235_125 = mat[2][1] * det2_35_25 - mat[2][2] * det2_35_15 + mat[2][5] * det2_35_12;
  2052. float det3_235_134 = mat[2][1] * det2_35_34 - mat[2][3] * det2_35_14 + mat[2][4] * det2_35_13;
  2053. float det3_235_135 = mat[2][1] * det2_35_35 - mat[2][3] * det2_35_15 + mat[2][5] * det2_35_13;
  2054. float det3_235_145 = mat[2][1] * det2_35_45 - mat[2][4] * det2_35_15 + mat[2][5] * det2_35_14;
  2055. float det3_235_234 = mat[2][2] * det2_35_34 - mat[2][3] * det2_35_24 + mat[2][4] * det2_35_23;
  2056. float det3_235_235 = mat[2][2] * det2_35_35 - mat[2][3] * det2_35_25 + mat[2][5] * det2_35_23;
  2057. float det3_235_245 = mat[2][2] * det2_35_45 - mat[2][4] * det2_35_25 + mat[2][5] * det2_35_24;
  2058. float det3_235_345 = mat[2][3] * det2_35_45 - mat[2][4] * det2_35_35 + mat[2][5] * det2_35_34;
  2059. float det3_245_012 = mat[2][0] * det2_45_12 - mat[2][1] * det2_45_02 + mat[2][2] * det2_45_01;
  2060. float det3_245_013 = mat[2][0] * det2_45_13 - mat[2][1] * det2_45_03 + mat[2][3] * det2_45_01;
  2061. float det3_245_014 = mat[2][0] * det2_45_14 - mat[2][1] * det2_45_04 + mat[2][4] * det2_45_01;
  2062. float det3_245_015 = mat[2][0] * det2_45_15 - mat[2][1] * det2_45_05 + mat[2][5] * det2_45_01;
  2063. float det3_245_023 = mat[2][0] * det2_45_23 - mat[2][2] * det2_45_03 + mat[2][3] * det2_45_02;
  2064. float det3_245_024 = mat[2][0] * det2_45_24 - mat[2][2] * det2_45_04 + mat[2][4] * det2_45_02;
  2065. float det3_245_025 = mat[2][0] * det2_45_25 - mat[2][2] * det2_45_05 + mat[2][5] * det2_45_02;
  2066. float det3_245_034 = mat[2][0] * det2_45_34 - mat[2][3] * det2_45_04 + mat[2][4] * det2_45_03;
  2067. float det3_245_035 = mat[2][0] * det2_45_35 - mat[2][3] * det2_45_05 + mat[2][5] * det2_45_03;
  2068. float det3_245_045 = mat[2][0] * det2_45_45 - mat[2][4] * det2_45_05 + mat[2][5] * det2_45_04;
  2069. float det3_245_123 = mat[2][1] * det2_45_23 - mat[2][2] * det2_45_13 + mat[2][3] * det2_45_12;
  2070. float det3_245_124 = mat[2][1] * det2_45_24 - mat[2][2] * det2_45_14 + mat[2][4] * det2_45_12;
  2071. float det3_245_125 = mat[2][1] * det2_45_25 - mat[2][2] * det2_45_15 + mat[2][5] * det2_45_12;
  2072. float det3_245_134 = mat[2][1] * det2_45_34 - mat[2][3] * det2_45_14 + mat[2][4] * det2_45_13;
  2073. float det3_245_135 = mat[2][1] * det2_45_35 - mat[2][3] * det2_45_15 + mat[2][5] * det2_45_13;
  2074. float det3_245_145 = mat[2][1] * det2_45_45 - mat[2][4] * det2_45_15 + mat[2][5] * det2_45_14;
  2075. float det3_245_234 = mat[2][2] * det2_45_34 - mat[2][3] * det2_45_24 + mat[2][4] * det2_45_23;
  2076. float det3_245_235 = mat[2][2] * det2_45_35 - mat[2][3] * det2_45_25 + mat[2][5] * det2_45_23;
  2077. float det3_245_245 = mat[2][2] * det2_45_45 - mat[2][4] * det2_45_25 + mat[2][5] * det2_45_24;
  2078. float det3_245_345 = mat[2][3] * det2_45_45 - mat[2][4] * det2_45_35 + mat[2][5] * det2_45_34;
  2079. // remaining 4x4 sub-determinants
  2080. float det4_1234_0123 = mat[1][0] * det3_234_123 - mat[1][1] * det3_234_023 + mat[1][2] * det3_234_013 - mat[1][3] * det3_234_012;
  2081. float det4_1234_0124 = mat[1][0] * det3_234_124 - mat[1][1] * det3_234_024 + mat[1][2] * det3_234_014 - mat[1][4] * det3_234_012;
  2082. float det4_1234_0125 = mat[1][0] * det3_234_125 - mat[1][1] * det3_234_025 + mat[1][2] * det3_234_015 - mat[1][5] * det3_234_012;
  2083. float det4_1234_0134 = mat[1][0] * det3_234_134 - mat[1][1] * det3_234_034 + mat[1][3] * det3_234_014 - mat[1][4] * det3_234_013;
  2084. float det4_1234_0135 = mat[1][0] * det3_234_135 - mat[1][1] * det3_234_035 + mat[1][3] * det3_234_015 - mat[1][5] * det3_234_013;
  2085. float det4_1234_0145 = mat[1][0] * det3_234_145 - mat[1][1] * det3_234_045 + mat[1][4] * det3_234_015 - mat[1][5] * det3_234_014;
  2086. float det4_1234_0234 = mat[1][0] * det3_234_234 - mat[1][2] * det3_234_034 + mat[1][3] * det3_234_024 - mat[1][4] * det3_234_023;
  2087. float det4_1234_0235 = mat[1][0] * det3_234_235 - mat[1][2] * det3_234_035 + mat[1][3] * det3_234_025 - mat[1][5] * det3_234_023;
  2088. float det4_1234_0245 = mat[1][0] * det3_234_245 - mat[1][2] * det3_234_045 + mat[1][4] * det3_234_025 - mat[1][5] * det3_234_024;
  2089. float det4_1234_0345 = mat[1][0] * det3_234_345 - mat[1][3] * det3_234_045 + mat[1][4] * det3_234_035 - mat[1][5] * det3_234_034;
  2090. float det4_1234_1234 = mat[1][1] * det3_234_234 - mat[1][2] * det3_234_134 + mat[1][3] * det3_234_124 - mat[1][4] * det3_234_123;
  2091. float det4_1234_1235 = mat[1][1] * det3_234_235 - mat[1][2] * det3_234_135 + mat[1][3] * det3_234_125 - mat[1][5] * det3_234_123;
  2092. float det4_1234_1245 = mat[1][1] * det3_234_245 - mat[1][2] * det3_234_145 + mat[1][4] * det3_234_125 - mat[1][5] * det3_234_124;
  2093. float det4_1234_1345 = mat[1][1] * det3_234_345 - mat[1][3] * det3_234_145 + mat[1][4] * det3_234_135 - mat[1][5] * det3_234_134;
  2094. float det4_1234_2345 = mat[1][2] * det3_234_345 - mat[1][3] * det3_234_245 + mat[1][4] * det3_234_235 - mat[1][5] * det3_234_234;
  2095. float det4_1235_0123 = mat[1][0] * det3_235_123 - mat[1][1] * det3_235_023 + mat[1][2] * det3_235_013 - mat[1][3] * det3_235_012;
  2096. float det4_1235_0124 = mat[1][0] * det3_235_124 - mat[1][1] * det3_235_024 + mat[1][2] * det3_235_014 - mat[1][4] * det3_235_012;
  2097. float det4_1235_0125 = mat[1][0] * det3_235_125 - mat[1][1] * det3_235_025 + mat[1][2] * det3_235_015 - mat[1][5] * det3_235_012;
  2098. float det4_1235_0134 = mat[1][0] * det3_235_134 - mat[1][1] * det3_235_034 + mat[1][3] * det3_235_014 - mat[1][4] * det3_235_013;
  2099. float det4_1235_0135 = mat[1][0] * det3_235_135 - mat[1][1] * det3_235_035 + mat[1][3] * det3_235_015 - mat[1][5] * det3_235_013;
  2100. float det4_1235_0145 = mat[1][0] * det3_235_145 - mat[1][1] * det3_235_045 + mat[1][4] * det3_235_015 - mat[1][5] * det3_235_014;
  2101. float det4_1235_0234 = mat[1][0] * det3_235_234 - mat[1][2] * det3_235_034 + mat[1][3] * det3_235_024 - mat[1][4] * det3_235_023;
  2102. float det4_1235_0235 = mat[1][0] * det3_235_235 - mat[1][2] * det3_235_035 + mat[1][3] * det3_235_025 - mat[1][5] * det3_235_023;
  2103. float det4_1235_0245 = mat[1][0] * det3_235_245 - mat[1][2] * det3_235_045 + mat[1][4] * det3_235_025 - mat[1][5] * det3_235_024;
  2104. float det4_1235_0345 = mat[1][0] * det3_235_345 - mat[1][3] * det3_235_045 + mat[1][4] * det3_235_035 - mat[1][5] * det3_235_034;
  2105. float det4_1235_1234 = mat[1][1] * det3_235_234 - mat[1][2] * det3_235_134 + mat[1][3] * det3_235_124 - mat[1][4] * det3_235_123;
  2106. float det4_1235_1235 = mat[1][1] * det3_235_235 - mat[1][2] * det3_235_135 + mat[1][3] * det3_235_125 - mat[1][5] * det3_235_123;
  2107. float det4_1235_1245 = mat[1][1] * det3_235_245 - mat[1][2] * det3_235_145 + mat[1][4] * det3_235_125 - mat[1][5] * det3_235_124;
  2108. float det4_1235_1345 = mat[1][1] * det3_235_345 - mat[1][3] * det3_235_145 + mat[1][4] * det3_235_135 - mat[1][5] * det3_235_134;
  2109. float det4_1235_2345 = mat[1][2] * det3_235_345 - mat[1][3] * det3_235_245 + mat[1][4] * det3_235_235 - mat[1][5] * det3_235_234;
  2110. float det4_1245_0123 = mat[1][0] * det3_245_123 - mat[1][1] * det3_245_023 + mat[1][2] * det3_245_013 - mat[1][3] * det3_245_012;
  2111. float det4_1245_0124 = mat[1][0] * det3_245_124 - mat[1][1] * det3_245_024 + mat[1][2] * det3_245_014 - mat[1][4] * det3_245_012;
  2112. float det4_1245_0125 = mat[1][0] * det3_245_125 - mat[1][1] * det3_245_025 + mat[1][2] * det3_245_015 - mat[1][5] * det3_245_012;
  2113. float det4_1245_0134 = mat[1][0] * det3_245_134 - mat[1][1] * det3_245_034 + mat[1][3] * det3_245_014 - mat[1][4] * det3_245_013;
  2114. float det4_1245_0135 = mat[1][0] * det3_245_135 - mat[1][1] * det3_245_035 + mat[1][3] * det3_245_015 - mat[1][5] * det3_245_013;
  2115. float det4_1245_0145 = mat[1][0] * det3_245_145 - mat[1][1] * det3_245_045 + mat[1][4] * det3_245_015 - mat[1][5] * det3_245_014;
  2116. float det4_1245_0234 = mat[1][0] * det3_245_234 - mat[1][2] * det3_245_034 + mat[1][3] * det3_245_024 - mat[1][4] * det3_245_023;
  2117. float det4_1245_0235 = mat[1][0] * det3_245_235 - mat[1][2] * det3_245_035 + mat[1][3] * det3_245_025 - mat[1][5] * det3_245_023;
  2118. float det4_1245_0245 = mat[1][0] * det3_245_245 - mat[1][2] * det3_245_045 + mat[1][4] * det3_245_025 - mat[1][5] * det3_245_024;
  2119. float det4_1245_0345 = mat[1][0] * det3_245_345 - mat[1][3] * det3_245_045 + mat[1][4] * det3_245_035 - mat[1][5] * det3_245_034;
  2120. float det4_1245_1234 = mat[1][1] * det3_245_234 - mat[1][2] * det3_245_134 + mat[1][3] * det3_245_124 - mat[1][4] * det3_245_123;
  2121. float det4_1245_1235 = mat[1][1] * det3_245_235 - mat[1][2] * det3_245_135 + mat[1][3] * det3_245_125 - mat[1][5] * det3_245_123;
  2122. float det4_1245_1245 = mat[1][1] * det3_245_245 - mat[1][2] * det3_245_145 + mat[1][4] * det3_245_125 - mat[1][5] * det3_245_124;
  2123. float det4_1245_1345 = mat[1][1] * det3_245_345 - mat[1][3] * det3_245_145 + mat[1][4] * det3_245_135 - mat[1][5] * det3_245_134;
  2124. float det4_1245_2345 = mat[1][2] * det3_245_345 - mat[1][3] * det3_245_245 + mat[1][4] * det3_245_235 - mat[1][5] * det3_245_234;
  2125. float det4_1345_0123 = mat[1][0] * det3_345_123 - mat[1][1] * det3_345_023 + mat[1][2] * det3_345_013 - mat[1][3] * det3_345_012;
  2126. float det4_1345_0124 = mat[1][0] * det3_345_124 - mat[1][1] * det3_345_024 + mat[1][2] * det3_345_014 - mat[1][4] * det3_345_012;
  2127. float det4_1345_0125 = mat[1][0] * det3_345_125 - mat[1][1] * det3_345_025 + mat[1][2] * det3_345_015 - mat[1][5] * det3_345_012;
  2128. float det4_1345_0134 = mat[1][0] * det3_345_134 - mat[1][1] * det3_345_034 + mat[1][3] * det3_345_014 - mat[1][4] * det3_345_013;
  2129. float det4_1345_0135 = mat[1][0] * det3_345_135 - mat[1][1] * det3_345_035 + mat[1][3] * det3_345_015 - mat[1][5] * det3_345_013;
  2130. float det4_1345_0145 = mat[1][0] * det3_345_145 - mat[1][1] * det3_345_045 + mat[1][4] * det3_345_015 - mat[1][5] * det3_345_014;
  2131. float det4_1345_0234 = mat[1][0] * det3_345_234 - mat[1][2] * det3_345_034 + mat[1][3] * det3_345_024 - mat[1][4] * det3_345_023;
  2132. float det4_1345_0235 = mat[1][0] * det3_345_235 - mat[1][2] * det3_345_035 + mat[1][3] * det3_345_025 - mat[1][5] * det3_345_023;
  2133. float det4_1345_0245 = mat[1][0] * det3_345_245 - mat[1][2] * det3_345_045 + mat[1][4] * det3_345_025 - mat[1][5] * det3_345_024;
  2134. float det4_1345_0345 = mat[1][0] * det3_345_345 - mat[1][3] * det3_345_045 + mat[1][4] * det3_345_035 - mat[1][5] * det3_345_034;
  2135. float det4_1345_1234 = mat[1][1] * det3_345_234 - mat[1][2] * det3_345_134 + mat[1][3] * det3_345_124 - mat[1][4] * det3_345_123;
  2136. float det4_1345_1235 = mat[1][1] * det3_345_235 - mat[1][2] * det3_345_135 + mat[1][3] * det3_345_125 - mat[1][5] * det3_345_123;
  2137. float det4_1345_1245 = mat[1][1] * det3_345_245 - mat[1][2] * det3_345_145 + mat[1][4] * det3_345_125 - mat[1][5] * det3_345_124;
  2138. float det4_1345_1345 = mat[1][1] * det3_345_345 - mat[1][3] * det3_345_145 + mat[1][4] * det3_345_135 - mat[1][5] * det3_345_134;
  2139. float det4_1345_2345 = mat[1][2] * det3_345_345 - mat[1][3] * det3_345_245 + mat[1][4] * det3_345_235 - mat[1][5] * det3_345_234;
  2140. // remaining 5x5 sub-determinants
  2141. float det5_01234_01234 = mat[0][0] * det4_1234_1234 - mat[0][1] * det4_1234_0234 + mat[0][2] * det4_1234_0134 - mat[0][3] * det4_1234_0124 + mat[0][4] * det4_1234_0123;
  2142. float det5_01234_01235 = mat[0][0] * det4_1234_1235 - mat[0][1] * det4_1234_0235 + mat[0][2] * det4_1234_0135 - mat[0][3] * det4_1234_0125 + mat[0][5] * det4_1234_0123;
  2143. float det5_01234_01245 = mat[0][0] * det4_1234_1245 - mat[0][1] * det4_1234_0245 + mat[0][2] * det4_1234_0145 - mat[0][4] * det4_1234_0125 + mat[0][5] * det4_1234_0124;
  2144. float det5_01234_01345 = mat[0][0] * det4_1234_1345 - mat[0][1] * det4_1234_0345 + mat[0][3] * det4_1234_0145 - mat[0][4] * det4_1234_0135 + mat[0][5] * det4_1234_0134;
  2145. float det5_01234_02345 = mat[0][0] * det4_1234_2345 - mat[0][2] * det4_1234_0345 + mat[0][3] * det4_1234_0245 - mat[0][4] * det4_1234_0235 + mat[0][5] * det4_1234_0234;
  2146. float det5_01234_12345 = mat[0][1] * det4_1234_2345 - mat[0][2] * det4_1234_1345 + mat[0][3] * det4_1234_1245 - mat[0][4] * det4_1234_1235 + mat[0][5] * det4_1234_1234;
  2147. float det5_01235_01234 = mat[0][0] * det4_1235_1234 - mat[0][1] * det4_1235_0234 + mat[0][2] * det4_1235_0134 - mat[0][3] * det4_1235_0124 + mat[0][4] * det4_1235_0123;
  2148. float det5_01235_01235 = mat[0][0] * det4_1235_1235 - mat[0][1] * det4_1235_0235 + mat[0][2] * det4_1235_0135 - mat[0][3] * det4_1235_0125 + mat[0][5] * det4_1235_0123;
  2149. float det5_01235_01245 = mat[0][0] * det4_1235_1245 - mat[0][1] * det4_1235_0245 + mat[0][2] * det4_1235_0145 - mat[0][4] * det4_1235_0125 + mat[0][5] * det4_1235_0124;
  2150. float det5_01235_01345 = mat[0][0] * det4_1235_1345 - mat[0][1] * det4_1235_0345 + mat[0][3] * det4_1235_0145 - mat[0][4] * det4_1235_0135 + mat[0][5] * det4_1235_0134;
  2151. float det5_01235_02345 = mat[0][0] * det4_1235_2345 - mat[0][2] * det4_1235_0345 + mat[0][3] * det4_1235_0245 - mat[0][4] * det4_1235_0235 + mat[0][5] * det4_1235_0234;
  2152. float det5_01235_12345 = mat[0][1] * det4_1235_2345 - mat[0][2] * det4_1235_1345 + mat[0][3] * det4_1235_1245 - mat[0][4] * det4_1235_1235 + mat[0][5] * det4_1235_1234;
  2153. float det5_01245_01234 = mat[0][0] * det4_1245_1234 - mat[0][1] * det4_1245_0234 + mat[0][2] * det4_1245_0134 - mat[0][3] * det4_1245_0124 + mat[0][4] * det4_1245_0123;
  2154. float det5_01245_01235 = mat[0][0] * det4_1245_1235 - mat[0][1] * det4_1245_0235 + mat[0][2] * det4_1245_0135 - mat[0][3] * det4_1245_0125 + mat[0][5] * det4_1245_0123;
  2155. float det5_01245_01245 = mat[0][0] * det4_1245_1245 - mat[0][1] * det4_1245_0245 + mat[0][2] * det4_1245_0145 - mat[0][4] * det4_1245_0125 + mat[0][5] * det4_1245_0124;
  2156. float det5_01245_01345 = mat[0][0] * det4_1245_1345 - mat[0][1] * det4_1245_0345 + mat[0][3] * det4_1245_0145 - mat[0][4] * det4_1245_0135 + mat[0][5] * det4_1245_0134;
  2157. float det5_01245_02345 = mat[0][0] * det4_1245_2345 - mat[0][2] * det4_1245_0345 + mat[0][3] * det4_1245_0245 - mat[0][4] * det4_1245_0235 + mat[0][5] * det4_1245_0234;
  2158. float det5_01245_12345 = mat[0][1] * det4_1245_2345 - mat[0][2] * det4_1245_1345 + mat[0][3] * det4_1245_1245 - mat[0][4] * det4_1245_1235 + mat[0][5] * det4_1245_1234;
  2159. float det5_01345_01234 = mat[0][0] * det4_1345_1234 - mat[0][1] * det4_1345_0234 + mat[0][2] * det4_1345_0134 - mat[0][3] * det4_1345_0124 + mat[0][4] * det4_1345_0123;
  2160. float det5_01345_01235 = mat[0][0] * det4_1345_1235 - mat[0][1] * det4_1345_0235 + mat[0][2] * det4_1345_0135 - mat[0][3] * det4_1345_0125 + mat[0][5] * det4_1345_0123;
  2161. float det5_01345_01245 = mat[0][0] * det4_1345_1245 - mat[0][1] * det4_1345_0245 + mat[0][2] * det4_1345_0145 - mat[0][4] * det4_1345_0125 + mat[0][5] * det4_1345_0124;
  2162. float det5_01345_01345 = mat[0][0] * det4_1345_1345 - mat[0][1] * det4_1345_0345 + mat[0][3] * det4_1345_0145 - mat[0][4] * det4_1345_0135 + mat[0][5] * det4_1345_0134;
  2163. float det5_01345_02345 = mat[0][0] * det4_1345_2345 - mat[0][2] * det4_1345_0345 + mat[0][3] * det4_1345_0245 - mat[0][4] * det4_1345_0235 + mat[0][5] * det4_1345_0234;
  2164. float det5_01345_12345 = mat[0][1] * det4_1345_2345 - mat[0][2] * det4_1345_1345 + mat[0][3] * det4_1345_1245 - mat[0][4] * det4_1345_1235 + mat[0][5] * det4_1345_1234;
  2165. float det5_02345_01234 = mat[0][0] * det4_2345_1234 - mat[0][1] * det4_2345_0234 + mat[0][2] * det4_2345_0134 - mat[0][3] * det4_2345_0124 + mat[0][4] * det4_2345_0123;
  2166. float det5_02345_01235 = mat[0][0] * det4_2345_1235 - mat[0][1] * det4_2345_0235 + mat[0][2] * det4_2345_0135 - mat[0][3] * det4_2345_0125 + mat[0][5] * det4_2345_0123;
  2167. float det5_02345_01245 = mat[0][0] * det4_2345_1245 - mat[0][1] * det4_2345_0245 + mat[0][2] * det4_2345_0145 - mat[0][4] * det4_2345_0125 + mat[0][5] * det4_2345_0124;
  2168. float det5_02345_01345 = mat[0][0] * det4_2345_1345 - mat[0][1] * det4_2345_0345 + mat[0][3] * det4_2345_0145 - mat[0][4] * det4_2345_0135 + mat[0][5] * det4_2345_0134;
  2169. float det5_02345_02345 = mat[0][0] * det4_2345_2345 - mat[0][2] * det4_2345_0345 + mat[0][3] * det4_2345_0245 - mat[0][4] * det4_2345_0235 + mat[0][5] * det4_2345_0234;
  2170. float det5_02345_12345 = mat[0][1] * det4_2345_2345 - mat[0][2] * det4_2345_1345 + mat[0][3] * det4_2345_1245 - mat[0][4] * det4_2345_1235 + mat[0][5] * det4_2345_1234;
  2171. mat[0][0] = det5_12345_12345 * invDet;
  2172. mat[0][1] = -det5_02345_12345 * invDet;
  2173. mat[0][2] = det5_01345_12345 * invDet;
  2174. mat[0][3] = -det5_01245_12345 * invDet;
  2175. mat[0][4] = det5_01235_12345 * invDet;
  2176. mat[0][5] = -det5_01234_12345 * invDet;
  2177. mat[1][0] = -det5_12345_02345 * invDet;
  2178. mat[1][1] = det5_02345_02345 * invDet;
  2179. mat[1][2] = -det5_01345_02345 * invDet;
  2180. mat[1][3] = det5_01245_02345 * invDet;
  2181. mat[1][4] = -det5_01235_02345 * invDet;
  2182. mat[1][5] = det5_01234_02345 * invDet;
  2183. mat[2][0] = det5_12345_01345 * invDet;
  2184. mat[2][1] = -det5_02345_01345 * invDet;
  2185. mat[2][2] = det5_01345_01345 * invDet;
  2186. mat[2][3] = -det5_01245_01345 * invDet;
  2187. mat[2][4] = det5_01235_01345 * invDet;
  2188. mat[2][5] = -det5_01234_01345 * invDet;
  2189. mat[3][0] = -det5_12345_01245 * invDet;
  2190. mat[3][1] = det5_02345_01245 * invDet;
  2191. mat[3][2] = -det5_01345_01245 * invDet;
  2192. mat[3][3] = det5_01245_01245 * invDet;
  2193. mat[3][4] = -det5_01235_01245 * invDet;
  2194. mat[3][5] = det5_01234_01245 * invDet;
  2195. mat[4][0] = det5_12345_01235 * invDet;
  2196. mat[4][1] = -det5_02345_01235 * invDet;
  2197. mat[4][2] = det5_01345_01235 * invDet;
  2198. mat[4][3] = -det5_01245_01235 * invDet;
  2199. mat[4][4] = det5_01235_01235 * invDet;
  2200. mat[4][5] = -det5_01234_01235 * invDet;
  2201. mat[5][0] = -det5_12345_01234 * invDet;
  2202. mat[5][1] = det5_02345_01234 * invDet;
  2203. mat[5][2] = -det5_01345_01234 * invDet;
  2204. mat[5][3] = det5_01245_01234 * invDet;
  2205. mat[5][4] = -det5_01235_01234 * invDet;
  2206. mat[5][5] = det5_01234_01234 * invDet;
  2207. return true;
  2208. #elif 0
  2209. // 6*40 = 240 multiplications
  2210. // 6 divisions
  2211. float *mat = reinterpret_cast<float *>(this);
  2212. float s;
  2213. double d, di;
  2214. di = mat[0];
  2215. s = di;
  2216. mat[0] = d = 1.0f / di;
  2217. mat[1] *= d;
  2218. mat[2] *= d;
  2219. mat[3] *= d;
  2220. mat[4] *= d;
  2221. mat[5] *= d;
  2222. d = -d;
  2223. mat[6] *= d;
  2224. mat[12] *= d;
  2225. mat[18] *= d;
  2226. mat[24] *= d;
  2227. mat[30] *= d;
  2228. d = mat[6] * di;
  2229. mat[7] += mat[1] * d;
  2230. mat[8] += mat[2] * d;
  2231. mat[9] += mat[3] * d;
  2232. mat[10] += mat[4] * d;
  2233. mat[11] += mat[5] * d;
  2234. d = mat[12] * di;
  2235. mat[13] += mat[1] * d;
  2236. mat[14] += mat[2] * d;
  2237. mat[15] += mat[3] * d;
  2238. mat[16] += mat[4] * d;
  2239. mat[17] += mat[5] * d;
  2240. d = mat[18] * di;
  2241. mat[19] += mat[1] * d;
  2242. mat[20] += mat[2] * d;
  2243. mat[21] += mat[3] * d;
  2244. mat[22] += mat[4] * d;
  2245. mat[23] += mat[5] * d;
  2246. d = mat[24] * di;
  2247. mat[25] += mat[1] * d;
  2248. mat[26] += mat[2] * d;
  2249. mat[27] += mat[3] * d;
  2250. mat[28] += mat[4] * d;
  2251. mat[29] += mat[5] * d;
  2252. d = mat[30] * di;
  2253. mat[31] += mat[1] * d;
  2254. mat[32] += mat[2] * d;
  2255. mat[33] += mat[3] * d;
  2256. mat[34] += mat[4] * d;
  2257. mat[35] += mat[5] * d;
  2258. di = mat[7];
  2259. s *= di;
  2260. mat[7] = d = 1.0f / di;
  2261. mat[6] *= d;
  2262. mat[8] *= d;
  2263. mat[9] *= d;
  2264. mat[10] *= d;
  2265. mat[11] *= d;
  2266. d = -d;
  2267. mat[1] *= d;
  2268. mat[13] *= d;
  2269. mat[19] *= d;
  2270. mat[25] *= d;
  2271. mat[31] *= d;
  2272. d = mat[1] * di;
  2273. mat[0] += mat[6] * d;
  2274. mat[2] += mat[8] * d;
  2275. mat[3] += mat[9] * d;
  2276. mat[4] += mat[10] * d;
  2277. mat[5] += mat[11] * d;
  2278. d = mat[13] * di;
  2279. mat[12] += mat[6] * d;
  2280. mat[14] += mat[8] * d;
  2281. mat[15] += mat[9] * d;
  2282. mat[16] += mat[10] * d;
  2283. mat[17] += mat[11] * d;
  2284. d = mat[19] * di;
  2285. mat[18] += mat[6] * d;
  2286. mat[20] += mat[8] * d;
  2287. mat[21] += mat[9] * d;
  2288. mat[22] += mat[10] * d;
  2289. mat[23] += mat[11] * d;
  2290. d = mat[25] * di;
  2291. mat[24] += mat[6] * d;
  2292. mat[26] += mat[8] * d;
  2293. mat[27] += mat[9] * d;
  2294. mat[28] += mat[10] * d;
  2295. mat[29] += mat[11] * d;
  2296. d = mat[31] * di;
  2297. mat[30] += mat[6] * d;
  2298. mat[32] += mat[8] * d;
  2299. mat[33] += mat[9] * d;
  2300. mat[34] += mat[10] * d;
  2301. mat[35] += mat[11] * d;
  2302. di = mat[14];
  2303. s *= di;
  2304. mat[14] = d = 1.0f / di;
  2305. mat[12] *= d;
  2306. mat[13] *= d;
  2307. mat[15] *= d;
  2308. mat[16] *= d;
  2309. mat[17] *= d;
  2310. d = -d;
  2311. mat[2] *= d;
  2312. mat[8] *= d;
  2313. mat[20] *= d;
  2314. mat[26] *= d;
  2315. mat[32] *= d;
  2316. d = mat[2] * di;
  2317. mat[0] += mat[12] * d;
  2318. mat[1] += mat[13] * d;
  2319. mat[3] += mat[15] * d;
  2320. mat[4] += mat[16] * d;
  2321. mat[5] += mat[17] * d;
  2322. d = mat[8] * di;
  2323. mat[6] += mat[12] * d;
  2324. mat[7] += mat[13] * d;
  2325. mat[9] += mat[15] * d;
  2326. mat[10] += mat[16] * d;
  2327. mat[11] += mat[17] * d;
  2328. d = mat[20] * di;
  2329. mat[18] += mat[12] * d;
  2330. mat[19] += mat[13] * d;
  2331. mat[21] += mat[15] * d;
  2332. mat[22] += mat[16] * d;
  2333. mat[23] += mat[17] * d;
  2334. d = mat[26] * di;
  2335. mat[24] += mat[12] * d;
  2336. mat[25] += mat[13] * d;
  2337. mat[27] += mat[15] * d;
  2338. mat[28] += mat[16] * d;
  2339. mat[29] += mat[17] * d;
  2340. d = mat[32] * di;
  2341. mat[30] += mat[12] * d;
  2342. mat[31] += mat[13] * d;
  2343. mat[33] += mat[15] * d;
  2344. mat[34] += mat[16] * d;
  2345. mat[35] += mat[17] * d;
  2346. di = mat[21];
  2347. s *= di;
  2348. mat[21] = d = 1.0f / di;
  2349. mat[18] *= d;
  2350. mat[19] *= d;
  2351. mat[20] *= d;
  2352. mat[22] *= d;
  2353. mat[23] *= d;
  2354. d = -d;
  2355. mat[3] *= d;
  2356. mat[9] *= d;
  2357. mat[15] *= d;
  2358. mat[27] *= d;
  2359. mat[33] *= d;
  2360. d = mat[3] * di;
  2361. mat[0] += mat[18] * d;
  2362. mat[1] += mat[19] * d;
  2363. mat[2] += mat[20] * d;
  2364. mat[4] += mat[22] * d;
  2365. mat[5] += mat[23] * d;
  2366. d = mat[9] * di;
  2367. mat[6] += mat[18] * d;
  2368. mat[7] += mat[19] * d;
  2369. mat[8] += mat[20] * d;
  2370. mat[10] += mat[22] * d;
  2371. mat[11] += mat[23] * d;
  2372. d = mat[15] * di;
  2373. mat[12] += mat[18] * d;
  2374. mat[13] += mat[19] * d;
  2375. mat[14] += mat[20] * d;
  2376. mat[16] += mat[22] * d;
  2377. mat[17] += mat[23] * d;
  2378. d = mat[27] * di;
  2379. mat[24] += mat[18] * d;
  2380. mat[25] += mat[19] * d;
  2381. mat[26] += mat[20] * d;
  2382. mat[28] += mat[22] * d;
  2383. mat[29] += mat[23] * d;
  2384. d = mat[33] * di;
  2385. mat[30] += mat[18] * d;
  2386. mat[31] += mat[19] * d;
  2387. mat[32] += mat[20] * d;
  2388. mat[34] += mat[22] * d;
  2389. mat[35] += mat[23] * d;
  2390. di = mat[28];
  2391. s *= di;
  2392. mat[28] = d = 1.0f / di;
  2393. mat[24] *= d;
  2394. mat[25] *= d;
  2395. mat[26] *= d;
  2396. mat[27] *= d;
  2397. mat[29] *= d;
  2398. d = -d;
  2399. mat[4] *= d;
  2400. mat[10] *= d;
  2401. mat[16] *= d;
  2402. mat[22] *= d;
  2403. mat[34] *= d;
  2404. d = mat[4] * di;
  2405. mat[0] += mat[24] * d;
  2406. mat[1] += mat[25] * d;
  2407. mat[2] += mat[26] * d;
  2408. mat[3] += mat[27] * d;
  2409. mat[5] += mat[29] * d;
  2410. d = mat[10] * di;
  2411. mat[6] += mat[24] * d;
  2412. mat[7] += mat[25] * d;
  2413. mat[8] += mat[26] * d;
  2414. mat[9] += mat[27] * d;
  2415. mat[11] += mat[29] * d;
  2416. d = mat[16] * di;
  2417. mat[12] += mat[24] * d;
  2418. mat[13] += mat[25] * d;
  2419. mat[14] += mat[26] * d;
  2420. mat[15] += mat[27] * d;
  2421. mat[17] += mat[29] * d;
  2422. d = mat[22] * di;
  2423. mat[18] += mat[24] * d;
  2424. mat[19] += mat[25] * d;
  2425. mat[20] += mat[26] * d;
  2426. mat[21] += mat[27] * d;
  2427. mat[23] += mat[29] * d;
  2428. d = mat[34] * di;
  2429. mat[30] += mat[24] * d;
  2430. mat[31] += mat[25] * d;
  2431. mat[32] += mat[26] * d;
  2432. mat[33] += mat[27] * d;
  2433. mat[35] += mat[29] * d;
  2434. di = mat[35];
  2435. s *= di;
  2436. mat[35] = d = 1.0f / di;
  2437. mat[30] *= d;
  2438. mat[31] *= d;
  2439. mat[32] *= d;
  2440. mat[33] *= d;
  2441. mat[34] *= d;
  2442. d = -d;
  2443. mat[5] *= d;
  2444. mat[11] *= d;
  2445. mat[17] *= d;
  2446. mat[23] *= d;
  2447. mat[29] *= d;
  2448. d = mat[5] * di;
  2449. mat[0] += mat[30] * d;
  2450. mat[1] += mat[31] * d;
  2451. mat[2] += mat[32] * d;
  2452. mat[3] += mat[33] * d;
  2453. mat[4] += mat[34] * d;
  2454. d = mat[11] * di;
  2455. mat[6] += mat[30] * d;
  2456. mat[7] += mat[31] * d;
  2457. mat[8] += mat[32] * d;
  2458. mat[9] += mat[33] * d;
  2459. mat[10] += mat[34] * d;
  2460. d = mat[17] * di;
  2461. mat[12] += mat[30] * d;
  2462. mat[13] += mat[31] * d;
  2463. mat[14] += mat[32] * d;
  2464. mat[15] += mat[33] * d;
  2465. mat[16] += mat[34] * d;
  2466. d = mat[23] * di;
  2467. mat[18] += mat[30] * d;
  2468. mat[19] += mat[31] * d;
  2469. mat[20] += mat[32] * d;
  2470. mat[21] += mat[33] * d;
  2471. mat[22] += mat[34] * d;
  2472. d = mat[29] * di;
  2473. mat[24] += mat[30] * d;
  2474. mat[25] += mat[31] * d;
  2475. mat[26] += mat[32] * d;
  2476. mat[27] += mat[33] * d;
  2477. mat[28] += mat[34] * d;
  2478. return ( s != 0.0f && !FLOAT_IS_NAN( s ) );
  2479. #else
  2480. // 6*27+2*30 = 222 multiplications
  2481. // 2*1 = 2 divisions
  2482. idMat3 r0, r1, r2, r3;
  2483. float c0, c1, c2, det, invDet;
  2484. float *mat = reinterpret_cast<float *>(this);
  2485. // r0 = m0.Inverse();
  2486. c0 = mat[1*6+1] * mat[2*6+2] - mat[1*6+2] * mat[2*6+1];
  2487. c1 = mat[1*6+2] * mat[2*6+0] - mat[1*6+0] * mat[2*6+2];
  2488. c2 = mat[1*6+0] * mat[2*6+1] - mat[1*6+1] * mat[2*6+0];
  2489. det = mat[0*6+0] * c0 + mat[0*6+1] * c1 + mat[0*6+2] * c2;
  2490. if ( idMath::Fabs( det ) < MATRIX_INVERSE_EPSILON ) {
  2491. return false;
  2492. }
  2493. invDet = 1.0f / det;
  2494. r0[0][0] = c0 * invDet;
  2495. r0[0][1] = ( mat[0*6+2] * mat[2*6+1] - mat[0*6+1] * mat[2*6+2] ) * invDet;
  2496. r0[0][2] = ( mat[0*6+1] * mat[1*6+2] - mat[0*6+2] * mat[1*6+1] ) * invDet;
  2497. r0[1][0] = c1 * invDet;
  2498. r0[1][1] = ( mat[0*6+0] * mat[2*6+2] - mat[0*6+2] * mat[2*6+0] ) * invDet;
  2499. r0[1][2] = ( mat[0*6+2] * mat[1*6+0] - mat[0*6+0] * mat[1*6+2] ) * invDet;
  2500. r0[2][0] = c2 * invDet;
  2501. r0[2][1] = ( mat[0*6+1] * mat[2*6+0] - mat[0*6+0] * mat[2*6+1] ) * invDet;
  2502. r0[2][2] = ( mat[0*6+0] * mat[1*6+1] - mat[0*6+1] * mat[1*6+0] ) * invDet;
  2503. // r1 = r0 * m1;
  2504. r1[0][0] = r0[0][0] * mat[0*6+3] + r0[0][1] * mat[1*6+3] + r0[0][2] * mat[2*6+3];
  2505. r1[0][1] = r0[0][0] * mat[0*6+4] + r0[0][1] * mat[1*6+4] + r0[0][2] * mat[2*6+4];
  2506. r1[0][2] = r0[0][0] * mat[0*6+5] + r0[0][1] * mat[1*6+5] + r0[0][2] * mat[2*6+5];
  2507. r1[1][0] = r0[1][0] * mat[0*6+3] + r0[1][1] * mat[1*6+3] + r0[1][2] * mat[2*6+3];
  2508. r1[1][1] = r0[1][0] * mat[0*6+4] + r0[1][1] * mat[1*6+4] + r0[1][2] * mat[2*6+4];
  2509. r1[1][2] = r0[1][0] * mat[0*6+5] + r0[1][1] * mat[1*6+5] + r0[1][2] * mat[2*6+5];
  2510. r1[2][0] = r0[2][0] * mat[0*6+3] + r0[2][1] * mat[1*6+3] + r0[2][2] * mat[2*6+3];
  2511. r1[2][1] = r0[2][0] * mat[0*6+4] + r0[2][1] * mat[1*6+4] + r0[2][2] * mat[2*6+4];
  2512. r1[2][2] = r0[2][0] * mat[0*6+5] + r0[2][1] * mat[1*6+5] + r0[2][2] * mat[2*6+5];
  2513. // r2 = m2 * r1;
  2514. r2[0][0] = mat[3*6+0] * r1[0][0] + mat[3*6+1] * r1[1][0] + mat[3*6+2] * r1[2][0];
  2515. r2[0][1] = mat[3*6+0] * r1[0][1] + mat[3*6+1] * r1[1][1] + mat[3*6+2] * r1[2][1];
  2516. r2[0][2] = mat[3*6+0] * r1[0][2] + mat[3*6+1] * r1[1][2] + mat[3*6+2] * r1[2][2];
  2517. r2[1][0] = mat[4*6+0] * r1[0][0] + mat[4*6+1] * r1[1][0] + mat[4*6+2] * r1[2][0];
  2518. r2[1][1] = mat[4*6+0] * r1[0][1] + mat[4*6+1] * r1[1][1] + mat[4*6+2] * r1[2][1];
  2519. r2[1][2] = mat[4*6+0] * r1[0][2] + mat[4*6+1] * r1[1][2] + mat[4*6+2] * r1[2][2];
  2520. r2[2][0] = mat[5*6+0] * r1[0][0] + mat[5*6+1] * r1[1][0] + mat[5*6+2] * r1[2][0];
  2521. r2[2][1] = mat[5*6+0] * r1[0][1] + mat[5*6+1] * r1[1][1] + mat[5*6+2] * r1[2][1];
  2522. r2[2][2] = mat[5*6+0] * r1[0][2] + mat[5*6+1] * r1[1][2] + mat[5*6+2] * r1[2][2];
  2523. // r3 = r2 - m3;
  2524. r3[0][0] = r2[0][0] - mat[3*6+3];
  2525. r3[0][1] = r2[0][1] - mat[3*6+4];
  2526. r3[0][2] = r2[0][2] - mat[3*6+5];
  2527. r3[1][0] = r2[1][0] - mat[4*6+3];
  2528. r3[1][1] = r2[1][1] - mat[4*6+4];
  2529. r3[1][2] = r2[1][2] - mat[4*6+5];
  2530. r3[2][0] = r2[2][0] - mat[5*6+3];
  2531. r3[2][1] = r2[2][1] - mat[5*6+4];
  2532. r3[2][2] = r2[2][2] - mat[5*6+5];
  2533. // r3.InverseSelf();
  2534. r2[0][0] = r3[1][1] * r3[2][2] - r3[1][2] * r3[2][1];
  2535. r2[1][0] = r3[1][2] * r3[2][0] - r3[1][0] * r3[2][2];
  2536. r2[2][0] = r3[1][0] * r3[2][1] - r3[1][1] * r3[2][0];
  2537. det = r3[0][0] * r2[0][0] + r3[0][1] * r2[1][0] + r3[0][2] * r2[2][0];
  2538. if ( idMath::Fabs( det ) < MATRIX_INVERSE_EPSILON ) {
  2539. return false;
  2540. }
  2541. invDet = 1.0f / det;
  2542. r2[0][1] = r3[0][2] * r3[2][1] - r3[0][1] * r3[2][2];
  2543. r2[0][2] = r3[0][1] * r3[1][2] - r3[0][2] * r3[1][1];
  2544. r2[1][1] = r3[0][0] * r3[2][2] - r3[0][2] * r3[2][0];
  2545. r2[1][2] = r3[0][2] * r3[1][0] - r3[0][0] * r3[1][2];
  2546. r2[2][1] = r3[0][1] * r3[2][0] - r3[0][0] * r3[2][1];
  2547. r2[2][2] = r3[0][0] * r3[1][1] - r3[0][1] * r3[1][0];
  2548. r3[0][0] = r2[0][0] * invDet;
  2549. r3[0][1] = r2[0][1] * invDet;
  2550. r3[0][2] = r2[0][2] * invDet;
  2551. r3[1][0] = r2[1][0] * invDet;
  2552. r3[1][1] = r2[1][1] * invDet;
  2553. r3[1][2] = r2[1][2] * invDet;
  2554. r3[2][0] = r2[2][0] * invDet;
  2555. r3[2][1] = r2[2][1] * invDet;
  2556. r3[2][2] = r2[2][2] * invDet;
  2557. // r2 = m2 * r0;
  2558. r2[0][0] = mat[3*6+0] * r0[0][0] + mat[3*6+1] * r0[1][0] + mat[3*6+2] * r0[2][0];
  2559. r2[0][1] = mat[3*6+0] * r0[0][1] + mat[3*6+1] * r0[1][1] + mat[3*6+2] * r0[2][1];
  2560. r2[0][2] = mat[3*6+0] * r0[0][2] + mat[3*6+1] * r0[1][2] + mat[3*6+2] * r0[2][2];
  2561. r2[1][0] = mat[4*6+0] * r0[0][0] + mat[4*6+1] * r0[1][0] + mat[4*6+2] * r0[2][0];
  2562. r2[1][1] = mat[4*6+0] * r0[0][1] + mat[4*6+1] * r0[1][1] + mat[4*6+2] * r0[2][1];
  2563. r2[1][2] = mat[4*6+0] * r0[0][2] + mat[4*6+1] * r0[1][2] + mat[4*6+2] * r0[2][2];
  2564. r2[2][0] = mat[5*6+0] * r0[0][0] + mat[5*6+1] * r0[1][0] + mat[5*6+2] * r0[2][0];
  2565. r2[2][1] = mat[5*6+0] * r0[0][1] + mat[5*6+1] * r0[1][1] + mat[5*6+2] * r0[2][1];
  2566. r2[2][2] = mat[5*6+0] * r0[0][2] + mat[5*6+1] * r0[1][2] + mat[5*6+2] * r0[2][2];
  2567. // m2 = r3 * r2;
  2568. mat[3*6+0] = r3[0][0] * r2[0][0] + r3[0][1] * r2[1][0] + r3[0][2] * r2[2][0];
  2569. mat[3*6+1] = r3[0][0] * r2[0][1] + r3[0][1] * r2[1][1] + r3[0][2] * r2[2][1];
  2570. mat[3*6+2] = r3[0][0] * r2[0][2] + r3[0][1] * r2[1][2] + r3[0][2] * r2[2][2];
  2571. mat[4*6+0] = r3[1][0] * r2[0][0] + r3[1][1] * r2[1][0] + r3[1][2] * r2[2][0];
  2572. mat[4*6+1] = r3[1][0] * r2[0][1] + r3[1][1] * r2[1][1] + r3[1][2] * r2[2][1];
  2573. mat[4*6+2] = r3[1][0] * r2[0][2] + r3[1][1] * r2[1][2] + r3[1][2] * r2[2][2];
  2574. mat[5*6+0] = r3[2][0] * r2[0][0] + r3[2][1] * r2[1][0] + r3[2][2] * r2[2][0];
  2575. mat[5*6+1] = r3[2][0] * r2[0][1] + r3[2][1] * r2[1][1] + r3[2][2] * r2[2][1];
  2576. mat[5*6+2] = r3[2][0] * r2[0][2] + r3[2][1] * r2[1][2] + r3[2][2] * r2[2][2];
  2577. // m0 = r0 - r1 * m2;
  2578. mat[0*6+0] = r0[0][0] - r1[0][0] * mat[3*6+0] - r1[0][1] * mat[4*6+0] - r1[0][2] * mat[5*6+0];
  2579. mat[0*6+1] = r0[0][1] - r1[0][0] * mat[3*6+1] - r1[0][1] * mat[4*6+1] - r1[0][2] * mat[5*6+1];
  2580. mat[0*6+2] = r0[0][2] - r1[0][0] * mat[3*6+2] - r1[0][1] * mat[4*6+2] - r1[0][2] * mat[5*6+2];
  2581. mat[1*6+0] = r0[1][0] - r1[1][0] * mat[3*6+0] - r1[1][1] * mat[4*6+0] - r1[1][2] * mat[5*6+0];
  2582. mat[1*6+1] = r0[1][1] - r1[1][0] * mat[3*6+1] - r1[1][1] * mat[4*6+1] - r1[1][2] * mat[5*6+1];
  2583. mat[1*6+2] = r0[1][2] - r1[1][0] * mat[3*6+2] - r1[1][1] * mat[4*6+2] - r1[1][2] * mat[5*6+2];
  2584. mat[2*6+0] = r0[2][0] - r1[2][0] * mat[3*6+0] - r1[2][1] * mat[4*6+0] - r1[2][2] * mat[5*6+0];
  2585. mat[2*6+1] = r0[2][1] - r1[2][0] * mat[3*6+1] - r1[2][1] * mat[4*6+1] - r1[2][2] * mat[5*6+1];
  2586. mat[2*6+2] = r0[2][2] - r1[2][0] * mat[3*6+2] - r1[2][1] * mat[4*6+2] - r1[2][2] * mat[5*6+2];
  2587. // m1 = r1 * r3;
  2588. mat[0*6+3] = r1[0][0] * r3[0][0] + r1[0][1] * r3[1][0] + r1[0][2] * r3[2][0];
  2589. mat[0*6+4] = r1[0][0] * r3[0][1] + r1[0][1] * r3[1][1] + r1[0][2] * r3[2][1];
  2590. mat[0*6+5] = r1[0][0] * r3[0][2] + r1[0][1] * r3[1][2] + r1[0][2] * r3[2][2];
  2591. mat[1*6+3] = r1[1][0] * r3[0][0] + r1[1][1] * r3[1][0] + r1[1][2] * r3[2][0];
  2592. mat[1*6+4] = r1[1][0] * r3[0][1] + r1[1][1] * r3[1][1] + r1[1][2] * r3[2][1];
  2593. mat[1*6+5] = r1[1][0] * r3[0][2] + r1[1][1] * r3[1][2] + r1[1][2] * r3[2][2];
  2594. mat[2*6+3] = r1[2][0] * r3[0][0] + r1[2][1] * r3[1][0] + r1[2][2] * r3[2][0];
  2595. mat[2*6+4] = r1[2][0] * r3[0][1] + r1[2][1] * r3[1][1] + r1[2][2] * r3[2][1];
  2596. mat[2*6+5] = r1[2][0] * r3[0][2] + r1[2][1] * r3[1][2] + r1[2][2] * r3[2][2];
  2597. // m3 = -r3;
  2598. mat[3*6+3] = -r3[0][0];
  2599. mat[3*6+4] = -r3[0][1];
  2600. mat[3*6+5] = -r3[0][2];
  2601. mat[4*6+3] = -r3[1][0];
  2602. mat[4*6+4] = -r3[1][1];
  2603. mat[4*6+5] = -r3[1][2];
  2604. mat[5*6+3] = -r3[2][0];
  2605. mat[5*6+4] = -r3[2][1];
  2606. mat[5*6+5] = -r3[2][2];
  2607. return true;
  2608. #endif
  2609. }
  2610. /*
  2611. =============
  2612. idMat6::ToString
  2613. =============
  2614. */
  2615. const char *idMat6::ToString( int precision ) const {
  2616. return idStr::FloatArrayToString( ToFloatPtr(), GetDimension(), precision );
  2617. }
  2618. //===============================================================
  2619. //
  2620. // idMatX
  2621. //
  2622. //===============================================================
  2623. float idMatX::temp[MATX_MAX_TEMP+4];
  2624. float * idMatX::tempPtr = (float *) ( ( (int) idMatX::temp + 15 ) & ~15 );
  2625. int idMatX::tempIndex = 0;
  2626. /*
  2627. ============
  2628. idMatX::ChangeSize
  2629. ============
  2630. */
  2631. void idMatX::ChangeSize( int rows, int columns, bool makeZero ) {
  2632. int alloc = ( rows * columns + 3 ) & ~3;
  2633. if ( alloc > alloced && alloced != -1 ) {
  2634. float *oldMat = mat;
  2635. mat = (float *) Mem_Alloc16( alloc * sizeof( float ) );
  2636. if ( makeZero ) {
  2637. memset( mat, 0, alloc * sizeof( float ) );
  2638. }
  2639. alloced = alloc;
  2640. if ( oldMat ) {
  2641. int minRow = Min( numRows, rows );
  2642. int minColumn = Min( numColumns, columns );
  2643. for ( int i = 0; i < minRow; i++ ) {
  2644. for ( int j = 0; j < minColumn; j++ ) {
  2645. mat[ i * columns + j ] = oldMat[ i * numColumns + j ];
  2646. }
  2647. }
  2648. Mem_Free16( oldMat );
  2649. }
  2650. } else {
  2651. if ( columns < numColumns ) {
  2652. int minRow = Min( numRows, rows );
  2653. for ( int i = 0; i < minRow; i++ ) {
  2654. for ( int j = 0; j < columns; j++ ) {
  2655. mat[ i * columns + j ] = mat[ i * numColumns + j ];
  2656. }
  2657. }
  2658. } else if ( columns > numColumns ) {
  2659. for ( int i = Min( numRows, rows ) - 1; i >= 0; i-- ) {
  2660. if ( makeZero ) {
  2661. for ( int j = columns - 1; j >= numColumns; j-- ) {
  2662. mat[ i * columns + j ] = 0.0f;
  2663. }
  2664. }
  2665. for ( int j = numColumns - 1; j >= 0; j-- ) {
  2666. mat[ i * columns + j ] = mat[ i * numColumns + j ];
  2667. }
  2668. }
  2669. }
  2670. if ( makeZero && rows > numRows ) {
  2671. memset( mat + numRows * columns, 0, ( rows - numRows ) * columns * sizeof( float ) );
  2672. }
  2673. }
  2674. numRows = rows;
  2675. numColumns = columns;
  2676. MATX_CLEAREND();
  2677. }
  2678. /*
  2679. ============
  2680. idMatX::RemoveRow
  2681. ============
  2682. */
  2683. idMatX &idMatX::RemoveRow( int r ) {
  2684. int i;
  2685. assert( r < numRows );
  2686. numRows--;
  2687. for ( i = r; i < numRows; i++ ) {
  2688. memcpy( &mat[i * numColumns], &mat[( i + 1 ) * numColumns], numColumns * sizeof( float ) );
  2689. }
  2690. return *this;
  2691. }
  2692. /*
  2693. ============
  2694. idMatX::RemoveColumn
  2695. ============
  2696. */
  2697. idMatX &idMatX::RemoveColumn( int r ) {
  2698. int i;
  2699. assert( r < numColumns );
  2700. numColumns--;
  2701. for ( i = 0; i < numRows - 1; i++ ) {
  2702. memmove( &mat[i * numColumns + r], &mat[i * ( numColumns + 1 ) + r + 1], numColumns * sizeof( float ) );
  2703. }
  2704. memmove( &mat[i * numColumns + r], &mat[i * ( numColumns + 1 ) + r + 1], ( numColumns - r ) * sizeof( float ) );
  2705. return *this;
  2706. }
  2707. /*
  2708. ============
  2709. idMatX::RemoveRowColumn
  2710. ============
  2711. */
  2712. idMatX &idMatX::RemoveRowColumn( int r ) {
  2713. int i;
  2714. assert( r < numRows && r < numColumns );
  2715. numRows--;
  2716. numColumns--;
  2717. if ( r > 0 ) {
  2718. for ( i = 0; i < r - 1; i++ ) {
  2719. memmove( &mat[i * numColumns + r], &mat[i * ( numColumns + 1 ) + r + 1], numColumns * sizeof( float ) );
  2720. }
  2721. memmove( &mat[i * numColumns + r], &mat[i * ( numColumns + 1 ) + r + 1], ( numColumns - r ) * sizeof( float ) );
  2722. }
  2723. memcpy( &mat[r * numColumns], &mat[( r + 1 ) * ( numColumns + 1 )], r * sizeof( float ) );
  2724. for ( i = r; i < numRows - 1; i++ ) {
  2725. memcpy( &mat[i * numColumns + r], &mat[( i + 1 ) * ( numColumns + 1 ) + r + 1], numColumns * sizeof( float ) );
  2726. }
  2727. memcpy( &mat[i * numColumns + r], &mat[( i + 1 ) * ( numColumns + 1 ) + r + 1], ( numColumns - r ) * sizeof( float ) );
  2728. return *this;
  2729. }
  2730. /*
  2731. ============
  2732. idMatX::IsOrthogonal
  2733. returns true if (*this) * this->Transpose() == Identity
  2734. ============
  2735. */
  2736. bool idMatX::IsOrthogonal( const float epsilon ) const {
  2737. float *ptr1, *ptr2, sum;
  2738. if ( !IsSquare() ) {
  2739. return false;
  2740. }
  2741. ptr1 = mat;
  2742. for ( int i = 0; i < numRows; i++ ) {
  2743. for ( int j = 0; j < numColumns; j++ ) {
  2744. ptr2 = mat + j;
  2745. sum = ptr1[0] * ptr2[0] - (float) ( i == j );
  2746. for ( int n = 1; n < numColumns; n++ ) {
  2747. ptr2 += numColumns;
  2748. sum += ptr1[n] * ptr2[0];
  2749. }
  2750. if ( idMath::Fabs( sum ) > epsilon ) {
  2751. return false;
  2752. }
  2753. }
  2754. ptr1 += numColumns;
  2755. }
  2756. return true;
  2757. }
  2758. /*
  2759. ============
  2760. idMatX::IsOrthonormal
  2761. returns true if (*this) * this->Transpose() == Identity and the length of each column vector is 1
  2762. ============
  2763. */
  2764. bool idMatX::IsOrthonormal( const float epsilon ) const {
  2765. float *ptr1, *ptr2, sum;
  2766. if ( !IsSquare() ) {
  2767. return false;
  2768. }
  2769. ptr1 = mat;
  2770. for ( int i = 0; i < numRows; i++ ) {
  2771. for ( int j = 0; j < numColumns; j++ ) {
  2772. ptr2 = mat + j;
  2773. sum = ptr1[0] * ptr2[0] - (float) ( i == j );
  2774. for ( int n = 1; n < numColumns; n++ ) {
  2775. ptr2 += numColumns;
  2776. sum += ptr1[n] * ptr2[0];
  2777. }
  2778. if ( idMath::Fabs( sum ) > epsilon ) {
  2779. return false;
  2780. }
  2781. }
  2782. ptr1 += numColumns;
  2783. ptr2 = mat + i;
  2784. sum = ptr2[0] * ptr2[0] - 1.0f;
  2785. for ( i = 1; i < numRows; i++ ) {
  2786. ptr2 += numColumns;
  2787. sum += ptr2[i] * ptr2[i];
  2788. }
  2789. if ( idMath::Fabs( sum ) > epsilon ) {
  2790. return false;
  2791. }
  2792. }
  2793. return true;
  2794. }
  2795. /*
  2796. ============
  2797. idMatX::IsPMatrix
  2798. returns true if the matrix is a P-matrix
  2799. A square matrix is a P-matrix if all its principal minors are positive.
  2800. ============
  2801. */
  2802. bool idMatX::IsPMatrix( const float epsilon ) const {
  2803. int i, j;
  2804. float d;
  2805. idMatX m;
  2806. if ( !IsSquare() ) {
  2807. return false;
  2808. }
  2809. if ( numRows <= 0 ) {
  2810. return true;
  2811. }
  2812. if ( (*this)[0][0] <= epsilon ) {
  2813. return false;
  2814. }
  2815. if ( numRows <= 1 ) {
  2816. return true;
  2817. }
  2818. m.SetData( numRows - 1, numColumns - 1, MATX_ALLOCA( ( numRows - 1 ) * ( numColumns - 1 ) ) );
  2819. for ( i = 1; i < numRows; i++ ) {
  2820. for ( j = 1; j < numColumns; j++ ) {
  2821. m[i-1][j-1] = (*this)[i][j];
  2822. }
  2823. }
  2824. if ( !m.IsPMatrix( epsilon ) ) {
  2825. return false;
  2826. }
  2827. for ( i = 1; i < numRows; i++ ) {
  2828. d = (*this)[i][0] / (*this)[0][0];
  2829. for ( j = 1; j < numColumns; j++ ) {
  2830. m[i-1][j-1] = (*this)[i][j] - d * (*this)[0][j];
  2831. }
  2832. }
  2833. if ( !m.IsPMatrix( epsilon ) ) {
  2834. return false;
  2835. }
  2836. return true;
  2837. }
  2838. /*
  2839. ============
  2840. idMatX::IsZMatrix
  2841. returns true if the matrix is a Z-matrix
  2842. A square matrix M is a Z-matrix if M[i][j] <= 0 for all i != j.
  2843. ============
  2844. */
  2845. bool idMatX::IsZMatrix( const float epsilon ) const {
  2846. int i, j;
  2847. if ( !IsSquare() ) {
  2848. return false;
  2849. }
  2850. for ( i = 0; i < numRows; i++ ) {
  2851. for ( j = 0; j < numColumns; j++ ) {
  2852. if ( (*this)[i][j] > epsilon && i != j ) {
  2853. return false;
  2854. }
  2855. }
  2856. }
  2857. return true;
  2858. }
  2859. /*
  2860. ============
  2861. idMatX::IsPositiveDefinite
  2862. returns true if the matrix is Positive Definite (PD)
  2863. A square matrix M of order n is said to be PD if y'My > 0 for all vectors y of dimension n, y != 0.
  2864. ============
  2865. */
  2866. bool idMatX::IsPositiveDefinite( const float epsilon ) const {
  2867. int i, j, k;
  2868. float d, s;
  2869. idMatX m;
  2870. // the matrix must be square
  2871. if ( !IsSquare() ) {
  2872. return false;
  2873. }
  2874. // copy matrix
  2875. m.SetData( numRows, numColumns, MATX_ALLOCA( numRows * numColumns ) );
  2876. m = *this;
  2877. // add transpose
  2878. for ( i = 0; i < numRows; i++ ) {
  2879. for ( j = 0; j < numColumns; j++ ) {
  2880. m[i][j] += (*this)[j][i];
  2881. }
  2882. }
  2883. // test Positive Definiteness with Gaussian pivot steps
  2884. for ( i = 0; i < numRows; i++ ) {
  2885. for ( j = i; j < numColumns; j++ ) {
  2886. if ( m[j][j] <= epsilon ) {
  2887. return false;
  2888. }
  2889. }
  2890. d = 1.0f / m[i][i];
  2891. for ( j = i + 1; j < numColumns; j++ ) {
  2892. s = d * m[j][i];
  2893. m[j][i] = 0.0f;
  2894. for ( k = i + 1; k < numRows; k++ ) {
  2895. m[j][k] -= s * m[i][k];
  2896. }
  2897. }
  2898. }
  2899. return true;
  2900. }
  2901. /*
  2902. ============
  2903. idMatX::IsSymmetricPositiveDefinite
  2904. returns true if the matrix is Symmetric Positive Definite (PD)
  2905. ============
  2906. */
  2907. bool idMatX::IsSymmetricPositiveDefinite( const float epsilon ) const {
  2908. idMatX m;
  2909. // the matrix must be symmetric
  2910. if ( !IsSymmetric( epsilon ) ) {
  2911. return false;
  2912. }
  2913. // copy matrix
  2914. m.SetData( numRows, numColumns, MATX_ALLOCA( numRows * numColumns ) );
  2915. m = *this;
  2916. // being able to obtain Cholesky factors is both a necessary and sufficient condition for positive definiteness
  2917. return m.Cholesky_Factor();
  2918. }
  2919. /*
  2920. ============
  2921. idMatX::IsPositiveSemiDefinite
  2922. returns true if the matrix is Positive Semi Definite (PSD)
  2923. A square matrix M of order n is said to be PSD if y'My >= 0 for all vectors y of dimension n, y != 0.
  2924. ============
  2925. */
  2926. bool idMatX::IsPositiveSemiDefinite( const float epsilon ) const {
  2927. int i, j, k;
  2928. float d, s;
  2929. idMatX m;
  2930. // the matrix must be square
  2931. if ( !IsSquare() ) {
  2932. return false;
  2933. }
  2934. // copy original matrix
  2935. m.SetData( numRows, numColumns, MATX_ALLOCA( numRows * numColumns ) );
  2936. m = *this;
  2937. // add transpose
  2938. for ( i = 0; i < numRows; i++ ) {
  2939. for ( j = 0; j < numColumns; j++ ) {
  2940. m[i][j] += (*this)[j][i];
  2941. }
  2942. }
  2943. // test Positive Semi Definiteness with Gaussian pivot steps
  2944. for ( i = 0; i < numRows; i++ ) {
  2945. for ( j = i; j < numColumns; j++ ) {
  2946. if ( m[j][j] < -epsilon ) {
  2947. return false;
  2948. }
  2949. if ( m[j][j] > epsilon ) {
  2950. continue;
  2951. }
  2952. for ( k = 0; k < numRows; k++ ) {
  2953. if ( idMath::Fabs( m[k][j] ) > epsilon ) {
  2954. return false;
  2955. }
  2956. if ( idMath::Fabs( m[j][k] ) > epsilon ) {
  2957. return false;
  2958. }
  2959. }
  2960. }
  2961. if ( m[i][i] <= epsilon ) {
  2962. continue;
  2963. }
  2964. d = 1.0f / m[i][i];
  2965. for ( j = i + 1; j < numColumns; j++ ) {
  2966. s = d * m[j][i];
  2967. m[j][i] = 0.0f;
  2968. for ( k = i + 1; k < numRows; k++ ) {
  2969. m[j][k] -= s * m[i][k];
  2970. }
  2971. }
  2972. }
  2973. return true;
  2974. }
  2975. /*
  2976. ============
  2977. idMatX::IsSymmetricPositiveSemiDefinite
  2978. returns true if the matrix is Symmetric Positive Semi Definite (PSD)
  2979. ============
  2980. */
  2981. bool idMatX::IsSymmetricPositiveSemiDefinite( const float epsilon ) const {
  2982. // the matrix must be symmetric
  2983. if ( !IsSymmetric( epsilon ) ) {
  2984. return false;
  2985. }
  2986. return IsPositiveSemiDefinite( epsilon );
  2987. }
  2988. /*
  2989. ============
  2990. idMatX::LowerTriangularInverse
  2991. in-place inversion of the lower triangular matrix
  2992. ============
  2993. */
  2994. bool idMatX::LowerTriangularInverse( void ) {
  2995. int i, j, k;
  2996. double d, sum;
  2997. for ( i = 0; i < numRows; i++ ) {
  2998. d = (*this)[i][i];
  2999. if ( d == 0.0f ) {
  3000. return false;
  3001. }
  3002. (*this)[i][i] = d = 1.0f / d;
  3003. for ( j = 0; j < i; j++ ) {
  3004. sum = 0.0f;
  3005. for ( k = j; k < i; k++ ) {
  3006. sum -= (*this)[i][k] * (*this)[k][j];
  3007. }
  3008. (*this)[i][j] = sum * d;
  3009. }
  3010. }
  3011. return true;
  3012. }
  3013. /*
  3014. ============
  3015. idMatX::UpperTriangularInverse
  3016. in-place inversion of the upper triangular matrix
  3017. ============
  3018. */
  3019. bool idMatX::UpperTriangularInverse( void ) {
  3020. int i, j, k;
  3021. double d, sum;
  3022. for ( i = numRows-1; i >= 0; i-- ) {
  3023. d = (*this)[i][i];
  3024. if ( d == 0.0f ) {
  3025. return false;
  3026. }
  3027. (*this)[i][i] = d = 1.0f / d;
  3028. for ( j = numRows-1; j > i; j-- ) {
  3029. sum = 0.0f;
  3030. for ( k = j; k > i; k-- ) {
  3031. sum -= (*this)[i][k] * (*this)[k][j];
  3032. }
  3033. (*this)[i][j] = sum * d;
  3034. }
  3035. }
  3036. return true;
  3037. }
  3038. /*
  3039. =============
  3040. idMatX::ToString
  3041. =============
  3042. */
  3043. const char *idMatX::ToString( int precision ) const {
  3044. return idStr::FloatArrayToString( ToFloatPtr(), GetDimension(), precision );
  3045. }
  3046. /*
  3047. ============
  3048. idMatX::Update_RankOne
  3049. Updates the matrix to obtain the matrix: A + alpha * v * w'
  3050. ============
  3051. */
  3052. void idMatX::Update_RankOne( const idVecX &v, const idVecX &w, float alpha ) {
  3053. int i, j;
  3054. float s;
  3055. assert( v.GetSize() >= numRows );
  3056. assert( w.GetSize() >= numColumns );
  3057. for ( i = 0; i < numRows; i++ ) {
  3058. s = alpha * v[i];
  3059. for ( j = 0; j < numColumns; j++ ) {
  3060. (*this)[i][j] += s * w[j];
  3061. }
  3062. }
  3063. }
  3064. /*
  3065. ============
  3066. idMatX::Update_RankOneSymmetric
  3067. Updates the matrix to obtain the matrix: A + alpha * v * v'
  3068. ============
  3069. */
  3070. void idMatX::Update_RankOneSymmetric( const idVecX &v, float alpha ) {
  3071. int i, j;
  3072. float s;
  3073. assert( numRows == numColumns );
  3074. assert( v.GetSize() >= numRows );
  3075. for ( i = 0; i < numRows; i++ ) {
  3076. s = alpha * v[i];
  3077. for ( j = 0; j < numColumns; j++ ) {
  3078. (*this)[i][j] += s * v[j];
  3079. }
  3080. }
  3081. }
  3082. /*
  3083. ============
  3084. idMatX::Update_RowColumn
  3085. Updates the matrix to obtain the matrix:
  3086. [ 0 a 0 ]
  3087. A + [ d b e ]
  3088. [ 0 c 0 ]
  3089. where: a = v[0,r-1], b = v[r], c = v[r+1,numRows-1], d = w[0,r-1], w[r] = 0.0f, e = w[r+1,numColumns-1]
  3090. ============
  3091. */
  3092. void idMatX::Update_RowColumn( const idVecX &v, const idVecX &w, int r ) {
  3093. int i;
  3094. assert( w[r] == 0.0f );
  3095. assert( v.GetSize() >= numColumns );
  3096. assert( w.GetSize() >= numRows );
  3097. for ( i = 0; i < numRows; i++ ) {
  3098. (*this)[i][r] += v[i];
  3099. }
  3100. for ( i = 0; i < numColumns; i++ ) {
  3101. (*this)[r][i] += w[i];
  3102. }
  3103. }
  3104. /*
  3105. ============
  3106. idMatX::Update_RowColumnSymmetric
  3107. Updates the matrix to obtain the matrix:
  3108. [ 0 a 0 ]
  3109. A + [ a b c ]
  3110. [ 0 c 0 ]
  3111. where: a = v[0,r-1], b = v[r], c = v[r+1,numRows-1]
  3112. ============
  3113. */
  3114. void idMatX::Update_RowColumnSymmetric( const idVecX &v, int r ) {
  3115. int i;
  3116. assert( numRows == numColumns );
  3117. assert( v.GetSize() >= numRows );
  3118. for ( i = 0; i < r; i++ ) {
  3119. (*this)[i][r] += v[i];
  3120. (*this)[r][i] += v[i];
  3121. }
  3122. (*this)[r][r] += v[r];
  3123. for ( i = r+1; i < numRows; i++ ) {
  3124. (*this)[i][r] += v[i];
  3125. (*this)[r][i] += v[i];
  3126. }
  3127. }
  3128. /*
  3129. ============
  3130. idMatX::Update_Increment
  3131. Updates the matrix to obtain the matrix:
  3132. [ A a ]
  3133. [ c b ]
  3134. where: a = v[0,numRows-1], b = v[numRows], c = w[0,numColumns-1]], w[numColumns] = 0
  3135. ============
  3136. */
  3137. void idMatX::Update_Increment( const idVecX &v, const idVecX &w ) {
  3138. int i;
  3139. assert( numRows == numColumns );
  3140. assert( v.GetSize() >= numRows+1 );
  3141. assert( w.GetSize() >= numColumns+1 );
  3142. ChangeSize( numRows+1, numColumns+1, false );
  3143. for ( i = 0; i < numRows; i++ ) {
  3144. (*this)[i][numColumns-1] = v[i];
  3145. }
  3146. for ( i = 0; i < numColumns-1; i++ ) {
  3147. (*this)[numRows-1][i] = w[i];
  3148. }
  3149. }
  3150. /*
  3151. ============
  3152. idMatX::Update_IncrementSymmetric
  3153. Updates the matrix to obtain the matrix:
  3154. [ A a ]
  3155. [ a b ]
  3156. where: a = v[0,numRows-1], b = v[numRows]
  3157. ============
  3158. */
  3159. void idMatX::Update_IncrementSymmetric( const idVecX &v ) {
  3160. int i;
  3161. assert( numRows == numColumns );
  3162. assert( v.GetSize() >= numRows+1 );
  3163. ChangeSize( numRows+1, numColumns+1, false );
  3164. for ( i = 0; i < numRows-1; i++ ) {
  3165. (*this)[i][numColumns-1] = v[i];
  3166. }
  3167. for ( i = 0; i < numColumns; i++ ) {
  3168. (*this)[numRows-1][i] = v[i];
  3169. }
  3170. }
  3171. /*
  3172. ============
  3173. idMatX::Update_Decrement
  3174. Updates the matrix to obtain a matrix with row r and column r removed.
  3175. ============
  3176. */
  3177. void idMatX::Update_Decrement( int r ) {
  3178. RemoveRowColumn( r );
  3179. }
  3180. /*
  3181. ============
  3182. idMatX::Inverse_GaussJordan
  3183. in-place inversion using Gauss-Jordan elimination
  3184. ============
  3185. */
  3186. bool idMatX::Inverse_GaussJordan( void ) {
  3187. int i, j, k, r, c;
  3188. float d, max;
  3189. assert( numRows == numColumns );
  3190. int *columnIndex = (int *) _alloca16( numRows * sizeof( int ) );
  3191. int *rowIndex = (int *) _alloca16( numRows * sizeof( int ) );
  3192. bool *pivot = (bool *) _alloca16( numRows * sizeof( bool ) );
  3193. memset( pivot, 0, numRows * sizeof( bool ) );
  3194. // elimination with full pivoting
  3195. for ( i = 0; i < numRows; i++ ) {
  3196. // search the whole matrix except for pivoted rows for the maximum absolute value
  3197. max = 0.0f;
  3198. r = c = 0;
  3199. for ( j = 0; j < numRows; j++ ) {
  3200. if ( !pivot[j] ) {
  3201. for ( k = 0; k < numRows; k++ ) {
  3202. if ( !pivot[k] ) {
  3203. d = idMath::Fabs( (*this)[j][k] );
  3204. if ( d > max ) {
  3205. max = d;
  3206. r = j;
  3207. c = k;
  3208. }
  3209. }
  3210. }
  3211. }
  3212. }
  3213. if ( max == 0.0f ) {
  3214. // matrix is not invertible
  3215. return false;
  3216. }
  3217. pivot[c] = true;
  3218. // swap rows such that entry (c,c) has the pivot entry
  3219. if ( r != c ) {
  3220. SwapRows( r, c );
  3221. }
  3222. // keep track of the row permutation
  3223. rowIndex[i] = r;
  3224. columnIndex[i] = c;
  3225. // scale the row to make the pivot entry equal to 1
  3226. d = 1.0f / (*this)[c][c];
  3227. (*this)[c][c] = 1.0f;
  3228. for ( k = 0; k < numRows; k++ ) {
  3229. (*this)[c][k] *= d;
  3230. }
  3231. // zero out the pivot column entries in the other rows
  3232. for ( j = 0; j < numRows; j++ ) {
  3233. if ( j != c ) {
  3234. d = (*this)[j][c];
  3235. (*this)[j][c] = 0.0f;
  3236. for ( k = 0; k < numRows; k++ ) {
  3237. (*this)[j][k] -= (*this)[c][k] * d;
  3238. }
  3239. }
  3240. }
  3241. }
  3242. // reorder rows to store the inverse of the original matrix
  3243. for ( j = numRows - 1; j >= 0; j-- ) {
  3244. if ( rowIndex[j] != columnIndex[j] ) {
  3245. for ( k = 0; k < numRows; k++ ) {
  3246. d = (*this)[k][rowIndex[j]];
  3247. (*this)[k][rowIndex[j]] = (*this)[k][columnIndex[j]];
  3248. (*this)[k][columnIndex[j]] = d;
  3249. }
  3250. }
  3251. }
  3252. return true;
  3253. }
  3254. /*
  3255. ============
  3256. idMatX::Inverse_UpdateRankOne
  3257. Updates the in-place inverse using the Sherman-Morrison formula to obtain the inverse for the matrix: A + alpha * v * w'
  3258. ============
  3259. */
  3260. bool idMatX::Inverse_UpdateRankOne( const idVecX &v, const idVecX &w, float alpha ) {
  3261. int i, j;
  3262. float beta, s;
  3263. idVecX y, z;
  3264. assert( numRows == numColumns );
  3265. assert( v.GetSize() >= numColumns );
  3266. assert( w.GetSize() >= numRows );
  3267. y.SetData( numRows, VECX_ALLOCA( numRows ) );
  3268. z.SetData( numRows, VECX_ALLOCA( numRows ) );
  3269. Multiply( y, v );
  3270. TransposeMultiply( z, w );
  3271. beta = 1.0f + ( w * y );
  3272. if ( beta == 0.0f ) {
  3273. return false;
  3274. }
  3275. alpha /= beta;
  3276. for ( i = 0; i < numRows; i++ ) {
  3277. s = y[i] * alpha;
  3278. for ( j = 0; j < numColumns; j++ ) {
  3279. (*this)[i][j] -= s * z[j];
  3280. }
  3281. }
  3282. return true;
  3283. }
  3284. /*
  3285. ============
  3286. idMatX::Inverse_UpdateRowColumn
  3287. Updates the in-place inverse to obtain the inverse for the matrix:
  3288. [ 0 a 0 ]
  3289. A + [ d b e ]
  3290. [ 0 c 0 ]
  3291. where: a = v[0,r-1], b = v[r], c = v[r+1,numRows-1], d = w[0,r-1], w[r] = 0.0f, e = w[r+1,numColumns-1]
  3292. ============
  3293. */
  3294. bool idMatX::Inverse_UpdateRowColumn( const idVecX &v, const idVecX &w, int r ) {
  3295. idVecX s;
  3296. assert( numRows == numColumns );
  3297. assert( v.GetSize() >= numColumns );
  3298. assert( w.GetSize() >= numRows );
  3299. assert( r >= 0 && r < numRows && r < numColumns );
  3300. assert( w[r] == 0.0f );
  3301. s.SetData( Max( numRows, numColumns ), VECX_ALLOCA( Max( numRows, numColumns ) ) );
  3302. s.Zero();
  3303. s[r] = 1.0f;
  3304. if ( !Inverse_UpdateRankOne( v, s, 1.0f ) ) {
  3305. return false;
  3306. }
  3307. if ( !Inverse_UpdateRankOne( s, w, 1.0f ) ) {
  3308. return false;
  3309. }
  3310. return true;
  3311. }
  3312. /*
  3313. ============
  3314. idMatX::Inverse_UpdateIncrement
  3315. Updates the in-place inverse to obtain the inverse for the matrix:
  3316. [ A a ]
  3317. [ c b ]
  3318. where: a = v[0,numRows-1], b = v[numRows], c = w[0,numColumns-1], w[numColumns] = 0
  3319. ============
  3320. */
  3321. bool idMatX::Inverse_UpdateIncrement( const idVecX &v, const idVecX &w ) {
  3322. idVecX v2;
  3323. assert( numRows == numColumns );
  3324. assert( v.GetSize() >= numRows+1 );
  3325. assert( w.GetSize() >= numColumns+1 );
  3326. ChangeSize( numRows+1, numColumns+1, true );
  3327. (*this)[numRows-1][numRows-1] = 1.0f;
  3328. v2.SetData( numRows, VECX_ALLOCA( numRows ) );
  3329. v2 = v;
  3330. v2[numRows-1] -= 1.0f;
  3331. return Inverse_UpdateRowColumn( v2, w, numRows-1 );
  3332. }
  3333. /*
  3334. ============
  3335. idMatX::Inverse_UpdateDecrement
  3336. Updates the in-place inverse to obtain the inverse of the matrix with row r and column r removed.
  3337. v and w should store the column and row of the original matrix respectively.
  3338. ============
  3339. */
  3340. bool idMatX::Inverse_UpdateDecrement( const idVecX &v, const idVecX &w, int r ) {
  3341. idVecX v1, w1;
  3342. assert( numRows == numColumns );
  3343. assert( v.GetSize() >= numRows );
  3344. assert( w.GetSize() >= numColumns );
  3345. assert( r >= 0 && r < numRows && r < numColumns );
  3346. v1.SetData( numRows, VECX_ALLOCA( numRows ) );
  3347. w1.SetData( numRows, VECX_ALLOCA( numRows ) );
  3348. // update the row and column to identity
  3349. v1 = -v;
  3350. w1 = -w;
  3351. v1[r] += 1.0f;
  3352. w1[r] = 0.0f;
  3353. if ( !Inverse_UpdateRowColumn( v1, w1, r ) ) {
  3354. return false;
  3355. }
  3356. // physically remove the row and column
  3357. Update_Decrement( r );
  3358. return true;
  3359. }
  3360. /*
  3361. ============
  3362. idMatX::Inverse_Solve
  3363. Solve Ax = b with A inverted
  3364. ============
  3365. */
  3366. void idMatX::Inverse_Solve( idVecX &x, const idVecX &b ) const {
  3367. Multiply( x, b );
  3368. }
  3369. /*
  3370. ============
  3371. idMatX::LU_Factor
  3372. in-place factorization: LU
  3373. L is a triangular matrix stored in the lower triangle.
  3374. L has ones on the diagonal that are not stored.
  3375. U is a triangular matrix stored in the upper triangle.
  3376. If index != NULL partial pivoting is used for numerical stability.
  3377. If index != NULL it must point to an array of numRow integers and is used to keep track of the row permutation.
  3378. If det != NULL the determinant of the matrix is calculated and stored.
  3379. ============
  3380. */
  3381. bool idMatX::LU_Factor( int *index, float *det ) {
  3382. int i, j, k, newi, min;
  3383. double s, t, d, w;
  3384. // if partial pivoting should be used
  3385. if ( index ) {
  3386. for ( i = 0; i < numRows; i++ ) {
  3387. index[i] = i;
  3388. }
  3389. }
  3390. w = 1.0f;
  3391. min = Min( numRows, numColumns );
  3392. for ( i = 0; i < min; i++ ) {
  3393. newi = i;
  3394. s = idMath::Fabs( (*this)[i][i] );
  3395. if ( index ) {
  3396. // find the largest absolute pivot
  3397. for ( j = i + 1; j < numRows; j++ ) {
  3398. t = idMath::Fabs( (*this)[j][i] );
  3399. if ( t > s ) {
  3400. newi = j;
  3401. s = t;
  3402. }
  3403. }
  3404. }
  3405. if ( s == 0.0f ) {
  3406. return false;
  3407. }
  3408. if ( newi != i ) {
  3409. w = -w;
  3410. // swap index elements
  3411. k = index[i];
  3412. index[i] = index[newi];
  3413. index[newi] = k;
  3414. // swap rows
  3415. for ( j = 0; j < numColumns; j++ ) {
  3416. t = (*this)[newi][j];
  3417. (*this)[newi][j] = (*this)[i][j];
  3418. (*this)[i][j] = t;
  3419. }
  3420. }
  3421. if ( i < numRows ) {
  3422. d = 1.0f / (*this)[i][i];
  3423. for ( j = i + 1; j < numRows; j++ ) {
  3424. (*this)[j][i] *= d;
  3425. }
  3426. }
  3427. if ( i < min-1 ) {
  3428. for ( j = i + 1; j < numRows; j++ ) {
  3429. d = (*this)[j][i];
  3430. for ( k = i + 1; k < numColumns; k++ ) {
  3431. (*this)[j][k] -= d * (*this)[i][k];
  3432. }
  3433. }
  3434. }
  3435. }
  3436. if ( det ) {
  3437. for ( i = 0; i < numRows; i++ ) {
  3438. w *= (*this)[i][i];
  3439. }
  3440. *det = w;
  3441. }
  3442. return true;
  3443. }
  3444. /*
  3445. ============
  3446. idMatX::LU_UpdateRankOne
  3447. Updates the in-place LU factorization to obtain the factors for the matrix: LU + alpha * v * w'
  3448. ============
  3449. */
  3450. bool idMatX::LU_UpdateRankOne( const idVecX &v, const idVecX &w, float alpha, int *index ) {
  3451. int i, j, max;
  3452. float *y, *z;
  3453. double diag, beta, p0, p1, d;
  3454. assert( v.GetSize() >= numColumns );
  3455. assert( w.GetSize() >= numRows );
  3456. y = (float *) _alloca16( v.GetSize() * sizeof( float ) );
  3457. z = (float *) _alloca16( w.GetSize() * sizeof( float ) );
  3458. if ( index != NULL ) {
  3459. for ( i = 0; i < numRows; i++ ) {
  3460. y[i] = alpha * v[index[i]];
  3461. }
  3462. } else {
  3463. for ( i = 0; i < numRows; i++ ) {
  3464. y[i] = alpha * v[i];
  3465. }
  3466. }
  3467. memcpy( z, w.ToFloatPtr(), w.GetSize() * sizeof( float ) );
  3468. max = Min( numRows, numColumns );
  3469. for ( i = 0; i < max; i++ ) {
  3470. diag = (*this)[i][i];
  3471. p0 = y[i];
  3472. p1 = z[i];
  3473. diag += p0 * p1;
  3474. if ( diag == 0.0f ) {
  3475. return false;
  3476. }
  3477. beta = p1 / diag;
  3478. (*this)[i][i] = diag;
  3479. for ( j = i+1; j < numColumns; j++ ) {
  3480. d = (*this)[i][j];
  3481. d += p0 * z[j];
  3482. z[j] -= beta * d;
  3483. (*this)[i][j] = d;
  3484. }
  3485. for ( j = i+1; j < numRows; j++ ) {
  3486. d = (*this)[j][i];
  3487. y[j] -= p0 * d;
  3488. d += beta * y[j];
  3489. (*this)[j][i] = d;
  3490. }
  3491. }
  3492. return true;
  3493. }
  3494. /*
  3495. ============
  3496. idMatX::LU_UpdateRowColumn
  3497. Updates the in-place LU factorization to obtain the factors for the matrix:
  3498. [ 0 a 0 ]
  3499. LU + [ d b e ]
  3500. [ 0 c 0 ]
  3501. where: a = v[0,r-1], b = v[r], c = v[r+1,numRows-1], d = w[0,r-1], w[r] = 0.0f, e = w[r+1,numColumns-1]
  3502. ============
  3503. */
  3504. bool idMatX::LU_UpdateRowColumn( const idVecX &v, const idVecX &w, int r, int *index ) {
  3505. #if 0
  3506. idVecX s;
  3507. assert( v.GetSize() >= numColumns );
  3508. assert( w.GetSize() >= numRows );
  3509. assert( r >= 0 && r < numRows && r < numColumns );
  3510. assert( w[r] == 0.0f );
  3511. s.SetData( Max( numRows, numColumns ), VECX_ALLOCA( Max( numRows, numColumns ) ) );
  3512. s.Zero();
  3513. s[r] = 1.0f;
  3514. if ( !LU_UpdateRankOne( v, s, 1.0f, index ) ) {
  3515. return false;
  3516. }
  3517. if ( !LU_UpdateRankOne( s, w, 1.0f, index ) ) {
  3518. return false;
  3519. }
  3520. return true;
  3521. #else
  3522. int i, j, min, max, rp;
  3523. float *y0, *y1, *z0, *z1;
  3524. double diag, beta0, beta1, p0, p1, q0, q1, d;
  3525. assert( v.GetSize() >= numColumns );
  3526. assert( w.GetSize() >= numRows );
  3527. assert( r >= 0 && r < numColumns && r < numRows );
  3528. assert( w[r] == 0.0f );
  3529. y0 = (float *) _alloca16( v.GetSize() * sizeof( float ) );
  3530. z0 = (float *) _alloca16( w.GetSize() * sizeof( float ) );
  3531. y1 = (float *) _alloca16( v.GetSize() * sizeof( float ) );
  3532. z1 = (float *) _alloca16( w.GetSize() * sizeof( float ) );
  3533. if ( index != NULL ) {
  3534. for ( i = 0; i < numRows; i++ ) {
  3535. y0[i] = v[index[i]];
  3536. }
  3537. rp = r;
  3538. for ( i = 0; i < numRows; i++ ) {
  3539. if ( index[i] == r ) {
  3540. rp = i;
  3541. break;
  3542. }
  3543. }
  3544. } else {
  3545. memcpy( y0, v.ToFloatPtr(), v.GetSize() * sizeof( float ) );
  3546. rp = r;
  3547. }
  3548. memset( y1, 0, v.GetSize() * sizeof( float ) );
  3549. y1[rp] = 1.0f;
  3550. memset( z0, 0, w.GetSize() * sizeof( float ) );
  3551. z0[r] = 1.0f;
  3552. memcpy( z1, w.ToFloatPtr(), w.GetSize() * sizeof( float ) );
  3553. // update the beginning of the to be updated row and column
  3554. min = Min( r, rp );
  3555. for ( i = 0; i < min; i++ ) {
  3556. p0 = y0[i];
  3557. beta1 = z1[i] / (*this)[i][i];
  3558. (*this)[i][r] += p0;
  3559. for ( j = i+1; j < numColumns; j++ ) {
  3560. z1[j] -= beta1 * (*this)[i][j];
  3561. }
  3562. for ( j = i+1; j < numRows; j++ ) {
  3563. y0[j] -= p0 * (*this)[j][i];
  3564. }
  3565. (*this)[rp][i] += beta1;
  3566. }
  3567. // update the lower right corner starting at r,r
  3568. max = Min( numRows, numColumns );
  3569. for ( i = min; i < max; i++ ) {
  3570. diag = (*this)[i][i];
  3571. p0 = y0[i];
  3572. p1 = z0[i];
  3573. diag += p0 * p1;
  3574. if ( diag == 0.0f ) {
  3575. return false;
  3576. }
  3577. beta0 = p1 / diag;
  3578. q0 = y1[i];
  3579. q1 = z1[i];
  3580. diag += q0 * q1;
  3581. if ( diag == 0.0f ) {
  3582. return false;
  3583. }
  3584. beta1 = q1 / diag;
  3585. (*this)[i][i] = diag;
  3586. for ( j = i+1; j < numColumns; j++ ) {
  3587. d = (*this)[i][j];
  3588. d += p0 * z0[j];
  3589. z0[j] -= beta0 * d;
  3590. d += q0 * z1[j];
  3591. z1[j] -= beta1 * d;
  3592. (*this)[i][j] = d;
  3593. }
  3594. for ( j = i+1; j < numRows; j++ ) {
  3595. d = (*this)[j][i];
  3596. y0[j] -= p0 * d;
  3597. d += beta0 * y0[j];
  3598. y1[j] -= q0 * d;
  3599. d += beta1 * y1[j];
  3600. (*this)[j][i] = d;
  3601. }
  3602. }
  3603. return true;
  3604. #endif
  3605. }
  3606. /*
  3607. ============
  3608. idMatX::LU_UpdateIncrement
  3609. Updates the in-place LU factorization to obtain the factors for the matrix:
  3610. [ A a ]
  3611. [ c b ]
  3612. where: a = v[0,numRows-1], b = v[numRows], c = w[0,numColumns-1], w[numColumns] = 0
  3613. ============
  3614. */
  3615. bool idMatX::LU_UpdateIncrement( const idVecX &v, const idVecX &w, int *index ) {
  3616. int i, j;
  3617. float sum;
  3618. assert( numRows == numColumns );
  3619. assert( v.GetSize() >= numRows+1 );
  3620. assert( w.GetSize() >= numColumns+1 );
  3621. ChangeSize( numRows+1, numColumns+1, true );
  3622. // add row to L
  3623. for ( i = 0; i < numRows - 1; i++ ) {
  3624. sum = w[i];
  3625. for ( j = 0; j < i; j++ ) {
  3626. sum -= (*this)[numRows - 1][j] * (*this)[j][i];
  3627. }
  3628. (*this)[numRows - 1 ][i] = sum / (*this)[i][i];
  3629. }
  3630. // add row to the permutation index
  3631. if ( index != NULL ) {
  3632. index[numRows - 1] = numRows - 1;
  3633. }
  3634. // add column to U
  3635. for ( i = 0; i < numRows; i++ ) {
  3636. if ( index != NULL ) {
  3637. sum = v[index[i]];
  3638. } else {
  3639. sum = v[i];
  3640. }
  3641. for ( j = 0; j < i; j++ ) {
  3642. sum -= (*this)[i][j] * (*this)[j][numRows - 1];
  3643. }
  3644. (*this)[i][numRows - 1] = sum;
  3645. }
  3646. return true;
  3647. }
  3648. /*
  3649. ============
  3650. idMatX::LU_UpdateDecrement
  3651. Updates the in-place LU factorization to obtain the factors for the matrix with row r and column r removed.
  3652. v and w should store the column and row of the original matrix respectively.
  3653. If index != NULL then u should store row index[r] of the original matrix. If index == NULL then u = w.
  3654. ============
  3655. */
  3656. bool idMatX::LU_UpdateDecrement( const idVecX &v, const idVecX &w, const idVecX &u, int r, int *index ) {
  3657. int i, p;
  3658. idVecX v1, w1;
  3659. assert( numRows == numColumns );
  3660. assert( v.GetSize() >= numColumns );
  3661. assert( w.GetSize() >= numRows );
  3662. assert( r >= 0 && r < numRows && r < numColumns );
  3663. v1.SetData( numRows, VECX_ALLOCA( numRows ) );
  3664. w1.SetData( numRows, VECX_ALLOCA( numRows ) );
  3665. if ( index != NULL ) {
  3666. // find the pivot row
  3667. for ( p = i = 0; i < numRows; i++ ) {
  3668. if ( index[i] == r ) {
  3669. p = i;
  3670. break;
  3671. }
  3672. }
  3673. // update the row and column to identity
  3674. v1 = -v;
  3675. w1 = -u;
  3676. if ( p != r ) {
  3677. idSwap( v1[index[r]], v1[index[p]] );
  3678. idSwap( index[r], index[p] );
  3679. }
  3680. v1[r] += 1.0f;
  3681. w1[r] = 0.0f;
  3682. if ( !LU_UpdateRowColumn( v1, w1, r, index ) ) {
  3683. return false;
  3684. }
  3685. if ( p != r ) {
  3686. if ( idMath::Fabs( u[p] ) < 1e-4f ) {
  3687. // NOTE: an additional row interchange is required for numerical stability
  3688. }
  3689. // move row index[r] of the original matrix to row index[p] of the original matrix
  3690. v1.Zero();
  3691. v1[index[p]] = 1.0f;
  3692. w1 = u - w;
  3693. if ( !LU_UpdateRankOne( v1, w1, 1.0f, index ) ) {
  3694. return false;
  3695. }
  3696. }
  3697. // remove the row from the permutation index
  3698. for ( i = r; i < numRows - 1; i++ ) {
  3699. index[i] = index[i+1];
  3700. }
  3701. for ( i = 0; i < numRows - 1; i++ ) {
  3702. if ( index[i] > r ) {
  3703. index[i]--;
  3704. }
  3705. }
  3706. } else {
  3707. v1 = -v;
  3708. w1 = -w;
  3709. v1[r] += 1.0f;
  3710. w1[r] = 0.0f;
  3711. if ( !LU_UpdateRowColumn( v1, w1, r, index ) ) {
  3712. return false;
  3713. }
  3714. }
  3715. // physically remove the row and column
  3716. Update_Decrement( r );
  3717. return true;
  3718. }
  3719. /*
  3720. ============
  3721. idMatX::LU_Solve
  3722. Solve Ax = b with A factored in-place as: LU
  3723. ============
  3724. */
  3725. void idMatX::LU_Solve( idVecX &x, const idVecX &b, const int *index ) const {
  3726. int i, j;
  3727. double sum;
  3728. assert( x.GetSize() == numColumns && b.GetSize() == numRows );
  3729. // solve L
  3730. for ( i = 0; i < numRows; i++ ) {
  3731. if ( index != NULL ) {
  3732. sum = b[index[i]];
  3733. } else {
  3734. sum = b[i];
  3735. }
  3736. for ( j = 0; j < i; j++ ) {
  3737. sum -= (*this)[i][j] * x[j];
  3738. }
  3739. x[i] = sum;
  3740. }
  3741. // solve U
  3742. for ( i = numRows - 1; i >= 0; i-- ) {
  3743. sum = x[i];
  3744. for ( j = i + 1; j < numRows; j++ ) {
  3745. sum -= (*this)[i][j] * x[j];
  3746. }
  3747. x[i] = sum / (*this)[i][i];
  3748. }
  3749. }
  3750. /*
  3751. ============
  3752. idMatX::LU_Inverse
  3753. Calculates the inverse of the matrix which is factored in-place as LU
  3754. ============
  3755. */
  3756. void idMatX::LU_Inverse( idMatX &inv, const int *index ) const {
  3757. int i, j;
  3758. idVecX x, b;
  3759. assert( numRows == numColumns );
  3760. x.SetData( numRows, VECX_ALLOCA( numRows ) );
  3761. b.SetData( numRows, VECX_ALLOCA( numRows ) );
  3762. b.Zero();
  3763. inv.SetSize( numRows, numColumns );
  3764. for ( i = 0; i < numRows; i++ ) {
  3765. b[i] = 1.0f;
  3766. LU_Solve( x, b, index );
  3767. for ( j = 0; j < numRows; j++ ) {
  3768. inv[j][i] = x[j];
  3769. }
  3770. b[i] = 0.0f;
  3771. }
  3772. }
  3773. /*
  3774. ============
  3775. idMatX::LU_UnpackFactors
  3776. Unpacks the in-place LU factorization.
  3777. ============
  3778. */
  3779. void idMatX::LU_UnpackFactors( idMatX &L, idMatX &U ) const {
  3780. int i, j;
  3781. L.Zero( numRows, numColumns );
  3782. U.Zero( numRows, numColumns );
  3783. for ( i = 0; i < numRows; i++ ) {
  3784. for ( j = 0; j < i; j++ ) {
  3785. L[i][j] = (*this)[i][j];
  3786. }
  3787. L[i][i] = 1.0f;
  3788. for ( j = i; j < numColumns; j++ ) {
  3789. U[i][j] = (*this)[i][j];
  3790. }
  3791. }
  3792. }
  3793. /*
  3794. ============
  3795. idMatX::LU_MultiplyFactors
  3796. Multiplies the factors of the in-place LU factorization to form the original matrix.
  3797. ============
  3798. */
  3799. void idMatX::LU_MultiplyFactors( idMatX &m, const int *index ) const {
  3800. int r, rp, i, j;
  3801. double sum;
  3802. m.SetSize( numRows, numColumns );
  3803. for ( r = 0; r < numRows; r++ ) {
  3804. if ( index != NULL ) {
  3805. rp = index[r];
  3806. } else {
  3807. rp = r;
  3808. }
  3809. // calculate row of matrix
  3810. for ( i = 0; i < numColumns; i++ ) {
  3811. if ( i >= r ) {
  3812. sum = (*this)[r][i];
  3813. } else {
  3814. sum = 0.0f;
  3815. }
  3816. for ( j = 0; j <= i && j < r; j++ ) {
  3817. sum += (*this)[r][j] * (*this)[j][i];
  3818. }
  3819. m[rp][i] = sum;
  3820. }
  3821. }
  3822. }
  3823. /*
  3824. ============
  3825. idMatX::QR_Factor
  3826. in-place factorization: QR
  3827. Q is an orthogonal matrix represented as a product of Householder matrices stored in the lower triangle and c.
  3828. R is a triangular matrix stored in the upper triangle except for the diagonal elements which are stored in d.
  3829. The initial matrix has to be square.
  3830. ============
  3831. */
  3832. bool idMatX::QR_Factor( idVecX &c, idVecX &d ) {
  3833. int i, j, k;
  3834. double scale, s, t, sum;
  3835. bool singular = false;
  3836. assert( numRows == numColumns );
  3837. assert( c.GetSize() >= numRows && d.GetSize() >= numRows );
  3838. for ( k = 0; k < numRows-1; k++ ) {
  3839. scale = 0.0f;
  3840. for ( i = k; i < numRows; i++ ) {
  3841. s = idMath::Fabs( (*this)[i][k] );
  3842. if ( s > scale ) {
  3843. scale = s;
  3844. }
  3845. }
  3846. if ( scale == 0.0f ) {
  3847. singular = true;
  3848. c[k] = d[k] = 0.0f;
  3849. } else {
  3850. s = 1.0f / scale;
  3851. for ( i = k; i < numRows; i++ ) {
  3852. (*this)[i][k] *= s;
  3853. }
  3854. sum = 0.0f;
  3855. for ( i = k; i < numRows; i++ ) {
  3856. s = (*this)[i][k];
  3857. sum += s * s;
  3858. }
  3859. s = idMath::Sqrt( sum );
  3860. if ( (*this)[k][k] < 0.0f ) {
  3861. s = -s;
  3862. }
  3863. (*this)[k][k] += s;
  3864. c[k] = s * (*this)[k][k];
  3865. d[k] = -scale * s;
  3866. for ( j = k+1; j < numRows; j++ ) {
  3867. sum = 0.0f;
  3868. for ( i = k; i < numRows; i++ ) {
  3869. sum += (*this)[i][k] * (*this)[i][j];
  3870. }
  3871. t = sum / c[k];
  3872. for ( i = k; i < numRows; i++ ) {
  3873. (*this)[i][j] -= t * (*this)[i][k];
  3874. }
  3875. }
  3876. }
  3877. }
  3878. d[numRows-1] = (*this)[ (numRows-1) ][ (numRows-1) ];
  3879. if ( d[numRows-1] == 0.0f ) {
  3880. singular = true;
  3881. }
  3882. return !singular;
  3883. }
  3884. /*
  3885. ============
  3886. idMatX::QR_Rotate
  3887. Performs a Jacobi rotation on the rows i and i+1 of the unpacked QR factors.
  3888. ============
  3889. */
  3890. void idMatX::QR_Rotate( idMatX &R, int i, float a, float b ) {
  3891. int j;
  3892. float f, c, s, w, y;
  3893. if ( a == 0.0f ) {
  3894. c = 0.0f;
  3895. s = ( b >= 0.0f ) ? 1.0f : -1.0f;
  3896. } else if ( idMath::Fabs( a ) > idMath::Fabs( b ) ) {
  3897. f = b / a;
  3898. c = idMath::Fabs( 1.0f / idMath::Sqrt( 1.0f + f * f ) );
  3899. if ( a < 0.0f ) {
  3900. c = -c;
  3901. }
  3902. s = f * c;
  3903. } else {
  3904. f = a / b;
  3905. s = idMath::Fabs( 1.0f / idMath::Sqrt( 1.0f + f * f ) );
  3906. if ( b < 0.0f ) {
  3907. s = -s;
  3908. }
  3909. c = f * s;
  3910. }
  3911. for ( j = i; j < numRows; j++ ) {
  3912. y = R[i][j];
  3913. w = R[i+1][j];
  3914. R[i][j] = c * y - s * w;
  3915. R[i+1][j] = s * y + c * w;
  3916. }
  3917. for ( j = 0; j < numRows; j++ ) {
  3918. y = (*this)[j][i];
  3919. w = (*this)[j][i+1];
  3920. (*this)[j][i] = c * y - s * w;
  3921. (*this)[j][i+1] = s * y + c * w;
  3922. }
  3923. }
  3924. /*
  3925. ============
  3926. idMatX::QR_UpdateRankOne
  3927. Updates the unpacked QR factorization to obtain the factors for the matrix: QR + alpha * v * w'
  3928. ============
  3929. */
  3930. bool idMatX::QR_UpdateRankOne( idMatX &R, const idVecX &v, const idVecX &w, float alpha ) {
  3931. int i, k;
  3932. float f;
  3933. idVecX u;
  3934. assert( v.GetSize() >= numColumns );
  3935. assert( w.GetSize() >= numRows );
  3936. u.SetData( v.GetSize(), VECX_ALLOCA( v.GetSize() ) );
  3937. TransposeMultiply( u, v );
  3938. u *= alpha;
  3939. for ( k = v.GetSize()-1; k > 0; k-- ) {
  3940. if ( u[k] != 0.0f ) {
  3941. break;
  3942. }
  3943. }
  3944. for ( i = k-1; i >= 0; i-- ) {
  3945. QR_Rotate( R, i, u[i], -u[i+1] );
  3946. if ( u[i] == 0.0f ) {
  3947. u[i] = idMath::Fabs( u[i+1] );
  3948. } else if ( idMath::Fabs( u[i] ) > idMath::Fabs( u[i+1] ) ) {
  3949. f = u[i+1] / u[i];
  3950. u[i] = idMath::Fabs( u[i] ) * idMath::Sqrt( 1.0f + f * f );
  3951. } else {
  3952. f = u[i] / u[i+1];
  3953. u[i] = idMath::Fabs( u[i+1] ) * idMath::Sqrt( 1.0f + f * f );
  3954. }
  3955. }
  3956. for ( i = 0; i < v.GetSize(); i++ ) {
  3957. R[0][i] += u[0] * w[i];
  3958. }
  3959. for ( i = 0; i < k; i++ ) {
  3960. QR_Rotate( R, i, -R[i][i], R[i+1][i] );
  3961. }
  3962. return true;
  3963. }
  3964. /*
  3965. ============
  3966. idMatX::QR_UpdateRowColumn
  3967. Updates the unpacked QR factorization to obtain the factors for the matrix:
  3968. [ 0 a 0 ]
  3969. QR + [ d b e ]
  3970. [ 0 c 0 ]
  3971. where: a = v[0,r-1], b = v[r], c = v[r+1,numRows-1], d = w[0,r-1], w[r] = 0.0f, e = w[r+1,numColumns-1]
  3972. ============
  3973. */
  3974. bool idMatX::QR_UpdateRowColumn( idMatX &R, const idVecX &v, const idVecX &w, int r ) {
  3975. idVecX s;
  3976. assert( v.GetSize() >= numColumns );
  3977. assert( w.GetSize() >= numRows );
  3978. assert( r >= 0 && r < numRows && r < numColumns );
  3979. assert( w[r] == 0.0f );
  3980. s.SetData( Max( numRows, numColumns ), VECX_ALLOCA( Max( numRows, numColumns ) ) );
  3981. s.Zero();
  3982. s[r] = 1.0f;
  3983. if ( !QR_UpdateRankOne( R, v, s, 1.0f ) ) {
  3984. return false;
  3985. }
  3986. if ( !QR_UpdateRankOne( R, s, w, 1.0f ) ) {
  3987. return false;
  3988. }
  3989. return true;
  3990. }
  3991. /*
  3992. ============
  3993. idMatX::QR_UpdateIncrement
  3994. Updates the unpacked QR factorization to obtain the factors for the matrix:
  3995. [ A a ]
  3996. [ c b ]
  3997. where: a = v[0,numRows-1], b = v[numRows], c = w[0,numColumns-1], w[numColumns] = 0
  3998. ============
  3999. */
  4000. bool idMatX::QR_UpdateIncrement( idMatX &R, const idVecX &v, const idVecX &w ) {
  4001. idVecX v2;
  4002. assert( numRows == numColumns );
  4003. assert( v.GetSize() >= numRows+1 );
  4004. assert( w.GetSize() >= numColumns+1 );
  4005. ChangeSize( numRows+1, numColumns+1, true );
  4006. (*this)[numRows-1][numRows-1] = 1.0f;
  4007. R.ChangeSize( R.numRows+1, R.numColumns+1, true );
  4008. R[R.numRows-1][R.numRows-1] = 1.0f;
  4009. v2.SetData( numRows, VECX_ALLOCA( numRows ) );
  4010. v2 = v;
  4011. v2[numRows-1] -= 1.0f;
  4012. return QR_UpdateRowColumn( R, v2, w, numRows-1 );
  4013. }
  4014. /*
  4015. ============
  4016. idMatX::QR_UpdateDecrement
  4017. Updates the unpacked QR factorization to obtain the factors for the matrix with row r and column r removed.
  4018. v and w should store the column and row of the original matrix respectively.
  4019. ============
  4020. */
  4021. bool idMatX::QR_UpdateDecrement( idMatX &R, const idVecX &v, const idVecX &w, int r ) {
  4022. idVecX v1, w1;
  4023. assert( numRows == numColumns );
  4024. assert( v.GetSize() >= numRows );
  4025. assert( w.GetSize() >= numColumns );
  4026. assert( r >= 0 && r < numRows && r < numColumns );
  4027. v1.SetData( numRows, VECX_ALLOCA( numRows ) );
  4028. w1.SetData( numRows, VECX_ALLOCA( numRows ) );
  4029. // update the row and column to identity
  4030. v1 = -v;
  4031. w1 = -w;
  4032. v1[r] += 1.0f;
  4033. w1[r] = 0.0f;
  4034. if ( !QR_UpdateRowColumn( R, v1, w1, r ) ) {
  4035. return false;
  4036. }
  4037. // physically remove the row and column
  4038. Update_Decrement( r );
  4039. R.Update_Decrement( r );
  4040. return true;
  4041. }
  4042. /*
  4043. ============
  4044. idMatX::QR_Solve
  4045. Solve Ax = b with A factored in-place as: QR
  4046. ============
  4047. */
  4048. void idMatX::QR_Solve( idVecX &x, const idVecX &b, const idVecX &c, const idVecX &d ) const {
  4049. int i, j;
  4050. double sum, t;
  4051. assert( numRows == numColumns );
  4052. assert( x.GetSize() >= numRows && b.GetSize() >= numRows );
  4053. assert( c.GetSize() >= numRows && d.GetSize() >= numRows );
  4054. for ( i = 0; i < numRows; i++ ) {
  4055. x[i] = b[i];
  4056. }
  4057. // multiply b with transpose of Q
  4058. for ( i = 0; i < numRows-1; i++ ) {
  4059. sum = 0.0f;
  4060. for ( j = i; j < numRows; j++ ) {
  4061. sum += (*this)[j][i] * x[j];
  4062. }
  4063. t = sum / c[i];
  4064. for ( j = i; j < numRows; j++ ) {
  4065. x[j] -= t * (*this)[j][i];
  4066. }
  4067. }
  4068. // backsubstitution with R
  4069. for ( i = numRows-1; i >= 0; i-- ) {
  4070. sum = x[i];
  4071. for ( j = i + 1; j < numRows; j++ ) {
  4072. sum -= (*this)[i][j] * x[j];
  4073. }
  4074. x[i] = sum / d[i];
  4075. }
  4076. }
  4077. /*
  4078. ============
  4079. idMatX::QR_Solve
  4080. Solve Ax = b with A factored as: QR
  4081. ============
  4082. */
  4083. void idMatX::QR_Solve( idVecX &x, const idVecX &b, const idMatX &R ) const {
  4084. int i, j;
  4085. double sum;
  4086. assert( numRows == numColumns );
  4087. // multiply b with transpose of Q
  4088. TransposeMultiply( x, b );
  4089. // backsubstitution with R
  4090. for ( i = numRows-1; i >= 0; i-- ) {
  4091. sum = x[i];
  4092. for ( j = i + 1; j < numRows; j++ ) {
  4093. sum -= R[i][j] * x[j];
  4094. }
  4095. x[i] = sum / R[i][i];
  4096. }
  4097. }
  4098. /*
  4099. ============
  4100. idMatX::QR_Inverse
  4101. Calculates the inverse of the matrix which is factored in-place as: QR
  4102. ============
  4103. */
  4104. void idMatX::QR_Inverse( idMatX &inv, const idVecX &c, const idVecX &d ) const {
  4105. int i, j;
  4106. idVecX x, b;
  4107. assert( numRows == numColumns );
  4108. x.SetData( numRows, VECX_ALLOCA( numRows ) );
  4109. b.SetData( numRows, VECX_ALLOCA( numRows ) );
  4110. b.Zero();
  4111. inv.SetSize( numRows, numColumns );
  4112. for ( i = 0; i < numRows; i++ ) {
  4113. b[i] = 1.0f;
  4114. QR_Solve( x, b, c, d );
  4115. for ( j = 0; j < numRows; j++ ) {
  4116. inv[j][i] = x[j];
  4117. }
  4118. b[i] = 0.0f;
  4119. }
  4120. }
  4121. /*
  4122. ============
  4123. idMatX::QR_UnpackFactors
  4124. Unpacks the in-place QR factorization.
  4125. ============
  4126. */
  4127. void idMatX::QR_UnpackFactors( idMatX &Q, idMatX &R, const idVecX &c, const idVecX &d ) const {
  4128. int i, j, k;
  4129. double sum;
  4130. Q.Identity( numRows, numColumns );
  4131. for ( i = 0; i < numColumns-1; i++ ) {
  4132. if ( c[i] == 0.0f ) {
  4133. continue;
  4134. }
  4135. for ( j = 0; j < numRows; j++ ) {
  4136. sum = 0.0f;
  4137. for ( k = i; k < numColumns; k++ ) {
  4138. sum += (*this)[k][i] * Q[j][k];
  4139. }
  4140. sum /= c[i];
  4141. for ( k = i; k < numColumns; k++ ) {
  4142. Q[j][k] -= sum * (*this)[k][i];
  4143. }
  4144. }
  4145. }
  4146. R.Zero( numRows, numColumns );
  4147. for ( i = 0; i < numRows; i++ ) {
  4148. R[i][i] = d[i];
  4149. for ( j = i+1; j < numColumns; j++ ) {
  4150. R[i][j] = (*this)[i][j];
  4151. }
  4152. }
  4153. }
  4154. /*
  4155. ============
  4156. idMatX::QR_MultiplyFactors
  4157. Multiplies the factors of the in-place QR factorization to form the original matrix.
  4158. ============
  4159. */
  4160. void idMatX::QR_MultiplyFactors( idMatX &m, const idVecX &c, const idVecX &d ) const {
  4161. int i, j, k;
  4162. double sum;
  4163. idMatX Q;
  4164. Q.Identity( numRows, numColumns );
  4165. for ( i = 0; i < numColumns-1; i++ ) {
  4166. if ( c[i] == 0.0f ) {
  4167. continue;
  4168. }
  4169. for ( j = 0; j < numRows; j++ ) {
  4170. sum = 0.0f;
  4171. for ( k = i; k < numColumns; k++ ) {
  4172. sum += (*this)[k][i] * Q[j][k];
  4173. }
  4174. sum /= c[i];
  4175. for ( k = i; k < numColumns; k++ ) {
  4176. Q[j][k] -= sum * (*this)[k][i];
  4177. }
  4178. }
  4179. }
  4180. for ( i = 0; i < numRows; i++ ) {
  4181. for ( j = 0; j < numColumns; j++ ) {
  4182. sum = Q[i][j] * d[i];
  4183. for ( k = 0; k < i; k++ ) {
  4184. sum += Q[i][k] * (*this)[j][k];
  4185. }
  4186. m[i][j] = sum;
  4187. }
  4188. }
  4189. }
  4190. /*
  4191. ============
  4192. idMatX::Pythag
  4193. Computes (a^2 + b^2)^1/2 without underflow or overflow.
  4194. ============
  4195. */
  4196. float idMatX::Pythag( float a, float b ) const {
  4197. double at, bt, ct;
  4198. at = idMath::Fabs( a );
  4199. bt = idMath::Fabs( b );
  4200. if ( at > bt ) {
  4201. ct = bt / at;
  4202. return at * idMath::Sqrt( 1.0f + ct * ct );
  4203. } else {
  4204. if ( bt ) {
  4205. ct = at / bt;
  4206. return bt * idMath::Sqrt( 1.0f + ct * ct );
  4207. } else {
  4208. return 0.0f;
  4209. }
  4210. }
  4211. }
  4212. /*
  4213. ============
  4214. idMatX::SVD_BiDiag
  4215. ============
  4216. */
  4217. void idMatX::SVD_BiDiag( idVecX &w, idVecX &rv1, float &anorm ) {
  4218. int i, j, k, l;
  4219. double f, h, r, g, s, scale;
  4220. anorm = 0.0f;
  4221. g = s = scale = 0.0f;
  4222. for ( i = 0; i < numColumns; i++ ) {
  4223. l = i + 1;
  4224. rv1[i] = scale * g;
  4225. g = s = scale = 0.0f;
  4226. if ( i < numRows ) {
  4227. for ( k = i; k < numRows; k++ ) {
  4228. scale += idMath::Fabs( (*this)[k][i] );
  4229. }
  4230. if ( scale ) {
  4231. for ( k = i; k < numRows; k++ ) {
  4232. (*this)[k][i] /= scale;
  4233. s += (*this)[k][i] * (*this)[k][i];
  4234. }
  4235. f = (*this)[i][i];
  4236. g = idMath::Sqrt( s );
  4237. if ( f >= 0.0f ) {
  4238. g = -g;
  4239. }
  4240. h = f * g - s;
  4241. (*this)[i][i] = f - g;
  4242. if ( i != (numColumns-1) ) {
  4243. for ( j = l; j < numColumns; j++ ) {
  4244. for ( s = 0.0f, k = i; k < numRows; k++ ) {
  4245. s += (*this)[k][i] * (*this)[k][j];
  4246. }
  4247. f = s / h;
  4248. for ( k = i; k < numRows; k++ ) {
  4249. (*this)[k][j] += f * (*this)[k][i];
  4250. }
  4251. }
  4252. }
  4253. for ( k = i; k < numRows; k++ ) {
  4254. (*this)[k][i] *= scale;
  4255. }
  4256. }
  4257. }
  4258. w[i] = scale * g;
  4259. g = s = scale = 0.0f;
  4260. if ( i < numRows && i != (numColumns-1) ) {
  4261. for ( k = l; k < numColumns; k++ ) {
  4262. scale += idMath::Fabs( (*this)[i][k] );
  4263. }
  4264. if ( scale ) {
  4265. for ( k = l; k < numColumns; k++ ) {
  4266. (*this)[i][k] /= scale;
  4267. s += (*this)[i][k] * (*this)[i][k];
  4268. }
  4269. f = (*this)[i][l];
  4270. g = idMath::Sqrt( s );
  4271. if ( f >= 0.0f ) {
  4272. g = -g;
  4273. }
  4274. h = 1.0f / ( f * g - s );
  4275. (*this)[i][l] = f - g;
  4276. for ( k = l; k < numColumns; k++ ) {
  4277. rv1[k] = (*this)[i][k] * h;
  4278. }
  4279. if ( i != (numRows-1) ) {
  4280. for ( j = l; j < numRows; j++ ) {
  4281. for ( s = 0.0f, k = l; k < numColumns; k++ ) {
  4282. s += (*this)[j][k] * (*this)[i][k];
  4283. }
  4284. for ( k = l; k < numColumns; k++ ) {
  4285. (*this)[j][k] += s * rv1[k];
  4286. }
  4287. }
  4288. }
  4289. for ( k = l; k < numColumns; k++ ) {
  4290. (*this)[i][k] *= scale;
  4291. }
  4292. }
  4293. }
  4294. r = idMath::Fabs( w[i] ) + idMath::Fabs( rv1[i] );
  4295. if ( r > anorm ) {
  4296. anorm = r;
  4297. }
  4298. }
  4299. }
  4300. /*
  4301. ============
  4302. idMatX::SVD_InitialWV
  4303. ============
  4304. */
  4305. void idMatX::SVD_InitialWV( idVecX &w, idMatX &V, idVecX &rv1 ) {
  4306. int i, j, k, l;
  4307. double f, g, s;
  4308. g = 0.0f;
  4309. for ( i = (numColumns-1); i >= 0; i-- ) {
  4310. l = i + 1;
  4311. if ( i < ( numColumns - 1 ) ) {
  4312. if ( g ) {
  4313. for ( j = l; j < numColumns; j++ ) {
  4314. V[j][i] = ((*this)[i][j] / (*this)[i][l]) / g;
  4315. }
  4316. // double division to reduce underflow
  4317. for ( j = l; j < numColumns; j++ ) {
  4318. for ( s = 0.0f, k = l; k < numColumns; k++ ) {
  4319. s += (*this)[i][k] * V[k][j];
  4320. }
  4321. for ( k = l; k < numColumns; k++ ) {
  4322. V[k][j] += s * V[k][i];
  4323. }
  4324. }
  4325. }
  4326. for ( j = l; j < numColumns; j++ ) {
  4327. V[i][j] = V[j][i] = 0.0f;
  4328. }
  4329. }
  4330. V[i][i] = 1.0f;
  4331. g = rv1[i];
  4332. }
  4333. for ( i = numColumns - 1 ; i >= 0; i-- ) {
  4334. l = i + 1;
  4335. g = w[i];
  4336. if ( i < (numColumns-1) ) {
  4337. for ( j = l; j < numColumns; j++ ) {
  4338. (*this)[i][j] = 0.0f;
  4339. }
  4340. }
  4341. if ( g ) {
  4342. g = 1.0f / g;
  4343. if ( i != (numColumns-1) ) {
  4344. for ( j = l; j < numColumns; j++ ) {
  4345. for ( s = 0.0f, k = l; k < numRows; k++ ) {
  4346. s += (*this)[k][i] * (*this)[k][j];
  4347. }
  4348. f = (s / (*this)[i][i]) * g;
  4349. for ( k = i; k < numRows; k++ ) {
  4350. (*this)[k][j] += f * (*this)[k][i];
  4351. }
  4352. }
  4353. }
  4354. for ( j = i; j < numRows; j++ ) {
  4355. (*this)[j][i] *= g;
  4356. }
  4357. }
  4358. else {
  4359. for ( j = i; j < numRows; j++ ) {
  4360. (*this)[j][i] = 0.0f;
  4361. }
  4362. }
  4363. (*this)[i][i] += 1.0f;
  4364. }
  4365. }
  4366. /*
  4367. ============
  4368. idMatX::SVD_Factor
  4369. in-place factorization: U * Diag(w) * V.Transpose()
  4370. known as the Singular Value Decomposition.
  4371. U is a column-orthogonal matrix which overwrites the original matrix.
  4372. w is a diagonal matrix with all elements >= 0 which are the singular values.
  4373. V is the transpose of an orthogonal matrix.
  4374. ============
  4375. */
  4376. bool idMatX::SVD_Factor( idVecX &w, idMatX &V ) {
  4377. int flag, i, its, j, jj, k, l, nm;
  4378. double c, f, h, s, x, y, z, r, g = 0.0f;
  4379. float anorm = 0.0f;
  4380. idVecX rv1;
  4381. if ( numRows < numColumns ) {
  4382. return false;
  4383. }
  4384. rv1.SetData( numColumns, VECX_ALLOCA( numColumns ) );
  4385. rv1.Zero();
  4386. w.Zero( numColumns );
  4387. V.Zero( numColumns, numColumns );
  4388. SVD_BiDiag( w, rv1, anorm );
  4389. SVD_InitialWV( w, V, rv1 );
  4390. for ( k = numColumns - 1; k >= 0; k-- ) {
  4391. for ( its = 1; its <= 30; its++ ) {
  4392. flag = 1;
  4393. nm = 0;
  4394. for ( l = k; l >= 0; l-- ) {
  4395. nm = l - 1;
  4396. if ( ( idMath::Fabs( rv1[l] ) + anorm ) == anorm /* idMath::Fabs( rv1[l] ) < idMath::FLT_EPSILON */ ) {
  4397. flag = 0;
  4398. break;
  4399. }
  4400. if ( ( idMath::Fabs( w[nm] ) + anorm ) == anorm /* idMath::Fabs( w[nm] ) < idMath::FLT_EPSILON */ ) {
  4401. break;
  4402. }
  4403. }
  4404. if ( flag ) {
  4405. c = 0.0f;
  4406. s = 1.0f;
  4407. for ( i = l; i <= k; i++ ) {
  4408. f = s * rv1[i];
  4409. if ( ( idMath::Fabs( f ) + anorm ) != anorm /* idMath::Fabs( f ) > idMath::FLT_EPSILON */ ) {
  4410. g = w[i];
  4411. h = Pythag( f, g );
  4412. w[i] = h;
  4413. h = 1.0f / h;
  4414. c = g * h;
  4415. s = -f * h;
  4416. for ( j = 0; j < numRows; j++ ) {
  4417. y = (*this)[j][nm];
  4418. z = (*this)[j][i];
  4419. (*this)[j][nm] = y * c + z * s;
  4420. (*this)[j][i] = z * c - y * s;
  4421. }
  4422. }
  4423. }
  4424. }
  4425. z = w[k];
  4426. if ( l == k ) {
  4427. if ( z < 0.0f ) {
  4428. w[k] = -z;
  4429. for ( j = 0; j < numColumns; j++ ) {
  4430. V[j][k] = -V[j][k];
  4431. }
  4432. }
  4433. break;
  4434. }
  4435. if ( its == 30 ) {
  4436. return false; // no convergence
  4437. }
  4438. x = w[l];
  4439. nm = k - 1;
  4440. y = w[nm];
  4441. g = rv1[nm];
  4442. h = rv1[k];
  4443. f = ( ( y - z ) * ( y + z ) + ( g - h ) * ( g + h ) ) / ( 2.0f * h * y );
  4444. g = Pythag( f, 1.0f );
  4445. r = ( f >= 0.0f ? g : - g );
  4446. f= ( ( x - z ) * ( x + z ) + h * ( ( y / ( f + r ) ) - h ) ) / x;
  4447. c = s = 1.0f;
  4448. for ( j = l; j <= nm; j++ ) {
  4449. i = j + 1;
  4450. g = rv1[i];
  4451. y = w[i];
  4452. h = s * g;
  4453. g = c * g;
  4454. z = Pythag( f, h );
  4455. rv1[j] = z;
  4456. c = f / z;
  4457. s = h / z;
  4458. f = x * c + g * s;
  4459. g = g * c - x * s;
  4460. h = y * s;
  4461. y = y * c;
  4462. for ( jj = 0; jj < numColumns; jj++ ) {
  4463. x = V[jj][j];
  4464. z = V[jj][i];
  4465. V[jj][j] = x * c + z * s;
  4466. V[jj][i] = z * c - x * s;
  4467. }
  4468. z = Pythag( f, h );
  4469. w[j] = z;
  4470. if ( z ) {
  4471. z = 1.0f / z;
  4472. c = f * z;
  4473. s = h * z;
  4474. }
  4475. f = ( c * g ) + ( s * y );
  4476. x = ( c * y ) - ( s * g );
  4477. for ( jj = 0; jj < numRows; jj++ ) {
  4478. y = (*this)[jj][j];
  4479. z = (*this)[jj][i];
  4480. (*this)[jj][j] = y * c + z * s;
  4481. (*this)[jj][i] = z * c - y * s;
  4482. }
  4483. }
  4484. rv1[l] = 0.0f;
  4485. rv1[k] = f;
  4486. w[k] = x;
  4487. }
  4488. }
  4489. return true;
  4490. }
  4491. /*
  4492. ============
  4493. idMatX::SVD_Solve
  4494. Solve Ax = b with A factored as: U * Diag(w) * V.Transpose()
  4495. ============
  4496. */
  4497. void idMatX::SVD_Solve( idVecX &x, const idVecX &b, const idVecX &w, const idMatX &V ) const {
  4498. int i, j;
  4499. double sum;
  4500. idVecX tmp;
  4501. assert( x.GetSize() >= numColumns );
  4502. assert( b.GetSize() >= numColumns );
  4503. assert( w.GetSize() == numColumns );
  4504. assert( V.GetNumRows() == numColumns && V.GetNumColumns() == numColumns );
  4505. tmp.SetData( numColumns, VECX_ALLOCA( numColumns ) );
  4506. for ( i = 0; i < numColumns; i++ ) {
  4507. sum = 0.0f;
  4508. if ( w[i] >= idMath::FLT_EPSILON ) {
  4509. for ( j = 0; j < numRows; j++ ) {
  4510. sum += (*this)[j][i] * b[j];
  4511. }
  4512. sum /= w[i];
  4513. }
  4514. tmp[i] = sum;
  4515. }
  4516. for ( i = 0; i < numColumns; i++ ) {
  4517. sum = 0.0f;
  4518. for ( j = 0; j < numColumns; j++ ) {
  4519. sum += V[i][j] * tmp[j];
  4520. }
  4521. x[i] = sum;
  4522. }
  4523. }
  4524. /*
  4525. ============
  4526. idMatX::SVD_Inverse
  4527. Calculates the inverse of the matrix which is factored in-place as: U * Diag(w) * V.Transpose()
  4528. ============
  4529. */
  4530. void idMatX::SVD_Inverse( idMatX &inv, const idVecX &w, const idMatX &V ) const {
  4531. int i, j, k;
  4532. double wi, sum;
  4533. idMatX V2;
  4534. assert( numRows == numColumns );
  4535. V2 = V;
  4536. // V * [diag(1/w[i])]
  4537. for ( i = 0; i < numRows; i++ ) {
  4538. wi = w[i];
  4539. wi = ( wi < idMath::FLT_EPSILON ) ? 0.0f : 1.0f / wi;
  4540. for ( j = 0; j < numColumns; j++ ) {
  4541. V2[j][i] *= wi;
  4542. }
  4543. }
  4544. // V * [diag(1/w[i])] * Ut
  4545. for ( i = 0; i < numRows; i++ ) {
  4546. for ( j = 0; j < numColumns; j++ ) {
  4547. sum = V2[i][0] * (*this)[j][0];
  4548. for ( k = 1; k < numColumns; k++ ) {
  4549. sum += V2[i][k] * (*this)[j][k];
  4550. }
  4551. inv[i][j] = sum;
  4552. }
  4553. }
  4554. }
  4555. /*
  4556. ============
  4557. idMatX::SVD_MultiplyFactors
  4558. Multiplies the factors of the in-place SVD factorization to form the original matrix.
  4559. ============
  4560. */
  4561. void idMatX::SVD_MultiplyFactors( idMatX &m, const idVecX &w, const idMatX &V ) const {
  4562. int r, i, j;
  4563. double sum;
  4564. m.SetSize( numRows, V.GetNumRows() );
  4565. for ( r = 0; r < numRows; r++ ) {
  4566. // calculate row of matrix
  4567. if ( w[r] >= idMath::FLT_EPSILON ) {
  4568. for ( i = 0; i < V.GetNumRows(); i++ ) {
  4569. sum = 0.0f;
  4570. for ( j = 0; j < numColumns; j++ ) {
  4571. sum += (*this)[r][j] * V[i][j];
  4572. }
  4573. m[r][i] = sum * w[r];
  4574. }
  4575. } else {
  4576. for ( i = 0; i < V.GetNumRows(); i++ ) {
  4577. m[r][i] = 0.0f;
  4578. }
  4579. }
  4580. }
  4581. }
  4582. /*
  4583. ============
  4584. idMatX::Cholesky_Factor
  4585. in-place Cholesky factorization: LL'
  4586. L is a triangular matrix stored in the lower triangle.
  4587. The upper triangle is not cleared.
  4588. The initial matrix has to be symmetric positive definite.
  4589. ============
  4590. */
  4591. bool idMatX::Cholesky_Factor( void ) {
  4592. int i, j, k;
  4593. float *invSqrt;
  4594. double sum;
  4595. assert( numRows == numColumns );
  4596. invSqrt = (float *) _alloca16( numRows * sizeof( float ) );
  4597. for ( i = 0; i < numRows; i++ ) {
  4598. for ( j = 0; j < i; j++ ) {
  4599. sum = (*this)[i][j];
  4600. for ( k = 0; k < j; k++ ) {
  4601. sum -= (*this)[i][k] * (*this)[j][k];
  4602. }
  4603. (*this)[i][j] = sum * invSqrt[j];
  4604. }
  4605. sum = (*this)[i][i];
  4606. for ( k = 0; k < i; k++ ) {
  4607. sum -= (*this)[i][k] * (*this)[i][k];
  4608. }
  4609. if ( sum <= 0.0f ) {
  4610. return false;
  4611. }
  4612. invSqrt[i] = idMath::InvSqrt( sum );
  4613. (*this)[i][i] = invSqrt[i] * sum;
  4614. }
  4615. return true;
  4616. }
  4617. /*
  4618. ============
  4619. idMatX::Cholesky_UpdateRankOne
  4620. Updates the in-place Cholesky factorization to obtain the factors for the matrix: LL' + alpha * v * v'
  4621. If offset > 0 only the lower right corner starting at (offset, offset) is updated.
  4622. ============
  4623. */
  4624. bool idMatX::Cholesky_UpdateRankOne( const idVecX &v, float alpha, int offset ) {
  4625. int i, j;
  4626. float *y;
  4627. double diag, invDiag, diagSqr, newDiag, newDiagSqr, beta, p, d;
  4628. assert( numRows == numColumns );
  4629. assert( v.GetSize() >= numRows );
  4630. assert( offset >= 0 && offset < numRows );
  4631. y = (float *) _alloca16( v.GetSize() * sizeof( float ) );
  4632. memcpy( y, v.ToFloatPtr(), v.GetSize() * sizeof( float ) );
  4633. for ( i = offset; i < numColumns; i++ ) {
  4634. p = y[i];
  4635. diag = (*this)[i][i];
  4636. invDiag = 1.0f / diag;
  4637. diagSqr = diag * diag;
  4638. newDiagSqr = diagSqr + alpha * p * p;
  4639. if ( newDiagSqr <= 0.0f ) {
  4640. return false;
  4641. }
  4642. (*this)[i][i] = newDiag = idMath::Sqrt( newDiagSqr );
  4643. alpha /= newDiagSqr;
  4644. beta = p * alpha;
  4645. alpha *= diagSqr;
  4646. for ( j = i+1; j < numRows; j++ ) {
  4647. d = (*this)[j][i] * invDiag;
  4648. y[j] -= p * d;
  4649. d += beta * y[j];
  4650. (*this)[j][i] = d * newDiag;
  4651. }
  4652. }
  4653. return true;
  4654. }
  4655. /*
  4656. ============
  4657. idMatX::Cholesky_UpdateRowColumn
  4658. Updates the in-place Cholesky factorization to obtain the factors for the matrix:
  4659. [ 0 a 0 ]
  4660. LL' + [ a b c ]
  4661. [ 0 c 0 ]
  4662. where: a = v[0,r-1], b = v[r], c = v[r+1,numRows-1]
  4663. ============
  4664. */
  4665. bool idMatX::Cholesky_UpdateRowColumn( const idVecX &v, int r ) {
  4666. int i, j;
  4667. double sum;
  4668. float *original, *y;
  4669. idVecX addSub;
  4670. assert( numRows == numColumns );
  4671. assert( v.GetSize() >= numRows );
  4672. assert( r >= 0 && r < numRows );
  4673. addSub.SetData( numColumns, (float *) _alloca16( numColumns * sizeof( float ) ) );
  4674. if ( r == 0 ) {
  4675. if ( numColumns == 1 ) {
  4676. double v0 = v[0];
  4677. sum = (*this)[0][0];
  4678. sum = sum * sum;
  4679. sum = sum + v0;
  4680. if ( sum <= 0.0f ) {
  4681. return false;
  4682. }
  4683. (*this)[0][0] = idMath::Sqrt( sum );
  4684. return true;
  4685. }
  4686. for ( i = 0; i < numColumns; i++ ) {
  4687. addSub[i] = v[i];
  4688. }
  4689. } else {
  4690. original = (float *) _alloca16( numColumns * sizeof( float ) );
  4691. y = (float *) _alloca16( numColumns * sizeof( float ) );
  4692. // calculate original row/column of matrix
  4693. for ( i = 0; i < numRows; i++ ) {
  4694. sum = 0.0f;
  4695. for ( j = 0; j <= i; j++ ) {
  4696. sum += (*this)[r][j] * (*this)[i][j];
  4697. }
  4698. original[i] = sum;
  4699. }
  4700. // solve for y in L * y = original + v
  4701. for ( i = 0; i < r; i++ ) {
  4702. sum = original[i] + v[i];
  4703. for ( j = 0; j < i; j++ ) {
  4704. sum -= (*this)[r][j] * (*this)[i][j];
  4705. }
  4706. (*this)[r][i] = sum / (*this)[i][i];
  4707. }
  4708. // if the last row/column of the matrix is updated
  4709. if ( r == numColumns - 1 ) {
  4710. // only calculate new diagonal
  4711. sum = original[r] + v[r];
  4712. for ( j = 0; j < r; j++) {
  4713. sum -= (*this)[r][j] * (*this)[r][j];
  4714. }
  4715. if ( sum <= 0.0f ) {
  4716. return false;
  4717. }
  4718. (*this)[r][r] = idMath::Sqrt( sum );
  4719. return true;
  4720. }
  4721. // calculate the row/column to be added to the lower right sub matrix starting at (r, r)
  4722. for ( i = r; i < numColumns; i++ ) {
  4723. sum = 0.0f;
  4724. for ( j = 0; j <= r; j++ ) {
  4725. sum += (*this)[r][j] * (*this)[i][j];
  4726. }
  4727. addSub[i] = v[i] - ( sum - original[i] );
  4728. }
  4729. }
  4730. // add row/column to the lower right sub matrix starting at (r, r)
  4731. #if 0
  4732. idVecX v1, v2;
  4733. double d;
  4734. v1.SetData( numColumns, (float *) _alloca16( numColumns * sizeof( float ) ) );
  4735. v2.SetData( numColumns, (float *) _alloca16( numColumns * sizeof( float ) ) );
  4736. d = idMath::SQRT_1OVER2;
  4737. v1[r] = ( 0.5f * addSub[r] + 1.0f ) * d;
  4738. v2[r] = ( 0.5f * addSub[r] - 1.0f ) * d;
  4739. for ( i = r+1; i < numColumns; i++ ) {
  4740. v1[i] = v2[i] = addSub[i] * d;
  4741. }
  4742. // update
  4743. if ( !Cholesky_UpdateRankOne( v1, 1.0f, r ) ) {
  4744. return false;
  4745. }
  4746. // downdate
  4747. if ( !Cholesky_UpdateRankOne( v2, -1.0f, r ) ) {
  4748. return false;
  4749. }
  4750. #else
  4751. float *v1, *v2;
  4752. double diag, invDiag, diagSqr, newDiag, newDiagSqr;
  4753. double alpha1, alpha2, beta1, beta2, p1, p2, d;
  4754. v1 = (float *) _alloca16( numColumns * sizeof( float ) );
  4755. v2 = (float *) _alloca16( numColumns * sizeof( float ) );
  4756. d = idMath::SQRT_1OVER2;
  4757. v1[r] = ( 0.5f * addSub[r] + 1.0f ) * d;
  4758. v2[r] = ( 0.5f * addSub[r] - 1.0f ) * d;
  4759. for ( i = r+1; i < numColumns; i++ ) {
  4760. v1[i] = v2[i] = addSub[i] * d;
  4761. }
  4762. alpha1 = 1.0f;
  4763. alpha2 = -1.0f;
  4764. // simultaneous update/downdate of the sub matrix starting at (r, r)
  4765. for ( i = r; i < numColumns; i++ ) {
  4766. p1 = v1[i];
  4767. diag = (*this)[i][i];
  4768. invDiag = 1.0f / diag;
  4769. diagSqr = diag * diag;
  4770. newDiagSqr = diagSqr + alpha1 * p1 * p1;
  4771. if ( newDiagSqr <= 0.0f ) {
  4772. return false;
  4773. }
  4774. alpha1 /= newDiagSqr;
  4775. beta1 = p1 * alpha1;
  4776. alpha1 *= diagSqr;
  4777. p2 = v2[i];
  4778. diagSqr = newDiagSqr;
  4779. newDiagSqr = diagSqr + alpha2 * p2 * p2;
  4780. if ( newDiagSqr <= 0.0f ) {
  4781. return false;
  4782. }
  4783. (*this)[i][i] = newDiag = idMath::Sqrt( newDiagSqr );
  4784. alpha2 /= newDiagSqr;
  4785. beta2 = p2 * alpha2;
  4786. alpha2 *= diagSqr;
  4787. for ( j = i+1; j < numRows; j++ ) {
  4788. d = (*this)[j][i] * invDiag;
  4789. v1[j] -= p1 * d;
  4790. d += beta1 * v1[j];
  4791. v2[j] -= p2 * d;
  4792. d += beta2 * v2[j];
  4793. (*this)[j][i] = d * newDiag;
  4794. }
  4795. }
  4796. #endif
  4797. return true;
  4798. }
  4799. /*
  4800. ============
  4801. idMatX::Cholesky_UpdateIncrement
  4802. Updates the in-place Cholesky factorization to obtain the factors for the matrix:
  4803. [ A a ]
  4804. [ a b ]
  4805. where: a = v[0,numRows-1], b = v[numRows]
  4806. ============
  4807. */
  4808. bool idMatX::Cholesky_UpdateIncrement( const idVecX &v ) {
  4809. int i, j;
  4810. float *x;
  4811. double sum;
  4812. assert( numRows == numColumns );
  4813. assert( v.GetSize() >= numRows+1 );
  4814. ChangeSize( numRows+1, numColumns+1, false );
  4815. x = (float *) _alloca16( numRows * sizeof( float ) );
  4816. // solve for x in L * x = v
  4817. for ( i = 0; i < numRows - 1; i++ ) {
  4818. sum = v[i];
  4819. for ( j = 0; j < i; j++ ) {
  4820. sum -= (*this)[i][j] * x[j];
  4821. }
  4822. x[i] = sum / (*this)[i][i];
  4823. }
  4824. // calculate new row of L and calculate the square of the diagonal entry
  4825. sum = v[numRows - 1];
  4826. for ( i = 0; i < numRows - 1; i++ ) {
  4827. (*this)[numRows - 1][i] = x[i];
  4828. sum -= x[i] * x[i];
  4829. }
  4830. if ( sum <= 0.0f ) {
  4831. return false;
  4832. }
  4833. // store the diagonal entry
  4834. (*this)[numRows - 1][numRows - 1] = idMath::Sqrt( sum );
  4835. return true;
  4836. }
  4837. /*
  4838. ============
  4839. idMatX::Cholesky_UpdateDecrement
  4840. Updates the in-place Cholesky factorization to obtain the factors for the matrix with row r and column r removed.
  4841. v should store the row of the original matrix.
  4842. ============
  4843. */
  4844. bool idMatX::Cholesky_UpdateDecrement( const idVecX &v, int r ) {
  4845. idVecX v1;
  4846. assert( numRows == numColumns );
  4847. assert( v.GetSize() >= numRows );
  4848. assert( r >= 0 && r < numRows );
  4849. v1.SetData( numRows, VECX_ALLOCA( numRows ) );
  4850. // update the row and column to identity
  4851. v1 = -v;
  4852. v1[r] += 1.0f;
  4853. // NOTE: msvc compiler bug: the this pointer stored in edi is expected to stay
  4854. // untouched when calling Cholesky_UpdateRowColumn in the if statement
  4855. #if 0
  4856. if ( !Cholesky_UpdateRowColumn( v1, r ) ) {
  4857. #else
  4858. bool ret = Cholesky_UpdateRowColumn( v1, r );
  4859. if ( !ret ) {
  4860. #endif
  4861. return false;
  4862. }
  4863. // physically remove the row and column
  4864. Update_Decrement( r );
  4865. return true;
  4866. }
  4867. /*
  4868. ============
  4869. idMatX::Cholesky_Solve
  4870. Solve Ax = b with A factored in-place as: LL'
  4871. ============
  4872. */
  4873. void idMatX::Cholesky_Solve( idVecX &x, const idVecX &b ) const {
  4874. int i, j;
  4875. double sum;
  4876. assert( numRows == numColumns );
  4877. assert( x.GetSize() >= numRows && b.GetSize() >= numRows );
  4878. // solve L
  4879. for ( i = 0; i < numRows; i++ ) {
  4880. sum = b[i];
  4881. for ( j = 0; j < i; j++ ) {
  4882. sum -= (*this)[i][j] * x[j];
  4883. }
  4884. x[i] = sum / (*this)[i][i];
  4885. }
  4886. // solve Lt
  4887. for ( i = numRows - 1; i >= 0; i-- ) {
  4888. sum = x[i];
  4889. for ( j = i + 1; j < numRows; j++ ) {
  4890. sum -= (*this)[j][i] * x[j];
  4891. }
  4892. x[i] = sum / (*this)[i][i];
  4893. }
  4894. }
  4895. /*
  4896. ============
  4897. idMatX::Cholesky_Inverse
  4898. Calculates the inverse of the matrix which is factored in-place as: LL'
  4899. ============
  4900. */
  4901. void idMatX::Cholesky_Inverse( idMatX &inv ) const {
  4902. int i, j;
  4903. idVecX x, b;
  4904. assert( numRows == numColumns );
  4905. x.SetData( numRows, VECX_ALLOCA( numRows ) );
  4906. b.SetData( numRows, VECX_ALLOCA( numRows ) );
  4907. b.Zero();
  4908. inv.SetSize( numRows, numColumns );
  4909. for ( i = 0; i < numRows; i++ ) {
  4910. b[i] = 1.0f;
  4911. Cholesky_Solve( x, b );
  4912. for ( j = 0; j < numRows; j++ ) {
  4913. inv[j][i] = x[j];
  4914. }
  4915. b[i] = 0.0f;
  4916. }
  4917. }
  4918. /*
  4919. ============
  4920. idMatX::Cholesky_MultiplyFactors
  4921. Multiplies the factors of the in-place Cholesky factorization to form the original matrix.
  4922. ============
  4923. */
  4924. void idMatX::Cholesky_MultiplyFactors( idMatX &m ) const {
  4925. int r, i, j;
  4926. double sum;
  4927. m.SetSize( numRows, numColumns );
  4928. for ( r = 0; r < numRows; r++ ) {
  4929. // calculate row of matrix
  4930. for ( i = 0; i < numRows; i++ ) {
  4931. sum = 0.0f;
  4932. for ( j = 0; j <= i && j <= r; j++ ) {
  4933. sum += (*this)[r][j] * (*this)[i][j];
  4934. }
  4935. m[r][i] = sum;
  4936. }
  4937. }
  4938. }
  4939. /*
  4940. ============
  4941. idMatX::LDLT_Factor
  4942. in-place factorization: LDL'
  4943. L is a triangular matrix stored in the lower triangle.
  4944. L has ones on the diagonal that are not stored.
  4945. D is a diagonal matrix stored on the diagonal.
  4946. The upper triangle is not cleared.
  4947. The initial matrix has to be symmetric.
  4948. ============
  4949. */
  4950. bool idMatX::LDLT_Factor( void ) {
  4951. int i, j, k;
  4952. float *v;
  4953. double d, sum;
  4954. assert( numRows == numColumns );
  4955. v = (float *) _alloca16( numRows * sizeof( float ) );
  4956. for ( i = 0; i < numRows; i++ ) {
  4957. sum = (*this)[i][i];
  4958. for ( j = 0; j < i; j++ ) {
  4959. d = (*this)[i][j];
  4960. v[j] = (*this)[j][j] * d;
  4961. sum -= v[j] * d;
  4962. }
  4963. if ( sum == 0.0f ) {
  4964. return false;
  4965. }
  4966. (*this)[i][i] = sum;
  4967. d = 1.0f / sum;
  4968. for ( j = i + 1; j < numRows; j++ ) {
  4969. sum = (*this)[j][i];
  4970. for ( k = 0; k < i; k++ ) {
  4971. sum -= (*this)[j][k] * v[k];
  4972. }
  4973. (*this)[j][i] = sum * d;
  4974. }
  4975. }
  4976. return true;
  4977. }
  4978. /*
  4979. ============
  4980. idMatX::LDLT_UpdateRankOne
  4981. Updates the in-place LDL' factorization to obtain the factors for the matrix: LDL' + alpha * v * v'
  4982. If offset > 0 only the lower right corner starting at (offset, offset) is updated.
  4983. ============
  4984. */
  4985. bool idMatX::LDLT_UpdateRankOne( const idVecX &v, float alpha, int offset ) {
  4986. int i, j;
  4987. float *y;
  4988. double diag, newDiag, beta, p, d;
  4989. assert( numRows == numColumns );
  4990. assert( v.GetSize() >= numRows );
  4991. assert( offset >= 0 && offset < numRows );
  4992. y = (float *) _alloca16( v.GetSize() * sizeof( float ) );
  4993. memcpy( y, v.ToFloatPtr(), v.GetSize() * sizeof( float ) );
  4994. for ( i = offset; i < numColumns; i++ ) {
  4995. p = y[i];
  4996. diag = (*this)[i][i];
  4997. (*this)[i][i] = newDiag = diag + alpha * p * p;
  4998. if ( newDiag == 0.0f ) {
  4999. return false;
  5000. }
  5001. alpha /= newDiag;
  5002. beta = p * alpha;
  5003. alpha *= diag;
  5004. for ( j = i+1; j < numRows; j++ ) {
  5005. d = (*this)[j][i];
  5006. y[j] -= p * d;
  5007. d += beta * y[j];
  5008. (*this)[j][i] = d;
  5009. }
  5010. }
  5011. return true;
  5012. }
  5013. /*
  5014. ============
  5015. idMatX::LDLT_UpdateRowColumn
  5016. Updates the in-place LDL' factorization to obtain the factors for the matrix:
  5017. [ 0 a 0 ]
  5018. LDL' + [ a b c ]
  5019. [ 0 c 0 ]
  5020. where: a = v[0,r-1], b = v[r], c = v[r+1,numRows-1]
  5021. ============
  5022. */
  5023. bool idMatX::LDLT_UpdateRowColumn( const idVecX &v, int r ) {
  5024. int i, j;
  5025. double sum;
  5026. float *original, *y;
  5027. idVecX addSub;
  5028. assert( numRows == numColumns );
  5029. assert( v.GetSize() >= numRows );
  5030. assert( r >= 0 && r < numRows );
  5031. addSub.SetData( numColumns, (float *) _alloca16( numColumns * sizeof( float ) ) );
  5032. if ( r == 0 ) {
  5033. if ( numColumns == 1 ) {
  5034. (*this)[0][0] += v[0];
  5035. return true;
  5036. }
  5037. for ( i = 0; i < numColumns; i++ ) {
  5038. addSub[i] = v[i];
  5039. }
  5040. } else {
  5041. original = (float *) _alloca16( numColumns * sizeof( float ) );
  5042. y = (float *) _alloca16( numColumns * sizeof( float ) );
  5043. // calculate original row/column of matrix
  5044. for ( i = 0; i < r; i++ ) {
  5045. y[i] = (*this)[r][i] * (*this)[i][i];
  5046. }
  5047. for ( i = 0; i < numColumns; i++ ) {
  5048. if ( i < r ) {
  5049. sum = (*this)[i][i] * (*this)[r][i];
  5050. } else if ( i == r ) {
  5051. sum = (*this)[r][r];
  5052. } else {
  5053. sum = (*this)[r][r] * (*this)[i][r];
  5054. }
  5055. for ( j = 0; j < i && j < r; j++ ) {
  5056. sum += (*this)[i][j] * y[j];
  5057. }
  5058. original[i] = sum;
  5059. }
  5060. // solve for y in L * y = original + v
  5061. for ( i = 0; i < r; i++ ) {
  5062. sum = original[i] + v[i];
  5063. for ( j = 0; j < i; j++ ) {
  5064. sum -= (*this)[i][j] * y[j];
  5065. }
  5066. y[i] = sum;
  5067. }
  5068. // calculate new row of L
  5069. for ( i = 0; i < r; i++ ) {
  5070. (*this)[r][i] = y[i] / (*this)[i][i];
  5071. }
  5072. // if the last row/column of the matrix is updated
  5073. if ( r == numColumns - 1 ) {
  5074. // only calculate new diagonal
  5075. sum = original[r] + v[r];
  5076. for ( j = 0; j < r; j++ ) {
  5077. sum -= (*this)[r][j] * y[j];
  5078. }
  5079. if ( sum == 0.0f ) {
  5080. return false;
  5081. }
  5082. (*this)[r][r] = sum;
  5083. return true;
  5084. }
  5085. // calculate the row/column to be added to the lower right sub matrix starting at (r, r)
  5086. for ( i = 0; i < r; i++ ) {
  5087. y[i] = (*this)[r][i] * (*this)[i][i];
  5088. }
  5089. for ( i = r; i < numColumns; i++ ) {
  5090. if ( i == r ) {
  5091. sum = (*this)[r][r];
  5092. } else {
  5093. sum = (*this)[r][r] * (*this)[i][r];
  5094. }
  5095. for ( j = 0; j < r; j++ ) {
  5096. sum += (*this)[i][j] * y[j];
  5097. }
  5098. addSub[i] = v[i] - ( sum - original[i] );
  5099. }
  5100. }
  5101. // add row/column to the lower right sub matrix starting at (r, r)
  5102. #if 0
  5103. idVecX v1, v2;
  5104. double d;
  5105. v1.SetData( numColumns, (float *) _alloca16( numColumns * sizeof( float ) ) );
  5106. v2.SetData( numColumns, (float *) _alloca16( numColumns * sizeof( float ) ) );
  5107. d = idMath::SQRT_1OVER2;
  5108. v1[r] = ( 0.5f * addSub[r] + 1.0f ) * d;
  5109. v2[r] = ( 0.5f * addSub[r] - 1.0f ) * d;
  5110. for ( i = r+1; i < numColumns; i++ ) {
  5111. v1[i] = v2[i] = addSub[i] * d;
  5112. }
  5113. // update
  5114. if ( !LDLT_UpdateRankOne( v1, 1.0f, r ) ) {
  5115. return false;
  5116. }
  5117. // downdate
  5118. if ( !LDLT_UpdateRankOne( v2, -1.0f, r ) ) {
  5119. return false;
  5120. }
  5121. #else
  5122. float *v1, *v2;
  5123. double d, diag, newDiag, p1, p2, alpha1, alpha2, beta1, beta2;
  5124. v1 = (float *) _alloca16( numColumns * sizeof( float ) );
  5125. v2 = (float *) _alloca16( numColumns * sizeof( float ) );
  5126. d = idMath::SQRT_1OVER2;
  5127. v1[r] = ( 0.5f * addSub[r] + 1.0f ) * d;
  5128. v2[r] = ( 0.5f * addSub[r] - 1.0f ) * d;
  5129. for ( i = r+1; i < numColumns; i++ ) {
  5130. v1[i] = v2[i] = addSub[i] * d;
  5131. }
  5132. alpha1 = 1.0f;
  5133. alpha2 = -1.0f;
  5134. // simultaneous update/downdate of the sub matrix starting at (r, r)
  5135. for ( i = r; i < numColumns; i++ ) {
  5136. diag = (*this)[i][i];
  5137. p1 = v1[i];
  5138. newDiag = diag + alpha1 * p1 * p1;
  5139. if ( newDiag == 0.0f ) {
  5140. return false;
  5141. }
  5142. alpha1 /= newDiag;
  5143. beta1 = p1 * alpha1;
  5144. alpha1 *= diag;
  5145. diag = newDiag;
  5146. p2 = v2[i];
  5147. newDiag = diag + alpha2 * p2 * p2;
  5148. if ( newDiag == 0.0f ) {
  5149. return false;
  5150. }
  5151. alpha2 /= newDiag;
  5152. beta2 = p2 * alpha2;
  5153. alpha2 *= diag;
  5154. (*this)[i][i] = newDiag;
  5155. for ( j = i+1; j < numRows; j++ ) {
  5156. d = (*this)[j][i];
  5157. v1[j] -= p1 * d;
  5158. d += beta1 * v1[j];
  5159. v2[j] -= p2 * d;
  5160. d += beta2 * v2[j];
  5161. (*this)[j][i] = d;
  5162. }
  5163. }
  5164. #endif
  5165. return true;
  5166. }
  5167. /*
  5168. ============
  5169. idMatX::LDLT_UpdateIncrement
  5170. Updates the in-place LDL' factorization to obtain the factors for the matrix:
  5171. [ A a ]
  5172. [ a b ]
  5173. where: a = v[0,numRows-1], b = v[numRows]
  5174. ============
  5175. */
  5176. bool idMatX::LDLT_UpdateIncrement( const idVecX &v ) {
  5177. int i, j;
  5178. float *x;
  5179. double sum, d;
  5180. assert( numRows == numColumns );
  5181. assert( v.GetSize() >= numRows+1 );
  5182. ChangeSize( numRows+1, numColumns+1, false );
  5183. x = (float *) _alloca16( numRows * sizeof( float ) );
  5184. // solve for x in L * x = v
  5185. for ( i = 0; i < numRows - 1; i++ ) {
  5186. sum = v[i];
  5187. for ( j = 0; j < i; j++ ) {
  5188. sum -= (*this)[i][j] * x[j];
  5189. }
  5190. x[i] = sum;
  5191. }
  5192. // calculate new row of L and calculate the diagonal entry
  5193. sum = v[numRows - 1];
  5194. for ( i = 0; i < numRows - 1; i++ ) {
  5195. (*this)[numRows - 1][i] = d = x[i] / (*this)[i][i];
  5196. sum -= d * x[i];
  5197. }
  5198. if ( sum == 0.0f ) {
  5199. return false;
  5200. }
  5201. // store the diagonal entry
  5202. (*this)[numRows - 1][numRows - 1] = sum;
  5203. return true;
  5204. }
  5205. /*
  5206. ============
  5207. idMatX::LDLT_UpdateDecrement
  5208. Updates the in-place LDL' factorization to obtain the factors for the matrix with row r and column r removed.
  5209. v should store the row of the original matrix.
  5210. ============
  5211. */
  5212. bool idMatX::LDLT_UpdateDecrement( const idVecX &v, int r ) {
  5213. idVecX v1;
  5214. assert( numRows == numColumns );
  5215. assert( v.GetSize() >= numRows );
  5216. assert( r >= 0 && r < numRows );
  5217. v1.SetData( numRows, VECX_ALLOCA( numRows ) );
  5218. // update the row and column to identity
  5219. v1 = -v;
  5220. v1[r] += 1.0f;
  5221. // NOTE: msvc compiler bug: the this pointer stored in edi is expected to stay
  5222. // untouched when calling LDLT_UpdateRowColumn in the if statement
  5223. #if 0
  5224. if ( !LDLT_UpdateRowColumn( v1, r ) ) {
  5225. #else
  5226. bool ret = LDLT_UpdateRowColumn( v1, r );
  5227. if ( !ret ) {
  5228. #endif
  5229. return false;
  5230. }
  5231. // physically remove the row and column
  5232. Update_Decrement( r );
  5233. return true;
  5234. }
  5235. /*
  5236. ============
  5237. idMatX::LDLT_Solve
  5238. Solve Ax = b with A factored in-place as: LDL'
  5239. ============
  5240. */
  5241. void idMatX::LDLT_Solve( idVecX &x, const idVecX &b ) const {
  5242. int i, j;
  5243. double sum;
  5244. assert( numRows == numColumns );
  5245. assert( x.GetSize() >= numRows && b.GetSize() >= numRows );
  5246. // solve L
  5247. for ( i = 0; i < numRows; i++ ) {
  5248. sum = b[i];
  5249. for ( j = 0; j < i; j++ ) {
  5250. sum -= (*this)[i][j] * x[j];
  5251. }
  5252. x[i] = sum;
  5253. }
  5254. // solve D
  5255. for ( i = 0; i < numRows; i++ ) {
  5256. x[i] /= (*this)[i][i];
  5257. }
  5258. // solve Lt
  5259. for ( i = numRows - 2; i >= 0; i-- ) {
  5260. sum = x[i];
  5261. for ( j = i + 1; j < numRows; j++ ) {
  5262. sum -= (*this)[j][i] * x[j];
  5263. }
  5264. x[i] = sum;
  5265. }
  5266. }
  5267. /*
  5268. ============
  5269. idMatX::LDLT_Inverse
  5270. Calculates the inverse of the matrix which is factored in-place as: LDL'
  5271. ============
  5272. */
  5273. void idMatX::LDLT_Inverse( idMatX &inv ) const {
  5274. int i, j;
  5275. idVecX x, b;
  5276. assert( numRows == numColumns );
  5277. x.SetData( numRows, VECX_ALLOCA( numRows ) );
  5278. b.SetData( numRows, VECX_ALLOCA( numRows ) );
  5279. b.Zero();
  5280. inv.SetSize( numRows, numColumns );
  5281. for ( i = 0; i < numRows; i++ ) {
  5282. b[i] = 1.0f;
  5283. LDLT_Solve( x, b );
  5284. for ( j = 0; j < numRows; j++ ) {
  5285. inv[j][i] = x[j];
  5286. }
  5287. b[i] = 0.0f;
  5288. }
  5289. }
  5290. /*
  5291. ============
  5292. idMatX::LDLT_UnpackFactors
  5293. Unpacks the in-place LDL' factorization.
  5294. ============
  5295. */
  5296. void idMatX::LDLT_UnpackFactors( idMatX &L, idMatX &D ) const {
  5297. int i, j;
  5298. L.Zero( numRows, numColumns );
  5299. D.Zero( numRows, numColumns );
  5300. for ( i = 0; i < numRows; i++ ) {
  5301. for ( j = 0; j < i; j++ ) {
  5302. L[i][j] = (*this)[i][j];
  5303. }
  5304. L[i][i] = 1.0f;
  5305. D[i][i] = (*this)[i][i];
  5306. }
  5307. }
  5308. /*
  5309. ============
  5310. idMatX::LDLT_MultiplyFactors
  5311. Multiplies the factors of the in-place LDL' factorization to form the original matrix.
  5312. ============
  5313. */
  5314. void idMatX::LDLT_MultiplyFactors( idMatX &m ) const {
  5315. int r, i, j;
  5316. float *v;
  5317. double sum;
  5318. v = (float *) _alloca16( numRows * sizeof( float ) );
  5319. m.SetSize( numRows, numColumns );
  5320. for ( r = 0; r < numRows; r++ ) {
  5321. // calculate row of matrix
  5322. for ( i = 0; i < r; i++ ) {
  5323. v[i] = (*this)[r][i] * (*this)[i][i];
  5324. }
  5325. for ( i = 0; i < numColumns; i++ ) {
  5326. if ( i < r ) {
  5327. sum = (*this)[i][i] * (*this)[r][i];
  5328. } else if ( i == r ) {
  5329. sum = (*this)[r][r];
  5330. } else {
  5331. sum = (*this)[r][r] * (*this)[i][r];
  5332. }
  5333. for ( j = 0; j < i && j < r; j++ ) {
  5334. sum += (*this)[i][j] * v[j];
  5335. }
  5336. m[r][i] = sum;
  5337. }
  5338. }
  5339. }
  5340. /*
  5341. ============
  5342. idMatX::TriDiagonal_ClearTriangles
  5343. ============
  5344. */
  5345. void idMatX::TriDiagonal_ClearTriangles( void ) {
  5346. int i, j;
  5347. assert( numRows == numColumns );
  5348. for ( i = 0; i < numRows-2; i++ ) {
  5349. for ( j = i+2; j < numColumns; j++ ) {
  5350. (*this)[i][j] = 0.0f;
  5351. (*this)[j][i] = 0.0f;
  5352. }
  5353. }
  5354. }
  5355. /*
  5356. ============
  5357. idMatX::TriDiagonal_Solve
  5358. Solve Ax = b with A being tridiagonal.
  5359. ============
  5360. */
  5361. bool idMatX::TriDiagonal_Solve( idVecX &x, const idVecX &b ) const {
  5362. int i;
  5363. float d;
  5364. idVecX tmp;
  5365. assert( numRows == numColumns );
  5366. assert( x.GetSize() >= numRows && b.GetSize() >= numRows );
  5367. tmp.SetData( numRows, VECX_ALLOCA( numRows ) );
  5368. d = (*this)[0][0];
  5369. if ( d == 0.0f ) {
  5370. return false;
  5371. }
  5372. d = 1.0f / d;
  5373. x[0] = b[0] * d;
  5374. for ( i = 1; i < numRows; i++ ) {
  5375. tmp[i] = (*this)[i-1][i] * d;
  5376. d = (*this)[i][i] - (*this)[i][i-1] * tmp[i];
  5377. if ( d == 0.0f ) {
  5378. return false;
  5379. }
  5380. d = 1.0f / d;
  5381. x[i] = ( b[i] - (*this)[i][i-1] * x[i-1] ) * d;
  5382. }
  5383. for ( i = numRows - 2; i >= 0; i-- ) {
  5384. x[i] -= tmp[i+1] * x[i+1];
  5385. }
  5386. return true;
  5387. }
  5388. /*
  5389. ============
  5390. idMatX::TriDiagonal_Inverse
  5391. Calculates the inverse of a tri-diagonal matrix.
  5392. ============
  5393. */
  5394. void idMatX::TriDiagonal_Inverse( idMatX &inv ) const {
  5395. int i, j;
  5396. idVecX x, b;
  5397. assert( numRows == numColumns );
  5398. x.SetData( numRows, VECX_ALLOCA( numRows ) );
  5399. b.SetData( numRows, VECX_ALLOCA( numRows ) );
  5400. b.Zero();
  5401. inv.SetSize( numRows, numColumns );
  5402. for ( i = 0; i < numRows; i++ ) {
  5403. b[i] = 1.0f;
  5404. TriDiagonal_Solve( x, b );
  5405. for ( j = 0; j < numRows; j++ ) {
  5406. inv[j][i] = x[j];
  5407. }
  5408. b[i] = 0.0f;
  5409. }
  5410. }
  5411. /*
  5412. ============
  5413. idMatX::HouseholderReduction
  5414. Householder reduction to symmetric tri-diagonal form.
  5415. The original matrix is replaced by an orthogonal matrix effecting the accumulated householder transformations.
  5416. The diagonal elements of the diagonal matrix are stored in diag.
  5417. The off-diagonal elements of the diagonal matrix are stored in subd.
  5418. The initial matrix has to be symmetric.
  5419. ============
  5420. */
  5421. void idMatX::HouseholderReduction( idVecX &diag, idVecX &subd ) {
  5422. int i0, i1, i2, i3;
  5423. float h, f, g, invH, halfFdivH, scale, invScale, sum;
  5424. assert( numRows == numColumns );
  5425. diag.SetSize( numRows );
  5426. subd.SetSize( numRows );
  5427. for ( i0 = numRows-1, i3 = numRows-2; i0 >= 1; i0--, i3-- ) {
  5428. h = 0.0f;
  5429. scale = 0.0f;
  5430. if ( i3 > 0 ) {
  5431. for ( i2 = 0; i2 <= i3; i2++ ) {
  5432. scale += idMath::Fabs( (*this)[i0][i2] );
  5433. }
  5434. if ( scale == 0 ) {
  5435. subd[i0] = (*this)[i0][i3];
  5436. } else {
  5437. invScale = 1.0f / scale;
  5438. for (i2 = 0; i2 <= i3; i2++)
  5439. {
  5440. (*this)[i0][i2] *= invScale;
  5441. h += (*this)[i0][i2] * (*this)[i0][i2];
  5442. }
  5443. f = (*this)[i0][i3];
  5444. g = idMath::Sqrt( h );
  5445. if ( f > 0.0f ) {
  5446. g = -g;
  5447. }
  5448. subd[i0] = scale * g;
  5449. h -= f * g;
  5450. (*this)[i0][i3] = f - g;
  5451. f = 0.0f;
  5452. invH = 1.0f / h;
  5453. for (i1 = 0; i1 <= i3; i1++) {
  5454. (*this)[i1][i0] = (*this)[i0][i1] * invH;
  5455. g = 0.0f;
  5456. for (i2 = 0; i2 <= i1; i2++) {
  5457. g += (*this)[i1][i2] * (*this)[i0][i2];
  5458. }
  5459. for (i2 = i1+1; i2 <= i3; i2++) {
  5460. g += (*this)[i2][i1] * (*this)[i0][i2];
  5461. }
  5462. subd[i1] = g * invH;
  5463. f += subd[i1] * (*this)[i0][i1];
  5464. }
  5465. halfFdivH = 0.5f * f * invH;
  5466. for ( i1 = 0; i1 <= i3; i1++ ) {
  5467. f = (*this)[i0][i1];
  5468. g = subd[i1] - halfFdivH * f;
  5469. subd[i1] = g;
  5470. for ( i2 = 0; i2 <= i1; i2++ ) {
  5471. (*this)[i1][i2] -= f * subd[i2] + g * (*this)[i0][i2];
  5472. }
  5473. }
  5474. }
  5475. } else {
  5476. subd[i0] = (*this)[i0][i3];
  5477. }
  5478. diag[i0] = h;
  5479. }
  5480. diag[0] = 0.0f;
  5481. subd[0] = 0.0f;
  5482. for ( i0 = 0, i3 = -1; i0 <= numRows-1; i0++, i3++ ) {
  5483. if ( diag[i0] ) {
  5484. for ( i1 = 0; i1 <= i3; i1++ ) {
  5485. sum = 0.0f;
  5486. for (i2 = 0; i2 <= i3; i2++) {
  5487. sum += (*this)[i0][i2] * (*this)[i2][i1];
  5488. }
  5489. for ( i2 = 0; i2 <= i3; i2++ ) {
  5490. (*this)[i2][i1] -= sum * (*this)[i2][i0];
  5491. }
  5492. }
  5493. }
  5494. diag[i0] = (*this)[i0][i0];
  5495. (*this)[i0][i0] = 1.0f;
  5496. for ( i1 = 0; i1 <= i3; i1++ ) {
  5497. (*this)[i1][i0] = 0.0f;
  5498. (*this)[i0][i1] = 0.0f;
  5499. }
  5500. }
  5501. // re-order
  5502. for ( i0 = 1, i3 = 0; i0 < numRows; i0++, i3++ ) {
  5503. subd[i3] = subd[i0];
  5504. }
  5505. subd[numRows-1] = 0.0f;
  5506. }
  5507. /*
  5508. ============
  5509. idMatX::QL
  5510. QL algorithm with implicit shifts to determine the eigenvalues and eigenvectors of a symmetric tri-diagonal matrix.
  5511. diag contains the diagonal elements of the symmetric tri-diagonal matrix on input and is overwritten with the eigenvalues.
  5512. subd contains the off-diagonal elements of the symmetric tri-diagonal matrix and is destroyed.
  5513. This matrix has to be either the identity matrix to determine the eigenvectors for a symmetric tri-diagonal matrix,
  5514. or the matrix returned by the Householder reduction to determine the eigenvalues for the original symmetric matrix.
  5515. ============
  5516. */
  5517. bool idMatX::QL( idVecX &diag, idVecX &subd ) {
  5518. const int maxIter = 32;
  5519. int i0, i1, i2, i3;
  5520. float a, b, f, g, r, p, s, c;
  5521. assert( numRows == numColumns );
  5522. for ( i0 = 0; i0 < numRows; i0++ ) {
  5523. for ( i1 = 0; i1 < maxIter; i1++ ) {
  5524. for ( i2 = i0; i2 <= numRows - 2; i2++ ) {
  5525. a = idMath::Fabs( diag[i2] ) + idMath::Fabs( diag[i2+1] );
  5526. if ( idMath::Fabs( subd[i2] ) + a == a ) {
  5527. break;
  5528. }
  5529. }
  5530. if ( i2 == i0 ) {
  5531. break;
  5532. }
  5533. g = ( diag[i0+1] - diag[i0] ) / ( 2.0f * subd[i0] );
  5534. r = idMath::Sqrt( g * g + 1.0f );
  5535. if ( g < 0.0f ) {
  5536. g = diag[i2] - diag[i0] + subd[i0] / ( g - r );
  5537. } else {
  5538. g = diag[i2] - diag[i0] + subd[i0] / ( g + r );
  5539. }
  5540. s = 1.0f;
  5541. c = 1.0f;
  5542. p = 0.0f;
  5543. for ( i3 = i2 - 1; i3 >= i0; i3-- ) {
  5544. f = s * subd[i3];
  5545. b = c * subd[i3];
  5546. if ( idMath::Fabs( f ) >= idMath::Fabs( g ) ) {
  5547. c = g / f;
  5548. r = idMath::Sqrt( c * c + 1.0f );
  5549. subd[i3+1] = f * r;
  5550. s = 1.0f / r;
  5551. c *= s;
  5552. } else {
  5553. s = f / g;
  5554. r = idMath::Sqrt( s * s + 1.0f );
  5555. subd[i3+1] = g * r;
  5556. c = 1.0f / r;
  5557. s *= c;
  5558. }
  5559. g = diag[i3+1] - p;
  5560. r = ( diag[i3] - g ) * s + 2.0f * b * c;
  5561. p = s * r;
  5562. diag[i3+1] = g + p;
  5563. g = c * r - b;
  5564. for ( int i4 = 0; i4 < numRows; i4++ ) {
  5565. f = (*this)[i4][i3+1];
  5566. (*this)[i4][i3+1] = s * (*this)[i4][i3] + c * f;
  5567. (*this)[i4][i3] = c * (*this)[i4][i3] - s * f;
  5568. }
  5569. }
  5570. diag[i0] -= p;
  5571. subd[i0] = g;
  5572. subd[i2] = 0.0f;
  5573. }
  5574. if ( i1 == maxIter ) {
  5575. return false;
  5576. }
  5577. }
  5578. return true;
  5579. }
  5580. /*
  5581. ============
  5582. idMatX::Eigen_SolveSymmetricTriDiagonal
  5583. Determine eigen values and eigen vectors for a symmetric tri-diagonal matrix.
  5584. The eigen values are stored in 'eigenValues'.
  5585. Column i of the original matrix will store the eigen vector corresponding to the eigenValues[i].
  5586. The initial matrix has to be symmetric tri-diagonal.
  5587. ============
  5588. */
  5589. bool idMatX::Eigen_SolveSymmetricTriDiagonal( idVecX &eigenValues ) {
  5590. int i;
  5591. idVecX subd;
  5592. assert( numRows == numColumns );
  5593. subd.SetData( numRows, VECX_ALLOCA( numRows ) );
  5594. eigenValues.SetSize( numRows );
  5595. for ( i = 0; i < numRows-1; i++ ) {
  5596. eigenValues[i] = (*this)[i][i];
  5597. subd[i] = (*this)[i+1][i];
  5598. }
  5599. eigenValues[numRows-1] = (*this)[numRows-1][numRows-1];
  5600. Identity();
  5601. return QL( eigenValues, subd );
  5602. }
  5603. /*
  5604. ============
  5605. idMatX::Eigen_SolveSymmetric
  5606. Determine eigen values and eigen vectors for a symmetric matrix.
  5607. The eigen values are stored in 'eigenValues'.
  5608. Column i of the original matrix will store the eigen vector corresponding to the eigenValues[i].
  5609. The initial matrix has to be symmetric.
  5610. ============
  5611. */
  5612. bool idMatX::Eigen_SolveSymmetric( idVecX &eigenValues ) {
  5613. idVecX subd;
  5614. assert( numRows == numColumns );
  5615. subd.SetData( numRows, VECX_ALLOCA( numRows ) );
  5616. eigenValues.SetSize( numRows );
  5617. HouseholderReduction( eigenValues, subd );
  5618. return QL( eigenValues, subd );
  5619. }
  5620. /*
  5621. ============
  5622. idMatX::HessenbergReduction
  5623. Reduction to Hessenberg form.
  5624. ============
  5625. */
  5626. void idMatX::HessenbergReduction( idMatX &H ) {
  5627. int i, j, m;
  5628. int low = 0;
  5629. int high = numRows - 1;
  5630. float scale, f, g, h;
  5631. idVecX v;
  5632. v.SetData( numRows, VECX_ALLOCA( numRows ) );
  5633. for ( m = low + 1; m <= high - 1; m++ ) {
  5634. scale = 0.0f;
  5635. for ( i = m; i <= high; i++ ) {
  5636. scale = scale + idMath::Fabs( H[i][m-1] );
  5637. }
  5638. if ( scale != 0.0f ) {
  5639. // compute Householder transformation.
  5640. h = 0.0f;
  5641. for ( i = high; i >= m; i-- ) {
  5642. v[i] = H[i][m-1] / scale;
  5643. h += v[i] * v[i];
  5644. }
  5645. g = idMath::Sqrt( h );
  5646. if ( v[m] > 0.0f ) {
  5647. g = -g;
  5648. }
  5649. h = h - v[m] * g;
  5650. v[m] = v[m] - g;
  5651. // apply Householder similarity transformation
  5652. // H = (I-u*u'/h)*H*(I-u*u')/h)
  5653. for ( j = m; j < numRows; j++) {
  5654. f = 0.0f;
  5655. for ( i = high; i >= m; i-- ) {
  5656. f += v[i] * H[i][j];
  5657. }
  5658. f = f / h;
  5659. for ( i = m; i <= high; i++ ) {
  5660. H[i][j] -= f * v[i];
  5661. }
  5662. }
  5663. for ( i = 0; i <= high; i++ ) {
  5664. f = 0.0f;
  5665. for ( j = high; j >= m; j-- ) {
  5666. f += v[j] * H[i][j];
  5667. }
  5668. f = f / h;
  5669. for ( j = m; j <= high; j++ ) {
  5670. H[i][j] -= f * v[j];
  5671. }
  5672. }
  5673. v[m] = scale * v[m];
  5674. H[m][m-1] = scale * g;
  5675. }
  5676. }
  5677. // accumulate transformations
  5678. Identity();
  5679. for ( int m = high - 1; m >= low + 1; m-- ) {
  5680. if ( H[m][m-1] != 0.0f ) {
  5681. for ( i = m + 1; i <= high; i++ ) {
  5682. v[i] = H[i][m-1];
  5683. }
  5684. for ( j = m; j <= high; j++ ) {
  5685. g = 0.0f;
  5686. for ( i = m; i <= high; i++ ) {
  5687. g += v[i] * (*this)[i][j];
  5688. }
  5689. // float division to avoid possible underflow
  5690. g = ( g / v[m] ) / H[m][m-1];
  5691. for ( i = m; i <= high; i++ ) {
  5692. (*this)[i][j] += g * v[i];
  5693. }
  5694. }
  5695. }
  5696. }
  5697. }
  5698. /*
  5699. ============
  5700. idMatX::ComplexDivision
  5701. Complex scalar division.
  5702. ============
  5703. */
  5704. void idMatX::ComplexDivision( float xr, float xi, float yr, float yi, float &cdivr, float &cdivi ) {
  5705. float r, d;
  5706. if ( idMath::Fabs( yr ) > idMath::Fabs( yi ) ) {
  5707. r = yi / yr;
  5708. d = yr + r * yi;
  5709. cdivr = ( xr + r * xi ) / d;
  5710. cdivi = ( xi - r * xr ) / d;
  5711. } else {
  5712. r = yr / yi;
  5713. d = yi + r * yr;
  5714. cdivr = ( r * xr + xi ) / d;
  5715. cdivi = ( r * xi - xr ) / d;
  5716. }
  5717. }
  5718. /*
  5719. ============
  5720. idMatX::HessenbergToRealSchur
  5721. Reduction from Hessenberg to real Schur form.
  5722. ============
  5723. */
  5724. bool idMatX::HessenbergToRealSchur( idMatX &H, idVecX &realEigenValues, idVecX &imaginaryEigenValues ) {
  5725. int i, j, k;
  5726. int n = numRows - 1;
  5727. int low = 0;
  5728. int high = numRows - 1;
  5729. float eps = 2e-16f, exshift = 0.0f;
  5730. float p = 0.0f, q = 0.0f, r = 0.0f, s = 0.0f, z = 0.0f, t, w, x, y;
  5731. // store roots isolated by balanc and compute matrix norm
  5732. float norm = 0.0f;
  5733. for ( i = 0; i < numRows; i++ ) {
  5734. if ( i < low || i > high ) {
  5735. realEigenValues[i] = H[i][i];
  5736. imaginaryEigenValues[i] = 0.0f;
  5737. }
  5738. for ( j = Max( i - 1, 0 ); j < numRows; j++ ) {
  5739. norm = norm + idMath::Fabs( H[i][j] );
  5740. }
  5741. }
  5742. int iter = 0;
  5743. while( n >= low ) {
  5744. // look for single small sub-diagonal element
  5745. int l = n;
  5746. while ( l > low ) {
  5747. s = idMath::Fabs( H[l-1][l-1] ) + idMath::Fabs( H[l][l] );
  5748. if ( s == 0.0f ) {
  5749. s = norm;
  5750. }
  5751. if ( idMath::Fabs( H[l][l-1] ) < eps * s ) {
  5752. break;
  5753. }
  5754. l--;
  5755. }
  5756. // check for convergence
  5757. if ( l == n ) { // one root found
  5758. H[n][n] = H[n][n] + exshift;
  5759. realEigenValues[n] = H[n][n];
  5760. imaginaryEigenValues[n] = 0.0f;
  5761. n--;
  5762. iter = 0;
  5763. } else if ( l == n-1 ) { // two roots found
  5764. w = H[n][n-1] * H[n-1][n];
  5765. p = ( H[n-1][n-1] - H[n][n] ) / 2.0f;
  5766. q = p * p + w;
  5767. z = idMath::Sqrt( idMath::Fabs( q ) );
  5768. H[n][n] = H[n][n] + exshift;
  5769. H[n-1][n-1] = H[n-1][n-1] + exshift;
  5770. x = H[n][n];
  5771. if ( q >= 0.0f ) { // real pair
  5772. if ( p >= 0.0f ) {
  5773. z = p + z;
  5774. } else {
  5775. z = p - z;
  5776. }
  5777. realEigenValues[n-1] = x + z;
  5778. realEigenValues[n] = realEigenValues[n-1];
  5779. if ( z != 0.0f ) {
  5780. realEigenValues[n] = x - w / z;
  5781. }
  5782. imaginaryEigenValues[n-1] = 0.0f;
  5783. imaginaryEigenValues[n] = 0.0f;
  5784. x = H[n][n-1];
  5785. s = idMath::Fabs( x ) + idMath::Fabs( z );
  5786. p = x / s;
  5787. q = z / s;
  5788. r = idMath::Sqrt( p * p + q * q );
  5789. p = p / r;
  5790. q = q / r;
  5791. // modify row
  5792. for ( j = n-1; j < numRows; j++ ) {
  5793. z = H[n-1][j];
  5794. H[n-1][j] = q * z + p * H[n][j];
  5795. H[n][j] = q * H[n][j] - p * z;
  5796. }
  5797. // modify column
  5798. for ( i = 0; i <= n; i++ ) {
  5799. z = H[i][n-1];
  5800. H[i][n-1] = q * z + p * H[i][n];
  5801. H[i][n] = q * H[i][n] - p * z;
  5802. }
  5803. // accumulate transformations
  5804. for ( i = low; i <= high; i++ ) {
  5805. z = (*this)[i][n-1];
  5806. (*this)[i][n-1] = q * z + p * (*this)[i][n];
  5807. (*this)[i][n] = q * (*this)[i][n] - p * z;
  5808. }
  5809. } else { // complex pair
  5810. realEigenValues[n-1] = x + p;
  5811. realEigenValues[n] = x + p;
  5812. imaginaryEigenValues[n-1] = z;
  5813. imaginaryEigenValues[n] = -z;
  5814. }
  5815. n = n - 2;
  5816. iter = 0;
  5817. } else { // no convergence yet
  5818. // form shift
  5819. x = H[n][n];
  5820. y = 0.0f;
  5821. w = 0.0f;
  5822. if ( l < n ) {
  5823. y = H[n-1][n-1];
  5824. w = H[n][n-1] * H[n-1][n];
  5825. }
  5826. // Wilkinson's original ad hoc shift
  5827. if ( iter == 10 ) {
  5828. exshift += x;
  5829. for ( i = low; i <= n; i++ ) {
  5830. H[i][i] -= x;
  5831. }
  5832. s = idMath::Fabs( H[n][n-1] ) + idMath::Fabs( H[n-1][n-2] );
  5833. x = y = 0.75f * s;
  5834. w = -0.4375f * s * s;
  5835. }
  5836. // new ad hoc shift
  5837. if ( iter == 30 ) {
  5838. s = ( y - x ) / 2.0f;
  5839. s = s * s + w;
  5840. if ( s > 0 ) {
  5841. s = idMath::Sqrt( s );
  5842. if ( y < x ) {
  5843. s = -s;
  5844. }
  5845. s = x - w / ( ( y - x ) / 2.0f + s );
  5846. for ( i = low; i <= n; i++ ) {
  5847. H[i][i] -= s;
  5848. }
  5849. exshift += s;
  5850. x = y = w = 0.964f;
  5851. }
  5852. }
  5853. iter = iter + 1;
  5854. // look for two consecutive small sub-diagonal elements
  5855. int m;
  5856. for( m = n-2; m >= l; m-- ) {
  5857. z = H[m][m];
  5858. r = x - z;
  5859. s = y - z;
  5860. p = ( r * s - w ) / H[m+1][m] + H[m][m+1];
  5861. q = H[m+1][m+1] - z - r - s;
  5862. r = H[m+2][m+1];
  5863. s = idMath::Fabs( p ) + idMath::Fabs( q ) + idMath::Fabs( r );
  5864. p = p / s;
  5865. q = q / s;
  5866. r = r / s;
  5867. if ( m == l ) {
  5868. break;
  5869. }
  5870. if ( idMath::Fabs( H[m][m-1] ) * ( idMath::Fabs( q ) + idMath::Fabs( r ) ) <
  5871. eps * ( idMath::Fabs( p ) * ( idMath::Fabs( H[m-1][m-1] ) + idMath::Fabs( z ) + idMath::Fabs( H[m+1][m+1] ) ) ) ) {
  5872. break;
  5873. }
  5874. }
  5875. for ( i = m+2; i <= n; i++ ) {
  5876. H[i][i-2] = 0.0f;
  5877. if ( i > m+2 ) {
  5878. H[i][i-3] = 0.0f;
  5879. }
  5880. }
  5881. // double QR step involving rows l:n and columns m:n
  5882. for ( k = m; k <= n-1; k++ ) {
  5883. bool notlast = ( k != n-1 );
  5884. if ( k != m ) {
  5885. p = H[k][k-1];
  5886. q = H[k+1][k-1];
  5887. r = ( notlast ? H[k+2][k-1] : 0.0f );
  5888. x = idMath::Fabs( p ) + idMath::Fabs( q ) + idMath::Fabs( r );
  5889. if ( x != 0.0f ) {
  5890. p = p / x;
  5891. q = q / x;
  5892. r = r / x;
  5893. }
  5894. }
  5895. if ( x == 0.0f ) {
  5896. break;
  5897. }
  5898. s = idMath::Sqrt( p * p + q * q + r * r );
  5899. if ( p < 0.0f ) {
  5900. s = -s;
  5901. }
  5902. if ( s != 0.0f ) {
  5903. if ( k != m ) {
  5904. H[k][k-1] = -s * x;
  5905. } else if ( l != m ) {
  5906. H[k][k-1] = -H[k][k-1];
  5907. }
  5908. p = p + s;
  5909. x = p / s;
  5910. y = q / s;
  5911. z = r / s;
  5912. q = q / p;
  5913. r = r / p;
  5914. // modify row
  5915. for ( j = k; j < numRows; j++ ) {
  5916. p = H[k][j] + q * H[k+1][j];
  5917. if ( notlast ) {
  5918. p = p + r * H[k+2][j];
  5919. H[k+2][j] = H[k+2][j] - p * z;
  5920. }
  5921. H[k][j] = H[k][j] - p * x;
  5922. H[k+1][j] = H[k+1][j] - p * y;
  5923. }
  5924. // modify column
  5925. for ( i = 0; i <= Min( n, k + 3 ); i++ ) {
  5926. p = x * H[i][k] + y * H[i][k+1];
  5927. if ( notlast ) {
  5928. p = p + z * H[i][k+2];
  5929. H[i][k+2] = H[i][k+2] - p * r;
  5930. }
  5931. H[i][k] = H[i][k] - p;
  5932. H[i][k+1] = H[i][k+1] - p * q;
  5933. }
  5934. // accumulate transformations
  5935. for ( i = low; i <= high; i++ ) {
  5936. p = x * (*this)[i][k] + y * (*this)[i][k+1];
  5937. if ( notlast ) {
  5938. p = p + z * (*this)[i][k+2];
  5939. (*this)[i][k+2] = (*this)[i][k+2] - p * r;
  5940. }
  5941. (*this)[i][k] = (*this)[i][k] - p;
  5942. (*this)[i][k+1] = (*this)[i][k+1] - p * q;
  5943. }
  5944. }
  5945. }
  5946. }
  5947. }
  5948. // backsubstitute to find vectors of upper triangular form
  5949. if ( norm == 0.0f ) {
  5950. return false;
  5951. }
  5952. for ( n = numRows-1; n >= 0; n-- ) {
  5953. p = realEigenValues[n];
  5954. q = imaginaryEigenValues[n];
  5955. if ( q == 0.0f ) { // real vector
  5956. int l = n;
  5957. H[n][n] = 1.0f;
  5958. for ( i = n-1; i >= 0; i-- ) {
  5959. w = H[i][i] - p;
  5960. r = 0.0f;
  5961. for ( j = l; j <= n; j++ ) {
  5962. r = r + H[i][j] * H[j][n];
  5963. }
  5964. if ( imaginaryEigenValues[i] < 0.0f ) {
  5965. z = w;
  5966. s = r;
  5967. } else {
  5968. l = i;
  5969. if ( imaginaryEigenValues[i] == 0.0f ) {
  5970. if ( w != 0.0f ) {
  5971. H[i][n] = -r / w;
  5972. } else {
  5973. H[i][n] = -r / ( eps * norm );
  5974. }
  5975. } else { // solve real equations
  5976. x = H[i][i+1];
  5977. y = H[i+1][i];
  5978. q = ( realEigenValues[i] - p ) * ( realEigenValues[i] - p ) + imaginaryEigenValues[i] * imaginaryEigenValues[i];
  5979. t = ( x * s - z * r ) / q;
  5980. H[i][n] = t;
  5981. if ( idMath::Fabs(x) > idMath::Fabs( z ) ) {
  5982. H[i+1][n] = ( -r - w * t ) / x;
  5983. } else {
  5984. H[i+1][n] = ( -s - y * t ) / z;
  5985. }
  5986. }
  5987. // overflow control
  5988. t = idMath::Fabs(H[i][n]);
  5989. if ( ( eps * t ) * t > 1 ) {
  5990. for ( j = i; j <= n; j++ ) {
  5991. H[j][n] = H[j][n] / t;
  5992. }
  5993. }
  5994. }
  5995. }
  5996. } else if ( q < 0.0f ) { // complex vector
  5997. int l = n-1;
  5998. // last vector component imaginary so matrix is triangular
  5999. if ( idMath::Fabs( H[n][n-1] ) > idMath::Fabs( H[n-1][n] ) ) {
  6000. H[n-1][n-1] = q / H[n][n-1];
  6001. H[n-1][n] = -( H[n][n] - p ) / H[n][n-1];
  6002. } else {
  6003. ComplexDivision( 0.0f, -H[n-1][n], H[n-1][n-1]-p, q, H[n-1][n-1], H[n-1][n] );
  6004. }
  6005. H[n][n-1] = 0.0f;
  6006. H[n][n] = 1.0f;
  6007. for ( i = n-2; i >= 0; i-- ) {
  6008. float ra, sa, vr, vi;
  6009. ra = 0.0f;
  6010. sa = 0.0f;
  6011. for ( j = l; j <= n; j++ ) {
  6012. ra = ra + H[i][j] * H[j][n-1];
  6013. sa = sa + H[i][j] * H[j][n];
  6014. }
  6015. w = H[i][i] - p;
  6016. if ( imaginaryEigenValues[i] < 0.0f ) {
  6017. z = w;
  6018. r = ra;
  6019. s = sa;
  6020. } else {
  6021. l = i;
  6022. if ( imaginaryEigenValues[i] == 0.0f ) {
  6023. ComplexDivision( -ra, -sa, w, q, H[i][n-1], H[i][n] );
  6024. } else {
  6025. // solve complex equations
  6026. x = H[i][i+1];
  6027. y = H[i+1][i];
  6028. vr = ( realEigenValues[i] - p ) * ( realEigenValues[i] - p ) + imaginaryEigenValues[i] * imaginaryEigenValues[i] - q * q;
  6029. vi = ( realEigenValues[i] - p ) * 2.0f * q;
  6030. if ( vr == 0.0f && vi == 0.0f ) {
  6031. vr = eps * norm * ( idMath::Fabs( w ) + idMath::Fabs( q ) + idMath::Fabs( x ) + idMath::Fabs( y ) + idMath::Fabs( z ) );
  6032. }
  6033. ComplexDivision( x * r - z * ra + q * sa, x * s - z * sa - q * ra, vr, vi, H[i][n-1], H[i][n] );
  6034. if ( idMath::Fabs( x ) > ( idMath::Fabs( z ) + idMath::Fabs( q ) ) ) {
  6035. H[i+1][n-1] = ( -ra - w * H[i][n-1] + q * H[i][n] ) / x;
  6036. H[i+1][n] = ( -sa - w * H[i][n] - q * H[i][n-1] ) / x;
  6037. } else {
  6038. ComplexDivision( -r - y * H[i][n-1], -s - y * H[i][n], z, q, H[i+1][n-1], H[i+1][n] );
  6039. }
  6040. }
  6041. // overflow control
  6042. t = Max( idMath::Fabs( H[i][n-1] ), idMath::Fabs( H[i][n] ) );
  6043. if ( ( eps * t ) * t > 1 ) {
  6044. for ( j = i; j <= n; j++ ) {
  6045. H[j][n-1] = H[j][n-1] / t;
  6046. H[j][n] = H[j][n] / t;
  6047. }
  6048. }
  6049. }
  6050. }
  6051. }
  6052. }
  6053. // vectors of isolated roots
  6054. for ( i = 0; i < numRows; i++ ) {
  6055. if ( i < low || i > high ) {
  6056. for ( j = i; j < numRows; j++ ) {
  6057. (*this)[i][j] = H[i][j];
  6058. }
  6059. }
  6060. }
  6061. // back transformation to get eigenvectors of original matrix
  6062. for ( j = numRows - 1; j >= low; j-- ) {
  6063. for ( i = low; i <= high; i++ ) {
  6064. z = 0.0f;
  6065. for ( k = low; k <= Min( j, high ); k++ ) {
  6066. z = z + (*this)[i][k] * H[k][j];
  6067. }
  6068. (*this)[i][j] = z;
  6069. }
  6070. }
  6071. return true;
  6072. }
  6073. /*
  6074. ============
  6075. idMatX::Eigen_Solve
  6076. Determine eigen values and eigen vectors for a square matrix.
  6077. The eigen values are stored in 'realEigenValues' and 'imaginaryEigenValues'.
  6078. Column i of the original matrix will store the eigen vector corresponding to the realEigenValues[i] and imaginaryEigenValues[i].
  6079. ============
  6080. */
  6081. bool idMatX::Eigen_Solve( idVecX &realEigenValues, idVecX &imaginaryEigenValues ) {
  6082. idMatX H;
  6083. assert( numRows == numColumns );
  6084. realEigenValues.SetSize( numRows );
  6085. imaginaryEigenValues.SetSize( numRows );
  6086. H = *this;
  6087. // reduce to Hessenberg form
  6088. HessenbergReduction( H );
  6089. // reduce Hessenberg to real Schur form
  6090. return HessenbergToRealSchur( H, realEigenValues, imaginaryEigenValues );
  6091. }
  6092. /*
  6093. ============
  6094. idMatX::Eigen_SortIncreasing
  6095. ============
  6096. */
  6097. void idMatX::Eigen_SortIncreasing( idVecX &eigenValues ) {
  6098. int i, j, k;
  6099. float min;
  6100. for ( i = 0, j; i <= numRows - 2; i++ ) {
  6101. j = i;
  6102. min = eigenValues[j];
  6103. for ( k = i + 1; k < numRows; k++ ) {
  6104. if ( eigenValues[k] < min ) {
  6105. j = k;
  6106. min = eigenValues[j];
  6107. }
  6108. }
  6109. if ( j != i ) {
  6110. eigenValues.SwapElements( i, j );
  6111. SwapColumns( i, j );
  6112. }
  6113. }
  6114. }
  6115. /*
  6116. ============
  6117. idMatX::Eigen_SortDecreasing
  6118. ============
  6119. */
  6120. void idMatX::Eigen_SortDecreasing( idVecX &eigenValues ) {
  6121. int i, j, k;
  6122. float max;
  6123. for ( i = 0, j; i <= numRows - 2; i++ ) {
  6124. j = i;
  6125. max = eigenValues[j];
  6126. for ( k = i + 1; k < numRows; k++ ) {
  6127. if ( eigenValues[k] > max ) {
  6128. j = k;
  6129. max = eigenValues[j];
  6130. }
  6131. }
  6132. if ( j != i ) {
  6133. eigenValues.SwapElements( i, j );
  6134. SwapColumns( i, j );
  6135. }
  6136. }
  6137. }
  6138. /*
  6139. ============
  6140. idMatX::DeterminantGeneric
  6141. ============
  6142. */
  6143. float idMatX::DeterminantGeneric( void ) const {
  6144. int *index;
  6145. float det;
  6146. idMatX tmp;
  6147. index = (int *) _alloca16( numRows * sizeof( int ) );
  6148. tmp.SetData( numRows, numColumns, MATX_ALLOCA( numRows * numColumns ) );
  6149. tmp = *this;
  6150. if ( !tmp.LU_Factor( index, &det ) ) {
  6151. return 0.0f;
  6152. }
  6153. return det;
  6154. }
  6155. /*
  6156. ============
  6157. idMatX::InverseSelfGeneric
  6158. ============
  6159. */
  6160. bool idMatX::InverseSelfGeneric( void ) {
  6161. int i, j, *index;
  6162. idMatX tmp;
  6163. idVecX x, b;
  6164. index = (int *) _alloca16( numRows * sizeof( int ) );
  6165. tmp.SetData( numRows, numColumns, MATX_ALLOCA( numRows * numColumns ) );
  6166. tmp = *this;
  6167. if ( !tmp.LU_Factor( index ) ) {
  6168. return false;
  6169. }
  6170. x.SetData( numRows, VECX_ALLOCA( numRows ) );
  6171. b.SetData( numRows, VECX_ALLOCA( numRows ) );
  6172. b.Zero();
  6173. for ( i = 0; i < numRows; i++ ) {
  6174. b[i] = 1.0f;
  6175. tmp.LU_Solve( x, b, index );
  6176. for ( j = 0; j < numRows; j++ ) {
  6177. (*this)[j][i] = x[j];
  6178. }
  6179. b[i] = 0.0f;
  6180. }
  6181. return true;
  6182. }
  6183. /*
  6184. ============
  6185. idMatX::Test
  6186. ============
  6187. */
  6188. void idMatX::Test( void ) {
  6189. idMatX original, m1, m2, m3, q1, q2, r1, r2;
  6190. idVecX v, w, u, c, d;
  6191. int offset, size, *index1, *index2;
  6192. size = 6;
  6193. original.Random( size, size, 0 );
  6194. original = original * original.Transpose();
  6195. index1 = (int *) _alloca16( ( size + 1 ) * sizeof( index1[0] ) );
  6196. index2 = (int *) _alloca16( ( size + 1 ) * sizeof( index2[0] ) );
  6197. /*
  6198. idMatX::LowerTriangularInverse
  6199. */
  6200. m1 = original;
  6201. m1.ClearUpperTriangle();
  6202. m2 = m1;
  6203. m2.InverseSelf();
  6204. m1.LowerTriangularInverse();
  6205. if ( !m1.Compare( m2, 1e-4f ) ) {
  6206. idLib::common->Warning( "idMatX::LowerTriangularInverse failed" );
  6207. }
  6208. /*
  6209. idMatX::UpperTriangularInverse
  6210. */
  6211. m1 = original;
  6212. m1.ClearLowerTriangle();
  6213. m2 = m1;
  6214. m2.InverseSelf();
  6215. m1.UpperTriangularInverse();
  6216. if ( !m1.Compare( m2, 1e-4f ) ) {
  6217. idLib::common->Warning( "idMatX::UpperTriangularInverse failed" );
  6218. }
  6219. /*
  6220. idMatX::Inverse_GaussJordan
  6221. */
  6222. m1 = original;
  6223. m1.Inverse_GaussJordan();
  6224. m1 *= original;
  6225. if ( !m1.IsIdentity( 1e-4f ) ) {
  6226. idLib::common->Warning( "idMatX::Inverse_GaussJordan failed" );
  6227. }
  6228. /*
  6229. idMatX::Inverse_UpdateRankOne
  6230. */
  6231. m1 = original;
  6232. m2 = original;
  6233. w.Random( size, 1 );
  6234. v.Random( size, 2 );
  6235. // invert m1
  6236. m1.Inverse_GaussJordan();
  6237. // modify and invert m2
  6238. m2.Update_RankOne( v, w, 1.0f );
  6239. if ( !m2.Inverse_GaussJordan() ) {
  6240. assert( 0 );
  6241. }
  6242. // update inverse of m1
  6243. m1.Inverse_UpdateRankOne( v, w, 1.0f );
  6244. if ( !m1.Compare( m2, 1e-4f ) ) {
  6245. idLib::common->Warning( "idMatX::Inverse_UpdateRankOne failed" );
  6246. }
  6247. /*
  6248. idMatX::Inverse_UpdateRowColumn
  6249. */
  6250. for ( offset = 0; offset < size; offset++ ) {
  6251. m1 = original;
  6252. m2 = original;
  6253. v.Random( size, 1 );
  6254. w.Random( size, 2 );
  6255. w[offset] = 0.0f;
  6256. // invert m1
  6257. m1.Inverse_GaussJordan();
  6258. // modify and invert m2
  6259. m2.Update_RowColumn( v, w, offset );
  6260. if ( !m2.Inverse_GaussJordan() ) {
  6261. assert( 0 );
  6262. }
  6263. // update inverse of m1
  6264. m1.Inverse_UpdateRowColumn( v, w, offset );
  6265. if ( !m1.Compare( m2, 1e-3f ) ) {
  6266. idLib::common->Warning( "idMatX::Inverse_UpdateRowColumn failed" );
  6267. }
  6268. }
  6269. /*
  6270. idMatX::Inverse_UpdateIncrement
  6271. */
  6272. m1 = original;
  6273. m2 = original;
  6274. v.Random( size + 1, 1 );
  6275. w.Random( size + 1, 2 );
  6276. w[size] = 0.0f;
  6277. // invert m1
  6278. m1.Inverse_GaussJordan();
  6279. // modify and invert m2
  6280. m2.Update_Increment( v, w );
  6281. if ( !m2.Inverse_GaussJordan() ) {
  6282. assert( 0 );
  6283. }
  6284. // update inverse of m1
  6285. m1.Inverse_UpdateIncrement( v, w );
  6286. if ( !m1.Compare( m2, 1e-4f ) ) {
  6287. idLib::common->Warning( "idMatX::Inverse_UpdateIncrement failed" );
  6288. }
  6289. /*
  6290. idMatX::Inverse_UpdateDecrement
  6291. */
  6292. for ( offset = 0; offset < size; offset++ ) {
  6293. m1 = original;
  6294. m2 = original;
  6295. v.SetSize( 6 );
  6296. w.SetSize( 6 );
  6297. for ( int i = 0; i < size; i++ ) {
  6298. v[i] = original[i][offset];
  6299. w[i] = original[offset][i];
  6300. }
  6301. // invert m1
  6302. m1.Inverse_GaussJordan();
  6303. // modify and invert m2
  6304. m2.Update_Decrement( offset );
  6305. if ( !m2.Inverse_GaussJordan() ) {
  6306. assert( 0 );
  6307. }
  6308. // update inverse of m1
  6309. m1.Inverse_UpdateDecrement( v, w, offset );
  6310. if ( !m1.Compare( m2, 1e-3f ) ) {
  6311. idLib::common->Warning( "idMatX::Inverse_UpdateDecrement failed" );
  6312. }
  6313. }
  6314. /*
  6315. idMatX::LU_Factor
  6316. */
  6317. m1 = original;
  6318. m1.LU_Factor( NULL ); // no pivoting
  6319. m1.LU_UnpackFactors( m2, m3 );
  6320. m1 = m2 * m3;
  6321. if ( !original.Compare( m1, 1e-4f ) ) {
  6322. idLib::common->Warning( "idMatX::LU_Factor failed" );
  6323. }
  6324. /*
  6325. idMatX::LU_UpdateRankOne
  6326. */
  6327. m1 = original;
  6328. m2 = original;
  6329. w.Random( size, 1 );
  6330. v.Random( size, 2 );
  6331. // factor m1
  6332. m1.LU_Factor( index1 );
  6333. // modify and factor m2
  6334. m2.Update_RankOne( v, w, 1.0f );
  6335. if ( !m2.LU_Factor( index2 ) ) {
  6336. assert( 0 );
  6337. }
  6338. m2.LU_MultiplyFactors( m3, index2 );
  6339. m2 = m3;
  6340. // update factored m1
  6341. m1.LU_UpdateRankOne( v, w, 1.0f, index1 );
  6342. m1.LU_MultiplyFactors( m3, index1 );
  6343. m1 = m3;
  6344. if ( !m1.Compare( m2, 1e-4f ) ) {
  6345. idLib::common->Warning( "idMatX::LU_UpdateRankOne failed" );
  6346. }
  6347. /*
  6348. idMatX::LU_UpdateRowColumn
  6349. */
  6350. for ( offset = 0; offset < size; offset++ ) {
  6351. m1 = original;
  6352. m2 = original;
  6353. v.Random( size, 1 );
  6354. w.Random( size, 2 );
  6355. w[offset] = 0.0f;
  6356. // factor m1
  6357. m1.LU_Factor( index1 );
  6358. // modify and factor m2
  6359. m2.Update_RowColumn( v, w, offset );
  6360. if ( !m2.LU_Factor( index2 ) ) {
  6361. assert( 0 );
  6362. }
  6363. m2.LU_MultiplyFactors( m3, index2 );
  6364. m2 = m3;
  6365. // update m1
  6366. m1.LU_UpdateRowColumn( v, w, offset, index1 );
  6367. m1.LU_MultiplyFactors( m3, index1 );
  6368. m1 = m3;
  6369. if ( !m1.Compare( m2, 1e-3f ) ) {
  6370. idLib::common->Warning( "idMatX::LU_UpdateRowColumn failed" );
  6371. }
  6372. }
  6373. /*
  6374. idMatX::LU_UpdateIncrement
  6375. */
  6376. m1 = original;
  6377. m2 = original;
  6378. v.Random( size + 1, 1 );
  6379. w.Random( size + 1, 2 );
  6380. w[size] = 0.0f;
  6381. // factor m1
  6382. m1.LU_Factor( index1 );
  6383. // modify and factor m2
  6384. m2.Update_Increment( v, w );
  6385. if ( !m2.LU_Factor( index2 ) ) {
  6386. assert( 0 );
  6387. }
  6388. m2.LU_MultiplyFactors( m3, index2 );
  6389. m2 = m3;
  6390. // update factored m1
  6391. m1.LU_UpdateIncrement( v, w, index1 );
  6392. m1.LU_MultiplyFactors( m3, index1 );
  6393. m1 = m3;
  6394. if ( !m1.Compare( m2, 1e-4f ) ) {
  6395. idLib::common->Warning( "idMatX::LU_UpdateIncrement failed" );
  6396. }
  6397. /*
  6398. idMatX::LU_UpdateDecrement
  6399. */
  6400. for ( offset = 0; offset < size; offset++ ) {
  6401. m1 = original;
  6402. m2 = original;
  6403. v.SetSize( 6 );
  6404. w.SetSize( 6 );
  6405. for ( int i = 0; i < size; i++ ) {
  6406. v[i] = original[i][offset];
  6407. w[i] = original[offset][i];
  6408. }
  6409. // factor m1
  6410. m1.LU_Factor( index1 );
  6411. // modify and factor m2
  6412. m2.Update_Decrement( offset );
  6413. if ( !m2.LU_Factor( index2 ) ) {
  6414. assert( 0 );
  6415. }
  6416. m2.LU_MultiplyFactors( m3, index2 );
  6417. m2 = m3;
  6418. u.SetSize( 6 );
  6419. for ( int i = 0; i < size; i++ ) {
  6420. u[i] = original[index1[offset]][i];
  6421. }
  6422. // update factors of m1
  6423. m1.LU_UpdateDecrement( v, w, u, offset, index1 );
  6424. m1.LU_MultiplyFactors( m3, index1 );
  6425. m1 = m3;
  6426. if ( !m1.Compare( m2, 1e-3f ) ) {
  6427. idLib::common->Warning( "idMatX::LU_UpdateDecrement failed" );
  6428. }
  6429. }
  6430. /*
  6431. idMatX::LU_Inverse
  6432. */
  6433. m2 = original;
  6434. m2.LU_Factor( NULL );
  6435. m2.LU_Inverse( m1, NULL );
  6436. m1 *= original;
  6437. if ( !m1.IsIdentity( 1e-4f ) ) {
  6438. idLib::common->Warning( "idMatX::LU_Inverse failed" );
  6439. }
  6440. /*
  6441. idMatX::QR_Factor
  6442. */
  6443. c.SetSize( size );
  6444. d.SetSize( size );
  6445. m1 = original;
  6446. m1.QR_Factor( c, d );
  6447. m1.QR_UnpackFactors( q1, r1, c, d );
  6448. m1 = q1 * r1;
  6449. if ( !original.Compare( m1, 1e-4f ) ) {
  6450. idLib::common->Warning( "idMatX::QR_Factor failed" );
  6451. }
  6452. /*
  6453. idMatX::QR_UpdateRankOne
  6454. */
  6455. c.SetSize( size );
  6456. d.SetSize( size );
  6457. m1 = original;
  6458. m2 = original;
  6459. w.Random( size, 0 );
  6460. v = w;
  6461. // factor m1
  6462. m1.QR_Factor( c, d );
  6463. m1.QR_UnpackFactors( q1, r1, c, d );
  6464. // modify and factor m2
  6465. m2.Update_RankOne( v, w, 1.0f );
  6466. if ( !m2.QR_Factor( c, d ) ) {
  6467. assert( 0 );
  6468. }
  6469. m2.QR_UnpackFactors( q2, r2, c, d );
  6470. m2 = q2 * r2;
  6471. // update factored m1
  6472. q1.QR_UpdateRankOne( r1, v, w, 1.0f );
  6473. m1 = q1 * r1;
  6474. if ( !m1.Compare( m2, 1e-4f ) ) {
  6475. idLib::common->Warning( "idMatX::QR_UpdateRankOne failed" );
  6476. }
  6477. /*
  6478. idMatX::QR_UpdateRowColumn
  6479. */
  6480. for ( offset = 0; offset < size; offset++ ) {
  6481. c.SetSize( size );
  6482. d.SetSize( size );
  6483. m1 = original;
  6484. m2 = original;
  6485. v.Random( size, 1 );
  6486. w.Random( size, 2 );
  6487. w[offset] = 0.0f;
  6488. // factor m1
  6489. m1.QR_Factor( c, d );
  6490. m1.QR_UnpackFactors( q1, r1, c, d );
  6491. // modify and factor m2
  6492. m2.Update_RowColumn( v, w, offset );
  6493. if ( !m2.QR_Factor( c, d ) ) {
  6494. assert( 0 );
  6495. }
  6496. m2.QR_UnpackFactors( q2, r2, c, d );
  6497. m2 = q2 * r2;
  6498. // update m1
  6499. q1.QR_UpdateRowColumn( r1, v, w, offset );
  6500. m1 = q1 * r1;
  6501. if ( !m1.Compare( m2, 1e-3f ) ) {
  6502. idLib::common->Warning( "idMatX::QR_UpdateRowColumn failed" );
  6503. }
  6504. }
  6505. /*
  6506. idMatX::QR_UpdateIncrement
  6507. */
  6508. c.SetSize( size+1 );
  6509. d.SetSize( size+1 );
  6510. m1 = original;
  6511. m2 = original;
  6512. v.Random( size + 1, 1 );
  6513. w.Random( size + 1, 2 );
  6514. w[size] = 0.0f;
  6515. // factor m1
  6516. m1.QR_Factor( c, d );
  6517. m1.QR_UnpackFactors( q1, r1, c, d );
  6518. // modify and factor m2
  6519. m2.Update_Increment( v, w );
  6520. if ( !m2.QR_Factor( c, d ) ) {
  6521. assert( 0 );
  6522. }
  6523. m2.QR_UnpackFactors( q2, r2, c, d );
  6524. m2 = q2 * r2;
  6525. // update factored m1
  6526. q1.QR_UpdateIncrement( r1, v, w );
  6527. m1 = q1 * r1;
  6528. if ( !m1.Compare( m2, 1e-4f ) ) {
  6529. idLib::common->Warning( "idMatX::QR_UpdateIncrement failed" );
  6530. }
  6531. /*
  6532. idMatX::QR_UpdateDecrement
  6533. */
  6534. for ( offset = 0; offset < size; offset++ ) {
  6535. c.SetSize( size+1 );
  6536. d.SetSize( size+1 );
  6537. m1 = original;
  6538. m2 = original;
  6539. v.SetSize( 6 );
  6540. w.SetSize( 6 );
  6541. for ( int i = 0; i < size; i++ ) {
  6542. v[i] = original[i][offset];
  6543. w[i] = original[offset][i];
  6544. }
  6545. // factor m1
  6546. m1.QR_Factor( c, d );
  6547. m1.QR_UnpackFactors( q1, r1, c, d );
  6548. // modify and factor m2
  6549. m2.Update_Decrement( offset );
  6550. if ( !m2.QR_Factor( c, d ) ) {
  6551. assert( 0 );
  6552. }
  6553. m2.QR_UnpackFactors( q2, r2, c, d );
  6554. m2 = q2 * r2;
  6555. // update factors of m1
  6556. q1.QR_UpdateDecrement( r1, v, w, offset );
  6557. m1 = q1 * r1;
  6558. if ( !m1.Compare( m2, 1e-3f ) ) {
  6559. idLib::common->Warning( "idMatX::QR_UpdateDecrement failed" );
  6560. }
  6561. }
  6562. /*
  6563. idMatX::QR_Inverse
  6564. */
  6565. m2 = original;
  6566. m2.QR_Factor( c, d );
  6567. m2.QR_Inverse( m1, c, d );
  6568. m1 *= original;
  6569. if ( !m1.IsIdentity( 1e-4f ) ) {
  6570. idLib::common->Warning( "idMatX::QR_Inverse failed" );
  6571. }
  6572. /*
  6573. idMatX::SVD_Factor
  6574. */
  6575. m1 = original;
  6576. m3.Zero( size, size );
  6577. w.Zero( size );
  6578. m1.SVD_Factor( w, m3 );
  6579. m2.Diag( w );
  6580. m3.TransposeSelf();
  6581. m1 = m1 * m2 * m3;
  6582. if ( !original.Compare( m1, 1e-4f ) ) {
  6583. idLib::common->Warning( "idMatX::SVD_Factor failed" );
  6584. }
  6585. /*
  6586. idMatX::SVD_Inverse
  6587. */
  6588. m2 = original;
  6589. m2.SVD_Factor( w, m3 );
  6590. m2.SVD_Inverse( m1, w, m3 );
  6591. m1 *= original;
  6592. if ( !m1.IsIdentity( 1e-4f ) ) {
  6593. idLib::common->Warning( "idMatX::SVD_Inverse failed" );
  6594. }
  6595. /*
  6596. idMatX::Cholesky_Factor
  6597. */
  6598. m1 = original;
  6599. m1.Cholesky_Factor();
  6600. m1.Cholesky_MultiplyFactors( m2 );
  6601. if ( !original.Compare( m2, 1e-4f ) ) {
  6602. idLib::common->Warning( "idMatX::Cholesky_Factor failed" );
  6603. }
  6604. /*
  6605. idMatX::Cholesky_UpdateRankOne
  6606. */
  6607. m1 = original;
  6608. m2 = original;
  6609. w.Random( size, 0 );
  6610. // factor m1
  6611. m1.Cholesky_Factor();
  6612. m1.ClearUpperTriangle();
  6613. // modify and factor m2
  6614. m2.Update_RankOneSymmetric( w, 1.0f );
  6615. if ( !m2.Cholesky_Factor() ) {
  6616. assert( 0 );
  6617. }
  6618. m2.ClearUpperTriangle();
  6619. // update factored m1
  6620. m1.Cholesky_UpdateRankOne( w, 1.0f, 0 );
  6621. if ( !m1.Compare( m2, 1e-4f ) ) {
  6622. idLib::common->Warning( "idMatX::Cholesky_UpdateRankOne failed" );
  6623. }
  6624. /*
  6625. idMatX::Cholesky_UpdateRowColumn
  6626. */
  6627. for ( offset = 0; offset < size; offset++ ) {
  6628. m1 = original;
  6629. m2 = original;
  6630. // factor m1
  6631. m1.Cholesky_Factor();
  6632. m1.ClearUpperTriangle();
  6633. int pdtable[] = { 1, 0, 1, 0, 0, 0 };
  6634. w.Random( size, pdtable[offset] );
  6635. w *= 0.1f;
  6636. // modify and factor m2
  6637. m2.Update_RowColumnSymmetric( w, offset );
  6638. if ( !m2.Cholesky_Factor() ) {
  6639. assert( 0 );
  6640. }
  6641. m2.ClearUpperTriangle();
  6642. // update m1
  6643. m1.Cholesky_UpdateRowColumn( w, offset );
  6644. if ( !m1.Compare( m2, 1e-3f ) ) {
  6645. idLib::common->Warning( "idMatX::Cholesky_UpdateRowColumn failed" );
  6646. }
  6647. }
  6648. /*
  6649. idMatX::Cholesky_UpdateIncrement
  6650. */
  6651. m1.Random( size + 1, size + 1, 0 );
  6652. m3 = m1 * m1.Transpose();
  6653. m1.SquareSubMatrix( m3, size );
  6654. m2 = m1;
  6655. w.SetSize( size + 1 );
  6656. for ( int i = 0; i < size + 1; i++ ) {
  6657. w[i] = m3[size][i];
  6658. }
  6659. // factor m1
  6660. m1.Cholesky_Factor();
  6661. // modify and factor m2
  6662. m2.Update_IncrementSymmetric( w );
  6663. if ( !m2.Cholesky_Factor() ) {
  6664. assert( 0 );
  6665. }
  6666. // update factored m1
  6667. m1.Cholesky_UpdateIncrement( w );
  6668. m1.ClearUpperTriangle();
  6669. m2.ClearUpperTriangle();
  6670. if ( !m1.Compare( m2, 1e-4f ) ) {
  6671. idLib::common->Warning( "idMatX::Cholesky_UpdateIncrement failed" );
  6672. }
  6673. /*
  6674. idMatX::Cholesky_UpdateDecrement
  6675. */
  6676. for ( offset = 0; offset < size; offset += size - 1 ) {
  6677. m1 = original;
  6678. m2 = original;
  6679. v.SetSize( 6 );
  6680. for ( int i = 0; i < size; i++ ) {
  6681. v[i] = original[i][offset];
  6682. }
  6683. // factor m1
  6684. m1.Cholesky_Factor();
  6685. // modify and factor m2
  6686. m2.Update_Decrement( offset );
  6687. if ( !m2.Cholesky_Factor() ) {
  6688. assert( 0 );
  6689. }
  6690. // update factors of m1
  6691. m1.Cholesky_UpdateDecrement( v, offset );
  6692. if ( !m1.Compare( m2, 1e-3f ) ) {
  6693. idLib::common->Warning( "idMatX::Cholesky_UpdateDecrement failed" );
  6694. }
  6695. }
  6696. /*
  6697. idMatX::Cholesky_Inverse
  6698. */
  6699. m2 = original;
  6700. m2.Cholesky_Factor();
  6701. m2.Cholesky_Inverse( m1 );
  6702. m1 *= original;
  6703. if ( !m1.IsIdentity( 1e-4f ) ) {
  6704. idLib::common->Warning( "idMatX::Cholesky_Inverse failed" );
  6705. }
  6706. /*
  6707. idMatX::LDLT_Factor
  6708. */
  6709. m1 = original;
  6710. m1.LDLT_Factor();
  6711. m1.LDLT_MultiplyFactors( m2 );
  6712. if ( !original.Compare( m2, 1e-4f ) ) {
  6713. idLib::common->Warning( "idMatX::LDLT_Factor failed" );
  6714. }
  6715. m1.LDLT_UnpackFactors( m2, m3 );
  6716. m2 = m2 * m3 * m2.Transpose();
  6717. if ( !original.Compare( m2, 1e-4f ) ) {
  6718. idLib::common->Warning( "idMatX::LDLT_Factor failed" );
  6719. }
  6720. /*
  6721. idMatX::LDLT_UpdateRankOne
  6722. */
  6723. m1 = original;
  6724. m2 = original;
  6725. w.Random( size, 0 );
  6726. // factor m1
  6727. m1.LDLT_Factor();
  6728. m1.ClearUpperTriangle();
  6729. // modify and factor m2
  6730. m2.Update_RankOneSymmetric( w, 1.0f );
  6731. if ( !m2.LDLT_Factor() ) {
  6732. assert( 0 );
  6733. }
  6734. m2.ClearUpperTriangle();
  6735. // update factored m1
  6736. m1.LDLT_UpdateRankOne( w, 1.0f, 0 );
  6737. if ( !m1.Compare( m2, 1e-4f ) ) {
  6738. idLib::common->Warning( "idMatX::LDLT_UpdateRankOne failed" );
  6739. }
  6740. /*
  6741. idMatX::LDLT_UpdateRowColumn
  6742. */
  6743. for ( offset = 0; offset < size; offset++ ) {
  6744. m1 = original;
  6745. m2 = original;
  6746. w.Random( size, 0 );
  6747. // factor m1
  6748. m1.LDLT_Factor();
  6749. m1.ClearUpperTriangle();
  6750. // modify and factor m2
  6751. m2.Update_RowColumnSymmetric( w, offset );
  6752. if ( !m2.LDLT_Factor() ) {
  6753. assert( 0 );
  6754. }
  6755. m2.ClearUpperTriangle();
  6756. // update m1
  6757. m1.LDLT_UpdateRowColumn( w, offset );
  6758. if ( !m1.Compare( m2, 1e-3f ) ) {
  6759. idLib::common->Warning( "idMatX::LDLT_UpdateRowColumn failed" );
  6760. }
  6761. }
  6762. /*
  6763. idMatX::LDLT_UpdateIncrement
  6764. */
  6765. m1.Random( size + 1, size + 1, 0 );
  6766. m3 = m1 * m1.Transpose();
  6767. m1.SquareSubMatrix( m3, size );
  6768. m2 = m1;
  6769. w.SetSize( size + 1 );
  6770. for ( int i = 0; i < size + 1; i++ ) {
  6771. w[i] = m3[size][i];
  6772. }
  6773. // factor m1
  6774. m1.LDLT_Factor();
  6775. // modify and factor m2
  6776. m2.Update_IncrementSymmetric( w );
  6777. if ( !m2.LDLT_Factor() ) {
  6778. assert( 0 );
  6779. }
  6780. // update factored m1
  6781. m1.LDLT_UpdateIncrement( w );
  6782. m1.ClearUpperTriangle();
  6783. m2.ClearUpperTriangle();
  6784. if ( !m1.Compare( m2, 1e-4f ) ) {
  6785. idLib::common->Warning( "idMatX::LDLT_UpdateIncrement failed" );
  6786. }
  6787. /*
  6788. idMatX::LDLT_UpdateDecrement
  6789. */
  6790. for ( offset = 0; offset < size; offset++ ) {
  6791. m1 = original;
  6792. m2 = original;
  6793. v.SetSize( 6 );
  6794. for ( int i = 0; i < size; i++ ) {
  6795. v[i] = original[i][offset];
  6796. }
  6797. // factor m1
  6798. m1.LDLT_Factor();
  6799. // modify and factor m2
  6800. m2.Update_Decrement( offset );
  6801. if ( !m2.LDLT_Factor() ) {
  6802. assert( 0 );
  6803. }
  6804. // update factors of m1
  6805. m1.LDLT_UpdateDecrement( v, offset );
  6806. if ( !m1.Compare( m2, 1e-3f ) ) {
  6807. idLib::common->Warning( "idMatX::LDLT_UpdateDecrement failed" );
  6808. }
  6809. }
  6810. /*
  6811. idMatX::LDLT_Inverse
  6812. */
  6813. m2 = original;
  6814. m2.LDLT_Factor();
  6815. m2.LDLT_Inverse( m1 );
  6816. m1 *= original;
  6817. if ( !m1.IsIdentity( 1e-4f ) ) {
  6818. idLib::common->Warning( "idMatX::LDLT_Inverse failed" );
  6819. }
  6820. /*
  6821. idMatX::Eigen_SolveSymmetricTriDiagonal
  6822. */
  6823. m3 = original;
  6824. m3.TriDiagonal_ClearTriangles();
  6825. m1 = m3;
  6826. v.SetSize( size );
  6827. m1.Eigen_SolveSymmetricTriDiagonal( v );
  6828. m3.TransposeMultiply( m2, m1 );
  6829. for ( int i = 0; i < size; i++ ) {
  6830. for ( int j = 0; j < size; j++ ) {
  6831. m1[i][j] *= v[j];
  6832. }
  6833. }
  6834. if ( !m1.Compare( m2, 1e-4f ) ) {
  6835. idLib::common->Warning( "idMatX::Eigen_SolveSymmetricTriDiagonal failed" );
  6836. }
  6837. /*
  6838. idMatX::Eigen_SolveSymmetric
  6839. */
  6840. m3 = original;
  6841. m1 = m3;
  6842. v.SetSize( size );
  6843. m1.Eigen_SolveSymmetric( v );
  6844. m3.TransposeMultiply( m2, m1 );
  6845. for ( int i = 0; i < size; i++ ) {
  6846. for ( int j = 0; j < size; j++ ) {
  6847. m1[i][j] *= v[j];
  6848. }
  6849. }
  6850. if ( !m1.Compare( m2, 1e-4f ) ) {
  6851. idLib::common->Warning( "idMatX::Eigen_SolveSymmetric failed" );
  6852. }
  6853. /*
  6854. idMatX::Eigen_Solve
  6855. */
  6856. m3 = original;
  6857. m1 = m3;
  6858. v.SetSize( size );
  6859. w.SetSize( size );
  6860. m1.Eigen_Solve( v, w );
  6861. m3.TransposeMultiply( m2, m1 );
  6862. for ( int i = 0; i < size; i++ ) {
  6863. for ( int j = 0; j < size; j++ ) {
  6864. m1[i][j] *= v[j];
  6865. }
  6866. }
  6867. if ( !m1.Compare( m2, 1e-4f ) ) {
  6868. idLib::common->Warning( "idMatX::Eigen_Solve failed" );
  6869. }
  6870. }