123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662 |
- 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 ChunkTerrainGenerator chunkTerrainGenerator;
- 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) return;
- 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);
- //chunkTerrainGenerator.terrainMeshes[jobs[i].initialPosition] = target;
- chunkTerrainGenerator.AddGeneratedTerrainMesh(jobs[i].initialPosition, target);
- // Remove this
- jobs[i].blocks.Dispose();
- jobs[i].codes.Dispose();
- jobs[i].vertices.Dispose();
- jobs[i].triangles.Dispose();
- jobs[i].vertexColors.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 int GetJobCount() => jobHandles.Count;
- public void Generate(ChunkSystem<BlockBase> chunkSystem, ChunkTerrainGenerator chunkTerrainGenerator, 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;
- this.chunkTerrainGenerator = chunkTerrainGenerator;
- //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/1000);
- 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;
- }
- }
- }
|