Space-Smash-Out/Assets/Scripts/MeshWireframeComputor.cs

103 lines
2.2 KiB
C#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(MeshFilter))]
public class MeshWireframeComputor : MonoBehaviour
{
private static Color[] _COLORS = new Color[]
{
Color.red,
Color.green,
Color.blue,
};
#if UNITY_EDITOR
private void OnValidate()
{
// (called whenever the object is updated)
UpdateMesh();
}
#endif
[ContextMenu("Update Mesh")]
public void UpdateMesh()
{
if (!gameObject.activeSelf || !GetComponent<MeshRenderer>().enabled)
return;
Mesh m = GetComponent<MeshFilter>().sharedMesh;
if (m == null) return;
// compute and store vertex colors for the
// wireframe shader
Color[] colors = _SortedColoring(m);
if (colors != null)
m.SetColors(colors);
}
private Color[] _SortedColoring(Mesh mesh)
{
int n = mesh.vertexCount;
int[] labels = new int[n];
List<int[]> triangles = _GetSortedTriangles(mesh.triangles);
triangles.Sort((int[] t1, int[] t2) =>
{
int i = 0;
while (i < t1.Length && i < t2.Length)
{
if (t1[i] < t2[i]) return -1;
if (t1[i] > t2[i]) return 1;
i += 1;
}
if (t1.Length < t2.Length) return -1;
if (t1.Length > t2.Length) return 1;
return 0;
});
foreach (int[] triangle in triangles)
{
List<int> availableLabels = new List<int>() { 1, 2, 3 };
foreach (int vertexIndex in triangle)
{
if (availableLabels.Contains(labels[vertexIndex]))
availableLabels.Remove(labels[vertexIndex]);
}
foreach (int vertexIndex in triangle)
{
if (labels[vertexIndex] == 0)
{
if (availableLabels.Count == 0)
{
Debug.LogError("Could not find color");
return null;
}
labels[vertexIndex] = availableLabels[0];
availableLabels.RemoveAt(0);
}
}
}
Color[] colors = new Color[n];
for (int i = 0; i < n; i++)
colors[i] = labels[i] > 0 ? _COLORS[labels[i] - 1] : _COLORS[0];
return colors;
}
private List<int[]> _GetSortedTriangles(int[] triangles)
{
List<int[]> result = new List<int[]>();
for (int i = 0; i < triangles.Length; i += 3)
{
List<int> t = new List<int> { triangles[i], triangles[i + 1], triangles[i + 2] };
t.Sort();
result.Add(t.ToArray());
}
return result;
}
}