/// <summary>
 /// Default constructor for Object.  Sets all values to 0
 /// </summary>
 public Object()
 {
     speed = Vector2.Zero;
     position = Vector2.Zero;
     origin = Vector2.Zero;
     angle = 0;
     turnSpeed = 0;
     image = "";
     Bounding = new RectangleF();
 }
 /// <summary>
 /// Construct new cannon ball.
 /// </summary>
 /// <param name="p">Position of the projectile</param>
 /// <param name="dir">Direction of movement</param>
 /// <param name="t">Texture representing projectile</param>
 /// <param name="da">Damage that projectile deals upon impact</param>
 /// <param name="s">Speed for projectile</param>
 /// <param name="a">Angle that projectile is oriented upon spawn</param>
 public CannonBall(Vector2 p, Vector2 dir, Texture2D t, float da, Vector2 s, float a)
     : this()
 {
     position = p;
     direction = dir;
     texture = t;
     damage = da;
     speed = s;
     angle = a;
     origin = new Vector2(texture.Width / 2, texture.Height / 2);
     Bounding = new RectangleF(position, texture);
 }
        /// <summary>
        /// Takes in an ObjectData sturcture and pulls all data from it, and stores it in the proper variables.  Also takes in a texture to represent this object
        /// </summary>
        /// <param name="d">ObjectData structure.  Loaded from main game through ContentPipeline</param>
        /// <param name="tex">Texture to represent object.  Loaded from main game through ContentPipeline</param>
        public Object(ObjectData d, Texture2D tex)
        {
            speed = d.speed;
            position = Vector2.Zero;;
            image = d.image;
            texture = tex;
            origin = new Vector2(texture.Width / 2, texture.Height / 2);

            //angle and turnSpeed are stored as degrees in XML file.  Convert to radians
            angle = MathHelper.ToRadians(d.angle);
            turnSpeed = MathHelper.ToRadians(d.turnSpeed);
            Bounding = new RectangleF(position, texture);
        }
 /// <summary>
 /// Constructor for Objects without using ObjectData structure
 /// </summary>
 /// <param name="p">Position to spawn object</param>
 /// <param name="a">Angle to rotate object by at spawn</param>
 /// <param name="tex">Texture to represent that object</param>
 public Object(Vector2 p, float a, Texture2D tex)
 {
     position = p;
     angle = a;
     texture = tex;
     origin = new Vector2(texture.Width/2, texture.Height/2);
     Bounding = new RectangleF(position, texture);
 }
 /// <summary>
 /// A different collision detection algorithm using very basic axis aligned boxes.
 /// </summary>
 /// <param name="r">The other rectangle that is being checked against</param>
 /// <returns>returns true if the two boxes overlap, false otherwise</returns>
 public bool IntersectsB(RectangleF r)
 {
     /*
      * (x,y)  (x+w,y)
      * ----------
      * |        |
      * |        |
      * |        |
      * ----------
      * (x,y+h)(x+w,y+h)
      */
     //if the this retangle's position + its dimension are less than the the other retangle's position, then the two are not intersecting.  Same is true the other way around.
     if (position.X + dimensions.X < r.position.X)
         return false;
     if (r.position.X + r.dimensions.X < this.position.X)
         return false;
     if (this.position.Y + this.dimensions.Y < r.position.Y)
         return false;
     if (r.position.Y + r.dimensions.Y < this.position.Y)
         return false;
     return true;
 }
        /// <summary>
        /// Check if two RectangleF's intersect using the Separating Axis Theorem
        /// </summary>
        /// <param name="B">The rectangle that this one is being checked against for collisions</param>
        /// <returns></returns>
        public bool Intersects(RectangleF B)
        {
            /*
             * There are four cases when using the Seperating Axis Theorem with axis aligned bounding boxes
             *      Case 1: there is a seperating line along the first box's X-AXIS
             *      Case 2: there is a seperating line along the first box's Y-AXIS
             *      Case 3: there is a seperating line along the second box's X-AXIS
             *      Case 4: there is a seperating line along the second box's Y-AXIS
             *  If any of these four cases is true, then there is no collision (there exists a seperating axis between the two objects)
             *  So, apply each of the four cases, if any is true, return false.  If the are all false, return true
             *  The general seperating axis theorem algorithm is as follows:
             *      | T • L | > | ( WA*Ax ) • L | + | ( HA*Ay ) • L | + | ( WB*Bx ) • L | + |( HB*By ) • L |
             *
             *      VARIABLE KEY
             *          T   =   distance between object A and B                 (B.Position - A.Position)
             *          L   =   the axis you are checking along                 (changes for each case)
             *
             *          WA  =   the halfwidth of object A. Changes when rotated (A.HalfX)
             *          HA  =   the halfheight of object A. "       "    "      (A.HalfY)
             *          Ax  =   the vector describing the x-axis of object A    (Vector2.Normalize(A.HalfX))
             *          Ay  =   the vector describing the y-axis of object A    (Vector2.Normalize(A.HalfY))
             *
             *          WB  =   the halfwidth of object B. Changes when rotated (B.HalfX)
             *          HB  =   the halfheight of object B. "       "    "      (B.HalfY)
             *          Bx  =   the vector describing the x-axis of object B    (Vector2.Normalize(B.HalfX))
             *          By  =   the vector describing the y-axis of object B    (Vector2.Normalize(B.HalfY))
             * It is important to take the absolute value of each dot product.  Depending on the angle of the OBB, the dot product could be negative or positive.  Allowing negative values can lead to false-positive tests, so everything needs to be kept in a >=0 range.
             * This algorithm was found from the following pdf
             * http://www.jkh.me/files/tutorials/Separating%20Axis%20Theorem%20for%20Oriented%20Bounding%20Boxes.pdf
             */

            //calculate the distance between the objects, and the axes of the objects (normalized half width, and half height)
            //The normalize function passes by reference.  So need to set axes variables equal to the half values and then normalize them
            Vector2 distance = B.Position - this.position;
            Vector2 Ax = this.XAxis;
            Vector2 Ay = this.YAxis;
            Vector2 Bx = B.XAxis;
            Vector2 By = B.YAxis;

            //case 1: check along THIS rectangles X Axis
            float transform = Math.Abs(Vector2.Dot((this.HalfX * Ax), Ax))
                            + Math.Abs(Vector2.Dot((this.HalfY * Ay), Ax))
                            + Math.Abs(Vector2.Dot((B.HalfX * Bx), Ax))
                            + Math.Abs(Vector2.Dot((B.HalfY * By), Ax));
            if (Math.Abs(Vector2.Dot(distance, Ax)) > transform)
                return false;

            //case 2: check along THIs rectangle's Y Axis
            transform = Math.Abs(Vector2.Dot((this.HalfX * Ax), Ay))
                        + Math.Abs(Vector2.Dot((this.HalfY * Ay), Ay))
                        + Math.Abs(Vector2.Dot((B.HalfX * Bx), Ay))
                        + Math.Abs(Vector2.Dot((B.HalfY * By), Ay));
            if (Math.Abs(Vector2.Dot(distance, Ay)) > transform)
                return false;

            //case 3: check along B's X-Axis
            transform = Math.Abs(Vector2.Dot((this.HalfX * Ax), Bx))
                        + Math.Abs(Vector2.Dot((this.HalfY * Ay), Bx))
                        + Math.Abs(Vector2.Dot((B.HalfX * Bx), Bx))
                        + Math.Abs(Vector2.Dot((B.HalfY * By), Bx));

            if (Math.Abs(Vector2.Dot(distance, Bx)) > transform)
                return false;

            //case 4: check along B's Y-Axis
            transform = Math.Abs(Vector2.Dot((this.HalfX * Ax), By))
                        + Math.Abs(Vector2.Dot((this.HalfY * Ay), By))
                        + Math.Abs(Vector2.Dot((B.HalfX * Bx), By))
                        + Math.Abs(Vector2.Dot((B.HalfY * By), By));
            if (Math.Abs(Vector2.Dot(distance, By)) > transform)
                return false;

            //if all cases are true, then there is a collision
            return true;
        }