您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
234 行
7.9 KiB
234 行
7.9 KiB
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using Unity.Collections;
|
|
using Unity.Collections.LowLevel.Unsafe;
|
|
|
|
public class MeshAdjacency
|
|
{
|
|
public LinkedIndexListArray vertexTriangles;
|
|
public LinkedIndexListArray vertexVertices;
|
|
public LinkedIndexListArray vertexWelded;
|
|
public int[] vertexResolve;
|
|
public int vertexCount;
|
|
|
|
public LinkedIndexListArray triangleTriangles;
|
|
public LinkedIndexListArray triangleVertices;
|
|
public int triangleCount;
|
|
|
|
public MeshAdjacency(MeshBuffers meshBuffers, bool welded = false)
|
|
{
|
|
LoadFrom(meshBuffers, welded);
|
|
}
|
|
|
|
public void LoadFrom(MeshBuffers meshBuffers, bool welded = false)
|
|
{
|
|
vertexCount = meshBuffers.vertexCount;
|
|
vertexTriangles.Allocate(vertexCount, vertexCount * 8);
|
|
vertexVertices.Allocate(vertexCount, vertexCount * 8);
|
|
vertexWelded.Allocate(vertexCount, vertexCount);
|
|
|
|
ArrayUtils.ResizeCheckedIfLessThan(ref vertexResolve, vertexCount);
|
|
|
|
triangleCount = meshBuffers.triangleCount / 3;
|
|
triangleTriangles.Allocate(triangleCount, triangleCount * 8);
|
|
triangleVertices.Allocate(triangleCount, triangleCount * 3);
|
|
|
|
int[] triangles = meshBuffers.triangles;
|
|
|
|
// build vertex-triangle
|
|
{
|
|
for (int i = 0; i != triangleCount; i++)
|
|
{
|
|
int _0 = i * 3;
|
|
int v0 = triangles[_0 + 0];
|
|
int v1 = triangles[_0 + 1];
|
|
int v2 = triangles[_0 + 2];
|
|
|
|
vertexTriangles.Append(v0, i);
|
|
vertexTriangles.Append(v1, i);
|
|
vertexTriangles.Append(v2, i);
|
|
}
|
|
}
|
|
|
|
// build vertex-welded
|
|
unsafe
|
|
{
|
|
if (welded)
|
|
{
|
|
// for each vertex
|
|
// if vertex != closest vertex
|
|
// replace references to vertex with closest vertex
|
|
triangles = triangles.Clone() as int[];
|
|
|
|
using (var vertexWeldedMap = new UnsafeArrayBool(meshBuffers.vertexCount))
|
|
{
|
|
vertexWeldedMap.Clear(false);
|
|
|
|
var vertexBSP = new KdTree3(meshBuffers.vertexPositions, meshBuffers.vertexCount);
|
|
|
|
for (int i = 0; i != vertexCount; i++)
|
|
{
|
|
int j = vertexBSP.FindNearest(ref meshBuffers.vertexPositions[i]);
|
|
if (j != i)
|
|
{
|
|
//Debug.Assert(vertexWeldedMap.val[j] == false);
|
|
|
|
// replace references to i with j, keeping j
|
|
foreach (var triangle in vertexTriangles[i])
|
|
{
|
|
int _0 = triangle * 3;
|
|
int v0 = triangles[_0 + 0];
|
|
int v1 = triangles[_0 + 1];
|
|
//..v2 = triangles[_0 + 2];
|
|
|
|
if (v0 == i)
|
|
triangles[_0 + 0] = j;
|
|
else if (v1 == i)
|
|
triangles[_0 + 1] = j;
|
|
else // (v2 == i)
|
|
triangles[_0 + 2] = j;
|
|
|
|
// store i under j, so we can recover i at a later time
|
|
if (vertexWeldedMap.val[i] == false)
|
|
{
|
|
vertexWeldedMap.val[i] = true;
|
|
vertexWelded.Append(j, i);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// rebuild vertex-triangle
|
|
vertexTriangles.Clear();
|
|
|
|
for (int i = 0; i != triangleCount; i++)
|
|
{
|
|
int _0 = i * 3;
|
|
int v0 = triangles[_0 + 0];
|
|
int v1 = triangles[_0 + 1];
|
|
int v2 = triangles[_0 + 2];
|
|
|
|
vertexTriangles.Append(v0, i);
|
|
vertexTriangles.Append(v1, i);
|
|
vertexTriangles.Append(v2, i);
|
|
}
|
|
}
|
|
}
|
|
|
|
// build vertex-resolve
|
|
{
|
|
for (int i = 0; i != vertexCount; i++)
|
|
{
|
|
vertexResolve[i] = i;
|
|
}
|
|
|
|
for (int i = 0; i != vertexCount; i++)
|
|
{
|
|
foreach (var j in vertexWelded[i])
|
|
{
|
|
vertexResolve[j] = i;
|
|
}
|
|
}
|
|
}
|
|
|
|
// build vertex-vertex
|
|
unsafe
|
|
{
|
|
using (var vertexAdded = new UnsafeArrayBool(vertexCount))
|
|
{
|
|
vertexAdded.Clear(false);
|
|
|
|
for (int i = 0; i != vertexCount; i++)
|
|
{
|
|
foreach (int triangle in vertexTriangles[i])
|
|
{
|
|
int _0 = triangle * 3;
|
|
int v0 = triangles[_0 + 0];
|
|
int v1 = triangles[_0 + 1];
|
|
int v2 = triangles[_0 + 2];
|
|
|
|
int vA, vB;
|
|
if (i == v0)
|
|
{
|
|
vA = v1;
|
|
vB = v2;
|
|
}
|
|
else if (i == v1)
|
|
{
|
|
vA = v2;
|
|
vB = v0;
|
|
}
|
|
else // (i == v2)
|
|
{
|
|
vA = v0;
|
|
vB = v1;
|
|
}
|
|
|
|
if (vertexAdded.val[vA] == false && (vertexAdded.val[vA] = true))
|
|
vertexVertices.Append(i, vA);
|
|
|
|
if (vertexAdded.val[vB] == false && (vertexAdded.val[vB] = true))
|
|
vertexVertices.Append(i, vB);
|
|
}
|
|
|
|
foreach (int j in vertexVertices[i])
|
|
vertexAdded.val[j] = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
// build triangle-triangle
|
|
unsafe
|
|
{
|
|
using (var triangleAdded = new UnsafeArrayBool(triangleCount))
|
|
{
|
|
triangleAdded.Clear(false);
|
|
|
|
for (int i = 0; i != triangleCount; i++)
|
|
{
|
|
int _0 = i * 3;
|
|
int v0 = triangles[_0 + 0];
|
|
int v1 = triangles[_0 + 1];
|
|
int v2 = triangles[_0 + 2];
|
|
|
|
triangleAdded.val[i] = true;
|
|
|
|
foreach (int j in vertexTriangles[v0])
|
|
if (triangleAdded.val[j] == false && (triangleAdded.val[j] = true))
|
|
triangleTriangles.Append(i, j);
|
|
|
|
foreach (int j in vertexTriangles[v1])
|
|
if (triangleAdded.val[j] == false && (triangleAdded.val[j] = true))
|
|
triangleTriangles.Append(i, j);
|
|
|
|
foreach (int j in vertexTriangles[v2])
|
|
if (triangleAdded.val[j] == false && (triangleAdded.val[j] = true))
|
|
triangleTriangles.Append(i, j);
|
|
|
|
triangleAdded.val[i] = false;
|
|
|
|
foreach (int j in triangleTriangles[i])
|
|
triangleAdded.val[j] = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
// build triangle-vertex
|
|
{
|
|
for (int i = 0; i != triangleCount; i++)
|
|
{
|
|
int _0 = i * 3;
|
|
int v0 = triangles[_0 + 0];
|
|
int v1 = triangles[_0 + 1];
|
|
int v2 = triangles[_0 + 2];
|
|
|
|
triangleVertices.Append(i, v0);
|
|
triangleVertices.Append(i, v1);
|
|
triangleVertices.Append(i, v2);
|
|
}
|
|
}
|
|
}
|
|
}
|