NvSplitMesh.cpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. /*
  2. NvSplitMesh.cpp : A code snippet to split a mesh into two seperate meshes based on a slicing plane.
  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. #define SHOW_DEBUG 0
  50. #if SHOW_DEBUG
  51. #include "RenderDebug.h"
  52. #endif
  53. #include "NvSplitMesh.h"
  54. #include "NvFloatMath.h"
  55. #include "NvHashMap.h"
  56. #pragma warning(disable:4100)
  57. namespace CONVEX_DECOMPOSITION
  58. {
  59. typedef Array< NxU32 > NxU32Array;
  60. class SplitMesh : public iSplitMesh, public Memalloc
  61. {
  62. public:
  63. SplitMesh(void)
  64. {
  65. mLeftVertices = 0;
  66. mRightVertices = 0;
  67. }
  68. ~SplitMesh(void)
  69. {
  70. reset();
  71. }
  72. void reset(void)
  73. {
  74. if ( mLeftVertices )
  75. {
  76. fm_releaseVertexIndex(mLeftVertices);
  77. mLeftVertices = 0;
  78. }
  79. if ( mRightVertices )
  80. {
  81. fm_releaseVertexIndex(mRightVertices);
  82. mRightVertices = 0;
  83. }
  84. mLeftIndices.clear();
  85. mRightIndices.clear();
  86. }
  87. virtual void splitMesh(const NvSplitMesh &source,NvSplitMesh &leftMesh,NvSplitMesh &rightMesh,const NxF32 *planeEquation,NxF32 precision)
  88. {
  89. reset();
  90. mLeftVertices = fm_createVertexIndex(precision,false);
  91. mRightVertices = fm_createVertexIndex(precision,false);
  92. for (NxU32 i=0; i<source.mTcount; i++)
  93. {
  94. NxU32 i1 = source.mIndices[i*3+0];
  95. NxU32 i2 = source.mIndices[i*3+1];
  96. NxU32 i3 = source.mIndices[i*3+2];
  97. const NxF32 *p1 = &source.mVertices[i1*3];
  98. const NxF32 *p2 = &source.mVertices[i2*3];
  99. const NxF32 *p3 = &source.mVertices[i3*3];
  100. NxF32 source_tri[3*3];
  101. source_tri[0] = p1[0];
  102. source_tri[1] = p1[1];
  103. source_tri[2] = p1[2];
  104. source_tri[3] = p2[0];
  105. source_tri[4] = p2[1];
  106. source_tri[5] = p2[2];
  107. source_tri[6] = p3[0];
  108. source_tri[7] = p3[1];
  109. source_tri[8] = p3[2];
  110. NxF32 front_tri[3*5];
  111. NxF32 back_tri[3*5];
  112. NxU32 fcount,bcount;
  113. fm_planeTriIntersection(planeEquation,source_tri,sizeof(NxF32)*3,0.000001f,front_tri,fcount,back_tri,bcount);
  114. bool newPos;
  115. if ( fcount )
  116. {
  117. NxU32 i1,i2,i3,i4;
  118. i1 = mLeftVertices->getIndex( &front_tri[0],newPos );
  119. i2 = mLeftVertices->getIndex( &front_tri[3],newPos );
  120. i3 = mLeftVertices->getIndex( &front_tri[6],newPos );
  121. mLeftIndices.pushBack(i1);
  122. mLeftIndices.pushBack(i2);
  123. mLeftIndices.pushBack(i3);
  124. #if SHOW_DEBUG
  125. NVSHARE::gRenderDebug->setCurrentColor(0xFFFFFF);
  126. NVSHARE::gRenderDebug->DebugTri(&front_tri[0],&front_tri[3],&front_tri[6]);
  127. #endif
  128. if ( fcount == 4 )
  129. {
  130. i4 = mLeftVertices->getIndex( &front_tri[9],newPos );
  131. mLeftIndices.pushBack(i1);
  132. mLeftIndices.pushBack(i3);
  133. mLeftIndices.pushBack(i4);
  134. #if SHOW_DEBUG
  135. NVSHARE::gRenderDebug->setCurrentColor(0xFFFF00);
  136. NVSHARE::gRenderDebug->DebugTri(&front_tri[0],&front_tri[6],&front_tri[9]);
  137. #endif
  138. }
  139. }
  140. if ( bcount )
  141. {
  142. NxU32 i1,i2,i3,i4;
  143. i1 = mRightVertices->getIndex( &back_tri[0],newPos );
  144. i2 = mRightVertices->getIndex( &back_tri[3],newPos );
  145. i3 = mRightVertices->getIndex( &back_tri[6],newPos );
  146. mRightIndices.pushBack(i1);
  147. mRightIndices.pushBack(i2);
  148. mRightIndices.pushBack(i3);
  149. #if SHOW_DEBUG
  150. NVSHARE::gRenderDebug->setCurrentColor(0xFF8080);
  151. NVSHARE::gRenderDebug->DebugTri(&back_tri[0],&back_tri[3],&back_tri[6]);
  152. #endif
  153. if ( bcount == 4 )
  154. {
  155. i4 = mRightVertices->getIndex( &back_tri[9],newPos );
  156. mRightIndices.pushBack(i1);
  157. mRightIndices.pushBack(i3);
  158. mRightIndices.pushBack(i4);
  159. #if SHOW_DEBUG
  160. NVSHARE::gRenderDebug->setCurrentColor(0x00FF00);
  161. NVSHARE::gRenderDebug->DebugTri(&back_tri[0],&back_tri[6],&back_tri[9]);
  162. #endif
  163. }
  164. }
  165. }
  166. leftMesh.mVcount = mLeftVertices->getVcount();
  167. leftMesh.mVertices = mLeftVertices->getVerticesFloat();
  168. leftMesh.mTcount = mLeftIndices.size()/3;
  169. leftMesh.mIndices = &mLeftIndices[0];
  170. rightMesh.mVcount = mRightVertices->getVcount();
  171. rightMesh.mVertices = mRightVertices->getVerticesFloat();
  172. rightMesh.mTcount = mRightIndices.size()/3;
  173. rightMesh.mIndices = &mRightIndices[0];
  174. }
  175. fm_VertexIndex *mLeftVertices;
  176. fm_VertexIndex *mRightVertices;
  177. NxU32Array mLeftIndices;
  178. NxU32Array mRightIndices;
  179. };
  180. iSplitMesh *createSplitMesh(void)
  181. {
  182. SplitMesh *sm = MEMALLOC_NEW(SplitMesh);
  183. return static_cast< iSplitMesh *>(sm);
  184. }
  185. void releaseSplitMesh(iSplitMesh *splitMesh)
  186. {
  187. SplitMesh *sm = static_cast< SplitMesh *>(splitMesh);
  188. delete sm;
  189. }
  190. }; // end of namespace