示例#1
0
        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
            });
        }