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.
223 lines
8.7 KiB
223 lines
8.7 KiB
using UnityEngine;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
|
|
namespace MeshVoxelizerProject
|
|
{
|
|
|
|
public class VoxelizerDemo : MonoBehaviour
|
|
{
|
|
|
|
public int size = 16;
|
|
|
|
public bool drawAABBTree;
|
|
|
|
private MeshVoxelizer m_voxelizer;
|
|
|
|
void Start()
|
|
{
|
|
MeshFilter filter = GetComponent<MeshFilter>();
|
|
MeshRenderer renderer = GetComponent<MeshRenderer>();
|
|
|
|
if(filter == null || renderer == null)
|
|
{
|
|
filter = GetComponentInChildren<MeshFilter>();
|
|
renderer = GetComponentInChildren<MeshRenderer>();
|
|
}
|
|
|
|
if (filter == null || renderer == null) return;
|
|
|
|
renderer.enabled = false;
|
|
|
|
Mesh mesh = filter.mesh;
|
|
Material mat = renderer.material;
|
|
|
|
Box3 bounds = new Box3(mesh.bounds.min, mesh.bounds.max);
|
|
|
|
m_voxelizer = new MeshVoxelizer(size, size, size);
|
|
m_voxelizer.Voxelize(mesh.vertices, mesh.triangles, bounds);
|
|
|
|
Vector3 scale = new Vector3(bounds.Size.x / size, bounds.Size.y / size, bounds.Size.z / size);
|
|
Vector3 m = new Vector3(bounds.Min.x, bounds.Min.y, bounds.Min.z);
|
|
mesh = CreateMesh(m_voxelizer.Voxels, scale, m);
|
|
|
|
GameObject go = new GameObject("Voxelized");
|
|
go.transform.parent = transform;
|
|
go.transform.localPosition = Vector3.zero;
|
|
go.transform.localScale = Vector3.one;
|
|
go.transform.localRotation = Quaternion.identity;
|
|
|
|
filter = go.AddComponent<MeshFilter>();
|
|
renderer = go.AddComponent<MeshRenderer>();
|
|
|
|
filter.mesh = mesh;
|
|
renderer.material = mat;
|
|
}
|
|
|
|
private void OnRenderObject()
|
|
{
|
|
var camera = Camera.current;
|
|
|
|
if (drawAABBTree && m_voxelizer != null)
|
|
{
|
|
Matrix4x4 m = transform.localToWorldMatrix;
|
|
|
|
foreach (Box3 box in m_voxelizer.Bounds)
|
|
{
|
|
DrawLines.DrawBounds(camera, Color.red, box, m);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
private Mesh CreateMesh(int[,,] voxels, Vector3 scale, Vector3 min)
|
|
{
|
|
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 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 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 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 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 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 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);
|
|
}
|
|
|
|
}
|
|
|
|
} |