Exemplo n.º 1
0
        public static Polygon RandomCircleSweep(FP scale, int vertexCount)
        {
            FP fP = scale / 4;

            PolygonPoint[] array = new PolygonPoint[vertexCount];
            for (int i = 0; i < vertexCount; i++)
            {
                do
                {
                    bool flag = i % 250 == 0;
                    if (flag)
                    {
                        fP += scale / 2 * (0.5 - PolygonGenerator.RNG.NextFP());
                    }
                    else
                    {
                        bool flag2 = i % 50 == 0;
                        if (flag2)
                        {
                            fP += scale / 5 * (0.5 - PolygonGenerator.RNG.NextFP());
                        }
                        else
                        {
                            fP += 25 * scale / vertexCount * (0.5 - PolygonGenerator.RNG.NextFP());
                        }
                    }
                    fP = ((fP > scale / 2) ? (scale / 2) : fP);
                    fP = ((fP < scale / 10) ? (scale / 10) : fP);
                }while (fP < scale / 10 || fP > scale / 2);
                PolygonPoint polygonPoint = new PolygonPoint(fP * FP.Cos(PolygonGenerator.PI_2 * i / vertexCount), fP * FP.Sin(PolygonGenerator.PI_2 * i / vertexCount));
                array[i] = polygonPoint;
            }
            return(new Polygon(array));
        }
Exemplo n.º 2
0
        public static Vertices CreateRoundedRectangle(FP width, FP height, FP xRadius, FP yRadius, int segments)
        {
            bool flag = yRadius > height / 2 || xRadius > width / 2;

            if (flag)
            {
                throw new Exception("Rounding amount can't be more than half the height and width respectively.");
            }
            bool flag2 = segments < 0;

            if (flag2)
            {
                throw new Exception("Segments must be zero or more.");
            }
            Debug.Assert(Settings.MaxPolygonVertices >= 8);
            Vertices vertices = new Vertices();
            bool     flag3    = segments == 0;

            if (flag3)
            {
                vertices.Add(new TSVector2(width * 0.5f - xRadius, -height * 0.5f));
                vertices.Add(new TSVector2(width * 0.5f, -height * 0.5f + yRadius));
                vertices.Add(new TSVector2(width * 0.5f, height * 0.5f - yRadius));
                vertices.Add(new TSVector2(width * 0.5f - xRadius, height * 0.5f));
                vertices.Add(new TSVector2(-width * 0.5f + xRadius, height * 0.5f));
                vertices.Add(new TSVector2(-width * 0.5f, height * 0.5f - yRadius));
                vertices.Add(new TSVector2(-width * 0.5f, -height * 0.5f + yRadius));
                vertices.Add(new TSVector2(-width * 0.5f + xRadius, -height * 0.5f));
            }
            else
            {
                int       num   = segments * 4 + 8;
                FP        x     = MathHelper.TwoPi / (num - 4);
                int       num2  = num / 4;
                TSVector2 value = new TSVector2(width / 2 - xRadius, height / 2 - yRadius);
                vertices.Add(value + new TSVector2(xRadius, -yRadius + yRadius));
                short num3 = 0;
                for (int i = 1; i < num; i++)
                {
                    bool flag4 = i - num2 == 0 || i - num2 * 3 == 0;
                    if (flag4)
                    {
                        value.x *= -1;
                        num3    -= 1;
                    }
                    else
                    {
                        bool flag5 = i - num2 * 2 == 0;
                        if (flag5)
                        {
                            value.y *= -1;
                            num3    -= 1;
                        }
                    }
                    vertices.Add(value + new TSVector2(xRadius * FP.Cos(x * -(i + (int)num3)), -yRadius * FP.Sin(x * -(i + (int)num3))));
                }
            }
            return(vertices);
        }
Exemplo n.º 3
0
 public static void CreateRotationX(FP radians, out Matrix result)
 {
     result     = Matrix.Identity;
     result.M22 = FP.Cos(radians);
     result.M23 = FP.Sin(radians);
     result.M32 = -result.M23;
     result.M33 = result.M22;
 }
Exemplo n.º 4
0
 public static void CreateRotationY(FP radians, out Matrix result)
 {
     result     = Matrix.Identity;
     result.M11 = FP.Cos(radians);
     result.M13 = FP.Sin(radians);
     result.M31 = -result.M13;
     result.M33 = result.M11;
 }
Exemplo n.º 5
0
 public static void CreateRotationZ(FP radians, out Matrix result)
 {
     result     = Matrix.Identity;
     result.M11 = FP.Cos(radians);
     result.M12 = FP.Sin(radians);
     result.M21 = -result.M12;
     result.M22 = result.M11;
 }
Exemplo n.º 6
0
        private void IntegrateCallback(object obj)
        {
            RigidBody body = obj as RigidBody;

            TSVector temp;

            TSVector.Multiply(ref body.linearVelocity, timestep, out temp);
            TSVector.Add(ref temp, ref body.position, out body.position);

            if (!(body.isParticle))
            {
                //exponential map
                TSVector axis;
                FP       angle             = body.angularVelocity.magnitude;
                FP       halfTimeStep      = FP.Half * timestep;
                FP       halfTimeStepAngle = halfTimeStep * angle;
                if (angle < FP.EN3)
                {
                    // use Taylor's expansions of sync function
                    // axis = body.angularVelocity * (FP.Half * timestep - (timestep * timestep * timestep) * (0.020833333333f) * angle * angle);
                    //TSVector.Multiply(ref body.angularVelocity, (halfTimeStep - (timestep * timestep * timestep) * (2082 * FP.EN6) * angle * angle), out axis);
                    TSVector.Multiply(ref body.angularVelocity, halfTimeStep, out axis);
                }
                else
                {
                    // sync(fAngle) = sin(c*fAngle)/t
                    TSVector.Multiply(ref body.angularVelocity, (FP.Sin(halfTimeStepAngle) / angle), out axis);
                }

                TSQuaternion dorn = new TSQuaternion(axis.x, axis.y, axis.z, FP.Cos(halfTimeStepAngle));
                TSQuaternion ornA;
                TSQuaternion.CreateFromMatrix(ref body.orientation, out ornA);

                TSQuaternion.Multiply(ref dorn, ref ornA, out dorn);

                dorn.Normalize();
                TSMatrix.CreateFromQuaternion(ref dorn, out body.orientation);
            }

            body.linearVelocity  /= (1 + timestep * body.linearDrag);
            body.angularVelocity /= (1 + timestep * body.angularDrag);

            /*if ((body.Damping & RigidBody.DampingType.Linear) != 0)
             *  TSVector.Multiply(ref body.linearVelocity, currentLinearDampFactor, out body.linearVelocity);
             *
             * if ((body.Damping & RigidBody.DampingType.Angular) != 0)
             *  TSVector.Multiply(ref body.angularVelocity, currentAngularDampFactor, out body.angularVelocity);*/

            body.Update();


            if (CollisionSystem.EnableSpeculativeContacts || body.EnableSpeculativeContacts)
            {
                body.SweptExpandBoundingBox(timestep);
            }
        }
