sphere.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Recursively subdivide a triangle mesh to produce a sphere
  4. //
  5. //////////////////////////////////////////////////////////////////////////////
  6. typedef WORD Index;
  7. class Edge {
  8. public:
  9. Index v0;
  10. Index v1;
  11. Edge() {};
  12. Edge(Index v0In, Index v1In) :
  13. v0(v0In),
  14. v1(v1In)
  15. {
  16. }
  17. Edge(const Edge& edge) :
  18. v0(edge.v0),
  19. v1(edge.v1)
  20. {
  21. }
  22. };
  23. class Triangle {
  24. public:
  25. Index edge[3];
  26. Triangle() {};
  27. Triangle(Index e0, Index e1, Index e2)
  28. {
  29. edge[0] = e0;
  30. edge[1] = e1;
  31. edge[2] = e2;
  32. }
  33. Triangle(const Triangle& triangle)
  34. {
  35. edge[0] = triangle.edge[0];
  36. edge[1] = triangle.edge[1];
  37. edge[2] = triangle.edge[2];
  38. }
  39. };
  40. class TriangleMesh : public IObject {
  41. private:
  42. TVector<Vector> m_positions;
  43. TVector<Edge> m_edges;
  44. TVector<Triangle> m_triangles;
  45. public:
  46. TriangleMesh(
  47. int vcount, Vector* pvector,
  48. int ecount, Edge* pedge,
  49. int tcount, Triangle* ptriangle
  50. ) :
  51. m_positions(vcount, pvector, false),
  52. m_edges(ecount, pedge, false),
  53. m_triangles(tcount, ptriangle, false)
  54. {
  55. }
  56. TriangleMesh(
  57. const TVector<Vector>& positions,
  58. const TVector<Edge>& edges,
  59. const TVector<Triangle>& triangles
  60. ) :
  61. m_positions(positions),
  62. m_edges(edges),
  63. m_triangles(triangles)
  64. {
  65. }
  66. static TRef<TriangleMesh> SubdivideSphere(TriangleMesh* pmesh)
  67. {
  68. int pcount = pmesh->m_positions.GetCount();
  69. int ecount = pmesh->m_edges.GetCount();
  70. int tcount = pmesh->m_triangles.GetCount();
  71. int m = 4;
  72. TVector<Vector> positions(pcount + ecount);
  73. TVector<Edge> edges(ecount * 2 + tcount * 3);
  74. TVector<Triangle> triangles(tcount * m);
  75. //
  76. // Copy the old positions
  77. //
  78. for (int iposition = 0; iposition < pcount; iposition++) {
  79. positions.Set(iposition, pmesh->m_positions[iposition]);
  80. }
  81. //
  82. // Subdivide each edge
  83. //
  84. for (int iedge = 0; iedge < ecount; iedge++) {
  85. const Edge& edge = pmesh->m_edges[iedge];
  86. positions.Set(
  87. pcount + iedge,
  88. (pmesh->m_positions[edge.v0] + pmesh->m_positions[edge.v1]).Normalize()
  89. );
  90. edges.Set(iedge, Edge(edge.v0, pcount + iedge));
  91. edges.Set(iedge + ecount, Edge(pcount + iedge, edge.v1 ));
  92. }
  93. //
  94. // Subdivide the triangles
  95. //
  96. for (int itriangle = 0; itriangle < tcount; itriangle++) {
  97. const Triangle& triangle = pmesh->m_triangles[itriangle];
  98. Index a = triangle.edge[0];
  99. Index b = triangle.edge[1];
  100. Index c = triangle.edge[2];
  101. //
  102. // add three new edges
  103. //
  104. Index ab = ecount * 2 + itriangle * 3 + 0;
  105. Index bc = ecount * 2 + itriangle * 3 + 1;
  106. Index ca = ecount * 2 + itriangle * 3 + 2;
  107. edges.Set(ab, Edge(pcount + a, pcount + b));
  108. edges.Set(bc, Edge(pcount + b, pcount + c));
  109. edges.Set(ca, Edge(pcount + c, pcount + a));
  110. //
  111. // store 4 triangles
  112. //
  113. Index a0 = pmesh->m_edges[a].v0;
  114. Index a1 = pmesh->m_edges[a].v1;
  115. Index b0 = pmesh->m_edges[b].v0;
  116. Index b1 = pmesh->m_edges[b].v1;
  117. Index c0 = pmesh->m_edges[c].v0;
  118. Index c1 = pmesh->m_edges[c].v1;
  119. if (a0 == b0) {
  120. triangles.Set(itriangle * m + 0, Triangle(a, b, ab));
  121. if (a1 == c0) {
  122. triangles.Set(itriangle * 4 + 1, Triangle(a + ecount, c, ca));
  123. triangles.Set(itriangle * 4 + 2, Triangle(b + ecount, c + ecount, ab));
  124. } else {
  125. triangles.Set(itriangle * 4 + 1, Triangle(a + ecount, c + ecount, ca));
  126. triangles.Set(itriangle * 4 + 2, Triangle(b + ecount, c, ab));
  127. }
  128. } else if (a0 == b1) {
  129. triangles.Set(itriangle * m + 0, Triangle(a, b + ecount, ab));
  130. if (a1 == c0) {
  131. triangles.Set(itriangle * 4 + 1, Triangle(a + ecount, c, ca));
  132. triangles.Set(itriangle * 4 + 2, Triangle(b, c + ecount, ab));
  133. } else {
  134. triangles.Set(itriangle * 4 + 1, Triangle(a + ecount, c + ecount, ca));
  135. triangles.Set(itriangle * 4 + 2, Triangle(b, c, ab));
  136. }
  137. } else if (a0 == c0) {
  138. triangles.Set(itriangle * m + 0, Triangle(a, c, ca));
  139. if (a1 == b0) {
  140. triangles.Set(itriangle * 4 + 1, Triangle(a + ecount, b, ab));
  141. triangles.Set(itriangle * 4 + 2, Triangle(c + ecount, b + ecount, bc));
  142. } else {
  143. triangles.Set(itriangle * 4 + 1, Triangle(a + ecount, b + ecount, ab));
  144. triangles.Set(itriangle * 4 + 2, Triangle(c + ecount, b, bc));
  145. }
  146. } else {
  147. ZAssert(a0 == c1);
  148. triangles.Set(itriangle * m + 0, Triangle(a, c + ecount, ca));
  149. if (a1 == b0) {
  150. triangles.Set(itriangle * 4 + 1, Triangle(a + ecount, b, ab));
  151. triangles.Set(itriangle * 4 + 2, Triangle(c, b + ecount, bc));
  152. } else {
  153. triangles.Set(itriangle * 4 + 1, Triangle(a + ecount, b + ecount, ab));
  154. triangles.Set(itriangle * 4 + 2, Triangle(c, b, bc));
  155. }
  156. }
  157. triangles.Set(itriangle * m + 3, Triangle(ab, bc, ca));
  158. }
  159. //
  160. // Create the new Mesh
  161. //
  162. return new TriangleMesh(positions, edges, triangles);
  163. }
  164. TRef<Geo> ConvertToMeshGeo()
  165. {
  166. int vcount = m_positions.GetCount();
  167. int tcount = m_triangles.GetCount();
  168. TVector<Vertex> vertices(vcount);
  169. TVector<WORD> indices(tcount * 3);
  170. int index;
  171. for (index = 0; index < vcount; index++) {
  172. vertices.Get(index).SetPosition(m_positions[index]);
  173. vertices.Get(index).SetNormal(m_positions[index]);
  174. vertices.Get(index).u = 0;
  175. vertices.Get(index).v = 0;
  176. }
  177. for (index = 0; index < tcount; index++) {
  178. Index i00 = m_edges[m_triangles[index].edge[0]].v0;
  179. Index i01 = m_edges[m_triangles[index].edge[0]].v1;
  180. Index i10 = m_edges[m_triangles[index].edge[1]].v0;
  181. Index i11 = m_edges[m_triangles[index].edge[1]].v1;
  182. if (i00 == i10 || i00 == i11) {
  183. indices.Get(index * 3 + 0) = i01;
  184. indices.Get(index * 3 + 1) = i00;
  185. if (i10 == i00) {
  186. indices.Get(index * 3 + 2) = i11;
  187. } else {
  188. indices.Get(index * 3 + 2) = i10;
  189. }
  190. } else {
  191. indices.Get(index * 3 + 0) = i00;
  192. indices.Get(index * 3 + 1) = i01;
  193. if (i10 == i01) {
  194. indices.Get(index * 3 + 2) = i11;
  195. } else {
  196. indices.Get(index * 3 + 2) = i10;
  197. }
  198. }
  199. }
  200. return Geo::CreateMesh(vertices, indices);
  201. }
  202. static TRef<TriangleMesh> CreateIcosahedron()
  203. {
  204. const float s = 0.5256f;
  205. const float b = 0.8506f;
  206. Vector positions[12] =
  207. {
  208. Vector(0.0f, -s, -b),
  209. Vector(0.0f, s, -b),
  210. Vector(0.0f, s, b),
  211. Vector(0.0f, -s, b),
  212. Vector( -b, 0.0f, -s),
  213. Vector( -b, 0.0f, s),
  214. Vector( b, 0.0f, s),
  215. Vector( b, 0.0f, -s),
  216. Vector( -s, -b, 0.0f),
  217. Vector( s, -b, 0.0f),
  218. Vector( s, b, 0.0f),
  219. Vector( -s, b, 0.0f)
  220. };
  221. Edge edges[30] =
  222. {
  223. Edge( 0, 1), // (x = 0 && z < 0)
  224. Edge( 2, 3), // (x = 0 && z > 0)
  225. Edge( 4, 5), // (y = 0 && x < 0)
  226. Edge( 6, 7), // (y = 0 && x > 0)
  227. Edge( 8, 9), // (z = 0 && y < 0)
  228. Edge(10, 11), // (z = 0 && y > 0)
  229. Edge( 1, 4), // (x = 0 && z < 0) to (y = 0 && x < 0)
  230. Edge( 4, 0),
  231. Edge( 0, 7), // (x = 0 && z < 0) to (y = 0 && x > 0)
  232. Edge( 7, 1),
  233. Edge( 3, 5), // (x = 0 && z > 0) to (y = 0 && x < 0)
  234. Edge( 5, 2),
  235. Edge( 2, 6), // (x = 0 && z > 0) to (y = 0 && x > 0)
  236. Edge( 6, 3),
  237. Edge( 5, 8), // (y = 0 && x < 0) to (z = 0 && y < 0)
  238. Edge( 8, 4),
  239. Edge( 4, 11), // (y = 0 && x < 0) to (z = 0 && y > 0)
  240. Edge(11, 5),
  241. Edge( 7, 9), // (y = 0 && x > 0) to (z = 0 && y < 0)
  242. Edge( 9, 6),
  243. Edge( 6, 10), // (y = 0 && x > 0) to (z = 0 && y > 0)
  244. Edge(10, 7),
  245. Edge( 9, 0), // (z = 0 && y < 0) to (x = 0 && z < 0)
  246. Edge( 0, 8),
  247. Edge( 8, 3), // (z = 0 && y < 0) to (x = 0 && z > 0)
  248. Edge( 3, 9),
  249. Edge(11, 1), // (z = 0 && y > 0) to (x = 0 && z < 0)
  250. Edge( 1, 10),
  251. Edge(10, 2), // (z = 0 && y > 0) to (x = 0 && z > 0)
  252. Edge( 2, 11)
  253. };
  254. Triangle triangles[20] =
  255. {
  256. Triangle( 0, 6, 7), // connect two planes
  257. Triangle( 0, 8, 9),
  258. Triangle( 1, 10, 11),
  259. Triangle( 1, 12, 13),
  260. Triangle( 2, 14, 15),
  261. Triangle( 2, 16, 17),
  262. Triangle( 3, 18, 19),
  263. Triangle( 3, 20, 21),
  264. Triangle( 4, 22, 23),
  265. Triangle( 4, 24, 25),
  266. Triangle( 5, 26, 27),
  267. Triangle( 5, 28, 29),
  268. Triangle(26, 16, 6), // connect three planes
  269. Triangle(17, 29, 11),
  270. Triangle(15, 23, 7),
  271. Triangle(24, 14, 10),
  272. Triangle(22, 18, 8),
  273. Triangle(19, 25, 13),
  274. Triangle(21, 27, 9),
  275. Triangle(28, 20, 12)
  276. };
  277. return new TriangleMesh(12, positions, 30, edges, 20, triangles);
  278. }
  279. };
  280. //////////////////////////////////////////////////////////////////////////////
  281. //
  282. //
  283. //
  284. //////////////////////////////////////////////////////////////////////////////
  285. TRef<Geo> MakeSphere(int level)
  286. {
  287. TRef<TriangleMesh> pmesh = TriangleMesh::CreateIcosahedron();
  288. for (int index = 0; index < level; index++) {
  289. pmesh = TriangleMesh::SubdivideSphere(pmesh);
  290. }
  291. return pmesh->ConvertToMeshGeo();
  292. }