💿🐜 Antkeeper source code https://antkeeper.com
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

949 lines
34 KiB

7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
  1. #include "terrain.hpp"
  2. Terrain::Terrain()
  3. {
  4. surfaceOctree = nullptr;
  5. }
  6. Terrain::~Terrain()
  7. {
  8. delete surfaceOctree;
  9. }
  10. void Terrain::create(int columns, int rows, const Vector3& dimensions)
  11. {
  12. this->columns = columns;
  13. this->rows = rows;
  14. this->dimensions = dimensions;
  15. createSurface();
  16. createSubsurface();
  17. }
  18. void Terrain::createSurface()
  19. {
  20. surfaceVertexSize = 3 + 3 + 2;
  21. surfaceVertexCount = (columns + 1) * (rows + 1);
  22. surfaceTriangleCount = columns * rows * 2;
  23. surfaceIndexCount = surfaceTriangleCount * 3;
  24. surfaceVertexData = new float[surfaceVertexSize * surfaceVertexCount];
  25. surfaceIndexData = new std::uint32_t[surfaceIndexCount];
  26. surfaceVertices.resize(surfaceVertexCount);
  27. surfaceIndices.resize(surfaceIndexCount);
  28. // Calculate scale and offset
  29. Vector2 scale(dimensions.x / (float)columns, dimensions.z / (float)rows);
  30. Vector2 offset(dimensions.x * -0.5f, dimensions.z * -0.5f);
  31. // Calculate vertex positions
  32. for (int i = 0; i <= rows; ++i)
  33. {
  34. for (int j = 0; j <= columns; ++j)
  35. {
  36. std::size_t index = i * (columns + 1) + j;
  37. Vector3* vertex = &surfaceVertices[index];
  38. vertex->x = (float)j * scale.x + offset.x;
  39. vertex->y = 0.0f;
  40. vertex->z = (float)i * scale.y + offset.y;
  41. float* data = &surfaceVertexData[index * surfaceVertexSize];
  42. *(data++) = vertex->x;
  43. *(data++) = vertex->y;
  44. *(data++) = vertex->z;
  45. *(data++) = 0.0f;
  46. *(data++) = 1.0f;
  47. *(data++) = 0.0f;
  48. *(data++) = static_cast<float>(j) / static_cast<float>(columns) * 2.0f;
  49. *(data++) = static_cast<float>(i) / static_cast<float>(rows) * 2.0f;
  50. }
  51. }
  52. // Generate indices
  53. for (int i = 0; i < rows; ++i)
  54. {
  55. for (int j = 0; j < columns; ++j)
  56. {
  57. unsigned int a = i * (columns + 1) + j;
  58. unsigned int b = (i + 1) * (columns + 1) + j;
  59. unsigned int c = i * (columns + 1) + j + 1;
  60. unsigned int d = (i + 1) * (columns + 1) + j + 1;
  61. std::size_t index = (i * columns + j) * 2 * 3;
  62. surfaceIndices[index++] = a;
  63. surfaceIndices[index++] = b;
  64. surfaceIndices[index++] = c;
  65. surfaceIndices[index++] = c;
  66. surfaceIndices[index++] = b;
  67. surfaceIndices[index] = d;
  68. }
  69. }
  70. // Generate index data
  71. for (std::size_t i = 0; i < surfaceIndexCount; ++i)
  72. {
  73. surfaceIndexData[i] = surfaceIndices[i];
  74. }
  75. // Generate navmesh
  76. surfaceNavmesh.create(surfaceVertices, surfaceIndices);
  77. // Calculate vertex normals
  78. calculateSurfaceNormals();
  79. // Create and load VAO, VBO, and IBO
  80. glGenVertexArrays(1, &surfaceVAO);
  81. glBindVertexArray(surfaceVAO);
  82. glGenBuffers(1, &surfaceVBO);
  83. glBindBuffer(GL_ARRAY_BUFFER, surfaceVBO);
  84. glBufferData(GL_ARRAY_BUFFER, sizeof(float) * surfaceVertexSize * surfaceVertexCount, surfaceVertexData, GL_STATIC_DRAW);
  85. glEnableVertexAttribArray(EMERGENT_VERTEX_POSITION);
  86. glVertexAttribPointer(EMERGENT_VERTEX_POSITION, 3, GL_FLOAT, GL_FALSE, surfaceVertexSize * sizeof(float), (char*)0 + 0 * sizeof(float));
  87. glEnableVertexAttribArray(EMERGENT_VERTEX_NORMAL);
  88. glVertexAttribPointer(EMERGENT_VERTEX_NORMAL, 3, GL_FLOAT, GL_FALSE, surfaceVertexSize * sizeof(float), (char*)0 + 3 * sizeof(float));
  89. glEnableVertexAttribArray(EMERGENT_VERTEX_TEXCOORD);
  90. glVertexAttribPointer(EMERGENT_VERTEX_TEXCOORD, 2, GL_FLOAT, GL_FALSE, surfaceVertexSize * sizeof(float), (char*)0 + 6 * sizeof(float));
  91. glGenBuffers(1, &surfaceIBO);
  92. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, surfaceIBO);
  93. glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(std::uint32_t) * surfaceIndexCount, surfaceIndexData, GL_STATIC_DRAW);
  94. // Setup material
  95. surfaceMaterial.flags = static_cast<unsigned int>(PhysicalMaterial::Flags::OBJECT);
  96. // Setup buffers
  97. surfaceModel.setVAO(surfaceVAO);
  98. surfaceModel.setVBO(surfaceVBO);
  99. surfaceModel.setIBO(surfaceIBO);
  100. // Create model group
  101. Model::Group* group = new Model::Group();
  102. group->name = "default";
  103. group->material = &surfaceMaterial;
  104. group->indexOffset = 0;
  105. group->triangleCount = surfaceTriangleCount;
  106. // Add group to the model
  107. surfaceModel.addGroup(group);
  108. // Set model bounds
  109. surfaceModel.setBounds(surfaceNavmesh.getBounds());
  110. // Calculate octree
  111. surfaceOctree = surfaceNavmesh.createOctree(5);
  112. }
  113. void Terrain::createSubsurface()
  114. {
  115. subsurfaceVertexSize = 3 + 3 + 2;
  116. subsurfaceVertexCount = (columns + 1) * 4 + (rows + 1) * 4;
  117. subsurfaceTriangleCount = columns * 4 + rows * 4 + 2;
  118. subsurfaceIndexCount = subsurfaceTriangleCount * 3;
  119. subsurfaceVertexData = new float[subsurfaceVertexSize * subsurfaceVertexCount];
  120. subsurfaceIndexData = new std::uint32_t[subsurfaceIndexCount];
  121. subsurfaceVertices.resize(subsurfaceVertexCount);
  122. subsurfaceIndices.resize(subsurfaceIndexCount);
  123. float maxDimension = dimensions.y;
  124. float textureScaleX = dimensions.x / maxDimension;
  125. float textureScaleY = dimensions.y / maxDimension;
  126. float textureScaleZ = dimensions.z / maxDimension;
  127. // Calculate floor position
  128. float subsurfaceFloor = -dimensions.y;
  129. // Calculate vertex positions
  130. Vector3* vertex = &subsurfaceVertices[0];
  131. float* data = &subsurfaceVertexData[0];
  132. // Top row
  133. for (int j = 0; j <= columns; ++j)
  134. {
  135. int i = 0;
  136. std::size_t surfaceIndex = i * (columns + 1) + j;
  137. const Vector3& surfaceVertex = surfaceVertices[surfaceIndex];
  138. float u = 1.0f - (static_cast<float>(j) / static_cast<float>(columns)) * textureScaleX;
  139. *(vertex++) = surfaceVertex;
  140. *(data++) = surfaceVertex.x;
  141. *(data++) = surfaceVertex.y;
  142. *(data++) = surfaceVertex.z;
  143. *(data++) = 0.0f;
  144. *(data++) = 0.0f;
  145. *(data++) = 1.0f;
  146. *(data++) = u;
  147. *(data++) = 0.0f;
  148. *(vertex++) = Vector3(surfaceVertex.x, subsurfaceFloor, surfaceVertex.z);
  149. *(data++) = surfaceVertex.x;
  150. *(data++) = subsurfaceFloor;
  151. *(data++) = surfaceVertex.z;
  152. *(data++) = 0.0f;
  153. *(data++) = 0.0f;
  154. *(data++) = 1.0f;
  155. *(data++) = u;
  156. *(data++) = textureScaleY;
  157. }
  158. // Bottom row
  159. for (int j = 0; j <= columns; ++j)
  160. {
  161. int i = rows;
  162. std::size_t surfaceIndex = i * (columns + 1) + j;
  163. const Vector3& surfaceVertex = surfaceVertices[surfaceIndex];
  164. float u = (static_cast<float>(j) / static_cast<float>(columns)) * textureScaleX;
  165. *(vertex++) = surfaceVertex;
  166. *(data++) = surfaceVertex.x;
  167. *(data++) = surfaceVertex.y;
  168. *(data++) = surfaceVertex.z;
  169. *(data++) = 0.0f;
  170. *(data++) = 0.0f;
  171. *(data++) = 1.0f;
  172. *(data++) = u;
  173. *(data++) = 0.0f;
  174. *(vertex++) = Vector3(surfaceVertex.x, subsurfaceFloor, surfaceVertex.z);
  175. *(data++) = surfaceVertex.x;
  176. *(data++) = subsurfaceFloor;
  177. *(data++) = surfaceVertex.z;
  178. *(data++) = 0.0f;
  179. *(data++) = 0.0f;
  180. *(data++) = 1.0f;
  181. *(data++) = u;
  182. *(data++) = textureScaleY;
  183. }
  184. // Left column
  185. for (int i = 0; i <= rows; ++i)
  186. {
  187. int j = 0;
  188. std::size_t surfaceIndex = i * (columns + 1) + j;
  189. const Vector3& surfaceVertex = surfaceVertices[surfaceIndex];
  190. float u = (static_cast<float>(i) / static_cast<float>(rows)) * textureScaleZ;
  191. *(vertex++) = surfaceVertex;
  192. *(data++) = surfaceVertex.x;
  193. *(data++) = surfaceVertex.y;
  194. *(data++) = surfaceVertex.z;
  195. *(data++) = 0.0f;
  196. *(data++) = 0.0f;
  197. *(data++) = 1.0f;
  198. *(data++) = u;
  199. *(data++) = 0.0f;
  200. *(vertex++) = Vector3(surfaceVertex.x, subsurfaceFloor, surfaceVertex.z);
  201. *(data++) = surfaceVertex.x;
  202. *(data++) = subsurfaceFloor;
  203. *(data++) = surfaceVertex.z;
  204. *(data++) = 0.0f;
  205. *(data++) = 0.0f;
  206. *(data++) = 1.0f;
  207. *(data++) = u;
  208. *(data++) = textureScaleY;
  209. }
  210. // Right column
  211. for (int i = 0; i <= rows; ++i)
  212. {
  213. int j = columns;
  214. std::size_t surfaceIndex = i * (columns + 1) + j;
  215. const Vector3& surfaceVertex = surfaceVertices[surfaceIndex];
  216. float u = 1.0f - (static_cast<float>(i) / static_cast<float>(rows)) * textureScaleZ;
  217. *(vertex++) = surfaceVertex;
  218. *(data++) = surfaceVertex.x;
  219. *(data++) = surfaceVertex.y;
  220. *(data++) = surfaceVertex.z;
  221. *(data++) = 0.0f;
  222. *(data++) = 0.0f;
  223. *(data++) = 1.0f;
  224. *(data++) = u;
  225. *(data++) = 0.0f;
  226. *(vertex++) = Vector3(surfaceVertex.x, subsurfaceFloor, surfaceVertex.z);
  227. *(data++) = surfaceVertex.x;
  228. *(data++) = subsurfaceFloor;
  229. *(data++) = surfaceVertex.z;
  230. *(data++) = 0.0f;
  231. *(data++) = 0.0f;
  232. *(data++) = 1.0f;
  233. *(data++) = u;
  234. *(data++) = textureScaleY;
  235. }
  236. // Generate indices
  237. std::size_t* index = &subsurfaceIndices[0];
  238. for (int i = 0; i < columns; ++i)
  239. {
  240. std::size_t a = i * 2;
  241. std::size_t b = i * 2 + 1;
  242. std::size_t c = (i + 1) * 2;
  243. std::size_t d = (i + 1) * 2 + 1;
  244. (*(index++)) = b;
  245. (*(index++)) = a;
  246. (*(index++)) = c;
  247. (*(index++)) = b;
  248. (*(index++)) = c;
  249. (*(index++)) = d;
  250. a += (columns + 1) * 2;
  251. b += (columns + 1) * 2;
  252. c += (columns + 1) * 2;
  253. d += (columns + 1) * 2;
  254. (*(index++)) = a;
  255. (*(index++)) = b;
  256. (*(index++)) = c;
  257. (*(index++)) = c;
  258. (*(index++)) = b;
  259. (*(index++)) = d;
  260. }
  261. for (int i = 0; i < rows; ++i)
  262. {
  263. std::size_t a = (columns + 1) * 4 + i * 2;
  264. std::size_t b = (columns + 1) * 4 + i * 2 + 1;
  265. std::size_t c = (columns + 1) * 4 + (i + 1) * 2;
  266. std::size_t d = (columns + 1) * 4 + (i + 1) * 2 + 1;
  267. (*(index++)) = a;
  268. (*(index++)) = b;
  269. (*(index++)) = c;
  270. (*(index++)) = c;
  271. (*(index++)) = b;
  272. (*(index++)) = d;
  273. a += (rows + 1) * 2;
  274. b += (rows + 1) * 2;
  275. c += (rows + 1) * 2;
  276. d += (rows + 1) * 2;
  277. (*(index++)) = b;
  278. (*(index++)) = a;
  279. (*(index++)) = c;
  280. (*(index++)) = b;
  281. (*(index++)) = c;
  282. (*(index++)) = d;
  283. }
  284. // Floor
  285. std::size_t a = 1;
  286. std::size_t b = 1 + (rows + 1) * 2;
  287. std::size_t c = columns * 2 + 1;
  288. std::size_t d = columns * 2 + 1 + (columns + 1) * 2;
  289. (*(index++)) = a;
  290. (*(index++)) = c;
  291. (*(index++)) = b;
  292. (*(index++)) = b;
  293. (*(index++)) = c;
  294. (*(index++)) = d;
  295. // Generate index data
  296. for (std::size_t i = 0; i < subsurfaceIndexCount; ++i)
  297. {
  298. subsurfaceIndexData[i] = subsurfaceIndices[i];
  299. }
  300. // Generate navmesh
  301. subsurfaceNavmesh.create(subsurfaceVertices, subsurfaceIndices);
  302. // Create and load VAO, VBO, and IBO
  303. glGenVertexArrays(1, &subsurfaceVAO);
  304. glBindVertexArray(subsurfaceVAO);
  305. glGenBuffers(1, &subsurfaceVBO);
  306. glBindBuffer(GL_ARRAY_BUFFER, subsurfaceVBO);
  307. glBufferData(GL_ARRAY_BUFFER, sizeof(float) * subsurfaceVertexSize * subsurfaceVertexCount, subsurfaceVertexData, GL_STATIC_DRAW);
  308. glEnableVertexAttribArray(EMERGENT_VERTEX_POSITION);
  309. glVertexAttribPointer(EMERGENT_VERTEX_POSITION, 3, GL_FLOAT, GL_FALSE, subsurfaceVertexSize * sizeof(float), (char*)0 + 0 * sizeof(float));
  310. glEnableVertexAttribArray(EMERGENT_VERTEX_NORMAL);
  311. glVertexAttribPointer(EMERGENT_VERTEX_NORMAL, 3, GL_FLOAT, GL_FALSE, subsurfaceVertexSize * sizeof(float), (char*)0 + 3 * sizeof(float));
  312. glEnableVertexAttribArray(EMERGENT_VERTEX_TEXCOORD);
  313. glVertexAttribPointer(EMERGENT_VERTEX_TEXCOORD, 2, GL_FLOAT, GL_FALSE, subsurfaceVertexSize * sizeof(float), (char*)0 + 6 * sizeof(float));
  314. glGenBuffers(1, &subsurfaceIBO);
  315. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, subsurfaceIBO);
  316. glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(std::uint32_t) * subsurfaceIndexCount, subsurfaceIndexData, GL_STATIC_DRAW);
  317. // Setup material
  318. subsurfaceMaterial.flags = static_cast<unsigned int>(PhysicalMaterial::Flags::SOIL);
  319. // Setup buffers
  320. subsurfaceModel.setVAO(subsurfaceVAO);
  321. subsurfaceModel.setVBO(subsurfaceVBO);
  322. subsurfaceModel.setIBO(subsurfaceIBO);
  323. // Create model group
  324. Model::Group* group = new Model::Group();
  325. group->name = "default";
  326. group->material = &subsurfaceMaterial;
  327. group->indexOffset = 0;
  328. group->triangleCount = subsurfaceTriangleCount;
  329. // Add group to the model
  330. subsurfaceModel.addGroup(group);
  331. // Set model bounds
  332. subsurfaceModel.setBounds(subsurfaceNavmesh.getBounds());
  333. }
  334. void Terrain::calculateSurfaceNormals()
  335. {
  336. for (std::size_t i = 0; i < surfaceVertexCount; ++i)
  337. {
  338. const Navmesh::Vertex* vertex = (*surfaceNavmesh.getVertices())[i];
  339. Vector3 normal(0.0f);
  340. const Navmesh::Edge* start = vertex->edge;
  341. const Navmesh::Edge* e = start;
  342. do
  343. {
  344. normal += e->triangle->normal;
  345. e = e->previous->symmetric;
  346. }
  347. while (e != start && e != nullptr);
  348. normal = glm::normalize(normal);
  349. float* data = &surfaceVertexData[i * surfaceVertexSize];
  350. data[3] = normal.x;
  351. data[4] = normal.y;
  352. data[5] = normal.z;
  353. }
  354. }
  355. bool Terrain::load(const std::string& filename)
  356. {
  357. int width;
  358. int height;
  359. int channels;
  360. stbi_set_flip_vertically_on_load(true);
  361. // Load image data
  362. unsigned char* pixels = stbi_load(filename.c_str(), &width, &height, &channels, 1);
  363. if (width != columns + 1 || height != rows + 1)
  364. {
  365. // Free loaded image data
  366. stbi_image_free(pixels);
  367. return false;
  368. }
  369. // Set surface vertex heights
  370. for (int i = 0; i <= rows; ++i)
  371. {
  372. for (int j = 0; j <= columns; ++j)
  373. {
  374. std::size_t index = i * (columns + 1) + j;
  375. float elevation = (float)pixels[index] / 255.0f * 5.0f;
  376. surfaceVertexData[index * surfaceVertexSize + 1] = elevation;
  377. surfaceVertices[index].y = elevation;
  378. (*surfaceNavmesh.getVertices())[index]->position.y = elevation;
  379. }
  380. }
  381. // Free loaded image data
  382. stbi_image_free(pixels);
  383. // Set subsurface vertex heights
  384. std::size_t subsurfaceIndex = 0;
  385. // Top row
  386. for (int j = 0; j <= columns; ++j)
  387. {
  388. int i = 0;
  389. std::size_t surfaceIndex = i * (columns + 1) + j;
  390. float elevation = surfaceVertices[surfaceIndex].y;
  391. subsurfaceVertexData[subsurfaceIndex * subsurfaceVertexSize + 1] = elevation;
  392. subsurfaceVertices[subsurfaceIndex].y = elevation;
  393. (*subsurfaceNavmesh.getVertices())[subsurfaceIndex]->position.y = elevation;
  394. subsurfaceIndex += 2;
  395. }
  396. // Bottom row
  397. for (int j = 0; j <= columns; ++j)
  398. {
  399. int i = rows;
  400. std::size_t surfaceIndex = i * (columns + 1) + j;
  401. float elevation = surfaceVertices[surfaceIndex].y;
  402. subsurfaceVertexData[subsurfaceIndex * subsurfaceVertexSize + 1] = elevation;
  403. subsurfaceVertices[subsurfaceIndex].y = elevation;
  404. (*subsurfaceNavmesh.getVertices())[subsurfaceIndex]->position.y = elevation;
  405. subsurfaceIndex += 2;
  406. }
  407. // Left column
  408. for (int i = 0; i <= rows; ++i)
  409. {
  410. int j = 0;
  411. std::size_t surfaceIndex = i * (columns + 1) + j;
  412. float elevation = surfaceVertices[surfaceIndex].y;
  413. subsurfaceVertexData[subsurfaceIndex * subsurfaceVertexSize + 1] = elevation;
  414. subsurfaceVertices[subsurfaceIndex].y = elevation;
  415. (*subsurfaceNavmesh.getVertices())[subsurfaceIndex]->position.y = elevation;
  416. subsurfaceIndex += 2;
  417. }
  418. // Right column
  419. for (int i = 0; i <= rows; ++i)
  420. {
  421. int j = columns;
  422. std::size_t surfaceIndex = i * (columns + 1) + j;
  423. float elevation = surfaceVertices[surfaceIndex].y;
  424. subsurfaceVertexData[subsurfaceIndex * subsurfaceVertexSize + 1] = elevation;
  425. subsurfaceVertices[subsurfaceIndex].y = elevation;
  426. (*subsurfaceNavmesh.getVertices())[subsurfaceIndex]->position.y = elevation;
  427. subsurfaceIndex += 2;
  428. }
  429. // Calculate navmesh normals
  430. surfaceNavmesh.calculateNormals();
  431. subsurfaceNavmesh.calculateNormals();
  432. // Calculate navmesh bounds
  433. surfaceNavmesh.calculateBounds();
  434. subsurfaceNavmesh.calculateBounds();
  435. // Calculate vertex normals
  436. calculateSurfaceNormals();
  437. // Update VBOs
  438. glBindBuffer(GL_ARRAY_BUFFER, surfaceVBO);
  439. glBufferSubData(GL_ARRAY_BUFFER, 0, surfaceVertexCount * surfaceVertexSize * sizeof(float), surfaceVertexData);
  440. glBindBuffer(GL_ARRAY_BUFFER, subsurfaceVBO);
  441. glBufferSubData(GL_ARRAY_BUFFER, 0, subsurfaceVertexCount * subsurfaceVertexSize * sizeof(float), subsurfaceVertexData);
  442. // Update bounds
  443. surfaceModel.setBounds(surfaceNavmesh.getBounds());
  444. subsurfaceModel.setBounds(subsurfaceNavmesh.getBounds());
  445. // Calculate octree
  446. delete surfaceOctree;
  447. surfaceOctree = surfaceNavmesh.createOctree(5);
  448. return true;
  449. }
  450. struct voxel
  451. {
  452. glm::vec3 vertices[8];
  453. float values[8];
  454. };
  455. // LUT to map isosurface vertices to intersecting edges
  456. static const int EDGE_TABLE[256] =
  457. {
  458. 0x000, 0x109, 0x203, 0x30a, 0x406, 0x50f, 0x605, 0x70c,
  459. 0x80c, 0x905, 0xa0f, 0xb06, 0xc0a, 0xd03, 0xe09, 0xf00,
  460. 0x190, 0x099, 0x393, 0x29a, 0x596, 0x49f, 0x795, 0x69c,
  461. 0x99c, 0x895, 0xb9f, 0xa96, 0xd9a, 0xc93, 0xf99, 0xe90,
  462. 0x230, 0x339, 0x033, 0x13a, 0x636, 0x73f, 0x435, 0x53c,
  463. 0xa3c, 0xb35, 0x83f, 0x936, 0xe3a, 0xf33, 0xc39, 0xd30,
  464. 0x3a0, 0x2a9, 0x1a3, 0x0aa, 0x7a6, 0x6af, 0x5a5, 0x4ac,
  465. 0xbac, 0xaa5, 0x9af, 0x8a6, 0xfaa, 0xea3, 0xda9, 0xca0,
  466. 0x460, 0x569, 0x663, 0x76a, 0x066, 0x16f, 0x265, 0x36c,
  467. 0xc6c, 0xd65, 0xe6f, 0xf66, 0x86a, 0x963, 0xa69, 0xb60,
  468. 0x5f0, 0x4f9, 0x7f3, 0x6fa, 0x1f6, 0x0ff, 0x3f5, 0x2fc,
  469. 0xdfc, 0xcf5, 0xfff, 0xef6, 0x9fa, 0x8f3, 0xbf9, 0xaf0,
  470. 0x650, 0x759, 0x453, 0x55a, 0x256, 0x35f, 0x055, 0x15c,
  471. 0xe5c, 0xf55, 0xc5f, 0xd56, 0xa5a, 0xb53, 0x859, 0x950,
  472. 0x7c0, 0x6c9, 0x5c3, 0x4ca, 0x3c6, 0x2cf, 0x1c5, 0x0cc,
  473. 0xfcc, 0xec5, 0xdcf, 0xcc6, 0xbca, 0xac3, 0x9c9, 0x8c0,
  474. 0x8c0, 0x9c9, 0xac3, 0xbca, 0xcc6, 0xdcf, 0xec5, 0xfcc,
  475. 0x0cc, 0x1c5, 0x2cf, 0x3c6, 0x4ca, 0x5c3, 0x6c9, 0x7c0,
  476. 0x950, 0x859, 0xb53, 0xa5a, 0xd56, 0xc5f, 0xf55, 0xe5c,
  477. 0x15c, 0x055, 0x35f, 0x256, 0x55a, 0x453, 0x759, 0x650,
  478. 0xaf0, 0xbf9, 0x8f3, 0x9fa, 0xef6, 0xfff, 0xcf5, 0xdfc,
  479. 0x2fc, 0x3f5, 0x0ff, 0x1f6, 0x6fa, 0x7f3, 0x4f9, 0x5f0,
  480. 0xb60, 0xa69, 0x963, 0x86a, 0xf66, 0xe6f, 0xd65, 0xc6c,
  481. 0x36c, 0x265, 0x16f, 0x066, 0x76a, 0x663, 0x569, 0x460,
  482. 0xca0, 0xda9, 0xea3, 0xfaa, 0x8a6, 0x9af, 0xaa5, 0xbac,
  483. 0x4ac, 0x5a5, 0x6af, 0x7a6, 0x0aa, 0x1a3, 0x2a9, 0x3a0,
  484. 0xd30, 0xc39, 0xf33, 0xe3a, 0x936, 0x83f, 0xb35, 0xa3c,
  485. 0x53c, 0x435, 0x73f, 0x636, 0x13a, 0x033, 0x339, 0x230,
  486. 0xe90, 0xf99, 0xc93, 0xd9a, 0xa96, 0xb9f, 0x895, 0x99c,
  487. 0x69c, 0x795, 0x49f, 0x596, 0x29a, 0x393, 0x099, 0x190,
  488. 0xf00, 0xe09, 0xd03, 0xc0a, 0xb06, 0xa0f, 0x905, 0x80c,
  489. 0x70c, 0x605, 0x50f, 0x406, 0x30a, 0x203, 0x109, 0x000
  490. };
  491. static const int TRIANGLE_TABLE[256][16] =
  492. {
  493. {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  494. {0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  495. {0, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  496. {1, 8, 3, 9, 8, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  497. {1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  498. {0, 8, 3, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  499. {9, 2, 10, 0, 2, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  500. {2, 8, 3, 2, 10, 8, 10, 9, 8, -1, -1, -1, -1, -1, -1, -1},
  501. {3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  502. {0, 11, 2, 8, 11, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  503. {1, 9, 0, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  504. {1, 11, 2, 1, 9, 11, 9, 8, 11, -1, -1, -1, -1, -1, -1, -1},
  505. {3, 10, 1, 11, 10, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  506. {0, 10, 1, 0, 8, 10, 8, 11, 10, -1, -1, -1, -1, -1, -1, -1},
  507. {3, 9, 0, 3, 11, 9, 11, 10, 9, -1, -1, -1, -1, -1, -1, -1},
  508. {9, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  509. {4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  510. {4, 3, 0, 7, 3, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  511. {0, 1, 9, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  512. {4, 1, 9, 4, 7, 1, 7, 3, 1, -1, -1, -1, -1, -1, -1, -1},
  513. {1, 2, 10, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  514. {3, 4, 7, 3, 0, 4, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1},
  515. {9, 2, 10, 9, 0, 2, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1},
  516. {2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4, -1, -1, -1, -1},
  517. {8, 4, 7, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  518. {11, 4, 7, 11, 2, 4, 2, 0, 4, -1, -1, -1, -1, -1, -1, -1},
  519. {9, 0, 1, 8, 4, 7, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1},
  520. {4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1, -1, -1, -1, -1},
  521. {3, 10, 1, 3, 11, 10, 7, 8, 4, -1, -1, -1, -1, -1, -1, -1},
  522. {1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4, -1, -1, -1, -1},
  523. {4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3, -1, -1, -1, -1},
  524. {4, 7, 11, 4, 11, 9, 9, 11, 10, -1, -1, -1, -1, -1, -1, -1},
  525. {9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  526. {9, 5, 4, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  527. {0, 5, 4, 1, 5, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  528. {8, 5, 4, 8, 3, 5, 3, 1, 5, -1, -1, -1, -1, -1, -1, -1},
  529. {1, 2, 10, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  530. {3, 0, 8, 1, 2, 10, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1},
  531. {5, 2, 10, 5, 4, 2, 4, 0, 2, -1, -1, -1, -1, -1, -1, -1},
  532. {2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8, -1, -1, -1, -1},
  533. {9, 5, 4, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  534. {0, 11, 2, 0, 8, 11, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1},
  535. {0, 5, 4, 0, 1, 5, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1},
  536. {2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5, -1, -1, -1, -1},
  537. {10, 3, 11, 10, 1, 3, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1},
  538. {4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11, 10, -1, -1, -1, -1},
  539. {5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3, -1, -1, -1, -1},
  540. {5, 4, 8, 5, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1},
  541. {9, 7, 8, 5, 7, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  542. {9, 3, 0, 9, 5, 3, 5, 7, 3, -1, -1, -1, -1, -1, -1, -1},
  543. {0, 7, 8, 0, 1, 7, 1, 5, 7, -1, -1, -1, -1, -1, -1, -1},
  544. {1, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  545. {9, 7, 8, 9, 5, 7, 10, 1, 2, -1, -1, -1, -1, -1, -1, -1},
  546. {10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3, -1, -1, -1, -1},
  547. {8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2, -1, -1, -1, -1},
  548. {2, 10, 5, 2, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1},
  549. {7, 9, 5, 7, 8, 9, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1},
  550. {9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11, -1, -1, -1, -1},
  551. {2, 3, 11, 0, 1, 8, 1, 7, 8, 1, 5, 7, -1, -1, -1, -1},
  552. {11, 2, 1, 11, 1, 7, 7, 1, 5, -1, -1, -1, -1, -1, -1, -1},
  553. {9, 5, 8, 8, 5, 7, 10, 1, 3, 10, 3, 11, -1, -1, -1, -1},
  554. {5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10, 11, 10, 0, -1},
  555. {11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7, 0, -1},
  556. {11, 10, 5, 7, 11, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  557. {10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  558. {0, 8, 3, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  559. {9, 0, 1, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  560. {1, 8, 3, 1, 9, 8, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1},
  561. {1, 6, 5, 2, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  562. {1, 6, 5, 1, 2, 6, 3, 0, 8, -1, -1, -1, -1, -1, -1, -1},
  563. {9, 6, 5, 9, 0, 6, 0, 2, 6, -1, -1, -1, -1, -1, -1, -1},
  564. {5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, -1, -1, -1, -1},
  565. {2, 3, 11, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  566. {11, 0, 8, 11, 2, 0, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1},
  567. {0, 1, 9, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1},
  568. {5, 10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11, -1, -1, -1, -1},
  569. {6, 3, 11, 6, 5, 3, 5, 1, 3, -1, -1, -1, -1, -1, -1, -1},
  570. {0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6, -1, -1, -1, -1},
  571. {3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9, -1, -1, -1, -1},
  572. {6, 5, 9, 6, 9, 11, 11, 9, 8, -1, -1, -1, -1, -1, -1, -1},
  573. {5, 10, 6, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  574. {4, 3, 0, 4, 7, 3, 6, 5, 10, -1, -1, -1, -1, -1, -1, -1},
  575. {1, 9, 0, 5, 10, 6, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1},
  576. {10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, -1, -1, -1, -1},
  577. {6, 1, 2, 6, 5, 1, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1},
  578. {1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7, -1, -1, -1, -1},
  579. {8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6, -1, -1, -1, -1},
  580. {7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9, -1},
  581. {3, 11, 2, 7, 8, 4, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1},
  582. {5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11, -1, -1, -1, -1},
  583. {0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1},
  584. {9, 2, 1, 9, 11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6, -1},
  585. {8, 4, 7, 3, 11, 5, 3, 5, 1, 5, 11, 6, -1, -1, -1, -1},
  586. {5, 1, 11, 5, 11, 6, 1, 0, 11, 7, 11, 4, 0, 4, 11, -1},
  587. {0, 5, 9, 0, 6, 5, 0, 3, 6, 11, 6, 3, 8, 4, 7, -1},
  588. {6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9, -1, -1, -1, -1},
  589. {10, 4, 9, 6, 4, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  590. {4, 10, 6, 4, 9, 10, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1},
  591. {10, 0, 1, 10, 6, 0, 6, 4, 0, -1, -1, -1, -1, -1, -1, -1},
  592. {8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10, -1, -1, -1, -1},
  593. {1, 4, 9, 1, 2, 4, 2, 6, 4, -1, -1, -1, -1, -1, -1, -1},
  594. {3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4, -1, -1, -1, -1},
  595. {0, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  596. {8, 3, 2, 8, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1},
  597. {10, 4, 9, 10, 6, 4, 11, 2, 3, -1, -1, -1, -1, -1, -1, -1},
  598. {0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6, -1, -1, -1, -1},
  599. {3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, 10, -1, -1, -1, -1},
  600. {6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, 8, 11, 1, -1},
  601. {9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3, -1, -1, -1, -1},
  602. {8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1, -1},
  603. {3, 11, 6, 3, 6, 0, 0, 6, 4, -1, -1, -1, -1, -1, -1, -1},
  604. {6, 4, 8, 11, 6, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  605. {7, 10, 6, 7, 8, 10, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1},
  606. {0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10, -1, -1, -1, -1},
  607. {10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0, -1, -1, -1, -1},
  608. {10, 6, 7, 10, 7, 1, 1, 7, 3, -1, -1, -1, -1, -1, -1, -1},
  609. {1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7, -1, -1, -1, -1},
  610. {2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9, -1},
  611. {7, 8, 0, 7, 0, 6, 6, 0, 2, -1, -1, -1, -1, -1, -1, -1},
  612. {7, 3, 2, 6, 7, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  613. {2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7, -1, -1, -1, -1},
  614. {2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7, -1},
  615. {1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11, -1},
  616. {11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1, -1, -1, -1, -1},
  617. {8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6, -1},
  618. {0, 9, 1, 11, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  619. {7, 8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0, -1, -1, -1, -1},
  620. {7, 11, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  621. {7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  622. {3, 0, 8, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  623. {0, 1, 9, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  624. {8, 1, 9, 8, 3, 1, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1},
  625. {10, 1, 2, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  626. {1, 2, 10, 3, 0, 8, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1},
  627. {2, 9, 0, 2, 10, 9, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1},
  628. {6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, 8, -1, -1, -1, -1},
  629. {7, 2, 3, 6, 2, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  630. {7, 0, 8, 7, 6, 0, 6, 2, 0, -1, -1, -1, -1, -1, -1, -1},
  631. {2, 7, 6, 2, 3, 7, 0, 1, 9, -1, -1, -1, -1, -1, -1, -1},
  632. {1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6, -1, -1, -1, -1},
  633. {10, 7, 6, 10, 1, 7, 1, 3, 7, -1, -1, -1, -1, -1, -1, -1},
  634. {10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8, -1, -1, -1, -1},
  635. {0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7, -1, -1, -1, -1},
  636. {7, 6, 10, 7, 10, 8, 8, 10, 9, -1, -1, -1, -1, -1, -1, -1},
  637. {6, 8, 4, 11, 8, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  638. {3, 6, 11, 3, 0, 6, 0, 4, 6, -1, -1, -1, -1, -1, -1, -1},
  639. {8, 6, 11, 8, 4, 6, 9, 0, 1, -1, -1, -1, -1, -1, -1, -1},
  640. {9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6, -1, -1, -1, -1},
  641. {6, 8, 4, 6, 11, 8, 2, 10, 1, -1, -1, -1, -1, -1, -1, -1},
  642. {1, 2, 10, 3, 0, 11, 0, 6, 11, 0, 4, 6, -1, -1, -1, -1},
  643. {4, 11, 8, 4, 6, 11, 0, 2, 9, 2, 10, 9, -1, -1, -1, -1},
  644. {10, 9, 3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3, -1},
  645. {8, 2, 3, 8, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1},
  646. {0, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  647. {1, 9, 0, 2, 3, 4, 2, 4, 6, 4, 3, 8, -1, -1, -1, -1},
  648. {1, 9, 4, 1, 4, 2, 2, 4, 6, -1, -1, -1, -1, -1, -1, -1},
  649. {8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1, -1, -1, -1, -1},
  650. {10, 1, 0, 10, 0, 6, 6, 0, 4, -1, -1, -1, -1, -1, -1, -1},
  651. {4, 6, 3, 4, 3, 8, 6, 10, 3, 0, 3, 9, 10, 9, 3, -1},
  652. {10, 9, 4, 6, 10, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  653. {4, 9, 5, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  654. {0, 8, 3, 4, 9, 5, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1},
  655. {5, 0, 1, 5, 4, 0, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1},
  656. {11, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5, -1, -1, -1, -1},
  657. {9, 5, 4, 10, 1, 2, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1},
  658. {6, 11, 7, 1, 2, 10, 0, 8, 3, 4, 9, 5, -1, -1, -1, -1},
  659. {7, 6, 11, 5, 4, 10, 4, 2, 10, 4, 0, 2, -1, -1, -1, -1},
  660. {3, 4, 8, 3, 5, 4, 3, 2, 5, 10, 5, 2, 11, 7, 6, -1},
  661. {7, 2, 3, 7, 6, 2, 5, 4, 9, -1, -1, -1, -1, -1, -1, -1},
  662. {9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7, -1, -1, -1, -1},
  663. {3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0, -1, -1, -1, -1},
  664. {6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8, -1},
  665. {9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7, -1, -1, -1, -1},
  666. {1, 6, 10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4, -1},
  667. {4, 0, 10, 4, 10, 5, 0, 3, 10, 6, 10, 7, 3, 7, 10, -1},
  668. {7, 6, 10, 7, 10, 8, 5, 4, 10, 4, 8, 10, -1, -1, -1, -1},
  669. {6, 9, 5, 6, 11, 9, 11, 8, 9, -1, -1, -1, -1, -1, -1, -1},
  670. {3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5, -1, -1, -1, -1},
  671. {0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11, -1, -1, -1, -1},
  672. {6, 11, 3, 6, 3, 5, 5, 3, 1, -1, -1, -1, -1, -1, -1, -1},
  673. {1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6, -1, -1, -1, -1},
  674. {0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10, -1},
  675. {11, 8, 5, 11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5, -1},
  676. {6, 11, 3, 6, 3, 5, 2, 10, 3, 10, 5, 3, -1, -1, -1, -1},
  677. {5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2, -1, -1, -1, -1},
  678. {9, 5, 6, 9, 6, 0, 0, 6, 2, -1, -1, -1, -1, -1, -1, -1},
  679. {1, 5, 8, 1, 8, 0, 5, 6, 8, 3, 8, 2, 6, 2, 8, -1},
  680. {1, 5, 6, 2, 1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  681. {1, 3, 6, 1, 6, 10, 3, 8, 6, 5, 6, 9, 8, 9, 6, -1},
  682. {10, 1, 0, 10, 0, 6, 9, 5, 0, 5, 6, 0, -1, -1, -1, -1},
  683. {0, 3, 8, 5, 6, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  684. {10, 5, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  685. {11, 5, 10, 7, 5, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  686. {11, 5, 10, 11, 7, 5, 8, 3, 0, -1, -1, -1, -1, -1, -1, -1},
  687. {5, 11, 7, 5, 10, 11, 1, 9, 0, -1, -1, -1, -1, -1, -1, -1},
  688. {10, 7, 5, 10, 11, 7, 9, 8, 1, 8, 3, 1, -1, -1, -1, -1},
  689. {11, 1, 2, 11, 7, 1, 7, 5, 1, -1, -1, -1, -1, -1, -1, -1},
  690. {0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 11, -1, -1, -1, -1},
  691. {9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7, -1, -1, -1, -1},
  692. {7, 5, 2, 7, 2, 11, 5, 9, 2, 3, 2, 8, 9, 8, 2, -1},
  693. {2, 5, 10, 2, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1},
  694. {8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5, -1, -1, -1, -1},
  695. {9, 0, 1, 5, 10, 3, 5, 3, 7, 3, 10, 2, -1, -1, -1, -1},
  696. {9, 8, 2, 9, 2, 1, 8, 7, 2, 10, 2, 5, 7, 5, 2, -1},
  697. {1, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  698. {0, 8, 7, 0, 7, 1, 1, 7, 5, -1, -1, -1, -1, -1, -1, -1},
  699. {9, 0, 3, 9, 3, 5, 5, 3, 7, -1, -1, -1, -1, -1, -1, -1},
  700. {9, 8, 7, 5, 9, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  701. {5, 8, 4, 5, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1},
  702. {5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0, -1, -1, -1, -1},
  703. {0, 1, 9, 8, 4, 10, 8, 10, 11, 10, 4, 5, -1, -1, -1, -1},
  704. {10, 11, 4, 10, 4, 5, 11, 3, 4, 9, 4, 1, 3, 1, 4, -1},
  705. {2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8, -1, -1, -1, -1},
  706. {0, 4, 11, 0, 11, 3, 4, 5, 11, 2, 11, 1, 5, 1, 11, -1},
  707. {0, 2, 5, 0, 5, 9, 2, 11, 5, 4, 5, 8, 11, 8, 5, -1},
  708. {9, 4, 5, 2, 11, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  709. {2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4, -1, -1, -1, -1},
  710. {5, 10, 2, 5, 2, 4, 4, 2, 0, -1, -1, -1, -1, -1, -1, -1},
  711. {3, 10, 2, 3, 5, 10, 3, 8, 5, 4, 5, 8, 0, 1, 9, -1},
  712. {5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2, -1, -1, -1, -1},
  713. {8, 4, 5, 8, 5, 3, 3, 5, 1, -1, -1, -1, -1, -1, -1, -1},
  714. {0, 4, 5, 1, 0, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  715. {8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5, -1, -1, -1, -1},
  716. {9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  717. {4, 11, 7, 4, 9, 11, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1},
  718. {0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11, -1, -1, -1, -1},
  719. {1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11, -1, -1, -1, -1},
  720. {3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4, -1},
  721. {4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2, -1, -1, -1, -1},
  722. {9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3, -1},
  723. {11, 7, 4, 11, 4, 2, 2, 4, 0, -1, -1, -1, -1, -1, -1, -1},
  724. {11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4, -1, -1, -1, -1},
  725. {2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9, -1, -1, -1, -1},
  726. {9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7, -1},
  727. {3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10, -1},
  728. {1, 10, 2, 8, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  729. {4, 9, 1, 4, 1, 7, 7, 1, 3, -1, -1, -1, -1, -1, -1, -1},
  730. {4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, -1, -1, -1, -1},
  731. {4, 0, 3, 7, 4, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  732. {4, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  733. {9, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  734. {3, 0, 9, 3, 9, 11, 11, 9, 10, -1, -1, -1, -1, -1, -1, -1},
  735. {0, 1, 10, 0, 10, 8, 8, 10, 11, -1, -1, -1, -1, -1, -1, -1},
  736. {3, 1, 10, 11, 3, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  737. {1, 2, 11, 1, 11, 9, 9, 11, 8, -1, -1, -1, -1, -1, -1, -1},
  738. {3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9, -1, -1, -1, -1},
  739. {0, 2, 11, 8, 0, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  740. {3, 2, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  741. {2, 3, 8, 2, 8, 10, 10, 8, 9, -1, -1, -1, -1, -1, -1, -1},
  742. {9, 10, 2, 0, 9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  743. {2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8, -1, -1, -1, -1},
  744. {1, 10, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  745. {1, 3, 8, 9, 1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  746. {0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  747. {0, 3, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  748. {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}
  749. };
  750. // Lookup table which contains the indices of the vertices which define an edge.
  751. static const int VERTEX_TABLE[12][2] =
  752. {
  753. {0, 1},
  754. {1, 2},
  755. {2, 3},
  756. {3, 0},
  757. {4, 5},
  758. {5, 6},
  759. {6, 7},
  760. {7, 4},
  761. {0, 4},
  762. {1, 5},
  763. {2, 6},
  764. {3, 7}
  765. };
  766. /*
  767. * The marching cubes algorithm can produce a maximum of 5 triangles per cell. Therefore the maximum triangle count of a grid is `w * h * d * 5`.
  768. */
  769. struct triangle
  770. {
  771. glm::vec3 vertices[3];
  772. };
  773. bool less_than(const glm::vec3& a, const glm::vec3& b)
  774. {
  775. if (a.x < b.x)
  776. return true;
  777. else if (a.x > b.x)
  778. return false;
  779. if (a.y < b.y)
  780. return true;
  781. else if (a.y > b.y)
  782. return false;
  783. if (a.z < b.z)
  784. return true;
  785. return false;
  786. }
  787. glm::vec3 interpolate(float isolevel, glm::vec3 p0, glm::vec3 p1, float v0, float v1)
  788. {
  789. static const float epsilon = 0.00001f;
  790. if (less_than(p1, p0))
  791. {
  792. glm::vec3 ptemp = p0;
  793. p0 = p1;
  794. p1 = ptemp;
  795. float vtemp = v0;
  796. v0 = v1;
  797. v1 = vtemp;
  798. }
  799. if (std::fabs(v0 - v1) > epsilon)
  800. {
  801. return p0 + ((p1 - p0) / (v1 - v0) * (isolevel - v0));
  802. }
  803. return p0;
  804. }
  805. int polygonize(const voxel& vox, float isolevel, triangle* triangles)
  806. {
  807. // Set bitflags for each of the cube's 8 vertices, indicating whether or not they are inside the isosurface.
  808. int edge_index = 0;
  809. for (int i = 0; i < 8; ++i)
  810. {
  811. if (vox.values[i] < isolevel)
  812. edge_index |= (1 << i);
  813. }
  814. // Get edge flags from lookup table
  815. int edge_flags = EDGE_TABLE[edge_index];
  816. if (edge_flags == 0)
  817. {
  818. // No intersections, cube is completely in or out of the isosurface.
  819. return 0;
  820. }
  821. // Calculate vertex positions
  822. glm::vec3 vertices[12];
  823. // For each edge
  824. for (int i = 0; i < 12; ++i)
  825. {
  826. // If this edge is intersected
  827. if (edge_flags & (1 << i))
  828. {
  829. int a = VERTEX_TABLE[i][0];
  830. int b = VERTEX_TABLE[i][1];
  831. vertices[i] = interpolate(isolevel, vox.vertices[a], vox.vertices[b], vox.values[a], vox.values[b]);
  832. }
  833. }
  834. // Form triangles
  835. int triangle_count = 0;
  836. for (int i = 0; TRIANGLE_TABLE[edge_index][i] != -1; i += 3)
  837. {
  838. int a = TRIANGLE_TABLE[edge_index][i];
  839. int b = TRIANGLE_TABLE[edge_index][i + 1];
  840. int c = TRIANGLE_TABLE[edge_index][i + 2];
  841. triangles[triangle_count].vertices[0] = vertices[a];
  842. triangles[triangle_count].vertices[1] = vertices[b];
  843. triangles[triangle_count].vertices[2] = vertices[c];
  844. ++triangle_count;
  845. }
  846. return triangle_count;
  847. }