183 lines
5.8 KiB
C#
183 lines
5.8 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using GK;
|
|
using UnityEditor;
|
|
using UnityEngine;
|
|
using UnityEngine.Rendering;
|
|
|
|
namespace Net.Project.B.Bounds
|
|
{
|
|
public class UnityMeshColliderCovertExplorer
|
|
{
|
|
[MenuItem("Tools/Export GameObjects to Convex Mesh")]
|
|
private static void ExportConvex()
|
|
{
|
|
var go = Selection.activeGameObject;
|
|
|
|
if (!go)
|
|
{
|
|
Debug.LogError("No object selected");
|
|
return;
|
|
}
|
|
|
|
var nonConvexMesh = GetMesh(go);
|
|
|
|
var hullCalculator = new ConvexHullCalculator();
|
|
|
|
var allVertices = new List<Vector3>();
|
|
var allTriangles = new List<int>();
|
|
var allNormals = new List<Vector3>();
|
|
|
|
var vertices = new List<Vector3>();
|
|
|
|
|
|
nonConvexMesh.GetVertices(vertices);
|
|
hullCalculator.GenerateHull(vertices, true, ref allVertices, ref allTriangles,
|
|
ref allNormals);
|
|
|
|
var newMesh = new Mesh();
|
|
newMesh.SetVertices(allVertices);
|
|
newMesh.SetTriangles(allTriangles, 0);
|
|
newMesh.SetNormals(allNormals);
|
|
|
|
var newGo = new GameObject("Combined Mesh");
|
|
newGo.AddComponent<MeshFilter>().mesh = newMesh;
|
|
newGo.AddComponent<MeshRenderer>();
|
|
}
|
|
|
|
[MenuItem("Tools/Export GameObjects to Non Convex Mesh")]
|
|
private static void ExportNonConvex()
|
|
{
|
|
var go = Selection.activeGameObject;
|
|
|
|
if (!go)
|
|
{
|
|
Debug.LogError("No object selected");
|
|
return;
|
|
}
|
|
|
|
var newMesh = GetMesh(go);
|
|
|
|
var newGo = new GameObject("Combined Mesh");
|
|
newGo.AddComponent<MeshFilter>().mesh = newMesh;
|
|
newGo.AddComponent<MeshRenderer>();
|
|
|
|
}
|
|
|
|
private static Mesh GetMesh(GameObject go)
|
|
{
|
|
var hullCalculator = new ConvexHullCalculator();
|
|
|
|
var combineInstances = new List<CombineInstance>();
|
|
|
|
|
|
foreach (var collider in go.GetComponentsInChildren<Collider>())
|
|
{
|
|
switch (collider)
|
|
{
|
|
case BoxCollider boxCollider:
|
|
{
|
|
var mesh = CreateBoxMesh(boxCollider);
|
|
|
|
combineInstances.Add(new CombineInstance()
|
|
{
|
|
mesh = mesh,
|
|
transform = collider.transform.localToWorldMatrix
|
|
});
|
|
}
|
|
break;
|
|
case MeshCollider meshCollider:
|
|
{
|
|
var allVertices = new List<Vector3>();
|
|
var allTriangles = new List<int>();
|
|
var allNormals = new List<Vector3>();
|
|
|
|
var mesh = meshCollider.sharedMesh;
|
|
var vertices = new List<Vector3>();
|
|
for (var index = 0; index < vertices.Count; index++)
|
|
{
|
|
var vertex = vertices[index];
|
|
vertex = meshCollider.transform.TransformPoint(vertex);
|
|
vertices[index] = vertex;
|
|
}
|
|
|
|
mesh.GetVertices(vertices);
|
|
hullCalculator.GenerateHull(vertices, true, ref allVertices, ref allTriangles,
|
|
ref allNormals);
|
|
|
|
mesh = new Mesh
|
|
{
|
|
indexFormat = IndexFormat.UInt32
|
|
};
|
|
mesh.SetVertices(allVertices);
|
|
mesh.SetTriangles(allTriangles, 0);
|
|
mesh.SetNormals(allNormals);
|
|
|
|
combineInstances.Add(new CombineInstance()
|
|
{
|
|
mesh = mesh,
|
|
transform = meshCollider.transform.localToWorldMatrix
|
|
});
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
var newMesh = new Mesh();
|
|
newMesh.CombineMeshes(combineInstances.ToArray());
|
|
|
|
return newMesh;
|
|
}
|
|
|
|
private static Mesh CreateBoxMesh(BoxCollider box)
|
|
{
|
|
var size = box.size;
|
|
var center = box.center;
|
|
|
|
var mesh = new Mesh();
|
|
|
|
Vector3[] vertices = {
|
|
// Bottom
|
|
new Vector3(-1, -1, -1),
|
|
new Vector3( 1, -1, -1),
|
|
new Vector3( 1, -1, 1),
|
|
new Vector3(-1, -1, 1),
|
|
// Top
|
|
new Vector3(-1, 1, -1),
|
|
new Vector3( 1, 1, -1),
|
|
new Vector3( 1, 1, 1),
|
|
new Vector3(-1, 1, 1),
|
|
};
|
|
|
|
int[] triangles = {
|
|
// Bottom
|
|
0, 2, 1, 0, 3, 2,
|
|
// Top
|
|
4, 5, 6, 4, 6, 7,
|
|
// Front
|
|
0, 1, 5, 0, 5, 4,
|
|
// Back
|
|
2, 3, 7, 2, 7, 6,
|
|
// Left
|
|
3, 0, 4, 3, 4, 7,
|
|
// Right
|
|
1, 2, 6, 1, 6, 5,
|
|
};
|
|
|
|
// Scale and offset vertices according to size and center
|
|
for (int i = 0; i < vertices.Length; i++)
|
|
{
|
|
vertices[i] = Vector3.Scale(vertices[i], size * 0.5f) + center;
|
|
}
|
|
|
|
mesh.vertices = vertices;
|
|
mesh.triangles = triangles;
|
|
mesh.RecalculateNormals();
|
|
mesh.RecalculateBounds();
|
|
|
|
return mesh;
|
|
}
|
|
}
|
|
}
|