NvFloatMath.inl 125 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607
  1. // a set of routines that let you do common 3d math
  2. // operations without any vector, matrix, or quaternion
  3. // classes or templates.
  4. //
  5. // a vector (or point) is a 'NxF32 *' to 3 floating point numbers.
  6. // a matrix is a 'NxF32 *' to an array of 16 floating point numbers representing a 4x4 transformation matrix compatible with D3D or OGL
  7. // a quaternion is a 'NxF32 *' to 4 floats representing a quaternion x,y,z,w
  8. //
  9. //
  10. /*!
  11. **
  12. ** Copyright (c) 2009 by John W. Ratcliff mailto:[email protected]
  13. **
  14. ** Portions of this source has been released with the PhysXViewer application, as well as
  15. ** Rocket, CreateDynamics, ODF, and as a number of sample code snippets.
  16. **
  17. ** If you find this code useful or you are feeling particularily generous I would
  18. ** ask that you please go to http://www.amillionpixels.us and make a donation
  19. ** to Troy DeMolay.
  20. **
  21. ** DeMolay is a youth group for young men between the ages of 12 and 21.
  22. ** It teaches strong moral principles, as well as leadership skills and
  23. ** public speaking. The donations page uses the 'pay for pixels' paradigm
  24. ** where, in this case, a pixel is only a single penny. Donations can be
  25. ** made for as small as $4 or as high as a $100 block. Each person who donates
  26. ** will get a link to their own site as well as acknowledgement on the
  27. ** donations blog located here http://www.amillionpixels.blogspot.com/
  28. **
  29. ** If you wish to contact me you can use the following methods:
  30. **
  31. ** Skype ID: jratcliff63367
  32. ** Yahoo: jratcliff63367
  33. ** AOL: jratcliff1961
  34. ** email: [email protected]
  35. **
  36. **
  37. ** The MIT license:
  38. **
  39. ** Permission is hereby granted, free of charge, to any person obtaining a copy
  40. ** of this software and associated documentation files (the "Software"), to deal
  41. ** in the Software without restriction, including without limitation the rights
  42. ** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  43. ** copies of the Software, and to permit persons to whom the Software is furnished
  44. ** to do so, subject to the following conditions:
  45. **
  46. ** The above copyright notice and this permission notice shall be included in all
  47. ** copies or substantial portions of the Software.
  48. ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  49. ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  50. ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  51. ** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  52. ** WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  53. ** CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  54. */
  55. #pragma warning(disable:4996)
  56. #include "NvUserMemAlloc.h"
  57. #include "NvHashMap.h"
  58. namespace CONVEX_DECOMPOSITION
  59. {
  60. void fm_inverseRT(const REAL matrix[16],const REAL pos[3],REAL t[3]) // inverse rotate translate the point.
  61. {
  62. REAL _x = pos[0] - matrix[3*4+0];
  63. REAL _y = pos[1] - matrix[3*4+1];
  64. REAL _z = pos[2] - matrix[3*4+2];
  65. // Multiply inverse-translated source vector by inverted rotation transform
  66. t[0] = (matrix[0*4+0] * _x) + (matrix[0*4+1] * _y) + (matrix[0*4+2] * _z);
  67. t[1] = (matrix[1*4+0] * _x) + (matrix[1*4+1] * _y) + (matrix[1*4+2] * _z);
  68. t[2] = (matrix[2*4+0] * _x) + (matrix[2*4+1] * _y) + (matrix[2*4+2] * _z);
  69. }
  70. REAL fm_getDeterminant(const REAL matrix[16])
  71. {
  72. REAL tempv[3];
  73. REAL p0[3];
  74. REAL p1[3];
  75. REAL p2[3];
  76. p0[0] = matrix[0*4+0];
  77. p0[1] = matrix[0*4+1];
  78. p0[2] = matrix[0*4+2];
  79. p1[0] = matrix[1*4+0];
  80. p1[1] = matrix[1*4+1];
  81. p1[2] = matrix[1*4+2];
  82. p2[0] = matrix[2*4+0];
  83. p2[1] = matrix[2*4+1];
  84. p2[2] = matrix[2*4+2];
  85. fm_cross(tempv,p1,p2);
  86. return fm_dot(p0,tempv);
  87. }
  88. REAL fm_squared(REAL x) { return x*x; };
  89. void fm_decomposeTransform(const REAL local_transform[16],REAL trans[3],REAL rot[4],REAL scale[3])
  90. {
  91. trans[0] = local_transform[12];
  92. trans[1] = local_transform[13];
  93. trans[2] = local_transform[14];
  94. scale[0] = sqrt(fm_squared(local_transform[0*4+0]) + fm_squared(local_transform[0*4+1]) + fm_squared(local_transform[0*4+2]));
  95. scale[1] = sqrt(fm_squared(local_transform[1*4+0]) + fm_squared(local_transform[1*4+1]) + fm_squared(local_transform[1*4+2]));
  96. scale[2] = sqrt(fm_squared(local_transform[2*4+0]) + fm_squared(local_transform[2*4+1]) + fm_squared(local_transform[2*4+2]));
  97. REAL m[16];
  98. memcpy(m,local_transform,sizeof(REAL)*16);
  99. REAL sx = 1.0f / scale[0];
  100. REAL sy = 1.0f / scale[1];
  101. REAL sz = 1.0f / scale[2];
  102. m[0*4+0]*=sx;
  103. m[0*4+1]*=sx;
  104. m[0*4+2]*=sx;
  105. m[1*4+0]*=sy;
  106. m[1*4+1]*=sy;
  107. m[1*4+2]*=sy;
  108. m[2*4+0]*=sz;
  109. m[2*4+1]*=sz;
  110. m[2*4+2]*=sz;
  111. fm_matrixToQuat(m,rot);
  112. }
  113. void fm_getSubMatrix(NxI32 ki,NxI32 kj,REAL pDst[16],const REAL matrix[16])
  114. {
  115. NxI32 row, col;
  116. NxI32 dstCol = 0, dstRow = 0;
  117. for ( col = 0; col < 4; col++ )
  118. {
  119. if ( col == kj )
  120. {
  121. continue;
  122. }
  123. for ( dstRow = 0, row = 0; row < 4; row++ )
  124. {
  125. if ( row == ki )
  126. {
  127. continue;
  128. }
  129. pDst[dstCol*4+dstRow] = matrix[col*4+row];
  130. dstRow++;
  131. }
  132. dstCol++;
  133. }
  134. }
  135. void fm_inverseTransform(const REAL matrix[16],REAL inverse_matrix[16])
  136. {
  137. REAL determinant = fm_getDeterminant(matrix);
  138. determinant = 1.0f / determinant;
  139. for (NxI32 i = 0; i < 4; i++ )
  140. {
  141. for (NxI32 j = 0; j < 4; j++ )
  142. {
  143. NxI32 sign = 1 - ( ( i + j ) % 2 ) * 2;
  144. REAL subMat[16];
  145. fm_identity(subMat);
  146. fm_getSubMatrix( i, j, subMat, matrix );
  147. REAL subDeterminant = fm_getDeterminant(subMat);
  148. inverse_matrix[i*4+j] = ( subDeterminant * sign ) * determinant;
  149. }
  150. }
  151. }
  152. void fm_identity(REAL matrix[16]) // set 4x4 matrix to identity.
  153. {
  154. matrix[0*4+0] = 1;
  155. matrix[1*4+1] = 1;
  156. matrix[2*4+2] = 1;
  157. matrix[3*4+3] = 1;
  158. matrix[1*4+0] = 0;
  159. matrix[2*4+0] = 0;
  160. matrix[3*4+0] = 0;
  161. matrix[0*4+1] = 0;
  162. matrix[2*4+1] = 0;
  163. matrix[3*4+1] = 0;
  164. matrix[0*4+2] = 0;
  165. matrix[1*4+2] = 0;
  166. matrix[3*4+2] = 0;
  167. matrix[0*4+3] = 0;
  168. matrix[1*4+3] = 0;
  169. matrix[2*4+3] = 0;
  170. }
  171. void fm_quatToEuler(const REAL quat[4],REAL &ax,REAL &ay,REAL &az)
  172. {
  173. REAL x = quat[0];
  174. REAL y = quat[1];
  175. REAL z = quat[2];
  176. REAL w = quat[3];
  177. REAL sint = (2.0f * w * y) - (2.0f * x * z);
  178. REAL cost_temp = 1.0f - (sint * sint);
  179. REAL cost = 0;
  180. if ( (REAL)fabs(cost_temp) > 0.001f )
  181. {
  182. cost = sqrt( cost_temp );
  183. }
  184. REAL sinv, cosv, sinf, cosf;
  185. if ( (REAL)fabs(cost) > 0.001f )
  186. {
  187. cost = 1.0f / cost;
  188. sinv = ((2.0f * y * z) + (2.0f * w * x)) * cost;
  189. cosv = (1.0f - (2.0f * x * x) - (2.0f * y * y)) * cost;
  190. sinf = ((2.0f * x * y) + (2.0f * w * z)) * cost;
  191. cosf = (1.0f - (2.0f * y * y) - (2.0f * z * z)) * cost;
  192. }
  193. else
  194. {
  195. sinv = (2.0f * w * x) - (2.0f * y * z);
  196. cosv = 1.0f - (2.0f * x * x) - (2.0f * z * z);
  197. sinf = 0;
  198. cosf = 1.0f;
  199. }
  200. // compute output rotations
  201. ax = atan2( sinv, cosv );
  202. ay = atan2( sint, cost );
  203. az = atan2( sinf, cosf );
  204. }
  205. void fm_eulerToMatrix(REAL ax,REAL ay,REAL az,REAL *matrix) // convert euler (in radians) to a dest 4x4 matrix (translation set to zero)
  206. {
  207. REAL quat[4];
  208. fm_eulerToQuat(ax,ay,az,quat);
  209. fm_quatToMatrix(quat,matrix);
  210. }
  211. void fm_getAABB(NxU32 vcount,const REAL *points,NxU32 pstride,REAL *bmin,REAL *bmax)
  212. {
  213. const NxU8 *source = (const NxU8 *) points;
  214. bmin[0] = points[0];
  215. bmin[1] = points[1];
  216. bmin[2] = points[2];
  217. bmax[0] = points[0];
  218. bmax[1] = points[1];
  219. bmax[2] = points[2];
  220. for (NxU32 i=1; i<vcount; i++)
  221. {
  222. source+=pstride;
  223. const REAL *p = (const REAL *) source;
  224. if ( p[0] < bmin[0] ) bmin[0] = p[0];
  225. if ( p[1] < bmin[1] ) bmin[1] = p[1];
  226. if ( p[2] < bmin[2] ) bmin[2] = p[2];
  227. if ( p[0] > bmax[0] ) bmax[0] = p[0];
  228. if ( p[1] > bmax[1] ) bmax[1] = p[1];
  229. if ( p[2] > bmax[2] ) bmax[2] = p[2];
  230. }
  231. }
  232. void fm_eulerToQuat(const REAL *euler,REAL *quat) // convert euler angles to quaternion.
  233. {
  234. fm_eulerToQuat(euler[0],euler[1],euler[2],quat);
  235. }
  236. void fm_eulerToQuat(REAL roll,REAL pitch,REAL yaw,REAL *quat) // convert euler angles to quaternion.
  237. {
  238. roll *= 0.5f;
  239. pitch *= 0.5f;
  240. yaw *= 0.5f;
  241. REAL cr = cos(roll);
  242. REAL cp = cos(pitch);
  243. REAL cy = cos(yaw);
  244. REAL sr = sin(roll);
  245. REAL sp = sin(pitch);
  246. REAL sy = sin(yaw);
  247. REAL cpcy = cp * cy;
  248. REAL spsy = sp * sy;
  249. REAL spcy = sp * cy;
  250. REAL cpsy = cp * sy;
  251. quat[0] = ( sr * cpcy - cr * spsy);
  252. quat[1] = ( cr * spcy + sr * cpsy);
  253. quat[2] = ( cr * cpsy - sr * spcy);
  254. quat[3] = cr * cpcy + sr * spsy;
  255. }
  256. void fm_quatToMatrix(const REAL *quat,REAL *matrix) // convert quaterinion rotation to matrix, zeros out the translation component.
  257. {
  258. REAL xx = quat[0]*quat[0];
  259. REAL yy = quat[1]*quat[1];
  260. REAL zz = quat[2]*quat[2];
  261. REAL xy = quat[0]*quat[1];
  262. REAL xz = quat[0]*quat[2];
  263. REAL yz = quat[1]*quat[2];
  264. REAL wx = quat[3]*quat[0];
  265. REAL wy = quat[3]*quat[1];
  266. REAL wz = quat[3]*quat[2];
  267. matrix[0*4+0] = 1 - 2 * ( yy + zz );
  268. matrix[1*4+0] = 2 * ( xy - wz );
  269. matrix[2*4+0] = 2 * ( xz + wy );
  270. matrix[0*4+1] = 2 * ( xy + wz );
  271. matrix[1*4+1] = 1 - 2 * ( xx + zz );
  272. matrix[2*4+1] = 2 * ( yz - wx );
  273. matrix[0*4+2] = 2 * ( xz - wy );
  274. matrix[1*4+2] = 2 * ( yz + wx );
  275. matrix[2*4+2] = 1 - 2 * ( xx + yy );
  276. matrix[3*4+0] = matrix[3*4+1] = matrix[3*4+2] = (REAL) 0.0f;
  277. matrix[0*4+3] = matrix[1*4+3] = matrix[2*4+3] = (REAL) 0.0f;
  278. matrix[3*4+3] =(REAL) 1.0f;
  279. }
  280. void fm_quatRotate(const REAL *quat,const REAL *v,REAL *r) // rotate a vector directly by a quaternion.
  281. {
  282. REAL left[4];
  283. left[0] = quat[3]*v[0] + quat[1]*v[2] - v[1]*quat[2];
  284. left[1] = quat[3]*v[1] + quat[2]*v[0] - v[2]*quat[0];
  285. left[2] = quat[3]*v[2] + quat[0]*v[1] - v[0]*quat[1];
  286. left[3] = - quat[0]*v[0] - quat[1]*v[1] - quat[2]*v[2];
  287. r[0] = (left[3]*-quat[0]) + (quat[3]*left[0]) + (left[1]*-quat[2]) - (-quat[1]*left[2]);
  288. r[1] = (left[3]*-quat[1]) + (quat[3]*left[1]) + (left[2]*-quat[0]) - (-quat[2]*left[0]);
  289. r[2] = (left[3]*-quat[2]) + (quat[3]*left[2]) + (left[0]*-quat[1]) - (-quat[0]*left[1]);
  290. }
  291. void fm_getTranslation(const REAL *matrix,REAL *t)
  292. {
  293. t[0] = matrix[3*4+0];
  294. t[1] = matrix[3*4+1];
  295. t[2] = matrix[3*4+2];
  296. }
  297. void fm_matrixToQuat(const REAL *matrix,REAL *quat) // convert the 3x3 portion of a 4x4 matrix into a quaterion as x,y,z,w
  298. {
  299. REAL tr = matrix[0*4+0] + matrix[1*4+1] + matrix[2*4+2];
  300. // check the diagonal
  301. if (tr > 0.0f )
  302. {
  303. REAL s = (REAL) sqrt ( (NxF64) (tr + 1.0f) );
  304. quat[3] = s * 0.5f;
  305. s = 0.5f / s;
  306. quat[0] = (matrix[1*4+2] - matrix[2*4+1]) * s;
  307. quat[1] = (matrix[2*4+0] - matrix[0*4+2]) * s;
  308. quat[2] = (matrix[0*4+1] - matrix[1*4+0]) * s;
  309. }
  310. else
  311. {
  312. // diagonal is negative
  313. NxI32 nxt[3] = {1, 2, 0};
  314. REAL qa[4];
  315. NxI32 i = 0;
  316. if (matrix[1*4+1] > matrix[0*4+0]) i = 1;
  317. if (matrix[2*4+2] > matrix[i*4+i]) i = 2;
  318. NxI32 j = nxt[i];
  319. NxI32 k = nxt[j];
  320. REAL s = sqrt ( ((matrix[i*4+i] - (matrix[j*4+j] + matrix[k*4+k])) + 1.0f) );
  321. qa[i] = s * 0.5f;
  322. if (s != 0.0f ) s = 0.5f / s;
  323. qa[3] = (matrix[j*4+k] - matrix[k*4+j]) * s;
  324. qa[j] = (matrix[i*4+j] + matrix[j*4+i]) * s;
  325. qa[k] = (matrix[i*4+k] + matrix[k*4+i]) * s;
  326. quat[0] = qa[0];
  327. quat[1] = qa[1];
  328. quat[2] = qa[2];
  329. quat[3] = qa[3];
  330. }
  331. }
  332. REAL fm_sphereVolume(REAL radius) // return's the volume of a sphere of this radius (4/3 PI * R cubed )
  333. {
  334. return (4.0f / 3.0f ) * FM_PI * radius * radius * radius;
  335. }
  336. REAL fm_cylinderVolume(REAL radius,REAL h)
  337. {
  338. return FM_PI * radius * radius *h;
  339. }
  340. REAL fm_capsuleVolume(REAL radius,REAL h)
  341. {
  342. REAL volume = fm_sphereVolume(radius); // volume of the sphere portion.
  343. REAL ch = h-radius*2; // this is the cylinder length
  344. if ( ch > 0 )
  345. {
  346. volume+=fm_cylinderVolume(radius,ch);
  347. }
  348. return volume;
  349. }
  350. void fm_transform(const REAL matrix[16],const REAL v[3],REAL t[3]) // rotate and translate this point
  351. {
  352. if ( matrix )
  353. {
  354. REAL tx = (matrix[0*4+0] * v[0]) + (matrix[1*4+0] * v[1]) + (matrix[2*4+0] * v[2]) + matrix[3*4+0];
  355. REAL ty = (matrix[0*4+1] * v[0]) + (matrix[1*4+1] * v[1]) + (matrix[2*4+1] * v[2]) + matrix[3*4+1];
  356. REAL tz = (matrix[0*4+2] * v[0]) + (matrix[1*4+2] * v[1]) + (matrix[2*4+2] * v[2]) + matrix[3*4+2];
  357. t[0] = tx;
  358. t[1] = ty;
  359. t[2] = tz;
  360. }
  361. else
  362. {
  363. t[0] = v[0];
  364. t[1] = v[1];
  365. t[2] = v[2];
  366. }
  367. }
  368. void fm_rotate(const REAL matrix[16],const REAL v[3],REAL t[3]) // rotate and translate this point
  369. {
  370. if ( matrix )
  371. {
  372. REAL tx = (matrix[0*4+0] * v[0]) + (matrix[1*4+0] * v[1]) + (matrix[2*4+0] * v[2]);
  373. REAL ty = (matrix[0*4+1] * v[0]) + (matrix[1*4+1] * v[1]) + (matrix[2*4+1] * v[2]);
  374. REAL tz = (matrix[0*4+2] * v[0]) + (matrix[1*4+2] * v[1]) + (matrix[2*4+2] * v[2]);
  375. t[0] = tx;
  376. t[1] = ty;
  377. t[2] = tz;
  378. }
  379. else
  380. {
  381. t[0] = v[0];
  382. t[1] = v[1];
  383. t[2] = v[2];
  384. }
  385. }
  386. REAL fm_distance(const REAL *p1,const REAL *p2)
  387. {
  388. REAL dx = p1[0] - p2[0];
  389. REAL dy = p1[1] - p2[1];
  390. REAL dz = p1[2] - p2[2];
  391. return sqrt( dx*dx + dy*dy + dz *dz );
  392. }
  393. REAL fm_distanceSquared(const REAL *p1,const REAL *p2)
  394. {
  395. REAL dx = p1[0] - p2[0];
  396. REAL dy = p1[1] - p2[1];
  397. REAL dz = p1[2] - p2[2];
  398. return dx*dx + dy*dy + dz *dz;
  399. }
  400. REAL fm_distanceSquaredXZ(const REAL *p1,const REAL *p2)
  401. {
  402. REAL dx = p1[0] - p2[0];
  403. REAL dz = p1[2] - p2[2];
  404. return dx*dx + dz *dz;
  405. }
  406. REAL fm_computePlane(const REAL *A,const REAL *B,const REAL *C,REAL *n) // returns D
  407. {
  408. REAL vx = (B[0] - C[0]);
  409. REAL vy = (B[1] - C[1]);
  410. REAL vz = (B[2] - C[2]);
  411. REAL wx = (A[0] - B[0]);
  412. REAL wy = (A[1] - B[1]);
  413. REAL wz = (A[2] - B[2]);
  414. REAL vw_x = vy * wz - vz * wy;
  415. REAL vw_y = vz * wx - vx * wz;
  416. REAL vw_z = vx * wy - vy * wx;
  417. REAL mag = sqrt((vw_x * vw_x) + (vw_y * vw_y) + (vw_z * vw_z));
  418. if ( mag < 0.000001f )
  419. {
  420. mag = 0;
  421. }
  422. else
  423. {
  424. mag = 1.0f/mag;
  425. }
  426. REAL x = vw_x * mag;
  427. REAL y = vw_y * mag;
  428. REAL z = vw_z * mag;
  429. REAL D = 0.0f - ((x*A[0])+(y*A[1])+(z*A[2]));
  430. n[0] = x;
  431. n[1] = y;
  432. n[2] = z;
  433. return D;
  434. }
  435. REAL fm_distToPlane(const REAL *plane,const REAL *p) // computes the distance of this point from the plane.
  436. {
  437. return p[0]*plane[0]+p[1]*plane[1]+p[2]*plane[2]+plane[3];
  438. }
  439. REAL fm_dot(const REAL *p1,const REAL *p2)
  440. {
  441. return p1[0]*p2[0]+p1[1]*p2[1]+p1[2]*p2[2];
  442. }
  443. void fm_cross(REAL *cross,const REAL *a,const REAL *b)
  444. {
  445. cross[0] = a[1]*b[2] - a[2]*b[1];
  446. cross[1] = a[2]*b[0] - a[0]*b[2];
  447. cross[2] = a[0]*b[1] - a[1]*b[0];
  448. }
  449. void fm_computeNormalVector(REAL *n,const REAL *p1,const REAL *p2)
  450. {
  451. n[0] = p2[0] - p1[0];
  452. n[1] = p2[1] - p1[1];
  453. n[2] = p2[2] - p1[2];
  454. fm_normalize(n);
  455. }
  456. bool fm_computeWindingOrder(const REAL *p1,const REAL *p2,const REAL *p3) // returns true if the triangle is clockwise.
  457. {
  458. bool ret = false;
  459. REAL v1[3];
  460. REAL v2[3];
  461. fm_computeNormalVector(v1,p1,p2); // p2-p1 (as vector) and then normalized
  462. fm_computeNormalVector(v2,p1,p3); // p3-p1 (as vector) and then normalized
  463. REAL cross[3];
  464. fm_cross(cross, v1, v2 );
  465. REAL ref[3] = { 1, 0, 0 };
  466. REAL d = fm_dot( cross, ref );
  467. if ( d <= 0 )
  468. ret = false;
  469. else
  470. ret = true;
  471. return ret;
  472. }
  473. REAL fm_normalize(REAL *n) // normalize this vector
  474. {
  475. REAL dist = (REAL)sqrt(n[0]*n[0] + n[1]*n[1] + n[2]*n[2]);
  476. if ( dist > 0.0000001f )
  477. {
  478. REAL mag = 1.0f / dist;
  479. n[0]*=mag;
  480. n[1]*=mag;
  481. n[2]*=mag;
  482. }
  483. else
  484. {
  485. n[0] = 1;
  486. n[1] = 0;
  487. n[2] = 0;
  488. }
  489. return dist;
  490. }
  491. void fm_matrixMultiply(const REAL *pA,const REAL *pB,REAL *pM)
  492. {
  493. #if 1
  494. REAL a = pA[0*4+0] * pB[0*4+0] + pA[0*4+1] * pB[1*4+0] + pA[0*4+2] * pB[2*4+0] + pA[0*4+3] * pB[3*4+0];
  495. REAL b = pA[0*4+0] * pB[0*4+1] + pA[0*4+1] * pB[1*4+1] + pA[0*4+2] * pB[2*4+1] + pA[0*4+3] * pB[3*4+1];
  496. REAL c = pA[0*4+0] * pB[0*4+2] + pA[0*4+1] * pB[1*4+2] + pA[0*4+2] * pB[2*4+2] + pA[0*4+3] * pB[3*4+2];
  497. REAL d = pA[0*4+0] * pB[0*4+3] + pA[0*4+1] * pB[1*4+3] + pA[0*4+2] * pB[2*4+3] + pA[0*4+3] * pB[3*4+3];
  498. REAL e = pA[1*4+0] * pB[0*4+0] + pA[1*4+1] * pB[1*4+0] + pA[1*4+2] * pB[2*4+0] + pA[1*4+3] * pB[3*4+0];
  499. REAL f = pA[1*4+0] * pB[0*4+1] + pA[1*4+1] * pB[1*4+1] + pA[1*4+2] * pB[2*4+1] + pA[1*4+3] * pB[3*4+1];
  500. REAL g = pA[1*4+0] * pB[0*4+2] + pA[1*4+1] * pB[1*4+2] + pA[1*4+2] * pB[2*4+2] + pA[1*4+3] * pB[3*4+2];
  501. REAL h = pA[1*4+0] * pB[0*4+3] + pA[1*4+1] * pB[1*4+3] + pA[1*4+2] * pB[2*4+3] + pA[1*4+3] * pB[3*4+3];
  502. REAL i = pA[2*4+0] * pB[0*4+0] + pA[2*4+1] * pB[1*4+0] + pA[2*4+2] * pB[2*4+0] + pA[2*4+3] * pB[3*4+0];
  503. REAL j = pA[2*4+0] * pB[0*4+1] + pA[2*4+1] * pB[1*4+1] + pA[2*4+2] * pB[2*4+1] + pA[2*4+3] * pB[3*4+1];
  504. REAL k = pA[2*4+0] * pB[0*4+2] + pA[2*4+1] * pB[1*4+2] + pA[2*4+2] * pB[2*4+2] + pA[2*4+3] * pB[3*4+2];
  505. REAL l = pA[2*4+0] * pB[0*4+3] + pA[2*4+1] * pB[1*4+3] + pA[2*4+2] * pB[2*4+3] + pA[2*4+3] * pB[3*4+3];
  506. REAL m = pA[3*4+0] * pB[0*4+0] + pA[3*4+1] * pB[1*4+0] + pA[3*4+2] * pB[2*4+0] + pA[3*4+3] * pB[3*4+0];
  507. REAL n = pA[3*4+0] * pB[0*4+1] + pA[3*4+1] * pB[1*4+1] + pA[3*4+2] * pB[2*4+1] + pA[3*4+3] * pB[3*4+1];
  508. REAL o = pA[3*4+0] * pB[0*4+2] + pA[3*4+1] * pB[1*4+2] + pA[3*4+2] * pB[2*4+2] + pA[3*4+3] * pB[3*4+2];
  509. REAL p = pA[3*4+0] * pB[0*4+3] + pA[3*4+1] * pB[1*4+3] + pA[3*4+2] * pB[2*4+3] + pA[3*4+3] * pB[3*4+3];
  510. pM[0] = a;
  511. pM[1] = b;
  512. pM[2] = c;
  513. pM[3] = d;
  514. pM[4] = e;
  515. pM[5] = f;
  516. pM[6] = g;
  517. pM[7] = h;
  518. pM[8] = i;
  519. pM[9] = j;
  520. pM[10] = k;
  521. pM[11] = l;
  522. pM[12] = m;
  523. pM[13] = n;
  524. pM[14] = o;
  525. pM[15] = p;
  526. #else
  527. memset(pM, 0, sizeof(REAL)*16);
  528. for(NxI32 i=0; i<4; i++ )
  529. for(NxI32 j=0; j<4; j++ )
  530. for(NxI32 k=0; k<4; k++ )
  531. pM[4*i+j] += pA[4*i+k] * pB[4*k+j];
  532. #endif
  533. }
  534. void fm_eulerToQuatDX(REAL x,REAL y,REAL z,REAL *quat) // convert euler angles to quaternion using the fucked up DirectX method
  535. {
  536. REAL matrix[16];
  537. fm_eulerToMatrix(x,y,z,matrix);
  538. fm_matrixToQuat(matrix,quat);
  539. }
  540. // implementation copied from: http://blogs.msdn.com/mikepelton/archive/2004/10/29/249501.aspx
  541. void fm_eulerToMatrixDX(REAL x,REAL y,REAL z,REAL *matrix) // convert euler angles to quaternion using the fucked up DirectX method.
  542. {
  543. fm_identity(matrix);
  544. matrix[0*4+0] = cos(z)*cos(y) + sin(z)*sin(x)*sin(y);
  545. matrix[0*4+1] = sin(z)*cos(x);
  546. matrix[0*4+2] = cos(z)*-sin(y) + sin(z)*sin(x)*cos(y);
  547. matrix[1*4+0] = -sin(z)*cos(y)+cos(z)*sin(x)*sin(y);
  548. matrix[1*4+1] = cos(z)*cos(x);
  549. matrix[1*4+2] = sin(z)*sin(y) +cos(z)*sin(x)*cos(y);
  550. matrix[2*4+0] = cos(x)*sin(y);
  551. matrix[2*4+1] = -sin(x);
  552. matrix[2*4+2] = cos(x)*cos(y);
  553. }
  554. void fm_scale(REAL x,REAL y,REAL z,REAL *fscale) // apply scale to the matrix.
  555. {
  556. fscale[0*4+0] = x;
  557. fscale[1*4+1] = y;
  558. fscale[2*4+2] = z;
  559. }
  560. void fm_composeTransform(const REAL *position,const REAL *quat,const REAL *scale,REAL *matrix)
  561. {
  562. fm_identity(matrix);
  563. fm_quatToMatrix(quat,matrix);
  564. if ( scale && ( scale[0] != 1 || scale[1] != 1 || scale[2] != 1 ) )
  565. {
  566. REAL work[16];
  567. memcpy(work,matrix,sizeof(REAL)*16);
  568. REAL mscale[16];
  569. fm_identity(mscale);
  570. fm_scale(scale[0],scale[1],scale[2],mscale);
  571. fm_matrixMultiply(work,mscale,matrix);
  572. }
  573. matrix[12] = position[0];
  574. matrix[13] = position[1];
  575. matrix[14] = position[2];
  576. }
  577. void fm_setTranslation(const REAL *translation,REAL *matrix)
  578. {
  579. matrix[12] = translation[0];
  580. matrix[13] = translation[1];
  581. matrix[14] = translation[2];
  582. }
  583. static REAL enorm0_3d ( REAL x0, REAL y0, REAL z0, REAL x1, REAL y1, REAL z1 )
  584. /**********************************************************************/
  585. /*
  586. Purpose:
  587. ENORM0_3D computes the Euclidean norm of (P1-P0) in 3D.
  588. Modified:
  589. 18 April 1999
  590. Author:
  591. John Burkardt
  592. Parameters:
  593. Input, REAL X0, Y0, Z0, X1, Y1, Z1, the coordinates of the points
  594. P0 and P1.
  595. Output, REAL ENORM0_3D, the Euclidean norm of (P1-P0).
  596. */
  597. {
  598. REAL value;
  599. value = sqrt (
  600. ( x1 - x0 ) * ( x1 - x0 ) +
  601. ( y1 - y0 ) * ( y1 - y0 ) +
  602. ( z1 - z0 ) * ( z1 - z0 ) );
  603. return value;
  604. }
  605. static REAL triangle_area_3d ( REAL x1, REAL y1, REAL z1, REAL x2,REAL y2, REAL z2, REAL x3, REAL y3, REAL z3 )
  606. /**********************************************************************/
  607. /*
  608. Purpose:
  609. TRIANGLE_AREA_3D computes the area of a triangle in 3D.
  610. Modified:
  611. 22 April 1999
  612. Author:
  613. John Burkardt
  614. Parameters:
  615. Input, REAL X1, Y1, Z1, X2, Y2, Z2, X3, Y3, Z3, the (X,Y,Z)
  616. coordinates of the corners of the triangle.
  617. Output, REAL TRIANGLE_AREA_3D, the area of the triangle.
  618. */
  619. {
  620. REAL a;
  621. REAL alpha;
  622. REAL area;
  623. REAL b;
  624. REAL base;
  625. REAL c;
  626. REAL dot;
  627. REAL height;
  628. /*
  629. Find the projection of (P3-P1) onto (P2-P1).
  630. */
  631. dot =
  632. ( x2 - x1 ) * ( x3 - x1 ) +
  633. ( y2 - y1 ) * ( y3 - y1 ) +
  634. ( z2 - z1 ) * ( z3 - z1 );
  635. base = enorm0_3d ( x1, y1, z1, x2, y2, z2 );
  636. /*
  637. The height of the triangle is the length of (P3-P1) after its
  638. projection onto (P2-P1) has been subtracted.
  639. */
  640. if ( base == 0.0 ) {
  641. height = 0.0;
  642. }
  643. else {
  644. alpha = dot / ( base * base );
  645. a = x3 - x1 - alpha * ( x2 - x1 );
  646. b = y3 - y1 - alpha * ( y2 - y1 );
  647. c = z3 - z1 - alpha * ( z2 - z1 );
  648. height = sqrt ( a * a + b * b + c * c );
  649. }
  650. area = 0.5f * base * height;
  651. return area;
  652. }
  653. REAL fm_computeArea(const REAL *p1,const REAL *p2,const REAL *p3)
  654. {
  655. REAL ret = 0;
  656. ret = triangle_area_3d(p1[0],p1[1],p1[2],p2[0],p2[1],p2[2],p3[0],p3[1],p3[2]);
  657. return ret;
  658. }
  659. void fm_lerp(const REAL *p1,const REAL *p2,REAL *dest,REAL lerpValue)
  660. {
  661. dest[0] = ((p2[0] - p1[0])*lerpValue) + p1[0];
  662. dest[1] = ((p2[1] - p1[1])*lerpValue) + p1[1];
  663. dest[2] = ((p2[2] - p1[2])*lerpValue) + p1[2];
  664. }
  665. bool fm_pointTestXZ(const REAL *p,const REAL *i,const REAL *j)
  666. {
  667. bool ret = false;
  668. if (((( i[2] <= p[2] ) && ( p[2] < j[2] )) || (( j[2] <= p[2] ) && ( p[2] < i[2] ))) && ( p[0] < (j[0] - i[0]) * (p[2] - i[2]) / (j[2] - i[2]) + i[0]))
  669. ret = true;
  670. return ret;
  671. };
  672. bool fm_insideTriangleXZ(const REAL *p,const REAL *p1,const REAL *p2,const REAL *p3)
  673. {
  674. bool ret = false;
  675. NxI32 c = 0;
  676. if ( fm_pointTestXZ(p,p1,p2) ) c = !c;
  677. if ( fm_pointTestXZ(p,p2,p3) ) c = !c;
  678. if ( fm_pointTestXZ(p,p3,p1) ) c = !c;
  679. if ( c ) ret = true;
  680. return ret;
  681. }
  682. bool fm_insideAABB(const REAL *pos,const REAL *bmin,const REAL *bmax)
  683. {
  684. bool ret = false;
  685. if ( pos[0] >= bmin[0] && pos[0] <= bmax[0] &&
  686. pos[1] >= bmin[1] && pos[1] <= bmax[1] &&
  687. pos[2] >= bmin[2] && pos[2] <= bmax[2] )
  688. ret = true;
  689. return ret;
  690. }
  691. NxU32 fm_clipTestPoint(const REAL *bmin,const REAL *bmax,const REAL *pos)
  692. {
  693. NxU32 ret = 0;
  694. if ( pos[0] < bmin[0] )
  695. ret|=FMCS_XMIN;
  696. else if ( pos[0] > bmax[0] )
  697. ret|=FMCS_XMAX;
  698. if ( pos[1] < bmin[1] )
  699. ret|=FMCS_YMIN;
  700. else if ( pos[1] > bmax[1] )
  701. ret|=FMCS_YMAX;
  702. if ( pos[2] < bmin[2] )
  703. ret|=FMCS_ZMIN;
  704. else if ( pos[2] > bmax[2] )
  705. ret|=FMCS_ZMAX;
  706. return ret;
  707. }
  708. NxU32 fm_clipTestPointXZ(const REAL *bmin,const REAL *bmax,const REAL *pos) // only tests X and Z, not Y
  709. {
  710. NxU32 ret = 0;
  711. if ( pos[0] < bmin[0] )
  712. ret|=FMCS_XMIN;
  713. else if ( pos[0] > bmax[0] )
  714. ret|=FMCS_XMAX;
  715. if ( pos[2] < bmin[2] )
  716. ret|=FMCS_ZMIN;
  717. else if ( pos[2] > bmax[2] )
  718. ret|=FMCS_ZMAX;
  719. return ret;
  720. }
  721. NxU32 fm_clipTestAABB(const REAL *bmin,const REAL *bmax,const REAL *p1,const REAL *p2,const REAL *p3,NxU32 &andCode)
  722. {
  723. NxU32 orCode = 0;
  724. andCode = FMCS_XMIN | FMCS_XMAX | FMCS_YMIN | FMCS_YMAX | FMCS_ZMIN | FMCS_ZMAX;
  725. NxU32 c = fm_clipTestPoint(bmin,bmax,p1);
  726. orCode|=c;
  727. andCode&=c;
  728. c = fm_clipTestPoint(bmin,bmax,p2);
  729. orCode|=c;
  730. andCode&=c;
  731. c = fm_clipTestPoint(bmin,bmax,p3);
  732. orCode|=c;
  733. andCode&=c;
  734. return orCode;
  735. }
  736. bool intersect(const REAL *si,const REAL *ei,const REAL *bmin,const REAL *bmax,REAL *time)
  737. {
  738. REAL st,et,fst = 0,fet = 1;
  739. for (NxI32 i = 0; i < 3; i++)
  740. {
  741. if (*si < *ei)
  742. {
  743. if (*si > *bmax || *ei < *bmin)
  744. return false;
  745. REAL di = *ei - *si;
  746. st = (*si < *bmin)? (*bmin - *si) / di: 0;
  747. et = (*ei > *bmax)? (*bmax - *si) / di: 1;
  748. }
  749. else
  750. {
  751. if (*ei > *bmax || *si < *bmin)
  752. return false;
  753. REAL di = *ei - *si;
  754. st = (*si > *bmax)? (*bmax - *si) / di: 0;
  755. et = (*ei < *bmin)? (*bmin - *si) / di: 1;
  756. }
  757. if (st > fst) fst = st;
  758. if (et < fet) fet = et;
  759. if (fet < fst)
  760. return false;
  761. bmin++; bmax++;
  762. si++; ei++;
  763. }
  764. *time = fst;
  765. return true;
  766. }
  767. bool fm_lineTestAABB(const REAL *p1,const REAL *p2,const REAL *bmin,const REAL *bmax,REAL &time)
  768. {
  769. bool sect = intersect(p1,p2,bmin,bmax,&time);
  770. return sect;
  771. }
  772. bool fm_lineTestAABBXZ(const REAL *p1,const REAL *p2,const REAL *bmin,const REAL *bmax,REAL &time)
  773. {
  774. REAL _bmin[3];
  775. REAL _bmax[3];
  776. _bmin[0] = bmin[0];
  777. _bmin[1] = -1e9;
  778. _bmin[2] = bmin[2];
  779. _bmax[0] = bmax[0];
  780. _bmax[1] = 1e9;
  781. _bmax[2] = bmax[2];
  782. bool sect = intersect(p1,p2,_bmin,_bmax,&time);
  783. return sect;
  784. }
  785. void fm_minmax(const REAL *p,REAL *bmin,REAL *bmax) // accmulate to a min-max value
  786. {
  787. if ( p[0] < bmin[0] ) bmin[0] = p[0];
  788. if ( p[1] < bmin[1] ) bmin[1] = p[1];
  789. if ( p[2] < bmin[2] ) bmin[2] = p[2];
  790. if ( p[0] > bmax[0] ) bmax[0] = p[0];
  791. if ( p[1] > bmax[1] ) bmax[1] = p[1];
  792. if ( p[2] > bmax[2] ) bmax[2] = p[2];
  793. }
  794. REAL fm_solveX(const REAL *plane,REAL y,REAL z) // solve for X given this plane equation and the other two components.
  795. {
  796. REAL x = (y*plane[1]+z*plane[2]+plane[3]) / -plane[0];
  797. return x;
  798. }
  799. REAL fm_solveY(const REAL *plane,REAL x,REAL z) // solve for Y given this plane equation and the other two components.
  800. {
  801. REAL y = (x*plane[0]+z*plane[2]+plane[3]) / -plane[1];
  802. return y;
  803. }
  804. REAL fm_solveZ(const REAL *plane,REAL x,REAL y) // solve for Y given this plane equation and the other two components.
  805. {
  806. REAL z = (x*plane[0]+y*plane[1]+plane[3]) / -plane[2];
  807. return z;
  808. }
  809. void fm_getAABBCenter(const REAL *bmin,const REAL *bmax,REAL *center)
  810. {
  811. center[0] = (bmax[0]-bmin[0])*0.5f+bmin[0];
  812. center[1] = (bmax[1]-bmin[1])*0.5f+bmin[1];
  813. center[2] = (bmax[2]-bmin[2])*0.5f+bmin[2];
  814. }
  815. FM_Axis fm_getDominantAxis(const REAL normal[3])
  816. {
  817. FM_Axis ret = FM_XAXIS;
  818. REAL x = fabs(normal[0]);
  819. REAL y = fabs(normal[1]);
  820. REAL z = fabs(normal[2]);
  821. if ( y > x && y > z )
  822. ret = FM_YAXIS;
  823. else if ( z > x && z > y )
  824. ret = FM_ZAXIS;
  825. return ret;
  826. }
  827. bool fm_lineSphereIntersect(const REAL *center,REAL radius,const REAL *p1,const REAL *p2,REAL *intersect)
  828. {
  829. bool ret = false;
  830. REAL dir[3];
  831. dir[0] = p2[0]-p1[0];
  832. dir[1] = p2[1]-p1[1];
  833. dir[2] = p2[2]-p1[2];
  834. REAL distance = sqrt( dir[0]*dir[0]+dir[1]*dir[1]+dir[2]*dir[2]);
  835. if ( distance > 0 )
  836. {
  837. REAL recip = 1.0f / distance;
  838. dir[0]*=recip;
  839. dir[1]*=recip;
  840. dir[2]*=recip;
  841. ret = fm_raySphereIntersect(center,radius,p1,dir,distance,intersect);
  842. }
  843. else
  844. {
  845. dir[0] = center[0]-p1[0];
  846. dir[1] = center[1]-p1[1];
  847. dir[2] = center[2]-p1[2];
  848. REAL d2 = dir[0]*dir[0]+dir[1]*dir[1]+dir[2]*dir[2];
  849. REAL r2 = radius*radius;
  850. if ( d2 < r2 )
  851. {
  852. ret = true;
  853. if ( intersect )
  854. {
  855. intersect[0] = p1[0];
  856. intersect[1] = p1[1];
  857. intersect[2] = p1[2];
  858. }
  859. }
  860. }
  861. return ret;
  862. }
  863. #define DOT(p1,p2) (p1[0]*p2[0]+p1[1]*p2[1]+p1[2]*p2[2])
  864. bool fm_raySphereIntersect(const REAL *center,REAL radius,const REAL *pos,const REAL *dir,REAL distance,REAL *intersect)
  865. {
  866. bool ret = false;
  867. REAL E0[3];
  868. E0[0] = center[0] - pos[0];
  869. E0[1] = center[1] - pos[1];
  870. E0[2] = center[2] - pos[2];
  871. REAL V[3];
  872. V[0] = dir[0];
  873. V[1] = dir[1];
  874. V[2] = dir[2];
  875. REAL dist2 = E0[0]*E0[0] + E0[1]*E0[1] + E0[2] * E0[2];
  876. REAL radius2 = radius*radius; // radius squared..
  877. // Bug Fix For Gem, if origin is *inside* the sphere, invert the
  878. // direction vector so that we get a valid intersection location.
  879. if ( dist2 < radius2 )
  880. {
  881. V[0]*=-1;
  882. V[1]*=-1;
  883. V[2]*=-1;
  884. }
  885. REAL v = DOT(E0,V);
  886. REAL disc = radius2 - (dist2 - v*v);
  887. if (disc > 0.0f)
  888. {
  889. if ( intersect )
  890. {
  891. REAL d = sqrt(disc);
  892. REAL diff = v-d;
  893. if ( diff < distance )
  894. {
  895. intersect[0] = pos[0]+V[0]*diff;
  896. intersect[1] = pos[1]+V[1]*diff;
  897. intersect[2] = pos[2]+V[2]*diff;
  898. ret = true;
  899. }
  900. }
  901. }
  902. return ret;
  903. }
  904. void fm_catmullRom(REAL *out_vector,const REAL *p1,const REAL *p2,const REAL *p3,const REAL *p4, const REAL s)
  905. {
  906. REAL s_squared = s * s;
  907. REAL s_cubed = s_squared * s;
  908. REAL coefficient_p1 = -s_cubed + 2*s_squared - s;
  909. REAL coefficient_p2 = 3 * s_cubed - 5 * s_squared + 2;
  910. REAL coefficient_p3 = -3 * s_cubed +4 * s_squared + s;
  911. REAL coefficient_p4 = s_cubed - s_squared;
  912. out_vector[0] = (coefficient_p1 * p1[0] + coefficient_p2 * p2[0] + coefficient_p3 * p3[0] + coefficient_p4 * p4[0])*0.5f;
  913. out_vector[1] = (coefficient_p1 * p1[1] + coefficient_p2 * p2[1] + coefficient_p3 * p3[1] + coefficient_p4 * p4[1])*0.5f;
  914. out_vector[2] = (coefficient_p1 * p1[2] + coefficient_p2 * p2[2] + coefficient_p3 * p3[2] + coefficient_p4 * p4[2])*0.5f;
  915. }
  916. bool fm_intersectAABB(const REAL *bmin1,const REAL *bmax1,const REAL *bmin2,const REAL *bmax2)
  917. {
  918. if ((bmin1[0] > bmax2[0]) || (bmin2[0] > bmax1[0])) return false;
  919. if ((bmin1[1] > bmax2[1]) || (bmin2[1] > bmax1[1])) return false;
  920. if ((bmin1[2] > bmax2[2]) || (bmin2[2] > bmax1[2])) return false;
  921. return true;
  922. }
  923. bool fm_insideAABB(const REAL *obmin,const REAL *obmax,const REAL *tbmin,const REAL *tbmax) // test if bounding box tbmin/tmbax is fully inside obmin/obmax
  924. {
  925. bool ret = false;
  926. if ( tbmax[0] <= obmax[0] &&
  927. tbmax[1] <= obmax[1] &&
  928. tbmax[2] <= obmax[2] &&
  929. tbmin[0] >= obmin[0] &&
  930. tbmin[1] >= obmin[1] &&
  931. tbmin[2] >= obmin[2] ) ret = true;
  932. return ret;
  933. }
  934. // Reference, from Stan Melax in Game Gems I
  935. // Quaternion q;
  936. // vector3 c = CrossProduct(v0,v1);
  937. // REAL d = DotProduct(v0,v1);
  938. // REAL s = (REAL)sqrt((1+d)*2);
  939. // q.x = c.x / s;
  940. // q.y = c.y / s;
  941. // q.z = c.z / s;
  942. // q.w = s /2.0f;
  943. // return q;
  944. void fm_rotationArc(const REAL *v0,const REAL *v1,REAL *quat)
  945. {
  946. REAL cross[3];
  947. fm_cross(cross,v0,v1);
  948. REAL d = fm_dot(v0,v1);
  949. REAL s = sqrt((1+d)*2);
  950. REAL recip = 1.0f / s;
  951. quat[0] = cross[0] * recip;
  952. quat[1] = cross[1] * recip;
  953. quat[2] = cross[2] * recip;
  954. quat[3] = s * 0.5f;
  955. }
  956. REAL fm_distancePointLineSegment(const REAL *Point,const REAL *LineStart,const REAL *LineEnd,REAL *intersection,LineSegmentType &type,REAL epsilon)
  957. {
  958. REAL ret;
  959. REAL LineMag = fm_distance( LineEnd, LineStart );
  960. if ( LineMag > 0 )
  961. {
  962. REAL U = ( ( ( Point[0] - LineStart[0] ) * ( LineEnd[0] - LineStart[0] ) ) + ( ( Point[1] - LineStart[1] ) * ( LineEnd[1] - LineStart[1] ) ) + ( ( Point[2] - LineStart[2] ) * ( LineEnd[2] - LineStart[2] ) ) ) / ( LineMag * LineMag );
  963. if( U < 0.0f || U > 1.0f )
  964. {
  965. REAL d1 = fm_distanceSquared(Point,LineStart);
  966. REAL d2 = fm_distanceSquared(Point,LineEnd);
  967. if ( d1 <= d2 )
  968. {
  969. ret = sqrt(d1);
  970. intersection[0] = LineStart[0];
  971. intersection[1] = LineStart[1];
  972. intersection[2] = LineStart[2];
  973. type = LS_START;
  974. }
  975. else
  976. {
  977. ret = sqrt(d2);
  978. intersection[0] = LineEnd[0];
  979. intersection[1] = LineEnd[1];
  980. intersection[2] = LineEnd[2];
  981. type = LS_END;
  982. }
  983. }
  984. else
  985. {
  986. intersection[0] = LineStart[0] + U * ( LineEnd[0] - LineStart[0] );
  987. intersection[1] = LineStart[1] + U * ( LineEnd[1] - LineStart[1] );
  988. intersection[2] = LineStart[2] + U * ( LineEnd[2] - LineStart[2] );
  989. ret = fm_distance(Point,intersection);
  990. REAL d1 = fm_distanceSquared(intersection,LineStart);
  991. REAL d2 = fm_distanceSquared(intersection,LineEnd);
  992. REAL mag = (epsilon*2)*(epsilon*2);
  993. if ( d1 < mag ) // if less than 1/100th the total distance, treat is as the 'start'
  994. {
  995. type = LS_START;
  996. }
  997. else if ( d2 < mag )
  998. {
  999. type = LS_END;
  1000. }
  1001. else
  1002. {
  1003. type = LS_MIDDLE;
  1004. }
  1005. }
  1006. }
  1007. else
  1008. {
  1009. ret = LineMag;
  1010. intersection[0] = LineEnd[0];
  1011. intersection[1] = LineEnd[1];
  1012. intersection[2] = LineEnd[2];
  1013. type = LS_END;
  1014. }
  1015. return ret;
  1016. }
  1017. #ifndef BEST_FIT_PLANE_H
  1018. #define BEST_FIT_PLANE_H
  1019. template <class Type> class Eigen
  1020. {
  1021. public:
  1022. void DecrSortEigenStuff(void)
  1023. {
  1024. Tridiagonal(); //diagonalize the matrix.
  1025. QLAlgorithm(); //
  1026. DecreasingSort();
  1027. GuaranteeRotation();
  1028. }
  1029. void Tridiagonal(void)
  1030. {
  1031. Type fM00 = mElement[0][0];
  1032. Type fM01 = mElement[0][1];
  1033. Type fM02 = mElement[0][2];
  1034. Type fM11 = mElement[1][1];
  1035. Type fM12 = mElement[1][2];
  1036. Type fM22 = mElement[2][2];
  1037. m_afDiag[0] = fM00;
  1038. m_afSubd[2] = 0;
  1039. if (fM02 != (Type)0.0)
  1040. {
  1041. Type fLength = sqrt(fM01*fM01+fM02*fM02);
  1042. Type fInvLength = ((Type)1.0)/fLength;
  1043. fM01 *= fInvLength;
  1044. fM02 *= fInvLength;
  1045. Type fQ = ((Type)2.0)*fM01*fM12+fM02*(fM22-fM11);
  1046. m_afDiag[1] = fM11+fM02*fQ;
  1047. m_afDiag[2] = fM22-fM02*fQ;
  1048. m_afSubd[0] = fLength;
  1049. m_afSubd[1] = fM12-fM01*fQ;
  1050. mElement[0][0] = (Type)1.0;
  1051. mElement[0][1] = (Type)0.0;
  1052. mElement[0][2] = (Type)0.0;
  1053. mElement[1][0] = (Type)0.0;
  1054. mElement[1][1] = fM01;
  1055. mElement[1][2] = fM02;
  1056. mElement[2][0] = (Type)0.0;
  1057. mElement[2][1] = fM02;
  1058. mElement[2][2] = -fM01;
  1059. m_bIsRotation = false;
  1060. }
  1061. else
  1062. {
  1063. m_afDiag[1] = fM11;
  1064. m_afDiag[2] = fM22;
  1065. m_afSubd[0] = fM01;
  1066. m_afSubd[1] = fM12;
  1067. mElement[0][0] = (Type)1.0;
  1068. mElement[0][1] = (Type)0.0;
  1069. mElement[0][2] = (Type)0.0;
  1070. mElement[1][0] = (Type)0.0;
  1071. mElement[1][1] = (Type)1.0;
  1072. mElement[1][2] = (Type)0.0;
  1073. mElement[2][0] = (Type)0.0;
  1074. mElement[2][1] = (Type)0.0;
  1075. mElement[2][2] = (Type)1.0;
  1076. m_bIsRotation = true;
  1077. }
  1078. }
  1079. bool QLAlgorithm(void)
  1080. {
  1081. const NxI32 iMaxIter = 32;
  1082. for (NxI32 i0 = 0; i0 <3; i0++)
  1083. {
  1084. NxI32 i1;
  1085. for (i1 = 0; i1 < iMaxIter; i1++)
  1086. {
  1087. NxI32 i2;
  1088. for (i2 = i0; i2 <= (3-2); i2++)
  1089. {
  1090. Type fTmp = fabs(m_afDiag[i2]) + fabs(m_afDiag[i2+1]);
  1091. if ( fabs(m_afSubd[i2]) + fTmp == fTmp )
  1092. break;
  1093. }
  1094. if (i2 == i0)
  1095. {
  1096. break;
  1097. }
  1098. Type fG = (m_afDiag[i0+1] - m_afDiag[i0])/(((Type)2.0) * m_afSubd[i0]);
  1099. Type fR = sqrt(fG*fG+(Type)1.0);
  1100. if (fG < (Type)0.0)
  1101. {
  1102. fG = m_afDiag[i2]-m_afDiag[i0]+m_afSubd[i0]/(fG-fR);
  1103. }
  1104. else
  1105. {
  1106. fG = m_afDiag[i2]-m_afDiag[i0]+m_afSubd[i0]/(fG+fR);
  1107. }
  1108. Type fSin = (Type)1.0, fCos = (Type)1.0, fP = (Type)0.0;
  1109. for (NxI32 i3 = i2-1; i3 >= i0; i3--)
  1110. {
  1111. Type fF = fSin*m_afSubd[i3];
  1112. Type fB = fCos*m_afSubd[i3];
  1113. if (fabs(fF) >= fabs(fG))
  1114. {
  1115. fCos = fG/fF;
  1116. fR = sqrt(fCos*fCos+(Type)1.0);
  1117. m_afSubd[i3+1] = fF*fR;
  1118. fSin = ((Type)1.0)/fR;
  1119. fCos *= fSin;
  1120. }
  1121. else
  1122. {
  1123. fSin = fF/fG;
  1124. fR = sqrt(fSin*fSin+(Type)1.0);
  1125. m_afSubd[i3+1] = fG*fR;
  1126. fCos = ((Type)1.0)/fR;
  1127. fSin *= fCos;
  1128. }
  1129. fG = m_afDiag[i3+1]-fP;
  1130. fR = (m_afDiag[i3]-fG)*fSin+((Type)2.0)*fB*fCos;
  1131. fP = fSin*fR;
  1132. m_afDiag[i3+1] = fG+fP;
  1133. fG = fCos*fR-fB;
  1134. for (NxI32 i4 = 0; i4 < 3; i4++)
  1135. {
  1136. fF = mElement[i4][i3+1];
  1137. mElement[i4][i3+1] = fSin*mElement[i4][i3]+fCos*fF;
  1138. mElement[i4][i3] = fCos*mElement[i4][i3]-fSin*fF;
  1139. }
  1140. }
  1141. m_afDiag[i0] -= fP;
  1142. m_afSubd[i0] = fG;
  1143. m_afSubd[i2] = (Type)0.0;
  1144. }
  1145. if (i1 == iMaxIter)
  1146. {
  1147. return false;
  1148. }
  1149. }
  1150. return true;
  1151. }
  1152. void DecreasingSort(void)
  1153. {
  1154. //sort eigenvalues in decreasing order, e[0] >= ... >= e[iSize-1]
  1155. for (NxI32 i0 = 0, i1; i0 <= 3-2; i0++)
  1156. {
  1157. // locate maximum eigenvalue
  1158. i1 = i0;
  1159. Type fMax = m_afDiag[i1];
  1160. NxI32 i2;
  1161. for (i2 = i0+1; i2 < 3; i2++)
  1162. {
  1163. if (m_afDiag[i2] > fMax)
  1164. {
  1165. i1 = i2;
  1166. fMax = m_afDiag[i1];
  1167. }
  1168. }
  1169. if (i1 != i0)
  1170. {
  1171. // swap eigenvalues
  1172. m_afDiag[i1] = m_afDiag[i0];
  1173. m_afDiag[i0] = fMax;
  1174. // swap eigenvectors
  1175. for (i2 = 0; i2 < 3; i2++)
  1176. {
  1177. Type fTmp = mElement[i2][i0];
  1178. mElement[i2][i0] = mElement[i2][i1];
  1179. mElement[i2][i1] = fTmp;
  1180. m_bIsRotation = !m_bIsRotation;
  1181. }
  1182. }
  1183. }
  1184. }
  1185. void GuaranteeRotation(void)
  1186. {
  1187. if (!m_bIsRotation)
  1188. {
  1189. // change sign on the first column
  1190. for (NxI32 iRow = 0; iRow <3; iRow++)
  1191. {
  1192. mElement[iRow][0] = -mElement[iRow][0];
  1193. }
  1194. }
  1195. }
  1196. Type mElement[3][3];
  1197. Type m_afDiag[3];
  1198. Type m_afSubd[3];
  1199. bool m_bIsRotation;
  1200. };
  1201. #endif
  1202. bool fm_computeBestFitPlane(NxU32 vcount,
  1203. const REAL *points,
  1204. NxU32 vstride,
  1205. const REAL *weights,
  1206. NxU32 wstride,
  1207. REAL *plane)
  1208. {
  1209. bool ret = false;
  1210. REAL kOrigin[3] = { 0, 0, 0 };
  1211. REAL wtotal = 0;
  1212. {
  1213. const char *source = (const char *) points;
  1214. const char *wsource = (const char *) weights;
  1215. for (NxU32 i=0; i<vcount; i++)
  1216. {
  1217. const REAL *p = (const REAL *) source;
  1218. REAL w = 1;
  1219. if ( wsource )
  1220. {
  1221. const REAL *ws = (const REAL *) wsource;
  1222. w = *ws; //
  1223. wsource+=wstride;
  1224. }
  1225. kOrigin[0]+=p[0]*w;
  1226. kOrigin[1]+=p[1]*w;
  1227. kOrigin[2]+=p[2]*w;
  1228. wtotal+=w;
  1229. source+=vstride;
  1230. }
  1231. }
  1232. REAL recip = 1.0f / wtotal; // reciprocol of total weighting
  1233. kOrigin[0]*=recip;
  1234. kOrigin[1]*=recip;
  1235. kOrigin[2]*=recip;
  1236. REAL fSumXX=0;
  1237. REAL fSumXY=0;
  1238. REAL fSumXZ=0;
  1239. REAL fSumYY=0;
  1240. REAL fSumYZ=0;
  1241. REAL fSumZZ=0;
  1242. {
  1243. const char *source = (const char *) points;
  1244. const char *wsource = (const char *) weights;
  1245. for (NxU32 i=0; i<vcount; i++)
  1246. {
  1247. const REAL *p = (const REAL *) source;
  1248. REAL w = 1;
  1249. if ( wsource )
  1250. {
  1251. const REAL *ws = (const REAL *) wsource;
  1252. w = *ws; //
  1253. wsource+=wstride;
  1254. }
  1255. REAL kDiff[3];
  1256. kDiff[0] = w*(p[0] - kOrigin[0]); // apply vertex weighting!
  1257. kDiff[1] = w*(p[1] - kOrigin[1]);
  1258. kDiff[2] = w*(p[2] - kOrigin[2]);
  1259. fSumXX+= kDiff[0] * kDiff[0]; // sume of the squares of the differences.
  1260. fSumXY+= kDiff[0] * kDiff[1]; // sume of the squares of the differences.
  1261. fSumXZ+= kDiff[0] * kDiff[2]; // sume of the squares of the differences.
  1262. fSumYY+= kDiff[1] * kDiff[1];
  1263. fSumYZ+= kDiff[1] * kDiff[2];
  1264. fSumZZ+= kDiff[2] * kDiff[2];
  1265. source+=vstride;
  1266. }
  1267. }
  1268. fSumXX *= recip;
  1269. fSumXY *= recip;
  1270. fSumXZ *= recip;
  1271. fSumYY *= recip;
  1272. fSumYZ *= recip;
  1273. fSumZZ *= recip;
  1274. // setup the eigensolver
  1275. Eigen<REAL> kES;
  1276. kES.mElement[0][0] = fSumXX;
  1277. kES.mElement[0][1] = fSumXY;
  1278. kES.mElement[0][2] = fSumXZ;
  1279. kES.mElement[1][0] = fSumXY;
  1280. kES.mElement[1][1] = fSumYY;
  1281. kES.mElement[1][2] = fSumYZ;
  1282. kES.mElement[2][0] = fSumXZ;
  1283. kES.mElement[2][1] = fSumYZ;
  1284. kES.mElement[2][2] = fSumZZ;
  1285. // compute eigenstuff, smallest eigenvalue is in last position
  1286. kES.DecrSortEigenStuff();
  1287. REAL kNormal[3];
  1288. kNormal[0] = kES.mElement[0][2];
  1289. kNormal[1] = kES.mElement[1][2];
  1290. kNormal[2] = kES.mElement[2][2];
  1291. // the minimum energy
  1292. plane[0] = kNormal[0];
  1293. plane[1] = kNormal[1];
  1294. plane[2] = kNormal[2];
  1295. plane[3] = 0 - fm_dot(kNormal,kOrigin);
  1296. ret = true;
  1297. return ret;
  1298. }
  1299. bool fm_colinear(const REAL a1[3],const REAL a2[3],const REAL b1[3],const REAL b2[3],REAL epsilon) // true if these two line segments are co-linear.
  1300. {
  1301. bool ret = false;
  1302. REAL dir1[3];
  1303. REAL dir2[3];
  1304. dir1[0] = (a2[0] - a1[0]);
  1305. dir1[1] = (a2[1] - a1[1]);
  1306. dir1[2] = (a2[2] - a1[2]);
  1307. dir2[0] = (b2[0]-a1[0]) - (b1[0]-a1[0]);
  1308. dir2[1] = (b2[1]-a1[1]) - (b1[1]-a1[1]);
  1309. dir2[2] = (b2[2]-a2[2]) - (b1[2]-a2[2]);
  1310. fm_normalize(dir1);
  1311. fm_normalize(dir2);
  1312. REAL dot = fm_dot(dir1,dir2);
  1313. if ( dot >= epsilon )
  1314. {
  1315. ret = true;
  1316. }
  1317. return ret;
  1318. }
  1319. bool fm_colinear(const REAL *p1,const REAL *p2,const REAL *p3,REAL epsilon)
  1320. {
  1321. bool ret = false;
  1322. REAL dir1[3];
  1323. REAL dir2[3];
  1324. dir1[0] = p2[0] - p1[0];
  1325. dir1[1] = p2[1] - p1[1];
  1326. dir1[2] = p2[2] - p1[2];
  1327. dir2[0] = p3[0] - p2[0];
  1328. dir2[1] = p3[1] - p2[1];
  1329. dir2[2] = p3[2] - p2[2];
  1330. fm_normalize(dir1);
  1331. fm_normalize(dir2);
  1332. REAL dot = fm_dot(dir1,dir2);
  1333. if ( dot >= epsilon )
  1334. {
  1335. ret = true;
  1336. }
  1337. return ret;
  1338. }
  1339. void fm_initMinMax(const REAL *p,REAL *bmin,REAL *bmax)
  1340. {
  1341. bmax[0] = bmin[0] = p[0];
  1342. bmax[1] = bmin[1] = p[1];
  1343. bmax[2] = bmin[2] = p[2];
  1344. }
  1345. IntersectResult fm_intersectLineSegments2d(const REAL *a1,const REAL *a2,const REAL *b1,const REAL *b2,REAL *intersection)
  1346. {
  1347. IntersectResult ret;
  1348. REAL denom = ((b2[1] - b1[1])*(a2[0] - a1[0])) - ((b2[0] - b1[0])*(a2[1] - a1[1]));
  1349. REAL nume_a = ((b2[0] - b1[0])*(a1[1] - b1[1])) - ((b2[1] - b1[1])*(a1[0] - b1[0]));
  1350. REAL nume_b = ((a2[0] - a1[0])*(a1[1] - b1[1])) - ((a2[1] - a1[1])*(a1[0] - b1[0]));
  1351. if (denom == 0 )
  1352. {
  1353. if(nume_a == 0 && nume_b == 0)
  1354. {
  1355. ret = IR_COINCIDENT;
  1356. }
  1357. else
  1358. {
  1359. ret = IR_PARALLEL;
  1360. }
  1361. }
  1362. else
  1363. {
  1364. REAL recip = 1 / denom;
  1365. REAL ua = nume_a * recip;
  1366. REAL ub = nume_b * recip;
  1367. if(ua >= 0 && ua <= 1 && ub >= 0 && ub <= 1 )
  1368. {
  1369. // Get the intersection point.
  1370. intersection[0] = a1[0] + ua*(a2[0] - a1[0]);
  1371. intersection[1] = a1[1] + ua*(a2[1] - a1[1]);
  1372. ret = IR_DO_INTERSECT;
  1373. }
  1374. else
  1375. {
  1376. ret = IR_DONT_INTERSECT;
  1377. }
  1378. }
  1379. return ret;
  1380. }
  1381. IntersectResult fm_intersectLineSegments2dTime(const REAL *a1,const REAL *a2,const REAL *b1,const REAL *b2,REAL &t1,REAL &t2)
  1382. {
  1383. IntersectResult ret;
  1384. REAL denom = ((b2[1] - b1[1])*(a2[0] - a1[0])) - ((b2[0] - b1[0])*(a2[1] - a1[1]));
  1385. REAL nume_a = ((b2[0] - b1[0])*(a1[1] - b1[1])) - ((b2[1] - b1[1])*(a1[0] - b1[0]));
  1386. REAL nume_b = ((a2[0] - a1[0])*(a1[1] - b1[1])) - ((a2[1] - a1[1])*(a1[0] - b1[0]));
  1387. if (denom == 0 )
  1388. {
  1389. if(nume_a == 0 && nume_b == 0)
  1390. {
  1391. ret = IR_COINCIDENT;
  1392. }
  1393. else
  1394. {
  1395. ret = IR_PARALLEL;
  1396. }
  1397. }
  1398. else
  1399. {
  1400. REAL recip = 1 / denom;
  1401. REAL ua = nume_a * recip;
  1402. REAL ub = nume_b * recip;
  1403. if(ua >= 0 && ua <= 1 && ub >= 0 && ub <= 1 )
  1404. {
  1405. t1 = ua;
  1406. t2 = ub;
  1407. ret = IR_DO_INTERSECT;
  1408. }
  1409. else
  1410. {
  1411. ret = IR_DONT_INTERSECT;
  1412. }
  1413. }
  1414. return ret;
  1415. }
  1416. //**** Plane Triangle Intersection
  1417. // assumes that the points are on opposite sides of the plane!
  1418. void fm_intersectPointPlane(const REAL *p1,const REAL *p2,REAL *split,const REAL *plane)
  1419. {
  1420. REAL dp1 = fm_distToPlane(plane,p1);
  1421. REAL dir[3];
  1422. dir[0] = p2[0] - p1[0];
  1423. dir[1] = p2[1] - p1[1];
  1424. dir[2] = p2[2] - p1[2];
  1425. REAL dot1 = dir[0]*plane[0] + dir[1]*plane[1] + dir[2]*plane[2];
  1426. REAL dot2 = dp1 - plane[3];
  1427. REAL t = -(plane[3] + dot2 ) / dot1;
  1428. split[0] = (dir[0]*t)+p1[0];
  1429. split[1] = (dir[1]*t)+p1[1];
  1430. split[2] = (dir[2]*t)+p1[2];
  1431. }
  1432. PlaneTriResult fm_getSidePlane(const REAL *p,const REAL *plane,REAL epsilon)
  1433. {
  1434. PlaneTriResult ret = PTR_ON_PLANE;
  1435. REAL d = fm_distToPlane(plane,p);
  1436. if ( d < -epsilon || d > epsilon )
  1437. {
  1438. if ( d > 0 )
  1439. ret = PTR_FRONT; // it is 'in front' within the provided epsilon value.
  1440. else
  1441. ret = PTR_BACK;
  1442. }
  1443. return ret;
  1444. }
  1445. #ifndef PLANE_TRIANGLE_INTERSECTION_H
  1446. #define PLANE_TRIANGLE_INTERSECTION_H
  1447. #define MAXPTS 256
  1448. template <class Type> class point
  1449. {
  1450. public:
  1451. void set(const Type *p)
  1452. {
  1453. x = p[0];
  1454. y = p[1];
  1455. z = p[2];
  1456. }
  1457. Type x;
  1458. Type y;
  1459. Type z;
  1460. };
  1461. template <class Type> class plane
  1462. {
  1463. public:
  1464. plane(const Type *p)
  1465. {
  1466. normal.x = p[0];
  1467. normal.y = p[1];
  1468. normal.z = p[2];
  1469. D = p[3];
  1470. }
  1471. Type Classify_Point(const point<Type> &p)
  1472. {
  1473. return p.x*normal.x + p.y*normal.y + p.z*normal.z + D;
  1474. }
  1475. point<Type> normal;
  1476. Type D;
  1477. };
  1478. template <class Type> class polygon
  1479. {
  1480. public:
  1481. polygon(void)
  1482. {
  1483. mVcount = 0;
  1484. }
  1485. polygon(const Type *p1,const Type *p2,const Type *p3)
  1486. {
  1487. mVcount = 3;
  1488. mVertices[0].set(p1);
  1489. mVertices[1].set(p2);
  1490. mVertices[2].set(p3);
  1491. }
  1492. NxI32 NumVertices(void) const { return mVcount; };
  1493. const point<Type>& Vertex(NxI32 index)
  1494. {
  1495. if ( index < 0 ) index+=mVcount;
  1496. return mVertices[index];
  1497. };
  1498. void set(const point<Type> *pts,NxI32 count)
  1499. {
  1500. for (NxI32 i=0; i<count; i++)
  1501. {
  1502. mVertices[i] = pts[i];
  1503. }
  1504. mVcount = count;
  1505. }
  1506. void Split_Polygon(polygon<Type> *poly,plane<Type> *part, polygon<Type> &front, polygon<Type> &back)
  1507. {
  1508. NxI32 count = poly->NumVertices ();
  1509. NxI32 out_c = 0, in_c = 0;
  1510. point<Type> ptA, ptB,outpts[MAXPTS],inpts[MAXPTS];
  1511. Type sideA, sideB;
  1512. ptA = poly->Vertex (count - 1);
  1513. sideA = part->Classify_Point (ptA);
  1514. for (NxI32 i = -1; ++i < count;)
  1515. {
  1516. ptB = poly->Vertex(i);
  1517. sideB = part->Classify_Point(ptB);
  1518. if (sideB > 0)
  1519. {
  1520. if (sideA < 0)
  1521. {
  1522. point<Type> v;
  1523. fm_intersectPointPlane(&ptB.x, &ptA.x, &v.x, &part->normal.x );
  1524. outpts[out_c++] = inpts[in_c++] = v;
  1525. }
  1526. outpts[out_c++] = ptB;
  1527. }
  1528. else if (sideB < 0)
  1529. {
  1530. if (sideA > 0)
  1531. {
  1532. point<Type> v;
  1533. fm_intersectPointPlane(&ptB.x, &ptA.x, &v.x, &part->normal.x );
  1534. outpts[out_c++] = inpts[in_c++] = v;
  1535. }
  1536. inpts[in_c++] = ptB;
  1537. }
  1538. else
  1539. outpts[out_c++] = inpts[in_c++] = ptB;
  1540. ptA = ptB;
  1541. sideA = sideB;
  1542. }
  1543. front.set(&outpts[0], out_c);
  1544. back.set(&inpts[0], in_c);
  1545. }
  1546. NxI32 mVcount;
  1547. point<Type> mVertices[MAXPTS];
  1548. };
  1549. #endif
  1550. static inline void add(const REAL *p,REAL *dest,NxU32 tstride,NxU32 &pcount)
  1551. {
  1552. char *d = (char *) dest;
  1553. d = d + pcount*tstride;
  1554. dest = (REAL *) d;
  1555. dest[0] = p[0];
  1556. dest[1] = p[1];
  1557. dest[2] = p[2];
  1558. pcount++;
  1559. assert( pcount <= 4 );
  1560. }
  1561. PlaneTriResult fm_planeTriIntersection(const REAL *_plane, // the plane equation in Ax+By+Cz+D format
  1562. const REAL *triangle, // the source triangle.
  1563. NxU32 tstride, // stride in bytes of the input and output *vertices*
  1564. REAL epsilon, // the co-planar epsilon value.
  1565. REAL *front, // the triangle in front of the
  1566. NxU32 &fcount, // number of vertices in the 'front' triangle
  1567. REAL *back, // the triangle in back of the plane
  1568. NxU32 &bcount) // the number of vertices in the 'back' triangle.
  1569. {
  1570. fcount = 0;
  1571. bcount = 0;
  1572. const char *tsource = (const char *) triangle;
  1573. // get the three vertices of the triangle.
  1574. const REAL *p1 = (const REAL *) (tsource);
  1575. const REAL *p2 = (const REAL *) (tsource+tstride);
  1576. const REAL *p3 = (const REAL *) (tsource+tstride*2);
  1577. PlaneTriResult r1 = fm_getSidePlane(p1,_plane,epsilon); // compute the side of the plane each vertex is on
  1578. PlaneTriResult r2 = fm_getSidePlane(p2,_plane,epsilon);
  1579. PlaneTriResult r3 = fm_getSidePlane(p3,_plane,epsilon);
  1580. // If any of the points lay right *on* the plane....
  1581. if ( r1 == PTR_ON_PLANE || r2 == PTR_ON_PLANE || r3 == PTR_ON_PLANE )
  1582. {
  1583. // If the triangle is completely co-planar, then just treat it as 'front' and return!
  1584. if ( r1 == PTR_ON_PLANE && r2 == PTR_ON_PLANE && r3 == PTR_ON_PLANE )
  1585. {
  1586. add(p1,front,tstride,fcount);
  1587. add(p2,front,tstride,fcount);
  1588. add(p3,front,tstride,fcount);
  1589. return PTR_FRONT;
  1590. }
  1591. // Decide to place the co-planar points on the same side as the co-planar point.
  1592. PlaneTriResult r= PTR_ON_PLANE;
  1593. if ( r1 != PTR_ON_PLANE )
  1594. r = r1;
  1595. else if ( r2 != PTR_ON_PLANE )
  1596. r = r2;
  1597. else if ( r3 != PTR_ON_PLANE )
  1598. r = r3;
  1599. if ( r1 == PTR_ON_PLANE ) r1 = r;
  1600. if ( r2 == PTR_ON_PLANE ) r2 = r;
  1601. if ( r3 == PTR_ON_PLANE ) r3 = r;
  1602. }
  1603. if ( r1 == r2 && r1 == r3 ) // if all three vertices are on the same side of the plane.
  1604. {
  1605. if ( r1 == PTR_FRONT ) // if all three are in front of the plane, then copy to the 'front' output triangle.
  1606. {
  1607. add(p1,front,tstride,fcount);
  1608. add(p2,front,tstride,fcount);
  1609. add(p3,front,tstride,fcount);
  1610. }
  1611. else
  1612. {
  1613. add(p1,back,tstride,bcount); // if all three are in 'back' then copy to the 'back' output triangle.
  1614. add(p2,back,tstride,bcount);
  1615. add(p3,back,tstride,bcount);
  1616. }
  1617. return r1; // if all three points are on the same side of the plane return result
  1618. }
  1619. polygon<REAL> pi(p1,p2,p3);
  1620. polygon<REAL> pfront,pback;
  1621. plane<REAL> part(_plane);
  1622. pi.Split_Polygon(&pi,&part,pfront,pback);
  1623. for (NxI32 i=0; i<pfront.mVcount; i++)
  1624. {
  1625. add( &pfront.mVertices[i].x, front, tstride, fcount );
  1626. }
  1627. for (NxI32 i=0; i<pback.mVcount; i++)
  1628. {
  1629. add( &pback.mVertices[i].x, back, tstride, bcount );
  1630. }
  1631. PlaneTriResult ret = PTR_SPLIT;
  1632. if ( fcount < 3 ) fcount = 0;
  1633. if ( bcount < 3 ) bcount = 0;
  1634. if ( fcount == 0 && bcount )
  1635. ret = PTR_BACK;
  1636. if ( bcount == 0 && fcount )
  1637. ret = PTR_FRONT;
  1638. return ret;
  1639. }
  1640. // computes the OBB for this set of points relative to this transform matrix.
  1641. void computeOBB(NxU32 vcount,const REAL *points,NxU32 pstride,REAL *sides,REAL *matrix)
  1642. {
  1643. const char *src = (const char *) points;
  1644. REAL bmin[3] = { 1e9, 1e9, 1e9 };
  1645. REAL bmax[3] = { -1e9, -1e9, -1e9 };
  1646. for (NxU32 i=0; i<vcount; i++)
  1647. {
  1648. const REAL *p = (const REAL *) src;
  1649. REAL t[3];
  1650. fm_inverseRT(matrix, p, t ); // inverse rotate translate
  1651. if ( t[0] < bmin[0] ) bmin[0] = t[0];
  1652. if ( t[1] < bmin[1] ) bmin[1] = t[1];
  1653. if ( t[2] < bmin[2] ) bmin[2] = t[2];
  1654. if ( t[0] > bmax[0] ) bmax[0] = t[0];
  1655. if ( t[1] > bmax[1] ) bmax[1] = t[1];
  1656. if ( t[2] > bmax[2] ) bmax[2] = t[2];
  1657. src+=pstride;
  1658. }
  1659. REAL center[3];
  1660. sides[0] = bmax[0]-bmin[0];
  1661. sides[1] = bmax[1]-bmin[1];
  1662. sides[2] = bmax[2]-bmin[2];
  1663. center[0] = sides[0]*0.5f+bmin[0];
  1664. center[1] = sides[1]*0.5f+bmin[1];
  1665. center[2] = sides[2]*0.5f+bmin[2];
  1666. REAL ocenter[3];
  1667. fm_rotate(matrix,center,ocenter);
  1668. matrix[12]+=ocenter[0];
  1669. matrix[13]+=ocenter[1];
  1670. matrix[14]+=ocenter[2];
  1671. }
  1672. void fm_computeBestFitOBB(NxU32 vcount,const REAL *points,NxU32 pstride,REAL *sides,REAL *matrix,bool bruteForce)
  1673. {
  1674. REAL plane[4];
  1675. fm_computeBestFitPlane(vcount,points,pstride,0,0,plane);
  1676. fm_planeToMatrix(plane,matrix);
  1677. computeOBB( vcount, points, pstride, sides, matrix );
  1678. REAL refmatrix[16];
  1679. memcpy(refmatrix,matrix,16*sizeof(REAL));
  1680. REAL volume = sides[0]*sides[1]*sides[2];
  1681. if ( bruteForce )
  1682. {
  1683. for (REAL a=10; a<180; a+=10)
  1684. {
  1685. REAL quat[4];
  1686. fm_eulerToQuat(0,a*FM_DEG_TO_RAD,0,quat);
  1687. REAL temp[16];
  1688. REAL pmatrix[16];
  1689. fm_quatToMatrix(quat,temp);
  1690. fm_matrixMultiply(temp,refmatrix,pmatrix);
  1691. REAL psides[3];
  1692. computeOBB( vcount, points, pstride, psides, pmatrix );
  1693. REAL v = psides[0]*psides[1]*psides[2];
  1694. if ( v < volume )
  1695. {
  1696. volume = v;
  1697. memcpy(matrix,pmatrix,sizeof(REAL)*16);
  1698. sides[0] = psides[0];
  1699. sides[1] = psides[1];
  1700. sides[2] = psides[2];
  1701. }
  1702. }
  1703. }
  1704. }
  1705. void fm_computeBestFitOBB(NxU32 vcount,const REAL *points,NxU32 pstride,REAL *sides,REAL *pos,REAL *quat,bool bruteForce)
  1706. {
  1707. REAL matrix[16];
  1708. fm_computeBestFitOBB(vcount,points,pstride,sides,matrix,bruteForce);
  1709. fm_getTranslation(matrix,pos);
  1710. fm_matrixToQuat(matrix,quat);
  1711. }
  1712. void fm_computeBestFitABB(NxU32 vcount,const REAL *points,NxU32 pstride,REAL *sides,REAL *pos)
  1713. {
  1714. REAL bmin[3];
  1715. REAL bmax[3];
  1716. bmin[0] = points[0];
  1717. bmin[1] = points[1];
  1718. bmin[2] = points[2];
  1719. bmax[0] = points[0];
  1720. bmax[1] = points[1];
  1721. bmax[2] = points[2];
  1722. const char *cp = (const char *) points;
  1723. for (NxU32 i=0; i<vcount; i++)
  1724. {
  1725. const REAL *p = (const REAL *) cp;
  1726. if ( p[0] < bmin[0] ) bmin[0] = p[0];
  1727. if ( p[1] < bmin[1] ) bmin[1] = p[1];
  1728. if ( p[2] < bmin[2] ) bmin[2] = p[2];
  1729. if ( p[0] > bmax[0] ) bmax[0] = p[0];
  1730. if ( p[1] > bmax[1] ) bmax[1] = p[1];
  1731. if ( p[2] > bmax[2] ) bmax[2] = p[2];
  1732. cp+=pstride;
  1733. }
  1734. sides[0] = bmax[0] - bmin[0];
  1735. sides[1] = bmax[1] - bmin[1];
  1736. sides[2] = bmax[2] - bmin[2];
  1737. pos[0] = bmin[0]+sides[0]*0.5f;
  1738. pos[1] = bmin[1]+sides[1]*0.5f;
  1739. pos[2] = bmin[2]+sides[2]*0.5f;
  1740. }
  1741. void fm_planeToMatrix(const REAL *plane,REAL *matrix) // convert a plane equation to a 4x4 rotation matrix
  1742. {
  1743. REAL ref[3] = { 0, 1, 0 };
  1744. REAL quat[4];
  1745. fm_rotationArc(ref,plane,quat);
  1746. fm_quatToMatrix(quat,matrix);
  1747. REAL origin[3] = { 0, -plane[3], 0 };
  1748. REAL center[3];
  1749. fm_transform(matrix,origin,center);
  1750. fm_setTranslation(center,matrix);
  1751. }
  1752. void fm_planeToQuat(const REAL *plane,REAL *quat,REAL *pos) // convert a plane equation to a quaternion and translation
  1753. {
  1754. REAL ref[3] = { 0, 1, 0 };
  1755. REAL matrix[16];
  1756. fm_rotationArc(ref,plane,quat);
  1757. fm_quatToMatrix(quat,matrix);
  1758. REAL origin[3] = { 0, plane[3], 0 };
  1759. fm_transform(matrix,origin,pos);
  1760. }
  1761. void fm_eulerMatrix(REAL ax,REAL ay,REAL az,REAL *matrix) // convert euler (in radians) to a dest 4x4 matrix (translation set to zero)
  1762. {
  1763. REAL quat[4];
  1764. fm_eulerToQuat(ax,ay,az,quat);
  1765. fm_quatToMatrix(quat,matrix);
  1766. }
  1767. //**********************************************************
  1768. //**********************************************************
  1769. //**** Vertex Welding
  1770. //**********************************************************
  1771. //**********************************************************
  1772. #ifndef VERTEX_INDEX_H
  1773. #define VERTEX_INDEX_H
  1774. namespace VERTEX_INDEX
  1775. {
  1776. class KdTreeNode;
  1777. typedef CONVEX_DECOMPOSITION::Array< KdTreeNode * > KdTreeNodeVector;
  1778. enum Axes
  1779. {
  1780. X_AXIS = 0,
  1781. Y_AXIS = 1,
  1782. Z_AXIS = 2
  1783. };
  1784. class KdTreeFindNode
  1785. {
  1786. public:
  1787. KdTreeFindNode(void)
  1788. {
  1789. mNode = 0;
  1790. mDistance = 0;
  1791. }
  1792. KdTreeNode *mNode;
  1793. NxF64 mDistance;
  1794. };
  1795. class KdTreeInterface
  1796. {
  1797. public:
  1798. virtual const NxF64 * getPositionDouble(NxU32 index) const = 0;
  1799. virtual const NxF32 * getPositionFloat(NxU32 index) const = 0;
  1800. };
  1801. class KdTreeNode
  1802. {
  1803. public:
  1804. KdTreeNode(void)
  1805. {
  1806. mIndex = 0;
  1807. mLeft = 0;
  1808. mRight = 0;
  1809. }
  1810. KdTreeNode(NxU32 index)
  1811. {
  1812. mIndex = index;
  1813. mLeft = 0;
  1814. mRight = 0;
  1815. };
  1816. ~KdTreeNode(void)
  1817. {
  1818. }
  1819. void addDouble(KdTreeNode *node,Axes dim,const KdTreeInterface *iface)
  1820. {
  1821. const NxF64 *nodePosition = iface->getPositionDouble( node->mIndex );
  1822. const NxF64 *position = iface->getPositionDouble( mIndex );
  1823. switch ( dim )
  1824. {
  1825. case X_AXIS:
  1826. if ( nodePosition[0] <= position[0] )
  1827. {
  1828. if ( mLeft )
  1829. mLeft->addDouble(node,Y_AXIS,iface);
  1830. else
  1831. mLeft = node;
  1832. }
  1833. else
  1834. {
  1835. if ( mRight )
  1836. mRight->addDouble(node,Y_AXIS,iface);
  1837. else
  1838. mRight = node;
  1839. }
  1840. break;
  1841. case Y_AXIS:
  1842. if ( nodePosition[1] <= position[1] )
  1843. {
  1844. if ( mLeft )
  1845. mLeft->addDouble(node,Z_AXIS,iface);
  1846. else
  1847. mLeft = node;
  1848. }
  1849. else
  1850. {
  1851. if ( mRight )
  1852. mRight->addDouble(node,Z_AXIS,iface);
  1853. else
  1854. mRight = node;
  1855. }
  1856. break;
  1857. case Z_AXIS:
  1858. if ( nodePosition[2] <= position[2] )
  1859. {
  1860. if ( mLeft )
  1861. mLeft->addDouble(node,X_AXIS,iface);
  1862. else
  1863. mLeft = node;
  1864. }
  1865. else
  1866. {
  1867. if ( mRight )
  1868. mRight->addDouble(node,X_AXIS,iface);
  1869. else
  1870. mRight = node;
  1871. }
  1872. break;
  1873. }
  1874. }
  1875. void addFloat(KdTreeNode *node,Axes dim,const KdTreeInterface *iface)
  1876. {
  1877. const NxF32 *nodePosition = iface->getPositionFloat( node->mIndex );
  1878. const NxF32 *position = iface->getPositionFloat( mIndex );
  1879. switch ( dim )
  1880. {
  1881. case X_AXIS:
  1882. if ( nodePosition[0] <= position[0] )
  1883. {
  1884. if ( mLeft )
  1885. mLeft->addFloat(node,Y_AXIS,iface);
  1886. else
  1887. mLeft = node;
  1888. }
  1889. else
  1890. {
  1891. if ( mRight )
  1892. mRight->addFloat(node,Y_AXIS,iface);
  1893. else
  1894. mRight = node;
  1895. }
  1896. break;
  1897. case Y_AXIS:
  1898. if ( nodePosition[1] <= position[1] )
  1899. {
  1900. if ( mLeft )
  1901. mLeft->addFloat(node,Z_AXIS,iface);
  1902. else
  1903. mLeft = node;
  1904. }
  1905. else
  1906. {
  1907. if ( mRight )
  1908. mRight->addFloat(node,Z_AXIS,iface);
  1909. else
  1910. mRight = node;
  1911. }
  1912. break;
  1913. case Z_AXIS:
  1914. if ( nodePosition[2] <= position[2] )
  1915. {
  1916. if ( mLeft )
  1917. mLeft->addFloat(node,X_AXIS,iface);
  1918. else
  1919. mLeft = node;
  1920. }
  1921. else
  1922. {
  1923. if ( mRight )
  1924. mRight->addFloat(node,X_AXIS,iface);
  1925. else
  1926. mRight = node;
  1927. }
  1928. break;
  1929. }
  1930. }
  1931. NxU32 getIndex(void) const { return mIndex; };
  1932. void search(Axes axis,const NxF64 *pos,NxF64 radius,NxU32 &count,NxU32 maxObjects,KdTreeFindNode *found,const KdTreeInterface *iface)
  1933. {
  1934. const NxF64 *position = iface->getPositionDouble(mIndex);
  1935. NxF64 dx = pos[0] - position[0];
  1936. NxF64 dy = pos[1] - position[1];
  1937. NxF64 dz = pos[2] - position[2];
  1938. KdTreeNode *search1 = 0;
  1939. KdTreeNode *search2 = 0;
  1940. switch ( axis )
  1941. {
  1942. case X_AXIS:
  1943. if ( dx <= 0 ) // JWR if we are to the left
  1944. {
  1945. search1 = mLeft; // JWR then search to the left
  1946. if ( -dx < radius ) // JWR if distance to the right is less than our search radius, continue on the right as well.
  1947. search2 = mRight;
  1948. }
  1949. else
  1950. {
  1951. search1 = mRight; // JWR ok, we go down the left tree
  1952. if ( dx < radius ) // JWR if the distance from the right is less than our search radius
  1953. search2 = mLeft;
  1954. }
  1955. axis = Y_AXIS;
  1956. break;
  1957. case Y_AXIS:
  1958. if ( dy <= 0 )
  1959. {
  1960. search1 = mLeft;
  1961. if ( -dy < radius )
  1962. search2 = mRight;
  1963. }
  1964. else
  1965. {
  1966. search1 = mRight;
  1967. if ( dy < radius )
  1968. search2 = mLeft;
  1969. }
  1970. axis = Z_AXIS;
  1971. break;
  1972. case Z_AXIS:
  1973. if ( dz <= 0 )
  1974. {
  1975. search1 = mLeft;
  1976. if ( -dz < radius )
  1977. search2 = mRight;
  1978. }
  1979. else
  1980. {
  1981. search1 = mRight;
  1982. if ( dz < radius )
  1983. search2 = mLeft;
  1984. }
  1985. axis = X_AXIS;
  1986. break;
  1987. }
  1988. NxF64 r2 = radius*radius;
  1989. NxF64 m = dx*dx+dy*dy+dz*dz;
  1990. if ( m < r2 )
  1991. {
  1992. switch ( count )
  1993. {
  1994. case 0:
  1995. found[count].mNode = this;
  1996. found[count].mDistance = m;
  1997. break;
  1998. case 1:
  1999. if ( m < found[0].mDistance )
  2000. {
  2001. if ( maxObjects == 1 )
  2002. {
  2003. found[0].mNode = this;
  2004. found[0].mDistance = m;
  2005. }
  2006. else
  2007. {
  2008. found[1] = found[0];
  2009. found[0].mNode = this;
  2010. found[0].mDistance = m;
  2011. }
  2012. }
  2013. else if ( maxObjects > 1)
  2014. {
  2015. found[1].mNode = this;
  2016. found[1].mDistance = m;
  2017. }
  2018. break;
  2019. default:
  2020. {
  2021. bool inserted = false;
  2022. for (NxU32 i=0; i<count; i++)
  2023. {
  2024. if ( m < found[i].mDistance ) // if this one is closer than a pre-existing one...
  2025. {
  2026. // insertion sort...
  2027. NxU32 scan = count;
  2028. if ( scan >= maxObjects ) scan=maxObjects-1;
  2029. for (NxU32 j=scan; j>i; j--)
  2030. {
  2031. found[j] = found[j-1];
  2032. }
  2033. found[i].mNode = this;
  2034. found[i].mDistance = m;
  2035. inserted = true;
  2036. break;
  2037. }
  2038. }
  2039. if ( !inserted && count < maxObjects )
  2040. {
  2041. found[count].mNode = this;
  2042. found[count].mDistance = m;
  2043. }
  2044. }
  2045. break;
  2046. }
  2047. count++;
  2048. if ( count > maxObjects )
  2049. {
  2050. count = maxObjects;
  2051. }
  2052. }
  2053. if ( search1 )
  2054. search1->search( axis, pos,radius, count, maxObjects, found, iface);
  2055. if ( search2 )
  2056. search2->search( axis, pos,radius, count, maxObjects, found, iface);
  2057. }
  2058. void search(Axes axis,const NxF32 *pos,NxF32 radius,NxU32 &count,NxU32 maxObjects,KdTreeFindNode *found,const KdTreeInterface *iface)
  2059. {
  2060. const NxF32 *position = iface->getPositionFloat(mIndex);
  2061. NxF32 dx = pos[0] - position[0];
  2062. NxF32 dy = pos[1] - position[1];
  2063. NxF32 dz = pos[2] - position[2];
  2064. KdTreeNode *search1 = 0;
  2065. KdTreeNode *search2 = 0;
  2066. switch ( axis )
  2067. {
  2068. case X_AXIS:
  2069. if ( dx <= 0 ) // JWR if we are to the left
  2070. {
  2071. search1 = mLeft; // JWR then search to the left
  2072. if ( -dx < radius ) // JWR if distance to the right is less than our search radius, continue on the right as well.
  2073. search2 = mRight;
  2074. }
  2075. else
  2076. {
  2077. search1 = mRight; // JWR ok, we go down the left tree
  2078. if ( dx < radius ) // JWR if the distance from the right is less than our search radius
  2079. search2 = mLeft;
  2080. }
  2081. axis = Y_AXIS;
  2082. break;
  2083. case Y_AXIS:
  2084. if ( dy <= 0 )
  2085. {
  2086. search1 = mLeft;
  2087. if ( -dy < radius )
  2088. search2 = mRight;
  2089. }
  2090. else
  2091. {
  2092. search1 = mRight;
  2093. if ( dy < radius )
  2094. search2 = mLeft;
  2095. }
  2096. axis = Z_AXIS;
  2097. break;
  2098. case Z_AXIS:
  2099. if ( dz <= 0 )
  2100. {
  2101. search1 = mLeft;
  2102. if ( -dz < radius )
  2103. search2 = mRight;
  2104. }
  2105. else
  2106. {
  2107. search1 = mRight;
  2108. if ( dz < radius )
  2109. search2 = mLeft;
  2110. }
  2111. axis = X_AXIS;
  2112. break;
  2113. }
  2114. NxF32 r2 = radius*radius;
  2115. NxF32 m = dx*dx+dy*dy+dz*dz;
  2116. if ( m < r2 )
  2117. {
  2118. switch ( count )
  2119. {
  2120. case 0:
  2121. found[count].mNode = this;
  2122. found[count].mDistance = m;
  2123. break;
  2124. case 1:
  2125. if ( m < found[0].mDistance )
  2126. {
  2127. if ( maxObjects == 1 )
  2128. {
  2129. found[0].mNode = this;
  2130. found[0].mDistance = m;
  2131. }
  2132. else
  2133. {
  2134. found[1] = found[0];
  2135. found[0].mNode = this;
  2136. found[0].mDistance = m;
  2137. }
  2138. }
  2139. else if ( maxObjects > 1)
  2140. {
  2141. found[1].mNode = this;
  2142. found[1].mDistance = m;
  2143. }
  2144. break;
  2145. default:
  2146. {
  2147. bool inserted = false;
  2148. for (NxU32 i=0; i<count; i++)
  2149. {
  2150. if ( m < found[i].mDistance ) // if this one is closer than a pre-existing one...
  2151. {
  2152. // insertion sort...
  2153. NxU32 scan = count;
  2154. if ( scan >= maxObjects ) scan=maxObjects-1;
  2155. for (NxU32 j=scan; j>i; j--)
  2156. {
  2157. found[j] = found[j-1];
  2158. }
  2159. found[i].mNode = this;
  2160. found[i].mDistance = m;
  2161. inserted = true;
  2162. break;
  2163. }
  2164. }
  2165. if ( !inserted && count < maxObjects )
  2166. {
  2167. found[count].mNode = this;
  2168. found[count].mDistance = m;
  2169. }
  2170. }
  2171. break;
  2172. }
  2173. count++;
  2174. if ( count > maxObjects )
  2175. {
  2176. count = maxObjects;
  2177. }
  2178. }
  2179. if ( search1 )
  2180. search1->search( axis, pos,radius, count, maxObjects, found, iface);
  2181. if ( search2 )
  2182. search2->search( axis, pos,radius, count, maxObjects, found, iface);
  2183. }
  2184. private:
  2185. void setLeft(KdTreeNode *left) { mLeft = left; };
  2186. void setRight(KdTreeNode *right) { mRight = right; };
  2187. KdTreeNode *getLeft(void) { return mLeft; }
  2188. KdTreeNode *getRight(void) { return mRight; }
  2189. NxU32 mIndex;
  2190. KdTreeNode *mLeft;
  2191. KdTreeNode *mRight;
  2192. };
  2193. #define MAX_BUNDLE_SIZE 1024 // 1024 nodes at a time, to minimize memory allocation and guarentee that pointers are persistent.
  2194. class KdTreeNodeBundle : public Memalloc
  2195. {
  2196. public:
  2197. KdTreeNodeBundle(void)
  2198. {
  2199. mNext = 0;
  2200. mIndex = 0;
  2201. }
  2202. bool isFull(void) const
  2203. {
  2204. return (bool)( mIndex == MAX_BUNDLE_SIZE );
  2205. }
  2206. KdTreeNode * getNextNode(void)
  2207. {
  2208. assert(mIndex<MAX_BUNDLE_SIZE);
  2209. KdTreeNode *ret = &mNodes[mIndex];
  2210. mIndex++;
  2211. return ret;
  2212. }
  2213. KdTreeNodeBundle *mNext;
  2214. NxU32 mIndex;
  2215. KdTreeNode mNodes[MAX_BUNDLE_SIZE];
  2216. };
  2217. typedef CONVEX_DECOMPOSITION::Array< NxF64 > DoubleVector;
  2218. typedef CONVEX_DECOMPOSITION::Array< NxF32 > FloatVector;
  2219. class KdTree : public KdTreeInterface, public Memalloc
  2220. {
  2221. public:
  2222. KdTree(void)
  2223. {
  2224. mRoot = 0;
  2225. mBundle = 0;
  2226. mVcount = 0;
  2227. mUseDouble = false;
  2228. }
  2229. virtual ~KdTree(void)
  2230. {
  2231. reset();
  2232. }
  2233. const NxF64 * getPositionDouble(NxU32 index) const
  2234. {
  2235. assert( mUseDouble );
  2236. assert ( index < mVcount );
  2237. return &mVerticesDouble[index*3];
  2238. }
  2239. const NxF32 * getPositionFloat(NxU32 index) const
  2240. {
  2241. assert( !mUseDouble );
  2242. assert ( index < mVcount );
  2243. return &mVerticesFloat[index*3];
  2244. }
  2245. NxU32 search(const NxF64 *pos,NxF64 radius,NxU32 maxObjects,KdTreeFindNode *found) const
  2246. {
  2247. assert( mUseDouble );
  2248. if ( !mRoot ) return 0;
  2249. NxU32 count = 0;
  2250. mRoot->search(X_AXIS,pos,radius,count,maxObjects,found,this);
  2251. return count;
  2252. }
  2253. NxU32 search(const NxF32 *pos,NxF32 radius,NxU32 maxObjects,KdTreeFindNode *found) const
  2254. {
  2255. assert( !mUseDouble );
  2256. if ( !mRoot ) return 0;
  2257. NxU32 count = 0;
  2258. mRoot->search(X_AXIS,pos,radius,count,maxObjects,found,this);
  2259. return count;
  2260. }
  2261. void reset(void)
  2262. {
  2263. mRoot = 0;
  2264. mVerticesDouble.clear();
  2265. mVerticesFloat.clear();
  2266. KdTreeNodeBundle *bundle = mBundle;
  2267. while ( bundle )
  2268. {
  2269. KdTreeNodeBundle *next = bundle->mNext;
  2270. delete bundle;
  2271. bundle = next;
  2272. }
  2273. mBundle = 0;
  2274. mVcount = 0;
  2275. }
  2276. NxU32 add(NxF64 x,NxF64 y,NxF64 z)
  2277. {
  2278. assert(mUseDouble);
  2279. NxU32 ret = mVcount;
  2280. mVerticesDouble.pushBack(x);
  2281. mVerticesDouble.pushBack(y);
  2282. mVerticesDouble.pushBack(z);
  2283. mVcount++;
  2284. KdTreeNode *node = getNewNode(ret);
  2285. if ( mRoot )
  2286. {
  2287. mRoot->addDouble(node,X_AXIS,this);
  2288. }
  2289. else
  2290. {
  2291. mRoot = node;
  2292. }
  2293. return ret;
  2294. }
  2295. NxU32 add(NxF32 x,NxF32 y,NxF32 z)
  2296. {
  2297. assert(!mUseDouble);
  2298. NxU32 ret = mVcount;
  2299. mVerticesFloat.pushBack(x);
  2300. mVerticesFloat.pushBack(y);
  2301. mVerticesFloat.pushBack(z);
  2302. mVcount++;
  2303. KdTreeNode *node = getNewNode(ret);
  2304. if ( mRoot )
  2305. {
  2306. mRoot->addFloat(node,X_AXIS,this);
  2307. }
  2308. else
  2309. {
  2310. mRoot = node;
  2311. }
  2312. return ret;
  2313. }
  2314. KdTreeNode * getNewNode(NxU32 index)
  2315. {
  2316. if ( mBundle == 0 )
  2317. {
  2318. mBundle = MEMALLOC_NEW(KdTreeNodeBundle);
  2319. }
  2320. if ( mBundle->isFull() )
  2321. {
  2322. KdTreeNodeBundle *bundle = MEMALLOC_NEW(KdTreeNodeBundle);
  2323. mBundle->mNext = bundle;
  2324. mBundle = bundle;
  2325. }
  2326. KdTreeNode *node = mBundle->getNextNode();
  2327. new ( node ) KdTreeNode(index);
  2328. return node;
  2329. }
  2330. NxU32 getNearest(const NxF64 *pos,NxF64 radius,bool &_found) const // returns the nearest possible neighbor's index.
  2331. {
  2332. assert( mUseDouble );
  2333. NxU32 ret = 0;
  2334. _found = false;
  2335. KdTreeFindNode found[1];
  2336. NxU32 count = search(pos,radius,1,found);
  2337. if ( count )
  2338. {
  2339. KdTreeNode *node = found[0].mNode;
  2340. ret = node->getIndex();
  2341. _found = true;
  2342. }
  2343. return ret;
  2344. }
  2345. NxU32 getNearest(const NxF32 *pos,NxF32 radius,bool &_found) const // returns the nearest possible neighbor's index.
  2346. {
  2347. assert( !mUseDouble );
  2348. NxU32 ret = 0;
  2349. _found = false;
  2350. KdTreeFindNode found[1];
  2351. NxU32 count = search(pos,radius,1,found);
  2352. if ( count )
  2353. {
  2354. KdTreeNode *node = found[0].mNode;
  2355. ret = node->getIndex();
  2356. _found = true;
  2357. }
  2358. return ret;
  2359. }
  2360. const NxF64 * getVerticesDouble(void) const
  2361. {
  2362. assert( mUseDouble );
  2363. const NxF64 *ret = 0;
  2364. if ( !mVerticesDouble.empty() )
  2365. {
  2366. ret = &mVerticesDouble[0];
  2367. }
  2368. return ret;
  2369. }
  2370. const NxF32 * getVerticesFloat(void) const
  2371. {
  2372. assert( !mUseDouble );
  2373. const NxF32 * ret = 0;
  2374. if ( !mVerticesFloat.empty() )
  2375. {
  2376. ret = &mVerticesFloat[0];
  2377. }
  2378. return ret;
  2379. }
  2380. NxU32 getVcount(void) const { return mVcount; };
  2381. void setUseDouble(bool useDouble)
  2382. {
  2383. mUseDouble = useDouble;
  2384. }
  2385. private:
  2386. bool mUseDouble;
  2387. KdTreeNode *mRoot;
  2388. KdTreeNodeBundle *mBundle;
  2389. NxU32 mVcount;
  2390. DoubleVector mVerticesDouble;
  2391. FloatVector mVerticesFloat;
  2392. };
  2393. }; // end of namespace VERTEX_INDEX
  2394. class MyVertexIndex : public fm_VertexIndex, public Memalloc
  2395. {
  2396. public:
  2397. MyVertexIndex(NxF64 granularity,bool snapToGrid)
  2398. {
  2399. mDoubleGranularity = granularity;
  2400. mFloatGranularity = (NxF32)granularity;
  2401. mSnapToGrid = snapToGrid;
  2402. mUseDouble = true;
  2403. mKdTree.setUseDouble(true);
  2404. }
  2405. MyVertexIndex(NxF32 granularity,bool snapToGrid)
  2406. {
  2407. mDoubleGranularity = granularity;
  2408. mFloatGranularity = (NxF32)granularity;
  2409. mSnapToGrid = snapToGrid;
  2410. mUseDouble = false;
  2411. mKdTree.setUseDouble(false);
  2412. }
  2413. virtual ~MyVertexIndex(void)
  2414. {
  2415. }
  2416. NxF64 snapToGrid(NxF64 p)
  2417. {
  2418. NxF64 m = fmod(p,mDoubleGranularity);
  2419. p-=m;
  2420. return p;
  2421. }
  2422. NxF32 snapToGrid(NxF32 p)
  2423. {
  2424. NxF32 m = fmodf(p,mFloatGranularity);
  2425. p-=m;
  2426. return p;
  2427. }
  2428. NxU32 getIndex(const NxF32 *_p,bool &newPos) // get index for a vector NxF32
  2429. {
  2430. NxU32 ret;
  2431. if ( mUseDouble )
  2432. {
  2433. NxF64 p[3];
  2434. p[0] = _p[0];
  2435. p[1] = _p[1];
  2436. p[2] = _p[2];
  2437. return getIndex(p,newPos);
  2438. }
  2439. newPos = false;
  2440. NxF32 p[3];
  2441. if ( mSnapToGrid )
  2442. {
  2443. p[0] = snapToGrid(_p[0]);
  2444. p[1] = snapToGrid(_p[1]);
  2445. p[2] = snapToGrid(_p[2]);
  2446. }
  2447. else
  2448. {
  2449. p[0] = _p[0];
  2450. p[1] = _p[1];
  2451. p[2] = _p[2];
  2452. }
  2453. bool found;
  2454. ret = mKdTree.getNearest(p,mFloatGranularity,found);
  2455. if ( !found )
  2456. {
  2457. newPos = true;
  2458. ret = mKdTree.add(p[0],p[1],p[2]);
  2459. }
  2460. return ret;
  2461. }
  2462. NxU32 getIndex(const NxF64 *_p,bool &newPos) // get index for a vector NxF64
  2463. {
  2464. NxU32 ret;
  2465. if ( !mUseDouble )
  2466. {
  2467. NxF32 p[3];
  2468. p[0] = (NxF32)_p[0];
  2469. p[1] = (NxF32)_p[1];
  2470. p[2] = (NxF32)_p[2];
  2471. return getIndex(p,newPos);
  2472. }
  2473. newPos = false;
  2474. NxF64 p[3];
  2475. if ( mSnapToGrid )
  2476. {
  2477. p[0] = snapToGrid(_p[0]);
  2478. p[1] = snapToGrid(_p[1]);
  2479. p[2] = snapToGrid(_p[2]);
  2480. }
  2481. else
  2482. {
  2483. p[0] = _p[0];
  2484. p[1] = _p[1];
  2485. p[2] = _p[2];
  2486. }
  2487. bool found;
  2488. ret = mKdTree.getNearest(p,mDoubleGranularity,found);
  2489. if ( !found )
  2490. {
  2491. newPos = true;
  2492. ret = mKdTree.add(p[0],p[1],p[2]);
  2493. }
  2494. return ret;
  2495. }
  2496. const NxF32 * getVerticesFloat(void) const
  2497. {
  2498. const NxF32 * ret = 0;
  2499. assert( !mUseDouble );
  2500. ret = mKdTree.getVerticesFloat();
  2501. return ret;
  2502. }
  2503. const NxF64 * getVerticesDouble(void) const
  2504. {
  2505. const NxF64 * ret = 0;
  2506. assert( mUseDouble );
  2507. ret = mKdTree.getVerticesDouble();
  2508. return ret;
  2509. }
  2510. const NxF32 * getVertexFloat(NxU32 index) const
  2511. {
  2512. const NxF32 * ret = 0;
  2513. assert( !mUseDouble );
  2514. #ifdef _DEBUG
  2515. NxU32 vcount = mKdTree.getVcount();
  2516. assert( index < vcount );
  2517. #endif
  2518. ret = mKdTree.getVerticesFloat();
  2519. ret = &ret[index*3];
  2520. return ret;
  2521. }
  2522. const NxF64 * getVertexDouble(NxU32 index) const
  2523. {
  2524. const NxF64 * ret = 0;
  2525. assert( mUseDouble );
  2526. #ifdef _DEBUG
  2527. NxU32 vcount = mKdTree.getVcount();
  2528. assert( index < vcount );
  2529. #endif
  2530. ret = mKdTree.getVerticesDouble();
  2531. ret = &ret[index*3];
  2532. return ret;
  2533. }
  2534. NxU32 getVcount(void) const
  2535. {
  2536. return mKdTree.getVcount();
  2537. }
  2538. bool isDouble(void) const
  2539. {
  2540. return mUseDouble;
  2541. }
  2542. bool saveAsObj(const char *fname,NxU32 tcount,NxU32 *indices)
  2543. {
  2544. bool ret = false;
  2545. FILE *fph = fopen(fname,"wb");
  2546. if ( fph )
  2547. {
  2548. ret = true;
  2549. NxU32 vcount = getVcount();
  2550. if ( mUseDouble )
  2551. {
  2552. const NxF64 *v = getVerticesDouble();
  2553. for (NxU32 i=0; i<vcount; i++)
  2554. {
  2555. fprintf(fph,"v %0.9f %0.9f %0.9f\r\n", (NxF32)v[0], (NxF32)v[1], (NxF32)v[2] );
  2556. v+=3;
  2557. }
  2558. }
  2559. else
  2560. {
  2561. const NxF32 *v = getVerticesFloat();
  2562. for (NxU32 i=0; i<vcount; i++)
  2563. {
  2564. fprintf(fph,"v %0.9f %0.9f %0.9f\r\n", v[0], v[1], v[2] );
  2565. v+=3;
  2566. }
  2567. }
  2568. for (NxU32 i=0; i<tcount; i++)
  2569. {
  2570. NxU32 i1 = *indices++;
  2571. NxU32 i2 = *indices++;
  2572. NxU32 i3 = *indices++;
  2573. fprintf(fph,"f %d %d %d\r\n", i1+1, i2+1, i3+1 );
  2574. }
  2575. fclose(fph);
  2576. }
  2577. return ret;
  2578. }
  2579. private:
  2580. bool mUseDouble:1;
  2581. bool mSnapToGrid:1;
  2582. NxF64 mDoubleGranularity;
  2583. NxF32 mFloatGranularity;
  2584. VERTEX_INDEX::KdTree mKdTree;
  2585. };
  2586. fm_VertexIndex * fm_createVertexIndex(NxF64 granularity,bool snapToGrid) // create an indexed vertex system for doubles
  2587. {
  2588. MyVertexIndex *ret = MEMALLOC_NEW(MyVertexIndex)(granularity,snapToGrid);
  2589. return static_cast< fm_VertexIndex *>(ret);
  2590. }
  2591. fm_VertexIndex * fm_createVertexIndex(NxF32 granularity,bool snapToGrid) // create an indexed vertext system for floats
  2592. {
  2593. MyVertexIndex *ret = MEMALLOC_NEW(MyVertexIndex)(granularity,snapToGrid);
  2594. return static_cast< fm_VertexIndex *>(ret);
  2595. }
  2596. void fm_releaseVertexIndex(fm_VertexIndex *vindex)
  2597. {
  2598. MyVertexIndex *m = static_cast< MyVertexIndex *>(vindex);
  2599. delete m;
  2600. }
  2601. #endif // END OF VERTEX WELDING CODE
  2602. //**********************************************************
  2603. //**********************************************************
  2604. //**** LineSweep Line-Segment Intersection Code
  2605. //**********************************************************
  2606. //**********************************************************
  2607. //#ifndef LINE_SWEEP_H
  2608. #if 0
  2609. #define LINE_SWEEP_H
  2610. class fm_quickSort
  2611. {
  2612. public:
  2613. void qsort(void **base,NxI32 num); // perform the qsort.
  2614. protected:
  2615. // -1 less, 0 equal, +1 greater.
  2616. virtual NxI32 compare(void **p1,void **p2) = 0;
  2617. private:
  2618. void inline swap(char **a,char **b);
  2619. };
  2620. void fm_quickSort::swap(char **a,char **b)
  2621. {
  2622. char *tmp;
  2623. if ( a != b )
  2624. {
  2625. tmp = *a;
  2626. *a++ = *b;
  2627. *b++ = tmp;
  2628. }
  2629. }
  2630. void fm_quickSort::qsort(void **b,NxI32 num)
  2631. {
  2632. char *lo,*hi;
  2633. char *mid;
  2634. char *bottom, *top;
  2635. NxI32 size;
  2636. char *lostk[30], *histk[30];
  2637. NxI32 stkptr;
  2638. char **base = (char **)b;
  2639. if (num < 2 ) return;
  2640. stkptr = 0;
  2641. lo = (char *)base;
  2642. hi = (char *)base + sizeof(char **) * (num-1);
  2643. nextone:
  2644. size = (NxI32)(hi - lo) / sizeof(char**) + 1;
  2645. mid = lo + (size / 2) * sizeof(char **);
  2646. swap((char **)mid,(char **)lo);
  2647. bottom = lo;
  2648. top = hi + sizeof(char **);
  2649. for (;;)
  2650. {
  2651. do
  2652. {
  2653. bottom += sizeof(char **);
  2654. } while (bottom <= hi && compare((void **)bottom,(void **)lo) <= 0);
  2655. do
  2656. {
  2657. top -= sizeof(char **);
  2658. } while (top > lo && compare((void **)top,(void **)lo) >= 0);
  2659. if (top < bottom) break;
  2660. swap((char **)bottom,(char **)top);
  2661. }
  2662. swap((char **)lo,(char **)top);
  2663. if ( top - 1 - lo >= hi - bottom )
  2664. {
  2665. if (lo + sizeof(char **) < top)
  2666. {
  2667. lostk[stkptr] = lo;
  2668. histk[stkptr] = top - sizeof(char **);
  2669. stkptr++;
  2670. }
  2671. if (bottom < hi)
  2672. {
  2673. lo = bottom;
  2674. goto nextone;
  2675. }
  2676. }
  2677. else
  2678. {
  2679. if ( bottom < hi )
  2680. {
  2681. lostk[stkptr] = bottom;
  2682. histk[stkptr] = hi;
  2683. stkptr++;
  2684. }
  2685. if (lo + sizeof(char **) < top)
  2686. {
  2687. hi = top - sizeof(char **);
  2688. goto nextone; /* do small recursion */
  2689. }
  2690. }
  2691. stkptr--;
  2692. if (stkptr >= 0)
  2693. {
  2694. lo = lostk[stkptr];
  2695. hi = histk[stkptr];
  2696. goto nextone;
  2697. }
  2698. return;
  2699. }
  2700. typedef CONVEX_DECOMPOSITION::Array< fm_LineSegment > LineSegmentVector;
  2701. static inline void setMinMax(NxF64 &vmin,NxF64 &vmax,NxF64 v1,NxF64 v2)
  2702. {
  2703. if ( v1 <= v2 )
  2704. {
  2705. vmin = v1;
  2706. vmax = v2;
  2707. }
  2708. else
  2709. {
  2710. vmin = v2;
  2711. vmax = v1;
  2712. }
  2713. }
  2714. class Intersection
  2715. {
  2716. public:
  2717. Intersection(void)
  2718. {
  2719. mIndex = 0;
  2720. mTime = 0;
  2721. }
  2722. Intersection(NxF64 time,const NxF64 *from,const NxF64 *to,fm_VertexIndex *vpool)
  2723. {
  2724. mTime = time;
  2725. NxF64 pos[3];
  2726. pos[0] = (to[0]-from[0])*time+from[0];
  2727. pos[1] = (to[1]-from[1])*time+from[1];
  2728. pos[2] = (to[2]-from[2])*time+from[2];
  2729. bool newPos;
  2730. mIndex = vpool->getIndex(pos,newPos);
  2731. }
  2732. NxU32 mIndex;
  2733. NxF64 mTime;
  2734. };
  2735. typedef CONVEX_DECOMPOSITION::Array< Intersection > IntersectionList;
  2736. class MyLineSegment : public fm_LineSegment, public Memalloc
  2737. {
  2738. public:
  2739. void init(const fm_LineSegment &s,fm_VertexIndex *vpool,NxU32 x)
  2740. {
  2741. fm_LineSegment *dest = static_cast< fm_LineSegment *>(this);
  2742. *dest = s;
  2743. mFlipped = false;
  2744. const NxF64 *p1 = vpool->getVertexDouble(mE1);
  2745. const NxF64 *p2 = vpool->getVertexDouble(mE2);
  2746. setMinMax(mMin[0],mMax[0],p1[0],p2[0]);
  2747. setMinMax(mMin[1],mMax[1],p1[1],p2[1]);
  2748. setMinMax(mMin[2],mMax[2],p1[2],p2[2]);
  2749. if ( p1[x] <= p2[x] )
  2750. {
  2751. mFrom[0] = p1[0];
  2752. mFrom[1] = p1[1];
  2753. mFrom[2] = p1[2];
  2754. mTo[0] = p2[0];
  2755. mTo[1] = p2[1];
  2756. mTo[2] = p2[2];
  2757. }
  2758. else
  2759. {
  2760. mFrom[0] = p2[0];
  2761. mFrom[1] = p2[1];
  2762. mFrom[2] = p2[2];
  2763. mTo[0] = p1[0];
  2764. mTo[1] = p1[1];
  2765. mTo[2] = p1[2];
  2766. mFlipped = true;
  2767. swap(mE1,mE2);
  2768. }
  2769. }
  2770. // we already know that the x-extent overlaps or we wouldn't be in this routine..
  2771. void intersect(MyLineSegment *segment,NxU32 x,NxU32 y,NxU32 /* z */,fm_VertexIndex *vpool)
  2772. {
  2773. NxU32 count = 0;
  2774. // if the two segments share any start/end points then they cannot intersect at all!
  2775. if ( segment->mE1 == mE1 || segment->mE1 == mE2 ) count++;
  2776. if ( segment->mE2 == mE1 || segment->mE2 == mE2 ) count++;
  2777. if ( count == 0 )
  2778. {
  2779. if ( mMax[y] < segment->mMin[y] ) // no intersection...
  2780. {
  2781. }
  2782. else if ( mMin[y] > segment->mMax[y] ) // no intersection
  2783. {
  2784. }
  2785. else
  2786. {
  2787. NxF64 a1[2];
  2788. NxF64 a2[2];
  2789. NxF64 b1[2];
  2790. NxF64 b2[2];
  2791. a1[0] = mFrom[x];
  2792. a1[1] = mFrom[y];
  2793. a2[0] = mTo[x];
  2794. a2[1] = mTo[y];
  2795. b1[0] = segment->mFrom[x];
  2796. b1[1] = segment->mFrom[y];
  2797. b2[0] = segment->mTo[x];
  2798. b2[1] = segment->mTo[y];
  2799. NxF64 t1,t2;
  2800. IntersectResult result = fm_intersectLineSegments2dTime(a1,a2,b1,b2,t1,t2);
  2801. if ( result == IR_DO_INTERSECT )
  2802. {
  2803. addIntersect(t1,vpool);
  2804. segment->addIntersect(t2,vpool);
  2805. }
  2806. }
  2807. }
  2808. }
  2809. void addIntersect(NxF64 time,fm_VertexIndex *vpool)
  2810. {
  2811. Intersection intersect(time,mFrom,mTo,vpool);
  2812. if ( mE1 == intersect.mIndex || mE2 == intersect.mIndex )
  2813. {
  2814. //printf("Split too close to the beginning or the end of the line segment.\r\n");
  2815. }
  2816. else
  2817. {
  2818. if ( mIntersections.empty() )
  2819. {
  2820. mIntersections.pushBack(intersect);
  2821. }
  2822. else
  2823. {
  2824. IntersectionList::Iterator i;
  2825. for (i=mIntersections.begin(); i!=mIntersections.end(); ++i)
  2826. {
  2827. Intersection &it = (*i);
  2828. if ( it.mIndex == intersect.mIndex )
  2829. {
  2830. //printf("Duplicate Intersection, throwing it away.\r\n");
  2831. break;
  2832. }
  2833. else
  2834. {
  2835. if ( it.mTime > time )
  2836. {
  2837. //*** TODO TODO TODO mIntersections.insert(i,intersect);
  2838. break;
  2839. }
  2840. }
  2841. }
  2842. if ( i==mIntersections.end() )
  2843. {
  2844. mIntersections.pushBack(intersect);
  2845. }
  2846. }
  2847. }
  2848. }
  2849. void getResults(LineSegmentVector &results)
  2850. {
  2851. if ( mIntersections.empty() )
  2852. {
  2853. fm_LineSegment seg(mE1,mE2);
  2854. if ( mFlipped )
  2855. {
  2856. swap(seg.mE1,seg.mE2);
  2857. }
  2858. results.pushBack(seg);
  2859. }
  2860. else
  2861. {
  2862. NxU32 prev = mE1;
  2863. IntersectionList::Iterator i;
  2864. for (i=mIntersections.begin(); i!=mIntersections.end(); ++i)
  2865. {
  2866. Intersection &it = (*i);
  2867. fm_LineSegment seg(prev,it.mIndex);
  2868. if ( mFlipped )
  2869. {
  2870. swap(seg.mE1,seg.mE2);
  2871. }
  2872. results.pushBack(seg);
  2873. prev = it.mIndex;
  2874. }
  2875. fm_LineSegment seg(prev,mE2);
  2876. if ( mFlipped )
  2877. {
  2878. swap(seg.mE1,seg.mE2);
  2879. }
  2880. results.pushBack(seg);
  2881. }
  2882. }
  2883. void swap(NxU32 &a,NxU32 &b)
  2884. {
  2885. NxU32 temp = a;
  2886. a = b;
  2887. b = temp;
  2888. }
  2889. bool mFlipped;
  2890. NxF64 mFrom[3];
  2891. NxF64 mTo[3];
  2892. NxF64 mMin[3];
  2893. NxF64 mMax[3];
  2894. IntersectionList mIntersections;
  2895. };
  2896. typedef CONVEX_DECOMPOSITION::Array< MyLineSegment > MyLineSegmentVector;
  2897. class MyLineSweep : public fm_LineSweep, public fm_quickSort, public Memalloc
  2898. {
  2899. public:
  2900. virtual ~MyLineSweep(void)
  2901. {
  2902. }
  2903. fm_LineSegment * performLineSweep(const fm_LineSegment *segments,NxU32 icount,const NxF64 *planeEquation,fm_VertexIndex *pool,NxU32 &scount)
  2904. {
  2905. fm_LineSegment *ret = 0;
  2906. FM_Axis axis = fm_getDominantAxis(planeEquation);
  2907. switch ( axis )
  2908. {
  2909. case FM_XAXIS:
  2910. mX = 1;
  2911. mY = 2;
  2912. mZ = 0;
  2913. break;
  2914. case FM_YAXIS:
  2915. mX = 0;
  2916. mY = 2;
  2917. mZ = 1;
  2918. break;
  2919. case FM_ZAXIS:
  2920. mX = 0;
  2921. mY = 1;
  2922. mZ = 2;
  2923. break;
  2924. }
  2925. mResults.clear();
  2926. scount = 0;
  2927. MyLineSegment *mls = MEMALLOC_NEW(MyLineSegment)[icount];
  2928. MyLineSegment **mptr = (MyLineSegment **)MEMALLOC_MALLOC(sizeof(MyLineSegment *)*icount);
  2929. for (NxU32 i=0; i<icount; i++)
  2930. {
  2931. mls[i].init(segments[i],pool,mX);
  2932. mptr[i] = &mls[i];
  2933. }
  2934. qsort((void **)mptr,(NxI32)icount);
  2935. for (NxU32 i=0; i<icount; i++)
  2936. {
  2937. MyLineSegment *segment = mptr[i];
  2938. NxF64 esegment = segment->mTo[mX];
  2939. for (NxU32 j=i+1; j<icount; j++)
  2940. {
  2941. MyLineSegment *test = mptr[j];
  2942. if ( test->mFrom[mX] >= esegment )
  2943. {
  2944. break;
  2945. }
  2946. else
  2947. {
  2948. test->intersect(segment,mX,mY,mZ,pool);
  2949. }
  2950. }
  2951. }
  2952. for (NxU32 i=0; i<icount; i++)
  2953. {
  2954. MyLineSegment *segment = mptr[i];
  2955. segment->getResults(mResults);
  2956. }
  2957. delete []mls;
  2958. MEMALLOC_FREE(mptr);
  2959. if ( !mResults.empty() )
  2960. {
  2961. scount = (NxU32)mResults.size();
  2962. ret = &mResults[0];
  2963. }
  2964. return ret;
  2965. }
  2966. NxI32 compare(void **p1,void **p2)
  2967. {
  2968. NxI32 ret = 0;
  2969. MyLineSegment **m1 = (MyLineSegment **) p1;
  2970. MyLineSegment **m2 = (MyLineSegment **) p2;
  2971. MyLineSegment *s1 = *m1;
  2972. MyLineSegment *s2 = *m2;
  2973. if ( s1->mFrom[mX] < s2->mFrom[mX] )
  2974. ret = -1;
  2975. else if ( s1->mFrom[mX] > s2->mFrom[mX] )
  2976. ret = 1;
  2977. else if ( s1->mFrom[mY] < s2->mFrom[mY] )
  2978. ret = -1;
  2979. else if ( s1->mFrom[mY] > s2->mFrom[mY] )
  2980. ret = 1;
  2981. return ret;
  2982. }
  2983. NxU32 mX; // index for the x-axis
  2984. NxU32 mY; // index for the y-axis
  2985. NxU32 mZ;
  2986. fm_VertexIndex *mfm_VertexIndex;
  2987. LineSegmentVector mResults;
  2988. };
  2989. fm_LineSweep * fm_createLineSweep(void)
  2990. {
  2991. MyLineSweep *mls = MEMALLOC_NEW(MyLineSweep);
  2992. return static_cast< fm_LineSweep *>(mls);
  2993. }
  2994. void fm_releaseLineSweep(fm_LineSweep *sweep)
  2995. {
  2996. MyLineSweep *mls = static_cast< MyLineSweep *>(sweep);
  2997. delete mls;
  2998. }
  2999. #endif // End of LineSweep code
  3000. REAL fm_computeBestFitAABB(NxU32 vcount,const REAL *points,NxU32 pstride,REAL *bmin,REAL *bmax) // returns the diagonal distance
  3001. {
  3002. const NxU8 *source = (const NxU8 *) points;
  3003. bmin[0] = points[0];
  3004. bmin[1] = points[1];
  3005. bmin[2] = points[2];
  3006. bmax[0] = points[0];
  3007. bmax[1] = points[1];
  3008. bmax[2] = points[2];
  3009. for (NxU32 i=1; i<vcount; i++)
  3010. {
  3011. source+=pstride;
  3012. const REAL *p = (const REAL *) source;
  3013. if ( p[0] < bmin[0] ) bmin[0] = p[0];
  3014. if ( p[1] < bmin[1] ) bmin[1] = p[1];
  3015. if ( p[2] < bmin[2] ) bmin[2] = p[2];
  3016. if ( p[0] > bmax[0] ) bmax[0] = p[0];
  3017. if ( p[1] > bmax[1] ) bmax[1] = p[1];
  3018. if ( p[2] > bmax[2] ) bmax[2] = p[2];
  3019. }
  3020. REAL dx = bmax[0] - bmin[0];
  3021. REAL dy = bmax[1] - bmin[1];
  3022. REAL dz = bmax[2] - bmin[2];
  3023. return (REAL) sqrt( dx*dx + dy*dy + dz*dz );
  3024. }
  3025. /* a = b - c */
  3026. #define vector(a,b,c) \
  3027. (a)[0] = (b)[0] - (c)[0]; \
  3028. (a)[1] = (b)[1] - (c)[1]; \
  3029. (a)[2] = (b)[2] - (c)[2];
  3030. #define innerProduct(v,q) \
  3031. ((v)[0] * (q)[0] + \
  3032. (v)[1] * (q)[1] + \
  3033. (v)[2] * (q)[2])
  3034. #define crossProduct(a,b,c) \
  3035. (a)[0] = (b)[1] * (c)[2] - (c)[1] * (b)[2]; \
  3036. (a)[1] = (b)[2] * (c)[0] - (c)[2] * (b)[0]; \
  3037. (a)[2] = (b)[0] * (c)[1] - (c)[0] * (b)[1];
  3038. bool fm_lineIntersectsTriangle(const REAL *rayStart,const REAL *rayEnd,const REAL *p1,const REAL *p2,const REAL *p3,REAL *sect)
  3039. {
  3040. REAL dir[3];
  3041. dir[0] = rayEnd[0] - rayStart[0];
  3042. dir[1] = rayEnd[1] - rayStart[1];
  3043. dir[2] = rayEnd[2] - rayStart[2];
  3044. REAL d = (REAL)sqrt(dir[0]*dir[0] + dir[1]*dir[1] + dir[2]*dir[2]);
  3045. REAL r = 1.0f / d;
  3046. dir[0]*=r;
  3047. dir[1]*=r;
  3048. dir[2]*=r;
  3049. REAL t;
  3050. bool ret = fm_rayIntersectsTriangle(rayStart, dir, p1, p2, p3, t );
  3051. if ( ret )
  3052. {
  3053. if ( t > d )
  3054. {
  3055. sect[0] = rayStart[0] + dir[0]*t;
  3056. sect[1] = rayStart[1] + dir[1]*t;
  3057. sect[2] = rayStart[2] + dir[2]*t;
  3058. }
  3059. else
  3060. {
  3061. ret = false;
  3062. }
  3063. }
  3064. return ret;
  3065. }
  3066. bool fm_rayIntersectsTriangle(const REAL *p,const REAL *d,const REAL *v0,const REAL *v1,const REAL *v2,REAL &t)
  3067. {
  3068. REAL e1[3],e2[3],h[3],s[3],q[3];
  3069. REAL a,f,u,v;
  3070. vector(e1,v1,v0);
  3071. vector(e2,v2,v0);
  3072. crossProduct(h,d,e2);
  3073. a = innerProduct(e1,h);
  3074. if (a > -0.00001 && a < 0.00001)
  3075. return(false);
  3076. f = 1/a;
  3077. vector(s,p,v0);
  3078. u = f * (innerProduct(s,h));
  3079. if (u < 0.0 || u > 1.0)
  3080. return(false);
  3081. crossProduct(q,s,e1);
  3082. v = f * innerProduct(d,q);
  3083. if (v < 0.0 || u + v > 1.0)
  3084. return(false);
  3085. // at this stage we can compute t to find out where
  3086. // the intersection point is on the line
  3087. t = f * innerProduct(e2,q);
  3088. if (t > 0) // ray intersection
  3089. return(true);
  3090. else // this means that there is a line intersection
  3091. // but not a ray intersection
  3092. return (false);
  3093. }
  3094. inline REAL det(const REAL *p1,const REAL *p2,const REAL *p3)
  3095. {
  3096. return p1[0]*p2[1]*p3[2] + p2[0]*p3[1]*p1[2] + p3[0]*p1[1]*p2[2] -p1[0]*p3[1]*p2[2] - p2[0]*p1[1]*p3[2] - p3[0]*p2[1]*p1[2];
  3097. }
  3098. REAL fm_computeMeshVolume(const REAL *vertices,NxU32 tcount,const NxU32 *indices)
  3099. {
  3100. REAL volume = 0;
  3101. for (NxU32 i=0; i<tcount; i++,indices+=3)
  3102. {
  3103. const REAL *p1 = &vertices[ indices[0]*3 ];
  3104. const REAL *p2 = &vertices[ indices[1]*3 ];
  3105. const REAL *p3 = &vertices[ indices[2]*3 ];
  3106. volume+=det(p1,p2,p3); // compute the volume of the tetrahedran relative to the origin.
  3107. }
  3108. volume*=(1.0f/6.0f);
  3109. if ( volume < 0 )
  3110. volume*=-1;
  3111. return volume;
  3112. }
  3113. const REAL * fm_getPoint(const REAL *points,NxU32 pstride,NxU32 index)
  3114. {
  3115. const NxU8 *scan = (const NxU8 *)points;
  3116. scan+=(index*pstride);
  3117. return (REAL *)scan;
  3118. }
  3119. bool fm_insideTriangle(REAL Ax, REAL Ay,
  3120. REAL Bx, REAL By,
  3121. REAL Cx, REAL Cy,
  3122. REAL Px, REAL Py)
  3123. {
  3124. REAL ax, ay, bx, by, cx, cy, apx, apy, bpx, bpy, cpx, cpy;
  3125. REAL cCROSSap, bCROSScp, aCROSSbp;
  3126. ax = Cx - Bx; ay = Cy - By;
  3127. bx = Ax - Cx; by = Ay - Cy;
  3128. cx = Bx - Ax; cy = By - Ay;
  3129. apx= Px - Ax; apy= Py - Ay;
  3130. bpx= Px - Bx; bpy= Py - By;
  3131. cpx= Px - Cx; cpy= Py - Cy;
  3132. aCROSSbp = ax*bpy - ay*bpx;
  3133. cCROSSap = cx*apy - cy*apx;
  3134. bCROSScp = bx*cpy - by*cpx;
  3135. return ((aCROSSbp >= 0.0f) && (bCROSScp >= 0.0f) && (cCROSSap >= 0.0f));
  3136. }
  3137. REAL fm_areaPolygon2d(NxU32 pcount,const REAL *points,NxU32 pstride)
  3138. {
  3139. NxI32 n = (NxI32)pcount;
  3140. REAL A=0.0f;
  3141. for(NxI32 p=n-1,q=0; q<n; p=q++)
  3142. {
  3143. const REAL *p1 = fm_getPoint(points,pstride,p);
  3144. const REAL *p2 = fm_getPoint(points,pstride,q);
  3145. A+= p1[0]*p2[1] - p2[0]*p1[1];
  3146. }
  3147. return A*0.5f;
  3148. }
  3149. bool fm_pointInsidePolygon2d(NxU32 pcount,const REAL *points,NxU32 pstride,const REAL *point,NxU32 xindex,NxU32 yindex)
  3150. {
  3151. NxU32 j = pcount-1;
  3152. NxI32 oddNodes = 0;
  3153. REAL x = point[xindex];
  3154. REAL y = point[yindex];
  3155. for (NxU32 i=0; i<pcount; i++)
  3156. {
  3157. const REAL *p1 = fm_getPoint(points,pstride,i);
  3158. const REAL *p2 = fm_getPoint(points,pstride,j);
  3159. REAL x1 = p1[xindex];
  3160. REAL y1 = p1[yindex];
  3161. REAL x2 = p2[xindex];
  3162. REAL y2 = p2[yindex];
  3163. if ( y1 < y && y2 >= y || y2 < y && y1 >= y )
  3164. {
  3165. if (x1+(y-y1)/(y2-y1)*(x2-x1)<x)
  3166. {
  3167. oddNodes = 1-oddNodes;
  3168. }
  3169. }
  3170. j = i;
  3171. }
  3172. return oddNodes ? true : false;
  3173. }
  3174. NxU32 fm_consolidatePolygon(NxU32 pcount,const REAL *points,NxU32 pstride,REAL *_dest,REAL epsilon) // collapses co-linear edges.
  3175. {
  3176. NxU32 ret = 0;
  3177. if ( pcount >= 3 )
  3178. {
  3179. const REAL *prev = fm_getPoint(points,pstride,pcount-1);
  3180. const REAL *current = points;
  3181. const REAL *next = fm_getPoint(points,pstride,1);
  3182. REAL *dest = _dest;
  3183. for (NxU32 i=0; i<pcount; i++)
  3184. {
  3185. next = (i+1)==pcount ? points : next;
  3186. if ( !fm_colinear(prev,current,next,epsilon) )
  3187. {
  3188. dest[0] = current[0];
  3189. dest[1] = current[1];
  3190. dest[2] = current[2];
  3191. dest+=3;
  3192. ret++;
  3193. }
  3194. prev = current;
  3195. current+=3;
  3196. next+=3;
  3197. }
  3198. }
  3199. return ret;
  3200. }
  3201. #ifndef RECT3D_TEMPLATE
  3202. #define RECT3D_TEMPLATE
  3203. template <class T> class Rect3d
  3204. {
  3205. public:
  3206. Rect3d(void) { };
  3207. Rect3d(const T *bmin,const T *bmax)
  3208. {
  3209. mMin[0] = bmin[0];
  3210. mMin[1] = bmin[1];
  3211. mMin[2] = bmin[2];
  3212. mMax[0] = bmax[0];
  3213. mMax[1] = bmax[1];
  3214. mMax[2] = bmax[2];
  3215. }
  3216. void SetMin(const T *bmin)
  3217. {
  3218. mMin[0] = bmin[0];
  3219. mMin[1] = bmin[1];
  3220. mMin[2] = bmin[2];
  3221. }
  3222. void SetMax(const T *bmax)
  3223. {
  3224. mMax[0] = bmax[0];
  3225. mMax[1] = bmax[1];
  3226. mMax[2] = bmax[2];
  3227. }
  3228. void SetMin(T x,T y,T z)
  3229. {
  3230. mMin[0] = x;
  3231. mMin[1] = y;
  3232. mMin[2] = z;
  3233. }
  3234. void SetMax(T x,T y,T z)
  3235. {
  3236. mMax[0] = x;
  3237. mMax[1] = y;
  3238. mMax[2] = z;
  3239. }
  3240. T mMin[3];
  3241. T mMax[3];
  3242. };
  3243. #endif
  3244. void splitRect(NxU32 axis,
  3245. const Rect3d<REAL> &source,
  3246. Rect3d<REAL> &b1,
  3247. Rect3d<REAL> &b2,
  3248. const REAL *midpoint)
  3249. {
  3250. switch ( axis )
  3251. {
  3252. case 0:
  3253. b1.SetMin(source.mMin);
  3254. b1.SetMax( midpoint[0], source.mMax[1], source.mMax[2] );
  3255. b2.SetMin( midpoint[0], source.mMin[1], source.mMin[2] );
  3256. b2.SetMax(source.mMax);
  3257. break;
  3258. case 1:
  3259. b1.SetMin(source.mMin);
  3260. b1.SetMax( source.mMax[0], midpoint[1], source.mMax[2] );
  3261. b2.SetMin( source.mMin[0], midpoint[1], source.mMin[2] );
  3262. b2.SetMax(source.mMax);
  3263. break;
  3264. case 2:
  3265. b1.SetMin(source.mMin);
  3266. b1.SetMax( source.mMax[0], source.mMax[1], midpoint[2] );
  3267. b2.SetMin( source.mMin[0], source.mMin[1], midpoint[2] );
  3268. b2.SetMax(source.mMax);
  3269. break;
  3270. }
  3271. }
  3272. bool fm_computeSplitPlane(NxU32 vcount,
  3273. const REAL *vertices,
  3274. NxU32 /* tcount */,
  3275. const NxU32 * /* indices */,
  3276. REAL *plane)
  3277. {
  3278. REAL sides[3];
  3279. REAL matrix[16];
  3280. fm_computeBestFitOBB( vcount, vertices, sizeof(REAL)*3, sides, matrix );
  3281. REAL bmax[3];
  3282. REAL bmin[3];
  3283. bmax[0] = sides[0]*0.5f;
  3284. bmax[1] = sides[1]*0.5f;
  3285. bmax[2] = sides[2]*0.5f;
  3286. bmin[0] = -bmax[0];
  3287. bmin[1] = -bmax[1];
  3288. bmin[2] = -bmax[2];
  3289. REAL dx = sides[0];
  3290. REAL dy = sides[1];
  3291. REAL dz = sides[2];
  3292. REAL laxis = dx;
  3293. NxU32 axis = 0;
  3294. if ( dy > dx )
  3295. {
  3296. axis = 1;
  3297. laxis = dy;
  3298. }
  3299. if ( dz > dx && dz > dy )
  3300. {
  3301. axis = 2;
  3302. laxis = dz;
  3303. }
  3304. REAL p1[3];
  3305. REAL p2[3];
  3306. REAL p3[3];
  3307. p3[0] = p2[0] = p1[0] = bmin[0] + dx*0.5f;
  3308. p3[1] = p2[1] = p1[1] = bmin[1] + dy*0.5f;
  3309. p3[2] = p2[2] = p1[2] = bmin[2] + dz*0.5f;
  3310. Rect3d<REAL> b(bmin,bmax);
  3311. Rect3d<REAL> b1,b2;
  3312. splitRect(axis,b,b1,b2,p1);
  3313. switch ( axis )
  3314. {
  3315. case 0:
  3316. p2[1] = bmin[1];
  3317. p2[2] = bmin[2];
  3318. if ( dz > dy )
  3319. {
  3320. p3[1] = bmax[1];
  3321. p3[2] = bmin[2];
  3322. }
  3323. else
  3324. {
  3325. p3[1] = bmin[1];
  3326. p3[2] = bmax[2];
  3327. }
  3328. break;
  3329. case 1:
  3330. p2[0] = bmin[0];
  3331. p2[2] = bmin[2];
  3332. if ( dx > dz )
  3333. {
  3334. p3[0] = bmax[0];
  3335. p3[2] = bmin[2];
  3336. }
  3337. else
  3338. {
  3339. p3[0] = bmin[0];
  3340. p3[2] = bmax[2];
  3341. }
  3342. break;
  3343. case 2:
  3344. p2[0] = bmin[0];
  3345. p2[1] = bmin[1];
  3346. if ( dx > dy )
  3347. {
  3348. p3[0] = bmax[0];
  3349. p3[1] = bmin[1];
  3350. }
  3351. else
  3352. {
  3353. p3[0] = bmin[0];
  3354. p3[1] = bmax[1];
  3355. }
  3356. break;
  3357. }
  3358. REAL tp1[3];
  3359. REAL tp2[3];
  3360. REAL tp3[3];
  3361. fm_transform(matrix,p1,tp1);
  3362. fm_transform(matrix,p2,tp2);
  3363. fm_transform(matrix,p3,tp3);
  3364. plane[3] = fm_computePlane(tp1,tp2,tp3,plane);
  3365. return true;
  3366. }
  3367. #pragma warning(disable:4100)
  3368. void fm_nearestPointInTriangle(const REAL *nearestPoint,const REAL *p1,const REAL *p2,const REAL *p3,REAL *nearest)
  3369. {
  3370. }
  3371. static REAL Partial(const REAL *a,const REAL *p)
  3372. {
  3373. return (a[0]*p[1]) - (p[0]*a[1]);
  3374. }
  3375. REAL fm_areaTriangle(const REAL *p0,const REAL *p1,const REAL *p2)
  3376. {
  3377. REAL A = Partial(p0,p1);
  3378. A+= Partial(p1,p2);
  3379. A+= Partial(p2,p0);
  3380. return A*0.5f;
  3381. }
  3382. void fm_subtract(const REAL *A,const REAL *B,REAL *diff) // compute A-B and store the result in 'diff'
  3383. {
  3384. diff[0] = A[0]-B[0];
  3385. diff[1] = A[1]-B[1];
  3386. diff[2] = A[2]-B[2];
  3387. }
  3388. void fm_multiplyTransform(const REAL *pA,const REAL *pB,REAL *pM)
  3389. {
  3390. REAL a = pA[0*4+0] * pB[0*4+0] + pA[0*4+1] * pB[1*4+0] + pA[0*4+2] * pB[2*4+0] + pA[0*4+3] * pB[3*4+0];
  3391. REAL b = pA[0*4+0] * pB[0*4+1] + pA[0*4+1] * pB[1*4+1] + pA[0*4+2] * pB[2*4+1] + pA[0*4+3] * pB[3*4+1];
  3392. REAL c = pA[0*4+0] * pB[0*4+2] + pA[0*4+1] * pB[1*4+2] + pA[0*4+2] * pB[2*4+2] + pA[0*4+3] * pB[3*4+2];
  3393. REAL d = pA[0*4+0] * pB[0*4+3] + pA[0*4+1] * pB[1*4+3] + pA[0*4+2] * pB[2*4+3] + pA[0*4+3] * pB[3*4+3];
  3394. REAL e = pA[1*4+0] * pB[0*4+0] + pA[1*4+1] * pB[1*4+0] + pA[1*4+2] * pB[2*4+0] + pA[1*4+3] * pB[3*4+0];
  3395. REAL f = pA[1*4+0] * pB[0*4+1] + pA[1*4+1] * pB[1*4+1] + pA[1*4+2] * pB[2*4+1] + pA[1*4+3] * pB[3*4+1];
  3396. REAL g = pA[1*4+0] * pB[0*4+2] + pA[1*4+1] * pB[1*4+2] + pA[1*4+2] * pB[2*4+2] + pA[1*4+3] * pB[3*4+2];
  3397. REAL h = pA[1*4+0] * pB[0*4+3] + pA[1*4+1] * pB[1*4+3] + pA[1*4+2] * pB[2*4+3] + pA[1*4+3] * pB[3*4+3];
  3398. REAL i = pA[2*4+0] * pB[0*4+0] + pA[2*4+1] * pB[1*4+0] + pA[2*4+2] * pB[2*4+0] + pA[2*4+3] * pB[3*4+0];
  3399. REAL j = pA[2*4+0] * pB[0*4+1] + pA[2*4+1] * pB[1*4+1] + pA[2*4+2] * pB[2*4+1] + pA[2*4+3] * pB[3*4+1];
  3400. REAL k = pA[2*4+0] * pB[0*4+2] + pA[2*4+1] * pB[1*4+2] + pA[2*4+2] * pB[2*4+2] + pA[2*4+3] * pB[3*4+2];
  3401. REAL l = pA[2*4+0] * pB[0*4+3] + pA[2*4+1] * pB[1*4+3] + pA[2*4+2] * pB[2*4+3] + pA[2*4+3] * pB[3*4+3];
  3402. REAL m = pA[3*4+0] * pB[0*4+0] + pA[3*4+1] * pB[1*4+0] + pA[3*4+2] * pB[2*4+0] + pA[3*4+3] * pB[3*4+0];
  3403. REAL n = pA[3*4+0] * pB[0*4+1] + pA[3*4+1] * pB[1*4+1] + pA[3*4+2] * pB[2*4+1] + pA[3*4+3] * pB[3*4+1];
  3404. REAL o = pA[3*4+0] * pB[0*4+2] + pA[3*4+1] * pB[1*4+2] + pA[3*4+2] * pB[2*4+2] + pA[3*4+3] * pB[3*4+2];
  3405. REAL p = pA[3*4+0] * pB[0*4+3] + pA[3*4+1] * pB[1*4+3] + pA[3*4+2] * pB[2*4+3] + pA[3*4+3] * pB[3*4+3];
  3406. pM[0] = a; pM[1] = b; pM[2] = c; pM[3] = d;
  3407. pM[4] = e; pM[5] = f; pM[6] = g; pM[7] = h;
  3408. pM[8] = i; pM[9] = j; pM[10] = k; pM[11] = l;
  3409. pM[12] = m; pM[13] = n; pM[14] = o; pM[15] = p;
  3410. }
  3411. void fm_multiply(REAL *A,REAL scaler)
  3412. {
  3413. A[0]*=scaler;
  3414. A[1]*=scaler;
  3415. A[2]*=scaler;
  3416. }
  3417. void fm_add(const REAL *A,const REAL *B,REAL *sum)
  3418. {
  3419. sum[0] = A[0]+B[0];
  3420. sum[1] = A[1]+B[1];
  3421. sum[2] = A[2]+B[2];
  3422. }
  3423. void fm_copy3(const REAL *source,REAL *dest)
  3424. {
  3425. dest[0] = source[0];
  3426. dest[1] = source[1];
  3427. dest[2] = source[2];
  3428. }
  3429. NxU32 fm_copyUniqueVertices(NxU32 vcount,const REAL *input_vertices,REAL *output_vertices,NxU32 tcount,const NxU32 *input_indices,NxU32 *output_indices)
  3430. {
  3431. NxU32 ret = 0;
  3432. REAL *vertices = (REAL *)MEMALLOC_MALLOC(sizeof(REAL)*vcount*3);
  3433. memcpy(vertices,input_vertices,sizeof(REAL)*vcount*3);
  3434. REAL *dest = output_vertices;
  3435. NxU32 *reindex = (NxU32 *)MEMALLOC_MALLOC(sizeof(NxU32)*vcount);
  3436. memset(reindex,0xFF,sizeof(NxU32)*vcount);
  3437. NxU32 icount = tcount*3;
  3438. for (NxU32 i=0; i<icount; i++)
  3439. {
  3440. NxU32 index = *input_indices++;
  3441. assert( index < vcount );
  3442. if ( reindex[index] == 0xFFFFFFFF )
  3443. {
  3444. *output_indices++ = ret;
  3445. reindex[index] = ret;
  3446. const REAL *pos = &vertices[index*3];
  3447. dest[0] = pos[0];
  3448. dest[1] = pos[1];
  3449. dest[2] = pos[2];
  3450. dest+=3;
  3451. ret++;
  3452. }
  3453. else
  3454. {
  3455. *output_indices++ = reindex[index];
  3456. }
  3457. }
  3458. MEMALLOC_FREE(vertices);
  3459. MEMALLOC_FREE(reindex);
  3460. return ret;
  3461. }
  3462. bool fm_isMeshCoplanar(NxU32 tcount,const NxU32 *indices,const REAL *vertices,bool doubleSided) // returns true if this collection of indexed triangles are co-planar!
  3463. {
  3464. bool ret = true;
  3465. if ( tcount > 0 )
  3466. {
  3467. NxU32 i1 = indices[0];
  3468. NxU32 i2 = indices[1];
  3469. NxU32 i3 = indices[2];
  3470. const REAL *p1 = &vertices[i1*3];
  3471. const REAL *p2 = &vertices[i2*3];
  3472. const REAL *p3 = &vertices[i3*3];
  3473. REAL plane[4];
  3474. plane[3] = fm_computePlane(p1,p2,p3,plane);
  3475. const NxU32 *scan = &indices[3];
  3476. for (NxU32 i=1; i<tcount; i++)
  3477. {
  3478. i1 = *scan++;
  3479. i2 = *scan++;
  3480. i3 = *scan++;
  3481. p1 = &vertices[i1*3];
  3482. p2 = &vertices[i2*3];
  3483. p3 = &vertices[i3*3];
  3484. REAL _plane[4];
  3485. _plane[3] = fm_computePlane(p1,p2,p3,_plane);
  3486. if ( !fm_samePlane(plane,_plane,0.01f,0.001f,doubleSided) )
  3487. {
  3488. ret = false;
  3489. break;
  3490. }
  3491. }
  3492. }
  3493. return ret;
  3494. }
  3495. bool fm_samePlane(const REAL p1[4],const REAL p2[4],REAL normalEpsilon,REAL dEpsilon,bool doubleSided)
  3496. {
  3497. bool ret = false;
  3498. REAL diff = (REAL) fabs(p1[3]-p2[3]);
  3499. if ( diff < dEpsilon ) // if the plane -d co-efficient is within our epsilon
  3500. {
  3501. REAL dot = fm_dot(p1,p2); // compute the dot-product of the vector normals.
  3502. if ( doubleSided ) dot = (REAL)fabs(dot);
  3503. REAL dmin = 1 - normalEpsilon;
  3504. REAL dmax = 1 + normalEpsilon;
  3505. if ( dot >= dmin && dot <= dmax )
  3506. {
  3507. ret = true; // then the plane equation is for practical purposes identical.
  3508. }
  3509. }
  3510. return ret;
  3511. }
  3512. void fm_initMinMax(REAL bmin[3],REAL bmax[3])
  3513. {
  3514. bmin[0] = FLT_MAX;
  3515. bmin[1] = FLT_MAX;
  3516. bmin[2] = FLT_MAX;
  3517. bmax[0] = FLT_MIN;
  3518. bmax[1] = FLT_MIN;
  3519. bmax[2] = FLT_MIN;
  3520. }
  3521. #ifndef TESSELATE_H
  3522. #define TESSELATE_H
  3523. typedef CONVEX_DECOMPOSITION::Array< NxU32 > UintVector;
  3524. class Myfm_Tesselate : public fm_Tesselate, public Memalloc
  3525. {
  3526. public:
  3527. virtual ~Myfm_Tesselate(void)
  3528. {
  3529. }
  3530. const NxU32 * tesselate(fm_VertexIndex *vindex,NxU32 tcount,const NxU32 *indices,NxF32 longEdge,NxU32 maxDepth,NxU32 &outcount)
  3531. {
  3532. const NxU32 *ret = 0;
  3533. mMaxDepth = maxDepth;
  3534. mLongEdge = longEdge*longEdge;
  3535. mLongEdgeD = mLongEdge;
  3536. mVertices = vindex;
  3537. if ( mVertices->isDouble() )
  3538. {
  3539. NxU32 vcount = mVertices->getVcount();
  3540. NxF64 *vertices = (NxF64 *)MEMALLOC_MALLOC(sizeof(NxF64)*vcount*3);
  3541. memcpy(vertices,mVertices->getVerticesDouble(),sizeof(NxF64)*vcount*3);
  3542. for (NxU32 i=0; i<tcount; i++)
  3543. {
  3544. NxU32 i1 = *indices++;
  3545. NxU32 i2 = *indices++;
  3546. NxU32 i3 = *indices++;
  3547. const NxF64 *p1 = &vertices[i1*3];
  3548. const NxF64 *p2 = &vertices[i2*3];
  3549. const NxF64 *p3 = &vertices[i3*3];
  3550. tesselate(p1,p2,p3,0);
  3551. }
  3552. MEMALLOC_FREE(vertices);
  3553. }
  3554. else
  3555. {
  3556. NxU32 vcount = mVertices->getVcount();
  3557. NxF32 *vertices = (NxF32 *)MEMALLOC_MALLOC(sizeof(NxF32)*vcount*3);
  3558. memcpy(vertices,mVertices->getVerticesFloat(),sizeof(NxF32)*vcount*3);
  3559. for (NxU32 i=0; i<tcount; i++)
  3560. {
  3561. NxU32 i1 = *indices++;
  3562. NxU32 i2 = *indices++;
  3563. NxU32 i3 = *indices++;
  3564. const NxF32 *p1 = &vertices[i1*3];
  3565. const NxF32 *p2 = &vertices[i2*3];
  3566. const NxF32 *p3 = &vertices[i3*3];
  3567. tesselate(p1,p2,p3,0);
  3568. }
  3569. MEMALLOC_FREE(vertices);
  3570. }
  3571. outcount = (NxU32)(mIndices.size()/3);
  3572. ret = &mIndices[0];
  3573. return ret;
  3574. }
  3575. void tesselate(const NxF32 *p1,const NxF32 *p2,const NxF32 *p3,NxU32 recurse)
  3576. {
  3577. bool split = false;
  3578. NxF32 l1,l2,l3;
  3579. l1 = l2 = l3 = 0;
  3580. if ( recurse < mMaxDepth )
  3581. {
  3582. l1 = fm_distanceSquared(p1,p2);
  3583. l2 = fm_distanceSquared(p2,p3);
  3584. l3 = fm_distanceSquared(p3,p1);
  3585. if ( l1 > mLongEdge || l2 > mLongEdge || l3 > mLongEdge )
  3586. split = true;
  3587. }
  3588. if ( split )
  3589. {
  3590. NxU32 edge;
  3591. if ( l1 >= l2 && l1 >= l3 )
  3592. edge = 0;
  3593. else if ( l2 >= l1 && l2 >= l3 )
  3594. edge = 1;
  3595. else
  3596. edge = 2;
  3597. NxF32 split[3];
  3598. switch ( edge )
  3599. {
  3600. case 0:
  3601. {
  3602. fm_lerp(p1,p2,split,0.5f);
  3603. tesselate(p1,split,p3, recurse+1 );
  3604. tesselate(split,p2,p3, recurse+1 );
  3605. }
  3606. break;
  3607. case 1:
  3608. {
  3609. fm_lerp(p2,p3,split,0.5f);
  3610. tesselate(p1,p2,split, recurse+1 );
  3611. tesselate(p1,split,p3, recurse+1 );
  3612. }
  3613. break;
  3614. case 2:
  3615. {
  3616. fm_lerp(p3,p1,split,0.5f);
  3617. tesselate(p1,p2,split, recurse+1 );
  3618. tesselate(split,p2,p3, recurse+1 );
  3619. }
  3620. break;
  3621. }
  3622. }
  3623. else
  3624. {
  3625. bool newp;
  3626. NxU32 i1 = mVertices->getIndex(p1,newp);
  3627. NxU32 i2 = mVertices->getIndex(p2,newp);
  3628. NxU32 i3 = mVertices->getIndex(p3,newp);
  3629. mIndices.pushBack(i1);
  3630. mIndices.pushBack(i2);
  3631. mIndices.pushBack(i3);
  3632. }
  3633. }
  3634. void tesselate(const NxF64 *p1,const NxF64 *p2,const NxF64 *p3,NxU32 recurse)
  3635. {
  3636. bool split = false;
  3637. NxF64 l1,l2,l3;
  3638. l1 = l2 = l3 = 0;
  3639. if ( recurse < mMaxDepth )
  3640. {
  3641. l1 = fm_distanceSquared(p1,p2);
  3642. l2 = fm_distanceSquared(p2,p3);
  3643. l3 = fm_distanceSquared(p3,p1);
  3644. if ( l1 > mLongEdgeD || l2 > mLongEdgeD || l3 > mLongEdgeD )
  3645. split = true;
  3646. }
  3647. if ( split )
  3648. {
  3649. NxU32 edge;
  3650. if ( l1 >= l2 && l1 >= l3 )
  3651. edge = 0;
  3652. else if ( l2 >= l1 && l2 >= l3 )
  3653. edge = 1;
  3654. else
  3655. edge = 2;
  3656. NxF64 split[3];
  3657. switch ( edge )
  3658. {
  3659. case 0:
  3660. {
  3661. fm_lerp(p1,p2,split,0.5);
  3662. tesselate(p1,split,p3, recurse+1 );
  3663. tesselate(split,p2,p3, recurse+1 );
  3664. }
  3665. break;
  3666. case 1:
  3667. {
  3668. fm_lerp(p2,p3,split,0.5);
  3669. tesselate(p1,p2,split, recurse+1 );
  3670. tesselate(p1,split,p3, recurse+1 );
  3671. }
  3672. break;
  3673. case 2:
  3674. {
  3675. fm_lerp(p3,p1,split,0.5);
  3676. tesselate(p1,p2,split, recurse+1 );
  3677. tesselate(split,p2,p3, recurse+1 );
  3678. }
  3679. break;
  3680. }
  3681. }
  3682. else
  3683. {
  3684. bool newp;
  3685. NxU32 i1 = mVertices->getIndex(p1,newp);
  3686. NxU32 i2 = mVertices->getIndex(p2,newp);
  3687. NxU32 i3 = mVertices->getIndex(p3,newp);
  3688. mIndices.pushBack(i1);
  3689. mIndices.pushBack(i2);
  3690. mIndices.pushBack(i3);
  3691. }
  3692. }
  3693. private:
  3694. NxF32 mLongEdge;
  3695. NxF64 mLongEdgeD;
  3696. fm_VertexIndex *mVertices;
  3697. UintVector mIndices;
  3698. NxU32 mMaxDepth;
  3699. };
  3700. fm_Tesselate * fm_createTesselate(void)
  3701. {
  3702. Myfm_Tesselate *m = MEMALLOC_NEW(Myfm_Tesselate);
  3703. return static_cast< fm_Tesselate * >(m);
  3704. }
  3705. void fm_releaseTesselate(fm_Tesselate *t)
  3706. {
  3707. Myfm_Tesselate *m = static_cast< Myfm_Tesselate *>(t);
  3708. delete m;
  3709. }
  3710. #endif
  3711. #ifndef RAY_ABB_INTERSECT
  3712. #define RAY_ABB_INTERSECT
  3713. //! Integer representation of a floating-point value.
  3714. #define IR(x) ((NxU32&)x)
  3715. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3716. /**
  3717. * A method to compute a ray-AABB intersection.
  3718. * Original code by Andrew Woo, from "Graphics Gems", Academic Press, 1990
  3719. * Optimized code by Pierre Terdiman, 2000 (~20-30% faster on my Celeron 500)
  3720. * Epsilon value added by Klaus Hartmann. (discarding it saves a few cycles only)
  3721. *
  3722. * Hence this version is faster as well as more robust than the original one.
  3723. *
  3724. * Should work provided:
  3725. * 1) the integer representation of 0.0f is 0x00000000
  3726. * 2) the sign bit of the NxF32 is the most significant one
  3727. *
  3728. * Report bugs: [email protected]
  3729. *
  3730. * \param aabb [in] the axis-aligned bounding box
  3731. * \param origin [in] ray origin
  3732. * \param dir [in] ray direction
  3733. * \param coord [out] impact coordinates
  3734. * \return true if ray intersects AABB
  3735. */
  3736. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3737. #define RAYAABB_EPSILON 0.00001f
  3738. bool fm_intersectRayAABB(const NxF32 MinB[3],const NxF32 MaxB[3],const NxF32 origin[3],const NxF32 dir[3],NxF32 coord[3])
  3739. {
  3740. bool Inside = true;
  3741. NxF32 MaxT[3];
  3742. MaxT[0]=MaxT[1]=MaxT[2]=-1.0f;
  3743. // Find candidate planes.
  3744. for(NxU32 i=0;i<3;i++)
  3745. {
  3746. if(origin[i] < MinB[i])
  3747. {
  3748. coord[i] = MinB[i];
  3749. Inside = false;
  3750. // Calculate T distances to candidate planes
  3751. if(IR(dir[i])) MaxT[i] = (MinB[i] - origin[i]) / dir[i];
  3752. }
  3753. else if(origin[i] > MaxB[i])
  3754. {
  3755. coord[i] = MaxB[i];
  3756. Inside = false;
  3757. // Calculate T distances to candidate planes
  3758. if(IR(dir[i])) MaxT[i] = (MaxB[i] - origin[i]) / dir[i];
  3759. }
  3760. }
  3761. // Ray origin inside bounding box
  3762. if(Inside)
  3763. {
  3764. coord[0] = origin[0];
  3765. coord[1] = origin[1];
  3766. coord[2] = origin[2];
  3767. return true;
  3768. }
  3769. // Get largest of the maxT's for final choice of intersection
  3770. NxU32 WhichPlane = 0;
  3771. if(MaxT[1] > MaxT[WhichPlane]) WhichPlane = 1;
  3772. if(MaxT[2] > MaxT[WhichPlane]) WhichPlane = 2;
  3773. // Check final candidate actually inside box
  3774. if(IR(MaxT[WhichPlane])&0x80000000) return false;
  3775. for(NxU32 i=0;i<3;i++)
  3776. {
  3777. if(i!=WhichPlane)
  3778. {
  3779. coord[i] = origin[i] + MaxT[WhichPlane] * dir[i];
  3780. #ifdef RAYAABB_EPSILON
  3781. if(coord[i] < MinB[i] - RAYAABB_EPSILON || coord[i] > MaxB[i] + RAYAABB_EPSILON) return false;
  3782. #else
  3783. if(coord[i] < MinB[i] || coord[i] > MaxB[i]) return false;
  3784. #endif
  3785. }
  3786. }
  3787. return true; // ray hits box
  3788. }
  3789. bool fm_intersectLineSegmentAABB(const NxF32 bmin[3],const NxF32 bmax[3],const NxF32 p1[3],const NxF32 p2[3],NxF32 intersect[3])
  3790. {
  3791. bool ret = false;
  3792. NxF32 dir[3];
  3793. dir[0] = p2[0] - p1[0];
  3794. dir[1] = p2[1] - p1[1];
  3795. dir[2] = p2[2] - p1[2];
  3796. NxF32 dist = fm_normalize(dir);
  3797. if ( dist > RAYAABB_EPSILON )
  3798. {
  3799. ret = fm_intersectRayAABB(bmin,bmax,p1,dir,intersect);
  3800. if ( ret )
  3801. {
  3802. NxF32 d = fm_distanceSquared(p1,intersect);
  3803. if ( d > (dist*dist) )
  3804. {
  3805. ret = false;
  3806. }
  3807. }
  3808. }
  3809. return ret;
  3810. }
  3811. #endif
  3812. #ifndef OBB_TO_AABB
  3813. #define OBB_TO_AABB
  3814. #pragma warning(disable:4100)
  3815. void fm_OBBtoAABB(const NxF32 obmin[3],const NxF32 obmax[3],const NxF32 matrix[16],NxF32 abmin[3],NxF32 abmax[3])
  3816. {
  3817. assert(0); // not yet implemented.
  3818. }
  3819. const REAL * computePos(NxU32 index,const REAL *vertices,NxU32 vstride)
  3820. {
  3821. const char *tmp = (const char *)vertices;
  3822. tmp+=(index*vstride);
  3823. return (const REAL*)tmp;
  3824. }
  3825. void computeNormal(NxU32 index,REAL *normals,NxU32 nstride,const REAL *normal)
  3826. {
  3827. char *tmp = (char *)normals;
  3828. tmp+=(index*nstride);
  3829. REAL *dest = (REAL *)tmp;
  3830. dest[0]+=normal[0];
  3831. dest[1]+=normal[1];
  3832. dest[2]+=normal[2];
  3833. }
  3834. void fm_computeMeanNormals(NxU32 vcount, // the number of vertices
  3835. const REAL *vertices, // the base address of the vertex position data.
  3836. NxU32 vstride, // the stride between position data.
  3837. REAL *normals, // the base address of the destination for mean vector normals
  3838. NxU32 nstride, // the stride between normals
  3839. NxU32 tcount, // the number of triangles
  3840. const NxU32 *indices) // the triangle indices
  3841. {
  3842. // Step #1 : Zero out the vertex normals
  3843. char *dest = (char *)normals;
  3844. for (NxU32 i=0; i<vcount; i++)
  3845. {
  3846. REAL *n = (REAL *)dest;
  3847. n[0] = 0;
  3848. n[1] = 0;
  3849. n[2] = 0;
  3850. dest+=nstride;
  3851. }
  3852. // Step #2 : Compute the face normals and accumulate them
  3853. const NxU32 *scan = indices;
  3854. for (NxU32 i=0; i<tcount; i++)
  3855. {
  3856. NxU32 i1 = *scan++;
  3857. NxU32 i2 = *scan++;
  3858. NxU32 i3 = *scan++;
  3859. const REAL *p1 = computePos(i1,vertices,vstride);
  3860. const REAL *p2 = computePos(i2,vertices,vstride);
  3861. const REAL *p3 = computePos(i3,vertices,vstride);
  3862. REAL normal[3];
  3863. fm_computePlane(p3,p2,p1,normal);
  3864. computeNormal(i1,normals,nstride,normal);
  3865. computeNormal(i2,normals,nstride,normal);
  3866. computeNormal(i3,normals,nstride,normal);
  3867. }
  3868. // Normalize the accumulated normals
  3869. dest = (char *)normals;
  3870. for (NxU32 i=0; i<vcount; i++)
  3871. {
  3872. REAL *n = (REAL *)dest;
  3873. fm_normalize(n);
  3874. dest+=nstride;
  3875. }
  3876. }
  3877. #endif
  3878. #define BIGNUMBER 100000000.0 /* hundred million */
  3879. static inline void Set(REAL *n,REAL x,REAL y,REAL z)
  3880. {
  3881. n[0] = x;
  3882. n[1] = y;
  3883. n[2] = z;
  3884. };
  3885. static inline void Copy(REAL *dest,const REAL *source)
  3886. {
  3887. dest[0] = source[0];
  3888. dest[1] = source[1];
  3889. dest[2] = source[2];
  3890. }
  3891. REAL fm_computeBestFitSphere(NxU32 vcount,const REAL *points,NxU32 pstride,REAL *center)
  3892. {
  3893. REAL radius;
  3894. REAL radius2;
  3895. REAL xmin[3];
  3896. REAL xmax[3];
  3897. REAL ymin[3];
  3898. REAL ymax[3];
  3899. REAL zmin[3];
  3900. REAL zmax[3];
  3901. REAL dia1[3];
  3902. REAL dia2[3];
  3903. /* FIRST PASS: find 6 minima/maxima points */
  3904. Set(xmin,BIGNUMBER,BIGNUMBER,BIGNUMBER);
  3905. Set(xmax,-BIGNUMBER,-BIGNUMBER,-BIGNUMBER);
  3906. Set(ymin,BIGNUMBER,BIGNUMBER,BIGNUMBER);
  3907. Set(ymax,-BIGNUMBER,-BIGNUMBER,-BIGNUMBER);
  3908. Set(zmin,BIGNUMBER,BIGNUMBER,BIGNUMBER);
  3909. Set(zmax,-BIGNUMBER,-BIGNUMBER,-BIGNUMBER);
  3910. const char *scan = (const char *)points;
  3911. for (NxU32 i=0; i<vcount; i++)
  3912. {
  3913. const REAL *caller_p = (const REAL *)scan;
  3914. if (caller_p[0]<xmin[0])
  3915. Copy(xmin,caller_p); /* New xminimum point */
  3916. if (caller_p[0]>xmax[0])
  3917. Copy(xmax,caller_p);
  3918. if (caller_p[1]<ymin[1])
  3919. Copy(ymin,caller_p);
  3920. if (caller_p[1]>ymax[1])
  3921. Copy(ymax,caller_p);
  3922. if (caller_p[2]<zmin[2])
  3923. Copy(zmin,caller_p);
  3924. if (caller_p[2]>zmax[2])
  3925. Copy(zmax,caller_p);
  3926. scan+=pstride;
  3927. }
  3928. /* Set xspan = distance between the 2 points xmin & xmax (squared) */
  3929. REAL dx = xmax[0] - xmin[0];
  3930. REAL dy = xmax[1] - xmin[1];
  3931. REAL dz = xmax[2] - xmin[2];
  3932. REAL xspan = dx*dx + dy*dy + dz*dz;
  3933. /* Same for y & z spans */
  3934. dx = ymax[0] - ymin[0];
  3935. dy = ymax[1] - ymin[1];
  3936. dz = ymax[2] - ymin[2];
  3937. REAL yspan = dx*dx + dy*dy + dz*dz;
  3938. dx = zmax[0] - zmin[0];
  3939. dy = zmax[1] - zmin[1];
  3940. dz = zmax[2] - zmin[2];
  3941. REAL zspan = dx*dx + dy*dy + dz*dz;
  3942. /* Set points dia1 & dia2 to the maximally separated pair */
  3943. Copy(dia1,xmin);
  3944. Copy(dia2,xmax); /* assume xspan biggest */
  3945. REAL maxspan = xspan;
  3946. if (yspan>maxspan)
  3947. {
  3948. maxspan = yspan;
  3949. Copy(dia1,ymin);
  3950. Copy(dia2,ymax);
  3951. }
  3952. if (zspan>maxspan)
  3953. {
  3954. Copy(dia1,zmin);
  3955. Copy(dia2,zmax);
  3956. }
  3957. /* dia1,dia2 is a diameter of initial sphere */
  3958. /* calc initial center */
  3959. center[0] = (dia1[0]+dia2[0])*0.5f;
  3960. center[1] = (dia1[1]+dia2[1])*0.5f;
  3961. center[2] = (dia1[2]+dia2[2])*0.5f;
  3962. /* calculate initial radius**2 and radius */
  3963. dx = dia2[0]-center[0]; /* x component of radius vector */
  3964. dy = dia2[1]-center[1]; /* y component of radius vector */
  3965. dz = dia2[2]-center[2]; /* z component of radius vector */
  3966. radius2 = dx*dx + dy*dy + dz*dz;
  3967. radius = REAL(sqrt(radius2));
  3968. /* SECOND PASS: increment current sphere */
  3969. {
  3970. const char *scan = (const char *)points;
  3971. for (NxU32 i=0; i<vcount; i++)
  3972. {
  3973. const REAL *caller_p = (const REAL *)scan;
  3974. dx = caller_p[0]-center[0];
  3975. dy = caller_p[1]-center[1];
  3976. dz = caller_p[2]-center[2];
  3977. REAL old_to_p_sq = dx*dx + dy*dy + dz*dz;
  3978. if (old_to_p_sq > radius2) /* do r**2 test first */
  3979. { /* this point is outside of current sphere */
  3980. REAL old_to_p = REAL(sqrt(old_to_p_sq));
  3981. /* calc radius of new sphere */
  3982. radius = (radius + old_to_p) * 0.5f;
  3983. radius2 = radius*radius; /* for next r**2 compare */
  3984. REAL old_to_new = old_to_p - radius;
  3985. /* calc center of new sphere */
  3986. REAL recip = 1.0f /old_to_p;
  3987. REAL cx = (radius*center[0] + old_to_new*caller_p[0]) * recip;
  3988. REAL cy = (radius*center[1] + old_to_new*caller_p[1]) * recip;
  3989. REAL cz = (radius*center[2] + old_to_new*caller_p[2]) * recip;
  3990. Set(center,cx,cy,cz);
  3991. scan+=pstride;
  3992. }
  3993. }
  3994. }
  3995. return radius;
  3996. }
  3997. void fm_computeBestFitCapsule(NxU32 vcount,const REAL *points,NxU32 pstride,REAL &radius,REAL &height,REAL matrix[16],bool bruteForce)
  3998. {
  3999. REAL sides[3];
  4000. REAL omatrix[16];
  4001. fm_computeBestFitOBB(vcount,points,pstride,sides,omatrix,bruteForce);
  4002. NxI32 axis = 0;
  4003. if ( sides[0] > sides[1] && sides[0] > sides[2] )
  4004. axis = 0;
  4005. else if ( sides[1] > sides[0] && sides[1] > sides[2] )
  4006. axis = 1;
  4007. else
  4008. axis = 2;
  4009. REAL localTransform[16];
  4010. REAL maxDist = 0;
  4011. REAL maxLen = 0;
  4012. switch ( axis )
  4013. {
  4014. case 0:
  4015. {
  4016. fm_eulerMatrix(0,0,FM_PI/2,localTransform);
  4017. fm_matrixMultiply(localTransform,omatrix,matrix);
  4018. const NxU8 *scan = (const NxU8 *)points;
  4019. for (NxU32 i=0; i<vcount; i++)
  4020. {
  4021. const REAL *p = (const REAL *)scan;
  4022. REAL t[3];
  4023. fm_inverseRT(omatrix,p,t);
  4024. REAL dist = t[1]*t[1]+t[2]*t[2];
  4025. if ( dist > maxDist )
  4026. {
  4027. maxDist = dist;
  4028. }
  4029. REAL l = (REAL) fabs(t[0]);
  4030. if ( l > maxLen )
  4031. {
  4032. maxLen = l;
  4033. }
  4034. scan+=pstride;
  4035. }
  4036. }
  4037. height = sides[0];
  4038. break;
  4039. case 1:
  4040. {
  4041. fm_eulerMatrix(0,FM_PI/2,0,localTransform);
  4042. fm_matrixMultiply(localTransform,omatrix,matrix);
  4043. const NxU8 *scan = (const NxU8 *)points;
  4044. for (NxU32 i=0; i<vcount; i++)
  4045. {
  4046. const REAL *p = (const REAL *)scan;
  4047. REAL t[3];
  4048. fm_inverseRT(omatrix,p,t);
  4049. REAL dist = t[0]*t[0]+t[2]*t[2];
  4050. if ( dist > maxDist )
  4051. {
  4052. maxDist = dist;
  4053. }
  4054. REAL l = (REAL) fabs(t[1]);
  4055. if ( l > maxLen )
  4056. {
  4057. maxLen = l;
  4058. }
  4059. scan+=pstride;
  4060. }
  4061. }
  4062. height = sides[1];
  4063. break;
  4064. case 2:
  4065. {
  4066. fm_eulerMatrix(FM_PI/2,0,0,localTransform);
  4067. fm_matrixMultiply(localTransform,omatrix,matrix);
  4068. const NxU8 *scan = (const NxU8 *)points;
  4069. for (NxU32 i=0; i<vcount; i++)
  4070. {
  4071. const REAL *p = (const REAL *)scan;
  4072. REAL t[3];
  4073. fm_inverseRT(omatrix,p,t);
  4074. REAL dist = t[0]*t[0]+t[1]*t[1];
  4075. if ( dist > maxDist )
  4076. {
  4077. maxDist = dist;
  4078. }
  4079. REAL l = (REAL) fabs(t[2]);
  4080. if ( l > maxLen )
  4081. {
  4082. maxLen = l;
  4083. }
  4084. scan+=pstride;
  4085. }
  4086. }
  4087. height = sides[2];
  4088. break;
  4089. }
  4090. radius = (REAL)sqrt(maxDist);
  4091. height = (maxLen*2)-(radius*2);
  4092. }
  4093. //************* Triangulation
  4094. #ifndef TRIANGULATE_H
  4095. #define TRIANGULATE_H
  4096. typedef NxU32 TU32;
  4097. class TVec
  4098. {
  4099. public:
  4100. TVec(NxF64 _x,NxF64 _y,NxF64 _z) { x = _x; y = _y; z = _z; };
  4101. TVec(void) { };
  4102. NxF64 x;
  4103. NxF64 y;
  4104. NxF64 z;
  4105. };
  4106. typedef CONVEX_DECOMPOSITION::Array< TVec > TVecVector;
  4107. typedef CONVEX_DECOMPOSITION::Array< TU32 > TU32Vector;
  4108. class CTriangulator
  4109. {
  4110. public:
  4111. /// Default constructor
  4112. CTriangulator();
  4113. /// Default destructor
  4114. virtual ~CTriangulator();
  4115. /// Triangulates the contour
  4116. void triangulate(TU32Vector &indices);
  4117. /// Returns the given point in the triangulator array
  4118. inline TVec get(const TU32 id) { return mPoints[id]; }
  4119. virtual void reset(void)
  4120. {
  4121. mInputPoints.clear();
  4122. mPoints.clear();
  4123. mIndices.clear();
  4124. }
  4125. virtual void addPoint(NxF64 x,NxF64 y,NxF64 z)
  4126. {
  4127. TVec v(x,y,z);
  4128. // update bounding box...
  4129. if ( mInputPoints.empty() )
  4130. {
  4131. mMin = v;
  4132. mMax = v;
  4133. }
  4134. else
  4135. {
  4136. if ( x < mMin.x ) mMin.x = x;
  4137. if ( y < mMin.y ) mMin.y = y;
  4138. if ( z < mMin.z ) mMin.z = z;
  4139. if ( x > mMax.x ) mMax.x = x;
  4140. if ( y > mMax.y ) mMax.y = y;
  4141. if ( z > mMax.z ) mMax.z = z;
  4142. }
  4143. mInputPoints.pushBack(v);
  4144. }
  4145. // Triangulation happens in 2d. We could inverse transform the polygon around the normal direction, or we just use the two most signficant axes
  4146. // Here we find the two longest axes and use them to triangulate. Inverse transforming them would introduce more doubleing point error and isn't worth it.
  4147. virtual NxU32 * triangulate(NxU32 &tcount,NxF64 epsilon)
  4148. {
  4149. NxU32 *ret = 0;
  4150. tcount = 0;
  4151. mEpsilon = epsilon;
  4152. if ( !mInputPoints.empty() )
  4153. {
  4154. mPoints.clear();
  4155. NxF64 dx = mMax.x - mMin.x; // locate the first, second and third longest edges and store them in i1, i2, i3
  4156. NxF64 dy = mMax.y - mMin.y;
  4157. NxF64 dz = mMax.z - mMin.z;
  4158. NxU32 i1,i2,i3;
  4159. if ( dx > dy && dx > dz )
  4160. {
  4161. i1 = 0;
  4162. if ( dy > dz )
  4163. {
  4164. i2 = 1;
  4165. i3 = 2;
  4166. }
  4167. else
  4168. {
  4169. i2 = 2;
  4170. i3 = 1;
  4171. }
  4172. }
  4173. else if ( dy > dx && dy > dz )
  4174. {
  4175. i1 = 1;
  4176. if ( dx > dz )
  4177. {
  4178. i2 = 0;
  4179. i3 = 2;
  4180. }
  4181. else
  4182. {
  4183. i2 = 2;
  4184. i3 = 0;
  4185. }
  4186. }
  4187. else
  4188. {
  4189. i1 = 2;
  4190. if ( dx > dy )
  4191. {
  4192. i2 = 0;
  4193. i3 = 1;
  4194. }
  4195. else
  4196. {
  4197. i2 = 1;
  4198. i3 = 0;
  4199. }
  4200. }
  4201. NxU32 pcount = (NxU32)mInputPoints.size();
  4202. const NxF64 *points = &mInputPoints[0].x;
  4203. for (NxU32 i=0; i<pcount; i++)
  4204. {
  4205. TVec v( points[i1], points[i2], points[i3] );
  4206. mPoints.pushBack(v);
  4207. points+=3;
  4208. }
  4209. mIndices.clear();
  4210. triangulate(mIndices);
  4211. tcount = (NxU32)mIndices.size()/3;
  4212. if ( tcount )
  4213. {
  4214. ret = &mIndices[0];
  4215. }
  4216. }
  4217. return ret;
  4218. }
  4219. virtual const NxF64 * getPoint(NxU32 index)
  4220. {
  4221. return &mInputPoints[index].x;
  4222. }
  4223. private:
  4224. NxF64 mEpsilon;
  4225. TVec mMin;
  4226. TVec mMax;
  4227. TVecVector mInputPoints;
  4228. TVecVector mPoints;
  4229. TU32Vector mIndices;
  4230. /// Tests if a point is inside the given triangle
  4231. bool _insideTriangle(const TVec& A, const TVec& B, const TVec& C,const TVec& P);
  4232. /// Returns the area of the contour
  4233. NxF64 _area();
  4234. bool _snip(NxI32 u, NxI32 v, NxI32 w, NxI32 n, NxI32 *V);
  4235. /// Processes the triangulation
  4236. void _process(TU32Vector &indices);
  4237. };
  4238. /// Default constructor
  4239. CTriangulator::CTriangulator(void)
  4240. {
  4241. }
  4242. /// Default destructor
  4243. CTriangulator::~CTriangulator()
  4244. {
  4245. }
  4246. /// Triangulates the contour
  4247. void CTriangulator::triangulate(TU32Vector &indices)
  4248. {
  4249. _process(indices);
  4250. }
  4251. /// Processes the triangulation
  4252. void CTriangulator::_process(TU32Vector &indices)
  4253. {
  4254. const NxI32 n = (const NxI32)mPoints.size();
  4255. if (n < 3)
  4256. return;
  4257. NxI32 *V = (NxI32 *)MEMALLOC_MALLOC(sizeof(NxI32)*n);
  4258. bool flipped = false;
  4259. if (0.0f < _area())
  4260. {
  4261. for (NxI32 v = 0; v < n; v++)
  4262. V[v] = v;
  4263. }
  4264. else
  4265. {
  4266. flipped = true;
  4267. for (NxI32 v = 0; v < n; v++)
  4268. V[v] = (n - 1) - v;
  4269. }
  4270. NxI32 nv = n;
  4271. NxI32 count = 2 * nv;
  4272. for (NxI32 m = 0, v = nv - 1; nv > 2;)
  4273. {
  4274. if (0 >= (count--))
  4275. return;
  4276. NxI32 u = v;
  4277. if (nv <= u)
  4278. u = 0;
  4279. v = u + 1;
  4280. if (nv <= v)
  4281. v = 0;
  4282. NxI32 w = v + 1;
  4283. if (nv <= w)
  4284. w = 0;
  4285. if (_snip(u, v, w, nv, V))
  4286. {
  4287. NxI32 a, b, c, s, t;
  4288. a = V[u];
  4289. b = V[v];
  4290. c = V[w];
  4291. if ( flipped )
  4292. {
  4293. indices.pushBack(a);
  4294. indices.pushBack(b);
  4295. indices.pushBack(c);
  4296. }
  4297. else
  4298. {
  4299. indices.pushBack(c);
  4300. indices.pushBack(b);
  4301. indices.pushBack(a);
  4302. }
  4303. m++;
  4304. for (s = v, t = v + 1; t < nv; s++, t++)
  4305. V[s] = V[t];
  4306. nv--;
  4307. count = 2 * nv;
  4308. }
  4309. }
  4310. MEMALLOC_FREE(V);
  4311. }
  4312. /// Returns the area of the contour
  4313. NxF64 CTriangulator::_area()
  4314. {
  4315. NxI32 n = (NxU32)mPoints.size();
  4316. NxF64 A = 0.0f;
  4317. for (NxI32 p = n - 1, q = 0; q < n; p = q++)
  4318. {
  4319. const TVec &pval = mPoints[p];
  4320. const TVec &qval = mPoints[q];
  4321. A += pval.x * qval.y - qval.x * pval.y;
  4322. }
  4323. A*=0.5f;
  4324. return A;
  4325. }
  4326. bool CTriangulator::_snip(NxI32 u, NxI32 v, NxI32 w, NxI32 n, NxI32 *V)
  4327. {
  4328. NxI32 p;
  4329. const TVec &A = mPoints[ V[u] ];
  4330. const TVec &B = mPoints[ V[v] ];
  4331. const TVec &C = mPoints[ V[w] ];
  4332. if (mEpsilon > (((B.x - A.x) * (C.y - A.y)) - ((B.y - A.y) * (C.x - A.x))) )
  4333. return false;
  4334. for (p = 0; p < n; p++)
  4335. {
  4336. if ((p == u) || (p == v) || (p == w))
  4337. continue;
  4338. const TVec &P = mPoints[ V[p] ];
  4339. if (_insideTriangle(A, B, C, P))
  4340. return false;
  4341. }
  4342. return true;
  4343. }
  4344. /// Tests if a point is inside the given triangle
  4345. bool CTriangulator::_insideTriangle(const TVec& A, const TVec& B, const TVec& C,const TVec& P)
  4346. {
  4347. NxF64 ax, ay, bx, by, cx, cy, apx, apy, bpx, bpy, cpx, cpy;
  4348. NxF64 cCROSSap, bCROSScp, aCROSSbp;
  4349. ax = C.x - B.x; ay = C.y - B.y;
  4350. bx = A.x - C.x; by = A.y - C.y;
  4351. cx = B.x - A.x; cy = B.y - A.y;
  4352. apx = P.x - A.x; apy = P.y - A.y;
  4353. bpx = P.x - B.x; bpy = P.y - B.y;
  4354. cpx = P.x - C.x; cpy = P.y - C.y;
  4355. aCROSSbp = ax * bpy - ay * bpx;
  4356. cCROSSap = cx * apy - cy * apx;
  4357. bCROSScp = bx * cpy - by * cpx;
  4358. return ((aCROSSbp >= 0.0f) && (bCROSScp >= 0.0f) && (cCROSSap >= 0.0f));
  4359. }
  4360. class Triangulate : public fm_Triangulate, public Memalloc
  4361. {
  4362. public:
  4363. Triangulate(void)
  4364. {
  4365. mPointsFloat = 0;
  4366. mPointsDouble = 0;
  4367. }
  4368. virtual ~Triangulate(void)
  4369. {
  4370. reset();
  4371. }
  4372. void reset(void)
  4373. {
  4374. MEMALLOC_FREE(mPointsFloat);
  4375. MEMALLOC_FREE(mPointsDouble);
  4376. mPointsFloat = 0;
  4377. mPointsDouble = 0;
  4378. }
  4379. virtual const NxF64 * triangulate3d(NxU32 pcount,
  4380. const NxF64 *_points,
  4381. NxU32 vstride,
  4382. NxU32 &tcount,
  4383. bool consolidate,
  4384. NxF64 epsilon)
  4385. {
  4386. reset();
  4387. NxF64 *points = (NxF64 *)MEMALLOC_MALLOC(sizeof(NxF64)*pcount*3);
  4388. if ( consolidate )
  4389. {
  4390. pcount = fm_consolidatePolygon(pcount,_points,vstride,points,1-epsilon);
  4391. }
  4392. else
  4393. {
  4394. NxF64 *dest = points;
  4395. for (NxU32 i=0; i<pcount; i++)
  4396. {
  4397. const NxF64 *src = fm_getPoint(_points,vstride,i);
  4398. dest[0] = src[0];
  4399. dest[1] = src[1];
  4400. dest[2] = src[2];
  4401. dest+=3;
  4402. }
  4403. vstride = sizeof(NxF64)*3;
  4404. }
  4405. if ( pcount >= 3 )
  4406. {
  4407. CTriangulator ct;
  4408. for (NxU32 i=0; i<pcount; i++)
  4409. {
  4410. const NxF64 *src = fm_getPoint(points,vstride,i);
  4411. ct.addPoint( src[0], src[1], src[2] );
  4412. }
  4413. NxU32 _tcount;
  4414. NxU32 *indices = ct.triangulate(_tcount,epsilon);
  4415. if ( indices )
  4416. {
  4417. tcount = _tcount;
  4418. mPointsDouble = (NxF64 *)MEMALLOC_MALLOC(sizeof(NxF64)*tcount*3*3);
  4419. NxF64 *dest = mPointsDouble;
  4420. for (NxU32 i=0; i<tcount; i++)
  4421. {
  4422. NxU32 i1 = indices[i*3+0];
  4423. NxU32 i2 = indices[i*3+1];
  4424. NxU32 i3 = indices[i*3+2];
  4425. const NxF64 *p1 = ct.getPoint(i1);
  4426. const NxF64 *p2 = ct.getPoint(i2);
  4427. const NxF64 *p3 = ct.getPoint(i3);
  4428. dest[0] = p1[0];
  4429. dest[1] = p1[1];
  4430. dest[2] = p1[2];
  4431. dest[3] = p2[0];
  4432. dest[4] = p2[1];
  4433. dest[5] = p2[2];
  4434. dest[6] = p3[0];
  4435. dest[7] = p3[1];
  4436. dest[8] = p3[2];
  4437. dest+=9;
  4438. }
  4439. }
  4440. }
  4441. MEMALLOC_FREE(points);
  4442. return mPointsDouble;
  4443. }
  4444. virtual const NxF32 * triangulate3d(NxU32 pcount,
  4445. const NxF32 *points,
  4446. NxU32 vstride,
  4447. NxU32 &tcount,
  4448. bool consolidate,
  4449. NxF32 epsilon)
  4450. {
  4451. reset();
  4452. NxF64 *temp = (NxF64 *)MEMALLOC_MALLOC(sizeof(NxF64)*pcount*3);
  4453. NxF64 *dest = temp;
  4454. for (NxU32 i=0; i<pcount; i++)
  4455. {
  4456. const NxF32 *p = fm_getPoint(points,vstride,i);
  4457. dest[0] = p[0];
  4458. dest[1] = p[1];
  4459. dest[2] = p[2];
  4460. dest+=3;
  4461. }
  4462. const NxF64 *results = triangulate3d(pcount,temp,sizeof(NxF64)*3,tcount,consolidate,epsilon);
  4463. if ( results )
  4464. {
  4465. NxU32 fcount = tcount*3*3;
  4466. mPointsFloat = (NxF32 *)MEMALLOC_MALLOC(sizeof(NxF32)*tcount*3*3);
  4467. NxF32 *dest = mPointsFloat;
  4468. for (NxU32 i=0; i<fcount; i++)
  4469. {
  4470. dest[i] = (NxF32) results[i];
  4471. }
  4472. MEMALLOC_FREE(mPointsDouble);
  4473. mPointsDouble = 0;
  4474. }
  4475. MEMALLOC_FREE(temp);
  4476. return mPointsFloat;
  4477. }
  4478. private:
  4479. NxF32 *mPointsFloat;
  4480. NxF64 *mPointsDouble;
  4481. };
  4482. fm_Triangulate * fm_createTriangulate(void)
  4483. {
  4484. Triangulate *t = MEMALLOC_NEW(Triangulate);
  4485. return static_cast< fm_Triangulate *>(t);
  4486. }
  4487. void fm_releaseTriangulate(fm_Triangulate *t)
  4488. {
  4489. Triangulate *tt = static_cast< Triangulate *>(t);
  4490. delete tt;
  4491. }
  4492. #endif
  4493. bool validDistance(const REAL *p1,const REAL *p2,REAL epsilon)
  4494. {
  4495. bool ret = true;
  4496. REAL dx = p1[0] - p2[0];
  4497. REAL dy = p1[1] - p2[1];
  4498. REAL dz = p1[2] - p2[2];
  4499. REAL dist = dx*dx+dy*dy+dz*dz;
  4500. if ( dist < (epsilon*epsilon) )
  4501. {
  4502. ret = false;
  4503. }
  4504. return ret;
  4505. }
  4506. bool fm_isValidTriangle(const REAL *p1,const REAL *p2,const REAL *p3,REAL epsilon)
  4507. {
  4508. bool ret = false;
  4509. if ( validDistance(p1,p2,epsilon) &&
  4510. validDistance(p1,p3,epsilon) &&
  4511. validDistance(p2,p3,epsilon) )
  4512. {
  4513. REAL area = fm_computeArea(p1,p2,p3);
  4514. if ( area > epsilon )
  4515. {
  4516. REAL _vertices[3*3],vertices[64*3];
  4517. _vertices[0] = p1[0];
  4518. _vertices[1] = p1[1];
  4519. _vertices[2] = p1[2];
  4520. _vertices[3] = p2[0];
  4521. _vertices[4] = p2[1];
  4522. _vertices[5] = p2[2];
  4523. _vertices[6] = p3[0];
  4524. _vertices[7] = p3[1];
  4525. _vertices[8] = p3[2];
  4526. NxU32 pcount = fm_consolidatePolygon(3,_vertices,sizeof(REAL)*3,vertices,1-epsilon);
  4527. if ( pcount == 3 )
  4528. {
  4529. ret = true;
  4530. }
  4531. }
  4532. }
  4533. return ret;
  4534. }
  4535. void fm_multiplyQuat(const REAL *left,const REAL *right,REAL *quat)
  4536. {
  4537. REAL a,b,c,d;
  4538. a = left[3]*right[3] - left[0]*right[0] - left[1]*right[1] - left[2]*right[2];
  4539. b = left[3]*right[0] + right[3]*left[0] + left[1]*right[2] - right[1]*left[2];
  4540. c = left[3]*right[1] + right[3]*left[1] + left[2]*right[0] - right[2]*left[0];
  4541. d = left[3]*right[2] + right[3]*left[2] + left[0]*right[1] - right[0]*left[1];
  4542. quat[3] = a;
  4543. quat[0] = b;
  4544. quat[1] = c;
  4545. quat[2] = d;
  4546. }
  4547. }; // end of namespace