MarchingCubes4.cs 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using UnityEngine;
  5. using Unity.Jobs;
  6. using Unity.Collections;
  7. using UnityEngine.Assertions;
  8. using Sirenix.OdinInspector;
  9. using KairoEngine.Core;
  10. using KairoEngine.Chunks;
  11. namespace KairoEngine.TerrainEngine
  12. {
  13. public class MarchingCubes4 : MonoBehaviour
  14. {
  15. public float terrainSurface = 0.5f;
  16. public bool smoothTerrain;
  17. public bool flatShaded;
  18. public Material material;
  19. MeshFilter meshFilter;
  20. MeshCollider meshCollider;
  21. GameObject prefab;
  22. int width = 32;
  23. int length = 32;
  24. int height = 8;
  25. Vector3 voxelSize = new Vector3(1f, 1f, 1f);
  26. float[,,] terrainMap;
  27. uint[,,] terrainCodes;
  28. List<Vector3> vertices = new List<Vector3>();
  29. List<int> triangles = new List<int>();
  30. private ChunkSystem<BlockBase> chunkSystem;
  31. private List<JobHandle> jobHandles = new List<JobHandle>();
  32. private List<MarchingCubesJob4> jobs = new List<MarchingCubesJob4>();
  33. private void Update()
  34. {
  35. UpdateFinishedJobs();
  36. }
  37. public void OnDestroy()
  38. {
  39. // Make sure we run our jobs to completion before exiting.
  40. for (int i = 0; i < jobHandles.Count; i++)
  41. {
  42. jobHandles[i].Complete();
  43. }
  44. }
  45. public void UpdateFinishedJobs()
  46. {
  47. //jobHandle.Complete();
  48. Debug.Log("Updating finished jobs - " + jobHandles.Count);
  49. for (int i = 0; i < jobHandles.Count; i++)
  50. {
  51. if(jobHandles[i].IsCompleted)
  52. {
  53. }
  54. jobHandles[i].Complete();
  55. Debug.Log($"Job {i} is completed");
  56. if(prefab == null) prefab = new GameObject();
  57. GameObject target = Instantiate(prefab, jobs[i].initialPosition, transform.rotation, this.transform);
  58. // Create vertices and triangle arrays
  59. int verticeCount = jobs[i].arrayIndexes[0];
  60. int trianglesCount = jobs[i].arrayIndexes[1];
  61. Debug.Log($"Completed job has {jobs[i].vertices.Count()}/{verticeCount} vertices and {jobs[i].triangles.Count()}/{trianglesCount} triangles");
  62. Vector3[] vertices = jobs[i].vertices.Take(verticeCount).ToArray();
  63. int[] triangles = jobs[i].triangles.Take(trianglesCount).ToArray();
  64. Color[] vertexColors = jobs[i].vertexColors.Take(verticeCount).ToArray();
  65. BuildMesh(target, vertices, triangles, vertexColors);
  66. // Remove this
  67. jobs[i].blocks.Dispose();
  68. jobs[i].codes.Dispose();
  69. jobs[i].vertices.Dispose();
  70. jobs[i].triangles.Dispose();
  71. jobs[i].arrayIndexes.Dispose();
  72. jobs[i].triangleTable.Dispose();
  73. jobs.RemoveAt(i);
  74. jobHandles.RemoveAt(i);
  75. i -= 1;
  76. }
  77. }
  78. public bool IsGeneratorDone() => jobHandles.Count == 0 ? true : false;
  79. public void Generate(ChunkSystem<BlockBase> chunkSystem, Vector3 initialPosition = new Vector3())
  80. {
  81. Debug.Log("Generating chunk " + initialPosition);
  82. this.chunkSystem = chunkSystem;
  83. width = chunkSystem.chunkSize.x;
  84. length = chunkSystem.chunkSize.z;
  85. height = chunkSystem.chunkSize.y;
  86. voxelSize = chunkSystem.voxelSize;
  87. //transform.tag = "Terrain";
  88. terrainMap = new float[width + 1, height + 1, length + 1];
  89. terrainCodes = new uint[width + 1, height + 1, length + 1];
  90. PopulateTerrainMap(chunkSystem, initialPosition);
  91. ScheduleJob(initialPosition);
  92. //CreateMeshData();
  93. }
  94. void PopulateTerrainMap (ChunkSystem<BlockBase> chunkSystem, Vector3 initialPosition = new Vector3())
  95. {
  96. // The data points for terrain are stored at the corners of our "cubes", so the terrainMap needs to be 1 larger
  97. // than the width/height of our mesh.
  98. for (int x = 0; x < width + 1; x++) {
  99. for (int z = 0; z < length + 1; z++) {
  100. for (int y = 0; y < height + 1; y++) {
  101. Vector3 pos = initialPosition + new Vector3(x * voxelSize.x, y * voxelSize.y, z * voxelSize.z);
  102. BlockBase block = chunkSystem.GetBlock(pos);
  103. // Set the value of this point in the terrainMap.
  104. terrainMap[x, y, z] = (float)pos.y - ((float)block.value * voxelSize.y);
  105. terrainCodes[x, y, z] = block.code;
  106. }
  107. }
  108. }
  109. }
  110. void BuildMesh (GameObject target, Vector3[] vertices, int[] triangles, Color[] vertexColors)
  111. {
  112. //Debug.Log($"Building mesh with {vertices.Length} vertices and {triangles.Length} triangles");
  113. MeshRenderer meshRederer = target.GetComponent<MeshRenderer>();
  114. if(meshRederer == null) meshRederer = target.AddComponent<MeshRenderer>();
  115. meshRederer.sharedMaterial = material;
  116. MeshFilter meshFilter = target.GetComponent<MeshFilter>();
  117. if(meshFilter == null) meshFilter = target.AddComponent<MeshFilter>();
  118. MeshCollider meshCollider = target.GetComponent<MeshCollider>();
  119. if(meshCollider == null) meshCollider = target.AddComponent<MeshCollider>();
  120. Mesh mesh = new Mesh();
  121. mesh.vertices = vertices;
  122. mesh.triangles = triangles;
  123. mesh.colors = vertexColors;
  124. mesh.RecalculateNormals();
  125. meshFilter.mesh = mesh;
  126. meshCollider.sharedMesh = mesh;
  127. }
  128. private void ScheduleJob(Vector3 initialPosition)
  129. {
  130. JobHandle jobHandle = new JobHandle();
  131. var marchingCubesJob = new MarchingCubesJob4
  132. {
  133. chunkSize = this.chunkSystem.chunkSize,
  134. voxelSize = this.voxelSize,
  135. terrainSurface = terrainSurface,
  136. smoothTerrain = smoothTerrain,
  137. flatShaded = flatShaded,
  138. blocks = new NativeArray<float>(terrainMap.Length, Allocator.TempJob),
  139. codes = new NativeArray<uint>(terrainMap.Length, Allocator.TempJob),
  140. vertices = new NativeArray<Vector3>(15000, Allocator.TempJob),
  141. triangles = new NativeArray<int>(25000, Allocator.TempJob),
  142. vertexColors = new NativeArray<Color>(15000, Allocator.TempJob),
  143. arrayIndexes = new NativeArray<int>(2, Allocator.TempJob),
  144. triangleTable = new NativeArray<int>(4096, Allocator.TempJob),
  145. initialPosition = initialPosition
  146. };
  147. int blockIndex = 0;
  148. for (int x = 0; x < width + 1; x++) {
  149. for (int y = 0; y < height + 1; y++) {
  150. for (int z = 0; z < length + 1; z++) {
  151. marchingCubesJob.blocks[blockIndex] = terrainMap[x, y, z];
  152. marchingCubesJob.codes[blockIndex] = terrainCodes[x, y, z];
  153. blockIndex += 1;
  154. }
  155. }
  156. }
  157. jobHandle = marchingCubesJob.Schedule(jobHandle);
  158. jobHandles.Add(jobHandle);
  159. jobs.Add(marchingCubesJob);
  160. }
  161. }
  162. [ExecuteInEditMode]
  163. struct MarchingCubesJob4 : IJob
  164. {
  165. public Vector3Int chunkSize;
  166. public Vector3 voxelSize;
  167. public float terrainSurface;
  168. public bool smoothTerrain;
  169. public bool flatShaded;
  170. public NativeArray<float> blocks;
  171. public NativeArray<uint> codes;
  172. public NativeArray<Vector3> vertices;
  173. public NativeArray<int> triangles;
  174. public NativeArray<Color> vertexColors;
  175. public Vector3 initialPosition;
  176. public NativeArray<int> arrayIndexes;
  177. public NativeArray<int> triangleTable;
  178. private int verticesArrayIndex;
  179. private int trianglesArrayIndex;
  180. public void Execute()
  181. {
  182. verticesArrayIndex = 0;
  183. trianglesArrayIndex = 0;
  184. Debug.Log("Executing job");
  185. CreateTriangleTable();
  186. // Loop through each "cube" in our terrain.
  187. for (int x = 0; x < chunkSize.x; x++) {
  188. for (int y = 0; y < chunkSize.y; y++) {
  189. for (int z = 0; z < chunkSize.z; z++) {
  190. // Pass the value into our MarchCube function.
  191. MarchCube(new Vector3Int(x, y, z));
  192. }
  193. }
  194. }
  195. arrayIndexes[0] = verticesArrayIndex;
  196. arrayIndexes[1] = trianglesArrayIndex;
  197. }
  198. void MarchCube (Vector3Int position) {
  199. // Sample terrain values at each corner of the cube.
  200. float[] cube = new float[8];
  201. for (int i = 0; i < 8; i++) {
  202. cube[i] = SampleTerrain(position + CornerTable(i));
  203. }
  204. Vector3 realPosition = new Vector3(position.x * voxelSize.x, position.y * voxelSize.y, position.z * voxelSize.z);
  205. // Get the configuration index of this cube.
  206. int configIndex = GetCubeConfiguration(cube);
  207. // If the configuration of this cube is 0 or 255 (completely inside the terrain or completely outside of it) we don't need to do anything.
  208. if (configIndex == 0 || configIndex == 255) return;
  209. // Loop through the triangles. There are never more than 5 triangles to a cube and only three vertices to a triangle.
  210. int edgeIndex = 0;
  211. for(int i = 0; i < 5; i++)
  212. {
  213. for(int p = 0; p < 3; p++)
  214. {
  215. // Get the current indice. We increment triangleIndex through each loop.
  216. int indice = GetFromTriangleTable(configIndex, edgeIndex);
  217. // If the current edgeIndex is -1, there are no more indices and we can exit the function.
  218. if (indice == -1) return;
  219. // Get the vertices for the start and end of this edge.
  220. Vector3 vert1 = position + CornerTable(EdgeIndexes()[indice, 0]);
  221. Vector3 vert2 = position + CornerTable(EdgeIndexes()[indice, 1]);
  222. //vert1 = new Vector3(vert1.x * voxelSize.x, vert1.y * voxelSize.y, vert1.z * voxelSize.z);
  223. //vert2 = new Vector3(vert2.x * voxelSize.x, vert2.y * voxelSize.y, vert2.z * voxelSize.z);
  224. Vector3 vertPosition;
  225. if (smoothTerrain) {
  226. // Get the terrain values at either end of our current edge from the cube array created above.
  227. float vert1Sample = cube[EdgeIndexes()[indice, 0]];
  228. float vert2Sample = cube[EdgeIndexes()[indice, 1]];
  229. // Calculate the difference between the terrain values.
  230. float difference = vert2Sample - vert1Sample;
  231. // If the difference is 0, then the terrain passes through the middle.
  232. if (difference == 0) difference = terrainSurface;
  233. else difference = (terrainSurface - vert1Sample) / difference;
  234. // Calculate the point along the edge that passes through.
  235. vertPosition = vert1 + ((vert2 - vert1) * difference);
  236. }
  237. else
  238. {
  239. // Get the midpoint of this edge.
  240. vertPosition = (vert1 + vert2) / 2f;
  241. }
  242. vertPosition = new Vector3(vertPosition.x * voxelSize.x, vertPosition.y * voxelSize.y, vertPosition.z * voxelSize.z);
  243. // Add to our vertices and triangles list and incremement the edgeIndex.
  244. if (flatShaded)
  245. {
  246. vertices[verticesArrayIndex] = vertPosition;
  247. triangles[trianglesArrayIndex] = verticesArrayIndex;
  248. vertexColors[verticesArrayIndex] = SampleTerrainColor(position);
  249. verticesArrayIndex += 1;
  250. trianglesArrayIndex += 1;
  251. }
  252. else
  253. {
  254. triangles[trianglesArrayIndex] = VertForIndice(vertPosition, position);
  255. trianglesArrayIndex += 1;
  256. }
  257. edgeIndex++;
  258. }
  259. }
  260. }
  261. float SampleTerrain (Vector3Int point)
  262. {
  263. // https://stackoverflow.com/questions/3613429/algorithm-to-convert-a-multi-dimensional-array-to-a-one-dimensional-array
  264. int index = (((chunkSize.y + 1) * (chunkSize.z + 1)) * point.x) + ((chunkSize.z + 1) * point.y) + point.z;
  265. return blocks[index];
  266. }
  267. Color SampleTerrainColor (Vector3Int point)
  268. {
  269. int index = (((chunkSize.y + 1) * (chunkSize.z + 1)) * point.x) + ((chunkSize.z + 1) * point.y) + point.z;
  270. uint code = codes[index];
  271. switch (code)
  272. {
  273. default:
  274. case 0:
  275. return Color.white;
  276. case 1:
  277. return Color.red;
  278. case 2:
  279. return Color.green;
  280. case 3:
  281. return Color.blue;
  282. case 4:
  283. return Color.black;
  284. case 5:
  285. return Color.yellow;
  286. case 6:
  287. return new Color(1f, 0, 1f); // Purple
  288. case 7:
  289. return new Color(0f, 1f, 1f); // Purple
  290. }
  291. }
  292. int GetCubeConfiguration (float[] cube)
  293. {
  294. // Starting with a configuration of zero, loop through each point in the cube and check if it is below the terrain surface.
  295. int configurationIndex = 0;
  296. for (int i = 0; i < 8; i++) {
  297. // If it is, use bit-magic to the set the corresponding bit to 1. So if only the 3rd point in the cube was below
  298. // the surface, the bit would look like 00100000, which represents the integer value 32.
  299. if (cube[i] > terrainSurface)
  300. configurationIndex |= 1 << i;
  301. }
  302. return configurationIndex;
  303. }
  304. int VertForIndice (Vector3 vert, Vector3Int point)
  305. {
  306. // Loop through all the vertices currently in the vertices list.
  307. for (int i = 0; i < verticesArrayIndex; i++)
  308. {
  309. // If we find a vert that matches ours, then simply return this index.
  310. if (vertices[i] == vert) return i;
  311. }
  312. // If we didn't find a match, add this vert to the list and return last index.
  313. vertices[verticesArrayIndex] = vert;
  314. vertexColors[verticesArrayIndex] = SampleTerrainColor(point);
  315. verticesArrayIndex += 1;
  316. return verticesArrayIndex - 1;
  317. }
  318. // Vector3Int[] CornerTable;
  319. // int[,] EdgeIndexes;
  320. // private int[,] TriangleTable;
  321. private Vector3Int CornerTable(int index)
  322. {
  323. Vector3Int[] CornerTable = new Vector3Int[8] {
  324. new Vector3Int(0, 0, 0),
  325. new Vector3Int(1, 0, 0),
  326. new Vector3Int(1, 1, 0),
  327. new Vector3Int(0, 1, 0),
  328. new Vector3Int(0, 0, 1),
  329. new Vector3Int(1, 0, 1),
  330. new Vector3Int(1, 1, 1),
  331. new Vector3Int(0, 1, 1)
  332. };
  333. return CornerTable[index];
  334. }
  335. private int[,] EdgeIndexes()
  336. {
  337. int[,] EdgeIndexes = new int[12, 2] {
  338. {0, 1}, {1, 2}, {3, 2}, {0, 3}, {4, 5}, {5, 6}, {7, 6}, {4, 7}, {0, 4}, {1, 5}, {2, 6}, {3, 7}
  339. };
  340. return EdgeIndexes;
  341. }
  342. private void CreateTriangleTable()
  343. {
  344. int[,] table = TriangleTable();
  345. int index = 0;
  346. for (int x = 0; x < table.GetLength(0); x++)
  347. {
  348. for (int y = 0; y < table.GetLength(1); y++)
  349. {
  350. triangleTable[index] = table[x, y];
  351. index += 1;
  352. }
  353. }
  354. }
  355. private int GetFromTriangleTable(int x, int y)
  356. {
  357. return triangleTable[x * 16 + y];
  358. }
  359. private int[,] TriangleTable()
  360. {
  361. int[,] TriangleTable = new int[,]
  362. {
  363. {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  364. {0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  365. {0, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  366. {1, 8, 3, 9, 8, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  367. {1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  368. {0, 8, 3, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  369. {9, 2, 10, 0, 2, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  370. {2, 8, 3, 2, 10, 8, 10, 9, 8, -1, -1, -1, -1, -1, -1, -1},
  371. {3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  372. {0, 11, 2, 8, 11, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  373. {1, 9, 0, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  374. {1, 11, 2, 1, 9, 11, 9, 8, 11, -1, -1, -1, -1, -1, -1, -1},
  375. {3, 10, 1, 11, 10, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  376. {0, 10, 1, 0, 8, 10, 8, 11, 10, -1, -1, -1, -1, -1, -1, -1},
  377. {3, 9, 0, 3, 11, 9, 11, 10, 9, -1, -1, -1, -1, -1, -1, -1},
  378. {9, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  379. {4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  380. {4, 3, 0, 7, 3, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  381. {0, 1, 9, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  382. {4, 1, 9, 4, 7, 1, 7, 3, 1, -1, -1, -1, -1, -1, -1, -1},
  383. {1, 2, 10, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  384. {3, 4, 7, 3, 0, 4, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1},
  385. {9, 2, 10, 9, 0, 2, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1},
  386. {2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4, -1, -1, -1, -1},
  387. {8, 4, 7, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  388. {11, 4, 7, 11, 2, 4, 2, 0, 4, -1, -1, -1, -1, -1, -1, -1},
  389. {9, 0, 1, 8, 4, 7, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1},
  390. {4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1, -1, -1, -1, -1},
  391. {3, 10, 1, 3, 11, 10, 7, 8, 4, -1, -1, -1, -1, -1, -1, -1},
  392. {1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4, -1, -1, -1, -1},
  393. {4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3, -1, -1, -1, -1},
  394. {4, 7, 11, 4, 11, 9, 9, 11, 10, -1, -1, -1, -1, -1, -1, -1},
  395. {9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  396. {9, 5, 4, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  397. {0, 5, 4, 1, 5, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  398. {8, 5, 4, 8, 3, 5, 3, 1, 5, -1, -1, -1, -1, -1, -1, -1},
  399. {1, 2, 10, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  400. {3, 0, 8, 1, 2, 10, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1},
  401. {5, 2, 10, 5, 4, 2, 4, 0, 2, -1, -1, -1, -1, -1, -1, -1},
  402. {2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8, -1, -1, -1, -1},
  403. {9, 5, 4, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  404. {0, 11, 2, 0, 8, 11, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1},
  405. {0, 5, 4, 0, 1, 5, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1},
  406. {2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5, -1, -1, -1, -1},
  407. {10, 3, 11, 10, 1, 3, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1},
  408. {4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11, 10, -1, -1, -1, -1},
  409. {5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3, -1, -1, -1, -1},
  410. {5, 4, 8, 5, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1},
  411. {9, 7, 8, 5, 7, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  412. {9, 3, 0, 9, 5, 3, 5, 7, 3, -1, -1, -1, -1, -1, -1, -1},
  413. {0, 7, 8, 0, 1, 7, 1, 5, 7, -1, -1, -1, -1, -1, -1, -1},
  414. {1, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  415. {9, 7, 8, 9, 5, 7, 10, 1, 2, -1, -1, -1, -1, -1, -1, -1},
  416. {10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3, -1, -1, -1, -1},
  417. {8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2, -1, -1, -1, -1},
  418. {2, 10, 5, 2, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1},
  419. {7, 9, 5, 7, 8, 9, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1},
  420. {9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11, -1, -1, -1, -1},
  421. {2, 3, 11, 0, 1, 8, 1, 7, 8, 1, 5, 7, -1, -1, -1, -1},
  422. {11, 2, 1, 11, 1, 7, 7, 1, 5, -1, -1, -1, -1, -1, -1, -1},
  423. {9, 5, 8, 8, 5, 7, 10, 1, 3, 10, 3, 11, -1, -1, -1, -1},
  424. {5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10, 11, 10, 0, -1},
  425. {11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7, 0, -1},
  426. {11, 10, 5, 7, 11, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  427. {10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  428. {0, 8, 3, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  429. {9, 0, 1, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  430. {1, 8, 3, 1, 9, 8, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1},
  431. {1, 6, 5, 2, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  432. {1, 6, 5, 1, 2, 6, 3, 0, 8, -1, -1, -1, -1, -1, -1, -1},
  433. {9, 6, 5, 9, 0, 6, 0, 2, 6, -1, -1, -1, -1, -1, -1, -1},
  434. {5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, -1, -1, -1, -1},
  435. {2, 3, 11, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  436. {11, 0, 8, 11, 2, 0, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1},
  437. {0, 1, 9, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1},
  438. {5, 10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11, -1, -1, -1, -1},
  439. {6, 3, 11, 6, 5, 3, 5, 1, 3, -1, -1, -1, -1, -1, -1, -1},
  440. {0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6, -1, -1, -1, -1},
  441. {3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9, -1, -1, -1, -1},
  442. {6, 5, 9, 6, 9, 11, 11, 9, 8, -1, -1, -1, -1, -1, -1, -1},
  443. {5, 10, 6, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  444. {4, 3, 0, 4, 7, 3, 6, 5, 10, -1, -1, -1, -1, -1, -1, -1},
  445. {1, 9, 0, 5, 10, 6, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1},
  446. {10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, -1, -1, -1, -1},
  447. {6, 1, 2, 6, 5, 1, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1},
  448. {1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7, -1, -1, -1, -1},
  449. {8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6, -1, -1, -1, -1},
  450. {7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9, -1},
  451. {3, 11, 2, 7, 8, 4, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1},
  452. {5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11, -1, -1, -1, -1},
  453. {0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1},
  454. {9, 2, 1, 9, 11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6, -1},
  455. {8, 4, 7, 3, 11, 5, 3, 5, 1, 5, 11, 6, -1, -1, -1, -1},
  456. {5, 1, 11, 5, 11, 6, 1, 0, 11, 7, 11, 4, 0, 4, 11, -1},
  457. {0, 5, 9, 0, 6, 5, 0, 3, 6, 11, 6, 3, 8, 4, 7, -1},
  458. {6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9, -1, -1, -1, -1},
  459. {10, 4, 9, 6, 4, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  460. {4, 10, 6, 4, 9, 10, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1},
  461. {10, 0, 1, 10, 6, 0, 6, 4, 0, -1, -1, -1, -1, -1, -1, -1},
  462. {8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10, -1, -1, -1, -1},
  463. {1, 4, 9, 1, 2, 4, 2, 6, 4, -1, -1, -1, -1, -1, -1, -1},
  464. {3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4, -1, -1, -1, -1},
  465. {0, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  466. {8, 3, 2, 8, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1},
  467. {10, 4, 9, 10, 6, 4, 11, 2, 3, -1, -1, -1, -1, -1, -1, -1},
  468. {0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6, -1, -1, -1, -1},
  469. {3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, 10, -1, -1, -1, -1},
  470. {6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, 8, 11, 1, -1},
  471. {9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3, -1, -1, -1, -1},
  472. {8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1, -1},
  473. {3, 11, 6, 3, 6, 0, 0, 6, 4, -1, -1, -1, -1, -1, -1, -1},
  474. {6, 4, 8, 11, 6, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  475. {7, 10, 6, 7, 8, 10, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1},
  476. {0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10, -1, -1, -1, -1},
  477. {10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0, -1, -1, -1, -1},
  478. {10, 6, 7, 10, 7, 1, 1, 7, 3, -1, -1, -1, -1, -1, -1, -1},
  479. {1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7, -1, -1, -1, -1},
  480. {2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9, -1},
  481. {7, 8, 0, 7, 0, 6, 6, 0, 2, -1, -1, -1, -1, -1, -1, -1},
  482. {7, 3, 2, 6, 7, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  483. {2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7, -1, -1, -1, -1},
  484. {2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7, -1},
  485. {1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11, -1},
  486. {11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1, -1, -1, -1, -1},
  487. {8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6, -1},
  488. {0, 9, 1, 11, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  489. {7, 8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0, -1, -1, -1, -1},
  490. {7, 11, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  491. {7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  492. {3, 0, 8, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  493. {0, 1, 9, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  494. {8, 1, 9, 8, 3, 1, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1},
  495. {10, 1, 2, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  496. {1, 2, 10, 3, 0, 8, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1},
  497. {2, 9, 0, 2, 10, 9, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1},
  498. {6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, 8, -1, -1, -1, -1},
  499. {7, 2, 3, 6, 2, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  500. {7, 0, 8, 7, 6, 0, 6, 2, 0, -1, -1, -1, -1, -1, -1, -1},
  501. {2, 7, 6, 2, 3, 7, 0, 1, 9, -1, -1, -1, -1, -1, -1, -1},
  502. {1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6, -1, -1, -1, -1},
  503. {10, 7, 6, 10, 1, 7, 1, 3, 7, -1, -1, -1, -1, -1, -1, -1},
  504. {10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8, -1, -1, -1, -1},
  505. {0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7, -1, -1, -1, -1},
  506. {7, 6, 10, 7, 10, 8, 8, 10, 9, -1, -1, -1, -1, -1, -1, -1},
  507. {6, 8, 4, 11, 8, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  508. {3, 6, 11, 3, 0, 6, 0, 4, 6, -1, -1, -1, -1, -1, -1, -1},
  509. {8, 6, 11, 8, 4, 6, 9, 0, 1, -1, -1, -1, -1, -1, -1, -1},
  510. {9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6, -1, -1, -1, -1},
  511. {6, 8, 4, 6, 11, 8, 2, 10, 1, -1, -1, -1, -1, -1, -1, -1},
  512. {1, 2, 10, 3, 0, 11, 0, 6, 11, 0, 4, 6, -1, -1, -1, -1},
  513. {4, 11, 8, 4, 6, 11, 0, 2, 9, 2, 10, 9, -1, -1, -1, -1},
  514. {10, 9, 3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3, -1},
  515. {8, 2, 3, 8, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1},
  516. {0, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  517. {1, 9, 0, 2, 3, 4, 2, 4, 6, 4, 3, 8, -1, -1, -1, -1},
  518. {1, 9, 4, 1, 4, 2, 2, 4, 6, -1, -1, -1, -1, -1, -1, -1},
  519. {8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1, -1, -1, -1, -1},
  520. {10, 1, 0, 10, 0, 6, 6, 0, 4, -1, -1, -1, -1, -1, -1, -1},
  521. {4, 6, 3, 4, 3, 8, 6, 10, 3, 0, 3, 9, 10, 9, 3, -1},
  522. {10, 9, 4, 6, 10, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  523. {4, 9, 5, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  524. {0, 8, 3, 4, 9, 5, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1},
  525. {5, 0, 1, 5, 4, 0, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1},
  526. {11, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5, -1, -1, -1, -1},
  527. {9, 5, 4, 10, 1, 2, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1},
  528. {6, 11, 7, 1, 2, 10, 0, 8, 3, 4, 9, 5, -1, -1, -1, -1},
  529. {7, 6, 11, 5, 4, 10, 4, 2, 10, 4, 0, 2, -1, -1, -1, -1},
  530. {3, 4, 8, 3, 5, 4, 3, 2, 5, 10, 5, 2, 11, 7, 6, -1},
  531. {7, 2, 3, 7, 6, 2, 5, 4, 9, -1, -1, -1, -1, -1, -1, -1},
  532. {9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7, -1, -1, -1, -1},
  533. {3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0, -1, -1, -1, -1},
  534. {6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8, -1},
  535. {9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7, -1, -1, -1, -1},
  536. {1, 6, 10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4, -1},
  537. {4, 0, 10, 4, 10, 5, 0, 3, 10, 6, 10, 7, 3, 7, 10, -1},
  538. {7, 6, 10, 7, 10, 8, 5, 4, 10, 4, 8, 10, -1, -1, -1, -1},
  539. {6, 9, 5, 6, 11, 9, 11, 8, 9, -1, -1, -1, -1, -1, -1, -1},
  540. {3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5, -1, -1, -1, -1},
  541. {0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11, -1, -1, -1, -1},
  542. {6, 11, 3, 6, 3, 5, 5, 3, 1, -1, -1, -1, -1, -1, -1, -1},
  543. {1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6, -1, -1, -1, -1},
  544. {0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10, -1},
  545. {11, 8, 5, 11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5, -1},
  546. {6, 11, 3, 6, 3, 5, 2, 10, 3, 10, 5, 3, -1, -1, -1, -1},
  547. {5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2, -1, -1, -1, -1},
  548. {9, 5, 6, 9, 6, 0, 0, 6, 2, -1, -1, -1, -1, -1, -1, -1},
  549. {1, 5, 8, 1, 8, 0, 5, 6, 8, 3, 8, 2, 6, 2, 8, -1},
  550. {1, 5, 6, 2, 1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  551. {1, 3, 6, 1, 6, 10, 3, 8, 6, 5, 6, 9, 8, 9, 6, -1},
  552. {10, 1, 0, 10, 0, 6, 9, 5, 0, 5, 6, 0, -1, -1, -1, -1},
  553. {0, 3, 8, 5, 6, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  554. {10, 5, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  555. {11, 5, 10, 7, 5, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  556. {11, 5, 10, 11, 7, 5, 8, 3, 0, -1, -1, -1, -1, -1, -1, -1},
  557. {5, 11, 7, 5, 10, 11, 1, 9, 0, -1, -1, -1, -1, -1, -1, -1},
  558. {10, 7, 5, 10, 11, 7, 9, 8, 1, 8, 3, 1, -1, -1, -1, -1},
  559. {11, 1, 2, 11, 7, 1, 7, 5, 1, -1, -1, -1, -1, -1, -1, -1},
  560. {0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 11, -1, -1, -1, -1},
  561. {9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7, -1, -1, -1, -1},
  562. {7, 5, 2, 7, 2, 11, 5, 9, 2, 3, 2, 8, 9, 8, 2, -1},
  563. {2, 5, 10, 2, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1},
  564. {8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5, -1, -1, -1, -1},
  565. {9, 0, 1, 5, 10, 3, 5, 3, 7, 3, 10, 2, -1, -1, -1, -1},
  566. {9, 8, 2, 9, 2, 1, 8, 7, 2, 10, 2, 5, 7, 5, 2, -1},
  567. {1, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  568. {0, 8, 7, 0, 7, 1, 1, 7, 5, -1, -1, -1, -1, -1, -1, -1},
  569. {9, 0, 3, 9, 3, 5, 5, 3, 7, -1, -1, -1, -1, -1, -1, -1},
  570. {9, 8, 7, 5, 9, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  571. {5, 8, 4, 5, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1},
  572. {5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0, -1, -1, -1, -1},
  573. {0, 1, 9, 8, 4, 10, 8, 10, 11, 10, 4, 5, -1, -1, -1, -1},
  574. {10, 11, 4, 10, 4, 5, 11, 3, 4, 9, 4, 1, 3, 1, 4, -1},
  575. {2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8, -1, -1, -1, -1},
  576. {0, 4, 11, 0, 11, 3, 4, 5, 11, 2, 11, 1, 5, 1, 11, -1},
  577. {0, 2, 5, 0, 5, 9, 2, 11, 5, 4, 5, 8, 11, 8, 5, -1},
  578. {9, 4, 5, 2, 11, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  579. {2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4, -1, -1, -1, -1},
  580. {5, 10, 2, 5, 2, 4, 4, 2, 0, -1, -1, -1, -1, -1, -1, -1},
  581. {3, 10, 2, 3, 5, 10, 3, 8, 5, 4, 5, 8, 0, 1, 9, -1},
  582. {5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2, -1, -1, -1, -1},
  583. {8, 4, 5, 8, 5, 3, 3, 5, 1, -1, -1, -1, -1, -1, -1, -1},
  584. {0, 4, 5, 1, 0, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  585. {8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5, -1, -1, -1, -1},
  586. {9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  587. {4, 11, 7, 4, 9, 11, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1},
  588. {0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11, -1, -1, -1, -1},
  589. {1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11, -1, -1, -1, -1},
  590. {3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4, -1},
  591. {4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2, -1, -1, -1, -1},
  592. {9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3, -1},
  593. {11, 7, 4, 11, 4, 2, 2, 4, 0, -1, -1, -1, -1, -1, -1, -1},
  594. {11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4, -1, -1, -1, -1},
  595. {2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9, -1, -1, -1, -1},
  596. {9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7, -1},
  597. {3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10, -1},
  598. {1, 10, 2, 8, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  599. {4, 9, 1, 4, 1, 7, 7, 1, 3, -1, -1, -1, -1, -1, -1, -1},
  600. {4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, -1, -1, -1, -1},
  601. {4, 0, 3, 7, 4, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  602. {4, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  603. {9, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  604. {3, 0, 9, 3, 9, 11, 11, 9, 10, -1, -1, -1, -1, -1, -1, -1},
  605. {0, 1, 10, 0, 10, 8, 8, 10, 11, -1, -1, -1, -1, -1, -1, -1},
  606. {3, 1, 10, 11, 3, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  607. {1, 2, 11, 1, 11, 9, 9, 11, 8, -1, -1, -1, -1, -1, -1, -1},
  608. {3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9, -1, -1, -1, -1},
  609. {0, 2, 11, 8, 0, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  610. {3, 2, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  611. {2, 3, 8, 2, 8, 10, 10, 8, 9, -1, -1, -1, -1, -1, -1, -1},
  612. {9, 10, 2, 0, 9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  613. {2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8, -1, -1, -1, -1},
  614. {1, 10, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  615. {1, 3, 8, 9, 1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  616. {0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  617. {0, 3, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
  618. {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}
  619. };
  620. return TriangleTable;
  621. }
  622. }
  623. }