Exemplo n.º 7
0
        public static Matrix CreateRotationX(FP radians)
        {
            Matrix matrix = Matrix.Identity;

            matrix.M22 = FP.Cos(radians);
            matrix.M23 = FP.Sin(radians);
            matrix.M32 = -matrix.M23;
            matrix.M33 = matrix.M22;
            return(matrix);
        }
Exemplo n.º 8
0
        public static Matrix CreateRotationY(FP radians)
        {
            Matrix matrix = Matrix.Identity;

            matrix.M11 = FP.Cos(radians);
            matrix.M13 = FP.Sin(radians);
            matrix.M31 = -matrix.M13;
            matrix.M33 = matrix.M11;
            return(matrix);
        }
Exemplo n.º 9
0
        public static Matrix CreateRotationZ(FP radians)
        {
            Matrix matrix = Matrix.Identity;

            matrix.M11 = FP.Cos(radians);
            matrix.M12 = FP.Sin(radians);
            matrix.M21 = -matrix.M12;
            matrix.M22 = matrix.M11;
            return(matrix);
        }
Exemplo n.º 10
0
        private void Integrate()
        {
            for (int index = 0, length = rigidBodies.Count; index < length; index++)
            {
                var body = rigidBodies[index];
                if (body.isStatic || !body.IsActive)
                {
                    continue;
                }

                body.position += body.linearVelocity * timestep;
                if (!(body.isParticle))
                {
                    //exponential map
                    TSVector axis;
                    FP       angle = body.angularVelocity.magnitude;

                    if (angle < FP.EN3)
                    {
                        // use Taylor's expansions of sync function
                        // axis = body.angularVelocity * (FP.Half * timestep - (timestep * timestep * timestep) * (0.020833333333f) * angle * angle);
                        TSVector.Multiply(body.angularVelocity, (FP.Half * timestep - (timestep * timestep * timestep) * (2082 * FP.EN6) * angle * angle), out axis);
                    }
                    else
                    {
                        // sync(fAngle) = sin(c*fAngle)/t
                        TSVector.Multiply(body.angularVelocity, (FP.Sin(FP.Half * angle * timestep) / angle), out axis);
                    }

                    TSQuaternion dorn = new TSQuaternion(axis.x, axis.y, axis.z, FP.Cos(angle * timestep * FP.Half));
                    TSQuaternion ornA; TSQuaternion.CreateFromMatrix(ref body.orientation, out ornA);

                    TSQuaternion.Multiply(ref dorn, ref ornA, out dorn);

                    dorn.Normalize(); TSMatrix.CreateFromQuaternion(ref dorn, out body.orientation);
                }

                body.linearVelocity  *= 1 / (1 + timestep * body.linearDrag);
                body.angularVelocity *= 1 / (1 + timestep * body.angularDrag);

                /*if ((body.Damping & RigidBody.DampingType.Linear) != 0)
                 *  TSVector.Multiply(ref body.linearVelocity, currentLinearDampFactor, out body.linearVelocity);
                 *
                 * if ((body.Damping & RigidBody.DampingType.Angular) != 0)
                 *  TSVector.Multiply(ref body.angularVelocity, currentAngularDampFactor, out body.angularVelocity);*/

                body.Update();


                if (CollisionSystem.EnableSpeculativeContacts || body.EnableSpeculativeContacts)
                {
                    body.SweptExpandBoundingBox(timestep);
                }
            }
        }
        public static TSVector2 Rotate(this TSVector2 v, FP degrees)
        {
            FP sin = FP.Sin(degrees * FP.Deg2Rad);
            FP cos = FP.Cos(degrees * FP.Deg2Rad);

            FP tx = v.x;
            FP ty = v.y;

            v.x = (cos * tx) - (sin * ty);
            v.y = (sin * tx) + (cos * ty);
            return(v);
        }
Exemplo n.º 12
0
        public static Vertices CreateEllipse(FP xRadius, FP yRadius, int numberOfEdges)
        {
            Vertices vertices = new Vertices();
            FP       x        = MathHelper.TwoPi / numberOfEdges;

            vertices.Add(new TSVector2(xRadius, 0));
            for (int i = numberOfEdges - 1; i > 0; i--)
            {
                vertices.Add(new TSVector2(xRadius * FP.Cos(x * i), -yRadius * FP.Sin(x * i)));
            }
            return(vertices);
        }
Exemplo n.º 13
0
        public static Vertices CreateArc(FP radians, int sides, FP radius)
        {
            Debug.Assert(radians > 0, "The arc needs to be larger than 0");
            Debug.Assert(sides > 1, "The arc needs to have more than 1 sides");
            Debug.Assert(radius > 0, "The arc needs to have a radius larger than 0");
            Vertices vertices = new Vertices();
            FP       x        = radians / sides;

            for (int i = sides - 1; i > 0; i--)
            {
                vertices.Add(new TSVector2(radius * FP.Cos(x * i), radius * FP.Sin(x * i)));
            }
            return(vertices);
        }
Exemplo n.º 14
0
        /// <summary>
        /// Creates a ellipse with the specified width, height and number of edges.
        /// </summary>
        /// <param name="xRadius">Width of the ellipse.</param>
        /// <param name="yRadius">Height of the ellipse.</param>
        /// <param name="numberOfEdges">The number of edges. The more edges, the more it resembles an ellipse</param>
        /// <returns></returns>
        public static Vertices CreateEllipse(FP xRadius, FP yRadius, int numberOfEdges)
        {
            Vertices vertices = new Vertices();

            FP stepSize = FP.PiTimes2 / numberOfEdges;

            vertices.Add(new FPVector2(xRadius, 0));
            for (int i = numberOfEdges - 1; i > 0; --i)
            {
                vertices.Add(new FPVector2(xRadius * FP.Cos(stepSize * i),
                                           -yRadius * FP.Sin(stepSize * i)));
            }

            return(vertices);
        }
