FluidInfo ILineFluidAffectable.GetFluidInfo(GetTangentCallback callback, Line line)
        {
            if (polygons.Length == 1)
            {
                return(ShapeHelper.GetFluidInfo(Vertexes, callback, line));
            }
            List <Vector2D[]> submerged = new List <Vector2D[]>(polygons.Length);

            for (int index = 0; index < polygons.Length; ++index)
            {
                Vector2D[] vertexes = VertexHelper.GetIntersection(polygons[index], line);
                if (vertexes.Length >= 3)
                {
                    submerged.Add(vertexes);
                }
            }
            if (submerged.Count == 0)
            {
                return(null);
            }
            Vector2D[][] newPolygons = submerged.ToArray();
            Vector2D     centroid    = VertexHelper.GetCentroidOfRange(newPolygons);
            Scalar       area        = VertexHelper.GetAreaOfRange(newPolygons);
            Vector2D     tangent     = callback(centroid);
            Vector2D     dragCenter;
            Scalar       dragArea;

            ShapeHelper.GetFluidInfo(newPolygons, tangent, out dragCenter, out dragArea);
            return(new FluidInfo(dragCenter, dragArea, centroid, area));
        }
        public static FluidInfo GetFluidInfo(Vector2D[] vertexes2, GetTangentCallback callback, Line line)
        {
            Vector2D centroid;
            Scalar   area;
            Vector2D dragCenter;
            Scalar   dragArea;

            Vector2D[] vertexes = ShapeHelper.GetIntersection(vertexes2, line);
            if (vertexes.Length < 3)
            {
                return(null);
            }
            centroid = PolygonShape.GetCentroid(vertexes);
            area     = PolygonShape.GetArea(vertexes);
            Vector2D tangent = callback(centroid);
            Scalar   min, max;

            ShapeHelper.GetProjectedBounds(vertexes, tangent, out min, out max);
            Scalar avg = (max + min) / 2;

            dragCenter = tangent * avg;
            dragArea   = max - min;
            return(new FluidInfo(dragCenter, dragArea, centroid, area));
        }
