s
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
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}");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user