public static RecastGridData VoxelizationToGrid(Voxelization voxel) { Vector3 min = voxel.Bounds.min; RecastGridData gridData = new RecastGridData { OriginPoint = new Vector3(min.x, min.z), Width = voxel.Size.x, Length = voxel.Size.z, Mask = new SerializBitArray(voxel.Size.x * voxel.Size.z) }; int bgHeight = (int)voxel.Bounds.min.y; if (bgHeight < 0) { bgHeight = -bgHeight; } for (int x = 0; x < voxel.Size.x; ++x) { for (int z = 0; z < voxel.Size.x; ++z) { if (voxel.Check(x, bgHeight, z) && !voxel.Check(x, bgHeight + 1, z)) { gridData.Mask.Set(z * voxel.Size.x + x, true); } } } return(gridData); }
public static void AddMesh(Voxelization voxel, Vector3[] vertices, int[] triangles, Matrix4x4 matrix) { int count = triangles.Length / 3; for (int i = 0; i < count; i++) { Vector3 v1 = vertices[triangles[i * 3]]; Vector3 v2 = vertices[triangles[i * 3 + 1]]; Vector3 v3 = vertices[triangles[i * 3 + 2]]; voxel.VoxelTriangle(matrix.MultiplyPoint(v1), matrix.MultiplyPoint(v2), matrix.MultiplyPoint(v3)); } }
public static void AddMeshByRender(Voxelization voxel, MeshRenderer renderer) { MeshFilter meshFilter = renderer.GetComponent <MeshFilter>(); if (meshFilter == null || meshFilter.sharedMesh == null) { return; } if (!renderer.bounds.Intersects(voxel.Bounds)) { return; } var mesh = meshFilter.sharedMesh; AddMesh(voxel, mesh.vertices, mesh.triangles, meshFilter.transform.localToWorldMatrix); }
//体素转换为高度区域 public static Heightfield VoxelToHeightfield(Voxelization voxel) { Heightfield heightfield = new Heightfield(voxel.Bounds.min, voxel.Size.x, voxel.Size.z, voxel.CellSize); Cell cell = new Cell(voxel.Size.y); for (int x = 0; x < voxel.Size.x; ++x) { for (int z = 0; z < voxel.Size.z; ++z) { int min = -1; int count = 0; for (int y = 0; y < voxel.Size.y; ++y) { bool mask = voxel.Voxel.Get(x, y, z); if (mask) { count++; if (min == -1) { min = y; count = 1; } } else { if (min != -1) { cell.Spans.Add(new Cell.Span { Min = min, Max = min + count }); min = -1; count = 0; } } } if (cell.Spans.Count > 0) { int cellIndex = z * voxel.Size.x + x; heightfield.Cells[cellIndex] = cell; cell = new Cell(voxel.Size.y); } } } return(heightfield); }
public static BitArray VoxelizationWalkableFilter(Voxelization voxel) { BitArray bitArray = new BitArray(voxel.Size.x * voxel.Size.z); int bgHeight = (int)voxel.Bounds.min.y; if (bgHeight < 0) { bgHeight = -bgHeight; } for (int x = 0; x < voxel.Size.x; ++x) { for (int z = 0; z < voxel.Size.x; ++z) { if (voxel.Check(x, bgHeight, z) && !voxel.Check(x, bgHeight + 1, z)) { bitArray.Set(z * voxel.Size.x + x, true); } } } return(bitArray); }
public static void AddGameObject(Voxelization voxel, GameObject gameObject, int layerMask = -1) { var renderers = gameObject.GetComponentsInChildren <MeshRenderer>(); foreach (var render in renderers) { if (((1 << render.gameObject.layer) & layerMask) != 0) { AddMeshByRender(voxel, render); } } var boxCollider = gameObject.GetComponentsInChildren <BoxCollider>(); foreach (var box in boxCollider) { if (box.isTrigger || ((1 << box.gameObject.layer) & layerMask) != 0) { continue; } AddBox(voxel, box.center, box.size, box.transform.localToWorldMatrix); } }
public static void DrawVoxel(Voxelization voxel) { Color color = Gizmos.color; Gizmos.color = Color.blue; Vector3 offset = voxel.Bounds.min; for (int x = 0; x < voxel.Size.x; ++x) { for (int y = 0; y < voxel.Size.y; ++y) { for (int z = 0; z < voxel.Size.z; ++z) { if (voxel.Voxel.Get(x, y, z)) { DrawGrid(x, y, z, voxel.CellSize, offset); } } } } Gizmos.color = color; }
public static void AddBox(Voxelization voxel, Vector3 center, Vector3 size, Matrix4x4 matrix) { matrix = Matrix4x4.TRS(center, Quaternion.identity, size * 0.5f) * matrix; AddMesh(voxel, BoxVertices, BoxTriangles, matrix); }