private Vector3?GetCellValue(Vector3Int pos) { var dx = pos.x - voxelData.gridSize[0]; var dy = pos.y - voxelData.gridSize[1]; var dz = pos.z - voxelData.gridSize[2]; if (dx < 0 && dy < 0 && dz < 0) { var flat = TreeUtility.Flatten(pos, voxelData.gridSize); return(voxelData.cells.TryGetValue(flat, out var val) ? val : (Vector3?)null); } var neighborOffset = new Vector3Int(Math.Max(dx + 1, 0), Math.Max(dy + 1, 0), Math.Max(dz + 1, 0)); var neighborData = NeighborData[neighborOffset]; if (neighborData.cells.Count == 0) { return(null); } var nPos = (Vector3Int.one - neighborOffset) * pos; var nFlat = TreeUtility.Flatten(nPos, neighborData.gridSize); return(neighborData.cells.TryGetValue(nFlat, out var nVal) ? nVal : (Vector3?)null); }
public static SignedDistanceFieldData Generate(GameObject obj, ComputeShader cs, Vector3Int resolution, Bounds bounds, float step) { var width = resolution.x; var height = resolution.y; var depth = resolution.z; var meshFilters = obj.GetComponentsInChildren <MeshFilter>(); var voxelRes = new[] { width, height, depth }; var resVoxels = new bool[width][][]; for (var i = 0; i < width; ++i) { resVoxels[i] = new bool[height][]; for (var j = 0; j < height; ++j) { resVoxels[i][j] = new bool[depth]; } } foreach (var meshFilter in meshFilters) { Voxelize(meshFilter, bounds, resolution, step, resVoxels); } var count = width * height * depth; var bufferCpu = new float[count]; for (var x = 0; x < width; ++x) { for (var z = 0; z < depth; ++z) { var filled = false; for (var y = height - 1; y >= 0; --y) { var full = resVoxels[x][y][z] || filled; if (!filled && full) { filled = true; } var pos = TreeUtility.Flatten(x, y, z, voxelRes); bufferCpu[pos] = full ? 1f : 0f; } } } var buffer = new ComputeBuffer(count, sizeof(float)); buffer.SetData(bufferCpu); var texture = new RenderTexture(width, height, 0, RenderTextureFormat.R8, RenderTextureReadWrite.Default) { dimension = TextureDimension.Tex3D, volumeDepth = depth, enableRandomWrite = true, wrapMode = TextureWrapMode.Clamp }; texture.Create(); var initializeKernel = cs.FindKernel("Initialize"); cs.SetTexture(initializeKernel, "_Texture", texture); cs.SetBuffer(initializeKernel, "_VoxelBuffer", buffer); cs.SetVector("_TexSize", new Vector4(width, height, depth, 0f)); cs.Dispatch(initializeKernel, HDRPUtilities.GetGroupSize(width, 8), HDRPUtilities.GetGroupSize(height, 8), HDRPUtilities.GetGroupSize(depth, 8)); buffer.Dispose(); return(new SignedDistanceFieldData() { texture = texture, bounds = bounds, voxels = resVoxels, step = step }); }