/// <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);
         }
     }
 }
示例#2
0
        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);
                    }
                }
            }
        }