You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
207 lines
7.5 KiB
207 lines
7.5 KiB
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using MeshVoxelizerProject;
|
|
using UnityEngine;
|
|
|
|
public static class VoxelMeshBuilder
|
|
{
|
|
#region 外部方法
|
|
|
|
/// <summary>
|
|
/// 转换成体素网格
|
|
/// </summary>
|
|
/// <param name="origin_mesh">原始网格</param>
|
|
/// <param name="PixelSize">像素尺寸</param>
|
|
/// <returns></returns>
|
|
public static Mesh ConversionVoxelMesh(Mesh origin_mesh, int PixelSize)
|
|
{
|
|
if (!origin_mesh)
|
|
return null;
|
|
Box3 bounds = new Box3(origin_mesh.bounds.min, origin_mesh.bounds.max);
|
|
|
|
var m_voxelizer = new MeshVoxelizer(PixelSize, PixelSize, PixelSize);
|
|
m_voxelizer.Voxelize(origin_mesh.vertices, origin_mesh.triangles, bounds);
|
|
|
|
Vector3 scale = new Vector3(bounds.Size.x / PixelSize, bounds.Size.y / PixelSize, bounds.Size.z / PixelSize);
|
|
Vector3 m = new Vector3(bounds.Min.x, bounds.Min.y, bounds.Min.z);
|
|
return CreateMesh(m_voxelizer.Voxels, scale, m, PixelSize);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 内部方法
|
|
|
|
private static Mesh CreateMesh(int[,,] voxels, Vector3 scale, Vector3 min, int size)
|
|
{
|
|
List<Vector3> verts = new List<Vector3>();
|
|
List<int> indices = new List<int>();
|
|
|
|
for (int z = 0; z < size; z++)
|
|
{
|
|
for (int y = 0; y < size; y++)
|
|
{
|
|
for (int x = 0; x < size; x++)
|
|
{
|
|
if (voxels[x, y, z] != 1) continue;
|
|
|
|
Vector3 pos = min + new Vector3(x * scale.x, y * scale.y, z * scale.z);
|
|
|
|
if (x == size - 1 || voxels[x + 1, y, z] == 0)
|
|
AddRightQuad(verts, indices, scale, pos);
|
|
|
|
if (x == 0 || voxels[x - 1, y, z] == 0)
|
|
AddLeftQuad(verts, indices, scale, pos);
|
|
|
|
if (y == size - 1 || voxels[x, y + 1, z] == 0)
|
|
AddTopQuad(verts, indices, scale, pos);
|
|
|
|
if (y == 0 || voxels[x, y - 1, z] == 0)
|
|
AddBottomQuad(verts, indices, scale, pos);
|
|
|
|
if (z == size - 1 || voxels[x, y, z + 1] == 0)
|
|
AddFrontQuad(verts, indices, scale, pos);
|
|
|
|
if (z == 0 || voxels[x, y, z - 1] == 0)
|
|
AddBackQuad(verts, indices, scale, pos);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (verts.Count > 65000)
|
|
{
|
|
Debug.Log("Mesh has too many verts. You will have to add code to split it up.");
|
|
return new Mesh();
|
|
}
|
|
|
|
Mesh mesh = new Mesh();
|
|
mesh.SetVertices(verts);
|
|
mesh.SetTriangles(indices, 0);
|
|
|
|
mesh.RecalculateBounds();
|
|
mesh.RecalculateNormals();
|
|
|
|
return mesh;
|
|
}
|
|
|
|
private static void AddRightQuad(List<Vector3> verts, List<int> indices, Vector3 scale, Vector3 pos)
|
|
{
|
|
int count = verts.Count;
|
|
|
|
verts.Add(pos + new Vector3(1 * scale.x, 0 * scale.y, 1 * scale.z));
|
|
verts.Add(pos + new Vector3(1 * scale.x, 1 * scale.y, 0 * scale.z));
|
|
verts.Add(pos + new Vector3(1 * scale.x, 0 * scale.y, 0 * scale.z));
|
|
|
|
verts.Add(pos + new Vector3(1 * scale.x, 0 * scale.y, 1 * scale.z));
|
|
verts.Add(pos + new Vector3(1 * scale.x, 1 * scale.y, 1 * scale.z));
|
|
verts.Add(pos + new Vector3(1 * scale.x, 1 * scale.y, 0 * scale.z));
|
|
|
|
indices.Add(count + 2);
|
|
indices.Add(count + 1);
|
|
indices.Add(count + 0);
|
|
indices.Add(count + 5);
|
|
indices.Add(count + 4);
|
|
indices.Add(count + 3);
|
|
}
|
|
|
|
private static void AddLeftQuad(List<Vector3> verts, List<int> indices, Vector3 scale, Vector3 pos)
|
|
{
|
|
int count = verts.Count;
|
|
|
|
verts.Add(pos + new Vector3(0 * scale.x, 0 * scale.y, 1 * scale.z));
|
|
verts.Add(pos + new Vector3(0 * scale.x, 1 * scale.y, 0 * scale.z));
|
|
verts.Add(pos + new Vector3(0 * scale.x, 0 * scale.y, 0 * scale.z));
|
|
|
|
verts.Add(pos + new Vector3(0 * scale.x, 0 * scale.y, 1 * scale.z));
|
|
verts.Add(pos + new Vector3(0 * scale.x, 1 * scale.y, 1 * scale.z));
|
|
verts.Add(pos + new Vector3(0 * scale.x, 1 * scale.y, 0 * scale.z));
|
|
|
|
indices.Add(count + 0);
|
|
indices.Add(count + 1);
|
|
indices.Add(count + 2);
|
|
indices.Add(count + 3);
|
|
indices.Add(count + 4);
|
|
indices.Add(count + 5);
|
|
}
|
|
|
|
private static void AddTopQuad(List<Vector3> verts, List<int> indices, Vector3 scale, Vector3 pos)
|
|
{
|
|
int count = verts.Count;
|
|
|
|
verts.Add(pos + new Vector3(0 * scale.x, 1 * scale.y, 1 * scale.z));
|
|
verts.Add(pos + new Vector3(1 * scale.x, 1 * scale.y, 0 * scale.z));
|
|
verts.Add(pos + new Vector3(0 * scale.x, 1 * scale.y, 0 * scale.z));
|
|
|
|
verts.Add(pos + new Vector3(0 * scale.x, 1 * scale.y, 1 * scale.z));
|
|
verts.Add(pos + new Vector3(1 * scale.x, 1 * scale.y, 1 * scale.z));
|
|
verts.Add(pos + new Vector3(1 * scale.x, 1 * scale.y, 0 * scale.z));
|
|
|
|
indices.Add(count + 0);
|
|
indices.Add(count + 1);
|
|
indices.Add(count + 2);
|
|
indices.Add(count + 3);
|
|
indices.Add(count + 4);
|
|
indices.Add(count + 5);
|
|
}
|
|
|
|
private static void AddBottomQuad(List<Vector3> verts, List<int> indices, Vector3 scale, Vector3 pos)
|
|
{
|
|
int count = verts.Count;
|
|
|
|
verts.Add(pos + new Vector3(0 * scale.x, 0 * scale.y, 1 * scale.z));
|
|
verts.Add(pos + new Vector3(1 * scale.x, 0 * scale.y, 0 * scale.z));
|
|
verts.Add(pos + new Vector3(0 * scale.x, 0 * scale.y, 0 * scale.z));
|
|
|
|
verts.Add(pos + new Vector3(0 * scale.x, 0 * scale.y, 1 * scale.z));
|
|
verts.Add(pos + new Vector3(1 * scale.x, 0 * scale.y, 1 * scale.z));
|
|
verts.Add(pos + new Vector3(1 * scale.x, 0 * scale.y, 0 * scale.z));
|
|
|
|
indices.Add(count + 2);
|
|
indices.Add(count + 1);
|
|
indices.Add(count + 0);
|
|
indices.Add(count + 5);
|
|
indices.Add(count + 4);
|
|
indices.Add(count + 3);
|
|
}
|
|
|
|
private static void AddFrontQuad(List<Vector3> verts, List<int> indices, Vector3 scale, Vector3 pos)
|
|
{
|
|
int count = verts.Count;
|
|
|
|
verts.Add(pos + new Vector3(0 * scale.x, 1 * scale.y, 1 * scale.z));
|
|
verts.Add(pos + new Vector3(1 * scale.x, 0 * scale.y, 1 * scale.z));
|
|
verts.Add(pos + new Vector3(0 * scale.x, 0 * scale.y, 1 * scale.z));
|
|
|
|
verts.Add(pos + new Vector3(0 * scale.x, 1 * scale.y, 1 * scale.z));
|
|
verts.Add(pos + new Vector3(1 * scale.x, 1 * scale.y, 1 * scale.z));
|
|
verts.Add(pos + new Vector3(1 * scale.x, 0 * scale.y, 1 * scale.z));
|
|
|
|
indices.Add(count + 2);
|
|
indices.Add(count + 1);
|
|
indices.Add(count + 0);
|
|
indices.Add(count + 5);
|
|
indices.Add(count + 4);
|
|
indices.Add(count + 3);
|
|
}
|
|
|
|
private static void AddBackQuad(List<Vector3> verts, List<int> indices, Vector3 scale, Vector3 pos)
|
|
{
|
|
int count = verts.Count;
|
|
|
|
verts.Add(pos + new Vector3(0 * scale.x, 1 * scale.y, 0 * scale.z));
|
|
verts.Add(pos + new Vector3(1 * scale.x, 0 * scale.y, 0 * scale.z));
|
|
verts.Add(pos + new Vector3(0 * scale.x, 0 * scale.y, 0 * scale.z));
|
|
|
|
verts.Add(pos + new Vector3(0 * scale.x, 1 * scale.y, 0 * scale.z));
|
|
verts.Add(pos + new Vector3(1 * scale.x, 1 * scale.y, 0 * scale.z));
|
|
verts.Add(pos + new Vector3(1 * scale.x, 0 * scale.y, 0 * scale.z));
|
|
|
|
indices.Add(count + 0);
|
|
indices.Add(count + 1);
|
|
indices.Add(count + 2);
|
|
indices.Add(count + 3);
|
|
indices.Add(count + 4);
|
|
indices.Add(count + 5);
|
|
}
|
|
|
|
#endregion
|
|
} |