using UnityEngine; using Unity.Collections; using System.Collections.Generic; using System.Linq; namespace Obi { public interface IMeshDataProvider { Mesh sourceMesh { get; } uint meshInstances { get; } int vertexCount { get; } int triangleCount { get; } void GetVertices(List vertices); void GetNormals(List normals); void GetTangents(List tangents); void GetColors(List colors); void GetUVs(int channel, List uvs); void GetTriangles(List triangles); } public class MeshDataBatch { public struct MeshData { public int firstVertex; public int vertexCount; public int firstTriangle; public int triangleCount; } private Dictionary meshToIndex; // per mesh data: public ObiNativeList meshData; public ObiNativeList restPositions; public ObiNativeList restNormals; public ObiNativeList restTangents; public ObiNativeList restColors; public ObiNativeList uv; public ObiNativeList uv2; public ObiNativeList uv3; public ObiNativeList uv4; public ObiNativeList triangles; private List tempVertices; private List tempNormals; private List tempTangents; private List tempColors; private List tempUV; private List tempUV2; private List tempUV3; private List tempUV4; private List tempTriangles; public int Count { get { return meshData.count; } } public MeshDataBatch() { meshToIndex = new Dictionary(); meshData = new ObiNativeList(); InitializeTempData(); InitializeDynamicData(); InitializeStaticData(); } public void InitializeTempData() { tempVertices = new List(); tempNormals = new List(); tempTangents = new List(); tempColors = new List(); tempUV = new List(); tempUV2 = new List(); tempUV3 = new List(); tempUV4 = new List(); tempTriangles = new List(); } public void InitializeDynamicData() { if (restPositions == null) restPositions = new ObiNativeList(); if (restNormals == null) restNormals = new ObiNativeList(); if (restTangents == null) restTangents = new ObiNativeList(); if (restColors == null) restColors = new ObiNativeList(); } public void InitializeStaticData() { if (uv == null) uv = new ObiNativeList(); if (uv2 == null) uv2 = new ObiNativeList(); if (uv3 == null) uv3 = new ObiNativeList(); if (uv4 == null) uv4 = new ObiNativeList(); if (triangles == null) triangles = new ObiNativeList(); } public void Dispose() { if (meshData != null) meshData.Dispose(); DisposeOfTempData(); DisposeOfDynamicData(); DisposeOfStaticData(); } public void DisposeOfTempData() { tempVertices = null; tempNormals = null; tempTangents = null; tempColors = null; tempUV = null; tempUV2 = null; tempUV3 = null; tempUV4 = null; tempTriangles = null; } public void DisposeOfDynamicData() { if (restPositions != null) restPositions.Dispose(); restPositions = null; if (restNormals != null) restNormals.Dispose(); restNormals = null; if (restTangents != null) restTangents.Dispose(); restTangents = null; if (restColors != null) restColors.Dispose(); restColors = null; } public void DisposeOfStaticData() { if (uv != null) uv.Dispose(); uv = null; if (uv2 != null) uv2.Dispose(); uv2 = null; if (uv3 != null) uv3.Dispose(); uv3 = null; if (uv4 != null) uv4.Dispose(); uv4 = null; if (triangles != null) triangles.Dispose(); triangles = null; } public void Clear() { if (meshToIndex != null) meshToIndex.Clear(); if (meshData != null) meshData.Clear(); if (restPositions != null) restPositions.Clear(); if (restNormals != null) restNormals.Clear(); if (restTangents != null) restTangents.Clear(); if (restColors != null) restColors.Clear(); if (uv != null) uv.Clear(); if (uv2 != null) uv2.Clear(); if (uv3 != null) uv3.Clear(); if (uv4 != null) uv4.Clear(); if (triangles != null) triangles.Clear(); } public int AddMesh(IMeshDataProvider meshProvider) { if (!meshToIndex.TryGetValue(meshProvider.sourceMesh, out int index)) { index = meshData.count; meshToIndex[meshProvider.sourceMesh] = index; meshProvider.GetVertices(tempVertices); meshProvider.GetNormals(tempNormals); meshProvider.GetTangents(tempTangents); meshProvider.GetColors(tempColors); meshProvider.GetUVs(0, tempUV); meshProvider.GetUVs(1, tempUV2); meshProvider.GetUVs(2, tempUV3); meshProvider.GetUVs(3, tempUV4); meshProvider.GetTriangles(tempTriangles); if (tempTangents.Count == 0) tempTangents.AddRange(Enumerable.Repeat(Vector4.zero, tempVertices.Count)); if (tempColors.Count == 0) tempColors.AddRange(Enumerable.Repeat(Color.white, tempVertices.Count)); if (tempUV.Count == 0) tempUV.AddRange(Enumerable.Repeat(Vector2.zero, tempVertices.Count)); if (tempUV2.Count == 0) tempUV2.AddRange(Enumerable.Repeat(Vector2.zero, tempVertices.Count)); if (tempUV3.Count == 0) tempUV3.AddRange(Enumerable.Repeat(Vector2.zero, tempVertices.Count)); if (tempUV4.Count == 0) tempUV4.AddRange(Enumerable.Repeat(Vector2.zero, tempVertices.Count)); meshData.Add(new MeshData { firstVertex = restPositions.count, vertexCount = tempVertices.Count, firstTriangle = triangles.count, triangleCount = tempTriangles.Count }); restPositions.AddRange(tempVertices); restNormals.AddRange(tempNormals); restTangents.AddRange(tempTangents); restColors.AddRange(tempColors); uv.AddRange(tempUV); uv2.AddRange(tempUV2); uv3.AddRange(tempUV3); uv4.AddRange(tempUV4); triangles.AddRange(tempTriangles); } return index; } public void PrepareForCompute() { meshData.AsComputeBuffer(); restPositions.AsComputeBuffer(); restNormals.AsComputeBuffer(); restTangents.AsComputeBuffer(); restColors.AsComputeBuffer(); } public int GetVertexCount(int meshIndex) { return meshData[meshIndex].vertexCount; } public int GetTriangleCount(int meshIndex) { return meshData[meshIndex].triangleCount; } public NativeSlice GetVertices(int meshIndex) { int start = meshData[meshIndex].firstVertex; int count = meshData[meshIndex].vertexCount; return restPositions.AsNativeArray().Slice(start,count); } public NativeSlice GetNormals(int meshIndex) { int start = meshData[meshIndex].firstVertex; int count = meshData[meshIndex].vertexCount; return restNormals.AsNativeArray().Slice(start, count); } public NativeSlice GetTangents(int meshIndex) { int start = meshData[meshIndex].firstVertex; int count = meshData[meshIndex].vertexCount; return restTangents.AsNativeArray().Slice(start, count); } public NativeSlice GetColors(int meshIndex) { int start = meshData[meshIndex].firstVertex; int count = meshData[meshIndex].vertexCount; return restColors.AsNativeArray().Slice(start, count); } public NativeSlice GetUV(int meshIndex) { int start = meshData[meshIndex].firstVertex; int count = meshData[meshIndex].vertexCount; return uv.AsNativeArray().Slice(start, count); } public NativeSlice GetUV2(int meshIndex) { int start = meshData[meshIndex].firstVertex; int count = meshData[meshIndex].vertexCount; return uv2.AsNativeArray().Slice(start, count); } public NativeSlice GetUV3(int meshIndex) { int start = meshData[meshIndex].firstVertex; int count = meshData[meshIndex].vertexCount; return uv3.AsNativeArray().Slice(start, count); } public NativeSlice GetUV4(int meshIndex) { int start = meshData[meshIndex].firstVertex; int count = meshData[meshIndex].vertexCount; return uv4.AsNativeArray().Slice(start, count); } public NativeSlice GetTriangles(int meshIndex) { int start = meshData[meshIndex].firstTriangle; int count = meshData[meshIndex].triangleCount; return triangles.AsNativeArray().Slice(start, count); } } }