using UnityEngine; using System.Collections.Generic; using System; namespace AutoTiling { public class MeshData { private List vertices = new List(); private List normals = new List(); private List[] triangles = new List[1]; private List uv = new List(); private List uv2 = new List(); private List tangents = new List(); public List Vertices { get { return vertices; } } public List Normals { get { return normals; } } public List[] Triangles { get { return triangles; } } public List UV { get { return uv; } } public List UV2 { get { return uv2; } } public List Tangents { get { return tangents; } } public int subMeshCount { get { return triangles.Length; } set { List[] newTriangleList = new List[value]; for (int i = 0; i < newTriangleList.Length; i++) { if (i < triangles.Length) { newTriangleList[i] = triangles[i]; } else { newTriangleList[i] = new List(); } } triangles = newTriangleList; // Debug.Log ("Setting SubMeshCount to " + triangles.Length); } } public MeshData() { triangles = new List[1]; triangles[0] = new List(); } public MeshData(List vertices, List normals, List[] triangles, List uv, List uv2, List tangents) { this.vertices = vertices; this.normals = normals; this.triangles = triangles; this.uv = uv; this.uv2 = uv2; this.tangents = tangents; } public MeshData Copy() { List[] newTriangles = new List[triangles.Length]; for (int i = 0; i < triangles.Length; i++) { newTriangles[i] = new List(triangles[i]); } return new MeshData(new List(vertices), new List(normals), newTriangles, new List(uv), new List(uv2), new List(tangents)); } public void AddQuadTriangles() { if (triangles == null || triangles.Length < 1) { triangles = new List[1]; } if (triangles[0] == null) { triangles[0] = new List(); } if (triangles == null) { Debug.LogError("triangles were not set!"); return; } if (triangles[0] == null) { Debug.LogError("triangles[0] was not set!"); return; } if (vertices == null) { Debug.LogError("Vertices were not set!"); return; } triangles[0].Add(vertices.Count - 4); triangles[0].Add(vertices.Count - 3); triangles[0].Add(vertices.Count - 2); triangles[0].Add(vertices.Count - 4); triangles[0].Add(vertices.Count - 2); triangles[0].Add(vertices.Count - 1); } public void AddTriangle(int tri) { if (triangles == null || triangles.Length < 1) { triangles = new List[1]; triangles[0] = new List(); } // Debug.Log (GetType() + ".AddTriangle: Adding Triangle " + tri + " without specific material index."); triangles[0].Add(tri); } public void AddTriangle(int tri, int materialIndex) { if (materialIndex >= triangles.Length) { if (materialIndex > 0) { Debug.LogError(GetType() + ".AddTriangle: the material index is too high, set subMeshCount first."); return; } else { AddTriangle(tri); return; } } if (triangles[materialIndex] == null) { triangles[materialIndex] = new List(); } // Debug.Log (GetType() + ".AddTriangle: Adding Triangle " + tri + " to material: " + materialIndex); triangles[materialIndex].Add(tri); } public void SetTriangles(Mesh mesh) { this.triangles = new List[mesh.subMeshCount]; if (mesh == null) { this.triangles[0] = new List(); return; } for (int i = 0; i < mesh.subMeshCount; i++) { int[] triangles = mesh.GetTriangles(i); if (triangles == null) { this.triangles[i] = new List(); } else { this.triangles[i] = new List(mesh.GetTriangles(i)); } } } public void SetTriangles(int[] newTriangles) { if (newTriangles == null) { this.triangles[0] = new List(); return; } this.triangles[0] = new List(newTriangles); } public void AddVertex(Vector3 vertex) { vertices.Add(vertex); } private void RemoveVertices(Dictionary vertexIndexDict) { //vertexIndexDict.Sort( // delegate (VertexIndexReplacePair x, VertexIndexReplacePair y) { // if (x.indexToReplace < y.indexToReplace) { // return 1; // } // else if (x.indexToReplace > y.indexToReplace) { // return -1; // } // else { // return 0; // } // } //); for (int indexToReplace = vertices.Count - 1; indexToReplace >= 0; indexToReplace--) { if (vertexIndexDict.ContainsKey(indexToReplace)) { //Debug.Log("Trying to replace double vertex " + indexToReplace + " with vertex index " + vertexIndexDict[indexToReplace]); if (normals.Count > indexToReplace) { normals.RemoveAt(indexToReplace); } if (vertices.Count > indexToReplace) { vertices.RemoveAt(indexToReplace); } if (tangents.Count > indexToReplace) { tangents.RemoveAt(indexToReplace); } if (uv.Count > indexToReplace) { uv.RemoveAt(indexToReplace); } if (uv2.Count > indexToReplace) { uv2.RemoveAt(indexToReplace); //Debug.Log("Removed uv2 coordinate"); } //List triangleList = new List(triangles); for (int m = 0; m < triangles.Length; m++) { for (int t = 0; t < triangles[m].Count; t++) { if (triangles[m][t] == indexToReplace) { triangles[m][t] = vertexIndexDict[indexToReplace]; } else if (triangles[m][t] > indexToReplace) { //Debug.Log("Reducing index: " + triangles[m][t] + " to " + (triangles[m][t] - 1)); triangles[m][t]--; } } } } } } public void SetVertices(Vector3[] newVertices) { if (newVertices == null) { vertices = new List(); return; } vertices = new List(newVertices); } public void AddNormal(Vector3 normal) { normals.Add(normal); } public void SetNormals(Vector3[] newNormals) { if (newNormals == null) { normals = new List(); return; } normals = new List(newNormals); } public void AddTangent(Vector4 tangent) { tangents.Add(tangent); } public void SetTangents(Vector4[] newTangents) { if (newTangents == null) { tangents = new List(); return; } tangents = new List(newTangents); } public void AddUVCoordinates(Vector2[] uvCoordinates) { uv.AddRange(uvCoordinates); } public void AddUVCoordinate(Vector2 uvCoordinate) { // Debug.Log ("Adding UV Coordinate: " + uvCoordinate); uv.Add(uvCoordinate); } public void SetUV2Coordinates(Vector2[] uvCoordinates) { if (uvCoordinates == null) { uv2 = new List(); return; } uv2 = new List(uvCoordinates); } public void AddUV2Coordinate(Vector2 coordinate) { uv2.Add(coordinate); } public void RemoveDoubles(bool checkForDifferingUV2coords = false) { Dictionary doubleVertexIndices = new Dictionary(); for (int i = vertices.Count - 1; i >= 0; i--) { if (i >= normals.Count || i >= tangents.Count || (checkForDifferingUV2coords && i >= uv2.Count)) { //Debug.Log("Index out of range for i: " + i); // Handle index out of range error, possibly by breaking out of the loop or other appropriate action. break; } for (int j = 0; j < vertices.Count && j < i; j++) { if (j >= normals.Count || j >= tangents.Count || (checkForDifferingUV2coords && j >= uv2.Count)) { Debug.Log("Index out of range for j: " + j); // Handle index out of range error, possibly by breaking out of the loop or other appropriate action. break; } if (vertices[i] == vertices[j] && normals[i] == normals[j] && tangents[i] == tangents[j] && (!checkForDifferingUV2coords || (checkForDifferingUV2coords && uv2[i] == uv2[j]))) { doubleVertexIndices[i] = j; break; } } } RemoveVertices(doubleVertexIndices); List[] newTriangleList = new List[1]; newTriangleList[0] = new List(); for (int m = 0; m < triangles.Length; m++) { for (int t = 0; t < triangles[m].Count; t++) { newTriangleList[0].Add(triangles[m][t]); } } triangles = newTriangleList; //Debug.Log("Triangles after removing submeshes: " + triangles[0].Count); List triplets = new List(); for (int i = 0; i < triangles[0].Count; i += 3) { triplets.Add(new IndexTriplet(triangles[0][i], triangles[0][i + 1], triangles[0][i + 2])); } triplets.Sort(); List newTriangles = new List(); for (int i = 0; i < triplets.Count; i++) { newTriangles.Add(triplets[i].x); newTriangles.Add(triplets[i].y); newTriangles.Add(triplets[i].z); } triangles[0] = newTriangles; } private class IndexTriplet : System.IComparable { public int x; public int y; public int z; public IndexTriplet(int x, int y, int z) { this.x = x; this.y = y; this.z = z; } public int CompareTo(object otherObj) { IndexTriplet other = otherObj as IndexTriplet; if (other == null) { return 1; } if (x < other.x) { return -1; } else if (x == other.x) { if (y < other.y) { return -1; } else if (y == other.y) { if (z < other.z) { return -1; } else if (z == other.z) { return 0; } else { return 1; } } else { return 1; } } else { return 1; } } } /* public List RemoveDoubles(List faceDataList) { Dictionary doubleVertexIndices = new Dictionary(); for (int i = 0; i < faceDataList.Count; i++) { for (int tIndex = 0; tIndex < faceDataList[i].Triangles.Length; tIndex++) { if (faceDataList[i].Triangles[tIndex] >= vertices.Count) { Debug.LogError(GetType() + ".RemoveDoubles: tried to get vertex " + faceDataList[i].Triangles[tIndex] + ", but vertices List contains only " + vertices.Count + " entries."); continue; } int triangleVertexIndex = faceDataList[i].Triangles[tIndex]; List faceTriangleList = new List(faceDataList[i].Triangles); //string faceTriangleString = ""; //foreach (var t in faceTriangleList) { // faceTriangleString += t + ", "; //} //Debug.Log("Triangle indices on face: " + faceTriangleString); for (int v = 0; v < vertices.Count; v++) { if (v != triangleVertexIndex) { int indexToReplace = v; int indexToReplaceWith = triangleVertexIndex; if (indexToReplaceWith > indexToReplace) { int change = indexToReplace; indexToReplace = indexToReplaceWith; indexToReplaceWith = change; } if (vertices[indexToReplace] == vertices[indexToReplaceWith] && normals[indexToReplace] == normals[indexToReplaceWith] && (tangents.Count <= indexToReplace || tangents[indexToReplace] == tangents[indexToReplaceWith]) && faceTriangleList.Contains(indexToReplace)) { if (!doubleVertexIndices.ContainsKey(indexToReplace) || doubleVertexIndices[indexToReplace] > indexToReplaceWith) { //Debug.Log("Added Vertex #" + indexToReplace + " (" + vertices[indexToReplace] + ") to double list. Replace with Vertex #" + indexToReplaceWith + " (" + vertices[indexToReplaceWith] + ")"); doubleVertexIndices[indexToReplace] = indexToReplaceWith; } } } } } } RemoveVertices(doubleVertexIndices); for (int i = 0; i < faceDataList.Count; i++) { faceDataList[i].ReplaceTriangleIndices(doubleVertexIndices); } return faceDataList; } */ } //public struct VertexIndexReplacePair { // public int indexToReplace; // public int indexToReplaceWith; // public VertexIndexReplacePair(int indexToReplace, int indexToReplaceWith) { // this.indexToReplace = indexToReplace; // this.indexToReplaceWith = indexToReplaceWith; // } //} }