Example #3
0
        protected internal override void RunLogic(TimeStep step)
        {
            for (int index = 0; index < items.Count; ++index)
            {
                Wrapper wrapper = items[index];
                Body    body    = wrapper.body;

                if (wrapper.affectable == null ||
                    body.IgnoresPhysicsLogics ||
                    Scalar.IsPositiveInfinity(body.Mass.Mass))
                {
                    continue;
                }
                IShape shape         = body.Shape;
                int    isInsideCount = 0;
                foreach (Vector2D corner in body.Rectangle.Corners())
                {
                    Scalar distance = line.GetDistance(corner);
                    if (distance <= 0)
                    {
                        isInsideCount++;
                    }
                }
                if (isInsideCount == 0)
                {
                    continue;
                }

                if (isInsideCount != 4)
                {
                    Vector2D relativeVelocity  = Vector2D.Zero;
                    Vector2D velocityDirection = Vector2D.Zero;
                    Vector2D dragDirection     = Vector2D.Zero;
                    Vector2D centroid          = Vector2D.Zero;


                    Line bodyLine;
                    Line.Transform(ref body.Matrices.ToBody, ref line, out bodyLine);


                    GetTangentCallback callback = delegate(Vector2D centTemp)
                    {
                        centroid = body.Matrices.ToWorldNormal * centTemp;
                        PhysicsHelper.GetRelativeVelocity(ref body.State.Velocity, ref centroid, out relativeVelocity);
                        relativeVelocity  = FluidVelocity - relativeVelocity;
                        velocityDirection = relativeVelocity.Normalized;
                        dragDirection     = body.Matrices.ToBodyNormal * velocityDirection.LeftHandNormal;
                        return(dragDirection);
                    };

                    FluidInfo lineInfo = wrapper.affectable.GetFluidInfo(callback, bodyLine);
                    if (lineInfo == null)
                    {
                        continue;
                    }
                    //  Vector2D centTemp = lineInfo.Centroid;
                    Scalar areaTemp = lineInfo.Area;
                    //  Vector2D centroid = body.Matrices.ToWorldNormal * centTemp;
                    Vector2D buoyancyForce = body.State.Acceleration.Linear * areaTemp * -Density;
                    body.ApplyForce(buoyancyForce, centroid);


/*
 *                  PhysicsHelper.GetRelativeVelocity(ref body.State.Velocity, ref centroid, out relativeVelocity);
 *                  relativeVelocity =  FluidVelocity-relativeVelocity;
 *                  velocityDirection = relativeVelocity.Normalized;
 *                  dragDirection = body.Matrices.ToBodyNormal * velocityDirection.LeftHandNormal;
 *
 *                  lineInfo = wrapper.affectable.GetFluidInfo(dragDirection, bodyLine);
 *                  if (lineInfo == null) { continue; }*/

                    Scalar speedSq      = relativeVelocity.MagnitudeSq;
                    Scalar dragForceMag = -.5f * Density * speedSq * lineInfo.DragArea * DragCoefficient;
                    Scalar maxDrag      = -MathHelper.Sqrt(speedSq) * body.Mass.Mass * step.DtInv;
                    if (dragForceMag < maxDrag)
                    {
                        dragForceMag = maxDrag;
                    }

                    Vector2D dragForce = dragForceMag * velocityDirection;
                    body.ApplyForce(dragForce, body.Matrices.ToWorldNormal * lineInfo.DragCenter);

                    body.ApplyTorque(
                        -body.Mass.MomentOfInertia *
                        (body.Coefficients.DynamicFriction + Density + DragCoefficient) *
                        body.State.Velocity.Angular);
                }
                else
                {
                    Vector2D relativeVelocity  = body.State.Velocity.Linear - FluidVelocity;
                    Vector2D velocityDirection = relativeVelocity.Normalized;
                    Vector2D dragDirection     = body.Matrices.ToBodyNormal * velocityDirection.LeftHandNormal;

                    Vector2D centroid      = wrapper.body.Matrices.ToWorldNormal * wrapper.affectable.Centroid;
                    Vector2D buoyancyForce = body.State.Acceleration.Linear * wrapper.affectable.Area * -Density;
                    wrapper.body.ApplyForce(buoyancyForce, centroid);
                    if (velocityDirection == Vector2D.Zero)
                    {
                        continue;
                    }

                    DragInfo dragInfo = wrapper.affectable.GetFluidInfo(dragDirection);
                    if (dragInfo.DragArea < .01f)
                    {
                        continue;
                    }
                    Scalar speedSq      = relativeVelocity.MagnitudeSq;
                    Scalar dragForceMag = -.5f * Density * speedSq * dragInfo.DragArea * DragCoefficient;
                    Scalar maxDrag      = -MathHelper.Sqrt(speedSq) * body.Mass.Mass * step.DtInv;
                    if (dragForceMag < maxDrag)
                    {
                        dragForceMag = maxDrag;
                    }

                    Vector2D dragForce = dragForceMag * velocityDirection;
                    wrapper.body.ApplyForce(dragForce, body.Matrices.ToWorldNormal * dragInfo.DragCenter);

                    wrapper.body.ApplyTorque(
                        -body.Mass.MomentOfInertia *
                        (body.Coefficients.DynamicFriction + Density + DragCoefficient) *
                        body.State.Velocity.Angular);
                }
            }
        }
