393 lines
16 KiB
C#
393 lines
16 KiB
C#
|
namespace Dreamteck
|
||
|
{
|
||
|
using UnityEngine;
|
||
|
using System.Collections;
|
||
|
using System.Collections.Generic;
|
||
|
//Thread-safe mesh & bounds classes for working with threads.
|
||
|
public class TS_Mesh
|
||
|
{
|
||
|
public int vertexCount
|
||
|
{
|
||
|
get { return vertices.Length; }
|
||
|
set { }
|
||
|
}
|
||
|
public Vector3[] vertices = new Vector3[0];
|
||
|
public Vector3[] normals = new Vector3[0];
|
||
|
public Vector4[] tangents = new Vector4[0];
|
||
|
public Color[] colors = new Color[0];
|
||
|
public Vector2[] uv = new Vector2[0];
|
||
|
public Vector2[] uv2 = new Vector2[0];
|
||
|
public Vector2[] uv3 = new Vector2[0];
|
||
|
public Vector2[] uv4 = new Vector2[0];
|
||
|
public int[] triangles = new int[0];
|
||
|
public List<int[]> subMeshes = new List<int[]>();
|
||
|
public TS_Bounds bounds = new TS_Bounds(Vector3.zero, Vector3.zero);
|
||
|
public UnityEngine.Rendering.IndexFormat indexFormat = UnityEngine.Rendering.IndexFormat.UInt16;
|
||
|
|
||
|
public volatile bool hasUpdate = false;
|
||
|
|
||
|
private int[] _submeshTrisCount = new int[0];
|
||
|
private int[] _submeshOffsets = new int[0];
|
||
|
|
||
|
|
||
|
public TS_Mesh()
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
public TS_Mesh(Mesh mesh)
|
||
|
{
|
||
|
CreateFromMesh(mesh);
|
||
|
}
|
||
|
|
||
|
public void Clear()
|
||
|
{
|
||
|
vertices = new Vector3[0];
|
||
|
normals = new Vector3[0];
|
||
|
tangents = new Vector4[0];
|
||
|
colors = new Color[0];
|
||
|
uv = new Vector2[0];
|
||
|
uv2 = new Vector2[0];
|
||
|
uv3 = new Vector2[0];
|
||
|
uv4 = new Vector2[0];
|
||
|
triangles = new int[0];
|
||
|
subMeshes = new List<int[]>();
|
||
|
bounds = new TS_Bounds(Vector3.zero, Vector3.zero);
|
||
|
}
|
||
|
|
||
|
public void CreateFromMesh(Mesh mesh)
|
||
|
{
|
||
|
vertices = mesh.vertices;
|
||
|
normals = mesh.normals;
|
||
|
tangents = mesh.tangents;
|
||
|
colors = mesh.colors;
|
||
|
uv = mesh.uv;
|
||
|
uv2 = mesh.uv2;
|
||
|
uv3 = mesh.uv3;
|
||
|
uv4 = mesh.uv4;
|
||
|
triangles = mesh.triangles;
|
||
|
bounds = new TS_Bounds(mesh.bounds);
|
||
|
indexFormat = mesh.indexFormat;
|
||
|
for (int i = 0; i < mesh.subMeshCount; i++)
|
||
|
{
|
||
|
subMeshes.Add(mesh.GetTriangles(i));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Writes the combineMeshes array to the current TS_Mesh object and tries to not allocate memory
|
||
|
/// </summary>
|
||
|
/// <param name="combineMeshes"></param>
|
||
|
public void Combine(List<TS_Mesh> combineMeshes)
|
||
|
{
|
||
|
int totalVertexCount = 0;
|
||
|
int totalTrisCount = 0;
|
||
|
int addedSubmeshCount = 0;
|
||
|
|
||
|
for (int i = 0; i < combineMeshes.Count; i++)
|
||
|
{
|
||
|
totalVertexCount += combineMeshes[i].vertices.Length;
|
||
|
totalTrisCount += combineMeshes[i].triangles.Length;
|
||
|
if (combineMeshes[i].subMeshes.Count > addedSubmeshCount)
|
||
|
{
|
||
|
addedSubmeshCount = combineMeshes[i].subMeshes.Count;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (_submeshTrisCount.Length != addedSubmeshCount)
|
||
|
{
|
||
|
_submeshTrisCount = new int[addedSubmeshCount];
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
for (int i = 0; i < _submeshTrisCount.Length; i++)
|
||
|
{
|
||
|
_submeshTrisCount[i] = 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
for (int i = 0; i < combineMeshes.Count; i++)
|
||
|
{
|
||
|
for (int j = 0; j < combineMeshes[i].subMeshes.Count; j++)
|
||
|
{
|
||
|
_submeshTrisCount[j] += combineMeshes[i].subMeshes[j].Length;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (vertices.Length != totalVertexCount) vertices = new Vector3[totalVertexCount];
|
||
|
if (normals.Length != totalVertexCount) normals = new Vector3[totalVertexCount];
|
||
|
if (uv.Length != totalVertexCount) uv = new Vector2[totalVertexCount];
|
||
|
if (uv2.Length != totalVertexCount) uv2 = new Vector2[totalVertexCount];
|
||
|
if (uv3.Length != totalVertexCount) uv3 = new Vector2[totalVertexCount];
|
||
|
if (uv4.Length != totalVertexCount) uv4 = new Vector2[totalVertexCount];
|
||
|
if (colors.Length != totalVertexCount) colors = new Color[totalVertexCount];
|
||
|
if (tangents.Length != totalVertexCount) tangents = new Vector4[totalVertexCount];
|
||
|
if (triangles.Length != totalTrisCount) triangles = new int[totalTrisCount];
|
||
|
if (subMeshes.Count > addedSubmeshCount) subMeshes.Clear();
|
||
|
|
||
|
int vertexOffset = 0;
|
||
|
int trisOffset = 0;
|
||
|
|
||
|
if(_submeshOffsets.Length != addedSubmeshCount)
|
||
|
{
|
||
|
_submeshOffsets = new int[addedSubmeshCount];
|
||
|
} else
|
||
|
{
|
||
|
for (int i = 0; i < _submeshOffsets.Length; i++)
|
||
|
{
|
||
|
_submeshOffsets[i] = 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
for (int i = 0; i < combineMeshes.Count; i++)
|
||
|
{
|
||
|
combineMeshes[i].vertices.CopyTo(vertices, vertexOffset);
|
||
|
combineMeshes[i].normals.CopyTo(normals, vertexOffset);
|
||
|
combineMeshes[i].uv.CopyTo(uv, vertexOffset);
|
||
|
combineMeshes[i].uv2.CopyTo(uv2, vertexOffset);
|
||
|
combineMeshes[i].uv3.CopyTo(uv3, vertexOffset);
|
||
|
combineMeshes[i].uv4.CopyTo(uv4, vertexOffset);
|
||
|
combineMeshes[i].colors.CopyTo(colors, vertexOffset);
|
||
|
combineMeshes[i].tangents.CopyTo(tangents, vertexOffset);
|
||
|
|
||
|
for (int t = 0; t < combineMeshes[i].triangles.Length; t++)
|
||
|
{
|
||
|
int index = t + trisOffset;
|
||
|
triangles[index] = combineMeshes[i].triangles[t] + vertexOffset;
|
||
|
}
|
||
|
|
||
|
trisOffset += combineMeshes[i].triangles.Length;
|
||
|
|
||
|
for (int j = 0; j < combineMeshes[i].subMeshes.Count; j++)
|
||
|
{
|
||
|
if (j >= subMeshes.Count)
|
||
|
{
|
||
|
subMeshes.Add(new int[_submeshTrisCount[j]]);
|
||
|
}
|
||
|
else if (subMeshes[j].Length != _submeshTrisCount[j])
|
||
|
{
|
||
|
subMeshes[j] = new int[_submeshTrisCount[j]];
|
||
|
}
|
||
|
int[] submesh = combineMeshes[i].subMeshes[j];
|
||
|
|
||
|
for (int x = 0; x < submesh.Length; x++)
|
||
|
{
|
||
|
int index = _submeshOffsets[j] + x;
|
||
|
subMeshes[j][index] = submesh[x] + vertexOffset;
|
||
|
}
|
||
|
_submeshOffsets[j] += submesh.Length;
|
||
|
}
|
||
|
vertexOffset += combineMeshes[i].vertices.Length;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Adds the provieded mesh list to the current mesh and allocates memory
|
||
|
/// </summary>
|
||
|
/// <param name="addedMeshes"></param>
|
||
|
public void AddMeshes(List<TS_Mesh> addedMeshes)
|
||
|
{
|
||
|
int newVerts = 0;
|
||
|
int newTris = 0;
|
||
|
int submeshCount = 0;
|
||
|
for (int i = 0; i < addedMeshes.Count; i++)
|
||
|
{
|
||
|
newVerts += addedMeshes[i].vertexCount;
|
||
|
newTris += addedMeshes[i].triangles.Length;
|
||
|
if (addedMeshes[i].subMeshes.Count > submeshCount)
|
||
|
{
|
||
|
submeshCount = addedMeshes[i].subMeshes.Count;
|
||
|
}
|
||
|
}
|
||
|
int[] submeshTrisCount = new int[submeshCount];
|
||
|
int[] submeshOffsets = new int[submeshCount];
|
||
|
for (int i = 0; i < addedMeshes.Count; i++)
|
||
|
{
|
||
|
for (int j = 0; j < addedMeshes[i].subMeshes.Count; j++)
|
||
|
{
|
||
|
submeshTrisCount[j] += addedMeshes[i].subMeshes[j].Length;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
Vector3[] newVertices = new Vector3[vertices.Length + newVerts];
|
||
|
Vector3[] newNormals = new Vector3[vertices.Length + newVerts];
|
||
|
Vector2[] newUvs = new Vector2[vertices.Length + newVerts];
|
||
|
Vector2[] newUvs2 = new Vector2[vertices.Length + newVerts];
|
||
|
Vector2[] newUvs3 = new Vector2[vertices.Length + newVerts];
|
||
|
Vector2[] newUvs4 = new Vector2[vertices.Length + newVerts];
|
||
|
Color[] newColors = new Color[vertices.Length + newVerts];
|
||
|
Vector4[] newTangents = new Vector4[tangents.Length + newVerts];
|
||
|
int[] newTriangles = new int[triangles.Length + newTris];
|
||
|
List<int[]> newSubmeshes = new List<int[]>();
|
||
|
|
||
|
for (int i = 0; i < submeshTrisCount.Length; i++)
|
||
|
{
|
||
|
newSubmeshes.Add(new int[submeshTrisCount[i]]);
|
||
|
if (i < subMeshes.Count)
|
||
|
{
|
||
|
submeshTrisCount[i] = subMeshes[i].Length;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
submeshTrisCount[i] = 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
newVerts = vertexCount;
|
||
|
newTris = triangles.Length;
|
||
|
vertices.CopyTo(newVertices, 0);
|
||
|
normals.CopyTo(newNormals, 0);
|
||
|
uv.CopyTo(newUvs, 0);
|
||
|
uv2.CopyTo(newUvs2, 0);
|
||
|
uv3.CopyTo(newUvs3, 0);
|
||
|
uv4.CopyTo(newUvs4, 0);
|
||
|
colors.CopyTo(newColors, 0);
|
||
|
tangents.CopyTo(newTangents, 0);
|
||
|
triangles.CopyTo(newTriangles, 0);
|
||
|
|
||
|
for (int i = 0; i < addedMeshes.Count; i++)
|
||
|
{
|
||
|
addedMeshes[i].vertices.CopyTo(newVertices, newVerts);
|
||
|
addedMeshes[i].normals.CopyTo(newNormals, newVerts);
|
||
|
addedMeshes[i].uv.CopyTo(newUvs, newVerts);
|
||
|
addedMeshes[i].uv2.CopyTo(newUvs2, newVerts);
|
||
|
addedMeshes[i].uv3.CopyTo(newUvs3, newVerts);
|
||
|
addedMeshes[i].uv4.CopyTo(newUvs4, newVerts);
|
||
|
addedMeshes[i].colors.CopyTo(newColors, newVerts);
|
||
|
addedMeshes[i].tangents.CopyTo(newTangents, newVerts);
|
||
|
|
||
|
for (int n = newTris; n < newTris + addedMeshes[i].triangles.Length; n++)
|
||
|
{
|
||
|
newTriangles[n] = addedMeshes[i].triangles[n - newTris] + newVerts;
|
||
|
}
|
||
|
|
||
|
|
||
|
for (int n = 0; n < addedMeshes[i].subMeshes.Count; n++)
|
||
|
{
|
||
|
for (int x = submeshTrisCount[n]; x < submeshTrisCount[n] + addedMeshes[i].subMeshes[n].Length; x++)
|
||
|
{
|
||
|
newSubmeshes[n][x] = addedMeshes[i].subMeshes[n][x - submeshTrisCount[n]] + newVerts;
|
||
|
}
|
||
|
submeshTrisCount[n] += addedMeshes[i].subMeshes[n].Length;
|
||
|
}
|
||
|
newTris += addedMeshes[i].triangles.Length;
|
||
|
newVerts += addedMeshes[i].vertexCount;
|
||
|
}
|
||
|
|
||
|
vertices = newVertices;
|
||
|
normals = newNormals;
|
||
|
uv = newUvs;
|
||
|
uv2 = newUvs2;
|
||
|
uv3 = newUvs3;
|
||
|
uv4 = newUvs4;
|
||
|
colors = newColors;
|
||
|
tangents = newTangents;
|
||
|
triangles = newTriangles;
|
||
|
subMeshes = newSubmeshes;
|
||
|
}
|
||
|
|
||
|
public static TS_Mesh Copy(TS_Mesh input)
|
||
|
{
|
||
|
TS_Mesh result = new TS_Mesh();
|
||
|
result.vertices = new Vector3[input.vertices.Length];
|
||
|
input.vertices.CopyTo(result.vertices, 0);
|
||
|
result.normals = new Vector3[input.normals.Length];
|
||
|
input.normals.CopyTo(result.normals, 0);
|
||
|
result.uv = new Vector2[input.uv.Length];
|
||
|
input.uv.CopyTo(result.uv, 0);
|
||
|
result.uv2 = new Vector2[input.uv2.Length];
|
||
|
input.uv2.CopyTo(result.uv2, 0);
|
||
|
result.uv3 = new Vector2[input.uv3.Length];
|
||
|
input.uv3.CopyTo(result.uv3, 0);
|
||
|
result.uv4 = new Vector2[input.uv4.Length];
|
||
|
input.uv4.CopyTo(result.uv4, 0);
|
||
|
result.colors = new Color[input.colors.Length];
|
||
|
input.colors.CopyTo(result.colors, 0);
|
||
|
result.tangents = new Vector4[input.tangents.Length];
|
||
|
input.tangents.CopyTo(result.tangents, 0);
|
||
|
result.triangles = new int[input.triangles.Length];
|
||
|
input.triangles.CopyTo(result.triangles, 0);
|
||
|
result.subMeshes = new List<int[]>();
|
||
|
for(int i = 0; i < input.subMeshes.Count; i++)
|
||
|
{
|
||
|
result.subMeshes.Add(new int[input.subMeshes[i].Length]);
|
||
|
input.subMeshes[i].CopyTo(result.subMeshes[i], 0);
|
||
|
}
|
||
|
result.bounds = new TS_Bounds(input.bounds.center, input.bounds.size);
|
||
|
result.indexFormat = input.indexFormat;
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
public void Absorb(TS_Mesh input)
|
||
|
{
|
||
|
if (vertices.Length != input.vertexCount) vertices = new Vector3[input.vertexCount];
|
||
|
if (normals.Length != input.normals.Length) normals = new Vector3[input.normals.Length];
|
||
|
if (colors.Length != input.colors.Length) colors = new Color[input.colors.Length];
|
||
|
if (uv.Length != input.uv.Length) uv = new Vector2[input.uv.Length];
|
||
|
if (uv2.Length != input.uv2.Length) uv2 = new Vector2[input.uv2.Length];
|
||
|
if (uv3.Length != input.uv3.Length) uv3 = new Vector2[input.uv3.Length];
|
||
|
if (uv4.Length != input.uv4.Length) uv4 = new Vector2[input.uv4.Length];
|
||
|
if (tangents.Length != input.tangents.Length) tangents = new Vector4[input.tangents.Length];
|
||
|
if (triangles.Length != input.triangles.Length) triangles = new int[input.triangles.Length];
|
||
|
|
||
|
input.vertices.CopyTo(vertices, 0);
|
||
|
input.normals.CopyTo(normals, 0);
|
||
|
input.colors.CopyTo(colors, 0);
|
||
|
input.uv.CopyTo(uv, 0);
|
||
|
input.uv2.CopyTo(uv2, 0);
|
||
|
input.uv3.CopyTo(uv3, 0);
|
||
|
input.uv4.CopyTo(uv4, 0);
|
||
|
input.tangents.CopyTo(tangents, 0);
|
||
|
input.triangles.CopyTo(triangles, 0);
|
||
|
|
||
|
if (subMeshes.Count == input.subMeshes.Count)
|
||
|
{
|
||
|
for (int i = 0; i < subMeshes.Count; i++)
|
||
|
{
|
||
|
if (input.subMeshes[i].Length != subMeshes[i].Length) subMeshes[i] = new int[input.subMeshes[i].Length];
|
||
|
input.subMeshes[i].CopyTo(subMeshes[i], 0);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
subMeshes = new List<int[]>();
|
||
|
for (int i = 0; i < input.subMeshes.Count; i++)
|
||
|
{
|
||
|
subMeshes.Add(new int[input.subMeshes[i].Length]);
|
||
|
input.subMeshes[i].CopyTo(subMeshes[i], 0);
|
||
|
}
|
||
|
}
|
||
|
bounds = new TS_Bounds(input.bounds.center, input.bounds.size);
|
||
|
}
|
||
|
|
||
|
public void WriteMesh(ref Mesh input)
|
||
|
{
|
||
|
if (input == null) input = new Mesh();
|
||
|
input.Clear();
|
||
|
input.indexFormat = indexFormat;
|
||
|
input.vertices = vertices;
|
||
|
input.normals = normals;
|
||
|
if (tangents.Length == vertices.Length) input.tangents = tangents;
|
||
|
if (colors.Length == vertices.Length) input.colors = colors;
|
||
|
if (uv.Length == vertices.Length) input.uv = uv;
|
||
|
if (uv2.Length == vertices.Length) input.uv2 = uv2;
|
||
|
if (uv3.Length == vertices.Length) input.uv3 = uv3;
|
||
|
if (uv4.Length == vertices.Length) input.uv4 = uv4;
|
||
|
input.triangles = triangles;
|
||
|
if (subMeshes.Count > 0)
|
||
|
{
|
||
|
input.subMeshCount = subMeshes.Count;
|
||
|
for (int i = 0; i < subMeshes.Count; i++)
|
||
|
{
|
||
|
input.SetTriangles(subMeshes[i], i);
|
||
|
}
|
||
|
}
|
||
|
input.RecalculateBounds();
|
||
|
hasUpdate = false;
|
||
|
}
|
||
|
}
|
||
|
}
|