//This function is responsible for making a BlockMesh from the given convex Block //Method is from the link: https://www.habrador.com/tutorials/math/10-triangulation/ private void ConvexTriangulation(Block block) { BlockMesh convexMesh = new BlockMesh(block); for (int i = 2; i < block.Nodes.Count; i++) { Vector3 a = new Vector3(block.Nodes[0].X, block.Nodes[0].Y, 0); //For gizmos, we make the Vectors like this now, later Y goes to Z (Y is up) Vector3 b = new Vector3(block.Nodes[i - 1].X, block.Nodes[i - 1].Y, 0); Vector3 c = new Vector3(block.Nodes[i].X, block.Nodes[i].Y, 0); convexMesh.AddTriangle(a, b, c); } BlockMeshes.Add(convexMesh); }
//This function is responsible for making a BlockMesh from the given concave Block //The points on the polygon should be ordered counter-clockwise, Triangulation is made with ear-clipping //Method is from the link: https://www.habrador.com/tutorials/math/10-triangulation/ private void ConcaveTriangulation(Block block) { //Step 0. Check if the block stores the vertexes counter clockwise or not bool counterClockwise = IsCounterClockwise(block); //The list with triangles, that the ear clipping algorithm will generate List <Triangle> triangles = new List <Triangle>(); //Step 1. Store the vertices in a list and we also need to know the next and prev vertex List <Vertex> vertices = new List <Vertex>(); if (counterClockwise) { for (int i = 0; i < block.Nodes.Count; i++) { vertices.Add(new Vertex(new Vector3(block.Nodes[i].X, 0f, block.Nodes[i].Y))); } } else //The method requires the vertex list to be counter-clockwise { for (int i = block.Nodes.Count - 1; i > -1; i--) { vertices.Add(new Vertex(new Vector3(block.Nodes[i].X, 0f, block.Nodes[i].Y))); } } //Find the next and previous vertex vertices[0].PrevVertex = vertices[vertices.Count - 1]; vertices[0].NextVertex = vertices[1]; vertices[vertices.Count - 1].PrevVertex = vertices[vertices.Count - 2]; vertices[vertices.Count - 1].NextVertex = vertices[0]; for (int i = 1; i < vertices.Count - 1; i++) { vertices[i].PrevVertex = vertices[i - 1]; vertices[i].NextVertex = vertices[i + 1]; } //Step 2. Find the reflex (concave) and convex vertices, and ear vertices for (int i = 0; i < vertices.Count; i++) { CheckIfReflexOrConvex(vertices[i]); } //Have to find the ears after we have found if the vertex is reflex or convex List <Vertex> earVertices = new List <Vertex>(); for (int i = 0; i < vertices.Count; i++) { IsVertexEar(vertices[i], vertices, earVertices); } //Step 3. Triangulate! while (true) { //This means we have just one triangle left if (vertices.Count == 3) { //The final triangle triangles.Add(new Triangle(vertices[0].Position, vertices[0].PrevVertex.Position, vertices[0].NextVertex.Position)); break; } if (earVertices.Count == 0) { Debug.Log("earVertices not found, Triangulation failed."); break; } //Make a triangle of the first ear Vertex earVertex = earVertices[0]; Vertex earVertexPrev = earVertex.PrevVertex; Vertex earVertexNext = earVertex.NextVertex; Triangle newTriangle = new Triangle(earVertex.Position, earVertexPrev.Position, earVertexNext.Position); triangles.Add(newTriangle); //Remove the vertex from the lists earVertices.Remove(earVertex); vertices.Remove(earVertex); //Update the previous vertex and next vertex earVertexPrev.NextVertex = earVertexNext; earVertexNext.PrevVertex = earVertexPrev; //...see if we have found a new ear by investigating the two vertices that was part of the ear CheckIfReflexOrConvex(earVertexPrev); CheckIfReflexOrConvex(earVertexNext); earVertices.Remove(earVertexPrev); earVertices.Remove(earVertexNext); IsVertexEar(earVertexPrev, vertices, earVertices); IsVertexEar(earVertexNext, vertices, earVertices); } //Step4 insert the triangles inside the BlockMesh BlockMesh concaveMesh = new BlockMesh(block); foreach (Triangle tri in triangles) { Vector3 A = new Vector3(tri.A.x, tri.A.z, tri.A.y); //We want to draw the blockMeshes as gizmos right now! (up is z right now in the 2d model) Vector3 B = new Vector3(tri.B.x, tri.B.z, tri.B.y); Vector3 C = new Vector3(tri.C.x, tri.C.z, tri.C.y); concaveMesh.Triangles.Add(new Triangle(A, B, C)); } BlockMeshes.Add(concaveMesh); }