private void CreateFluid(float radius, float density)
        {
            Bounds  bounds = new Bounds();
            Vector3 min    = new Vector3(-8, 0, -1);
            Vector3 max    = new Vector3(-4, 8, 2);

            min.x += radius;
            min.y += radius;
            min.z += radius;

            max.x -= radius;
            max.y -= radius;
            max.z -= radius;

            bounds.SetMinMax(min, max);

            //The source will create a array of particles
            //evenly spaced inside the bounds.
            //Multiple the spacing by 0.9 to pack more
            //particles into bounds.
            float diameter             = radius * 2;
            ParticlesFromBounds source = new ParticlesFromBounds(diameter * 0.9f, bounds);

            Debug.Log("Fluid Particles = " + source.NumParticles);

            m_fluid = new FluidBody(source, radius, density, Matrix4x4.identity);

            m_fluidSource = bounds;
        }
        /// <summary>
        /// Fills the Volume texture with the particles densities.
        /// That texture can then be used to render the fluid by
        /// ray tracing in the meshes shader.
        /// </summary>
        public void FillVolume(FluidBody body, GridHash grid, SmoothingKernel kernel)
        {
            int computeKernel = m_shader.FindKernel("ComputeVolume");

            m_shader.SetFloat("VolumeScale", PixelSize);
            m_shader.SetVector("VolumeSize", Bounds.size);
            m_shader.SetVector("VolumeTranslate", Bounds.min);
            m_shader.SetFloat("HashScale", grid.InvCellSize);
            m_shader.SetVector("HashSize", grid.Bounds.size);
            m_shader.SetVector("HashTranslate", grid.Bounds.min);
            m_shader.SetFloat("KernelRadius", kernel.Radius);
            m_shader.SetFloat("KernelRadius2", kernel.Radius2);
            m_shader.SetFloat("Poly6", kernel.POLY6);
            m_shader.SetFloat("Density", body.Density);
            m_shader.SetInt("NumParticles", body.NumParticles);
            m_shader.SetFloat("ParticleVolume", body.ParticleVolume);
            m_shader.SetBuffer(computeKernel, "IndexMap", grid.IndexMap);
            m_shader.SetBuffer(computeKernel, "Table", grid.Table);
            m_shader.SetBuffer(computeKernel, "Positions", body.Positions);
            m_shader.SetBuffer(computeKernel, "Densities", body.Densities);
            m_shader.SetTexture(computeKernel, "Volume", Volume);

            m_shader.Dispatch(computeKernel, Groups.x, Groups.y, Groups.z);
        }
        public FluidSolver(FluidBody body, FluidBoundary boundary)
        {
            SolverIterations     = 2;
            ConstraintIterations = 2;

            Body     = body;
            Boundary = boundary;

            float cellSize = Body.ParticleRadius * 4.0f;
            int   total    = Body.NumParticles + Boundary.NumParticles;

            Hash   = new GridHash(Boundary.Bounds, total, cellSize);
            Kernel = new SmoothingKernel(cellSize);

            int numParticles = Body.NumParticles;

            Groups = numParticles / THREAD_1D;
            if (numParticles % THREAD_1D != 0)
            {
                Groups++;
            }

            m_shader = Resources.Load("FluidSolver") as ComputeShader;
        }