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; }
public void calcPresssureForce(Sphere p) { Vector3 f = new Vector3(0, 0, 0); int[] closePointInds = Game.neighborsIndicesConcatenated(p.Position); for (int i = 0; i < closePointInds.Length; i++) { float fScalar = -1.0f * Game.particles[closePointInds[i]].Mass * ((p.Pressure + Game.particles[closePointInds[i]].Pressure) / (2 * Game.particles[closePointInds[i]].Density)); f += fScalar * spikyPressureKernel(p.Position, Game.particles[closePointInds[i]].Position); } float withSelf = -1.0f * p.Mass * ((p.Pressure + p.Pressure) / (2 * p.Density)); f -= withSelf * spikyPressureKernel(p.Position, p.Position); if (p.verbose) { Console.WriteLine("pressure: " + f + " -- " + p.Density); } if (f.Length > 80) { f.Normalize(); f *= 80; } p.NetForce += f; }
public void calcColorGradient(Sphere p) { Vector3 n = new Vector3(0, 0, 0); int[] closePointInds = Game.neighborsIndicesConcatenated(p.Position); for (int i = 0; i < closePointInds.Length; i++) { n += ((Game.particles[closePointInds[i]].Mass / Game.particles[closePointInds[i]].Density)) * Poly6GradientKernel(p.Position, Game.particles[closePointInds[i]].Position); } if (n.Length > 0) { n.Normalize(); } p.normal = n; }
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; }
/** * 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; }