cd_hull.cpp 83 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261
  1. #include "float_math.h"
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <assert.h>
  6. #include <math.h>
  7. #include <float.h>
  8. /*----------------------------------------------------------------------
  9. Copyright (c) 2004 Open Dynamics Framework Group
  10. www.physicstools.org
  11. All rights reserved.
  12. Redistribution and use in source and binary forms, with or without modification, are permitted provided
  13. that the following conditions are met:
  14. Redistributions of source code must retain the above copyright notice, this list of conditions
  15. and the following disclaimer.
  16. Redistributions in binary form must reproduce the above copyright notice,
  17. this list of conditions and the following disclaimer in the documentation
  18. and/or other materials provided with the distribution.
  19. Neither the name of the Open Dynamics Framework Group nor the names of its contributors may
  20. be used to endorse or promote products derived from this software without specific prior written permission.
  21. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES,
  22. INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  23. DISCLAIMED. IN NO EVENT SHALL THE INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  24. EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  25. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
  26. IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  27. THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  28. -----------------------------------------------------------------------*/
  29. // http://codesuppository.blogspot.com
  30. //
  31. // mailto: [email protected]
  32. //
  33. // http://www.amillionpixels.us
  34. //
  35. #include "cd_hull.h"
  36. using namespace ConvexDecomposition;
  37. /*----------------------------------------------------------------------
  38. Copyright (c) 2004 Open Dynamics Framework Group
  39. www.physicstools.org
  40. All rights reserved.
  41. Redistribution and use in source and binary forms, with or without modification, are permitted provided
  42. that the following conditions are met:
  43. Redistributions of source code must retain the above copyright notice, this list of conditions
  44. and the following disclaimer.
  45. Redistributions in binary form must reproduce the above copyright notice,
  46. this list of conditions and the following disclaimer in the documentation
  47. and/or other materials provided with the distribution.
  48. Neither the name of the Open Dynamics Framework Group nor the names of its contributors may
  49. be used to endorse or promote products derived from this software without specific prior written permission.
  50. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES,
  51. INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  52. DISCLAIMED. IN NO EVENT SHALL THE INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  53. EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  54. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
  55. IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  56. THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  57. -----------------------------------------------------------------------*/
  58. #define PI 3.14159264f
  59. //*****************************************************
  60. //*****************************************************
  61. //********* Stan Melax's vector math template needed
  62. //********* to use his hull building code.
  63. //*****************************************************
  64. //*****************************************************
  65. #define DEG2RAD (PI / 180.0f)
  66. #define RAD2DEG (180.0f / PI)
  67. #define SQRT_OF_2 (1.4142135f)
  68. #define OFFSET(Class,Member) (((char*) (&(((Class*)NULL)-> Member )))- ((char*)NULL))
  69. namespace ConvexDecomposition
  70. {
  71. int argmin(float a[],int n);
  72. float sqr(float a);
  73. float clampf(float a) ;
  74. float Round(float a,float precision);
  75. float Interpolate(const float &f0,const float &f1,float alpha) ;
  76. template <class T>
  77. void Swap(T &a,T &b)
  78. {
  79. T tmp = a;
  80. a=b;
  81. b=tmp;
  82. }
  83. template <class T>
  84. T Max(const T &a,const T &b)
  85. {
  86. return (a>b)?a:b;
  87. }
  88. template <class T>
  89. T Min(const T &a,const T &b)
  90. {
  91. return (a<b)?a:b;
  92. }
  93. //----------------------------------
  94. class int3
  95. {
  96. public:
  97. int x,y,z;
  98. int3(){};
  99. int3(int _x,int _y, int _z){x=_x;y=_y;z=_z;}
  100. const int& operator[](int i) const {return (&x)[i];}
  101. int& operator[](int i) {return (&x)[i];}
  102. };
  103. //-------- 2D --------
  104. class float2
  105. {
  106. public:
  107. float x,y;
  108. float2(){x=0;y=0;};
  109. float2(float _x,float _y){x=_x;y=_y;}
  110. float& operator[](int i) {assert(i>=0&&i<2);return ((float*)this)[i];}
  111. const float& operator[](int i) const {assert(i>=0&&i<2);return ((float*)this)[i];}
  112. };
  113. inline float2 operator-( const float2& a, const float2& b ){return float2(a.x-b.x,a.y-b.y);}
  114. inline float2 operator+( const float2& a, const float2& b ){return float2(a.x+b.x,a.y+b.y);}
  115. //--------- 3D ---------
  116. class float3 // 3D
  117. {
  118. public:
  119. float x,y,z;
  120. float3(){x=0;y=0;z=0;};
  121. float3(float _x,float _y,float _z){x=_x;y=_y;z=_z;};
  122. //operator float *() { return &x;};
  123. float& operator[](int i) {assert(i>=0&&i<3);return ((float*)this)[i];}
  124. const float& operator[](int i) const {assert(i>=0&&i<3);return ((float*)this)[i];}
  125. # ifdef PLUGIN_3DSMAX
  126. float3(const Point3 &p):x(p.x),y(p.y),z(p.z){}
  127. operator Point3(){return *((Point3*)this);}
  128. # endif
  129. };
  130. float3& operator+=( float3 &a, const float3& b );
  131. float3& operator-=( float3 &a ,const float3& b );
  132. float3& operator*=( float3 &v ,const float s );
  133. float3& operator/=( float3 &v, const float s );
  134. float magnitude( const float3& v );
  135. float3 normalize( const float3& v );
  136. float3 safenormalize(const float3 &v);
  137. float3 vabs(const float3 &v);
  138. float3 operator+( const float3& a, const float3& b );
  139. float3 operator-( const float3& a, const float3& b );
  140. float3 operator-( const float3& v );
  141. float3 operator*( const float3& v, const float s );
  142. float3 operator*( const float s, const float3& v );
  143. float3 operator/( const float3& v, const float s );
  144. inline int operator==( const float3 &a, const float3 &b ) { return (a.x==b.x && a.y==b.y && a.z==b.z); }
  145. inline int operator!=( const float3 &a, const float3 &b ) { return (a.x!=b.x || a.y!=b.y || a.z!=b.z); }
  146. // due to ambiguity and inconsistent standards ther are no overloaded operators for mult such as va*vb.
  147. float dot( const float3& a, const float3& b );
  148. float3 cmul( const float3 &a, const float3 &b);
  149. float3 cross( const float3& a, const float3& b );
  150. float3 Interpolate(const float3 &v0,const float3 &v1,float alpha);
  151. float3 Round(const float3& a,float precision);
  152. float3 VectorMax(const float3 &a, const float3 &b);
  153. float3 VectorMin(const float3 &a, const float3 &b);
  154. class float3x3
  155. {
  156. public:
  157. float3 x,y,z; // the 3 rows of the Matrix
  158. float3x3(){}
  159. float3x3(float xx,float xy,float xz,float yx,float yy,float yz,float zx,float zy,float zz):x(xx,xy,xz),y(yx,yy,yz),z(zx,zy,zz){}
  160. float3x3(float3 _x,float3 _y,float3 _z):x(_x),y(_y),z(_z){}
  161. float3& operator[](int i) {assert(i>=0&&i<3);return (&x)[i];}
  162. const float3& operator[](int i) const {assert(i>=0&&i<3);return (&x)[i];}
  163. float& operator()(int r, int c) {assert(r>=0&&r<3&&c>=0&&c<3);return ((&x)[r])[c];}
  164. const float& operator()(int r, int c) const {assert(r>=0&&r<3&&c>=0&&c<3);return ((&x)[r])[c];}
  165. };
  166. float3x3 Transpose( const float3x3& m );
  167. float3 operator*( const float3& v , const float3x3& m );
  168. float3 operator*( const float3x3& m , const float3& v );
  169. float3x3 operator*( const float3x3& m , const float& s );
  170. float3x3 operator*( const float3x3& ma, const float3x3& mb );
  171. float3x3 operator/( const float3x3& a, const float& s ) ;
  172. float3x3 operator+( const float3x3& a, const float3x3& b );
  173. float3x3 operator-( const float3x3& a, const float3x3& b );
  174. float3x3 &operator+=( float3x3& a, const float3x3& b );
  175. float3x3 &operator-=( float3x3& a, const float3x3& b );
  176. float3x3 &operator*=( float3x3& a, const float& s );
  177. float Determinant(const float3x3& m );
  178. float3x3 Inverse(const float3x3& a); // its just 3x3 so we simply do that cofactor method
  179. //-------- 4D Math --------
  180. class float4
  181. {
  182. public:
  183. float x,y,z,w;
  184. float4(){x=0;y=0;z=0;w=0;};
  185. float4(float _x,float _y,float _z,float _w){x=_x;y=_y;z=_z;w=_w;}
  186. float4(const float3 &v,float _w){x=v.x;y=v.y;z=v.z;w=_w;}
  187. //operator float *() { return &x;};
  188. float& operator[](int i) {assert(i>=0&&i<4);return ((float*)this)[i];}
  189. const float& operator[](int i) const {assert(i>=0&&i<4);return ((float*)this)[i];}
  190. const float3& xyz() const { return *((float3*)this);}
  191. float3& xyz() { return *((float3*)this);}
  192. };
  193. struct D3DXMATRIX;
  194. class float4x4
  195. {
  196. public:
  197. float4 x,y,z,w; // the 4 rows
  198. float4x4(){}
  199. float4x4(const float4 &_x, const float4 &_y, const float4 &_z, const float4 &_w):x(_x),y(_y),z(_z),w(_w){}
  200. float4x4(float m00, float m01, float m02, float m03,
  201. float m10, float m11, float m12, float m13,
  202. float m20, float m21, float m22, float m23,
  203. float m30, float m31, float m32, float m33 )
  204. :x(m00,m01,m02,m03),y(m10,m11,m12,m13),z(m20,m21,m22,m23),w(m30,m31,m32,m33){}
  205. float& operator()(int r, int c) {assert(r>=0&&r<4&&c>=0&&c<4);return ((&x)[r])[c];}
  206. const float& operator()(int r, int c) const {assert(r>=0&&r<4&&c>=0&&c<4);return ((&x)[r])[c];}
  207. operator float* () {return &x.x;}
  208. operator const float* () const {return &x.x;}
  209. operator struct D3DXMATRIX* () { return (struct D3DXMATRIX*) this;}
  210. operator const struct D3DXMATRIX* () const { return (struct D3DXMATRIX*) this;}
  211. };
  212. int operator==( const float4 &a, const float4 &b );
  213. float4 Homogenize(const float3 &v3,const float &w=1.0f); // Turns a 3D float3 4D vector4 by appending w
  214. float4 cmul( const float4 &a, const float4 &b);
  215. float4 operator*( const float4 &v, float s);
  216. float4 operator*( float s, const float4 &v);
  217. float4 operator+( const float4 &a, const float4 &b);
  218. float4 operator-( const float4 &a, const float4 &b);
  219. float4x4 operator*( const float4x4& a, const float4x4& b );
  220. float4 operator*( const float4& v, const float4x4& m );
  221. float4x4 Inverse(const float4x4 &m);
  222. float4x4 MatrixRigidInverse(const float4x4 &m);
  223. float4x4 MatrixTranspose(const float4x4 &m);
  224. float4x4 MatrixPerspectiveFov(float fovy, float Aspect, float zn, float zf );
  225. float4x4 MatrixTranslation(const float3 &t);
  226. float4x4 MatrixRotationZ(const float angle_radians);
  227. float4x4 MatrixLookAt(const float3& eye, const float3& at, const float3& up);
  228. int operator==( const float4x4 &a, const float4x4 &b );
  229. //-------- Quaternion ------------
  230. class Quaternion :public float4
  231. {
  232. public:
  233. Quaternion() { x = y = z = 0.0f; w = 1.0f; }
  234. Quaternion( float3 v, float t ) { v = normalize(v); w = cosf(t/2.0f); v = v*sinf(t/2.0f); x = v.x; y = v.y; z = v.z; }
  235. Quaternion(float _x, float _y, float _z, float _w){x=_x;y=_y;z=_z;w=_w;}
  236. float angle() const { return acosf(w)*2.0f; }
  237. float3 axis() const { float3 a(x,y,z); if(fabsf(angle())<0.0000001f) return float3(1,0,0); return a*(1/sinf(angle()/2.0f)); }
  238. float3 xdir() const { return float3( 1-2*(y*y+z*z), 2*(x*y+w*z), 2*(x*z-w*y) ); }
  239. float3 ydir() const { return float3( 2*(x*y-w*z),1-2*(x*x+z*z), 2*(y*z+w*x) ); }
  240. float3 zdir() const { return float3( 2*(x*z+w*y), 2*(y*z-w*x),1-2*(x*x+y*y) ); }
  241. float3x3 getmatrix() const { return float3x3( xdir(), ydir(), zdir() ); }
  242. operator float3x3() { return getmatrix(); }
  243. void Normalize();
  244. };
  245. Quaternion& operator*=(Quaternion& a, float s );
  246. Quaternion operator*( const Quaternion& a, float s );
  247. Quaternion operator*( const Quaternion& a, const Quaternion& b);
  248. Quaternion operator+( const Quaternion& a, const Quaternion& b );
  249. Quaternion normalize( Quaternion a );
  250. float dot( const Quaternion &a, const Quaternion &b );
  251. float3 operator*( const Quaternion& q, const float3& v );
  252. float3 operator*( const float3& v, const Quaternion& q );
  253. Quaternion slerp( Quaternion a, const Quaternion& b, float interp );
  254. Quaternion Interpolate(const Quaternion &q0,const Quaternion &q1,float alpha);
  255. Quaternion RotationArc(float3 v0, float3 v1 ); // returns quat q where q*v0=v1
  256. Quaternion Inverse(const Quaternion &q);
  257. float4x4 MatrixFromQuatVec(const Quaternion &q, const float3 &v);
  258. //------ Euler Angle -----
  259. Quaternion YawPitchRoll( float yaw, float pitch, float roll );
  260. float Yaw( const Quaternion& q );
  261. float Pitch( const Quaternion& q );
  262. float Roll( Quaternion q );
  263. float Yaw( const float3& v );
  264. float Pitch( const float3& v );
  265. //------- Plane ----------
  266. class Plane
  267. {
  268. public:
  269. float3 normal;
  270. float dist; // distance below origin - the D from plane equasion Ax+By+Cz+D=0
  271. Plane(const float3 &n,float d):normal(n),dist(d){}
  272. Plane():normal(),dist(0){}
  273. void Transform(const float3 &position, const Quaternion &orientation);
  274. };
  275. inline Plane PlaneFlip(const Plane &plane){return Plane(-plane.normal,-plane.dist);}
  276. inline int operator==( const Plane &a, const Plane &b ) { return (a.normal==b.normal && a.dist==b.dist); }
  277. inline int coplanar( const Plane &a, const Plane &b ) { return (a==b || a==PlaneFlip(b)); }
  278. //--------- Utility Functions ------
  279. float3 PlaneLineIntersection(const Plane &plane, const float3 &p0, const float3 &p1);
  280. float3 PlaneProject(const Plane &plane, const float3 &point);
  281. float3 LineProject(const float3 &p0, const float3 &p1, const float3 &a); // projects a onto infinite line p0p1
  282. float LineProjectTime(const float3 &p0, const float3 &p1, const float3 &a);
  283. float3 ThreePlaneIntersection(const Plane &p0,const Plane &p1, const Plane &p2);
  284. int PolyHit(const float3 *vert,const int n,const float3 &v0, const float3 &v1, float3 *impact=NULL, float3 *normal=NULL);
  285. int BoxInside(const float3 &p,const float3 &bmin, const float3 &bmax) ;
  286. int BoxIntersect(const float3 &v0, const float3 &v1, const float3 &bmin, const float3 &bmax, float3 *impact);
  287. float DistanceBetweenLines(const float3 &ustart, const float3 &udir, const float3 &vstart, const float3 &vdir, float3 *upoint=NULL, float3 *vpoint=NULL);
  288. float3 TriNormal(const float3 &v0, const float3 &v1, const float3 &v2);
  289. float3 NormalOf(const float3 *vert, const int n);
  290. Quaternion VirtualTrackBall(const float3 &cop, const float3 &cor, const float3 &dir0, const float3 &dir1);
  291. float sqr(float a) {return a*a;}
  292. float clampf(float a) {return Min(1.0f,Max(0.0f,a));}
  293. float Round(float a,float precision)
  294. {
  295. return floorf(0.5f+a/precision)*precision;
  296. }
  297. float Interpolate(const float &f0,const float &f1,float alpha)
  298. {
  299. return f0*(1-alpha) + f1*alpha;
  300. }
  301. int argmin(float a[],int n)
  302. {
  303. int r=0;
  304. for(int i=1;i<n;i++)
  305. {
  306. if(a[i]<a[r])
  307. {
  308. r = i;
  309. }
  310. }
  311. return r;
  312. }
  313. //------------ float3 (3D) --------------
  314. float3 operator+( const float3& a, const float3& b )
  315. {
  316. return float3(a.x+b.x, a.y+b.y, a.z+b.z);
  317. }
  318. float3 operator-( const float3& a, const float3& b )
  319. {
  320. return float3( a.x-b.x, a.y-b.y, a.z-b.z );
  321. }
  322. float3 operator-( const float3& v )
  323. {
  324. return float3( -v.x, -v.y, -v.z );
  325. }
  326. float3 operator*( const float3& v, float s )
  327. {
  328. return float3( v.x*s, v.y*s, v.z*s );
  329. }
  330. float3 operator*( float s, const float3& v )
  331. {
  332. return float3( v.x*s, v.y*s, v.z*s );
  333. }
  334. float3 operator/( const float3& v, float s )
  335. {
  336. return v*(1.0f/s);
  337. }
  338. float dot( const float3& a, const float3& b )
  339. {
  340. return a.x*b.x + a.y*b.y + a.z*b.z;
  341. }
  342. float3 cmul( const float3 &v1, const float3 &v2)
  343. {
  344. return float3(v1.x*v2.x, v1.y*v2.y, v1.z*v2.z);
  345. }
  346. float3 cross( const float3& a, const float3& b )
  347. {
  348. return float3( a.y*b.z - a.z*b.y,
  349. a.z*b.x - a.x*b.z,
  350. a.x*b.y - a.y*b.x );
  351. }
  352. float3& operator+=( float3& a , const float3& b )
  353. {
  354. a.x += b.x;
  355. a.y += b.y;
  356. a.z += b.z;
  357. return a;
  358. }
  359. float3& operator-=( float3& a , const float3& b )
  360. {
  361. a.x -= b.x;
  362. a.y -= b.y;
  363. a.z -= b.z;
  364. return a;
  365. }
  366. float3& operator*=(float3& v , float s )
  367. {
  368. v.x *= s;
  369. v.y *= s;
  370. v.z *= s;
  371. return v;
  372. }
  373. float3& operator/=(float3& v , float s )
  374. {
  375. float sinv = 1.0f / s;
  376. v.x *= sinv;
  377. v.y *= sinv;
  378. v.z *= sinv;
  379. return v;
  380. }
  381. float3 vabs(const float3 &v)
  382. {
  383. return float3(fabsf(v.x),fabsf(v.y),fabsf(v.z));
  384. }
  385. float magnitude( const float3& v )
  386. {
  387. return sqrtf(sqr(v.x) + sqr( v.y)+ sqr(v.z));
  388. }
  389. float3 normalize( const float3 &v )
  390. {
  391. // this routine, normalize, is ok, provided magnitude works!!
  392. float d=magnitude(v);
  393. if (d==0)
  394. {
  395. printf("Cant normalize ZERO vector\n");
  396. assert(0);// yes this could go here
  397. d=0.1f;
  398. }
  399. d = 1/d;
  400. return float3(v.x*d,v.y*d,v.z*d);
  401. }
  402. float3 safenormalize(const float3 &v)
  403. {
  404. if(magnitude(v)<=0.0f)
  405. {
  406. return float3(1,0,0);
  407. }
  408. return normalize(v);
  409. }
  410. float3 Round(const float3 &a,float precision)
  411. {
  412. return float3(Round(a.x,precision),Round(a.y,precision),Round(a.z,precision));
  413. }
  414. float3 Interpolate(const float3 &v0,const float3 &v1,float alpha)
  415. {
  416. return v0*(1-alpha) + v1*alpha;
  417. }
  418. float3 VectorMin(const float3 &a,const float3 &b)
  419. {
  420. return float3(Min(a.x,b.x),Min(a.y,b.y),Min(a.z,b.z));
  421. }
  422. float3 VectorMax(const float3 &a,const float3 &b)
  423. {
  424. return float3(Max(a.x,b.x),Max(a.y,b.y),Max(a.z,b.z));
  425. }
  426. // the statement v1*v2 is ambiguous since there are 3 types
  427. // of vector multiplication
  428. // - componantwise (for example combining colors)
  429. // - dot product
  430. // - cross product
  431. // Therefore we never declare/implement this function.
  432. // So we will never see: float3 operator*(float3 a,float3 b)
  433. //------------ float3x3 ---------------
  434. float Determinant(const float3x3 &m)
  435. {
  436. return m.x.x*m.y.y*m.z.z + m.y.x*m.z.y*m.x.z + m.z.x*m.x.y*m.y.z
  437. -m.x.x*m.z.y*m.y.z - m.y.x*m.x.y*m.z.z - m.z.x*m.y.y*m.x.z ;
  438. }
  439. float3x3 Inverse(const float3x3 &a)
  440. {
  441. float3x3 b;
  442. float d=Determinant(a);
  443. assert(d!=0);
  444. for(int i=0;i<3;i++)
  445. {
  446. for(int j=0;j<3;j++)
  447. {
  448. int i1=(i+1)%3;
  449. int i2=(i+2)%3;
  450. int j1=(j+1)%3;
  451. int j2=(j+2)%3;
  452. // reverse indexs i&j to take transpose
  453. b[j][i] = (a[i1][j1]*a[i2][j2]-a[i1][j2]*a[i2][j1])/d;
  454. }
  455. }
  456. // Matrix check=a*b; // Matrix 'check' should be the identity (or close to it)
  457. return b;
  458. }
  459. float3x3 Transpose( const float3x3& m )
  460. {
  461. return float3x3( float3(m.x.x,m.y.x,m.z.x),
  462. float3(m.x.y,m.y.y,m.z.y),
  463. float3(m.x.z,m.y.z,m.z.z));
  464. }
  465. float3 operator*(const float3& v , const float3x3 &m ) {
  466. return float3((m.x.x*v.x + m.y.x*v.y + m.z.x*v.z),
  467. (m.x.y*v.x + m.y.y*v.y + m.z.y*v.z),
  468. (m.x.z*v.x + m.y.z*v.y + m.z.z*v.z));
  469. }
  470. float3 operator*(const float3x3 &m,const float3& v ) {
  471. return float3(dot(m.x,v),dot(m.y,v),dot(m.z,v));
  472. }
  473. float3x3 operator*( const float3x3& a, const float3x3& b )
  474. {
  475. return float3x3(a.x*b,a.y*b,a.z*b);
  476. }
  477. float3x3 operator*( const float3x3& a, const float& s )
  478. {
  479. return float3x3(a.x*s, a.y*s ,a.z*s);
  480. }
  481. float3x3 operator/( const float3x3& a, const float& s )
  482. {
  483. float t=1/s;
  484. return float3x3(a.x*t, a.y*t ,a.z*t);
  485. }
  486. float3x3 operator+( const float3x3& a, const float3x3& b )
  487. {
  488. return float3x3(a.x+b.x, a.y+b.y, a.z+b.z);
  489. }
  490. float3x3 operator-( const float3x3& a, const float3x3& b )
  491. {
  492. return float3x3(a.x-b.x, a.y-b.y, a.z-b.z);
  493. }
  494. float3x3 &operator+=( float3x3& a, const float3x3& b )
  495. {
  496. a.x+=b.x;
  497. a.y+=b.y;
  498. a.z+=b.z;
  499. return a;
  500. }
  501. float3x3 &operator-=( float3x3& a, const float3x3& b )
  502. {
  503. a.x-=b.x;
  504. a.y-=b.y;
  505. a.z-=b.z;
  506. return a;
  507. }
  508. float3x3 &operator*=( float3x3& a, const float& s )
  509. {
  510. a.x*=s;
  511. a.y*=s;
  512. a.z*=s;
  513. return a;
  514. }
  515. float3 ThreePlaneIntersection(const Plane &p0,const Plane &p1, const Plane &p2){
  516. float3x3 mp =Transpose(float3x3(p0.normal,p1.normal,p2.normal));
  517. float3x3 mi = Inverse(mp);
  518. float3 b(p0.dist,p1.dist,p2.dist);
  519. return -b * mi;
  520. }
  521. //--------------- 4D ----------------
  522. float4 operator*( const float4& v, const float4x4& m )
  523. {
  524. return v.x*m.x + v.y*m.y + v.z*m.z + v.w*m.w; // yes this actually works
  525. }
  526. int operator==( const float4 &a, const float4 &b )
  527. {
  528. return (a.x==b.x && a.y==b.y && a.z==b.z && a.w==b.w);
  529. }
  530. // Dont implement m*v for now, since that might confuse us
  531. // All our transforms are based on multiplying the "row" vector on the left
  532. //float4 operator*(const float4x4& m , const float4& v )
  533. //{
  534. // return float4(dot(v,m.x),dot(v,m.y),dot(v,m.z),dot(v,m.w));
  535. //}
  536. float4 cmul( const float4 &a, const float4 &b)
  537. {
  538. return float4(a.x*b.x,a.y*b.y,a.z*b.z,a.w*b.w);
  539. }
  540. float4 operator*( const float4 &v, float s)
  541. {
  542. return float4(v.x*s,v.y*s,v.z*s,v.w*s);
  543. }
  544. float4 operator*( float s, const float4 &v)
  545. {
  546. return float4(v.x*s,v.y*s,v.z*s,v.w*s);
  547. }
  548. float4 operator+( const float4 &a, const float4 &b)
  549. {
  550. return float4(a.x+b.x,a.y+b.y,a.z+b.z,a.w+b.w);
  551. }
  552. float4 operator-( const float4 &a, const float4 &b)
  553. {
  554. return float4(a.x-b.x,a.y-b.y,a.z-b.z,a.w-b.w);
  555. }
  556. float4 Homogenize(const float3 &v3,const float &w)
  557. {
  558. return float4(v3.x,v3.y,v3.z,w);
  559. }
  560. float4x4 operator*( const float4x4& a, const float4x4& b )
  561. {
  562. return float4x4(a.x*b,a.y*b,a.z*b,a.w*b);
  563. }
  564. float4x4 MatrixTranspose(const float4x4 &m)
  565. {
  566. return float4x4(
  567. m.x.x, m.y.x, m.z.x, m.w.x,
  568. m.x.y, m.y.y, m.z.y, m.w.y,
  569. m.x.z, m.y.z, m.z.z, m.w.z,
  570. m.x.w, m.y.w, m.z.w, m.w.w );
  571. }
  572. float4x4 MatrixRigidInverse(const float4x4 &m)
  573. {
  574. float4x4 trans_inverse = MatrixTranslation(-m.w.xyz());
  575. float4x4 rot = m;
  576. rot.w = float4(0,0,0,1);
  577. return trans_inverse * MatrixTranspose(rot);
  578. }
  579. float4x4 MatrixPerspectiveFov(float fovy, float aspect, float zn, float zf )
  580. {
  581. float h = 1.0f/tanf(fovy/2.0f); // view space height
  582. float w = h / aspect ; // view space width
  583. return float4x4(
  584. w, 0, 0 , 0,
  585. 0, h, 0 , 0,
  586. 0, 0, zf/(zn-zf) , -1,
  587. 0, 0, zn*zf/(zn-zf) , 0 );
  588. }
  589. float4x4 MatrixLookAt(const float3& eye, const float3& at, const float3& up)
  590. {
  591. float4x4 m;
  592. m.w.w = 1.0f;
  593. m.w.xyz() = eye;
  594. m.z.xyz() = normalize(eye-at);
  595. m.x.xyz() = normalize(cross(up,m.z.xyz()));
  596. m.y.xyz() = cross(m.z.xyz(),m.x.xyz());
  597. return MatrixRigidInverse(m);
  598. }
  599. float4x4 MatrixTranslation(const float3 &t)
  600. {
  601. return float4x4(
  602. 1, 0, 0, 0,
  603. 0, 1, 0, 0,
  604. 0, 0, 1, 0,
  605. t.x,t.y,t.z,1 );
  606. }
  607. float4x4 MatrixRotationZ(const float angle_radians)
  608. {
  609. float s = sinf(angle_radians);
  610. float c = cosf(angle_radians);
  611. return float4x4(
  612. c, s, 0, 0,
  613. -s, c, 0, 0,
  614. 0, 0, 1, 0,
  615. 0, 0, 0, 1 );
  616. }
  617. int operator==( const float4x4 &a, const float4x4 &b )
  618. {
  619. return (a.x==b.x && a.y==b.y && a.z==b.z && a.w==b.w);
  620. }
  621. float4x4 Inverse(const float4x4 &m)
  622. {
  623. float4x4 d;
  624. float *dst = &d.x.x;
  625. float tmp[12]; /* temp array for pairs */
  626. float src[16]; /* array of transpose source matrix */
  627. float det; /* determinant */
  628. /* transpose matrix */
  629. for ( int i = 0; i < 4; i++) {
  630. src[i] = m(i,0) ;
  631. src[i + 4] = m(i,1);
  632. src[i + 8] = m(i,2);
  633. src[i + 12] = m(i,3);
  634. }
  635. /* calculate pairs for first 8 elements (cofactors) */
  636. tmp[0] = src[10] * src[15];
  637. tmp[1] = src[11] * src[14];
  638. tmp[2] = src[9] * src[15];
  639. tmp[3] = src[11] * src[13];
  640. tmp[4] = src[9] * src[14];
  641. tmp[5] = src[10] * src[13];
  642. tmp[6] = src[8] * src[15];
  643. tmp[7] = src[11] * src[12];
  644. tmp[8] = src[8] * src[14];
  645. tmp[9] = src[10] * src[12];
  646. tmp[10] = src[8] * src[13];
  647. tmp[11] = src[9] * src[12];
  648. /* calculate first 8 elements (cofactors) */
  649. dst[0] = tmp[0]*src[5] + tmp[3]*src[6] + tmp[4]*src[7];
  650. dst[0] -= tmp[1]*src[5] + tmp[2]*src[6] + tmp[5]*src[7];
  651. dst[1] = tmp[1]*src[4] + tmp[6]*src[6] + tmp[9]*src[7];
  652. dst[1] -= tmp[0]*src[4] + tmp[7]*src[6] + tmp[8]*src[7];
  653. dst[2] = tmp[2]*src[4] + tmp[7]*src[5] + tmp[10]*src[7];
  654. dst[2] -= tmp[3]*src[4] + tmp[6]*src[5] + tmp[11]*src[7];
  655. dst[3] = tmp[5]*src[4] + tmp[8]*src[5] + tmp[11]*src[6];
  656. dst[3] -= tmp[4]*src[4] + tmp[9]*src[5] + tmp[10]*src[6];
  657. dst[4] = tmp[1]*src[1] + tmp[2]*src[2] + tmp[5]*src[3];
  658. dst[4] -= tmp[0]*src[1] + tmp[3]*src[2] + tmp[4]*src[3];
  659. dst[5] = tmp[0]*src[0] + tmp[7]*src[2] + tmp[8]*src[3];
  660. dst[5] -= tmp[1]*src[0] + tmp[6]*src[2] + tmp[9]*src[3];
  661. dst[6] = tmp[3]*src[0] + tmp[6]*src[1] + tmp[11]*src[3];
  662. dst[6] -= tmp[2]*src[0] + tmp[7]*src[1] + tmp[10]*src[3];
  663. dst[7] = tmp[4]*src[0] + tmp[9]*src[1] + tmp[10]*src[2];
  664. dst[7] -= tmp[5]*src[0] + tmp[8]*src[1] + tmp[11]*src[2];
  665. /* calculate pairs for second 8 elements (cofactors) */
  666. tmp[0] = src[2]*src[7];
  667. tmp[1] = src[3]*src[6];
  668. tmp[2] = src[1]*src[7];
  669. tmp[3] = src[3]*src[5];
  670. tmp[4] = src[1]*src[6];
  671. tmp[5] = src[2]*src[5];
  672. tmp[6] = src[0]*src[7];
  673. tmp[7] = src[3]*src[4];
  674. tmp[8] = src[0]*src[6];
  675. tmp[9] = src[2]*src[4];
  676. tmp[10] = src[0]*src[5];
  677. tmp[11] = src[1]*src[4];
  678. /* calculate second 8 elements (cofactors) */
  679. dst[8] = tmp[0]*src[13] + tmp[3]*src[14] + tmp[4]*src[15];
  680. dst[8] -= tmp[1]*src[13] + tmp[2]*src[14] + tmp[5]*src[15];
  681. dst[9] = tmp[1]*src[12] + tmp[6]*src[14] + tmp[9]*src[15];
  682. dst[9] -= tmp[0]*src[12] + tmp[7]*src[14] + tmp[8]*src[15];
  683. dst[10] = tmp[2]*src[12] + tmp[7]*src[13] + tmp[10]*src[15];
  684. dst[10]-= tmp[3]*src[12] + tmp[6]*src[13] + tmp[11]*src[15];
  685. dst[11] = tmp[5]*src[12] + tmp[8]*src[13] + tmp[11]*src[14];
  686. dst[11]-= tmp[4]*src[12] + tmp[9]*src[13] + tmp[10]*src[14];
  687. dst[12] = tmp[2]*src[10] + tmp[5]*src[11] + tmp[1]*src[9];
  688. dst[12]-= tmp[4]*src[11] + tmp[0]*src[9] + tmp[3]*src[10];
  689. dst[13] = tmp[8]*src[11] + tmp[0]*src[8] + tmp[7]*src[10];
  690. dst[13]-= tmp[6]*src[10] + tmp[9]*src[11] + tmp[1]*src[8];
  691. dst[14] = tmp[6]*src[9] + tmp[11]*src[11] + tmp[3]*src[8];
  692. dst[14]-= tmp[10]*src[11] + tmp[2]*src[8] + tmp[7]*src[9];
  693. dst[15] = tmp[10]*src[10] + tmp[4]*src[8] + tmp[9]*src[9];
  694. dst[15]-= tmp[8]*src[9] + tmp[11]*src[10] + tmp[5]*src[8];
  695. /* calculate determinant */
  696. det=src[0]*dst[0]+src[1]*dst[1]+src[2]*dst[2]+src[3]*dst[3];
  697. /* calculate matrix inverse */
  698. det = 1/det;
  699. for ( int j = 0; j < 16; j++)
  700. dst[j] *= det;
  701. return d;
  702. }
  703. //--------- Quaternion --------------
  704. Quaternion operator*( const Quaternion& a, const Quaternion& b )
  705. {
  706. Quaternion c;
  707. c.w = a.w*b.w - a.x*b.x - a.y*b.y - a.z*b.z;
  708. c.x = a.w*b.x + a.x*b.w + a.y*b.z - a.z*b.y;
  709. c.y = a.w*b.y - a.x*b.z + a.y*b.w + a.z*b.x;
  710. c.z = a.w*b.z + a.x*b.y - a.y*b.x + a.z*b.w;
  711. return c;
  712. }
  713. Quaternion operator*( const Quaternion& a, float b )
  714. {
  715. return Quaternion(a.x*b, a.y*b, a.z*b ,a.w*b);
  716. }
  717. Quaternion Inverse(const Quaternion &q)
  718. {
  719. return Quaternion(-q.x,-q.y,-q.z,q.w);
  720. }
  721. Quaternion& operator*=( Quaternion& q, const float s )
  722. {
  723. q.x *= s;
  724. q.y *= s;
  725. q.z *= s;
  726. q.w *= s;
  727. return q;
  728. }
  729. void Quaternion::Normalize()
  730. {
  731. float m = sqrtf(sqr(w)+sqr(x)+sqr(y)+sqr(z));
  732. if(m<0.000000001f) {
  733. w=1.0f;
  734. x=y=z=0.0f;
  735. return;
  736. }
  737. (*this) *= (1.0f/m);
  738. }
  739. float3 operator*( const Quaternion& q, const float3& v )
  740. {
  741. // The following is equivalent to:
  742. //return (q.getmatrix() * v);
  743. float qx2 = q.x*q.x;
  744. float qy2 = q.y*q.y;
  745. float qz2 = q.z*q.z;
  746. float qxqy = q.x*q.y;
  747. float qxqz = q.x*q.z;
  748. float qxqw = q.x*q.w;
  749. float qyqz = q.y*q.z;
  750. float qyqw = q.y*q.w;
  751. float qzqw = q.z*q.w;
  752. return float3(
  753. (1-2*(qy2+qz2))*v.x + (2*(qxqy-qzqw))*v.y + (2*(qxqz+qyqw))*v.z ,
  754. (2*(qxqy+qzqw))*v.x + (1-2*(qx2+qz2))*v.y + (2*(qyqz-qxqw))*v.z ,
  755. (2*(qxqz-qyqw))*v.x + (2*(qyqz+qxqw))*v.y + (1-2*(qx2+qy2))*v.z );
  756. }
  757. float3 operator*( const float3& v, const Quaternion& q )
  758. {
  759. assert(0); // must multiply with the quat on the left
  760. return float3(0.0f,0.0f,0.0f);
  761. }
  762. Quaternion operator+( const Quaternion& a, const Quaternion& b )
  763. {
  764. return Quaternion(a.x+b.x, a.y+b.y, a.z+b.z, a.w+b.w);
  765. }
  766. float dot( const Quaternion &a,const Quaternion &b )
  767. {
  768. return (a.w*b.w + a.x*b.x + a.y*b.y + a.z*b.z);
  769. }
  770. Quaternion normalize( Quaternion a )
  771. {
  772. float m = sqrtf(sqr(a.w)+sqr(a.x)+sqr(a.y)+sqr(a.z));
  773. if(m<0.000000001)
  774. {
  775. a.w=1;
  776. a.x=a.y=a.z=0;
  777. return a;
  778. }
  779. return a * (1/m);
  780. }
  781. Quaternion slerp( Quaternion a, const Quaternion& b, float interp )
  782. {
  783. if(dot(a,b) <0.0)
  784. {
  785. a.w=-a.w;
  786. a.x=-a.x;
  787. a.y=-a.y;
  788. a.z=-a.z;
  789. }
  790. float d = dot(a,b);
  791. if(d>=1.0) {
  792. return a;
  793. }
  794. float theta = acosf(d);
  795. if(theta==0.0f) { return(a);}
  796. return a*(sinf(theta-interp*theta)/sinf(theta)) + b*(sinf(interp*theta)/sinf(theta));
  797. }
  798. Quaternion Interpolate(const Quaternion &q0,const Quaternion &q1,float alpha) {
  799. return slerp(q0,q1,alpha);
  800. }
  801. Quaternion YawPitchRoll( float yaw, float pitch, float roll )
  802. {
  803. roll *= DEG2RAD;
  804. yaw *= DEG2RAD;
  805. pitch *= DEG2RAD;
  806. return Quaternion(float3(0.0f,0.0f,1.0f),yaw)*Quaternion(float3(1.0f,0.0f,0.0f),pitch)*Quaternion(float3(0.0f,1.0f,0.0f),roll);
  807. }
  808. float Yaw( const Quaternion& q )
  809. {
  810. float3 v;
  811. v=q.ydir();
  812. return (v.y==0.0&&v.x==0.0) ? 0.0f: atan2f(-v.x,v.y)*RAD2DEG;
  813. }
  814. float Pitch( const Quaternion& q )
  815. {
  816. float3 v;
  817. v=q.ydir();
  818. return atan2f(v.z,sqrtf(sqr(v.x)+sqr(v.y)))*RAD2DEG;
  819. }
  820. float Roll( Quaternion q )
  821. {
  822. q = Quaternion(float3(0.0f,0.0f,1.0f),-Yaw(q)*DEG2RAD) *q;
  823. q = Quaternion(float3(1.0f,0.0f,0.0f),-Pitch(q)*DEG2RAD) *q;
  824. return atan2f(-q.xdir().z,q.xdir().x)*RAD2DEG;
  825. }
  826. float Yaw( const float3& v )
  827. {
  828. return (v.y==0.0&&v.x==0.0) ? 0.0f: atan2f(-v.x,v.y)*RAD2DEG;
  829. }
  830. float Pitch( const float3& v )
  831. {
  832. return atan2f(v.z,sqrtf(sqr(v.x)+sqr(v.y)))*RAD2DEG;
  833. }
  834. //------------- Plane --------------
  835. void Plane::Transform(const float3 &position, const Quaternion &orientation) {
  836. // Transforms the plane to the space defined by the
  837. // given position/orientation.
  838. float3 newnormal;
  839. float3 origin;
  840. newnormal = Inverse(orientation)*normal;
  841. origin = Inverse(orientation)*(-normal*dist - position);
  842. normal = newnormal;
  843. dist = -dot(newnormal, origin);
  844. }
  845. //--------- utility functions -------------
  846. // RotationArc()
  847. // Given two vectors v0 and v1 this function
  848. // returns quaternion q where q*v0==v1.
  849. // Routine taken from game programming gems.
  850. Quaternion RotationArc(float3 v0,float3 v1){
  851. Quaternion q;
  852. v0 = normalize(v0); // Comment these two lines out if you know its not needed.
  853. v1 = normalize(v1); // If vector is already unit length then why do it again?
  854. float3 c = cross(v0,v1);
  855. float d = dot(v0,v1);
  856. if(d<=-1.0f) { return Quaternion(1,0,0,0);} // 180 about x axis
  857. float s = sqrtf((1+d)*2);
  858. q.x = c.x / s;
  859. q.y = c.y / s;
  860. q.z = c.z / s;
  861. q.w = s /2.0f;
  862. return q;
  863. }
  864. float4x4 MatrixFromQuatVec(const Quaternion &q, const float3 &v)
  865. {
  866. // builds a 4x4 transformation matrix based on orientation q and translation v
  867. float qx2 = q.x*q.x;
  868. float qy2 = q.y*q.y;
  869. float qz2 = q.z*q.z;
  870. float qxqy = q.x*q.y;
  871. float qxqz = q.x*q.z;
  872. float qxqw = q.x*q.w;
  873. float qyqz = q.y*q.z;
  874. float qyqw = q.y*q.w;
  875. float qzqw = q.z*q.w;
  876. return float4x4(
  877. 1-2*(qy2+qz2),
  878. 2*(qxqy+qzqw),
  879. 2*(qxqz-qyqw),
  880. 0 ,
  881. 2*(qxqy-qzqw),
  882. 1-2*(qx2+qz2),
  883. 2*(qyqz+qxqw),
  884. 0 ,
  885. 2*(qxqz+qyqw),
  886. 2*(qyqz-qxqw),
  887. 1-2*(qx2+qy2),
  888. 0 ,
  889. v.x ,
  890. v.y ,
  891. v.z ,
  892. 1.0f );
  893. }
  894. float3 PlaneLineIntersection(const Plane &plane, const float3 &p0, const float3 &p1)
  895. {
  896. // returns the point where the line p0-p1 intersects the plane n&d
  897. float3 dif;
  898. dif = p1-p0;
  899. float dn= dot(plane.normal,dif);
  900. float t = -(plane.dist+dot(plane.normal,p0) )/dn;
  901. return p0 + (dif*t);
  902. }
  903. float3 PlaneProject(const Plane &plane, const float3 &point)
  904. {
  905. return point - plane.normal * (dot(point,plane.normal)+plane.dist);
  906. }
  907. float3 LineProject(const float3 &p0, const float3 &p1, const float3 &a)
  908. {
  909. float3 w;
  910. w = p1-p0;
  911. float t= dot(w,(a-p0)) / (sqr(w.x)+sqr(w.y)+sqr(w.z));
  912. return p0+ w*t;
  913. }
  914. float LineProjectTime(const float3 &p0, const float3 &p1, const float3 &a)
  915. {
  916. float3 w;
  917. w = p1-p0;
  918. float t= dot(w,(a-p0)) / (sqr(w.x)+sqr(w.y)+sqr(w.z));
  919. return t;
  920. }
  921. float3 TriNormal(const float3 &v0, const float3 &v1, const float3 &v2)
  922. {
  923. // return the normal of the triangle
  924. // inscribed by v0, v1, and v2
  925. float3 cp=cross(v1-v0,v2-v1);
  926. float m=magnitude(cp);
  927. if(m==0) return float3(1,0,0);
  928. return cp*(1.0f/m);
  929. }
  930. int BoxInside(const float3 &p, const float3 &bmin, const float3 &bmax)
  931. {
  932. return (p.x >= bmin.x && p.x <=bmax.x &&
  933. p.y >= bmin.y && p.y <=bmax.y &&
  934. p.z >= bmin.z && p.z <=bmax.z );
  935. }
  936. int BoxIntersect(const float3 &v0, const float3 &v1, const float3 &bmin, const float3 &bmax,float3 *impact)
  937. {
  938. if(BoxInside(v0,bmin,bmax))
  939. {
  940. *impact=v0;
  941. return 1;
  942. }
  943. if(v0.x<=bmin.x && v1.x>=bmin.x)
  944. {
  945. float a = (bmin.x-v0.x)/(v1.x-v0.x);
  946. //v.x = bmin.x;
  947. float vy = (1-a) *v0.y + a*v1.y;
  948. float vz = (1-a) *v0.z + a*v1.z;
  949. if(vy>=bmin.y && vy<=bmax.y && vz>=bmin.z && vz<=bmax.z)
  950. {
  951. impact->x = bmin.x;
  952. impact->y = vy;
  953. impact->z = vz;
  954. return 1;
  955. }
  956. }
  957. else if(v0.x >= bmax.x && v1.x <= bmax.x)
  958. {
  959. float a = (bmax.x-v0.x)/(v1.x-v0.x);
  960. //v.x = bmax.x;
  961. float vy = (1-a) *v0.y + a*v1.y;
  962. float vz = (1-a) *v0.z + a*v1.z;
  963. if(vy>=bmin.y && vy<=bmax.y && vz>=bmin.z && vz<=bmax.z)
  964. {
  965. impact->x = bmax.x;
  966. impact->y = vy;
  967. impact->z = vz;
  968. return 1;
  969. }
  970. }
  971. if(v0.y<=bmin.y && v1.y>=bmin.y)
  972. {
  973. float a = (bmin.y-v0.y)/(v1.y-v0.y);
  974. float vx = (1-a) *v0.x + a*v1.x;
  975. //v.y = bmin.y;
  976. float vz = (1-a) *v0.z + a*v1.z;
  977. if(vx>=bmin.x && vx<=bmax.x && vz>=bmin.z && vz<=bmax.z)
  978. {
  979. impact->x = vx;
  980. impact->y = bmin.y;
  981. impact->z = vz;
  982. return 1;
  983. }
  984. }
  985. else if(v0.y >= bmax.y && v1.y <= bmax.y)
  986. {
  987. float a = (bmax.y-v0.y)/(v1.y-v0.y);
  988. float vx = (1-a) *v0.x + a*v1.x;
  989. // vy = bmax.y;
  990. float vz = (1-a) *v0.z + a*v1.z;
  991. if(vx>=bmin.x && vx<=bmax.x && vz>=bmin.z && vz<=bmax.z)
  992. {
  993. impact->x = vx;
  994. impact->y = bmax.y;
  995. impact->z = vz;
  996. return 1;
  997. }
  998. }
  999. if(v0.z<=bmin.z && v1.z>=bmin.z)
  1000. {
  1001. float a = (bmin.z-v0.z)/(v1.z-v0.z);
  1002. float vx = (1-a) *v0.x + a*v1.x;
  1003. float vy = (1-a) *v0.y + a*v1.y;
  1004. // v.z = bmin.z;
  1005. if(vy>=bmin.y && vy<=bmax.y && vx>=bmin.x && vx<=bmax.x)
  1006. {
  1007. impact->x = vx;
  1008. impact->y = vy;
  1009. impact->z = bmin.z;
  1010. return 1;
  1011. }
  1012. }
  1013. else if(v0.z >= bmax.z && v1.z <= bmax.z)
  1014. {
  1015. float a = (bmax.z-v0.z)/(v1.z-v0.z);
  1016. float vx = (1-a) *v0.x + a*v1.x;
  1017. float vy = (1-a) *v0.y + a*v1.y;
  1018. // v.z = bmax.z;
  1019. if(vy>=bmin.y && vy<=bmax.y && vx>=bmin.x && vx<=bmax.x)
  1020. {
  1021. impact->x = vx;
  1022. impact->y = vy;
  1023. impact->z = bmax.z;
  1024. return 1;
  1025. }
  1026. }
  1027. return 0;
  1028. }
  1029. float DistanceBetweenLines(const float3 &ustart, const float3 &udir, const float3 &vstart, const float3 &vdir, float3 *upoint, float3 *vpoint)
  1030. {
  1031. float3 cp;
  1032. cp = normalize(cross(udir,vdir));
  1033. float distu = -dot(cp,ustart);
  1034. float distv = -dot(cp,vstart);
  1035. float dist = (float)fabs(distu-distv);
  1036. if(upoint)
  1037. {
  1038. Plane plane;
  1039. plane.normal = normalize(cross(vdir,cp));
  1040. plane.dist = -dot(plane.normal,vstart);
  1041. *upoint = PlaneLineIntersection(plane,ustart,ustart+udir);
  1042. }
  1043. if(vpoint)
  1044. {
  1045. Plane plane;
  1046. plane.normal = normalize(cross(udir,cp));
  1047. plane.dist = -dot(plane.normal,ustart);
  1048. *vpoint = PlaneLineIntersection(plane,vstart,vstart+vdir);
  1049. }
  1050. return dist;
  1051. }
  1052. Quaternion VirtualTrackBall(const float3 &cop, const float3 &cor, const float3 &dir1, const float3 &dir2)
  1053. {
  1054. // routine taken from game programming gems.
  1055. // Implement track ball functionality to spin stuf on the screen
  1056. // cop center of projection
  1057. // cor center of rotation
  1058. // dir1 old mouse direction
  1059. // dir2 new mouse direction
  1060. // pretend there is a sphere around cor. Then find the points
  1061. // where dir1 and dir2 intersect that sphere. Find the
  1062. // rotation that takes the first point to the second.
  1063. float m;
  1064. // compute plane
  1065. float3 nrml = cor - cop;
  1066. float fudgefactor = 1.0f/(magnitude(nrml) * 0.25f); // since trackball proportional to distance from cop
  1067. nrml = normalize(nrml);
  1068. float dist = -dot(nrml,cor);
  1069. float3 u= PlaneLineIntersection(Plane(nrml,dist),cop,cop+dir1);
  1070. u=u-cor;
  1071. u=u*fudgefactor;
  1072. m= magnitude(u);
  1073. if(m>1)
  1074. {
  1075. u/=m;
  1076. }
  1077. else
  1078. {
  1079. u=u - (nrml * sqrtf(1-m*m));
  1080. }
  1081. float3 v= PlaneLineIntersection(Plane(nrml,dist),cop,cop+dir2);
  1082. v=v-cor;
  1083. v=v*fudgefactor;
  1084. m= magnitude(v);
  1085. if(m>1)
  1086. {
  1087. v/=m;
  1088. }
  1089. else
  1090. {
  1091. v=v - (nrml * sqrtf(1-m*m));
  1092. }
  1093. return RotationArc(u,v);
  1094. }
  1095. int countpolyhit=0;
  1096. int PolyHit(const float3 *vert, const int n, const float3 &v0, const float3 &v1, float3 *impact, float3 *normal)
  1097. {
  1098. countpolyhit++;
  1099. int i;
  1100. float3 nrml(0,0,0);
  1101. for(i=0;i<n;i++)
  1102. {
  1103. int i1=(i+1)%n;
  1104. int i2=(i+2)%n;
  1105. nrml = nrml + cross(vert[i1]-vert[i],vert[i2]-vert[i1]);
  1106. }
  1107. float m = magnitude(nrml);
  1108. if(m==0.0)
  1109. {
  1110. return 0;
  1111. }
  1112. nrml = nrml * (1.0f/m);
  1113. float dist = -dot(nrml,vert[0]);
  1114. float d0,d1;
  1115. if((d0=dot(v0,nrml)+dist) <0 || (d1=dot(v1,nrml)+dist) >0)
  1116. {
  1117. return 0;
  1118. }
  1119. float3 the_point;
  1120. // By using the cached plane distances d0 and d1
  1121. // we can optimize the following:
  1122. // the_point = planelineintersection(nrml,dist,v0,v1);
  1123. float a = d0/(d0-d1);
  1124. the_point = v0*(1-a) + v1*a;
  1125. int inside=1;
  1126. for(int j=0;inside && j<n;j++)
  1127. {
  1128. // let inside = 0 if outside
  1129. float3 pp1,pp2,side;
  1130. pp1 = vert[j] ;
  1131. pp2 = vert[(j+1)%n];
  1132. side = cross((pp2-pp1),(the_point-pp1));
  1133. inside = (dot(nrml,side) >= 0.0);
  1134. }
  1135. if(inside)
  1136. {
  1137. if(normal){*normal=nrml;}
  1138. if(impact){*impact=the_point;}
  1139. }
  1140. return inside;
  1141. }
  1142. //**************************************************************************
  1143. //**************************************************************************
  1144. //*** Stan Melax's array template, needed to compile his hull generation code
  1145. //**************************************************************************
  1146. //**************************************************************************
  1147. template <class Type> class ArrayRet;
  1148. template <class Type> class Array {
  1149. public:
  1150. Array(int s=0);
  1151. Array(Array<Type> &array);
  1152. Array(ArrayRet<Type> &array);
  1153. ~Array();
  1154. void allocate(int s);
  1155. void SetSize(int s);
  1156. void Pack();
  1157. Type& Add(Type);
  1158. void AddUnique(Type);
  1159. int Contains(Type);
  1160. void Insert(Type,int);
  1161. int IndexOf(Type);
  1162. void Remove(Type);
  1163. void DelIndex(int i);
  1164. Type * element;
  1165. int count;
  1166. int array_size;
  1167. const Type &operator[](int i) const { assert(i>=0 && i<count); return element[i]; }
  1168. Type &operator[](int i) { assert(i>=0 && i<count); return element[i]; }
  1169. Type &Pop() { assert(count); count--; return element[count]; }
  1170. Array<Type> &operator=(Array<Type> &array);
  1171. Array<Type> &operator=(ArrayRet<Type> &array);
  1172. // operator ArrayRet<Type> &() { return *(ArrayRet<Type> *)this;} // this worked but i suspect could be dangerous
  1173. };
  1174. template <class Type> class ArrayRet:public Array<Type>
  1175. {
  1176. };
  1177. template <class Type> Array<Type>::Array(int s)
  1178. {
  1179. count=0;
  1180. array_size = 0;
  1181. element = NULL;
  1182. if(s)
  1183. {
  1184. allocate(s);
  1185. }
  1186. }
  1187. template <class Type> Array<Type>::Array(Array<Type> &array)
  1188. {
  1189. count=0;
  1190. array_size = 0;
  1191. element = NULL;
  1192. for(int i=0;i<array.count;i++)
  1193. {
  1194. Add(array[i]);
  1195. }
  1196. }
  1197. template <class Type> Array<Type>::Array(ArrayRet<Type> &array)
  1198. {
  1199. *this = array;
  1200. }
  1201. template <class Type> Array<Type> &Array<Type>::operator=(ArrayRet<Type> &array)
  1202. {
  1203. count=array.count;
  1204. array_size = array.array_size;
  1205. element = array.element;
  1206. array.element=NULL;
  1207. array.count=0;
  1208. array.array_size=0;
  1209. return *this;
  1210. }
  1211. template <class Type> Array<Type> &Array<Type>::operator=(Array<Type> &array)
  1212. {
  1213. count=0;
  1214. for(int i=0;i<array.count;i++)
  1215. {
  1216. Add(array[i]);
  1217. }
  1218. return *this;
  1219. }
  1220. template <class Type> Array<Type>::~Array()
  1221. {
  1222. if (element != NULL)
  1223. {
  1224. free(element);
  1225. }
  1226. count=0;array_size=0;element=NULL;
  1227. }
  1228. template <class Type> void Array<Type>::allocate(int s)
  1229. {
  1230. assert(s>0);
  1231. assert(s>=count);
  1232. Type *old = element;
  1233. array_size =s;
  1234. element = (Type *) malloc( sizeof(Type)*array_size);
  1235. assert(element);
  1236. for(int i=0;i<count;i++)
  1237. {
  1238. element[i]=old[i];
  1239. }
  1240. if(old)
  1241. {
  1242. free(old);
  1243. }
  1244. }
  1245. template <class Type> void Array<Type>::SetSize(int s)
  1246. {
  1247. if(s==0)
  1248. {
  1249. if(element)
  1250. {
  1251. free(element);
  1252. element = NULL;
  1253. }
  1254. array_size = s;
  1255. }
  1256. else
  1257. {
  1258. allocate(s);
  1259. }
  1260. count=s;
  1261. }
  1262. template <class Type> void Array<Type>::Pack()
  1263. {
  1264. allocate(count);
  1265. }
  1266. template <class Type> Type& Array<Type>::Add(Type t)
  1267. {
  1268. assert(count<=array_size);
  1269. if(count==array_size)
  1270. {
  1271. allocate((array_size)?array_size *2:16);
  1272. }
  1273. element[count++] = t;
  1274. return element[count-1];
  1275. }
  1276. template <class Type> int Array<Type>::Contains(Type t)
  1277. {
  1278. int i;
  1279. int found=0;
  1280. for(i=0;i<count;i++)
  1281. {
  1282. if(element[i] == t) found++;
  1283. }
  1284. return found;
  1285. }
  1286. template <class Type> void Array<Type>::AddUnique(Type t)
  1287. {
  1288. if(!Contains(t)) Add(t);
  1289. }
  1290. template <class Type> void Array<Type>::DelIndex(int i)
  1291. {
  1292. assert(i<count);
  1293. count--;
  1294. while(i<count)
  1295. {
  1296. element[i] = element[i+1];
  1297. i++;
  1298. }
  1299. }
  1300. template <class Type> void Array<Type>::Remove(Type t)
  1301. {
  1302. int i;
  1303. for(i=0;i<count;i++)
  1304. {
  1305. if(element[i] == t)
  1306. {
  1307. break;
  1308. }
  1309. }
  1310. assert(i<count); // assert object t is in the array.
  1311. DelIndex(i);
  1312. for(i=0;i<count;i++)
  1313. {
  1314. assert(element[i] != t);
  1315. }
  1316. }
  1317. template <class Type> void Array<Type>::Insert(Type t,int k)
  1318. {
  1319. int i=count;
  1320. Add(t); // to allocate space
  1321. while(i>k)
  1322. {
  1323. element[i]=element[i-1];
  1324. i--;
  1325. }
  1326. assert(i==k);
  1327. element[k]=t;
  1328. }
  1329. template <class Type> int Array<Type>::IndexOf(Type t)
  1330. {
  1331. int i;
  1332. for(i=0;i<count;i++)
  1333. {
  1334. if(element[i] == t)
  1335. {
  1336. return i;
  1337. }
  1338. }
  1339. assert(0);
  1340. return -1;
  1341. }
  1342. //*********************************************************************
  1343. //*********************************************************************
  1344. //******** Hull header
  1345. //*********************************************************************
  1346. //*********************************************************************
  1347. class PHullResult
  1348. {
  1349. public:
  1350. PHullResult(void)
  1351. {
  1352. mVcount = 0;
  1353. mIndexCount = 0;
  1354. mFaceCount = 0;
  1355. mVertices = 0;
  1356. mIndices = 0;
  1357. }
  1358. unsigned int mVcount;
  1359. unsigned int mIndexCount;
  1360. unsigned int mFaceCount;
  1361. float *mVertices;
  1362. unsigned int *mIndices;
  1363. };
  1364. #define REAL3 float3
  1365. #define REAL float
  1366. #define COPLANAR (0)
  1367. #define UNDER (1)
  1368. #define OVER (2)
  1369. #define SPLIT (OVER|UNDER)
  1370. #define PAPERWIDTH (0.001f)
  1371. float planetestepsilon = PAPERWIDTH;
  1372. class ConvexH
  1373. {
  1374. public:
  1375. class HalfEdge
  1376. {
  1377. public:
  1378. short ea; // the other half of the edge (index into edges list)
  1379. unsigned char v; // the vertex at the start of this edge (index into vertices list)
  1380. unsigned char p; // the facet on which this edge lies (index into facets list)
  1381. HalfEdge(){}
  1382. HalfEdge(short _ea,unsigned char _v, unsigned char _p):ea(_ea),v(_v),p(_p){}
  1383. };
  1384. Array<REAL3> vertices;
  1385. Array<HalfEdge> edges;
  1386. Array<Plane> facets;
  1387. ConvexH(int vertices_size,int edges_size,int facets_size);
  1388. };
  1389. typedef ConvexH::HalfEdge HalfEdge;
  1390. ConvexH::ConvexH(int vertices_size,int edges_size,int facets_size)
  1391. :vertices(vertices_size)
  1392. ,edges(edges_size)
  1393. ,facets(facets_size)
  1394. {
  1395. vertices.count=vertices_size;
  1396. edges.count = edges_size;
  1397. facets.count = facets_size;
  1398. }
  1399. ConvexH *ConvexHDup(ConvexH *src) {
  1400. ConvexH *dst = new ConvexH(src->vertices.count,src->edges.count,src->facets.count);
  1401. memcpy(dst->vertices.element,src->vertices.element,sizeof(float3)*src->vertices.count);
  1402. memcpy(dst->edges.element,src->edges.element,sizeof(HalfEdge)*src->edges.count);
  1403. memcpy(dst->facets.element,src->facets.element,sizeof(Plane)*src->facets.count);
  1404. return dst;
  1405. }
  1406. int PlaneTest(const Plane &p, const REAL3 &v) {
  1407. REAL a = dot(v,p.normal)+p.dist;
  1408. int flag = (a>planetestepsilon)?OVER:((a<-planetestepsilon)?UNDER:COPLANAR);
  1409. return flag;
  1410. }
  1411. int SplitTest(ConvexH &convex,const Plane &plane) {
  1412. int flag=0;
  1413. for(int i=0;i<convex.vertices.count;i++) {
  1414. flag |= PlaneTest(plane,convex.vertices[i]);
  1415. }
  1416. return flag;
  1417. }
  1418. class VertFlag
  1419. {
  1420. public:
  1421. unsigned char planetest;
  1422. unsigned char junk;
  1423. unsigned char undermap;
  1424. unsigned char overmap;
  1425. };
  1426. class EdgeFlag
  1427. {
  1428. public:
  1429. unsigned char planetest;
  1430. unsigned char fixes;
  1431. short undermap;
  1432. short overmap;
  1433. };
  1434. class PlaneFlag
  1435. {
  1436. public:
  1437. unsigned char undermap;
  1438. unsigned char overmap;
  1439. };
  1440. class Coplanar{
  1441. public:
  1442. unsigned short ea;
  1443. unsigned char v0;
  1444. unsigned char v1;
  1445. };
  1446. int AssertIntact(ConvexH &convex) {
  1447. int i;
  1448. int estart=0;
  1449. for(i=0;i<convex.edges.count;i++) {
  1450. if(convex.edges[estart].p!= convex.edges[i].p) {
  1451. estart=i;
  1452. }
  1453. int inext = i+1;
  1454. if(inext>= convex.edges.count || convex.edges[inext].p != convex.edges[i].p) {
  1455. inext = estart;
  1456. }
  1457. assert(convex.edges[inext].p == convex.edges[i].p);
  1458. int nb = convex.edges[i].ea;
  1459. assert(nb!=255);
  1460. if(nb==255 || nb==-1) return 0;
  1461. assert(nb!=-1);
  1462. assert(i== convex.edges[nb].ea);
  1463. }
  1464. for(i=0;i<convex.edges.count;i++) {
  1465. assert(COPLANAR==PlaneTest(convex.facets[convex.edges[i].p],convex.vertices[convex.edges[i].v]));
  1466. if(COPLANAR!=PlaneTest(convex.facets[convex.edges[i].p],convex.vertices[convex.edges[i].v])) return 0;
  1467. if(convex.edges[estart].p!= convex.edges[i].p) {
  1468. estart=i;
  1469. }
  1470. int i1 = i+1;
  1471. if(i1>= convex.edges.count || convex.edges[i1].p != convex.edges[i].p) {
  1472. i1 = estart;
  1473. }
  1474. int i2 = i1+1;
  1475. if(i2>= convex.edges.count || convex.edges[i2].p != convex.edges[i].p) {
  1476. i2 = estart;
  1477. }
  1478. if(i==i2) continue; // i sliced tangent to an edge and created 2 meaningless edges
  1479. REAL3 localnormal = TriNormal(convex.vertices[convex.edges[i ].v],
  1480. convex.vertices[convex.edges[i1].v],
  1481. convex.vertices[convex.edges[i2].v]);
  1482. assert(dot(localnormal,convex.facets[convex.edges[i].p].normal)>0);
  1483. if(dot(localnormal,convex.facets[convex.edges[i].p].normal)<=0)return 0;
  1484. }
  1485. return 1;
  1486. }
  1487. // back to back quads
  1488. ConvexH *test_btbq() {
  1489. ConvexH *convex = new ConvexH(4,8,2);
  1490. convex->vertices[0] = REAL3(0,0,0);
  1491. convex->vertices[1] = REAL3(1,0,0);
  1492. convex->vertices[2] = REAL3(1,1,0);
  1493. convex->vertices[3] = REAL3(0,1,0);
  1494. convex->facets[0] = Plane(REAL3(0,0,1),0);
  1495. convex->facets[1] = Plane(REAL3(0,0,-1),0);
  1496. convex->edges[0] = HalfEdge(7,0,0);
  1497. convex->edges[1] = HalfEdge(6,1,0);
  1498. convex->edges[2] = HalfEdge(5,2,0);
  1499. convex->edges[3] = HalfEdge(4,3,0);
  1500. convex->edges[4] = HalfEdge(3,0,1);
  1501. convex->edges[5] = HalfEdge(2,3,1);
  1502. convex->edges[6] = HalfEdge(1,2,1);
  1503. convex->edges[7] = HalfEdge(0,1,1);
  1504. AssertIntact(*convex);
  1505. return convex;
  1506. }
  1507. ConvexH *test_cube() {
  1508. ConvexH *convex = new ConvexH(8,24,6);
  1509. convex->vertices[0] = REAL3(0,0,0);
  1510. convex->vertices[1] = REAL3(0,0,1);
  1511. convex->vertices[2] = REAL3(0,1,0);
  1512. convex->vertices[3] = REAL3(0,1,1);
  1513. convex->vertices[4] = REAL3(1,0,0);
  1514. convex->vertices[5] = REAL3(1,0,1);
  1515. convex->vertices[6] = REAL3(1,1,0);
  1516. convex->vertices[7] = REAL3(1,1,1);
  1517. convex->facets[0] = Plane(REAL3(-1,0,0),0);
  1518. convex->facets[1] = Plane(REAL3(1,0,0),-1);
  1519. convex->facets[2] = Plane(REAL3(0,-1,0),0);
  1520. convex->facets[3] = Plane(REAL3(0,1,0),-1);
  1521. convex->facets[4] = Plane(REAL3(0,0,-1),0);
  1522. convex->facets[5] = Plane(REAL3(0,0,1),-1);
  1523. convex->edges[0 ] = HalfEdge(11,0,0);
  1524. convex->edges[1 ] = HalfEdge(23,1,0);
  1525. convex->edges[2 ] = HalfEdge(15,3,0);
  1526. convex->edges[3 ] = HalfEdge(16,2,0);
  1527. convex->edges[4 ] = HalfEdge(13,6,1);
  1528. convex->edges[5 ] = HalfEdge(21,7,1);
  1529. convex->edges[6 ] = HalfEdge( 9,5,1);
  1530. convex->edges[7 ] = HalfEdge(18,4,1);
  1531. convex->edges[8 ] = HalfEdge(19,0,2);
  1532. convex->edges[9 ] = HalfEdge( 6,4,2);
  1533. convex->edges[10] = HalfEdge(20,5,2);
  1534. convex->edges[11] = HalfEdge( 0,1,2);
  1535. convex->edges[12] = HalfEdge(22,3,3);
  1536. convex->edges[13] = HalfEdge( 4,7,3);
  1537. convex->edges[14] = HalfEdge(17,6,3);
  1538. convex->edges[15] = HalfEdge( 2,2,3);
  1539. convex->edges[16] = HalfEdge( 3,0,4);
  1540. convex->edges[17] = HalfEdge(14,2,4);
  1541. convex->edges[18] = HalfEdge( 7,6,4);
  1542. convex->edges[19] = HalfEdge( 8,4,4);
  1543. convex->edges[20] = HalfEdge(10,1,5);
  1544. convex->edges[21] = HalfEdge( 5,5,5);
  1545. convex->edges[22] = HalfEdge(12,7,5);
  1546. convex->edges[23] = HalfEdge( 1,3,5);
  1547. return convex;
  1548. }
  1549. ConvexH *ConvexHMakeCube(const REAL3 &bmin, const REAL3 &bmax) {
  1550. ConvexH *convex = test_cube();
  1551. convex->vertices[0] = REAL3(bmin.x,bmin.y,bmin.z);
  1552. convex->vertices[1] = REAL3(bmin.x,bmin.y,bmax.z);
  1553. convex->vertices[2] = REAL3(bmin.x,bmax.y,bmin.z);
  1554. convex->vertices[3] = REAL3(bmin.x,bmax.y,bmax.z);
  1555. convex->vertices[4] = REAL3(bmax.x,bmin.y,bmin.z);
  1556. convex->vertices[5] = REAL3(bmax.x,bmin.y,bmax.z);
  1557. convex->vertices[6] = REAL3(bmax.x,bmax.y,bmin.z);
  1558. convex->vertices[7] = REAL3(bmax.x,bmax.y,bmax.z);
  1559. convex->facets[0] = Plane(REAL3(-1,0,0), bmin.x);
  1560. convex->facets[1] = Plane(REAL3(1,0,0), -bmax.x);
  1561. convex->facets[2] = Plane(REAL3(0,-1,0), bmin.y);
  1562. convex->facets[3] = Plane(REAL3(0,1,0), -bmax.y);
  1563. convex->facets[4] = Plane(REAL3(0,0,-1), bmin.z);
  1564. convex->facets[5] = Plane(REAL3(0,0,1), -bmax.z);
  1565. return convex;
  1566. }
  1567. ConvexH *ConvexHCrop(ConvexH &convex,const Plane &slice)
  1568. {
  1569. int i;
  1570. int vertcountunder=0;
  1571. int vertcountover =0;
  1572. Array<int> vertscoplanar; // existing vertex members of convex that are coplanar
  1573. vertscoplanar.count=0;
  1574. Array<int> edgesplit; // existing edges that members of convex that cross the splitplane
  1575. edgesplit.count=0;
  1576. assert(convex.edges.count<480);
  1577. EdgeFlag edgeflag[512];
  1578. VertFlag vertflag[256];
  1579. PlaneFlag planeflag[128];
  1580. HalfEdge tmpunderedges[512];
  1581. Plane tmpunderplanes[128];
  1582. Coplanar coplanaredges[512];
  1583. int coplanaredges_num=0;
  1584. Array<REAL3> createdverts;
  1585. // do the side-of-plane tests
  1586. for(i=0;i<convex.vertices.count;i++) {
  1587. vertflag[i].planetest = PlaneTest(slice,convex.vertices[i]);
  1588. if(vertflag[i].planetest == COPLANAR) {
  1589. // ? vertscoplanar.Add(i);
  1590. vertflag[i].undermap = vertcountunder++;
  1591. vertflag[i].overmap = vertcountover++;
  1592. }
  1593. else if(vertflag[i].planetest == UNDER) {
  1594. vertflag[i].undermap = vertcountunder++;
  1595. }
  1596. else {
  1597. assert(vertflag[i].planetest == OVER);
  1598. vertflag[i].overmap = vertcountover++;
  1599. vertflag[i].undermap = 255; // for debugging purposes
  1600. }
  1601. }
  1602. int vertcountunderold = vertcountunder; // for debugging only
  1603. int under_edge_count =0;
  1604. int underplanescount=0;
  1605. int e0=0;
  1606. for(int currentplane=0; currentplane<convex.facets.count; currentplane++) {
  1607. int estart =e0;
  1608. int enextface = 0;
  1609. int planeside = 0;
  1610. int e1 = e0+1;
  1611. int vout=-1;
  1612. int vin =-1;
  1613. int coplanaredge = -1;
  1614. do{
  1615. if(e1 >= convex.edges.count || convex.edges[e1].p!=currentplane) {
  1616. enextface = e1;
  1617. e1=estart;
  1618. }
  1619. HalfEdge &edge0 = convex.edges[e0];
  1620. HalfEdge &edge1 = convex.edges[e1];
  1621. HalfEdge &edgea = convex.edges[edge0.ea];
  1622. planeside |= vertflag[edge0.v].planetest;
  1623. //if((vertflag[edge0.v].planetest & vertflag[edge1.v].planetest) == COPLANAR) {
  1624. // assert(ecop==-1);
  1625. // ecop=e;
  1626. //}
  1627. if(vertflag[edge0.v].planetest == OVER && vertflag[edge1.v].planetest == OVER){
  1628. // both endpoints over plane
  1629. edgeflag[e0].undermap = -1;
  1630. }
  1631. else if((vertflag[edge0.v].planetest | vertflag[edge1.v].planetest) == UNDER) {
  1632. // at least one endpoint under, the other coplanar or under
  1633. edgeflag[e0].undermap = under_edge_count;
  1634. tmpunderedges[under_edge_count].v = vertflag[edge0.v].undermap;
  1635. tmpunderedges[under_edge_count].p = underplanescount;
  1636. if(edge0.ea < e0) {
  1637. // connect the neighbors
  1638. assert(edgeflag[edge0.ea].undermap !=-1);
  1639. tmpunderedges[under_edge_count].ea = edgeflag[edge0.ea].undermap;
  1640. tmpunderedges[edgeflag[edge0.ea].undermap].ea = under_edge_count;
  1641. }
  1642. under_edge_count++;
  1643. }
  1644. else if((vertflag[edge0.v].planetest | vertflag[edge1.v].planetest) == COPLANAR) {
  1645. // both endpoints coplanar
  1646. // must check a 3rd point to see if UNDER
  1647. int e2 = e1+1;
  1648. if(e2>=convex.edges.count || convex.edges[e2].p!=currentplane) {
  1649. e2 = estart;
  1650. }
  1651. assert(convex.edges[e2].p==currentplane);
  1652. HalfEdge &edge2 = convex.edges[e2];
  1653. if(vertflag[edge2.v].planetest==UNDER) {
  1654. edgeflag[e0].undermap = under_edge_count;
  1655. tmpunderedges[under_edge_count].v = vertflag[edge0.v].undermap;
  1656. tmpunderedges[under_edge_count].p = underplanescount;
  1657. tmpunderedges[under_edge_count].ea = -1;
  1658. // make sure this edge is added to the "coplanar" list
  1659. coplanaredge = under_edge_count;
  1660. vout = vertflag[edge0.v].undermap;
  1661. vin = vertflag[edge1.v].undermap;
  1662. under_edge_count++;
  1663. }
  1664. else {
  1665. edgeflag[e0].undermap = -1;
  1666. }
  1667. }
  1668. else if(vertflag[edge0.v].planetest == UNDER && vertflag[edge1.v].planetest == OVER) {
  1669. // first is under 2nd is over
  1670. edgeflag[e0].undermap = under_edge_count;
  1671. tmpunderedges[under_edge_count].v = vertflag[edge0.v].undermap;
  1672. tmpunderedges[under_edge_count].p = underplanescount;
  1673. if(edge0.ea < e0) {
  1674. assert(edgeflag[edge0.ea].undermap !=-1);
  1675. // connect the neighbors
  1676. tmpunderedges[under_edge_count].ea = edgeflag[edge0.ea].undermap;
  1677. tmpunderedges[edgeflag[edge0.ea].undermap].ea = under_edge_count;
  1678. vout = tmpunderedges[edgeflag[edge0.ea].undermap].v;
  1679. }
  1680. else {
  1681. Plane &p0 = convex.facets[edge0.p];
  1682. Plane &pa = convex.facets[edgea.p];
  1683. createdverts.Add(ThreePlaneIntersection(p0,pa,slice));
  1684. //createdverts.Add(PlaneProject(slice,PlaneLineIntersection(slice,convex.vertices[edge0.v],convex.vertices[edgea.v])));
  1685. //createdverts.Add(PlaneLineIntersection(slice,convex.vertices[edge0.v],convex.vertices[edgea.v]));
  1686. vout = vertcountunder++;
  1687. }
  1688. under_edge_count++;
  1689. /// hmmm something to think about: i might be able to output this edge regarless of
  1690. // wheter or not we know v-in yet. ok i;ll try this now:
  1691. tmpunderedges[under_edge_count].v = vout;
  1692. tmpunderedges[under_edge_count].p = underplanescount;
  1693. tmpunderedges[under_edge_count].ea = -1;
  1694. coplanaredge = under_edge_count;
  1695. under_edge_count++;
  1696. if(vin!=-1) {
  1697. // we previously processed an edge where we came under
  1698. // now we know about vout as well
  1699. // ADD THIS EDGE TO THE LIST OF EDGES THAT NEED NEIGHBOR ON PARTITION PLANE!!
  1700. }
  1701. }
  1702. else if(vertflag[edge0.v].planetest == COPLANAR && vertflag[edge1.v].planetest == OVER) {
  1703. // first is coplanar 2nd is over
  1704. edgeflag[e0].undermap = -1;
  1705. vout = vertflag[edge0.v].undermap;
  1706. // I hate this but i have to make sure part of this face is UNDER before ouputting this vert
  1707. int k=estart;
  1708. assert(edge0.p == currentplane);
  1709. while(!(planeside&UNDER) && k<convex.edges.count && convex.edges[k].p==edge0.p) {
  1710. planeside |= vertflag[convex.edges[k].v].planetest;
  1711. k++;
  1712. }
  1713. if(planeside&UNDER){
  1714. tmpunderedges[under_edge_count].v = vout;
  1715. tmpunderedges[under_edge_count].p = underplanescount;
  1716. tmpunderedges[under_edge_count].ea = -1;
  1717. coplanaredge = under_edge_count; // hmmm should make a note of the edge # for later on
  1718. under_edge_count++;
  1719. }
  1720. }
  1721. else if(vertflag[edge0.v].planetest == OVER && vertflag[edge1.v].planetest == UNDER) {
  1722. // first is over next is under
  1723. // new vertex!!!
  1724. assert(vin==-1);
  1725. if(e0<edge0.ea) {
  1726. Plane &p0 = convex.facets[edge0.p];
  1727. Plane &pa = convex.facets[edgea.p];
  1728. createdverts.Add(ThreePlaneIntersection(p0,pa,slice));
  1729. //createdverts.Add(PlaneLineIntersection(slice,convex.vertices[edge0.v],convex.vertices[edgea.v]));
  1730. //createdverts.Add(PlaneProject(slice,PlaneLineIntersection(slice,convex.vertices[edge0.v],convex.vertices[edgea.v])));
  1731. vin = vertcountunder++;
  1732. }
  1733. else {
  1734. // find the new vertex that was created by edge[edge0.ea]
  1735. int nea = edgeflag[edge0.ea].undermap;
  1736. assert(tmpunderedges[nea].p==tmpunderedges[nea+1].p);
  1737. vin = tmpunderedges[nea+1].v;
  1738. assert(vin < vertcountunder);
  1739. assert(vin >= vertcountunderold); // for debugging only
  1740. }
  1741. if(vout!=-1) {
  1742. // we previously processed an edge where we went over
  1743. // now we know vin too
  1744. // ADD THIS EDGE TO THE LIST OF EDGES THAT NEED NEIGHBOR ON PARTITION PLANE!!
  1745. }
  1746. // output edge
  1747. tmpunderedges[under_edge_count].v = vin;
  1748. tmpunderedges[under_edge_count].p = underplanescount;
  1749. edgeflag[e0].undermap = under_edge_count;
  1750. if(e0>edge0.ea) {
  1751. assert(edgeflag[edge0.ea].undermap !=-1);
  1752. // connect the neighbors
  1753. tmpunderedges[under_edge_count].ea = edgeflag[edge0.ea].undermap;
  1754. tmpunderedges[edgeflag[edge0.ea].undermap].ea = under_edge_count;
  1755. }
  1756. assert(edgeflag[e0].undermap == under_edge_count);
  1757. under_edge_count++;
  1758. }
  1759. else if(vertflag[edge0.v].planetest == OVER && vertflag[edge1.v].planetest == COPLANAR) {
  1760. // first is over next is coplanar
  1761. edgeflag[e0].undermap = -1;
  1762. vin = vertflag[edge1.v].undermap;
  1763. assert(vin!=-1);
  1764. if(vout!=-1) {
  1765. // we previously processed an edge where we came under
  1766. // now we know both endpoints
  1767. // ADD THIS EDGE TO THE LIST OF EDGES THAT NEED NEIGHBOR ON PARTITION PLANE!!
  1768. }
  1769. }
  1770. else {
  1771. assert(0);
  1772. }
  1773. e0=e1;
  1774. e1++; // do the modulo at the beginning of the loop
  1775. } while(e0!=estart) ;
  1776. e0 = enextface;
  1777. if(planeside&UNDER) {
  1778. planeflag[currentplane].undermap = underplanescount;
  1779. tmpunderplanes[underplanescount] = convex.facets[currentplane];
  1780. underplanescount++;
  1781. }
  1782. else {
  1783. planeflag[currentplane].undermap = 0;
  1784. }
  1785. if(vout>=0 && (planeside&UNDER)) {
  1786. assert(vin>=0);
  1787. assert(coplanaredge>=0);
  1788. assert(coplanaredge!=511);
  1789. coplanaredges[coplanaredges_num].ea = coplanaredge;
  1790. coplanaredges[coplanaredges_num].v0 = vin;
  1791. coplanaredges[coplanaredges_num].v1 = vout;
  1792. coplanaredges_num++;
  1793. }
  1794. }
  1795. // add the new plane to the mix:
  1796. if(coplanaredges_num>0) {
  1797. tmpunderplanes[underplanescount++]=slice;
  1798. }
  1799. for(i=0;i<coplanaredges_num-1;i++) {
  1800. if(coplanaredges[i].v1 != coplanaredges[i+1].v0) {
  1801. int j = 0;
  1802. for(j=i+2;j<coplanaredges_num;j++) {
  1803. if(coplanaredges[i].v1 == coplanaredges[j].v0) {
  1804. Coplanar tmp = coplanaredges[i+1];
  1805. coplanaredges[i+1] = coplanaredges[j];
  1806. coplanaredges[j] = tmp;
  1807. break;
  1808. }
  1809. }
  1810. if(j>=coplanaredges_num)
  1811. {
  1812. assert(j<coplanaredges_num);
  1813. return NULL;
  1814. }
  1815. }
  1816. }
  1817. ConvexH *punder = new ConvexH(vertcountunder,under_edge_count+coplanaredges_num,underplanescount);
  1818. ConvexH &under = *punder;
  1819. int k=0;
  1820. for(i=0;i<convex.vertices.count;i++) {
  1821. if(vertflag[i].planetest != OVER){
  1822. under.vertices[k++] = convex.vertices[i];
  1823. }
  1824. }
  1825. i=0;
  1826. while(k<vertcountunder) {
  1827. under.vertices[k++] = createdverts[i++];
  1828. }
  1829. assert(i==createdverts.count);
  1830. for(i=0;i<coplanaredges_num;i++) {
  1831. under.edges[under_edge_count+i].p = underplanescount-1;
  1832. under.edges[under_edge_count+i].ea = coplanaredges[i].ea;
  1833. tmpunderedges[coplanaredges[i].ea].ea = under_edge_count+i;
  1834. under.edges[under_edge_count+i].v = coplanaredges[i].v0;
  1835. }
  1836. memcpy(under.edges.element,tmpunderedges,sizeof(HalfEdge)*under_edge_count);
  1837. memcpy(under.facets.element,tmpunderplanes,sizeof(Plane)*underplanescount);
  1838. return punder;
  1839. }
  1840. static int candidateplane(Plane *planes,int planes_count,ConvexH *convex,float epsilon)
  1841. {
  1842. int p = 0 ;
  1843. REAL md= 0 ;
  1844. int i;
  1845. for(i=0;i<planes_count;i++)
  1846. {
  1847. REAL d=0;
  1848. for(int j=0;j<convex->vertices.count;j++)
  1849. {
  1850. d = Max(d,dot(convex->vertices[j],planes[i].normal)+planes[i].dist);
  1851. }
  1852. if(i==0 || d>md)
  1853. {
  1854. p=i;
  1855. md=d;
  1856. }
  1857. }
  1858. return (md>epsilon)?p:-1;
  1859. }
  1860. template<class T>
  1861. inline int maxdir(const T *p,int count,const T &dir)
  1862. {
  1863. assert(count);
  1864. int m=0;
  1865. float currDotm = dot(p[0], dir);
  1866. for(int i=1;i<count;i++)
  1867. {
  1868. const float currDoti = dot(p[i], dir);
  1869. if(currDoti > currDotm)
  1870. {
  1871. currDotm = currDoti;
  1872. m=i;
  1873. }
  1874. }
  1875. return m;
  1876. }
  1877. template<class T>
  1878. int maxdirfiltered(const T *p,int count,const T &dir,Array<int> &allow)
  1879. {
  1880. assert(count);
  1881. int m=-1;
  1882. float currDotm = dot(p[0], dir);
  1883. for(int i=0;i<count;i++)
  1884. {
  1885. if(allow[i])
  1886. {
  1887. if(m==-1 )
  1888. {
  1889. currDotm = dot(p[i], dir);
  1890. m=i;
  1891. }
  1892. else
  1893. {
  1894. const float currDoti = dot(p[i], dir);
  1895. if (currDoti>currDotm)
  1896. {
  1897. currDotm = currDoti;
  1898. m=i;
  1899. }
  1900. }
  1901. }
  1902. }
  1903. assert(m!=-1);
  1904. return m;
  1905. }
  1906. float3 orth(const float3 &v)
  1907. {
  1908. float3 a=cross(v,float3(0,0,1));
  1909. float3 b=cross(v,float3(0,1,0));
  1910. return normalize((magnitude(a)>magnitude(b))?a:b);
  1911. }
  1912. template<class T>
  1913. int maxdirsterid(const T *p,int count,const T &dir,Array<int> &allow)
  1914. {
  1915. int m=-1;
  1916. while(m==-1)
  1917. {
  1918. m = maxdirfiltered(p,count,dir,allow);
  1919. if(allow[m]==3) return m;
  1920. T u = orth(dir);
  1921. T v = cross(u,dir);
  1922. int ma=-1;
  1923. for(float x = 0.0f ; x<= 360.0f ; x+= 45.0f)
  1924. {
  1925. float s = sinf(DEG2RAD*(x));
  1926. float c = cosf(DEG2RAD*(x));
  1927. int mb = maxdirfiltered(p,count,dir+(u*s+v*c)*0.025f,allow);
  1928. if(ma==m && mb==m)
  1929. {
  1930. allow[m]=3;
  1931. return m;
  1932. }
  1933. if(ma!=-1 && ma!=mb) // Yuck - this is really ugly
  1934. {
  1935. int mc = ma;
  1936. for(float xx = x-40.0f ; xx <= x ; xx+= 5.0f)
  1937. {
  1938. float s = sinf(DEG2RAD*(xx));
  1939. float c = cosf(DEG2RAD*(xx));
  1940. int md = maxdirfiltered(p,count,dir+(u*s+v*c)*0.025f,allow);
  1941. if(mc==m && md==m)
  1942. {
  1943. allow[m]=3;
  1944. return m;
  1945. }
  1946. mc=md;
  1947. }
  1948. }
  1949. ma=mb;
  1950. }
  1951. allow[m]=0;
  1952. m=-1;
  1953. }
  1954. assert(0);
  1955. return m;
  1956. }
  1957. int operator ==(const int3 &a,const int3 &b)
  1958. {
  1959. for(int i=0;i<3;i++)
  1960. {
  1961. if(a[i]!=b[i]) return 0;
  1962. }
  1963. return 1;
  1964. }
  1965. int3 roll3(int3 a)
  1966. {
  1967. int tmp=a[0];
  1968. a[0]=a[1];
  1969. a[1]=a[2];
  1970. a[2]=tmp;
  1971. return a;
  1972. }
  1973. int isa(const int3 &a,const int3 &b)
  1974. {
  1975. return ( a==b || roll3(a)==b || a==roll3(b) );
  1976. }
  1977. int b2b(const int3 &a,const int3 &b)
  1978. {
  1979. return isa(a,int3(b[2],b[1],b[0]));
  1980. }
  1981. int above(float3* vertices,const int3& t, const float3 &p, float epsilon)
  1982. {
  1983. float3 n=TriNormal(vertices[t[0]],vertices[t[1]],vertices[t[2]]);
  1984. return (dot(n,p-vertices[t[0]]) > epsilon); // EPSILON???
  1985. }
  1986. int hasedge(const int3 &t, int a,int b)
  1987. {
  1988. for(int i=0;i<3;i++)
  1989. {
  1990. int i1= (i+1)%3;
  1991. if(t[i]==a && t[i1]==b) return 1;
  1992. }
  1993. return 0;
  1994. }
  1995. int hasvert(const int3 &t, int v)
  1996. {
  1997. return (t[0]==v || t[1]==v || t[2]==v) ;
  1998. }
  1999. int shareedge(const int3 &a,const int3 &b)
  2000. {
  2001. int i;
  2002. for(i=0;i<3;i++)
  2003. {
  2004. int i1= (i+1)%3;
  2005. if(hasedge(a,b[i1],b[i])) return 1;
  2006. }
  2007. return 0;
  2008. }
  2009. class btHullTriangle;
  2010. //Array<btHullTriangle*> tris;
  2011. class btHullTriangle : public int3
  2012. {
  2013. public:
  2014. int3 n;
  2015. int id;
  2016. int vmax;
  2017. float rise;
  2018. Array<btHullTriangle*>* tris;
  2019. btHullTriangle(int a,int b,int c, Array<btHullTriangle*>* pTris):int3(a,b,c),n(-1,-1,-1)
  2020. {
  2021. tris = pTris;
  2022. id = tris->count;
  2023. tris->Add(this);
  2024. vmax=-1;
  2025. rise = 0.0f;
  2026. }
  2027. ~btHullTriangle()
  2028. {
  2029. assert((*tris)[id]==this);
  2030. (*tris)[id]=NULL;
  2031. }
  2032. int &neib(int a,int b);
  2033. };
  2034. int &btHullTriangle::neib(int a,int b)
  2035. {
  2036. static int er=-1;
  2037. int i;
  2038. for(i=0;i<3;i++)
  2039. {
  2040. int i1=(i+1)%3;
  2041. int i2=(i+2)%3;
  2042. if((*this)[i]==a && (*this)[i1]==b) return n[i2];
  2043. if((*this)[i]==b && (*this)[i1]==a) return n[i2];
  2044. }
  2045. assert(0);
  2046. return er;
  2047. }
  2048. void b2bfix(btHullTriangle* s,btHullTriangle*t, Array<btHullTriangle*>& tris)
  2049. {
  2050. int i;
  2051. for(i=0;i<3;i++)
  2052. {
  2053. int i1=(i+1)%3;
  2054. int i2=(i+2)%3;
  2055. int a = (*s)[i1];
  2056. int b = (*s)[i2];
  2057. assert(tris[s->neib(a,b)]->neib(b,a) == s->id);
  2058. assert(tris[t->neib(a,b)]->neib(b,a) == t->id);
  2059. tris[s->neib(a,b)]->neib(b,a) = t->neib(b,a);
  2060. tris[t->neib(b,a)]->neib(a,b) = s->neib(a,b);
  2061. }
  2062. }
  2063. void removeb2b(btHullTriangle* s,btHullTriangle*t, Array<btHullTriangle*>& tris)
  2064. {
  2065. b2bfix(s,t, tris);
  2066. delete s;
  2067. delete t;
  2068. }
  2069. void checkit(btHullTriangle *t, Array<btHullTriangle*>& tris)
  2070. {
  2071. int i;
  2072. assert(tris[t->id]==t);
  2073. for(i=0;i<3;i++)
  2074. {
  2075. int i1=(i+1)%3;
  2076. int i2=(i+2)%3;
  2077. int a = (*t)[i1];
  2078. int b = (*t)[i2];
  2079. assert(a!=b);
  2080. assert( tris[t->n[i]]->neib(b,a) == t->id);
  2081. }
  2082. }
  2083. void extrude(btHullTriangle *t0,int v, Array<btHullTriangle*>& tris)
  2084. {
  2085. int3 t= *t0;
  2086. int n = tris.count;
  2087. btHullTriangle* ta = new btHullTriangle(v,t[1],t[2], &tris);
  2088. ta->n = int3(t0->n[0],n+1,n+2);
  2089. tris[t0->n[0]]->neib(t[1],t[2]) = n+0;
  2090. btHullTriangle* tb = new btHullTriangle(v,t[2],t[0], &tris);
  2091. tb->n = int3(t0->n[1],n+2,n+0);
  2092. tris[t0->n[1]]->neib(t[2],t[0]) = n+1;
  2093. btHullTriangle* tc = new btHullTriangle(v,t[0],t[1], &tris);
  2094. tc->n = int3(t0->n[2],n+0,n+1);
  2095. tris[t0->n[2]]->neib(t[0],t[1]) = n+2;
  2096. checkit(ta, tris);
  2097. checkit(tb, tris);
  2098. checkit(tc, tris);
  2099. if(hasvert(*tris[ta->n[0]],v)) removeb2b(ta,tris[ta->n[0]], tris);
  2100. if(hasvert(*tris[tb->n[0]],v)) removeb2b(tb,tris[tb->n[0]], tris);
  2101. if(hasvert(*tris[tc->n[0]],v)) removeb2b(tc,tris[tc->n[0]], tris);
  2102. delete t0;
  2103. }
  2104. btHullTriangle *extrudable(float epsilon, Array<btHullTriangle*>& tris)
  2105. {
  2106. int i;
  2107. btHullTriangle *t=NULL;
  2108. for(i=0;i<tris.count;i++)
  2109. {
  2110. if(!t || (tris[i] && t->rise<tris[i]->rise))
  2111. {
  2112. t = tris[i];
  2113. }
  2114. }
  2115. return (t->rise >epsilon)?t:NULL ;
  2116. }
  2117. class int4
  2118. {
  2119. public:
  2120. int x,y,z,w;
  2121. int4(){};
  2122. int4(int _x,int _y, int _z,int _w){x=_x;y=_y;z=_z;w=_w;}
  2123. const int& operator[](int i) const {return (&x)[i];}
  2124. int& operator[](int i) {return (&x)[i];}
  2125. };
  2126. int4 FindSimplex(float3 *verts,int verts_count,Array<int> &allow)
  2127. {
  2128. float3 basis[3];
  2129. basis[0] = float3( 0.01f, 0.02f, 1.0f );
  2130. int p0 = maxdirsterid(verts,verts_count, basis[0],allow);
  2131. int p1 = maxdirsterid(verts,verts_count,-basis[0],allow);
  2132. basis[0] = verts[p0]-verts[p1];
  2133. if(p0==p1 || basis[0]==float3(0,0,0))
  2134. return int4(-1,-1,-1,-1);
  2135. basis[1] = cross(float3( 1, 0.02f, 0),basis[0]);
  2136. basis[2] = cross(float3(-0.02f, 1, 0),basis[0]);
  2137. basis[1] = normalize( (magnitude(basis[1])>magnitude(basis[2])) ? basis[1]:basis[2]);
  2138. int p2 = maxdirsterid(verts,verts_count,basis[1],allow);
  2139. if(p2 == p0 || p2 == p1)
  2140. {
  2141. p2 = maxdirsterid(verts,verts_count,-basis[1],allow);
  2142. }
  2143. if(p2 == p0 || p2 == p1)
  2144. return int4(-1,-1,-1,-1);
  2145. basis[1] = verts[p2] - verts[p0];
  2146. basis[2] = normalize(cross(basis[1],basis[0]));
  2147. int p3 = maxdirsterid(verts,verts_count,basis[2],allow);
  2148. if(p3==p0||p3==p1||p3==p2) p3 = maxdirsterid(verts,verts_count,-basis[2],allow);
  2149. if(p3==p0||p3==p1||p3==p2)
  2150. return int4(-1,-1,-1,-1);
  2151. assert(!(p0==p1||p0==p2||p0==p3||p1==p2||p1==p3||p2==p3));
  2152. if(dot(verts[p3]-verts[p0],cross(verts[p1]-verts[p0],verts[p2]-verts[p0])) <0) {Swap(p2,p3);}
  2153. return int4(p0,p1,p2,p3);
  2154. }
  2155. int calchullgen(float3 *verts,int verts_count, int vlimit,Array<btHullTriangle*>& tris)
  2156. {
  2157. if(verts_count <4) return 0;
  2158. if(vlimit==0) vlimit=1000000000;
  2159. int j;
  2160. float3 bmin(*verts),bmax(*verts);
  2161. Array<int> isextreme(verts_count);
  2162. Array<int> allow(verts_count);
  2163. for(j=0;j<verts_count;j++)
  2164. {
  2165. allow.Add(1);
  2166. isextreme.Add(0);
  2167. bmin = VectorMin(bmin,verts[j]);
  2168. bmax = VectorMax(bmax,verts[j]);
  2169. }
  2170. float epsilon = magnitude(bmax-bmin) * 0.001f;
  2171. int4 p = FindSimplex(verts,verts_count,allow);
  2172. if(p.x==-1) return 0; // simplex failed
  2173. float3 center = (verts[p[0]]+verts[p[1]]+verts[p[2]]+verts[p[3]]) /4.0f; // a valid interior point
  2174. btHullTriangle *t0 = new btHullTriangle(p[2],p[3],p[1], &tris); t0->n=int3(2,3,1);
  2175. btHullTriangle *t1 = new btHullTriangle(p[3],p[2],p[0], &tris); t1->n=int3(3,2,0);
  2176. btHullTriangle *t2 = new btHullTriangle(p[0],p[1],p[3], &tris); t2->n=int3(0,1,3);
  2177. btHullTriangle *t3 = new btHullTriangle(p[1],p[0],p[2], &tris); t3->n=int3(1,0,2);
  2178. isextreme[p[0]]=isextreme[p[1]]=isextreme[p[2]]=isextreme[p[3]]=1;
  2179. checkit(t0, tris);checkit(t1, tris);checkit(t2, tris);checkit(t3, tris);
  2180. for(j=0;j<tris.count;j++)
  2181. {
  2182. btHullTriangle *t=tris[j];
  2183. assert(t);
  2184. assert(t->vmax<0);
  2185. float3 n=TriNormal(verts[(*t)[0]],verts[(*t)[1]],verts[(*t)[2]]);
  2186. t->vmax = maxdirsterid(verts,verts_count,n,allow);
  2187. t->rise = dot(n,verts[t->vmax]-verts[(*t)[0]]);
  2188. }
  2189. btHullTriangle *te;
  2190. vlimit-=4;
  2191. while(vlimit >0 && (te=extrudable(epsilon, tris)))
  2192. {
  2193. // int3 ti=*te;
  2194. int v=te->vmax;
  2195. assert(!isextreme[v]); // wtf we've already done this vertex
  2196. isextreme[v]=1;
  2197. //if(v==p0 || v==p1 || v==p2 || v==p3) continue; // done these already
  2198. j=tris.count;
  2199. while(j--) {
  2200. if(!tris[j]) continue;
  2201. int3 t=*tris[j];
  2202. if(above(verts,t,verts[v],0.01f*epsilon))
  2203. {
  2204. extrude(tris[j],v, tris);
  2205. }
  2206. }
  2207. // now check for those degenerate cases where we have a flipped triangle or a really skinny triangle
  2208. j=tris.count;
  2209. while(j--)
  2210. {
  2211. if(!tris[j]) continue;
  2212. if(!hasvert(*tris[j],v)) break;
  2213. int3 nt=*tris[j];
  2214. if(above(verts,nt,center,0.01f*epsilon) || magnitude(cross(verts[nt[1]]-verts[nt[0]],verts[nt[2]]-verts[nt[1]]))< epsilon*epsilon*0.1f )
  2215. {
  2216. btHullTriangle *nb = tris[tris[j]->n[0]];
  2217. assert(nb);assert(!hasvert(*nb,v));assert(nb->id<j);
  2218. extrude(nb,v, tris);
  2219. j=tris.count;
  2220. }
  2221. }
  2222. j=tris.count;
  2223. while(j--)
  2224. {
  2225. btHullTriangle *t=tris[j];
  2226. if(!t) continue;
  2227. if(t->vmax>=0) break;
  2228. float3 n=TriNormal(verts[(*t)[0]],verts[(*t)[1]],verts[(*t)[2]]);
  2229. t->vmax = maxdirsterid(verts,verts_count,n,allow);
  2230. if(isextreme[t->vmax])
  2231. {
  2232. t->vmax=-1; // already done that vertex - algorithm needs to be able to terminate.
  2233. }
  2234. else
  2235. {
  2236. t->rise = dot(n,verts[t->vmax]-verts[(*t)[0]]);
  2237. }
  2238. }
  2239. vlimit --;
  2240. }
  2241. return 1;
  2242. }
  2243. int calchull(float3 *verts,int verts_count, int *&tris_out, int &tris_count,int vlimit, Array<btHullTriangle*>& tris)
  2244. {
  2245. int rc=calchullgen(verts,verts_count, vlimit, tris) ;
  2246. if(!rc) return 0;
  2247. Array<int> ts;
  2248. for(int i=0;i<tris.count;i++)if(tris[i])
  2249. {
  2250. for(int j=0;j<3;j++)ts.Add((*tris[i])[j]);
  2251. delete tris[i];
  2252. }
  2253. tris_count = ts.count/3;
  2254. tris_out = ts.element;
  2255. ts.element=NULL; ts.count=ts.array_size=0;
  2256. tris.count=0;
  2257. return 1;
  2258. }
  2259. int calchullpbev(float3 *verts,int verts_count,int vlimit, Array<Plane> &planes,float bevangle, Array<btHullTriangle*>& tris)
  2260. {
  2261. int i,j;
  2262. planes.count=0;
  2263. int rc = calchullgen(verts,verts_count,vlimit, tris);
  2264. if(!rc) return 0;
  2265. for(i=0;i<tris.count;i++)if(tris[i])
  2266. {
  2267. Plane p;
  2268. btHullTriangle *t = tris[i];
  2269. p.normal = TriNormal(verts[(*t)[0]],verts[(*t)[1]],verts[(*t)[2]]);
  2270. p.dist = -dot(p.normal, verts[(*t)[0]]);
  2271. planes.Add(p);
  2272. for(j=0;j<3;j++)
  2273. {
  2274. if(t->n[j]<t->id) continue;
  2275. btHullTriangle *s = tris[t->n[j]];
  2276. REAL3 snormal = TriNormal(verts[(*s)[0]],verts[(*s)[1]],verts[(*s)[2]]);
  2277. if(dot(snormal,p.normal)>=cos(bevangle*DEG2RAD)) continue;
  2278. REAL3 n = normalize(snormal+p.normal);
  2279. planes.Add(Plane(n,-dot(n,verts[maxdir(verts,verts_count,n)])));
  2280. }
  2281. }
  2282. for(i=0;i<tris.count;i++)if(tris[i])
  2283. {
  2284. delete tris[i]; // delete tris[i];
  2285. }
  2286. tris.count=0;
  2287. return 1;
  2288. }
  2289. int overhull(Plane *planes,int planes_count,float3 *verts, int verts_count,int maxplanes,
  2290. float3 *&verts_out, int &verts_count_out, int *&faces_out, int &faces_count_out ,float inflate)
  2291. {
  2292. int i,j;
  2293. if(verts_count <4) return 0;
  2294. maxplanes = Min(maxplanes,planes_count);
  2295. float3 bmin(verts[0]),bmax(verts[0]);
  2296. for(i=0;i<verts_count;i++)
  2297. {
  2298. bmin = VectorMin(bmin,verts[i]);
  2299. bmax = VectorMax(bmax,verts[i]);
  2300. }
  2301. // float diameter = magnitude(bmax-bmin);
  2302. // inflate *=diameter; // RELATIVE INFLATION
  2303. bmin -= float3(inflate,inflate,inflate);
  2304. bmax += float3(inflate,inflate,inflate);
  2305. for(i=0;i<planes_count;i++)
  2306. {
  2307. planes[i].dist -= inflate;
  2308. }
  2309. float3 emin = bmin; // VectorMin(bmin,float3(0,0,0));
  2310. float3 emax = bmax; // VectorMax(bmax,float3(0,0,0));
  2311. float epsilon = magnitude(emax-emin) * 0.025f;
  2312. planetestepsilon = magnitude(emax-emin) * PAPERWIDTH;
  2313. // todo: add bounding cube planes to force bevel. or try instead not adding the diameter expansion ??? must think.
  2314. // ConvexH *convex = ConvexHMakeCube(bmin - float3(diameter,diameter,diameter),bmax+float3(diameter,diameter,diameter));
  2315. ConvexH *c = ConvexHMakeCube(REAL3(bmin),REAL3(bmax));
  2316. int k;
  2317. while(maxplanes-- && (k=candidateplane(planes,planes_count,c,epsilon))>=0)
  2318. {
  2319. ConvexH *tmp = c;
  2320. c = ConvexHCrop(*tmp,planes[k]);
  2321. if(c==NULL) {c=tmp; break;} // might want to debug this case better!!!
  2322. if(!AssertIntact(*c)) {c=tmp; break;} // might want to debug this case better too!!!
  2323. delete tmp;
  2324. }
  2325. assert(AssertIntact(*c));
  2326. //return c;
  2327. faces_out = (int*)malloc(sizeof(int)*(1+c->facets.count+c->edges.count)); // new int[1+c->facets.count+c->edges.count];
  2328. faces_count_out=0;
  2329. i=0;
  2330. faces_out[faces_count_out++]=-1;
  2331. k=0;
  2332. while(i<c->edges.count)
  2333. {
  2334. j=1;
  2335. while(j+i<c->edges.count && c->edges[i].p==c->edges[i+j].p) { j++; }
  2336. faces_out[faces_count_out++]=j;
  2337. while(j--)
  2338. {
  2339. faces_out[faces_count_out++] = c->edges[i].v;
  2340. i++;
  2341. }
  2342. k++;
  2343. }
  2344. faces_out[0]=k; // number of faces.
  2345. assert(k==c->facets.count);
  2346. assert(faces_count_out == 1+c->facets.count+c->edges.count);
  2347. verts_out = c->vertices.element; // new float3[c->vertices.count];
  2348. verts_count_out = c->vertices.count;
  2349. for(i=0;i<c->vertices.count;i++)
  2350. {
  2351. verts_out[i] = float3(c->vertices[i]);
  2352. }
  2353. c->vertices.count=c->vertices.array_size=0; c->vertices.element=NULL;
  2354. delete c;
  2355. return 1;
  2356. }
  2357. int overhullv(float3 *verts, int verts_count,int maxplanes,
  2358. float3 *&verts_out, int &verts_count_out, int *&faces_out, int &faces_count_out ,float inflate,float bevangle,int vlimit, Array<btHullTriangle*>& tris)
  2359. {
  2360. if(!verts_count) return 0;
  2361. extern int calchullpbev(float3 *verts,int verts_count,int vlimit, Array<Plane> &planes,float bevangle, Array<btHullTriangle*>& tris) ;
  2362. Array<Plane> planes;
  2363. int rc=calchullpbev(verts,verts_count,vlimit,planes,bevangle, tris) ;
  2364. if(!rc) return 0;
  2365. return overhull(planes.element,planes.count,verts,verts_count,maxplanes,verts_out,verts_count_out,faces_out,faces_count_out,inflate);
  2366. }
  2367. bool ComputeHull(unsigned int vcount,const float *vertices,PHullResult &result,unsigned int vlimit,float inflate, Array<btHullTriangle*>& arrtris)
  2368. {
  2369. int index_count;
  2370. int *faces;
  2371. float3 *verts_out;
  2372. int verts_count_out;
  2373. if(inflate==0.0f)
  2374. {
  2375. int *tris_out;
  2376. int tris_count;
  2377. int ret = calchull( (float3 *) vertices, (int) vcount, tris_out, tris_count, vlimit, arrtris );
  2378. if(!ret) return false;
  2379. result.mIndexCount = (unsigned int) (tris_count*3);
  2380. result.mFaceCount = (unsigned int) tris_count;
  2381. result.mVertices = (float*) vertices;
  2382. result.mVcount = (unsigned int) vcount;
  2383. result.mIndices = (unsigned int *) tris_out;
  2384. return true;
  2385. }
  2386. int ret = overhullv((float3*)vertices,vcount,35,verts_out,verts_count_out,faces,index_count,inflate,120.0f,vlimit, arrtris);
  2387. if(!ret) return false;
  2388. Array<int3> tris;
  2389. int n=faces[0];
  2390. int k=1;
  2391. for(int i=0;i<n;i++)
  2392. {
  2393. int pn = faces[k++];
  2394. for(int j=2;j<pn;j++) tris.Add(int3(faces[k],faces[k+j-1],faces[k+j]));
  2395. k+=pn;
  2396. }
  2397. assert(tris.count == index_count-1-(n*3));
  2398. result.mIndexCount = (unsigned int) (tris.count*3);
  2399. result.mFaceCount = (unsigned int) tris.count;
  2400. result.mVertices = (float*) verts_out;
  2401. result.mVcount = (unsigned int) verts_count_out;
  2402. result.mIndices = (unsigned int *) tris.element;
  2403. tris.element=NULL; tris.count = tris.array_size=0;
  2404. return true;
  2405. }
  2406. void ReleaseHull(PHullResult &result)
  2407. {
  2408. if ( result.mIndices )
  2409. {
  2410. free(result.mIndices);
  2411. }
  2412. result.mVcount = 0;
  2413. result.mIndexCount = 0;
  2414. result.mIndices = 0;
  2415. result.mVertices = 0;
  2416. result.mIndices = 0;
  2417. }
  2418. //*********************************************************************
  2419. //*********************************************************************
  2420. //******** HullLib header
  2421. //*********************************************************************
  2422. //*********************************************************************
  2423. //*********************************************************************
  2424. //*********************************************************************
  2425. //******** HullLib implementation
  2426. //*********************************************************************
  2427. //*********************************************************************
  2428. HullError HullLibrary::CreateConvexHull(const HullDesc &desc, // describes the input request
  2429. HullResult &result) // contains the resulst
  2430. {
  2431. HullError ret = QE_FAIL;
  2432. PHullResult hr;
  2433. unsigned int vcount = desc.mVcount;
  2434. if ( vcount < 8 ) vcount = 8;
  2435. float *vsource = (float *) malloc( sizeof(float)*vcount*3);
  2436. float scale[3];
  2437. unsigned int ovcount;
  2438. bool ok = CleanupVertices(desc.mVcount,desc.mVertices, desc.mVertexStride, ovcount, vsource, desc.mNormalEpsilon, scale ); // normalize point cloud, remove duplicates!
  2439. if ( ok )
  2440. {
  2441. if ( 1 ) // scale vertices back to their original size.
  2442. {
  2443. for (unsigned int i=0; i<ovcount; i++)
  2444. {
  2445. float *v = &vsource[i*3];
  2446. v[0]*=scale[0];
  2447. v[1]*=scale[1];
  2448. v[2]*=scale[2];
  2449. }
  2450. }
  2451. float skinwidth = 0;
  2452. if ( desc.HasHullFlag(QF_SKIN_WIDTH) )
  2453. skinwidth = desc.mSkinWidth;
  2454. Array<btHullTriangle*> tris;
  2455. ok = ComputeHull(ovcount,vsource,hr,desc.mMaxVertices,skinwidth, tris);
  2456. if ( ok )
  2457. {
  2458. // re-index triangle mesh so it refers to only used vertices, rebuild a new vertex table.
  2459. float *vscratch = (float *) malloc( sizeof(float)*hr.mVcount*3);
  2460. BringOutYourDead(hr.mVertices,hr.mVcount, vscratch, ovcount, hr.mIndices, hr.mIndexCount );
  2461. ret = QE_OK;
  2462. if ( desc.HasHullFlag(QF_TRIANGLES) ) // if he wants the results as triangle!
  2463. {
  2464. result.mPolygons = false;
  2465. result.mNumOutputVertices = ovcount;
  2466. result.mOutputVertices = (float *)malloc( sizeof(float)*ovcount*3);
  2467. result.mNumFaces = hr.mFaceCount;
  2468. result.mNumIndices = hr.mIndexCount;
  2469. result.mIndices = (unsigned int *) malloc( sizeof(unsigned int)*hr.mIndexCount);
  2470. memcpy(result.mOutputVertices, vscratch, sizeof(float)*3*ovcount );
  2471. if ( desc.HasHullFlag(QF_REVERSE_ORDER) )
  2472. {
  2473. const unsigned int *source = hr.mIndices;
  2474. unsigned int *dest = result.mIndices;
  2475. for (unsigned int i=0; i<hr.mFaceCount; i++)
  2476. {
  2477. dest[0] = source[2];
  2478. dest[1] = source[1];
  2479. dest[2] = source[0];
  2480. dest+=3;
  2481. source+=3;
  2482. }
  2483. }
  2484. else
  2485. {
  2486. memcpy(result.mIndices, hr.mIndices, sizeof(unsigned int)*hr.mIndexCount);
  2487. }
  2488. }
  2489. else
  2490. {
  2491. result.mPolygons = true;
  2492. result.mNumOutputVertices = ovcount;
  2493. result.mOutputVertices = (float *)malloc( sizeof(float)*ovcount*3);
  2494. result.mNumFaces = hr.mFaceCount;
  2495. result.mNumIndices = hr.mIndexCount+hr.mFaceCount;
  2496. result.mIndices = (unsigned int *) malloc( sizeof(unsigned int)*result.mNumIndices);
  2497. memcpy(result.mOutputVertices, vscratch, sizeof(float)*3*ovcount );
  2498. if ( 1 )
  2499. {
  2500. const unsigned int *source = hr.mIndices;
  2501. unsigned int *dest = result.mIndices;
  2502. for (unsigned int i=0; i<hr.mFaceCount; i++)
  2503. {
  2504. dest[0] = 3;
  2505. if ( desc.HasHullFlag(QF_REVERSE_ORDER) )
  2506. {
  2507. dest[1] = source[2];
  2508. dest[2] = source[1];
  2509. dest[3] = source[0];
  2510. }
  2511. else
  2512. {
  2513. dest[1] = source[0];
  2514. dest[2] = source[1];
  2515. dest[3] = source[2];
  2516. }
  2517. dest+=4;
  2518. source+=3;
  2519. }
  2520. }
  2521. }
  2522. ReleaseHull(hr);
  2523. if ( vscratch )
  2524. {
  2525. free(vscratch);
  2526. }
  2527. }
  2528. }
  2529. if ( vsource )
  2530. {
  2531. free(vsource);
  2532. }
  2533. return ret;
  2534. }
  2535. HullError HullLibrary::ReleaseResult(HullResult &result) // release memory allocated for this result, we are done with it.
  2536. {
  2537. if ( result.mOutputVertices )
  2538. {
  2539. free(result.mOutputVertices);
  2540. result.mOutputVertices = 0;
  2541. }
  2542. if ( result.mIndices )
  2543. {
  2544. free(result.mIndices);
  2545. result.mIndices = 0;
  2546. }
  2547. return QE_OK;
  2548. }
  2549. static void addPoint(unsigned int &vcount,float *p,float x,float y,float z)
  2550. {
  2551. float *dest = &p[vcount*3];
  2552. dest[0] = x;
  2553. dest[1] = y;
  2554. dest[2] = z;
  2555. vcount++;
  2556. }
  2557. float GetDist(float px,float py,float pz,const float *p2)
  2558. {
  2559. float dx = px - p2[0];
  2560. float dy = py - p2[1];
  2561. float dz = pz - p2[2];
  2562. return dx*dx+dy*dy+dz*dz;
  2563. }
  2564. bool HullLibrary::CleanupVertices(unsigned int svcount,
  2565. const float *svertices,
  2566. unsigned int stride,
  2567. unsigned int &vcount, // output number of vertices
  2568. float *vertices, // location to store the results.
  2569. float normalepsilon,
  2570. float *scale)
  2571. {
  2572. if ( svcount == 0 ) return false;
  2573. #define EPSILON 0.000001f /* close enough to consider two floating point numbers to be 'the same'. */
  2574. vcount = 0;
  2575. float recip[3];
  2576. if ( scale )
  2577. {
  2578. scale[0] = 1;
  2579. scale[1] = 1;
  2580. scale[2] = 1;
  2581. }
  2582. float bmin[3] = { FLT_MAX, FLT_MAX, FLT_MAX };
  2583. float bmax[3] = { -FLT_MAX, -FLT_MAX, -FLT_MAX };
  2584. const char *vtx = (const char *) svertices;
  2585. if ( 1 )
  2586. {
  2587. for (unsigned int i=0; i<svcount; i++)
  2588. {
  2589. const float *p = (const float *) vtx;
  2590. vtx+=stride;
  2591. for (int j=0; j<3; j++)
  2592. {
  2593. if ( p[j] < bmin[j] ) bmin[j] = p[j];
  2594. if ( p[j] > bmax[j] ) bmax[j] = p[j];
  2595. }
  2596. }
  2597. }
  2598. float dx = bmax[0] - bmin[0];
  2599. float dy = bmax[1] - bmin[1];
  2600. float dz = bmax[2] - bmin[2];
  2601. float center[3];
  2602. center[0] = dx*0.5f + bmin[0];
  2603. center[1] = dy*0.5f + bmin[1];
  2604. center[2] = dz*0.5f + bmin[2];
  2605. if ( dx < EPSILON || dy < EPSILON || dz < EPSILON || svcount < 3 )
  2606. {
  2607. float len = FLT_MAX;
  2608. if ( dx > EPSILON && dx < len ) len = dx;
  2609. if ( dy > EPSILON && dy < len ) len = dy;
  2610. if ( dz > EPSILON && dz < len ) len = dz;
  2611. if ( len == FLT_MAX )
  2612. {
  2613. dx = dy = dz = 0.01f; // one centimeter
  2614. }
  2615. else
  2616. {
  2617. if ( dx < EPSILON ) dx = len * 0.05f; // 1/5th the shortest non-zero edge.
  2618. if ( dy < EPSILON ) dy = len * 0.05f;
  2619. if ( dz < EPSILON ) dz = len * 0.05f;
  2620. }
  2621. float x1 = center[0] - dx;
  2622. float x2 = center[0] + dx;
  2623. float y1 = center[1] - dy;
  2624. float y2 = center[1] + dy;
  2625. float z1 = center[2] - dz;
  2626. float z2 = center[2] + dz;
  2627. addPoint(vcount,vertices,x1,y1,z1);
  2628. addPoint(vcount,vertices,x2,y1,z1);
  2629. addPoint(vcount,vertices,x2,y2,z1);
  2630. addPoint(vcount,vertices,x1,y2,z1);
  2631. addPoint(vcount,vertices,x1,y1,z2);
  2632. addPoint(vcount,vertices,x2,y1,z2);
  2633. addPoint(vcount,vertices,x2,y2,z2);
  2634. addPoint(vcount,vertices,x1,y2,z2);
  2635. return true; // return cube
  2636. }
  2637. else
  2638. {
  2639. if ( scale )
  2640. {
  2641. scale[0] = dx;
  2642. scale[1] = dy;
  2643. scale[2] = dz;
  2644. recip[0] = 1 / dx;
  2645. recip[1] = 1 / dy;
  2646. recip[2] = 1 / dz;
  2647. center[0]*=recip[0];
  2648. center[1]*=recip[1];
  2649. center[2]*=recip[2];
  2650. }
  2651. }
  2652. vtx = (const char *) svertices;
  2653. for (unsigned int i=0; i<svcount; i++)
  2654. {
  2655. const float *p = (const float *)vtx;
  2656. vtx+=stride;
  2657. float px = p[0];
  2658. float py = p[1];
  2659. float pz = p[2];
  2660. if ( scale )
  2661. {
  2662. px = px*recip[0]; // normalize
  2663. py = py*recip[1]; // normalize
  2664. pz = pz*recip[2]; // normalize
  2665. }
  2666. if ( 1 )
  2667. {
  2668. unsigned int j;
  2669. for (j=0; j<vcount; j++)
  2670. {
  2671. float *v = &vertices[j*3];
  2672. float x = v[0];
  2673. float y = v[1];
  2674. float z = v[2];
  2675. float dx = fabsf(x - px );
  2676. float dy = fabsf(y - py );
  2677. float dz = fabsf(z - pz );
  2678. if ( dx < normalepsilon && dy < normalepsilon && dz < normalepsilon )
  2679. {
  2680. // ok, it is close enough to the old one
  2681. // now let us see if it is further from the center of the point cloud than the one we already recorded.
  2682. // in which case we keep this one instead.
  2683. float dist1 = GetDist(px,py,pz,center);
  2684. float dist2 = GetDist(v[0],v[1],v[2],center);
  2685. if ( dist1 > dist2 )
  2686. {
  2687. v[0] = px;
  2688. v[1] = py;
  2689. v[2] = pz;
  2690. }
  2691. break;
  2692. }
  2693. }
  2694. if ( j == vcount )
  2695. {
  2696. float *dest = &vertices[vcount*3];
  2697. dest[0] = px;
  2698. dest[1] = py;
  2699. dest[2] = pz;
  2700. vcount++;
  2701. }
  2702. }
  2703. }
  2704. // ok..now make sure we didn't prune so many vertices it is now invalid.
  2705. if ( 1 )
  2706. {
  2707. float bmin[3] = { FLT_MAX, FLT_MAX, FLT_MAX };
  2708. float bmax[3] = { -FLT_MAX, -FLT_MAX, -FLT_MAX };
  2709. for (unsigned int i=0; i<vcount; i++)
  2710. {
  2711. const float *p = &vertices[i*3];
  2712. for (int j=0; j<3; j++)
  2713. {
  2714. if ( p[j] < bmin[j] ) bmin[j] = p[j];
  2715. if ( p[j] > bmax[j] ) bmax[j] = p[j];
  2716. }
  2717. }
  2718. float dx = bmax[0] - bmin[0];
  2719. float dy = bmax[1] - bmin[1];
  2720. float dz = bmax[2] - bmin[2];
  2721. if ( dx < EPSILON || dy < EPSILON || dz < EPSILON || vcount < 3)
  2722. {
  2723. float cx = dx*0.5f + bmin[0];
  2724. float cy = dy*0.5f + bmin[1];
  2725. float cz = dz*0.5f + bmin[2];
  2726. float len = FLT_MAX;
  2727. if ( dx >= EPSILON && dx < len ) len = dx;
  2728. if ( dy >= EPSILON && dy < len ) len = dy;
  2729. if ( dz >= EPSILON && dz < len ) len = dz;
  2730. if ( len == FLT_MAX )
  2731. {
  2732. dx = dy = dz = 0.01f; // one centimeter
  2733. }
  2734. else
  2735. {
  2736. if ( dx < EPSILON ) dx = len * 0.05f; // 1/5th the shortest non-zero edge.
  2737. if ( dy < EPSILON ) dy = len * 0.05f;
  2738. if ( dz < EPSILON ) dz = len * 0.05f;
  2739. }
  2740. float x1 = cx - dx;
  2741. float x2 = cx + dx;
  2742. float y1 = cy - dy;
  2743. float y2 = cy + dy;
  2744. float z1 = cz - dz;
  2745. float z2 = cz + dz;
  2746. vcount = 0; // add box
  2747. addPoint(vcount,vertices,x1,y1,z1);
  2748. addPoint(vcount,vertices,x2,y1,z1);
  2749. addPoint(vcount,vertices,x2,y2,z1);
  2750. addPoint(vcount,vertices,x1,y2,z1);
  2751. addPoint(vcount,vertices,x1,y1,z2);
  2752. addPoint(vcount,vertices,x2,y1,z2);
  2753. addPoint(vcount,vertices,x2,y2,z2);
  2754. addPoint(vcount,vertices,x1,y2,z2);
  2755. return true;
  2756. }
  2757. }
  2758. return true;
  2759. }
  2760. void HullLibrary::BringOutYourDead(const float *verts,unsigned int vcount, float *overts,unsigned int &ocount,unsigned int *indices,unsigned indexcount)
  2761. {
  2762. unsigned int *used = (unsigned int *)malloc(sizeof(unsigned int)*vcount);
  2763. memset(used,0,sizeof(unsigned int)*vcount);
  2764. ocount = 0;
  2765. for (unsigned int i=0; i<indexcount; i++)
  2766. {
  2767. unsigned int v = indices[i]; // original array index
  2768. assert( v >= 0 && v < vcount );
  2769. if ( used[v] ) // if already remapped
  2770. {
  2771. indices[i] = used[v]-1; // index to new array
  2772. }
  2773. else
  2774. {
  2775. indices[i] = ocount; // new index mapping
  2776. overts[ocount*3+0] = verts[v*3+0]; // copy old vert to new vert array
  2777. overts[ocount*3+1] = verts[v*3+1];
  2778. overts[ocount*3+2] = verts[v*3+2];
  2779. ocount++; // increment output vert count
  2780. assert( ocount >=0 && ocount <= vcount );
  2781. used[v] = ocount; // assign new index remapping
  2782. }
  2783. }
  2784. free(used);
  2785. }
  2786. }