|
@@ -0,0 +1,658 @@
|
|
|
+using System.Collections;
|
|
|
+using System.Collections.Generic;
|
|
|
+using System.Linq;
|
|
|
+using UnityEngine;
|
|
|
+using Unity.Jobs;
|
|
|
+using Unity.Collections;
|
|
|
+using UnityEngine.Assertions;
|
|
|
+using Sirenix.OdinInspector;
|
|
|
+using KairoEngine.Core;
|
|
|
+using KairoEngine.Chunks;
|
|
|
+
|
|
|
+namespace KairoEngine.TerrainEngine
|
|
|
+{
|
|
|
+ public class MarchingCubes4 : MonoBehaviour
|
|
|
+ {
|
|
|
+ public float terrainSurface = 0.5f;
|
|
|
+ public bool smoothTerrain;
|
|
|
+ public bool flatShaded;
|
|
|
+ public Material material;
|
|
|
+
|
|
|
+
|
|
|
+ MeshFilter meshFilter;
|
|
|
+ MeshCollider meshCollider;
|
|
|
+
|
|
|
+ GameObject prefab;
|
|
|
+
|
|
|
+
|
|
|
+ int width = 32;
|
|
|
+ int length = 32;
|
|
|
+ int height = 8;
|
|
|
+
|
|
|
+ Vector3 voxelSize = new Vector3(1f, 1f, 1f);
|
|
|
+
|
|
|
+ float[,,] terrainMap;
|
|
|
+ uint[,,] terrainCodes;
|
|
|
+
|
|
|
+ List<Vector3> vertices = new List<Vector3>();
|
|
|
+ List<int> triangles = new List<int>();
|
|
|
+
|
|
|
+ private ChunkSystem<BlockBase> chunkSystem;
|
|
|
+ private List<JobHandle> jobHandles = new List<JobHandle>();
|
|
|
+ private List<MarchingCubesJob4> jobs = new List<MarchingCubesJob4>();
|
|
|
+
|
|
|
+ private void Update()
|
|
|
+ {
|
|
|
+ UpdateFinishedJobs();
|
|
|
+ }
|
|
|
+
|
|
|
+ public void OnDestroy()
|
|
|
+ {
|
|
|
+ // Make sure we run our jobs to completion before exiting.
|
|
|
+ for (int i = 0; i < jobHandles.Count; i++)
|
|
|
+ {
|
|
|
+ jobHandles[i].Complete();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public void UpdateFinishedJobs()
|
|
|
+ {
|
|
|
+ //jobHandle.Complete();
|
|
|
+ Debug.Log("Updating finished jobs - " + jobHandles.Count);
|
|
|
+ for (int i = 0; i < jobHandles.Count; i++)
|
|
|
+ {
|
|
|
+
|
|
|
+ if(jobHandles[i].IsCompleted)
|
|
|
+ {
|
|
|
+
|
|
|
+ }
|
|
|
+ jobHandles[i].Complete();
|
|
|
+ Debug.Log($"Job {i} is completed");
|
|
|
+ if(prefab == null) prefab = new GameObject();
|
|
|
+ GameObject target = Instantiate(prefab, jobs[i].initialPosition, transform.rotation, this.transform);
|
|
|
+ // Create vertices and triangle arrays
|
|
|
+ int verticeCount = jobs[i].arrayIndexes[0];
|
|
|
+ int trianglesCount = jobs[i].arrayIndexes[1];
|
|
|
+ Debug.Log($"Completed job has {jobs[i].vertices.Count()}/{verticeCount} vertices and {jobs[i].triangles.Count()}/{trianglesCount} triangles");
|
|
|
+ Vector3[] vertices = jobs[i].vertices.Take(verticeCount).ToArray();
|
|
|
+ int[] triangles = jobs[i].triangles.Take(trianglesCount).ToArray();
|
|
|
+ Color[] vertexColors = jobs[i].vertexColors.Take(verticeCount).ToArray();
|
|
|
+ BuildMesh(target, vertices, triangles, vertexColors);
|
|
|
+ // Remove this
|
|
|
+ jobs[i].blocks.Dispose();
|
|
|
+ jobs[i].codes.Dispose();
|
|
|
+ jobs[i].vertices.Dispose();
|
|
|
+ jobs[i].triangles.Dispose();
|
|
|
+ jobs[i].arrayIndexes.Dispose();
|
|
|
+ jobs[i].triangleTable.Dispose();
|
|
|
+ jobs.RemoveAt(i);
|
|
|
+ jobHandles.RemoveAt(i);
|
|
|
+ i -= 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public bool IsGeneratorDone() => jobHandles.Count == 0 ? true : false;
|
|
|
+
|
|
|
+ public void Generate(ChunkSystem<BlockBase> chunkSystem, Vector3 initialPosition = new Vector3())
|
|
|
+ {
|
|
|
+ Debug.Log("Generating chunk " + initialPosition);
|
|
|
+ this.chunkSystem = chunkSystem;
|
|
|
+ width = chunkSystem.chunkSize.x;
|
|
|
+ length = chunkSystem.chunkSize.z;
|
|
|
+ height = chunkSystem.chunkSize.y;
|
|
|
+ voxelSize = chunkSystem.voxelSize;
|
|
|
+ //transform.tag = "Terrain";
|
|
|
+ terrainMap = new float[width + 1, height + 1, length + 1];
|
|
|
+ terrainCodes = new uint[width + 1, height + 1, length + 1];
|
|
|
+ PopulateTerrainMap(chunkSystem, initialPosition);
|
|
|
+ ScheduleJob(initialPosition);
|
|
|
+ //CreateMeshData();
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ void PopulateTerrainMap (ChunkSystem<BlockBase> chunkSystem, Vector3 initialPosition = new Vector3())
|
|
|
+ {
|
|
|
+ // The data points for terrain are stored at the corners of our "cubes", so the terrainMap needs to be 1 larger
|
|
|
+ // than the width/height of our mesh.
|
|
|
+ for (int x = 0; x < width + 1; x++) {
|
|
|
+ for (int z = 0; z < length + 1; z++) {
|
|
|
+ for (int y = 0; y < height + 1; y++) {
|
|
|
+ Vector3 pos = initialPosition + new Vector3(x * voxelSize.x, y * voxelSize.y, z * voxelSize.z);
|
|
|
+ BlockBase block = chunkSystem.GetBlock(pos);
|
|
|
+ // Set the value of this point in the terrainMap.
|
|
|
+ terrainMap[x, y, z] = (float)pos.y - ((float)block.value * voxelSize.y);
|
|
|
+ terrainCodes[x, y, z] = block.code;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ void BuildMesh (GameObject target, Vector3[] vertices, int[] triangles, Color[] vertexColors)
|
|
|
+ {
|
|
|
+ //Debug.Log($"Building mesh with {vertices.Length} vertices and {triangles.Length} triangles");
|
|
|
+ MeshRenderer meshRederer = target.GetComponent<MeshRenderer>();
|
|
|
+ if(meshRederer == null) meshRederer = target.AddComponent<MeshRenderer>();
|
|
|
+ meshRederer.sharedMaterial = material;
|
|
|
+ MeshFilter meshFilter = target.GetComponent<MeshFilter>();
|
|
|
+ if(meshFilter == null) meshFilter = target.AddComponent<MeshFilter>();
|
|
|
+ MeshCollider meshCollider = target.GetComponent<MeshCollider>();
|
|
|
+ if(meshCollider == null) meshCollider = target.AddComponent<MeshCollider>();
|
|
|
+ Mesh mesh = new Mesh();
|
|
|
+ mesh.vertices = vertices;
|
|
|
+ mesh.triangles = triangles;
|
|
|
+ mesh.colors = vertexColors;
|
|
|
+ mesh.RecalculateNormals();
|
|
|
+ meshFilter.mesh = mesh;
|
|
|
+ meshCollider.sharedMesh = mesh;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void ScheduleJob(Vector3 initialPosition)
|
|
|
+ {
|
|
|
+ JobHandle jobHandle = new JobHandle();
|
|
|
+ var marchingCubesJob = new MarchingCubesJob4
|
|
|
+ {
|
|
|
+ chunkSize = this.chunkSystem.chunkSize,
|
|
|
+ voxelSize = this.voxelSize,
|
|
|
+ terrainSurface = terrainSurface,
|
|
|
+ smoothTerrain = smoothTerrain,
|
|
|
+ flatShaded = flatShaded,
|
|
|
+ blocks = new NativeArray<float>(terrainMap.Length, Allocator.TempJob),
|
|
|
+ codes = new NativeArray<uint>(terrainMap.Length, Allocator.TempJob),
|
|
|
+ vertices = new NativeArray<Vector3>(15000, Allocator.TempJob),
|
|
|
+ triangles = new NativeArray<int>(25000, Allocator.TempJob),
|
|
|
+ vertexColors = new NativeArray<Color>(15000, Allocator.TempJob),
|
|
|
+ arrayIndexes = new NativeArray<int>(2, Allocator.TempJob),
|
|
|
+ triangleTable = new NativeArray<int>(4096, Allocator.TempJob),
|
|
|
+ initialPosition = initialPosition
|
|
|
+ };
|
|
|
+ int blockIndex = 0;
|
|
|
+ for (int x = 0; x < width + 1; x++) {
|
|
|
+ for (int y = 0; y < height + 1; y++) {
|
|
|
+ for (int z = 0; z < length + 1; z++) {
|
|
|
+ marchingCubesJob.blocks[blockIndex] = terrainMap[x, y, z];
|
|
|
+ marchingCubesJob.codes[blockIndex] = terrainCodes[x, y, z];
|
|
|
+ blockIndex += 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ jobHandle = marchingCubesJob.Schedule(jobHandle);
|
|
|
+ jobHandles.Add(jobHandle);
|
|
|
+ jobs.Add(marchingCubesJob);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ [ExecuteInEditMode]
|
|
|
+ struct MarchingCubesJob4 : IJob
|
|
|
+ {
|
|
|
+ public Vector3Int chunkSize;
|
|
|
+ public Vector3 voxelSize;
|
|
|
+ public float terrainSurface;
|
|
|
+ public bool smoothTerrain;
|
|
|
+ public bool flatShaded;
|
|
|
+ public NativeArray<float> blocks;
|
|
|
+ public NativeArray<uint> codes;
|
|
|
+ public NativeArray<Vector3> vertices;
|
|
|
+ public NativeArray<int> triangles;
|
|
|
+ public NativeArray<Color> vertexColors;
|
|
|
+ public Vector3 initialPosition;
|
|
|
+ public NativeArray<int> arrayIndexes;
|
|
|
+ public NativeArray<int> triangleTable;
|
|
|
+
|
|
|
+ private int verticesArrayIndex;
|
|
|
+ private int trianglesArrayIndex;
|
|
|
+
|
|
|
+ public void Execute()
|
|
|
+ {
|
|
|
+ verticesArrayIndex = 0;
|
|
|
+ trianglesArrayIndex = 0;
|
|
|
+ Debug.Log("Executing job");
|
|
|
+ CreateTriangleTable();
|
|
|
+ // Loop through each "cube" in our terrain.
|
|
|
+ for (int x = 0; x < chunkSize.x; x++) {
|
|
|
+ for (int y = 0; y < chunkSize.y; y++) {
|
|
|
+ for (int z = 0; z < chunkSize.z; z++) {
|
|
|
+ // Pass the value into our MarchCube function.
|
|
|
+ MarchCube(new Vector3Int(x, y, z));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ arrayIndexes[0] = verticesArrayIndex;
|
|
|
+ arrayIndexes[1] = trianglesArrayIndex;
|
|
|
+ }
|
|
|
+
|
|
|
+ void MarchCube (Vector3Int position) {
|
|
|
+ // Sample terrain values at each corner of the cube.
|
|
|
+ float[] cube = new float[8];
|
|
|
+ for (int i = 0; i < 8; i++) {
|
|
|
+ cube[i] = SampleTerrain(position + CornerTable(i));
|
|
|
+ }
|
|
|
+ Vector3 realPosition = new Vector3(position.x * voxelSize.x, position.y * voxelSize.y, position.z * voxelSize.z);
|
|
|
+ // Get the configuration index of this cube.
|
|
|
+ int configIndex = GetCubeConfiguration(cube);
|
|
|
+ // 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.
|
|
|
+ if (configIndex == 0 || configIndex == 255) return;
|
|
|
+ // Loop through the triangles. There are never more than 5 triangles to a cube and only three vertices to a triangle.
|
|
|
+ int edgeIndex = 0;
|
|
|
+ for(int i = 0; i < 5; i++)
|
|
|
+ {
|
|
|
+ for(int p = 0; p < 3; p++)
|
|
|
+ {
|
|
|
+ // Get the current indice. We increment triangleIndex through each loop.
|
|
|
+ int indice = GetFromTriangleTable(configIndex, edgeIndex);
|
|
|
+ // If the current edgeIndex is -1, there are no more indices and we can exit the function.
|
|
|
+ if (indice == -1) return;
|
|
|
+ // Get the vertices for the start and end of this edge.
|
|
|
+ Vector3 vert1 = position + CornerTable(EdgeIndexes()[indice, 0]);
|
|
|
+ Vector3 vert2 = position + CornerTable(EdgeIndexes()[indice, 1]);
|
|
|
+ //vert1 = new Vector3(vert1.x * voxelSize.x, vert1.y * voxelSize.y, vert1.z * voxelSize.z);
|
|
|
+ //vert2 = new Vector3(vert2.x * voxelSize.x, vert2.y * voxelSize.y, vert2.z * voxelSize.z);
|
|
|
+ Vector3 vertPosition;
|
|
|
+ if (smoothTerrain) {
|
|
|
+ // Get the terrain values at either end of our current edge from the cube array created above.
|
|
|
+ float vert1Sample = cube[EdgeIndexes()[indice, 0]];
|
|
|
+ float vert2Sample = cube[EdgeIndexes()[indice, 1]];
|
|
|
+ // Calculate the difference between the terrain values.
|
|
|
+ float difference = vert2Sample - vert1Sample;
|
|
|
+ // If the difference is 0, then the terrain passes through the middle.
|
|
|
+ if (difference == 0) difference = terrainSurface;
|
|
|
+ else difference = (terrainSurface - vert1Sample) / difference;
|
|
|
+ // Calculate the point along the edge that passes through.
|
|
|
+ vertPosition = vert1 + ((vert2 - vert1) * difference);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ // Get the midpoint of this edge.
|
|
|
+ vertPosition = (vert1 + vert2) / 2f;
|
|
|
+ }
|
|
|
+ vertPosition = new Vector3(vertPosition.x * voxelSize.x, vertPosition.y * voxelSize.y, vertPosition.z * voxelSize.z);
|
|
|
+ // Add to our vertices and triangles list and incremement the edgeIndex.
|
|
|
+ if (flatShaded)
|
|
|
+ {
|
|
|
+ vertices[verticesArrayIndex] = vertPosition;
|
|
|
+ triangles[trianglesArrayIndex] = verticesArrayIndex;
|
|
|
+ vertexColors[verticesArrayIndex] = SampleTerrainColor(position);
|
|
|
+ verticesArrayIndex += 1;
|
|
|
+ trianglesArrayIndex += 1;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ triangles[trianglesArrayIndex] = VertForIndice(vertPosition, position);
|
|
|
+ trianglesArrayIndex += 1;
|
|
|
+ }
|
|
|
+ edgeIndex++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ float SampleTerrain (Vector3Int point)
|
|
|
+ {
|
|
|
+ // https://stackoverflow.com/questions/3613429/algorithm-to-convert-a-multi-dimensional-array-to-a-one-dimensional-array
|
|
|
+ int index = (((chunkSize.y + 1) * (chunkSize.z + 1)) * point.x) + ((chunkSize.z + 1) * point.y) + point.z;
|
|
|
+ return blocks[index];
|
|
|
+ }
|
|
|
+
|
|
|
+ Color SampleTerrainColor (Vector3Int point)
|
|
|
+ {
|
|
|
+ int index = (((chunkSize.y + 1) * (chunkSize.z + 1)) * point.x) + ((chunkSize.z + 1) * point.y) + point.z;
|
|
|
+ uint code = codes[index];
|
|
|
+ switch (code)
|
|
|
+ {
|
|
|
+ default:
|
|
|
+ case 0:
|
|
|
+ return Color.white;
|
|
|
+ case 1:
|
|
|
+ return Color.red;
|
|
|
+ case 2:
|
|
|
+ return Color.green;
|
|
|
+ case 3:
|
|
|
+ return Color.blue;
|
|
|
+ case 4:
|
|
|
+ return Color.black;
|
|
|
+ case 5:
|
|
|
+ return Color.yellow;
|
|
|
+ case 6:
|
|
|
+ return new Color(1f, 0, 1f); // Purple
|
|
|
+ case 7:
|
|
|
+ return new Color(0f, 1f, 1f); // Purple
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ int GetCubeConfiguration (float[] cube)
|
|
|
+ {
|
|
|
+ // Starting with a configuration of zero, loop through each point in the cube and check if it is below the terrain surface.
|
|
|
+ int configurationIndex = 0;
|
|
|
+ for (int i = 0; i < 8; i++) {
|
|
|
+ // 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
|
|
|
+ // the surface, the bit would look like 00100000, which represents the integer value 32.
|
|
|
+ if (cube[i] > terrainSurface)
|
|
|
+ configurationIndex |= 1 << i;
|
|
|
+ }
|
|
|
+ return configurationIndex;
|
|
|
+ }
|
|
|
+
|
|
|
+ int VertForIndice (Vector3 vert, Vector3Int point)
|
|
|
+ {
|
|
|
+ // Loop through all the vertices currently in the vertices list.
|
|
|
+ for (int i = 0; i < verticesArrayIndex; i++)
|
|
|
+ {
|
|
|
+ // If we find a vert that matches ours, then simply return this index.
|
|
|
+ if (vertices[i] == vert) return i;
|
|
|
+ }
|
|
|
+ // If we didn't find a match, add this vert to the list and return last index.
|
|
|
+ vertices[verticesArrayIndex] = vert;
|
|
|
+ vertexColors[verticesArrayIndex] = SampleTerrainColor(point);
|
|
|
+ verticesArrayIndex += 1;
|
|
|
+ return verticesArrayIndex - 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Vector3Int[] CornerTable;
|
|
|
+ // int[,] EdgeIndexes;
|
|
|
+ // private int[,] TriangleTable;
|
|
|
+
|
|
|
+ private Vector3Int CornerTable(int index)
|
|
|
+ {
|
|
|
+ Vector3Int[] CornerTable = new Vector3Int[8] {
|
|
|
+ new Vector3Int(0, 0, 0),
|
|
|
+ new Vector3Int(1, 0, 0),
|
|
|
+ new Vector3Int(1, 1, 0),
|
|
|
+ new Vector3Int(0, 1, 0),
|
|
|
+ new Vector3Int(0, 0, 1),
|
|
|
+ new Vector3Int(1, 0, 1),
|
|
|
+ new Vector3Int(1, 1, 1),
|
|
|
+ new Vector3Int(0, 1, 1)
|
|
|
+ };
|
|
|
+ return CornerTable[index];
|
|
|
+ }
|
|
|
+
|
|
|
+ private int[,] EdgeIndexes()
|
|
|
+ {
|
|
|
+ int[,] EdgeIndexes = new int[12, 2] {
|
|
|
+ {0, 1}, {1, 2}, {3, 2}, {0, 3}, {4, 5}, {5, 6}, {7, 6}, {4, 7}, {0, 4}, {1, 5}, {2, 6}, {3, 7}
|
|
|
+ };
|
|
|
+ return EdgeIndexes;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void CreateTriangleTable()
|
|
|
+ {
|
|
|
+ int[,] table = TriangleTable();
|
|
|
+ int index = 0;
|
|
|
+ for (int x = 0; x < table.GetLength(0); x++)
|
|
|
+ {
|
|
|
+ for (int y = 0; y < table.GetLength(1); y++)
|
|
|
+ {
|
|
|
+ triangleTable[index] = table[x, y];
|
|
|
+ index += 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private int GetFromTriangleTable(int x, int y)
|
|
|
+ {
|
|
|
+ return triangleTable[x * 16 + y];
|
|
|
+ }
|
|
|
+
|
|
|
+ private int[,] TriangleTable()
|
|
|
+ {
|
|
|
+ int[,] TriangleTable = new int[,]
|
|
|
+ {
|
|
|
+ {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {0, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {1, 8, 3, 9, 8, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {0, 8, 3, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {9, 2, 10, 0, 2, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {2, 8, 3, 2, 10, 8, 10, 9, 8, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {0, 11, 2, 8, 11, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {1, 9, 0, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {1, 11, 2, 1, 9, 11, 9, 8, 11, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {3, 10, 1, 11, 10, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {0, 10, 1, 0, 8, 10, 8, 11, 10, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {3, 9, 0, 3, 11, 9, 11, 10, 9, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {9, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {4, 3, 0, 7, 3, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {0, 1, 9, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {4, 1, 9, 4, 7, 1, 7, 3, 1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {1, 2, 10, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {3, 4, 7, 3, 0, 4, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {9, 2, 10, 9, 0, 2, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4, -1, -1, -1, -1},
|
|
|
+ {8, 4, 7, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {11, 4, 7, 11, 2, 4, 2, 0, 4, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {9, 0, 1, 8, 4, 7, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1, -1, -1, -1, -1},
|
|
|
+ {3, 10, 1, 3, 11, 10, 7, 8, 4, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4, -1, -1, -1, -1},
|
|
|
+ {4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3, -1, -1, -1, -1},
|
|
|
+ {4, 7, 11, 4, 11, 9, 9, 11, 10, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {9, 5, 4, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {0, 5, 4, 1, 5, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {8, 5, 4, 8, 3, 5, 3, 1, 5, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {1, 2, 10, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {3, 0, 8, 1, 2, 10, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {5, 2, 10, 5, 4, 2, 4, 0, 2, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8, -1, -1, -1, -1},
|
|
|
+ {9, 5, 4, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {0, 11, 2, 0, 8, 11, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {0, 5, 4, 0, 1, 5, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5, -1, -1, -1, -1},
|
|
|
+ {10, 3, 11, 10, 1, 3, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11, 10, -1, -1, -1, -1},
|
|
|
+ {5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3, -1, -1, -1, -1},
|
|
|
+ {5, 4, 8, 5, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {9, 7, 8, 5, 7, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {9, 3, 0, 9, 5, 3, 5, 7, 3, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {0, 7, 8, 0, 1, 7, 1, 5, 7, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {1, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {9, 7, 8, 9, 5, 7, 10, 1, 2, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3, -1, -1, -1, -1},
|
|
|
+ {8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2, -1, -1, -1, -1},
|
|
|
+ {2, 10, 5, 2, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {7, 9, 5, 7, 8, 9, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11, -1, -1, -1, -1},
|
|
|
+ {2, 3, 11, 0, 1, 8, 1, 7, 8, 1, 5, 7, -1, -1, -1, -1},
|
|
|
+ {11, 2, 1, 11, 1, 7, 7, 1, 5, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {9, 5, 8, 8, 5, 7, 10, 1, 3, 10, 3, 11, -1, -1, -1, -1},
|
|
|
+ {5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10, 11, 10, 0, -1},
|
|
|
+ {11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7, 0, -1},
|
|
|
+ {11, 10, 5, 7, 11, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {0, 8, 3, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {9, 0, 1, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {1, 8, 3, 1, 9, 8, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {1, 6, 5, 2, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {1, 6, 5, 1, 2, 6, 3, 0, 8, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {9, 6, 5, 9, 0, 6, 0, 2, 6, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, -1, -1, -1, -1},
|
|
|
+ {2, 3, 11, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {11, 0, 8, 11, 2, 0, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {0, 1, 9, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {5, 10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11, -1, -1, -1, -1},
|
|
|
+ {6, 3, 11, 6, 5, 3, 5, 1, 3, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6, -1, -1, -1, -1},
|
|
|
+ {3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9, -1, -1, -1, -1},
|
|
|
+ {6, 5, 9, 6, 9, 11, 11, 9, 8, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {5, 10, 6, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {4, 3, 0, 4, 7, 3, 6, 5, 10, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {1, 9, 0, 5, 10, 6, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, -1, -1, -1, -1},
|
|
|
+ {6, 1, 2, 6, 5, 1, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7, -1, -1, -1, -1},
|
|
|
+ {8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6, -1, -1, -1, -1},
|
|
|
+ {7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9, -1},
|
|
|
+ {3, 11, 2, 7, 8, 4, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11, -1, -1, -1, -1},
|
|
|
+ {0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1},
|
|
|
+ {9, 2, 1, 9, 11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6, -1},
|
|
|
+ {8, 4, 7, 3, 11, 5, 3, 5, 1, 5, 11, 6, -1, -1, -1, -1},
|
|
|
+ {5, 1, 11, 5, 11, 6, 1, 0, 11, 7, 11, 4, 0, 4, 11, -1},
|
|
|
+ {0, 5, 9, 0, 6, 5, 0, 3, 6, 11, 6, 3, 8, 4, 7, -1},
|
|
|
+ {6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9, -1, -1, -1, -1},
|
|
|
+ {10, 4, 9, 6, 4, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {4, 10, 6, 4, 9, 10, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {10, 0, 1, 10, 6, 0, 6, 4, 0, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10, -1, -1, -1, -1},
|
|
|
+ {1, 4, 9, 1, 2, 4, 2, 6, 4, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4, -1, -1, -1, -1},
|
|
|
+ {0, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {8, 3, 2, 8, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {10, 4, 9, 10, 6, 4, 11, 2, 3, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6, -1, -1, -1, -1},
|
|
|
+ {3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, 10, -1, -1, -1, -1},
|
|
|
+ {6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, 8, 11, 1, -1},
|
|
|
+ {9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3, -1, -1, -1, -1},
|
|
|
+ {8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1, -1},
|
|
|
+ {3, 11, 6, 3, 6, 0, 0, 6, 4, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {6, 4, 8, 11, 6, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {7, 10, 6, 7, 8, 10, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10, -1, -1, -1, -1},
|
|
|
+ {10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0, -1, -1, -1, -1},
|
|
|
+ {10, 6, 7, 10, 7, 1, 1, 7, 3, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7, -1, -1, -1, -1},
|
|
|
+ {2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9, -1},
|
|
|
+ {7, 8, 0, 7, 0, 6, 6, 0, 2, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {7, 3, 2, 6, 7, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7, -1, -1, -1, -1},
|
|
|
+ {2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7, -1},
|
|
|
+ {1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11, -1},
|
|
|
+ {11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1, -1, -1, -1, -1},
|
|
|
+ {8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6, -1},
|
|
|
+ {0, 9, 1, 11, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {7, 8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0, -1, -1, -1, -1},
|
|
|
+ {7, 11, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {3, 0, 8, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {0, 1, 9, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {8, 1, 9, 8, 3, 1, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {10, 1, 2, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {1, 2, 10, 3, 0, 8, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {2, 9, 0, 2, 10, 9, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, 8, -1, -1, -1, -1},
|
|
|
+ {7, 2, 3, 6, 2, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {7, 0, 8, 7, 6, 0, 6, 2, 0, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {2, 7, 6, 2, 3, 7, 0, 1, 9, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6, -1, -1, -1, -1},
|
|
|
+ {10, 7, 6, 10, 1, 7, 1, 3, 7, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8, -1, -1, -1, -1},
|
|
|
+ {0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7, -1, -1, -1, -1},
|
|
|
+ {7, 6, 10, 7, 10, 8, 8, 10, 9, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {6, 8, 4, 11, 8, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {3, 6, 11, 3, 0, 6, 0, 4, 6, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {8, 6, 11, 8, 4, 6, 9, 0, 1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6, -1, -1, -1, -1},
|
|
|
+ {6, 8, 4, 6, 11, 8, 2, 10, 1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {1, 2, 10, 3, 0, 11, 0, 6, 11, 0, 4, 6, -1, -1, -1, -1},
|
|
|
+ {4, 11, 8, 4, 6, 11, 0, 2, 9, 2, 10, 9, -1, -1, -1, -1},
|
|
|
+ {10, 9, 3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3, -1},
|
|
|
+ {8, 2, 3, 8, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {0, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {1, 9, 0, 2, 3, 4, 2, 4, 6, 4, 3, 8, -1, -1, -1, -1},
|
|
|
+ {1, 9, 4, 1, 4, 2, 2, 4, 6, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1, -1, -1, -1, -1},
|
|
|
+ {10, 1, 0, 10, 0, 6, 6, 0, 4, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {4, 6, 3, 4, 3, 8, 6, 10, 3, 0, 3, 9, 10, 9, 3, -1},
|
|
|
+ {10, 9, 4, 6, 10, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {4, 9, 5, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {0, 8, 3, 4, 9, 5, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {5, 0, 1, 5, 4, 0, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {11, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5, -1, -1, -1, -1},
|
|
|
+ {9, 5, 4, 10, 1, 2, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {6, 11, 7, 1, 2, 10, 0, 8, 3, 4, 9, 5, -1, -1, -1, -1},
|
|
|
+ {7, 6, 11, 5, 4, 10, 4, 2, 10, 4, 0, 2, -1, -1, -1, -1},
|
|
|
+ {3, 4, 8, 3, 5, 4, 3, 2, 5, 10, 5, 2, 11, 7, 6, -1},
|
|
|
+ {7, 2, 3, 7, 6, 2, 5, 4, 9, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7, -1, -1, -1, -1},
|
|
|
+ {3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0, -1, -1, -1, -1},
|
|
|
+ {6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8, -1},
|
|
|
+ {9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7, -1, -1, -1, -1},
|
|
|
+ {1, 6, 10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4, -1},
|
|
|
+ {4, 0, 10, 4, 10, 5, 0, 3, 10, 6, 10, 7, 3, 7, 10, -1},
|
|
|
+ {7, 6, 10, 7, 10, 8, 5, 4, 10, 4, 8, 10, -1, -1, -1, -1},
|
|
|
+ {6, 9, 5, 6, 11, 9, 11, 8, 9, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5, -1, -1, -1, -1},
|
|
|
+ {0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11, -1, -1, -1, -1},
|
|
|
+ {6, 11, 3, 6, 3, 5, 5, 3, 1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6, -1, -1, -1, -1},
|
|
|
+ {0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10, -1},
|
|
|
+ {11, 8, 5, 11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5, -1},
|
|
|
+ {6, 11, 3, 6, 3, 5, 2, 10, 3, 10, 5, 3, -1, -1, -1, -1},
|
|
|
+ {5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2, -1, -1, -1, -1},
|
|
|
+ {9, 5, 6, 9, 6, 0, 0, 6, 2, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {1, 5, 8, 1, 8, 0, 5, 6, 8, 3, 8, 2, 6, 2, 8, -1},
|
|
|
+ {1, 5, 6, 2, 1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {1, 3, 6, 1, 6, 10, 3, 8, 6, 5, 6, 9, 8, 9, 6, -1},
|
|
|
+ {10, 1, 0, 10, 0, 6, 9, 5, 0, 5, 6, 0, -1, -1, -1, -1},
|
|
|
+ {0, 3, 8, 5, 6, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {10, 5, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {11, 5, 10, 7, 5, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {11, 5, 10, 11, 7, 5, 8, 3, 0, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {5, 11, 7, 5, 10, 11, 1, 9, 0, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {10, 7, 5, 10, 11, 7, 9, 8, 1, 8, 3, 1, -1, -1, -1, -1},
|
|
|
+ {11, 1, 2, 11, 7, 1, 7, 5, 1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 11, -1, -1, -1, -1},
|
|
|
+ {9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7, -1, -1, -1, -1},
|
|
|
+ {7, 5, 2, 7, 2, 11, 5, 9, 2, 3, 2, 8, 9, 8, 2, -1},
|
|
|
+ {2, 5, 10, 2, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5, -1, -1, -1, -1},
|
|
|
+ {9, 0, 1, 5, 10, 3, 5, 3, 7, 3, 10, 2, -1, -1, -1, -1},
|
|
|
+ {9, 8, 2, 9, 2, 1, 8, 7, 2, 10, 2, 5, 7, 5, 2, -1},
|
|
|
+ {1, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {0, 8, 7, 0, 7, 1, 1, 7, 5, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {9, 0, 3, 9, 3, 5, 5, 3, 7, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {9, 8, 7, 5, 9, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {5, 8, 4, 5, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0, -1, -1, -1, -1},
|
|
|
+ {0, 1, 9, 8, 4, 10, 8, 10, 11, 10, 4, 5, -1, -1, -1, -1},
|
|
|
+ {10, 11, 4, 10, 4, 5, 11, 3, 4, 9, 4, 1, 3, 1, 4, -1},
|
|
|
+ {2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8, -1, -1, -1, -1},
|
|
|
+ {0, 4, 11, 0, 11, 3, 4, 5, 11, 2, 11, 1, 5, 1, 11, -1},
|
|
|
+ {0, 2, 5, 0, 5, 9, 2, 11, 5, 4, 5, 8, 11, 8, 5, -1},
|
|
|
+ {9, 4, 5, 2, 11, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4, -1, -1, -1, -1},
|
|
|
+ {5, 10, 2, 5, 2, 4, 4, 2, 0, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {3, 10, 2, 3, 5, 10, 3, 8, 5, 4, 5, 8, 0, 1, 9, -1},
|
|
|
+ {5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2, -1, -1, -1, -1},
|
|
|
+ {8, 4, 5, 8, 5, 3, 3, 5, 1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {0, 4, 5, 1, 0, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5, -1, -1, -1, -1},
|
|
|
+ {9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {4, 11, 7, 4, 9, 11, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11, -1, -1, -1, -1},
|
|
|
+ {1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11, -1, -1, -1, -1},
|
|
|
+ {3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4, -1},
|
|
|
+ {4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2, -1, -1, -1, -1},
|
|
|
+ {9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3, -1},
|
|
|
+ {11, 7, 4, 11, 4, 2, 2, 4, 0, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4, -1, -1, -1, -1},
|
|
|
+ {2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9, -1, -1, -1, -1},
|
|
|
+ {9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7, -1},
|
|
|
+ {3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10, -1},
|
|
|
+ {1, 10, 2, 8, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {4, 9, 1, 4, 1, 7, 7, 1, 3, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, -1, -1, -1, -1},
|
|
|
+ {4, 0, 3, 7, 4, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {4, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {9, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {3, 0, 9, 3, 9, 11, 11, 9, 10, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {0, 1, 10, 0, 10, 8, 8, 10, 11, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {3, 1, 10, 11, 3, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {1, 2, 11, 1, 11, 9, 9, 11, 8, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9, -1, -1, -1, -1},
|
|
|
+ {0, 2, 11, 8, 0, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {3, 2, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {2, 3, 8, 2, 8, 10, 10, 8, 9, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {9, 10, 2, 0, 9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8, -1, -1, -1, -1},
|
|
|
+ {1, 10, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {1, 3, 8, 9, 1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {0, 3, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
|
|
+ {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}
|
|
|
+ };
|
|
|
+ return TriangleTable;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|