Exemplo n.º 15
0
        public static void CreateRotationZ(FP radians, out TSMatrix result)
        {
            FP num2 = FP.Cos(radians);
            FP num  = FP.Sin(radians);

            result.M11 = num2;
            result.M12 = num;
            result.M13 = FP.Zero;
            result.M21 = -num;
            result.M22 = num2;
            result.M23 = FP.Zero;
            result.M31 = FP.Zero;
            result.M32 = FP.Zero;
            result.M33 = FP.One;
        }
Exemplo n.º 16
0
    public static TSQuaternion AngleAxis(FP angle, TSVector axis)
    {
        axis = axis * FP.Deg2Rad;
        axis.Normalize();

        FP halfAngle = angle * FP.Deg2Rad * FP.Half;

        TSQuaternion rotation;
        FP           sin = FP.Sin(halfAngle);

        rotation.x = axis.x * sin;
        rotation.y = axis.y * sin;
        rotation.z = axis.z * sin;
        rotation.w = FP.Cos(halfAngle);

        return(rotation);
    }
Exemplo n.º 17
0
        public static TSMatrix CreateRotationZ(FP radians)
        {
            TSMatrix matrix;
            FP       num2 = FP.Cos(radians);
            FP       num  = FP.Sin(radians);

            matrix.M11 = num2;
            matrix.M12 = num;
            matrix.M13 = FP.Zero;
            matrix.M21 = -num;
            matrix.M22 = num2;
            matrix.M23 = FP.Zero;
            matrix.M31 = FP.Zero;
            matrix.M32 = FP.Zero;
            matrix.M33 = FP.One;
            return(matrix);
        }
Exemplo n.º 18
0
    public static void CreateFromYawPitchRoll(FP yaw, FP pitch, FP roll, out TSQuaternion result)
    {
        FP num9 = roll * FP.Half;
        FP num6 = FP.Sin(num9);
        FP num5 = FP.Cos(num9);
        FP num8 = pitch * FP.Half;
        FP num4 = FP.Sin(num8);
        FP num3 = FP.Cos(num8);
        FP num7 = yaw * FP.Half;
        FP num2 = FP.Sin(num7);
        FP num  = FP.Cos(num7);

        result.x = ((num * num4) * num5) + ((num2 * num3) * num6);
        result.y = ((num2 * num3) * num5) - ((num * num4) * num6);
        result.z = ((num * num3) * num6) - ((num2 * num4) * num5);
        result.w = ((num * num3) * num5) + ((num2 * num4) * num6);
    }
Exemplo n.º 19
0
        public static int[] Build(List <FPVector> pointCloud, Approximation factor)
        {
            List <int> allIndices = new List <int>();

            int steps = (int)factor;

            for (int thetaIndex = 0; thetaIndex < steps; thetaIndex++)
            {
                // [0,PI]
                FP theta    = FPMath.Pi / (steps - 1) * thetaIndex;
                FP sinTheta = FP.Sin(theta);
                FP cosTheta = FP.Cos(theta);

                for (int phiIndex = 0; phiIndex < steps; phiIndex++)
                {
                    // [-PI,PI]
                    FP phi    = ((2 * FP.One) * FPMath.Pi) / (steps - 0) * phiIndex - FPMath.Pi;
                    FP sinPhi = FP.Sin(phi);
                    FP cosPhi = FP.Cos(phi);

                    FPVector dir = new FPVector(sinTheta * cosPhi, cosTheta, sinTheta * sinPhi);

                    int index = FindExtremePoint(pointCloud, ref dir);
                    allIndices.Add(index);
                }
            }

            allIndices.Sort();

            for (int i = 1; i < allIndices.Count; i++)
            {
                if (allIndices[i - 1] == allIndices[i])
                {
                    allIndices.RemoveAt(i - 1); i--;
                }
            }

            return(allIndices.ToArray());

            // or using 3.5 extensions
            // return allIndices.Distinct().ToArray();
        }
Exemplo n.º 20
0
        /// <summary>
        /// Rotate the vertices with the defined value in radians.
        ///
        /// Warning: Using this method on an active set of vertices of a Body,
        /// will cause problems with collisions. Use Body.Rotation instead.
        /// </summary>
        /// <param name="value">The amount to rotate by in radians.</param>
        public void Rotate(FP value)
        {
            Debug.Assert(!AttachedToBody, "Rotating vertices that are used by a Body can result in unstable behavior.");

            FP num1 = FP.Cos(value);
            FP num2 = FP.Sin(value);

            for (int i = 0; i < Count; i++)
            {
                TSVector2 position = this[i];
                this[i] = new TSVector2((position.x * num1 + position.y * -num2), (position.x * num2 + position.y * num1));
            }

            if (Holes != null && Holes.Count > 0)
            {
                foreach (Vertices hole in Holes)
                {
                    hole.Rotate(value);
                }
            }
        }
Exemplo n.º 21
0
        public void Rotate(FP value)
        {
            Debug.Assert(!this.AttachedToBody, "Rotating vertices that are used by a Body can result in unstable behavior.");
            FP y  = FP.Cos(value);
            FP fP = FP.Sin(value);

            for (int i = 0; i < base.Count; i++)
            {
                TSVector2 tSVector = base[i];
                base[i] = new TSVector2(tSVector.x * y + tSVector.y * -fP, tSVector.x * fP + tSVector.y * y);
            }
            bool flag = this.Holes != null && this.Holes.Count > 0;

            if (flag)
            {
                foreach (Vertices current in this.Holes)
                {
                    current.Rotate(value);
                }
            }
        }
Exemplo n.º 22
0
        /// <summary>
        /// Creates a gear shape with the specified radius and number of teeth.
        /// </summary>
        /// <param name="radius">The radius.</param>
        /// <param name="numberOfTeeth">The number of teeth.</param>
        /// <param name="tipPercentage">The tip percentage.</param>
        /// <param name="toothHeight">Height of the tooth.</param>
        /// <returns></returns>
        public static Vertices CreateGear(FP radius, int numberOfTeeth, FP tipPercentage, FP toothHeight)
        {
            Vertices vertices = new Vertices();

            FP stepSize = FP.PiTimes2 / numberOfTeeth;

            tipPercentage /= 100f;
            FPMath.Clamp(tipPercentage, 0f, 1f);
            FP toothTipStepSize = (stepSize / 2f) * tipPercentage;

            FP toothAngleStepSize = (stepSize - (toothTipStepSize * 2f)) / 2f;

            for (int i = numberOfTeeth - 1; i >= 0; --i)
            {
                if (toothTipStepSize > 0f)
                {
                    vertices.Add(
                        new FPVector2(radius *
                                      FP.Cos(stepSize * i + toothAngleStepSize * 2f + toothTipStepSize),
                                      -radius *
                                      FP.Sin(stepSize * i + toothAngleStepSize * 2f + toothTipStepSize)));

                    vertices.Add(
                        new FPVector2((radius + toothHeight) *
                                      FP.Cos(stepSize * i + toothAngleStepSize + toothTipStepSize),
                                      -(radius + toothHeight) *
                                      FP.Sin(stepSize * i + toothAngleStepSize + toothTipStepSize)));
                }

                vertices.Add(new FPVector2((radius + toothHeight) *
                                           FP.Cos(stepSize * i + toothAngleStepSize),
                                           -(radius + toothHeight) *
                                           FP.Sin(stepSize * i + toothAngleStepSize)));

                vertices.Add(new FPVector2(radius * FP.Cos(stepSize * i),
                                           -radius * FP.Sin(stepSize * i)));
            }

            return(vertices);
        }
