private void updateForces(final List<FluidParticle> particles, final Vector2 globalForce) {
// Optimise slightly by precomputing a few things needed in our calculations.
final float halfMass = Constants.PARTICLE_MASS / 2.0f;
final float massViscosityProduct = Constants.PARTICLE_MASS * theViscosity;
final Vector2 distance = new Vector2();
for (int i = particles.size()-1; i >= 0 ; --i) {
final FluidParticle particle = particles.get(i);
// Add global force to every particle
particle.force.add(globalForce);
// Get neighbours for each of the particles
final List<Integer> neighbours = theGrid.GetNeighbourIndex(particle);
for (final int neighbourIndex : neighbours) {
// Prevent double tests
if (neighbourIndex > i) {
final FluidParticle neighbour = particles.get(neighbourIndex);
if (neighbour.density > Constants.FLOAT_EPSILON) {
distance.x = particle.position.x - neighbour.position.x;
distance.y = particle.position.y - neighbour.position.y;
// Pressure
float scalar = halfMass * (particle.pressure + neighbour.pressure) / neighbour.density;
Vector2 force = theSKPressure.CalculateGradient(distance);
force.multiply(scalar);
particle.force.subtract(force);
neighbour.force.add(force);
// Viscosity
scalar = massViscosityProduct * theSKViscosity.CalculateLaplacian(distance)
/ neighbour.density;
force = Vector2.Subtract(neighbour.velocity, particle.velocity);
force.multiply(scalar);
particle.force.add(force);
neighbour.force.subtract(force);
}
}