Rasagar/Library/PackageCache/com.unity.probuilder/External/CSG/Classes/Model.cs
2024-08-26 23:07:20 +03:00

140 lines
4.2 KiB
C#

using System;
using UnityEngine;
using System.Collections.Generic;
using System.Linq;
namespace UnityEngine.ProBuilder.Csg
{
/// <summary>
/// Representation of a mesh in CSG terms. Contains methods for translating to and from UnityEngine.Mesh.
/// </summary>
sealed class Model
{
List<Vertex> m_Vertices;
List<Material> m_Materials;
List<List<int>> m_Indices;
public List<Material> materials
{
get { return m_Materials; }
set { m_Materials = value; }
}
public List<Vertex> vertices
{
get { return m_Vertices; }
set { m_Vertices = value; }
}
public List<List<int>> indices
{
get { return m_Indices; }
set { m_Indices = value; }
}
public Mesh mesh
{
get { return (Mesh)this; }
}
public Model(GameObject gameObject) :
this(gameObject.GetComponent<MeshFilter>()?.sharedMesh,
gameObject.GetComponent<MeshRenderer>()?.sharedMaterials,
gameObject.GetComponent<Transform>())
{
}
/// <summary>
/// Initialize a Model from a UnityEngine.Mesh and transform.
/// </summary>
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<Material>(materials);
m_Indices = new List<List<int>>();
for (int i = 0, c = mesh.subMeshCount; i < c; i++)
{
if (mesh.GetTopology(i) != MeshTopology.Triangles)
continue;
var indices = new List<int>();
mesh.GetIndices(indices, i);
m_Indices.Add(indices);
}
}
internal Model(List<Polygon> polygons)
{
m_Vertices = new List<Vertex>();
Dictionary<Material, List<int>> submeshes = new Dictionary<Material, List<int>>();
int p = 0;
for (int i = 0; i < polygons.Count; i++)
{
Polygon poly = polygons[i];
List<int> indices;
if (!submeshes.TryGetValue(poly.material, out indices))
submeshes.Add(poly.material, indices = new List<int>());
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<Polygon> ToPolygons()
{
List<Polygon> list = new List<Polygon>();
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<Vertex> triangle = new List<Vertex>()
{
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;
}
}
}