Exemplo n.º 23
0
        public static Vertices CreateGear(FP radius, int numberOfTeeth, FP tipPercentage, FP toothHeight)
        {
            Vertices vertices = new Vertices();
            FP       x        = MathHelper.TwoPi / numberOfTeeth;

            tipPercentage /= 100f;
            MathHelper.Clamp(tipPercentage, 0f, 1f);
            FP fP  = x / 2f * tipPercentage;
            FP fP2 = (x - fP * 2f) / 2f;

            for (int i = numberOfTeeth - 1; i >= 0; i--)
            {
                bool flag = fP > 0f;
                if (flag)
                {
                    vertices.Add(new TSVector2(radius * FP.Cos(x * i + fP2 * 2f + fP), -radius * FP.Sin(x * i + fP2 * 2f + fP)));
                    vertices.Add(new TSVector2((radius + toothHeight) * FP.Cos(x * i + fP2 + fP), -(radius + toothHeight) * FP.Sin(x * i + fP2 + fP)));
                }
                vertices.Add(new TSVector2((radius + toothHeight) * FP.Cos(x * i + fP2), -(radius + toothHeight) * FP.Sin(x * i + fP2)));
                vertices.Add(new TSVector2(radius * FP.Cos(x * i), -radius * FP.Sin(x * i)));
            }
            return(vertices);
        }
Exemplo n.º 24
0
        /// <summary>
        /// Creates a matrix which rotates around the given axis by the given angle.
        /// </summary>
        /// <param name="axis">The axis.</param>
        /// <param name="angle">The angle.</param>
        /// <param name="result">The resulting rotation matrix</param>
        #region public static void CreateFromAxisAngle(ref JVector axis, FP angle, out JMatrix result)
        public static void CreateFromAxisAngle(ref TSVector axis, FP angle, out TSMatrix result)
        {
            FP x     = axis.x;
            FP y     = axis.y;
            FP z     = axis.z;
            FP num2  = FP.Sin(angle);
            FP num   = FP.Cos(angle);
            FP num11 = x * x;
            FP num10 = y * y;
            FP num9  = z * z;
            FP num8  = x * y;
            FP num7  = x * z;
            FP num6  = y * z;

            result.M11 = num11 + (num * (FP.One - num11));
            result.M12 = (num8 - (num * num8)) + (num2 * z);
            result.M13 = (num7 - (num * num7)) - (num2 * y);
            result.M21 = (num8 - (num * num8)) - (num2 * z);
            result.M22 = num10 + (num * (FP.One - num10));
            result.M23 = (num6 - (num * num6)) + (num2 * x);
            result.M31 = (num7 - (num * num7)) + (num2 * y);
            result.M32 = (num6 - (num * num6)) - (num2 * x);
            result.M33 = num9 + (num * (FP.One - num9));
        }
Exemplo n.º 25
0
        /// <summary>
        /// Creates an capsule with the specified  height, radius and number of edges.
        /// A capsule has the same form as a pill capsule.
        /// </summary>
        /// <param name="height">Height (inner height + radii) of the capsule.</param>
        /// <param name="topRadius">Radius of the top.</param>
        /// <param name="topEdges">The number of edges of the top. The more edges, the more it resembles an capsule</param>
        /// <param name="bottomRadius">Radius of bottom.</param>
        /// <param name="bottomEdges">The number of edges of the bottom. The more edges, the more it resembles an capsule</param>
        /// <returns></returns>
        public static Vertices CreateCapsule(FP height, FP topRadius, int topEdges, FP bottomRadius,
                                             int bottomEdges)
        {
            if (height <= 0)
            {
                throw new ArgumentException("Height must be longer than 0", "height");
            }

            if (topRadius <= 0)
            {
                throw new ArgumentException("The top radius must be more than 0", "topRadius");
            }

            if (topEdges <= 0)
            {
                throw new ArgumentException("Top edges must be more than 0", "topEdges");
            }

            if (bottomRadius <= 0)
            {
                throw new ArgumentException("The bottom radius must be more than 0", "bottomRadius");
            }

            if (bottomEdges <= 0)
            {
                throw new ArgumentException("Bottom edges must be more than 0", "bottomEdges");
            }

            if (topRadius >= height / 2)
            {
                throw new ArgumentException(
                          "The top radius must be lower than height / 2. Higher values of top radius would create a circle, and not a half circle.",
                          "topRadius");
            }

            if (bottomRadius >= height / 2)
            {
                throw new ArgumentException(
                          "The bottom radius must be lower than height / 2. Higher values of bottom radius would create a circle, and not a half circle.",
                          "bottomRadius");
            }

            Vertices vertices = new Vertices();

            FP newHeight = (height - topRadius - bottomRadius) * 0.5f;

            // top
            vertices.Add(new FPVector2(topRadius, newHeight));

            FP stepSize = FP.Pi / topEdges;

            for (int i = 1; i < topEdges; i++)
            {
                vertices.Add(new FPVector2(topRadius * FP.Cos(stepSize * i),
                                           topRadius * FP.Sin(stepSize * i) + newHeight));
            }

            vertices.Add(new FPVector2(-topRadius, newHeight));

            // bottom
            vertices.Add(new FPVector2(-bottomRadius, -newHeight));

            stepSize = FP.Pi / bottomEdges;
            for (int i = 1; i < bottomEdges; i++)
            {
                vertices.Add(new FPVector2(-bottomRadius * FP.Cos(stepSize * i),
                                           -bottomRadius * FP.Sin(stepSize * i) - newHeight));
            }

            vertices.Add(new FPVector2(bottomRadius, -newHeight));

            return(vertices);
        }
