WXGame/Blacksmith/Assets/Script/VoxelizationTool.cs
DESKTOP-DDTRVOR\asus c7001ae3d0 备份数据加
2025-01-14 10:33:27 +08:00

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);
}
}