Example #4
0
        protected internal override void RunLogic(TimeStep step)
        {
            Scalar         area    = MathHelper.Pi * radius * radius;
            Scalar         density = explosionBody.Mass.Mass / area;
            BoundingCircle circle  = new BoundingCircle(explosionBody.State.Position.Linear, radius);
            Matrix2x3      temp;

            ALVector2D.ToMatrix2x3(ref explosionBody.State.Position, out temp);

            Matrices matrices = new Matrices();

            matrices.SetToWorld(ref temp);


            Vector2D relativeVelocity  = Vector2D.Zero;
            Vector2D velocityDirection = Vector2D.Zero;
            Vector2D dragDirection     = Vector2D.Zero;


            for (int index = 0; index < items.Count; ++index)
            {
                Wrapper   wrapper = items[index];
                Body      body    = wrapper.body;
                Matrix2x3 matrix;
                Matrix2x3.Multiply(ref matrices.ToBody, ref body.Matrices.ToWorld, out matrix);
                ContainmentType   containmentType;
                BoundingRectangle rect = body.Rectangle;
                circle.Contains(ref rect, out containmentType);

                if (containmentType == ContainmentType.Intersects)
                {
                    return;

                    GetTangentCallback callback = delegate(Vector2D centroid)
                    {
                        centroid = body.Matrices.ToWorld * centroid;
                        Vector2D p1 = centroid - explosionBody.State.Position.Linear;
                        Vector2D p2 = centroid - body.State.Position.Linear;

                        PhysicsHelper.GetRelativeVelocity(
                            ref explosionBody.State.Velocity,
                            ref body.State.Velocity,
                            ref p1,
                            ref p2,
                            out relativeVelocity);
                        relativeVelocity  = p1.Normalized * this.pressurePulseSpeed;
                        relativeVelocity  = -relativeVelocity;
                        velocityDirection = relativeVelocity.Normalized;
                        dragDirection     = matrices.ToBodyNormal * velocityDirection.LeftHandNormal;
                        return(dragDirection);
                    };

                    DragInfo dragInfo = wrapper.affectable.GetExplosionInfo(matrix, radius, callback);
                    if (dragInfo == null)
                    {
                        continue;
                    }
                    if (velocityDirection == Vector2D.Zero)
                    {
                        continue;
                    }

                    if (dragInfo.DragArea < .01f)
                    {
                        continue;
                    }
                    Scalar speedSq      = relativeVelocity.MagnitudeSq;
                    Scalar dragForceMag = -.5f * density * speedSq * dragInfo.DragArea * dragCoefficient;
                    Scalar maxDrag      = -MathHelper.Sqrt(speedSq) * body.Mass.Mass * step.DtInv;
                    if (dragForceMag < maxDrag)
                    {
                        dragForceMag = maxDrag;
                    }

                    Vector2D dragForce = dragForceMag * velocityDirection;
                    wrapper.body.ApplyForce(dragForce, (body.Matrices.ToBody * matrices.ToWorld) * dragInfo.DragCenter);
                }
                else if (containmentType == ContainmentType.Contains)
                {
                    Vector2D centroid = body.Matrices.ToWorld * wrapper.affectable.Centroid;

                    Vector2D p1 = centroid - explosionBody.State.Position.Linear;
                    Vector2D p2 = centroid - body.State.Position.Linear;

                    PhysicsHelper.GetRelativeVelocity(
                        ref explosionBody.State.Velocity,
                        ref body.State.Velocity,
                        ref p1,
                        ref p2,
                        out relativeVelocity);
                    relativeVelocity  = p1.Normalized * this.pressurePulseSpeed;
                    relativeVelocity  = -relativeVelocity;
                    velocityDirection = relativeVelocity.Normalized;
                    dragDirection     = matrices.ToBodyNormal * velocityDirection.LeftHandNormal;


                    DragInfo dragInfo = wrapper.affectable.GetFluidInfo(dragDirection);
                    if (dragInfo.DragArea < .01f)
                    {
                        continue;
                    }
                    Scalar speedSq      = relativeVelocity.MagnitudeSq;
                    Scalar dragForceMag = -.5f * density * speedSq * dragInfo.DragArea * dragCoefficient;
                    Scalar maxDrag      = -MathHelper.Sqrt(speedSq) * body.Mass.Mass * step.DtInv;
                    if (dragForceMag < maxDrag)
                    {
                        dragForceMag = maxDrag;
                    }

                    Vector2D dragForce = dragForceMag * velocityDirection;
                    wrapper.body.ApplyForce(dragForce, body.Matrices.ToWorldNormal * dragInfo.DragCenter);

                    wrapper.body.ApplyTorque(
                        -body.Mass.MomentOfInertia *
                        (body.Coefficients.DynamicFriction + density + dragCoefficient) *
                        body.State.Velocity.Angular);
                }
            }
        }
        DragInfo IExplosionAffectable.GetExplosionInfo(Matrix2x3 matrix, Scalar radius, GetTangentCallback callback)
        {
            //TODO: do this right!
            //TODO: do this right!
            Vector2D[] vertexes2 = new Vector2D[Vertexes.Length];
            for (int index = 0; index < vertexes2.Length; ++index)
            {
                vertexes2[index] = matrix * Vertexes[index];
            }
            Vector2D[] inter = VertexHelper.GetIntersection(vertexes2, radius);
            if (inter.Length < 3)
            {
                return(null);
            }
            Vector2D centroid = VertexHelper.GetCentroid(inter);
            Vector2D tangent = callback(centroid);
            Scalar   min, max;

            ShapeHelper.GetProjectedBounds(inter, tangent, out min, out max);
            Scalar avg = (max + min) / 2;

            return(new DragInfo(tangent * avg, max - min));
        }
 FluidInfo ILineFluidAffectable.GetFluidInfo(GetTangentCallback callback, Line line)
 {
     return(ShapeHelper.GetFluidInfo(Vertexes, callback, line));
 }
