Exemplo n.º 1
0
        //Calculates the maximum boundingbox size of a standard rectangular boundingbox
        internal static float CalcBoxSize(MFG.Vector3 offset, Texture2D image)
        {
            float xx = Math.Max(Math.Abs(offset.x), Math.Abs(image.width - offset.x));
            float yy = Math.Max(Math.Abs(offset.y), Math.Abs(image.height - offset.y));

            return((float)Math.Sqrt(xx * xx + yy * yy));
        }
Exemplo n.º 2
0
 //Constructor calls base constructor, setting velocity to speed in rotation direction, and parented to Scene
 public Bullet(MFG.Vector3 position, float rotation, SpriteSet sprites, List <SceneObject> ignoreList, SceneObject ignoreParent) : base(position, DistDirToXY(speed, rotation), rotation + (float)Math.PI, sprites, Scene)
 {
     image           = sprites.images[2];                                       //Sets the image out of the spriteset
     friction        = 0;                                                       //No friction
     offset          = new MFG.Vector3(-image.width / 2, -image.height / 2, 0); //Sets the offset for the bullet (Centered)
     scale           = 1F;                                                      //Full scale
     maxBoxDimension = CalcBoxSize(offset, image);                              //Returns the maxiumum size of the box dimension (NOTE THAT THIS ONLY WORKS WITH DEFAULT BOXES)
     Box             = GetDefaultBoundingBox();                                 //Sets the default rectangular bounding box
     specificIgnore.AddRange(ignoreList.FindAll(x => (x != Scene)));            //Finds all non-Scene sceneObjects in the provided list, and adds them to the ignorelist
     specificIgnore.Add(ignoreParent);                                          //Adds the creator (not parent) to the ignorelist
 }
        //Checks if the provided lines intersect
        //Derived from https://blogs.sas.com/content/iml/2018/07/09/intersection-line-segments.html
        private static bool Intersects(VecLine a, VecLine b)
        {
            //Convert the lines to 4 points
            MFG.Vector3 p1 = a.p;
            MFG.Vector3 p2 = a.p + a.v;
            MFG.Vector3 q1 = b.p;
            MFG.Vector3 q2 = b.p + b.v;

            //Form a matrix from the vector differences between the points
            MFG.Matrix3 A = new MFG.Matrix3((p2 - p1).x, (p2 - p1).y, 0, (q1 - q2).x, (q1 - q2).y, 0, 0, 0, 1);

            //Form a vector from the differences between the start points
            MFG.Vector3 B = q1 - p1;

            //Then
            //A*t = b
            //t = A^-1 * b

            //Get the inverted matrix as required by the previous maths
            MFG.Matrix3 inverted = A.GetInverted();

            if (inverted != null)                                                                       //If it is invertible, they don't share a slope. The lines will intersect.
            {
                MFG.Vector3 solution = inverted * B;                                                    //Solve the equation
                return((solution.x >= 0 && solution.x <= 1) && (solution.y >= 0 && solution.y <= 1));   //If the solution falls in the unit square, valid collision, else not.
            }
            else                                                                                        //Otherwise, if they share a slope,
            {                                                                                           //Check for overlaps
                if (IsBetween(p1, p2, q1))                                                              //Is q1 between p1 and p2?
                {
                    return(true);                                                                       //They collide!
                }
                if (IsBetween(p1, p2, q2))                                                              //Is q2 between p1 and p2?
                {
                    return(true);                                                                       //They collide!
                }
                if (IsBetween(q1, q2, p1))                                                              //Is p11 between q1 and q2?
                {
                    return(true);                                                                       //They collide!
                }
                return(false);                                                                          //If there were no overlaps, they don't collide!
            }
        }
        /*
         * Narrow phase collision detection considers each line of the bounding box of object A vs each line in the bounding box of object B.
         * If slopes match+not collinear, it escapes as false.
         * It then checks for collisions by representing each line as a parametric linear equation point+t*vector, then checks for where their (x,y) match.
         * If the lines collide such that both parametric variables are between 0 and 1, there is a collision between the line segments.
         */
        private static bool Collides(BoundingBox a, BoundingBox b)
        {
            var origin = new MFG.Vector3(0, 0, 1);
            int aLen   = a.vertices.Length;
            int bLen   = b.vertices.Length;

            for (int i = 0; i < aLen; i++)                                                              //For each vertex comprising the bounding box of the first object
            {
                var lineA = new VecLine(a.vertices[i], a.vertices[(i + 1) % aLen]);                     //Create a line to the next vertex
                for (int j = 0; j < bLen; j++)                                                          //For each vertex comprising the bounding box of the first object
                {
                    var lineB = new VecLine(b.vertices[j], b.vertices[(j + 1) % bLen]);                 //Create a line to the next vertex
                    if (Intersects(lineA, lineB))                                                       //Do the line segments intersect?
                    {
                        return(true);                                                                   //Yes! So the boxes collide!
                    }
                }
            }
            return(false);                                                                               //No, none do, so the boxes don't collide.
        }
        //Checks if c is collinearly contained within a and b
        //Derived from https://stackoverflow.com/a/328122
        private static Boolean IsBetween(MFG.Vector3 a, MFG.Vector3 b, MFG.Vector3 c)
        {
            float crossProduct = (c.y - a.y) * (b.x - a.x) - (c.x - a.x) * (b.y - a.y);

            if (Math.Abs(crossProduct) > 0.000001F)
            {
                return(false);
            }
            float dotProduct = (c.x - a.x) * (b.x - a.x) + (c.y - a.y) * (b.y - a.y);

            if (dotProduct < 0)
            {
                return(false);
            }
            float squaredLengthBA = (b.x - a.x) * (b.x - a.x) + (b.y - a.y) * (b.y - a.y);

            if (dotProduct > squaredLengthBA)
            {
                return(false);
            }
            return(true);
        }
Exemplo n.º 6
0
 //Converts a homogenous V3 to a V2
 internal static Vector2 ConvertV3ToV2(MFG.Vector3 vec) => new Vector2(vec.x, vec.y);
 internal VecLine(MFG.Vector3 startPoint, MFG.Vector3 endPoint)
 {
     p = startPoint;
     v = endPoint - startPoint;
 }