Exemplo n.º 26
0
        public Dictionary <Fixture, TSVector2> Activate(TSVector2 pos, FP radius, FP maxForce)
        {
            AABB aABB;

            aABB.LowerBound = pos + new TSVector2(-radius, -radius);
            aABB.UpperBound = pos + new TSVector2(radius, radius);
            Fixture[] shapes              = new Fixture[this.MaxShapes];
            Fixture[] containedShapes     = new Fixture[5];
            bool      exit                = false;
            int       shapeCount          = 0;
            int       containedShapeCount = 0;

            this.World.QueryAABB(delegate(Fixture fixture)
            {
                bool flag22 = fixture.TestPoint(ref pos);
                bool result2;
                if (flag22)
                {
                    bool ignoreWhenInsideShape = this.IgnoreWhenInsideShape;
                    if (ignoreWhenInsideShape)
                    {
                        exit    = true;
                        result2 = false;
                        return(result2);
                    }
                    Fixture[] arg_45_0  = containedShapes;
                    int num4            = containedShapeCount;
                    containedShapeCount = num4 + 1;
                    arg_45_0[num4]      = fixture;
                }
                else
                {
                    Fixture[] arg_62_0 = shapes;
                    int num4           = shapeCount;
                    shapeCount         = num4 + 1;
                    arg_62_0[num4]     = fixture;
                }
                result2 = true;
                return(result2);
            }, ref aABB);
            bool exit2 = exit;
            Dictionary <Fixture, TSVector2> result;

            if (exit2)
            {
                result = new Dictionary <Fixture, TSVector2>();
            }
            else
            {
                Dictionary <Fixture, TSVector2> dictionary = new Dictionary <Fixture, TSVector2>(shapeCount + containedShapeCount);
                FP[] array = new FP[shapeCount * 2];
                int  num   = 0;
                for (int i = 0; i < shapeCount; i++)
                {
                    CircleShape  circleShape = shapes[i].Shape as CircleShape;
                    bool         flag        = circleShape != null;
                    PolygonShape polygonShape;
                    if (flag)
                    {
                        Vertices  vertices = new Vertices();
                        TSVector2 item     = TSVector2.zero + new TSVector2(circleShape.Radius, 0);
                        vertices.Add(item);
                        item = TSVector2.zero + new TSVector2(0, circleShape.Radius);
                        vertices.Add(item);
                        item = TSVector2.zero + new TSVector2(-circleShape.Radius, circleShape.Radius);
                        vertices.Add(item);
                        item = TSVector2.zero + new TSVector2(0, -circleShape.Radius);
                        vertices.Add(item);
                        polygonShape = new PolygonShape(vertices, 0);
                    }
                    else
                    {
                        polygonShape = (shapes[i].Shape as PolygonShape);
                    }
                    bool flag2 = shapes[i].Body.BodyType == BodyType.Dynamic && polygonShape != null;
                    if (flag2)
                    {
                        TSVector2 tSVector = shapes[i].Body.GetWorldPoint(polygonShape.MassData.Centroid) - pos;
                        FP        y        = FP.Atan2(tSVector.y, tSVector.x);
                        FP        y2       = FP.MaxValue;
                        FP        y3       = FP.MinValue;
                        FP        fP       = 0f;
                        FP        fP2      = 0f;
                        for (int j = 0; j < polygonShape.Vertices.Count; j++)
                        {
                            TSVector2 tSVector2 = shapes[i].Body.GetWorldPoint(polygonShape.Vertices[j]) - pos;
                            FP        fP3       = FP.Atan2(tSVector2.y, tSVector2.x);
                            FP        fP4       = fP3 - y;
                            fP4 = (fP4 - MathHelper.Pi) % (2 * MathHelper.Pi);
                            bool flag3 = fP4 < 0f;
                            if (flag3)
                            {
                                fP4 += 2 * MathHelper.Pi;
                            }
                            fP4 -= MathHelper.Pi;
                            bool flag4 = FP.Abs(fP4) > MathHelper.Pi;
                            if (!flag4)
                            {
                                bool flag5 = fP4 > y3;
                                if (flag5)
                                {
                                    y3  = fP4;
                                    fP2 = fP3;
                                }
                                bool flag6 = fP4 < y2;
                                if (flag6)
                                {
                                    y2 = fP4;
                                    fP = fP3;
                                }
                            }
                        }
                        array[num] = fP;
                        num++;
                        array[num] = fP2;
                        num++;
                    }
                }
                Array.Sort <FP>(array, 0, num, this._rdc);
                this._data.Clear();
                bool flag7 = true;
                for (int k = 0; k < num; k++)
                {
                    Fixture fixture = null;
                    int     num2    = (k == num - 1) ? 0 : (k + 1);
                    bool    flag8   = array[k] == array[num2];
                    if (!flag8)
                    {
                        bool flag9 = k == num - 1;
                        FP   x;
                        if (flag9)
                        {
                            x = array[0] + MathHelper.Pi * 2 + array[k];
                        }
                        else
                        {
                            x = array[k + 1] + array[k];
                        }
                        x /= 2;
                        TSVector2 pos2       = pos;
                        TSVector2 point      = radius * new TSVector2(FP.Cos(x), FP.Sin(x)) + pos;
                        bool      hitClosest = false;
                        this.World.RayCast(delegate(Fixture f, TSVector2 p, TSVector2 n, FP fr)
                        {
                            Body body   = f.Body;
                            bool flag22 = !this.IsActiveOn(body);
                            FP result2;
                            if (flag22)
                            {
                                result2 = 0;
                            }
                            else
                            {
                                hitClosest = true;
                                fixture    = f;
                                result2    = fr;
                            }
                            return(result2);
                        }, pos2, point);
                        bool flag10 = hitClosest && fixture.Body.BodyType == BodyType.Dynamic;
                        if (flag10)
                        {
                            bool flag11 = this._data.Any <ShapeData>() && this._data.Last <ShapeData>().Body == fixture.Body && !flag7;
                            if (flag11)
                            {
                                int       index = this._data.Count - 1;
                                ShapeData value = this._data[index];
                                value.Max         = array[num2];
                                this._data[index] = value;
                            }
                            else
                            {
                                ShapeData item2;
                                item2.Body = fixture.Body;
                                item2.Min  = array[k];
                                item2.Max  = array[num2];
                                this._data.Add(item2);
                            }
                            bool flag12 = this._data.Count > 1 && k == num - 1 && this._data.Last <ShapeData>().Body == this._data.First <ShapeData>().Body&& this._data.Last <ShapeData>().Max == this._data.First <ShapeData>().Min;
                            if (flag12)
                            {
                                ShapeData value2 = this._data[0];
                                value2.Min = this._data.Last <ShapeData>().Min;
                                this._data.RemoveAt(this._data.Count - 1);
                                this._data[0] = value2;
                                while (this._data.First <ShapeData>().Min >= this._data.First <ShapeData>().Max)
                                {
                                    value2.Min   -= MathHelper.Pi * 2;
                                    this._data[0] = value2;
                                }
                            }
                            int       index2 = this._data.Count - 1;
                            ShapeData value3 = this._data[index2];
                            while (this._data.Count > 0 && this._data.Last <ShapeData>().Min >= this._data.Last <ShapeData>().Max)
                            {
                                value3.Min         = this._data.Last <ShapeData>().Min - 2 * MathHelper.Pi;
                                this._data[index2] = value3;
                            }
                            flag7 = false;
                        }
                        else
                        {
                            flag7 = true;
                        }
                    }
                }
                for (int l = 0; l < this._data.Count; l++)
                {
                    bool flag13 = !this.IsActiveOn(this._data[l].Body);
                    if (!flag13)
                    {
                        FP   fP5    = this._data[l].Max - this._data[l].Min;
                        FP   fP6    = MathHelper.Min(RealExplosion.MaxEdgeOffset, this.EdgeRatio * fP5);
                        int  num3   = FP.Ceiling((fP5 - 2f * fP6 - (this.MinRays - 1) * this.MaxAngle) / this.MaxAngle).AsInt();
                        bool flag14 = num3 < 0;
                        if (flag14)
                        {
                            num3 = 0;
                        }
                        FP y4  = (fP5 - fP6 * 2f) / (this.MinRays + num3 - 1);
                        FP fP7 = this._data[l].Min + fP6;
                        while (fP7 < this._data[l].Max || MathUtils.FPEquals(fP7, this._data[l].Max, 0.0001f))
                        {
                            TSVector2      pos3        = pos;
                            TSVector2      tSVector3   = pos + radius * new TSVector2(FP.Cos(fP7), FP.Sin(fP7));
                            TSVector2      tSVector4   = TSVector2.zero;
                            FP             fP8         = FP.MaxValue;
                            List <Fixture> fixtureList = this._data[l].Body.FixtureList;
                            for (int m = 0; m < fixtureList.Count; m++)
                            {
                                Fixture      fixture3 = fixtureList[m];
                                RayCastInput rayCastInput;
                                rayCastInput.Point1      = pos3;
                                rayCastInput.Point2      = tSVector3;
                                rayCastInput.MaxFraction = 50f;
                                RayCastOutput rayCastOutput;
                                bool          flag15 = fixture3.RayCast(out rayCastOutput, ref rayCastInput, 0);
                                if (flag15)
                                {
                                    bool flag16 = fP8 > rayCastOutput.Fraction;
                                    if (flag16)
                                    {
                                        fP8       = rayCastOutput.Fraction;
                                        tSVector4 = rayCastOutput.Fraction * tSVector3 + (1 - rayCastOutput.Fraction) * pos3;
                                    }
                                }
                                FP        scaleFactor = fP5 / (this.MinRays + num3) * maxForce * 180f / MathHelper.Pi * (1f - TSMath.Min(FP.One, fP8));
                                TSVector2 tSVector5   = TSVector2.Dot(scaleFactor * new TSVector2(FP.Cos(fP7), FP.Sin(fP7)), -rayCastOutput.Normal) * new TSVector2(FP.Cos(fP7), FP.Sin(fP7));
                                this._data[l].Body.ApplyLinearImpulse(ref tSVector5, ref tSVector4);
                                bool flag17 = dictionary.ContainsKey(fixture3);
                                if (flag17)
                                {
                                    Dictionary <Fixture, TSVector2> dictionary2 = dictionary;
                                    Fixture key = fixture3;
                                    dictionary2[key] += tSVector5;
                                }
                                else
                                {
                                    dictionary.Add(fixture3, tSVector5);
                                }
                                bool flag18 = fP8 > 1f;
                                if (flag18)
                                {
                                    tSVector4 = tSVector3;
                                }
                            }
                            fP7 += y4;
                        }
                    }
                }
                for (int n2 = 0; n2 < containedShapeCount; n2++)
                {
                    Fixture fixture2 = containedShapes[n2];
                    bool    flag19   = !this.IsActiveOn(fixture2.Body);
                    if (!flag19)
                    {
                        FP          scaleFactor2 = this.MinRays * maxForce * 180f / MathHelper.Pi;
                        CircleShape circleShape2 = fixture2.Shape as CircleShape;
                        bool        flag20       = circleShape2 != null;
                        TSVector2   worldPoint;
                        if (flag20)
                        {
                            worldPoint = fixture2.Body.GetWorldPoint(circleShape2.Position);
                        }
                        else
                        {
                            PolygonShape polygonShape2 = fixture2.Shape as PolygonShape;
                            worldPoint = fixture2.Body.GetWorldPoint(polygonShape2.MassData.Centroid);
                        }
                        TSVector2 value4 = scaleFactor2 * (worldPoint - pos);
                        fixture2.Body.ApplyLinearImpulse(ref value4, ref worldPoint);
                        bool flag21 = !dictionary.ContainsKey(fixture2);
                        if (flag21)
                        {
                            dictionary.Add(fixture2, value4);
                        }
                    }
                }
                result = dictionary;
            }
            return(result);
        }
