NvMeshIslandGeneration.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783
  1. /*
  2. NvMeshIslandGeneration.cpp : This code snippet walks the toplogy of a triangle mesh and detects the set of unique connected 'mesh islands'
  3. */
  4. /*!
  5. **
  6. ** Copyright (c) 2009 by John W. Ratcliff mailto:[email protected]
  7. **
  8. ** Portions of this source has been released with the PhysXViewer application, as well as
  9. ** Rocket, CreateDynamics, ODF, and as a number of sample code snippets.
  10. **
  11. ** If you find this code useful or you are feeling particularily generous I would
  12. ** ask that you please go to http://www.amillionpixels.us and make a donation
  13. ** to Troy DeMolay.
  14. **
  15. ** DeMolay is a youth group for young men between the ages of 12 and 21.
  16. ** It teaches strong moral principles, as well as leadership skills and
  17. ** public speaking. The donations page uses the 'pay for pixels' paradigm
  18. ** where, in this case, a pixel is only a single penny. Donations can be
  19. ** made for as small as $4 or as high as a $100 block. Each person who donates
  20. ** will get a link to their own site as well as acknowledgement on the
  21. ** donations blog located here http://www.amillionpixels.blogspot.com/
  22. **
  23. ** If you wish to contact me you can use the following methods:
  24. **
  25. ** Skype ID: jratcliff63367
  26. ** Yahoo: jratcliff63367
  27. ** AOL: jratcliff1961
  28. ** email: [email protected]
  29. **
  30. **
  31. ** The MIT license:
  32. **
  33. ** Permission is hereby granted, free of charge, to any person obtaining a copy
  34. ** of this software and associated documentation files (the "Software"), to deal
  35. ** in the Software without restriction, including without limitation the rights
  36. ** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  37. ** copies of the Software, and to permit persons to whom the Software is furnished
  38. ** to do so, subject to the following conditions:
  39. **
  40. ** The above copyright notice and this permission notice shall be included in all
  41. ** copies or substantial portions of the Software.
  42. ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  43. ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  44. ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  45. ** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  46. ** WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  47. ** CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  48. */
  49. #include <stdio.h>
  50. #include <stdlib.h>
  51. #include <string.h>
  52. #include <assert.h>
  53. #pragma warning(disable:4100 4288)
  54. #include "NvMeshIslandGeneration.h"
  55. #include "NvFloatMath.h"
  56. #include "NvHashMap.h"
  57. namespace CONVEX_DECOMPOSITION
  58. {
  59. typedef CONVEX_DECOMPOSITION::Array< NxU32 > NxU32Vector;
  60. class Edge;
  61. class Island;
  62. class AABB
  63. {
  64. public:
  65. NxF32 mMin[3];
  66. NxF32 mMax[3];
  67. };
  68. class Triangle
  69. {
  70. public:
  71. Triangle(void)
  72. {
  73. mConsumed = false;
  74. mIsland = 0;
  75. mHandle = 0;
  76. mId = 0;
  77. }
  78. void minmax(const NxF32 *p,AABB &box)
  79. {
  80. if ( p[0] < box.mMin[0] ) box.mMin[0] = p[0];
  81. if ( p[1] < box.mMin[1] ) box.mMin[1] = p[1];
  82. if ( p[2] < box.mMin[2] ) box.mMin[2] = p[2];
  83. if ( p[0] > box.mMax[0] ) box.mMax[0] = p[0];
  84. if ( p[1] > box.mMax[1] ) box.mMax[1] = p[1];
  85. if ( p[2] > box.mMax[2] ) box.mMax[2] = p[2];
  86. }
  87. void minmax(const NxF64 *p,AABB &box)
  88. {
  89. if ( (NxF32)p[0] < box.mMin[0] ) box.mMin[0] = (NxF32)p[0];
  90. if ( (NxF32)p[1] < box.mMin[1] ) box.mMin[1] = (NxF32)p[1];
  91. if ( (NxF32)p[2] < box.mMin[2] ) box.mMin[2] = (NxF32)p[2];
  92. if ( (NxF32)p[0] > box.mMax[0] ) box.mMax[0] = (NxF32)p[0];
  93. if ( (NxF32)p[1] > box.mMax[1] ) box.mMax[1] = (NxF32)p[1];
  94. if ( (NxF32)p[2] > box.mMax[2] ) box.mMax[2] = (NxF32)p[2];
  95. }
  96. void buildBox(const NxF32 *vertices_f,const NxF64 *vertices_d,NxU32 id);
  97. void render(NxU32 color)
  98. {
  99. // gRenderDebug->DebugBound(&mBox.mMin[0],&mBox.mMax[0],color,60.0f);
  100. }
  101. void getTriangle(NxF32 *tri,const NxF32 *vertices_f,const NxF64 *vertices_d);
  102. NxU32 mHandle;
  103. bool mConsumed;
  104. Edge *mEdges[3];
  105. Island *mIsland; // identifies which island it is a member of
  106. unsigned short mId;
  107. AABB mBox;
  108. };
  109. class Edge
  110. {
  111. public:
  112. Edge(void)
  113. {
  114. mI1 = 0;
  115. mI2 = 0;
  116. mHash = 0;
  117. mNext = 0;
  118. mPrevious = 0;
  119. mParent = 0;
  120. mNextTriangleEdge = 0;
  121. }
  122. void init(NxU32 i1,NxU32 i2,Triangle *parent)
  123. {
  124. assert( i1 < 65536 );
  125. assert( i2 < 65536 );
  126. mI1 = i1;
  127. mI2 = i2;
  128. mHash = (i2<<16)|i1;
  129. mReverseHash = (i1<<16)|i2;
  130. mNext = 0;
  131. mPrevious = 0;
  132. mParent = parent;
  133. }
  134. NxU32 mI1;
  135. NxU32 mI2;
  136. NxU32 mHash;
  137. NxU32 mReverseHash;
  138. Edge *mNext;
  139. Edge *mPrevious;
  140. Edge *mNextTriangleEdge;
  141. Triangle *mParent;
  142. };
  143. typedef CONVEX_DECOMPOSITION::HashMap< NxU32, Edge * > EdgeHashMap;
  144. typedef CONVEX_DECOMPOSITION::Array< Triangle * > TriangleVector;
  145. class EdgeCheck
  146. {
  147. public:
  148. EdgeCheck(Triangle *t,Edge *e)
  149. {
  150. mTriangle = t;
  151. mEdge = e;
  152. }
  153. Triangle *mTriangle;
  154. Edge *mEdge;
  155. };
  156. typedef CONVEX_DECOMPOSITION::Array< EdgeCheck > EdgeCheckQueue;
  157. class Island
  158. {
  159. public:
  160. Island(Triangle *t,Triangle *root)
  161. {
  162. mVerticesFloat = 0;
  163. mVerticesDouble = 0;
  164. t->mIsland = this;
  165. mTriangles.pushBack(t);
  166. mCoplanar = false;
  167. fm_initMinMax(mMin,mMax);
  168. }
  169. void add(Triangle *t,Triangle *root)
  170. {
  171. t->mIsland = this;
  172. mTriangles.pushBack(t);
  173. }
  174. void merge(Island &isl)
  175. {
  176. TriangleVector::Iterator i;
  177. for (i=isl.mTriangles.begin(); i!=isl.mTriangles.end(); ++i)
  178. {
  179. Triangle *t = (*i);
  180. mTriangles.pushBack(t);
  181. }
  182. isl.mTriangles.clear();
  183. }
  184. bool isTouching(Island *isl,const NxF32 *vertices_f,const NxF64 *vertices_d)
  185. {
  186. bool ret = false;
  187. mVerticesFloat = vertices_f;
  188. mVerticesDouble = vertices_d;
  189. if ( fm_intersectAABB(mMin,mMax,isl->mMin,isl->mMax) ) // if the two islands has an intersecting AABB
  190. {
  191. // todo..
  192. }
  193. return ret;
  194. }
  195. void SAP_DeletePair(const void* object0, const void* object1, void* user_data, void* pair_user_data)
  196. {
  197. }
  198. void render(NxU32 color)
  199. {
  200. // gRenderDebug->DebugBound(mMin,mMax,color,60.0f);
  201. TriangleVector::Iterator i;
  202. for (i=mTriangles.begin(); i!=mTriangles.end(); ++i)
  203. {
  204. Triangle *t = (*i);
  205. t->render(color);
  206. }
  207. }
  208. const NxF64 *mVerticesDouble;
  209. const NxF32 *mVerticesFloat;
  210. NxF32 mMin[3];
  211. NxF32 mMax[3];
  212. bool mCoplanar; // marked as co-planar..
  213. TriangleVector mTriangles;
  214. };
  215. void Triangle::getTriangle(NxF32 *tri,const NxF32 *vertices_f,const NxF64 *vertices_d)
  216. {
  217. NxU32 i1 = mEdges[0]->mI1;
  218. NxU32 i2 = mEdges[1]->mI1;
  219. NxU32 i3 = mEdges[2]->mI1;
  220. if ( vertices_f )
  221. {
  222. const NxF32 *p1 = &vertices_f[i1*3];
  223. const NxF32 *p2 = &vertices_f[i2*3];
  224. const NxF32 *p3 = &vertices_f[i3*3];
  225. fm_copy3(p1,tri);
  226. fm_copy3(p2,tri+3);
  227. fm_copy3(p3,tri+6);
  228. }
  229. else
  230. {
  231. const NxF64 *p1 = &vertices_d[i1*3];
  232. const NxF64 *p2 = &vertices_d[i2*3];
  233. const NxF64 *p3 = &vertices_d[i3*3];
  234. fm_doubleToFloat3(p1,tri);
  235. fm_doubleToFloat3(p2,tri+3);
  236. fm_doubleToFloat3(p3,tri+6);
  237. }
  238. }
  239. void Triangle::buildBox(const NxF32 *vertices_f,const NxF64 *vertices_d,NxU32 id)
  240. {
  241. mId = (unsigned short)id;
  242. NxU32 i1 = mEdges[0]->mI1;
  243. NxU32 i2 = mEdges[1]->mI1;
  244. NxU32 i3 = mEdges[2]->mI1;
  245. if ( vertices_f )
  246. {
  247. const NxF32 *p1 = &vertices_f[i1*3];
  248. const NxF32 *p2 = &vertices_f[i2*3];
  249. const NxF32 *p3 = &vertices_f[i3*3];
  250. mBox.mMin[0] = p1[0];
  251. mBox.mMin[1] = p1[1];
  252. mBox.mMin[2] = p1[2];
  253. mBox.mMax[0] = p1[0];
  254. mBox.mMax[1] = p1[1];
  255. mBox.mMax[2] = p1[2];
  256. minmax(p2,mBox);
  257. minmax(p3,mBox);
  258. }
  259. else
  260. {
  261. const NxF64 *p1 = &vertices_d[i1*3];
  262. const NxF64 *p2 = &vertices_d[i2*3];
  263. const NxF64 *p3 = &vertices_d[i3*3];
  264. mBox.mMin[0] = (NxF32)p1[0];
  265. mBox.mMin[1] = (NxF32)p1[1];
  266. mBox.mMin[2] = (NxF32)p1[2];
  267. mBox.mMax[0] = (NxF32)p1[0];
  268. mBox.mMax[1] = (NxF32)p1[1];
  269. mBox.mMax[2] = (NxF32)p1[2];
  270. minmax(p2,mBox);
  271. minmax(p3,mBox);
  272. }
  273. assert(mIsland);
  274. if ( mIsland )
  275. {
  276. if ( mBox.mMin[0] < mIsland->mMin[0] ) mIsland->mMin[0] = mBox.mMin[0];
  277. if ( mBox.mMin[1] < mIsland->mMin[1] ) mIsland->mMin[1] = mBox.mMin[1];
  278. if ( mBox.mMin[2] < mIsland->mMin[2] ) mIsland->mMin[2] = mBox.mMin[2];
  279. if ( mBox.mMax[0] > mIsland->mMax[0] ) mIsland->mMax[0] = mBox.mMax[0];
  280. if ( mBox.mMax[1] > mIsland->mMax[1] ) mIsland->mMax[1] = mBox.mMax[1];
  281. if ( mBox.mMax[2] > mIsland->mMax[2] ) mIsland->mMax[2] = mBox.mMax[2];
  282. }
  283. }
  284. typedef CONVEX_DECOMPOSITION::Array< Island * > IslandVector;
  285. class MyMeshIslandGeneration : public MeshIslandGeneration
  286. {
  287. public:
  288. MyMeshIslandGeneration(void)
  289. {
  290. mTriangles = 0;
  291. mEdges = 0;
  292. mVerticesDouble = 0;
  293. mVerticesFloat = 0;
  294. }
  295. ~MyMeshIslandGeneration(void)
  296. {
  297. reset();
  298. }
  299. void reset(void)
  300. {
  301. delete []mTriangles;
  302. delete []mEdges;
  303. mTriangles = 0;
  304. mEdges = 0;
  305. mTriangleEdges.clear();
  306. IslandVector::Iterator i;
  307. for (i=mIslands.begin(); i!=mIslands.end(); ++i)
  308. {
  309. Island *_i = (*i);
  310. delete _i;
  311. }
  312. mIslands.clear();
  313. }
  314. NxU32 islandGenerate(NxU32 tcount,const NxU32 *indices,const NxF64 *vertices)
  315. {
  316. mVerticesDouble = vertices;
  317. mVerticesFloat = 0;
  318. return islandGenerate(tcount,indices);
  319. }
  320. NxU32 islandGenerate(NxU32 tcount,const NxU32 *indices,const NxF32 *vertices)
  321. {
  322. mVerticesDouble = 0;
  323. mVerticesFloat = vertices;
  324. return islandGenerate(tcount,indices);
  325. }
  326. NxU32 islandGenerate(NxU32 tcount,const NxU32 *indices)
  327. {
  328. NxU32 ret = 0;
  329. reset();
  330. mTcount = tcount;
  331. mTriangles = new Triangle[tcount];
  332. mEdges = new Edge[tcount*3];
  333. Edge *e = mEdges;
  334. for (NxU32 i=0; i<tcount; i++)
  335. {
  336. Triangle &t = mTriangles[i];
  337. NxU32 i1 = *indices++;
  338. NxU32 i2 = *indices++;
  339. NxU32 i3 = *indices++;
  340. t.mEdges[0] = e;
  341. t.mEdges[1] = e+1;
  342. t.mEdges[2] = e+2;
  343. e = addEdge(e,&t,i1,i2);
  344. e = addEdge(e,&t,i2,i3);
  345. e = addEdge(e,&t,i3,i1);
  346. }
  347. // while there are still edges to process...
  348. while ( mTriangleEdges.size() != 0 )
  349. {
  350. EdgeHashMap::Iterator iter = mTriangleEdges.getIterator();
  351. Triangle *t = iter->second->mParent;
  352. Island *i = new Island(t,mTriangles); // the initial triangle...
  353. removeTriangle(t); // remove this triangle from the triangle-edges hashmap
  354. mIslands.pushBack(i);
  355. // now keep adding to this island until we can no longer walk any shared edges..
  356. addEdgeCheck(t,t->mEdges[0]);
  357. addEdgeCheck(t,t->mEdges[1]);
  358. addEdgeCheck(t,t->mEdges[2]);
  359. while ( !mEdgeCheckQueue.empty() )
  360. {
  361. EdgeCheck e = mEdgeCheckQueue.popBack();
  362. // Process all triangles which share this edge
  363. Edge *edge = locateSharedEdge(e.mEdge);
  364. while ( edge )
  365. {
  366. Triangle *t = edge->mParent;
  367. assert(!t->mConsumed);
  368. i->add(t,mTriangles);
  369. removeTriangle(t); // remove this triangle from the triangle-edges hashmap
  370. // now keep adding to this island until we can no longer walk any shared edges..
  371. if ( edge != t->mEdges[0] )
  372. {
  373. addEdgeCheck(t,t->mEdges[0]);
  374. }
  375. if ( edge != t->mEdges[1] )
  376. {
  377. addEdgeCheck(t,t->mEdges[1]);
  378. }
  379. if ( edge != t->mEdges[2] )
  380. {
  381. addEdgeCheck(t,t->mEdges[2]);
  382. }
  383. edge = locateSharedEdge(e.mEdge); // keep going until all shared edges have been processed!
  384. }
  385. }
  386. }
  387. ret = (NxU32)mIslands.size();
  388. return ret;
  389. }
  390. NxU32 * getIsland(NxU32 index,NxU32 &otcount)
  391. {
  392. NxU32 *ret = 0;
  393. mIndices.clear();
  394. if ( index < mIslands.size() )
  395. {
  396. Island *i = mIslands[index];
  397. otcount = (NxU32)i->mTriangles.size();
  398. TriangleVector::Iterator j;
  399. for (j=i->mTriangles.begin(); j!=i->mTriangles.end(); ++j)
  400. {
  401. Triangle *t = (*j);
  402. mIndices.pushBack(t->mEdges[0]->mI1);
  403. mIndices.pushBack(t->mEdges[1]->mI1);
  404. mIndices.pushBack(t->mEdges[2]->mI1);
  405. }
  406. ret = &mIndices[0];
  407. }
  408. return ret;
  409. }
  410. private:
  411. void removeTriangle(Triangle *t)
  412. {
  413. t->mConsumed = true;
  414. removeEdge(t->mEdges[0]);
  415. removeEdge(t->mEdges[1]);
  416. removeEdge(t->mEdges[2]);
  417. }
  418. Edge * locateSharedEdge(Edge *e)
  419. {
  420. Edge *ret = 0;
  421. const EdgeHashMap::Entry *found = mTriangleEdges.find( e->mReverseHash );
  422. if ( found != NULL )
  423. {
  424. ret = (*found).second;
  425. assert( ret->mHash == e->mReverseHash );
  426. }
  427. return ret;
  428. }
  429. void removeEdge(Edge *e)
  430. {
  431. const EdgeHashMap::Entry *found = mTriangleEdges.find( e->mHash );
  432. if ( found != NULL )
  433. {
  434. Edge *prev = 0;
  435. Edge *scan = (*found).second;
  436. while ( scan && scan != e )
  437. {
  438. prev = scan;
  439. scan = scan->mNextTriangleEdge;
  440. }
  441. if ( scan )
  442. {
  443. if ( prev == 0 )
  444. {
  445. if ( scan->mNextTriangleEdge )
  446. {
  447. mTriangleEdges.erase(e->mHash);
  448. mTriangleEdges[e->mHash] = scan->mNextTriangleEdge;
  449. }
  450. else
  451. {
  452. mTriangleEdges.erase(e->mHash); // no more polygons have an edge here
  453. }
  454. }
  455. else
  456. {
  457. prev->mNextTriangleEdge = scan->mNextTriangleEdge;
  458. }
  459. }
  460. else
  461. {
  462. assert(0);
  463. }
  464. }
  465. else
  466. {
  467. assert(0); // impossible!
  468. }
  469. }
  470. Edge * addEdge(Edge *e,Triangle *t,NxU32 i1,NxU32 i2)
  471. {
  472. e->init(i1,i2,t);
  473. const EdgeHashMap::Entry *found = mTriangleEdges.find(e->mHash);
  474. if ( found == NULL )
  475. {
  476. mTriangleEdges[ e->mHash ] = e;
  477. }
  478. else
  479. {
  480. Edge *pn = (*found).second;
  481. e->mNextTriangleEdge = pn;
  482. mTriangleEdges.erase(e->mHash);
  483. mTriangleEdges[e->mHash] = e;
  484. }
  485. e++;
  486. return e;
  487. }
  488. void addEdgeCheck(Triangle *t,Edge *e)
  489. {
  490. EdgeCheck ec(t,e);
  491. mEdgeCheckQueue.pushBack(ec);
  492. }
  493. NxU32 mergeCoplanarIslands(const NxF32 *vertices)
  494. {
  495. mVerticesFloat = vertices;
  496. mVerticesDouble = 0;
  497. return mergeCoplanarIslands();
  498. }
  499. NxU32 mergeCoplanarIslands(const NxF64 *vertices)
  500. {
  501. mVerticesDouble = vertices;
  502. mVerticesFloat = 0;
  503. return mergeCoplanarIslands();
  504. }
  505. // this island needs to be merged
  506. void mergeTouching(Island *isl)
  507. {
  508. Island *touching = 0;
  509. IslandVector::Iterator i;
  510. for (i=mIslands.begin(); i!=mIslands.end(); ++i)
  511. {
  512. Island *_i = (*i);
  513. if ( !_i->mCoplanar ) // can't merge with coplanar islands!
  514. {
  515. if ( _i->isTouching(isl,mVerticesFloat,mVerticesDouble) )
  516. {
  517. touching = _i;
  518. }
  519. }
  520. }
  521. }
  522. NxU32 mergeCoplanarIslands(void)
  523. {
  524. NxU32 ret = 0;
  525. if ( !mIslands.empty() )
  526. {
  527. NxU32 cp_count = 0;
  528. NxU32 npc_count = 0;
  529. NxU32 count = (NxU32)mIslands.size();
  530. for (NxU32 i=0; i<count; i++)
  531. {
  532. NxU32 otcount;
  533. const NxU32 *oindices = getIsland(i,otcount);
  534. if ( otcount )
  535. {
  536. bool isCoplanar;
  537. if ( mVerticesFloat )
  538. isCoplanar = fm_isMeshCoplanar(otcount, oindices, mVerticesFloat, true);
  539. else
  540. isCoplanar = fm_isMeshCoplanar(otcount, oindices, mVerticesDouble, true);
  541. if ( isCoplanar )
  542. {
  543. Island *isl = mIslands[i];
  544. isl->mCoplanar = true;
  545. cp_count++;
  546. }
  547. else
  548. {
  549. npc_count++;
  550. }
  551. }
  552. else
  553. {
  554. assert(0);
  555. }
  556. }
  557. if ( cp_count )
  558. {
  559. if ( npc_count == 0 ) // all islands are co-planar!
  560. {
  561. IslandVector temp = mIslands;
  562. mIslands.clear();
  563. Island *isl = mIslands[0];
  564. mIslands.pushBack(isl);
  565. for (NxU32 i=1; i<cp_count; i++)
  566. {
  567. Island *_i = mIslands[i];
  568. isl->merge(*_i);
  569. delete _i;
  570. }
  571. }
  572. else
  573. {
  574. Triangle *t = mTriangles;
  575. for (NxU32 i=0; i<mTcount; i++)
  576. {
  577. t->buildBox(mVerticesFloat,mVerticesDouble,i);
  578. t++;
  579. }
  580. IslandVector::Iterator i;
  581. for (i=mIslands.begin(); i!=mIslands.end(); ++i)
  582. {
  583. Island *isl = (*i);
  584. NxU32 color = 0x00FF00;
  585. if ( isl->mCoplanar )
  586. {
  587. color = 0xFFFF00;
  588. }
  589. mergeTouching(isl);
  590. }
  591. IslandVector temp = mIslands;
  592. mIslands.clear();
  593. for (i=temp.begin(); i!=temp.end(); i++)
  594. {
  595. Island *isl = (*i);
  596. if ( isl->mCoplanar )
  597. {
  598. delete isl; // kill it
  599. }
  600. else
  601. {
  602. mIslands.pushBack(isl);
  603. }
  604. }
  605. ret = (NxU32)mIslands.size();
  606. }
  607. }
  608. else
  609. {
  610. ret = npc_count;
  611. }
  612. }
  613. return ret;
  614. }
  615. NxU32 mergeTouchingIslands(const NxF32 *vertices)
  616. {
  617. NxU32 ret = 0;
  618. return ret;
  619. }
  620. NxU32 mergeTouchingIslands(const NxF64 *vertices)
  621. {
  622. NxU32 ret = 0;
  623. return ret;
  624. }
  625. NxU32 mTcount;
  626. Triangle *mTriangles;
  627. Edge *mEdges;
  628. EdgeHashMap mTriangleEdges;
  629. IslandVector mIslands;
  630. EdgeCheckQueue mEdgeCheckQueue;
  631. const NxF64 *mVerticesDouble;
  632. const NxF32 *mVerticesFloat;
  633. NxU32Vector mIndices;
  634. };
  635. MeshIslandGeneration * createMeshIslandGeneration(void)
  636. {
  637. MyMeshIslandGeneration *mig = new MyMeshIslandGeneration;
  638. return static_cast< MeshIslandGeneration *>(mig);
  639. }
  640. void releaseMeshIslandGeneration(MeshIslandGeneration *cm)
  641. {
  642. MyMeshIslandGeneration *mig = static_cast< MyMeshIslandGeneration *>(cm);
  643. delete mig;
  644. }
  645. }; // end of namespace