示例#1
0
        public void calcViscosityForce(Sphere p)
        {
            Vector3 f = new Vector3(0, 0, 0);

            int[] closePointInds = Game.neighborsIndicesConcatenated(p.Position);
            for (int i = 0; i < closePointInds.Length; i++)
            {
                int   index = (int)((Game.getDistance(p.Position, Game.particles[closePointInds[i]].Position) * 100) / d);
                float lap   = 0;
                if (index <= 100 && index >= 0)
                {
                    lap = laplacianLookup[index];
                }
                else
                {
                    lap = Poly6WeightKernel(p.Position, Game.particles[closePointInds[i]].Position);
                }

                f += viscosity * Game.particles[closePointInds[i]].Mass * ((Game.particles[closePointInds[i]].Velocity - p.Velocity) / Game.particles[closePointInds[i]].Density) * lap;
            }
            // Console.WriteLine("viscosity force: " + f);
            if (p.verbose)
            {
                Console.WriteLine("Viscocity: " + f);
            }
            p.NetForce += f;
        }
示例#2
0
        /**
         * Kernels: the following functions are the kernels used to calculate the distance weighting of particles
         *          as well as the effect that graident of the vector field has on the particles for each force.
         *
         * Sources used to find these kernels:
         * https://www8.cs.umu.se/kurser/TDBD24/VT06/lectures/sphsurvivalkit.pdf
         * https://nccastaff.bournemouth.ac.uk/jmacey/MastersProjects/MSc15/06Burak/BurakErtekinMScThesis.pdf
         **/


        //Poly6 kernel for distance weighting. used in calculating a particle's density
        public float Poly6WeightKernel(Vector3 x1, Vector3 x2)
        {
            float r = Game.getDistance(x1, x2);

            if (r > d)
            {
                return(0.0f);
            }
            return((315 / (64 * (float)Math.PI * (float)Math.Pow(d, 9))) * (float)Math.Pow(d * d - r * r, 3));
        }
示例#3
0
        //Laplacian kernel for distance weighitng and vector gradient. used forcalculating viscosit force
        public float laplacianKernel(Vector3 x1, Vector3 x2)
        {
            float r = Game.getDistance(x1, x2);

            if (r > d)
            {
                return(0.0f);
            }

            return((45 / ((float)Math.PI * (float)Math.Pow(d, 6))) * (d - r));
        }
示例#4
0
        //Spiky kernel for distance weighitng and vector gradient. used for calculating pressure force
        public Vector3 spikyPressureKernel(Vector3 x1, Vector3 x2)
        {
            float r = Game.getDistance(x1, x2);

            if (r > d)
            {
                return(new Vector3(0, 0, 0));
            }

            return(-1.0f * (45 / ((float)Math.PI * (float)Math.Pow(d, 6))) * (float)Math.Pow(d - r, 2) * (x1 - x2));
        }
示例#5
0
        public Vector3 Poly6GradientKernel(Vector3 x1, Vector3 x2)
        {
            float r = Game.getDistance(x1, x2);

            if (r < 1.0f)
            {
                r = 0.1f;
            }

            if (r > d)
            {
                return(new Vector3(0, 0, 0));
            }

            return((-945 / (32 * (float)Math.PI * (float)Math.Pow(d, 9))) * ((x1 - x2) * (float)Math.Pow(d * d - r * r, 2)));
        }
示例#6
0
        public float CohesionKernel(Vector3 x1, Vector3 x2)
        {
            float r = Game.getDistance(x1, x2);

            float constant = (float)(32 / (Math.PI * Math.Pow(d, 9)));

            if (2 * r > d && r <= d)
            {
                //Console.WriteLine(1);
                return(constant * (float)Math.Pow((d - r), 3) * (float)Math.Pow(r, 3));
            }
            else if (r > 0.0001 && 2 * r <= d)
            {
                //Console.WriteLine(2);
                return(constant * 2 * (float)Math.Pow((d - r), 3) * (float)Math.Pow(r, 3) - (float)Math.Pow(d, 6) / 64);
            }
            //Console.WriteLine(3);
            return(0.0f);
        }
示例#7
0
        public void calcSurfaceTension(Sphere p)
        {
            if (p.normal.Length < gradientFieldThreshold)
            {
                return;
            }

            Vector3 f          = new Vector3(0, 0, 0);
            Vector3 cNormal    = new Vector3(0, 0, 0);
            Vector3 cCurvature = new Vector3(0, 0, 0);
            float   K          = p.Density;

            int[] closePointInds = Game.neighborsIndicesConcatenated(p.Position);
            for (int i = 0; i < closePointInds.Length; i++)
            {
                Vector3 r = p.Position - Game.particles[closePointInds[i]].Position;
                if (Game.getDistance(p.Position, Game.particles[closePointInds[i]].Position) > 0)
                {
                    cNormal    += Game.particles[closePointInds[i]].Mass * CohesionKernel(p.Position, Game.particles[closePointInds[i]].Position) * (r / r.Length);
                    cCurvature += p.normal - Game.particles[closePointInds[i]].normal;
                    K          += Game.particles[closePointInds[i]].Density;
                }
            }
            cNormal    *= p.Mass * -sigma;
            cCurvature *= p.Mass * -sigma;
            if (K > 0.0001)
            {
                K = 2 * p0 / K;
            }
            else
            {
                K = 0;
            }
            f = K * (cNormal + cCurvature);
            if (p.verbose)
            {
                Console.WriteLine("Surface: " + f);
            }

            p.NetForce += f;
        }
示例#8
0
        /**
         * The following functions are implementations of the langrangian fluid equations provided here:
         * https://www.cs.ubc.ca/~rbridson/fluidsimulation/fluids_notes.pdf
         *
         * This source was linked by Amir on the game physics course page
         **/

        public void calcDensity(Sphere p)
        {
            float dense = 1f;

            int[] closePointInds = Game.neighborsIndicesConcatenated(p.Position);
            for (int i = 0; i < closePointInds.Length; i++)
            {
                int   index = (int)((Game.getDistance(p.Position, Game.particles[closePointInds[i]].Position) * 100) / d);
                float poly  = 0;
                if (false)
                {
                    poly = poly6Lookup[index];
                }
                else
                {
                    poly = Poly6WeightKernel(p.Position, Game.particles[closePointInds[i]].Position);
                }

                dense += Game.particles[closePointInds[i]].Mass * poly;
            }
            p.Density = dense;
        }