Exemplo n.º 27
0
 /// <summary>
 /// Set using an angle in radians.
 /// </summary>
 /// <param name="angle"></param>
 public void Set(FP angle)
 {
     // TODO_ERIN optimize
     s = FP.Sin(angle);
     c = FP.Cos(angle);
 }
Exemplo n.º 28
0
 /// <summary>
 /// Returns the cosine of value.
 /// </summary>
 public static FP Cos(FP value)
 {
     return(FP.Cos(value));
 }
Exemplo n.º 29
0
        //Rounded rectangle contributed by Jonathan Smars - [email protected]

        /// <summary>
        /// Creates a rounded rectangle with the specified width and height.
        /// </summary>
        /// <param name="width">The width.</param>
        /// <param name="height">The height.</param>
        /// <param name="xRadius">The rounding X radius.</param>
        /// <param name="yRadius">The rounding Y radius.</param>
        /// <param name="segments">The number of segments to subdivide the edges.</param>
        /// <returns></returns>
        public static Vertices CreateRoundedRectangle(FP width, FP height, FP xRadius, FP yRadius,
                                                      int segments)
        {
            if (yRadius > height / 2 || xRadius > width / 2)
            {
                throw new Exception("Rounding amount can't be more than half the height and width respectively.");
            }
            if (segments < 0)
            {
                throw new Exception("Segments must be zero or more.");
            }

            //We need at least 8 vertices to create a rounded rectangle
            Debug.Assert(Settings.MaxPolygonVertices >= 8);

            Vertices vertices = new Vertices();

            if (segments == 0)
            {
                vertices.Add(new FPVector2(width * .5f - xRadius, -height * .5f));
                vertices.Add(new FPVector2(width * .5f, -height * .5f + yRadius));

                vertices.Add(new FPVector2(width * .5f, height * .5f - yRadius));
                vertices.Add(new FPVector2(width * .5f - xRadius, height * .5f));

                vertices.Add(new FPVector2(-width * .5f + xRadius, height * .5f));
                vertices.Add(new FPVector2(-width * .5f, height * .5f - yRadius));

                vertices.Add(new FPVector2(-width * .5f, -height * .5f + yRadius));
                vertices.Add(new FPVector2(-width * .5f + xRadius, -height * .5f));
            }
            else
            {
                int numberOfEdges = (segments * 4 + 8);

                FP  stepSize = FP.PiTimes2 / (numberOfEdges - 4);
                int perPhase = numberOfEdges / 4;

                FPVector2 posOffset = new FPVector2(width / 2 - xRadius, height / 2 - yRadius);
                vertices.Add(posOffset + new FPVector2(xRadius, -yRadius + yRadius));
                short phase = 0;
                for (int i = 1; i < numberOfEdges; i++)
                {
                    if (i - perPhase == 0 || i - perPhase * 3 == 0)
                    {
                        posOffset.x *= -1;
                        phase--;
                    }
                    else if (i - perPhase * 2 == 0)
                    {
                        posOffset.y *= -1;
                        phase--;
                    }

                    vertices.Add(posOffset + new FPVector2(xRadius * FP.Cos(stepSize * -(i + phase)),
                                                           -yRadius * FP.Sin(stepSize * -(i + phase))));
                }
            }

            return(vertices);
        }
