using System; using UnityEngine; using System.Collections.Generic; using System.Linq; namespace UnityEngine.ProBuilder.Csg { /// /// Representation of a mesh in CSG terms. Contains methods for translating to and from UnityEngine.Mesh. /// sealed class Model { List m_Vertices; List m_Materials; List> m_Indices; public List materials { get { return m_Materials; } set { m_Materials = value; } } public List vertices { get { return m_Vertices; } set { m_Vertices = value; } } public List> indices { get { return m_Indices; } set { m_Indices = value; } } public Mesh mesh { get { return (Mesh)this; } } public Model(GameObject gameObject) : this(gameObject.GetComponent()?.sharedMesh, gameObject.GetComponent()?.sharedMaterials, gameObject.GetComponent()) { } /// /// Initialize a Model from a UnityEngine.Mesh and transform. /// public Model(Mesh mesh, Material[] materials, Transform transform) { if(mesh == null) throw new ArgumentNullException("mesh"); if(transform == null) throw new ArgumentNullException("transform"); m_Vertices = VertexUtility.GetVertices(mesh).Select(x => transform.TransformVertex(x)).ToList(); m_Materials = new List(materials); m_Indices = new List>(); for (int i = 0, c = mesh.subMeshCount; i < c; i++) { if (mesh.GetTopology(i) != MeshTopology.Triangles) continue; var indices = new List(); mesh.GetIndices(indices, i); m_Indices.Add(indices); } } internal Model(List polygons) { m_Vertices = new List(); Dictionary> submeshes = new Dictionary>(); int p = 0; for (int i = 0; i < polygons.Count; i++) { Polygon poly = polygons[i]; List indices; if (!submeshes.TryGetValue(poly.material, out indices)) submeshes.Add(poly.material, indices = new List()); for (int j = 2; j < poly.vertices.Count; j++) { m_Vertices.Add(poly.vertices[0]); indices.Add(p++); m_Vertices.Add(poly.vertices[j - 1]); indices.Add(p++); m_Vertices.Add(poly.vertices[j]); indices.Add(p++); } } m_Materials = submeshes.Keys.ToList(); m_Indices = submeshes.Values.ToList(); } internal List ToPolygons() { List list = new List(); for (int s = 0, c = m_Indices.Count; s < c; s++) { var indices = m_Indices[s]; for (int i = 0, ic = indices.Count; i < indices.Count; i += 3) { List triangle = new List() { m_Vertices[indices[i + 0]], m_Vertices[indices[i + 1]], m_Vertices[indices[i + 2]] }; list.Add(new Polygon(triangle, m_Materials[s])); } } return list; } public static explicit operator Mesh(Model model) { var mesh = new Mesh(); VertexUtility.SetMesh(mesh, model.m_Vertices); mesh.subMeshCount = model.m_Indices.Count; for (int i = 0, c = mesh.subMeshCount; i < c; i++) mesh.SetIndices(model.m_Indices[i], MeshTopology.Triangles, i); return mesh; } } }