/// <summary> /// Finds what vertices of the geometry that is inside the fluidcontainer /// </summary> /// <param name="geom">The geometry to check against</param> private void FindVerticesInFluid(Geom geom) { _vertices.Clear(); for (int i = 0; i < geom.worldVertices.Count; i++) { _vert = geom.worldVertices[i]; if (_fluidContainer.Contains(ref _vert)) { _vertices.Add(_vert); } } }
public override void Update(float dt) { _fluidContainer.Update(dt); for (int i = 0; i < _geomList.Count; i++) { Fixture fixture = _geomList[i]; Body body = fixture.Body; Vertices localVertices = fixture.Shape.GetVertices(); _totalArea = fixture.Shape.Area; //If the AABB of the geometry does not intersect the fluidcontainer //continue to the next geometry AABB aabb; fixture.Shape.ComputeAABB(out aabb, ref fixture.Body._xf, 0); if (!_fluidContainer.Intersect(ref aabb)) { continue; } //Find the vertices contained in the fluidcontainer _vertices.Clear(); for (int k = 0; k < localVertices.Count; k++) { _vert = fixture.Body.GetWorldPoint(localVertices[k]); if (_fluidContainer.Contains(ref _vert)) { _vertices.Add(_vert); } } //The geometry is not in the fluid, up til a certain point. if (_vertices.Count < localVertices.Count * 0.15f) { _geomInFluidList[fixture] = false; } _area = _vertices.GetArea(); if (_area < .0001) { continue; } _centroid = _vertices.GetCentroid(); //Calculate buoyancy force _buoyancyForce = -_gravity * (_area * fixture.Shape.Density) * Density; //Calculate linear and rotational drag _centroidVelocity = fixture.Body.GetLinearVelocityFromWorldPoint(_centroid); _axis.X = -_centroidVelocity.Y; _axis.Y = _centroidVelocity.X; //can't normalize a zero length vector if (_axis.X != 0 || _axis.Y != 0) { _axis.Normalize(); } _vertices.ProjectToAxis(ref _axis, out _min, out _max); _dragArea = Math.Abs(_max - _min); _partialMass = fixture.Body.Mass * (_area / _totalArea); _linearDragForce = -.5f * Density * _dragArea * LinearDragCoefficient * _partialMass * _centroidVelocity; _rotationalDragTorque = -fixture.Body.AngularVelocity * AngularDragCoefficient * _partialMass; //Add the buoyancy force and lienar drag force Vector2.Add(ref _buoyancyForce, ref _linearDragForce, out _totalForce); //Apply total force to the body body.ApplyForce(ref _totalForce); //Apply rotational drag body.ApplyTorque(_rotationalDragTorque); if (_geomInFluidList[_geomList[i]] == false) { //The geometry is now in the water. Fire the Entry event _geomInFluidList[_geomList[i]] = true; if (Entry != null) { Entry(_geomList[i], _vertices); } } } }