Exemplo n.º 30
0
        /// <summary>
        /// Activate the explosion at the specified position.
        /// </summary>
        /// <param name="pos">The position where the explosion happens </param>
        /// <param name="radius">The explosion radius </param>
        /// <param name="maxForce">The explosion force at the explosion point (then is inversely proportional to the square of the distance)</param>
        /// <returns>A list of bodies and the amount of force that was applied to them.</returns>
        public Dictionary <Fixture, TSVector2> Activate(TSVector2 pos, FP radius, FP maxForce)
        {
            AABB aabb;

            aabb.LowerBound = pos + new TSVector2(-radius, -radius);
            aabb.UpperBound = pos + new TSVector2(radius, radius);
            Fixture[] shapes = new Fixture[MaxShapes];

            // More than 5 shapes in an explosion could be possible, but still strange.
            Fixture[] containedShapes = new Fixture[5];
            bool      exit            = false;

            int shapeCount          = 0;
            int containedShapeCount = 0;

            // Query the world for overlapping shapes.
            World.QueryAABB(
                fixture =>
            {
                if (fixture.TestPoint(ref pos))
                {
                    if (IgnoreWhenInsideShape)
                    {
                        exit = true;
                        return(false);
                    }

                    containedShapes[containedShapeCount++] = fixture;
                }
                else
                {
                    shapes[shapeCount++] = fixture;
                }

                // Continue the query.
                return(true);
            }, ref aabb);

            if (exit)
            {
                return(new Dictionary <Fixture, TSVector2>());
            }

            Dictionary <Fixture, TSVector2> exploded = new Dictionary <Fixture, TSVector2>(shapeCount + containedShapeCount);

            // Per shape max/min angles for now.
            FP[] vals     = new FP[shapeCount * 2];
            int  valIndex = 0;

            for (int i = 0; i < shapeCount; ++i)
            {
                PolygonShape ps;
                CircleShape  cs = shapes[i].Shape as CircleShape;
                if (cs != null)
                {
                    // We create a "diamond" approximation of the circle
                    Vertices  v   = new Vertices();
                    TSVector2 vec = TSVector2.zero + new TSVector2(cs.Radius, 0);
                    v.Add(vec);
                    vec = TSVector2.zero + new TSVector2(0, cs.Radius);
                    v.Add(vec);
                    vec = TSVector2.zero + new TSVector2(-cs.Radius, cs.Radius);
                    v.Add(vec);
                    vec = TSVector2.zero + new TSVector2(0, -cs.Radius);
                    v.Add(vec);
                    ps = new PolygonShape(v, 0);
                }
                else
                {
                    ps = shapes[i].Shape as PolygonShape;
                }

                if ((shapes[i].Body.BodyType == BodyType.Dynamic) && ps != null)
                {
                    TSVector2 toCentroid      = shapes[i].Body.GetWorldPoint(ps.MassData.Centroid) - pos;
                    FP        angleToCentroid = FP.Atan2(toCentroid.y, toCentroid.x);
                    FP        min             = FP.MaxValue;
                    FP        max             = FP.MinValue;
                    FP        minAbsolute     = 0.0f;
                    FP        maxAbsolute     = 0.0f;

                    for (int j = 0; j < ps.Vertices.Count; ++j)
                    {
                        TSVector2 toVertex = (shapes[i].Body.GetWorldPoint(ps.Vertices[j]) - pos);
                        FP        newAngle = FP.Atan2(toVertex.y, toVertex.x);
                        FP        diff     = (newAngle - angleToCentroid);

                        diff = (diff - FP.Pi) % (2 * FP.Pi);
                        // the minus pi is important. It means cutoff for going other direction is at 180 deg where it needs to be

                        if (diff < 0.0f)
                        {
                            diff += 2 * FP.Pi; // correction for not handling negs
                        }
                        diff -= FP.Pi;

                        if (FP.Abs(diff) > FP.Pi)
                        {
                            continue; // Something's wrong, point not in shape but exists angle diff > 180
                        }
                        if (diff > max)
                        {
                            max         = diff;
                            maxAbsolute = newAngle;
                        }
                        if (diff < min)
                        {
                            min         = diff;
                            minAbsolute = newAngle;
                        }
                    }

                    vals[valIndex] = minAbsolute;
                    ++valIndex;
                    vals[valIndex] = maxAbsolute;
                    ++valIndex;
                }
            }

            Array.Sort(vals, 0, valIndex, _rdc);
            _data.Clear();
            bool rayMissed = true;

            for (int i = 0; i < valIndex; ++i)
            {
                Fixture fixture = null;
                FP      midpt;

                int iplus = (i == valIndex - 1 ? 0 : i + 1);
                if (vals[i] == vals[iplus])
                {
                    continue;
                }

                if (i == valIndex - 1)
                {
                    // the single edgecase
                    midpt = (vals[0] + FP.PiTimes2 + vals[i]);
                }
                else
                {
                    midpt = (vals[i + 1] + vals[i]);
                }

                midpt = midpt / 2;

                TSVector2 p1 = pos;
                TSVector2 p2 = radius * new TSVector2(FP.Cos(midpt), FP.Sin(midpt)) + pos;

                // RaycastOne
                bool hitClosest = false;
                World.RayCast((f, p, n, fr) =>
                {
                    Body body = f.Body;

                    if (!IsActiveOn(body))
                    {
                        return(0);
                    }

                    hitClosest = true;
                    fixture    = f;
                    return(fr);
                }, p1, p2);

                //draws radius points
                if ((hitClosest) && (fixture.Body.BodyType == BodyType.Dynamic))
                {
                    if ((_data.Any()) && (_data.Last().Body == fixture.Body) && (!rayMissed))
                    {
                        int       laPos = _data.Count - 1;
                        ShapeData la    = _data[laPos];
                        la.Max       = vals[iplus];
                        _data[laPos] = la;
                    }
                    else
                    {
                        // make new
                        ShapeData d;
                        d.Body = fixture.Body;
                        d.Min  = vals[i];
                        d.Max  = vals[iplus];
                        _data.Add(d);
                    }

                    if ((_data.Count > 1) &&
                        (i == valIndex - 1) &&
                        (_data.Last().Body == _data.First().Body) &&
                        (_data.Last().Max == _data.First().Min))
                    {
                        ShapeData fi = _data[0];
                        fi.Min = _data.Last().Min;
                        _data.RemoveAt(_data.Count - 1);
                        _data[0] = fi;
                        while (_data.First().Min >= _data.First().Max)
                        {
                            fi.Min  -= FP.PiTimes2;
                            _data[0] = fi;
                        }
                    }

                    int       lastPos = _data.Count - 1;
                    ShapeData last    = _data[lastPos];
                    while ((_data.Count > 0) &&
                           (_data.Last().Min >= _data.Last().Max))    // just making sure min<max
                    {
                        last.Min       = _data.Last().Min - FP.PiTimes2;
                        _data[lastPos] = last;
                    }
                    rayMissed = false;
                }
                else
                {
                    rayMissed = true; // raycast did not find a shape
                }
            }

            for (int i = 0; i < _data.Count; ++i)
            {
                if (!IsActiveOn(_data[i].Body))
                {
                    continue;
                }

                FP arclen = _data[i].Max - _data[i].Min;

                FP  first        = TSMath.Min(MaxEdgeOffset, EdgeRatio * arclen);
                int insertedRays = FP.Ceiling((((arclen - 2.0f * first) - (MinRays - 1) * MaxAngle) / MaxAngle)).AsInt();

                if (insertedRays < 0)
                {
                    insertedRays = 0;
                }

                FP offset = (arclen - first * 2.0f) / ((FP)MinRays + insertedRays - 1);

                //Note: This loop can go into infinite as it operates on FPs.
                //Added FPEquals with a large epsilon.
                for (FP j = _data[i].Min + first;
                     j < _data[i].Max || MathUtils.FPEquals(j, _data[i].Max, 0.0001f);
                     j += offset)
                {
                    TSVector2 p1        = pos;
                    TSVector2 p2        = pos + radius * new TSVector2(FP.Cos(j), FP.Sin(j));
                    TSVector2 hitpoint  = TSVector2.zero;
                    FP        minlambda = FP.MaxValue;

                    List <Fixture> fl = _data[i].Body.FixtureList;
                    for (int x = 0; x < fl.Count; x++)
                    {
                        Fixture      f = fl[x];
                        RayCastInput ri;
                        ri.Point1      = p1;
                        ri.Point2      = p2;
                        ri.MaxFraction = 50f;

                        RayCastOutput ro;
                        if (f.RayCast(out ro, ref ri, 0))
                        {
                            if (minlambda > ro.Fraction)
                            {
                                minlambda = ro.Fraction;
                                hitpoint  = ro.Fraction * p2 + (1 - ro.Fraction) * p1;
                            }
                        }

                        // the force that is to be applied for this particular ray.
                        // offset is angular coverage. lambda*length of segment is distance.
                        FP impulse = (arclen / (MinRays + insertedRays)) * maxForce * 180.0f / FP.Pi * (1.0f - SyncFrame.TSMath.Min(FP.One, minlambda));

                        // We Apply the impulse!!!
                        TSVector2 vectImp = TSVector2.Dot(impulse * new TSVector2(FP.Cos(j), FP.Sin(j)), -ro.Normal) * new TSVector2(FP.Cos(j), FP.Sin(j));
                        _data[i].Body.ApplyLinearImpulse(ref vectImp, ref hitpoint);

                        // We gather the fixtures for returning them
                        if (exploded.ContainsKey(f))
                        {
                            exploded[f] += vectImp;
                        }
                        else
                        {
                            exploded.Add(f, vectImp);
                        }

                        if (minlambda > 1.0f)
                        {
                            hitpoint = p2;
                        }
                    }
                }
            }

            // We check contained shapes
            for (int i = 0; i < containedShapeCount; ++i)
            {
                Fixture fix = containedShapes[i];

                if (!IsActiveOn(fix.Body))
                {
                    continue;
                }

                FP        impulse = MinRays * maxForce * 180.0f / FP.Pi;
                TSVector2 hitPoint;

                CircleShape circShape = fix.Shape as CircleShape;
                if (circShape != null)
                {
                    hitPoint = fix.Body.GetWorldPoint(circShape.Position);
                }
                else
                {
                    PolygonShape shape = fix.Shape as PolygonShape;
                    hitPoint = fix.Body.GetWorldPoint(shape.MassData.Centroid);
                }

                TSVector2 vectImp = impulse * (hitPoint - pos);

                fix.Body.ApplyLinearImpulse(ref vectImp, ref hitPoint);

                if (!exploded.ContainsKey(fix))
                {
                    exploded.Add(fix, vectImp);
                }
            }

            return(exploded);
        }