using System.Collections.Generic; using UnityEngine; using BrainFailProductions.PolyFew.AsImpL.MathUtil; namespace BrainFailProductions.PolyFew.AsImpL { /// /// Implements triangulation of a face of a data set. /// public static class Triangulator { /// /// Triangulate a face of the given dataset. /// /// Input data set. /// Face to be triangulated (with more than 3 vertices) public static void Triangulate(DataSet dataSet, DataSet.FaceIndices[] face) { int numVerts = face.Length; //Debug.LogFormat("Triangulating a face with {0} vertices of {1}...", numVerts, dataSet.CurrGroupName); Vector3 planeNormal = FindPlaneNormal(dataSet, face); // setup the data structure used for triangluation List poly = new List(); for (int i = 0; i < numVerts; i++) { int idx = face[i].vertIdx; poly.Add(new MathUtil.Vertex(i, dataSet.vertList[idx])); } // use the ear clipping triangulation List newTris = Triangulation.TriangulateByEarClipping(poly, planeNormal, dataSet.CurrGroupName); // copy the data structure used for triangluation back to the data set for (int t = 0; t < newTris.Count; t++) { int idx1 = newTris[t].v1.OriginalIndex; int idx2 = newTris[t].v2.OriginalIndex; int idx3 = newTris[t].v3.OriginalIndex; dataSet.AddFaceIndices(face[idx1]); dataSet.AddFaceIndices(face[idx3]); dataSet.AddFaceIndices(face[idx2]); } } /// /// Get a normal of a plane used for polygon projection. /// /// Input data set. /// Face to be triangulated /// The mean of the normals if available or a vector perpendicular to the first triangle public static Vector3 FindPlaneNormal(DataSet dataSet, DataSet.FaceIndices[] face) { int vertCount = face.Length; bool hasNormals = dataSet.normalList.Count > 0; Vector3 planeNormal = Vector3.zero; if (hasNormals) { // if it has normals use the mean of the normals of the vertices for (int i = 0; i < vertCount; i++) { int normalIdx = face[i].normIdx; planeNormal += dataSet.normalList[normalIdx]; } planeNormal.Normalize(); } else { // else calculate a vector perpendicular to the first triangle Vector3 v0 = dataSet.vertList[face[0].vertIdx]; Vector3 v1 = dataSet.vertList[face[1].vertIdx]; Vector3 vn = dataSet.vertList[face[vertCount - 1].vertIdx]; planeNormal = MathUtility.ComputeNormal(v0, v1, vn); } return planeNormal; } } }