66 lines
2.5 KiB
C#
66 lines
2.5 KiB
C#
using UnityEngine;
|
|
using UnityEditor;
|
|
|
|
[ExecuteInEditMode]
|
|
public class VoxelizationTool : MonoBehaviour
|
|
{
|
|
public Vector3 gridSize = new Vector3(10, 10, 10); // 体素化区域的尺寸
|
|
public float voxelSize = 1.0f; // 每个体素的大小
|
|
public Color gridColor = Color.cyan; // 网格颜色
|
|
public bool showGrid = true; // 是否显示网格
|
|
public bool onlyShowMeshVoxels = true; // 是否仅显示包含 Mesh 的体素
|
|
|
|
private Bounds gridBounds; // 网格的总体包围盒
|
|
|
|
private void OnDrawGizmos()
|
|
{
|
|
if (!showGrid) return;
|
|
|
|
Gizmos.color = gridColor;
|
|
|
|
// 定义整个体素网格的包围盒
|
|
gridBounds = new Bounds(transform.position + gridSize * voxelSize / 2, gridSize * voxelSize);
|
|
|
|
// 获取场景中的所有 MeshFilter
|
|
MeshFilter[] meshFilters = FindObjectsOfType<MeshFilter>();
|
|
|
|
foreach (MeshFilter meshFilter in meshFilters)
|
|
{
|
|
Bounds meshBounds = meshFilter.sharedMesh.bounds;
|
|
meshBounds = TransformBounds(meshBounds, meshFilter.transform);
|
|
|
|
// 遍历体素,检查是否与当前 Mesh 的 Bounds 相交
|
|
for (int x = 0; x < gridSize.x; x++)
|
|
{
|
|
for (int y = 0; y < gridSize.y; y++)
|
|
{
|
|
for (int z = 0; z < gridSize.z; z++)
|
|
{
|
|
Vector3 voxelCenter = transform.position + new Vector3(x, y, z) * voxelSize + Vector3.one * voxelSize / 2;
|
|
|
|
// 跳过不在包围盒内的体素
|
|
if (!gridBounds.Contains(voxelCenter)) continue;
|
|
|
|
// 检查体素是否与 Mesh 的 Bounds 相交
|
|
Bounds voxelBounds = new Bounds(voxelCenter, Vector3.one * voxelSize);
|
|
if (meshBounds.Intersects(voxelBounds))
|
|
{
|
|
Gizmos.DrawWireCube(voxelCenter, Vector3.one * voxelSize);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 将本地 Bounds 转换为世界空间的 Bounds
|
|
/// </summary>
|
|
private Bounds TransformBounds(Bounds localBounds, Transform transform)
|
|
{
|
|
Vector3 worldCenter = transform.TransformPoint(localBounds.center);
|
|
Vector3 worldExtents = Vector3.Scale(localBounds.extents, transform.lossyScale);
|
|
return new Bounds(worldCenter, worldExtents * 2);
|
|
}
|
|
}
|