using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Unity.Burst;
using Unity.Collections;
using Unity.Jobs;
using UnityEngine;
///
/// 三角形合并网格
///
public class UnitAlgorithmMergeTriangle : UnitAlgorithm, UnitAlgorithm {
/// 三角形合并网格
public UnitAlgorithmMergeTriangle() { }
public void Compute(DataPlateDesign plateDesign) {
List polygons = plateDesign.triangles;
//三角形合并
List vertices = vertices = MergeVertices(polygons);
List triangles = JobFindTriangleIndex(polygons, vertices);
//展开uv (顶点去掉z坐标就是未缩放的平面UV)
List uv = new List();
for (int i = 0; i < vertices.Count; i++) { uv.Add(vertices[i]); }
//附加数据
plateDesign.mesh = new Mesh();
plateDesign.mesh.vertices = vertices.ToArray();
plateDesign.mesh.uv = uv.ToArray();
plateDesign.mesh.triangles = triangles.ToArray();
plateDesign.mesh.RecalculateBounds();
plateDesign.mesh.RecalculateNormals();
}
public void Compute(DataPlateBaking plateBaking) {
//List polygons = plateBaking.triangles;
////三角形合并
//List vertices = vertices = MergeVertices(polygons);
//List triangles = JobFindTriangleIndex(polygons, vertices);
////展开uv (顶点去掉z坐标就是未缩放的平面UV)
//List uv = new List();
//for (int i = 0; i < vertices.Count; i++) { uv.Add(vertices[i]); }
////附加数据
//plateBaking.mesh = new Mesh();
//plateBaking.mesh.vertices = vertices.ToArray();
//plateBaking.mesh.uv = uv.ToArray();
//plateBaking.mesh.triangles = triangles.ToArray();
//plateBaking.mesh.RecalculateBounds();
//plateBaking.mesh.RecalculateNormals();
}
/// 合并顶点
private List MergeVertices(List polygons) {
List vertices = new List();
for (int i = 0; i < polygons.Count; i++) {
vertices.Add(polygons[i].a);
vertices.Add(polygons[i].b);
vertices.Add(polygons[i].c);
}
return vertices.Distinct().ToList();
}
#region Jobs
/// 三角形顶点索引查找作业
private List JobFindTriangleIndex(List polygons, List vertices) {
NativeArray dataArray = new NativeArray(polygons.ToArray(), Allocator.TempJob);
NativeArray verticeArray = new NativeArray(vertices.ToArray(), Allocator.TempJob);
NativeArray trianglesArray = new NativeArray(polygons.Count, Allocator.TempJob);
TriangleIndex triangleIndex = new TriangleIndex();
triangleIndex.dataArray = dataArray;
triangleIndex.vertices = verticeArray;
triangleIndex.triangles = trianglesArray;
JobHandle dependency = new JobHandle();
JobHandle handle = triangleIndex.ScheduleParallel(polygons.Count, 32, dependency);
handle.Complete();
List triangles = new List();
for (int i = 0; i < trianglesArray.Length; i++) {
triangles.Add(trianglesArray[i].a);
triangles.Add(trianglesArray[i].b);
triangles.Add(trianglesArray[i].c);
}
dataArray.Dispose();
verticeArray.Dispose();
trianglesArray.Dispose();
return triangles;
}
/// 三角形顶点索引查找作业
[BurstCompile]
public struct TriangleIndex : IJobFor {
[ReadOnly] public NativeArray dataArray;
[ReadOnly] public NativeArray vertices;
public NativeArray triangles;
public void Execute(int index) {
DataTriangle dataTriangle = dataArray[index];
Triangle triangle = new Triangle();
bool a = false, b = false, c = false;
for (int i = 0; i < vertices.Length; i++) {
Vector3 vector = vertices[i];
if (dataTriangle.a == vector) { triangle.a = i; a = true; }
if (dataTriangle.b == vector) { triangle.b = i; b = true; }
if (dataTriangle.c == vector) { triangle.c = i; c = true; }
if (a && b && c) { break; }
}
triangles[index] = triangle;
}
}
/// 三角形顶点索引
public struct Triangle { public int a, b, c; }
#endregion
/// 是否启用计时器
private readonly bool isEnableTimer = true;
/// 计时器
private void Chronoscope(string content, Action action) {
if (!isEnableTimer) { action?.Invoke(); return; }
float time = Time.realtimeSinceStartup;
action?.Invoke();
float consumed = Time.realtimeSinceStartup - time;
Debug.Log($"{content}{consumed * 1000}");
}
}