sphereMesh.cpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #include "math/util/sphereMesh.h"
  23. SphereMesh::SphereMesh(U32 baseType)
  24. {
  25. VECTOR_SET_ASSOCIATION(mDetails);
  26. switch(baseType)
  27. {
  28. case Tetrahedron:
  29. mDetails.push_back(createTetrahedron());
  30. break;
  31. case Octahedron:
  32. mDetails.push_back(createOctahedron());
  33. break;
  34. case Icosahedron:
  35. mDetails.push_back(createIcosahedron());
  36. break;
  37. }
  38. calcNormals(mDetails[0]);
  39. }
  40. //------------------------------------------------------------------------------
  41. SphereMesh::TriangleMesh * SphereMesh::createTetrahedron()
  42. {
  43. const F32 sqrt3 = 0.5773502692f;
  44. static Point3F spherePnts[] = {
  45. Point3F( sqrt3, sqrt3, sqrt3 ),
  46. Point3F(-sqrt3,-sqrt3, sqrt3 ),
  47. Point3F(-sqrt3, sqrt3,-sqrt3 ),
  48. Point3F( sqrt3,-sqrt3,-sqrt3 )
  49. };
  50. static Triangle tetrahedron[] = {
  51. Triangle(spherePnts[0], spherePnts[1], spherePnts[2]),
  52. Triangle(spherePnts[0], spherePnts[3], spherePnts[1]),
  53. Triangle(spherePnts[2], spherePnts[1], spherePnts[3]),
  54. Triangle(spherePnts[3], spherePnts[0], spherePnts[2]),
  55. };
  56. static TriangleMesh tetrahedronMesh = {
  57. Tetrahedron,
  58. &tetrahedron[0]
  59. };
  60. return(&tetrahedronMesh);
  61. }
  62. //------------------------------------------------------------------------------
  63. SphereMesh::TriangleMesh * SphereMesh::createOctahedron()
  64. {
  65. //
  66. static Point3F spherePnts[] = {
  67. Point3F( 1, 0, 0),
  68. Point3F(-1, 0, 0),
  69. Point3F( 0, 1, 0),
  70. Point3F( 0,-1, 0),
  71. Point3F( 0, 0, 1),
  72. Point3F( 0, 0,-1)
  73. };
  74. //
  75. static Triangle octahedron[] = {
  76. Triangle(spherePnts[0], spherePnts[4], spherePnts[2]),
  77. Triangle(spherePnts[2], spherePnts[4], spherePnts[1]),
  78. Triangle(spherePnts[1], spherePnts[4], spherePnts[3]),
  79. Triangle(spherePnts[3], spherePnts[4], spherePnts[0]),
  80. Triangle(spherePnts[0], spherePnts[2], spherePnts[5]),
  81. Triangle(spherePnts[2], spherePnts[1], spherePnts[5]),
  82. Triangle(spherePnts[1], spherePnts[3], spherePnts[5]),
  83. Triangle(spherePnts[3], spherePnts[0], spherePnts[5])
  84. };
  85. //
  86. static TriangleMesh octahedronMesh = {
  87. Octahedron,
  88. &octahedron[0]
  89. };
  90. return(&octahedronMesh);
  91. }
  92. SphereMesh::TriangleMesh * SphereMesh::createIcosahedron()
  93. {
  94. const F32 tau = 0.8506508084f;
  95. const F32 one = 0.5257311121f;
  96. static Point3F spherePnts[] = {
  97. Point3F( tau, one, 0),
  98. Point3F(-tau, one, 0),
  99. Point3F(-tau,-one, 0),
  100. Point3F( tau,-one, 0),
  101. Point3F( one, 0, tau),
  102. Point3F( one, 0,-tau),
  103. Point3F(-one, 0,-tau),
  104. Point3F(-one, 0, tau),
  105. Point3F( 0, tau, one),
  106. Point3F( 0,-tau, one),
  107. Point3F( 0,-tau,-one),
  108. Point3F( 0, tau,-one),
  109. };
  110. static Triangle icosahedron[] = {
  111. Triangle(spherePnts[4], spherePnts[8], spherePnts[7]),
  112. Triangle(spherePnts[4], spherePnts[7], spherePnts[9]),
  113. Triangle(spherePnts[5], spherePnts[6], spherePnts[11]),
  114. Triangle(spherePnts[5], spherePnts[10], spherePnts[6]),
  115. Triangle(spherePnts[0], spherePnts[4], spherePnts[3]),
  116. Triangle(spherePnts[0], spherePnts[3], spherePnts[5]),
  117. Triangle(spherePnts[2], spherePnts[7], spherePnts[1]),
  118. Triangle(spherePnts[2], spherePnts[1], spherePnts[6]),
  119. Triangle(spherePnts[8], spherePnts[0], spherePnts[11]),
  120. Triangle(spherePnts[8], spherePnts[11], spherePnts[1]),
  121. Triangle(spherePnts[9], spherePnts[10], spherePnts[3]),
  122. Triangle(spherePnts[9], spherePnts[2], spherePnts[10]),
  123. Triangle(spherePnts[8], spherePnts[4], spherePnts[0]),
  124. Triangle(spherePnts[11], spherePnts[0], spherePnts[5]),
  125. Triangle(spherePnts[4], spherePnts[9], spherePnts[3]),
  126. Triangle(spherePnts[5], spherePnts[3], spherePnts[10]),
  127. Triangle(spherePnts[7], spherePnts[8], spherePnts[1]),
  128. Triangle(spherePnts[6], spherePnts[1], spherePnts[11]),
  129. Triangle(spherePnts[7], spherePnts[2], spherePnts[9]),
  130. Triangle(spherePnts[6], spherePnts[10], spherePnts[2]),
  131. };
  132. static TriangleMesh icosahedronMesh = {
  133. Icosahedron,
  134. &icosahedron[0]
  135. };
  136. return(&icosahedronMesh);
  137. }
  138. //------------------------------------------------------------------------------
  139. void SphereMesh::calcNormals(TriangleMesh * mesh)
  140. {
  141. for(U32 i = 0; i < mesh->numPoly; i++)
  142. {
  143. Triangle & tri = mesh->poly[i];
  144. mCross(tri.pnt[1] - tri.pnt[0], tri.pnt[2] - tri.pnt[0], &tri.normal);
  145. }
  146. }
  147. //------------------------------------------------------------------------------
  148. SphereMesh::~SphereMesh()
  149. {
  150. // level 0 is static data
  151. for(U32 i = 1; i < mDetails.size(); i++)
  152. {
  153. delete [] mDetails[i]->poly;
  154. delete mDetails[i];
  155. }
  156. }
  157. //------------------------------------------------------------------------------
  158. const SphereMesh::TriangleMesh * SphereMesh::getMesh(U32 level)
  159. {
  160. AssertFatal(mDetails.size(), "SphereMesh::getMesh: no details!");
  161. if(level > MaxLevel)
  162. level = MaxLevel;
  163. //
  164. while(mDetails.size() <= level)
  165. mDetails.push_back(subdivideMesh(mDetails.last()));
  166. return(mDetails[level]);
  167. }
  168. SphereMesh::TriangleMesh * SphereMesh::subdivideMesh(TriangleMesh * prevMesh)
  169. {
  170. AssertFatal(prevMesh, "SphereMesh::subdivideMesh: invalid previous mesh level!");
  171. //
  172. TriangleMesh * mesh = new TriangleMesh;
  173. mesh->numPoly = prevMesh->numPoly * 4;
  174. mesh->poly = new Triangle [mesh->numPoly];
  175. //
  176. for(U32 i = 0; i < prevMesh->numPoly; i++)
  177. {
  178. Triangle * pt = &prevMesh->poly[i];
  179. Triangle * nt = &mesh->poly[i*4];
  180. Point3F a = (pt->pnt[0] + pt->pnt[2]) / 2;
  181. Point3F b = (pt->pnt[0] + pt->pnt[1]) / 2;
  182. Point3F c = (pt->pnt[1] + pt->pnt[2]) / 2;
  183. // force the point onto the unit sphere surface
  184. a.normalize();
  185. b.normalize();
  186. c.normalize();
  187. //
  188. nt->pnt[0] = pt->pnt[0];
  189. nt->pnt[1] = b;
  190. nt->pnt[2] = a;
  191. nt++;
  192. //
  193. nt->pnt[0] = b;
  194. nt->pnt[1] = pt->pnt[1];
  195. nt->pnt[2] = c;
  196. nt++;
  197. //
  198. nt->pnt[0] = a;
  199. nt->pnt[1] = b;
  200. nt->pnt[2] = c;
  201. nt++;
  202. //
  203. nt->pnt[0] = a;
  204. nt->pnt[1] = c;
  205. nt->pnt[2] = pt->pnt[2];
  206. }
  207. calcNormals(mesh);
  208. return(mesh);
  209. }