public FluidRendererMarchingCubes(Fluid fluid, GraphicsDevice graphicsDevice)
        {
            this.Fluid = fluid;
            this.graphicsDevice = graphicsDevice;

            // Create vertexbuffer
            this.localVertices = new VertexPositionNormalTexture[MAX_TRIANGLES * 3];
            for (int i = 0; i < localVertices.Length; i++)
            {
                this.localVertices[i] = new VertexPositionNormalTexture();
            }

            BuildField();
        }
        public FluidHash(Fluid fluid)
        {
            this.fluid = fluid;

            this.h = SmoothKernel.h;
            this.h2 = h * h;

            // Calculate number of cells required
            this.width = (int)Math.Ceiling((double)((fluid.Container.Bounds.Max.X - fluid.Container.Bounds.Min.X) / this.h)); // Ceiling avrundar alltid uppåt
            this.height = (int)Math.Ceiling((double)((fluid.Container.Bounds.Max.Y - fluid.Container.Bounds.Min.Y) / this.h)); // 4.001 blir tex 5
            this.depth = (int)Math.Ceiling((double)((fluid.Container.Bounds.Max.Z - fluid.Container.Bounds.Min.Z) / this.h));

            // Create a list that holds lists of neighbours
            this.numberOfEntries = this.width * this.height * this.depth;
            this.Entry = new List<FluidParticle>[this.numberOfEntries];
            for (int i = 0; i < this.numberOfEntries; i++)
            {
                this.Entry[i] = new List<FluidParticle>(64); // Max number of neighbours
            }
        }
        private void ComputeGrids(Fluid fluid)
        {
            CreateColorField(fluid);

            //this.SmoothColorField();

            this.NumVertexes = 0;
            for (int i = 0; i < this.Z; i++)
            {
                for(int j = 0; j < this.Y; j++)
                {
                    for(int k = 0; k < this.X - 1; k++)
                    {
                        int index = (i * this.Y + j) * this.X + k;
                        int num6 = (i * this.Y + j) * this.X + k + 1;
                        int num7 = (i * this.Y + j) * (this.X - 1) + k;

                        if (this.isInside[index] * this.isInside[num6] < 0f)
                        {
                            this.xv[num7].Position = this.Bisect(this.isInside[index], this.isInside[num6], this.GCSToWCS(k, j, i), this.GCSToWCS(k + 1, j, i));
                            this.xv[num7].Normal = Vector3.Zero;
                            this.Vertexes[this.NumVertexes] = this.xv[num7];
                            this.NumVertexes++;
                        }
                    }
                }
            }

            for (int i = 0; i < this.Z; i++)
            {
                for (int j = 0; j < this.Y - 1; j++)
                {
                    for (int k = 0; k < this.X; k++)
                    {
                        int num8 = (((i * this.Y) + j) * this.X) + k;
                        int num9 = (((i * this.Y) + (j + 1)) * this.X) + k;
                        int num10 = (((i * (this.Y - 1)) + j) * this.X) + k;

                        if ((this.isInside[num8] * this.isInside[num9]) < 0f)
                        {
                            this.yv[num10].Position = this.Bisect(this.isInside[num8], this.isInside[num9], this.GCSToWCS(k, j, i), this.GCSToWCS(k, j + 1, i));
                            this.yv[num10].Normal = Vector3.Zero;
                            this.Vertexes[this.NumVertexes] = this.yv[num10];
                            this.NumVertexes++;
                        }
                    }
                }
            }

            for (int i = 0; i < this.Z - 1; i++)
            {
                for (int j = 0; j < this.Y; j++)
                {
                    for (int k = 0; k < this.X; k++)
                    {
                        int num11 = (((i * this.Y) + j) * this.X) + k;
                        int num12 = ((((i + 1) * this.Y) + j) * this.X) + k;
                        int num13 = (((i * this.Y) + j) * this.X) + k;

                        if ((this.isInside[num11] * this.isInside[num12]) < 0f)
                        {
                            this.zv[num13].Position = this.Bisect(this.isInside[num11], this.isInside[num12], this.GCSToWCS(k, j, i), this.GCSToWCS(k, j, i + 1));
                            this.zv[num13].Normal = Vector3.Zero;
                            this.Vertexes[this.NumVertexes] = this.zv[num13];
                            this.NumVertexes++;
                        }
                    }
                }
            }
        }
        public void GenerateMesh(Fluid fluid)
        {
            this.ComputeGrids(fluid);

            this.PolygonizeCubes();

            //if (this.SMOOTH)
            //{
            //    this.SmoothMesh();
            //}

            this.UpdateNormals();
        }
        public void CreateColorField(Fluid fluid)
        {
            for (int n = 0; n < X * Y * Z; n++)
            {
                isInside[n] = FluidRendererMarchingCubes.MinimumParticleSize;
            }

            for (int n = 0; n < fluid.ActiveParticles; n++)
            {
                FluidParticle particle = fluid.Particles[n];

                Vector3 position = particle.Position;

                float h = SmoothKernel.h;

                int num5 = (int)((position.X - h - bx) / dx);
                int num6 = (int)((position.Y - h - by) / dy);
                int num7 = (int)((position.Z - h - bz) / dz);
                int num8 = (int)((position.X + h - bx) / dx);
                int num9 = (int)((position.Y + h - by) / dy);
                int num10 = (int)((position.Z + h - bz) / dz);

                if (num5 < 0)
                {
                    num5 = 0;
                }
                else if (num5 >= X)
                {
                    num5 = X - 1;
                }

                if (num6 < 0)
                {
                    num6 = 0;
                }
                else if (num6 >= Y)
                {
                    num6 = Y - 1;
                }

                if (num7 < 0)
                {
                    num7 = 0;
                }
                else if (num7 >= Z)
                {
                    num7 = Z - 1;
                }

                if (num8 < 0)
                {
                    num8 = 0;
                }
                else if (num8 >= X)
                {
                    num8 = X - 1;
                }

                if (num9 < 0)
                {
                    num9 = 0;
                }
                else if (num9 >= Y)
                {
                    num9 = Y - 1;
                }

                if (num10 < 0)
                {
                    num10 = 0;
                }
                else if (num10 >= Z)
                {
                    num10 = Z - 1;
                }

                for (int i = num7; i <= num10; i++)
                {
                    for (int j = num6; j <= num9; j++)
                    {
                        for (int k = num5; k <= num8; k++)
                        {
                            Vector3 p = this.GCSToWCS(k, j, i);

                            if (fluid.Container.Bounds.Contains(p) == ContainmentType.Contains)
                            {
                                Vector3 rv = position - p;
                                if (rv.LengthSquared() < 0.0225f)
                                {
                                    isInside[(i * Y + j) * X + k] -= SmoothKernel.Poly6(rv) * particle.SurfaceNormal;
                                }
                            }
                        }
                    }
                }
            }
        }
        public void LoadContent()
        {
            if (content == null)
            {
                content = new ContentManager(fluidSimulation1.Services, "Content");
            }

            GlassBox glassBox = new GlassBox();
            glassBox.LoadContent(content);

            Fluid = new Fluid(2000, glassBox);
            Fluid.ActiveParticles = 500;

            surfaceTensionSlider = new Slider("Surface Tension: ", 0, 100, Fluid.SurfaceTension, 2);
            surfaceTensionSlider.OnValueChanged += new EventHandler(surfaceTensionSlider_OnValueChanged);
            surfaceTensionSlider.Length = 200;

            viscositySlider = new Slider("Viscosity: ", 0, 100, Fluid.Viscosity, 2);
            viscositySlider.OnValueChanged += new EventHandler(viscositySlider_OnValueChanged);
            viscositySlider.Length = 200;

            massSlider = new Slider("Particle Mass: ", 1, 20, Fluid.ParticleMass, 2);
            massSlider.OnValueChanged += new EventHandler(massSlider_OnValueChanged);
            massSlider.Length = 200;

            particlesSlider = new Slider("Particles: ", 1, Fluid.MaxParticles, Fluid.ActiveParticles, 0);
            particlesSlider.OnValueChanged += new EventHandler(particlesSlider_OnValueChanged);
            particlesSlider.Length = 200;

            timestepSlider = new Slider("Timestep: ", 1, 5, 1, 2);
            timestepSlider.OnValueChanged += new EventHandler(timestepSlider_OnValueChanged);
            timestepSlider.Length = 200;

            rotationSpeedSlider = new Slider("Rotation speed: ", -0.025f, 0.025f, rotationSpeed, 3);
            rotationSpeedSlider.OnValueChanged += new EventHandler(rotationSpeedSlider_OnValueChanged);
            rotationSpeedSlider.Length = 200;

            guiElements = new StackPanel(40);
            guiElements.Add(surfaceTensionSlider);
            guiElements.Add(viscositySlider);
            guiElements.Add(massSlider);
            guiElements.Add(particlesSlider);
            guiElements.Add(timestepSlider);
            guiElements.Add(rotationSpeedSlider);

            restartButton = new Button("Restart", FluidSimulation1.Font);
            restartButton.OnClick += new EventHandler(restartButton_OnClick);
            guiElements.Add(restartButton);

            debugGrid = new DebugGrid(fluidSimulation1.GraphicsDevice);

            guiElements.Font = FluidSimulation1.Font;
            guiElements.LoadContent(content);

            fluidRenderer = new FluidRendererMarchingCubes(Fluid, fluidSimulation1.GraphicsDevice);

            marchingCubesEffect = new BasicEffect(fluidSimulation1.GraphicsDevice);
        }