hull.cpp 84 KB

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