//private void DoubleDensityRelaxation1(FluidParticle p, float timeStep) //{ // _density = 0; // _densityNear = 0; // _len2 = p.Neighbours.Count; // if (_len2 > MaxNeighbors) // _len2 = MaxNeighbors; // for (_j = 0; _j < _len2; _j++) // { // _q = Vector2.DistanceSquared(p.Position, p.Neighbours[_j].Position); // _distanceCache[_j] = _q; // if (_q < _influenceRadiusSquared && _q != 0) // { // _q = (float)Math.Sqrt(_q); // _q /= Definition.InfluenceRadius; // _qq = ((1 - _q) * (1 - _q)); // _density += _qq; // _densityNear += _qq * (1 - _q); // } // } // _pressure = Definition.Stiffness * (_density - Definition.DensityRest); // _pressureNear = Definition.StiffnessNear * _densityNear; // _dx = Vector2.Zero; // for (_j = 0; _j < _len2; _j++) // { // _q = _distanceCache[_j]; // if (_q < _influenceRadiusSquared && _q != 0) // { // _q = (float)Math.Sqrt(_q); // _rij = p.Neighbours[_j].Position; // _rij -= p.Position; // _rij *= 1 / _q; // _q /= _influenceRadiusSquared; // _d = ((timeStep * timeStep) * (_pressure * (1 - _q) + _pressureNear * (1 - _q) * (1 - _q))); // _rij *= _d * 0.5f; // p.Neighbours[_j].Position += _rij; // _dx -= _rij; // } // } // p.Position += _dx; //} private void DoubleDensityRelaxation(FluidParticle particle, float deltaTime2) { _density = 0.0f; _densityNear = 0.0f; int neightborCount = particle.Neighbours.Count; if (neightborCount > MaxNeighbors) { neightborCount = MaxNeighbors; } for (int i = 0; i < neightborCount; ++i) { FluidParticle neighbour = particle.Neighbours[i]; if (particle.Index == neighbour.Index) { continue; } float q; Vector2.DistanceSquared(ref particle.Position, ref neighbour.Position, out q); _distanceCache[i] = q; if (q > _influenceRadiusSquared) { continue; } q = 1.0f - (float)Math.Sqrt(q) / Definition.InfluenceRadius; float densityDelta = q * q; _density += densityDelta; _densityNear += densityDelta * q; } _pressure = Definition.Stiffness * (_density - Definition.DensityRest); _pressureNear = Definition.StiffnessNear * _densityNear; // For gameplay purposes particle.Density = _density + _densityNear; particle.Pressure = _pressure + _pressureNear; Vector2 delta = Vector2.Zero; for (int i = 0; i < neightborCount; ++i) { FluidParticle neighbour = particle.Neighbours[i]; if (particle.Index == neighbour.Index) { continue; } float q = _distanceCache[i]; if (q > _influenceRadiusSquared) { continue; } q = 1.0f - (float)Math.Sqrt(q) / Definition.InfluenceRadius; float dispFactor = deltaTime2 * (q * (_pressure + _pressureNear * q)); Vector2 direction; Vector2.Subtract(ref neighbour.Position, ref particle.Position, out direction); if (direction.LengthSquared() < float.Epsilon) { continue; } direction.Normalize(); Vector2 disp; Vector2.Multiply(ref direction, dispFactor, out disp); Vector2.Add(ref neighbour.Position, ref disp, out neighbour.Position); Vector2.Multiply(ref direction, -dispFactor, out disp); Vector2.Add(ref delta, ref disp, out delta); } Vector2.Add(ref particle.Position, ref delta, out particle.Position); }
public static Vector2 Add(Vector2 left, Vector2 right) { var result = MonoGameVector2.Add(left.MonoGameVector, right.MonoGameVector); return(new Vector2(result)); }