108 lines
4.2 KiB
C#
108 lines
4.2 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using Unity.Burst;
|
|
using Unity.Collections;
|
|
using Unity.Jobs;
|
|
using UnityEngine;
|
|
|
|
/// <summary>
|
|
/// 三角形合并网格
|
|
/// </summary>
|
|
public class UnitAlgorithmMergeTriangle : UnitAlgorithm<DataPlate> {
|
|
/// <summary> 三角形合并网格 </summary>
|
|
public UnitAlgorithmMergeTriangle() { }
|
|
|
|
public void Compute(DataPlate data) {
|
|
List<DataTriangle> polygons = data.triangles;
|
|
//三角形合并
|
|
List<Vector3> vertices = vertices = MergeVertices(polygons);
|
|
List<int> triangles = JobFindTriangleIndex(polygons, vertices);
|
|
//展开uv (顶点去掉z坐标就是未缩放的平面UV)
|
|
List<Vector2> uv = new List<Vector2>();
|
|
for (int i = 0; i < vertices.Count; i++) { uv.Add(vertices[i]); }
|
|
//附加数据
|
|
data.designMesh = new Mesh();
|
|
data.designMesh.vertices = vertices.ToArray();
|
|
data.designMesh.uv = uv.ToArray();
|
|
data.designMesh.triangles = triangles.ToArray();
|
|
data.designMesh.RecalculateBounds();
|
|
data.designMesh.RecalculateNormals();
|
|
}
|
|
/// <summary> 合并顶点 </summary>
|
|
private List<Vector3> MergeVertices(List<DataTriangle> polygons) {
|
|
List<Vector3> vertices = new List<Vector3>();
|
|
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
|
|
/// <summary> 三角形顶点索引查找作业 </summary>
|
|
private List<int> JobFindTriangleIndex(List<DataTriangle> polygons, List<Vector3> vertices) {
|
|
NativeArray<DataTriangle> dataArray = new NativeArray<DataTriangle>(polygons.ToArray(), Allocator.TempJob);
|
|
NativeArray<Vector3> verticeArray = new NativeArray<Vector3>(vertices.ToArray(), Allocator.TempJob);
|
|
NativeArray<Triangle> trianglesArray = new NativeArray<Triangle>(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, 2048, dependency);
|
|
handle.Complete();
|
|
|
|
List<int> triangles = new List<int>();
|
|
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;
|
|
}
|
|
/// <summary> 三角形顶点索引查找作业 </summary>
|
|
[BurstCompile]
|
|
public struct TriangleIndex : IJobFor {
|
|
[ReadOnly] public NativeArray<DataTriangle> dataArray;
|
|
[ReadOnly] public NativeArray<Vector3> vertices;
|
|
public NativeArray<Triangle> 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;
|
|
}
|
|
}
|
|
/// <summary> 三角形顶点索引 </summary>
|
|
public struct Triangle { public int a, b, c; }
|
|
#endregion
|
|
|
|
/// <summary> 是否启用计时器 </summary>
|
|
private readonly bool isEnableTimer = true;
|
|
/// <summary> 计时器 </summary>
|
|
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}");
|
|
}
|
|
}
|