Example #7
0
 DragInfo IExplosionAffectable.GetExplosionInfo(Matrix2x3 matrix, Scalar radius, GetTangentCallback callback)
 {
     //TODO: do this right!
     Vector2D[] vertexes2 = new Vector2D[Vertexes.Length];
     for (int index = 0; index < vertexes2.Length; ++index)
     {
         vertexes2[index] = matrix * Vertexes[index];
     }
     Vector2D[] inter = VertexHelper.GetIntersection(vertexes2, radius);
     if (inter.Length < 3) { return null; }
     Vector2D centroid = VertexHelper.GetCentroid(inter);
     Vector2D tangent = callback(centroid);
     Scalar min, max;
     ShapeHelper.GetProjectedBounds(inter, tangent, out min, out max);
     Scalar avg = (max + min) / 2;
     return new DragInfo(tangent * avg, max - min);
 }
Example #8
0
 FluidInfo ILineFluidAffectable.GetFluidInfo(GetTangentCallback callback, Line line)
 {
     return ShapeHelper.GetFluidInfo(Vertexes, callback, line);
 }
 FluidInfo ILineFluidAffectable.GetFluidInfo(GetTangentCallback callback, Line line)
 {
     if (polygons.Length == 1)
     {
         return ShapeHelper.GetFluidInfo(Vertexes, callback, line);
     }
     List<Vector2D[]> submerged = new List<Vector2D[]>(polygons.Length);
     for (int index = 0; index < polygons.Length; ++index)
     {
         Vector2D[] vertexes = VertexHelper.GetIntersection(polygons[index], line);
         if (vertexes.Length >= 3) { submerged.Add(vertexes); }
     }
     if (submerged.Count == 0) { return null; }
     Vector2D[][] newPolygons = submerged.ToArray();
     Vector2D centroid = VertexHelper.GetCentroidOfRange(newPolygons);
     Scalar area = VertexHelper.GetAreaOfRange(newPolygons);
     Vector2D tangent = callback(centroid);
     Vector2D dragCenter;
     Scalar dragArea;
     ShapeHelper.GetFluidInfo(newPolygons, tangent, out dragCenter, out dragArea);
     return new FluidInfo(dragCenter, dragArea, centroid, area);
 }