concavity.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795
  1. #include "float_math.h"
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <assert.h>
  6. #include <vector>
  7. /*----------------------------------------------------------------------
  8. Copyright (c) 2004 Open Dynamics Framework Group
  9. www.physicstools.org
  10. All rights reserved.
  11. Redistribution and use in source and binary forms, with or without modification, are permitted provided
  12. that the following conditions are met:
  13. Redistributions of source code must retain the above copyright notice, this list of conditions
  14. and the following disclaimer.
  15. Redistributions in binary form must reproduce the above copyright notice,
  16. this list of conditions and the following disclaimer in the documentation
  17. and/or other materials provided with the distribution.
  18. Neither the name of the Open Dynamics Framework Group nor the names of its contributors may
  19. be used to endorse or promote products derived from this software without specific prior written permission.
  20. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES,
  21. INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  22. DISCLAIMED. IN NO EVENT SHALL THE INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  23. EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  24. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
  25. IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  26. THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27. -----------------------------------------------------------------------*/
  28. // http://codesuppository.blogspot.com
  29. //
  30. // mailto: [email protected]
  31. //
  32. // http://www.amillionpixels.us
  33. //
  34. #include "concavity.h"
  35. #include "raytri.h"
  36. #include "bestfit.h"
  37. #include "cd_hull.h"
  38. #include "meshvolume.h"
  39. #include "cd_vector.h"
  40. #include "splitplane.h"
  41. #include "ConvexDecomposition.h"
  42. #define WSCALE 4
  43. #define CONCAVE_THRESH 0.05f
  44. namespace ConvexDecomposition
  45. {
  46. unsigned int getDebugColor(void)
  47. {
  48. static unsigned int colors[8] =
  49. {
  50. 0xFF0000,
  51. 0x00FF00,
  52. 0x0000FF,
  53. 0xFFFF00,
  54. 0x00FFFF,
  55. 0xFF00FF,
  56. 0xFFFFFF,
  57. 0xFF8040
  58. };
  59. static int count = 0;
  60. count++;
  61. if ( count == 8 ) count = 0;
  62. assert( count >= 0 && count < 8 );
  63. unsigned int color = colors[count];
  64. return color;
  65. }
  66. class Wpoint
  67. {
  68. public:
  69. Wpoint(const Vector3d &p,float w)
  70. {
  71. mPoint = p;
  72. mWeight = w;
  73. }
  74. Vector3d mPoint;
  75. float mWeight;
  76. };
  77. typedef std::vector< Wpoint > WpointVector;
  78. static inline float DistToPt(const float *p,const float *plane)
  79. {
  80. float x = p[0];
  81. float y = p[1];
  82. float z = p[2];
  83. float d = x*plane[0] + y*plane[1] + z*plane[2] + plane[3];
  84. return d;
  85. }
  86. static void intersect(const float *p1,const float *p2,float *split,const float *plane)
  87. {
  88. float dp1 = DistToPt(p1,plane);
  89. float dir[3];
  90. dir[0] = p2[0] - p1[0];
  91. dir[1] = p2[1] - p1[1];
  92. dir[2] = p2[2] - p1[2];
  93. float dot1 = dir[0]*plane[0] + dir[1]*plane[1] + dir[2]*plane[2];
  94. float dot2 = dp1 - plane[3];
  95. float t = -(plane[3] + dot2 ) / dot1;
  96. split[0] = (dir[0]*t)+p1[0];
  97. split[1] = (dir[1]*t)+p1[1];
  98. split[2] = (dir[2]*t)+p1[2];
  99. }
  100. class CTri
  101. {
  102. public:
  103. CTri(void) { };
  104. CTri(const float *p1,const float *p2,const float *p3,unsigned int i1,unsigned int i2,unsigned int i3)
  105. {
  106. mProcessed = 0;
  107. mI1 = i1;
  108. mI2 = i2;
  109. mI3 = i3;
  110. mP1.Set(p1);
  111. mP2.Set(p2);
  112. mP3.Set(p3);
  113. mPlaneD = mNormal.ComputePlane(mP1,mP2,mP3);
  114. }
  115. float Facing(const CTri &t)
  116. {
  117. float d = mNormal.Dot(t.mNormal);
  118. return d;
  119. }
  120. // clip this line segment against this triangle.
  121. bool clip(const Vector3d &start,Vector3d &end) const
  122. {
  123. Vector3d sect;
  124. bool hit = lineIntersectsTriangle(start.Ptr(), end.Ptr(), mP1.Ptr(), mP2.Ptr(), mP3.Ptr(), sect.Ptr() );
  125. if ( hit )
  126. {
  127. end = sect;
  128. }
  129. return hit;
  130. }
  131. bool Concave(const Vector3d &p,float &distance,Vector3d &n) const
  132. {
  133. n.NearestPointInTriangle(p,mP1,mP2,mP3);
  134. distance = p.Distance(n);
  135. return true;
  136. }
  137. void addTri(unsigned int *indices,unsigned int i1,unsigned int i2,unsigned int i3,unsigned int &tcount) const
  138. {
  139. indices[tcount*3+0] = i1;
  140. indices[tcount*3+1] = i2;
  141. indices[tcount*3+2] = i3;
  142. tcount++;
  143. }
  144. float getVolume(ConvexDecompInterface *callback) const
  145. {
  146. unsigned int indices[8*3];
  147. unsigned int tcount = 0;
  148. addTri(indices,0,1,2,tcount);
  149. addTri(indices,3,4,5,tcount);
  150. addTri(indices,0,3,4,tcount);
  151. addTri(indices,0,4,1,tcount);
  152. addTri(indices,1,4,5,tcount);
  153. addTri(indices,1,5,2,tcount);
  154. addTri(indices,0,3,5,tcount);
  155. addTri(indices,0,5,2,tcount);
  156. const float *vertices = mP1.Ptr();
  157. if ( callback )
  158. {
  159. unsigned int color = getDebugColor();
  160. #if 0
  161. Vector3d d1 = mNear1;
  162. Vector3d d2 = mNear2;
  163. Vector3d d3 = mNear3;
  164. callback->ConvexDebugPoint(mP1.Ptr(),0.01f,0x00FF00);
  165. callback->ConvexDebugPoint(mP2.Ptr(),0.01f,0x00FF00);
  166. callback->ConvexDebugPoint(mP3.Ptr(),0.01f,0x00FF00);
  167. callback->ConvexDebugPoint(d1.Ptr(),0.01f,0xFF0000);
  168. callback->ConvexDebugPoint(d2.Ptr(),0.01f,0xFF0000);
  169. callback->ConvexDebugPoint(d3.Ptr(),0.01f,0xFF0000);
  170. callback->ConvexDebugTri(mP1.Ptr(), d1.Ptr(), d1.Ptr(),0x00FF00);
  171. callback->ConvexDebugTri(mP2.Ptr(), d2.Ptr(), d2.Ptr(),0x00FF00);
  172. callback->ConvexDebugTri(mP3.Ptr(), d3.Ptr(), d3.Ptr(),0x00FF00);
  173. #else
  174. for (unsigned int i=0; i<tcount; i++)
  175. {
  176. unsigned int i1 = indices[i*3+0];
  177. unsigned int i2 = indices[i*3+1];
  178. unsigned int i3 = indices[i*3+2];
  179. const float *p1 = &vertices[ i1*3 ];
  180. const float *p2 = &vertices[ i2*3 ];
  181. const float *p3 = &vertices[ i3*3 ];
  182. callback->ConvexDebugTri(p1,p2,p3,color);
  183. }
  184. #endif
  185. }
  186. float v = computeMeshVolume(mP1.Ptr(), tcount, indices );
  187. return v;
  188. }
  189. float raySect(const Vector3d &p,const Vector3d &dir,Vector3d &sect) const
  190. {
  191. float plane[4];
  192. plane[0] = mNormal.x;
  193. plane[1] = mNormal.y;
  194. plane[2] = mNormal.z;
  195. plane[3] = mPlaneD;
  196. Vector3d dest = p+dir*100000;
  197. intersect( p.Ptr(), dest.Ptr(), sect.Ptr(), plane );
  198. return sect.Distance(p); // return the intersection distance.
  199. }
  200. float planeDistance(const Vector3d &p) const
  201. {
  202. float plane[4];
  203. plane[0] = mNormal.x;
  204. plane[1] = mNormal.y;
  205. plane[2] = mNormal.z;
  206. plane[3] = mPlaneD;
  207. return DistToPt( p.Ptr(), plane );
  208. }
  209. bool samePlane(const CTri &t) const
  210. {
  211. const float THRESH = 0.001f;
  212. float dd = fabsf( t.mPlaneD - mPlaneD );
  213. if ( dd > THRESH ) return false;
  214. dd = fabsf( t.mNormal.x - mNormal.x );
  215. if ( dd > THRESH ) return false;
  216. dd = fabsf( t.mNormal.y - mNormal.y );
  217. if ( dd > THRESH ) return false;
  218. dd = fabsf( t.mNormal.z - mNormal.z );
  219. if ( dd > THRESH ) return false;
  220. return true;
  221. }
  222. bool hasIndex(unsigned int i) const
  223. {
  224. if ( i == mI1 || i == mI2 || i == mI3 ) return true;
  225. return false;
  226. }
  227. bool sharesEdge(const CTri &t) const
  228. {
  229. bool ret = false;
  230. unsigned int count = 0;
  231. if ( t.hasIndex(mI1) ) count++;
  232. if ( t.hasIndex(mI2) ) count++;
  233. if ( t.hasIndex(mI3) ) count++;
  234. if ( count >= 2 ) ret = true;
  235. return ret;
  236. }
  237. void debug(unsigned int color,ConvexDecompInterface *callback)
  238. {
  239. callback->ConvexDebugTri( mP1.Ptr(), mP2.Ptr(), mP3.Ptr(), color );
  240. callback->ConvexDebugTri( mP1.Ptr(), mP1.Ptr(), mNear1.Ptr(), 0xFF0000 );
  241. callback->ConvexDebugTri( mP2.Ptr(), mP2.Ptr(), mNear2.Ptr(), 0xFF0000 );
  242. callback->ConvexDebugTri( mP2.Ptr(), mP3.Ptr(), mNear3.Ptr(), 0xFF0000 );
  243. callback->ConvexDebugPoint( mNear1.Ptr(), 0.01f, 0xFF0000 );
  244. callback->ConvexDebugPoint( mNear2.Ptr(), 0.01f, 0xFF0000 );
  245. callback->ConvexDebugPoint( mNear3.Ptr(), 0.01f, 0xFF0000 );
  246. }
  247. float area(void)
  248. {
  249. float a = mConcavity*mP1.Area(mP2,mP3);
  250. return a;
  251. }
  252. void addWeighted(WpointVector &list,ConvexDecompInterface *callback)
  253. {
  254. Wpoint p1(mP1,mC1);
  255. Wpoint p2(mP2,mC2);
  256. Wpoint p3(mP3,mC3);
  257. Vector3d d1 = mNear1 - mP1;
  258. Vector3d d2 = mNear2 - mP2;
  259. Vector3d d3 = mNear3 - mP3;
  260. d1*=WSCALE;
  261. d2*=WSCALE;
  262. d3*=WSCALE;
  263. d1 = d1 + mP1;
  264. d2 = d2 + mP2;
  265. d3 = d3 + mP3;
  266. Wpoint p4(d1,mC1);
  267. Wpoint p5(d2,mC2);
  268. Wpoint p6(d3,mC3);
  269. list.push_back(p1);
  270. list.push_back(p2);
  271. list.push_back(p3);
  272. list.push_back(p4);
  273. list.push_back(p5);
  274. list.push_back(p6);
  275. #if 0
  276. callback->ConvexDebugPoint(mP1.Ptr(),0.01f,0x00FF00);
  277. callback->ConvexDebugPoint(mP2.Ptr(),0.01f,0x00FF00);
  278. callback->ConvexDebugPoint(mP3.Ptr(),0.01f,0x00FF00);
  279. callback->ConvexDebugPoint(d1.Ptr(),0.01f,0xFF0000);
  280. callback->ConvexDebugPoint(d2.Ptr(),0.01f,0xFF0000);
  281. callback->ConvexDebugPoint(d3.Ptr(),0.01f,0xFF0000);
  282. callback->ConvexDebugTri(mP1.Ptr(), d1.Ptr(), d1.Ptr(),0x00FF00);
  283. callback->ConvexDebugTri(mP2.Ptr(), d2.Ptr(), d2.Ptr(),0x00FF00);
  284. callback->ConvexDebugTri(mP3.Ptr(), d3.Ptr(), d3.Ptr(),0x00FF00);
  285. Vector3d np1 = mP1 + mNormal*0.05f;
  286. Vector3d np2 = mP2 + mNormal*0.05f;
  287. Vector3d np3 = mP3 + mNormal*0.05f;
  288. callback->ConvexDebugTri(mP1.Ptr(), np1.Ptr(), np1.Ptr(), 0xFF00FF );
  289. callback->ConvexDebugTri(mP2.Ptr(), np2.Ptr(), np2.Ptr(), 0xFF00FF );
  290. callback->ConvexDebugTri(mP3.Ptr(), np3.Ptr(), np3.Ptr(), 0xFF00FF );
  291. callback->ConvexDebugPoint( np1.Ptr(), 0.01F, 0XFF00FF );
  292. callback->ConvexDebugPoint( np2.Ptr(), 0.01F, 0XFF00FF );
  293. callback->ConvexDebugPoint( np3.Ptr(), 0.01F, 0XFF00FF );
  294. #endif
  295. }
  296. Vector3d mP1;
  297. Vector3d mP2;
  298. Vector3d mP3;
  299. Vector3d mNear1;
  300. Vector3d mNear2;
  301. Vector3d mNear3;
  302. Vector3d mNormal;
  303. float mPlaneD;
  304. float mConcavity;
  305. float mC1;
  306. float mC2;
  307. float mC3;
  308. unsigned int mI1;
  309. unsigned int mI2;
  310. unsigned int mI3;
  311. int mProcessed; // already been added...
  312. };
  313. typedef std::vector< CTri > CTriVector;
  314. bool featureMatch(CTri &m,const CTriVector &tris,ConvexDecompInterface *callback,const CTriVector &input_mesh)
  315. {
  316. bool ret = false;
  317. float neardot = 0.707f;
  318. m.mConcavity = 0;
  319. //gLog->Display("*********** FEATURE MATCH *************\r\n");
  320. //gLog->Display("Plane: %0.4f,%0.4f,%0.4f %0.4f\r\n", m.mNormal.x, m.mNormal.y, m.mNormal.z, m.mPlaneD );
  321. //gLog->Display("*********************************************\r\n");
  322. CTriVector::const_iterator i;
  323. CTri nearest;
  324. for (i=tris.begin(); i!=tris.end(); ++i)
  325. {
  326. const CTri &t = (*i);
  327. //gLog->Display(" HullPlane: %0.4f,%0.4f,%0.4f %0.4f\r\n", t.mNormal.x, t.mNormal.y, t.mNormal.z, t.mPlaneD );
  328. if ( t.samePlane(m) )
  329. {
  330. //gLog->Display("*** PLANE MATCH!!!\r\n");
  331. ret = false;
  332. break;
  333. }
  334. float dot = t.mNormal.Dot(m.mNormal);
  335. if ( dot > neardot )
  336. {
  337. float d1 = t.planeDistance( m.mP1 );
  338. float d2 = t.planeDistance( m.mP2 );
  339. float d3 = t.planeDistance( m.mP3 );
  340. if ( d1 > 0.001f || d2 > 0.001f || d3 > 0.001f ) // can't be near coplaner!
  341. {
  342. neardot = dot;
  343. Vector3d n1,n2,n3;
  344. t.raySect( m.mP1, m.mNormal, m.mNear1 );
  345. t.raySect( m.mP2, m.mNormal, m.mNear2 );
  346. t.raySect( m.mP3, m.mNormal, m.mNear3 );
  347. nearest = t;
  348. ret = true;
  349. }
  350. }
  351. }
  352. if ( ret )
  353. {
  354. if ( 0 )
  355. {
  356. CTriVector::const_iterator i;
  357. for (i=input_mesh.begin(); i!=input_mesh.end(); ++i)
  358. {
  359. const CTri &c = (*i);
  360. if ( c.mI1 != m.mI1 && c.mI2 != m.mI2 && c.mI3 != m.mI3 )
  361. {
  362. c.clip( m.mP1, m.mNear1 );
  363. c.clip( m.mP2, m.mNear2 );
  364. c.clip( m.mP3, m.mNear3 );
  365. }
  366. }
  367. }
  368. //gLog->Display("*********************************************\r\n");
  369. //gLog->Display(" HullPlaneNearest: %0.4f,%0.4f,%0.4f %0.4f\r\n", nearest.mNormal.x, nearest.mNormal.y, nearest.mNormal.z, nearest.mPlaneD );
  370. m.mC1 = m.mP1.Distance( m.mNear1 );
  371. m.mC2 = m.mP2.Distance( m.mNear2 );
  372. m.mC3 = m.mP3.Distance( m.mNear3 );
  373. m.mConcavity = m.mC1;
  374. if ( m.mC2 > m.mConcavity ) m.mConcavity = m.mC2;
  375. if ( m.mC3 > m.mConcavity ) m.mConcavity = m.mC3;
  376. #if 0
  377. callback->ConvexDebugTri( m.mP1.Ptr(), m.mP2.Ptr(), m.mP3.Ptr(), 0x00FF00 );
  378. callback->ConvexDebugTri( m.mNear1.Ptr(), m.mNear2.Ptr(), m.mNear3.Ptr(), 0xFF0000 );
  379. callback->ConvexDebugTri( m.mP1.Ptr(), m.mP1.Ptr(), m.mNear1.Ptr(), 0xFFFF00 );
  380. callback->ConvexDebugTri( m.mP2.Ptr(), m.mP2.Ptr(), m.mNear2.Ptr(), 0xFFFF00 );
  381. callback->ConvexDebugTri( m.mP3.Ptr(), m.mP3.Ptr(), m.mNear3.Ptr(), 0xFFFF00 );
  382. #endif
  383. }
  384. else
  385. {
  386. //gLog->Display("No match\r\n");
  387. }
  388. //gLog->Display("*********************************************\r\n");
  389. return ret;
  390. }
  391. bool isFeatureTri(CTri &t,CTriVector &flist,float fc,ConvexDecompInterface *callback,unsigned int color)
  392. {
  393. bool ret = false;
  394. if ( t.mProcessed == 0 ) // if not already processed
  395. {
  396. float c = t.mConcavity / fc; // must be within 80% of the concavity of the parent.
  397. if ( c > 0.85f )
  398. {
  399. // see if this triangle is a 'feature' triangle. Meaning it shares an
  400. // edge with any existing feature triangle and is within roughly the same
  401. // concavity of the parent.
  402. if ( flist.size() )
  403. {
  404. CTriVector::iterator i;
  405. for (i=flist.begin(); i!=flist.end(); ++i)
  406. {
  407. CTri &ftri = (*i);
  408. if ( ftri.sharesEdge(t) )
  409. {
  410. t.mProcessed = 2; // it is now part of a feature.
  411. flist.push_back(t); // add it to the feature list.
  412. // callback->ConvexDebugTri( t.mP1.Ptr(), t.mP2.Ptr(),t.mP3.Ptr(), color );
  413. ret = true;
  414. break;
  415. }
  416. }
  417. }
  418. else
  419. {
  420. t.mProcessed = 2;
  421. flist.push_back(t); // add it to the feature list.
  422. // callback->ConvexDebugTri( t.mP1.Ptr(), t.mP2.Ptr(),t.mP3.Ptr(), color );
  423. ret = true;
  424. }
  425. }
  426. else
  427. {
  428. t.mProcessed = 1; // eliminated for this feature, but might be valid for the next one..
  429. }
  430. }
  431. return ret;
  432. }
  433. float computeConcavity(unsigned int vcount,
  434. const float *vertices,
  435. unsigned int tcount,
  436. const unsigned int *indices,
  437. ConvexDecompInterface *callback,
  438. float *plane, // plane equation to split on
  439. float &volume)
  440. {
  441. float cret = 0;
  442. volume = 1;
  443. HullResult result;
  444. HullLibrary hl;
  445. HullDesc desc;
  446. desc.mMaxFaces = 256;
  447. desc.mMaxVertices = 256;
  448. desc.SetHullFlag(QF_TRIANGLES);
  449. desc.mVcount = vcount;
  450. desc.mVertices = vertices;
  451. desc.mVertexStride = sizeof(float)*3;
  452. HullError ret = hl.CreateConvexHull(desc,result);
  453. if ( ret == QE_OK )
  454. {
  455. #if 0
  456. float bmin[3];
  457. float bmax[3];
  458. float dx = bmax[0] - bmin[0];
  459. float dy = bmax[1] - bmin[1];
  460. float dz = bmax[2] - bmin[2];
  461. Vector3d center;
  462. center.x = bmin[0] + dx*0.5f;
  463. center.y = bmin[1] + dy*0.5f;
  464. center.z = bmin[2] + dz*0.5f;
  465. #endif
  466. volume = computeMeshVolume2( result.mOutputVertices, result.mNumFaces, result.mIndices );
  467. #if 1
  468. // ok..now..for each triangle on the original mesh..
  469. // we extrude the points to the nearest point on the hull.
  470. const unsigned int *source = result.mIndices;
  471. CTriVector tris;
  472. for (unsigned int i=0; i<result.mNumFaces; i++)
  473. {
  474. unsigned int i1 = *source++;
  475. unsigned int i2 = *source++;
  476. unsigned int i3 = *source++;
  477. const float *p1 = &result.mOutputVertices[i1*3];
  478. const float *p2 = &result.mOutputVertices[i2*3];
  479. const float *p3 = &result.mOutputVertices[i3*3];
  480. // callback->ConvexDebugTri(p1,p2,p3,0xFFFFFF);
  481. CTri t(p1,p2,p3,i1,i2,i3); //
  482. tris.push_back(t);
  483. }
  484. // we have not pre-computed the plane equation for each triangle in the convex hull..
  485. float totalVolume = 0;
  486. CTriVector ftris; // 'feature' triangles.
  487. const unsigned int *src = indices;
  488. float maxc=0;
  489. if ( 1 )
  490. {
  491. CTriVector input_mesh;
  492. if ( 1 )
  493. {
  494. const unsigned int *src = indices;
  495. for (unsigned int i=0; i<tcount; i++)
  496. {
  497. unsigned int i1 = *src++;
  498. unsigned int i2 = *src++;
  499. unsigned int i3 = *src++;
  500. const float *p1 = &vertices[i1*3];
  501. const float *p2 = &vertices[i2*3];
  502. const float *p3 = &vertices[i3*3];
  503. CTri t(p1,p2,p3,i1,i2,i3);
  504. input_mesh.push_back(t);
  505. }
  506. }
  507. CTri maxctri;
  508. for (unsigned int i=0; i<tcount; i++)
  509. {
  510. unsigned int i1 = *src++;
  511. unsigned int i2 = *src++;
  512. unsigned int i3 = *src++;
  513. const float *p1 = &vertices[i1*3];
  514. const float *p2 = &vertices[i2*3];
  515. const float *p3 = &vertices[i3*3];
  516. CTri t(p1,p2,p3,i1,i2,i3);
  517. featureMatch(t, tris, callback, input_mesh );
  518. if ( t.mConcavity > CONCAVE_THRESH )
  519. {
  520. if ( t.mConcavity > maxc )
  521. {
  522. maxc = t.mConcavity;
  523. maxctri = t;
  524. }
  525. float v = t.getVolume(0);
  526. totalVolume+=v;
  527. ftris.push_back(t);
  528. }
  529. }
  530. }
  531. if ( ftris.size() && 0 )
  532. {
  533. // ok..now we extract the triangles which form the maximum concavity.
  534. CTriVector major_feature;
  535. float maxarea = 0;
  536. while ( maxc > CONCAVE_THRESH )
  537. {
  538. unsigned int color = getDebugColor(); //
  539. CTriVector flist;
  540. bool found;
  541. float totalarea = 0;
  542. do
  543. {
  544. found = false;
  545. CTriVector::iterator i;
  546. for (i=ftris.begin(); i!=ftris.end(); ++i)
  547. {
  548. CTri &t = (*i);
  549. if ( isFeatureTri(t,flist,maxc,callback,color) )
  550. {
  551. found = true;
  552. totalarea+=t.area();
  553. }
  554. }
  555. } while ( found );
  556. if ( totalarea > maxarea )
  557. {
  558. major_feature = flist;
  559. maxarea = totalarea;
  560. }
  561. maxc = 0;
  562. for (unsigned int i=0; i<ftris.size(); i++)
  563. {
  564. CTri &t = ftris[i];
  565. if ( t.mProcessed != 2 )
  566. {
  567. t.mProcessed = 0;
  568. if ( t.mConcavity > maxc )
  569. {
  570. maxc = t.mConcavity;
  571. }
  572. }
  573. }
  574. }
  575. unsigned int color = getDebugColor();
  576. WpointVector list;
  577. for (unsigned int i=0; i<major_feature.size(); ++i)
  578. {
  579. major_feature[i].addWeighted(list,callback);
  580. major_feature[i].debug(color,callback);
  581. }
  582. getBestFitPlane( list.size(), &list[0].mPoint.x, sizeof(Wpoint), &list[0].mWeight, sizeof(Wpoint), plane );
  583. computeSplitPlane( vcount, vertices, tcount, indices, callback, plane );
  584. }
  585. else
  586. {
  587. computeSplitPlane( vcount, vertices, tcount, indices, callback, plane );
  588. }
  589. #endif
  590. cret = totalVolume;
  591. hl.ReleaseResult(result);
  592. }
  593. return cret;
  594. }
  595. }