FloatMath.inl 109 KB

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