private static bool IsOverlappingABB(Vector3 normal, AxisAlignBoundingBoxHull2D other, ObjectBoundingBoxHull2D self)
    {
        bool isOverlapping = false;

        //Project the corners of rectangle 1 onto the normal
        float dot1 = Vector3.Dot(normal, other.upLeft);
        float dot2 = Vector3.Dot(normal, other.upRight);
        float dot3 = Vector3.Dot(normal, other.botLeft);
        float dot4 = Vector3.Dot(normal, other.botRight);

        //Find the range
        float min1 = Mathf.Min(dot1, Mathf.Min(dot2, Mathf.Min(dot3, dot4)));
        float max1 = Mathf.Max(dot1, Mathf.Max(dot2, Mathf.Max(dot3, dot4)));


        //Project the corners of rectangle 2 onto the normal
        float dot5 = Vector3.Dot(normal, self.topLeftAxis);
        float dot6 = Vector3.Dot(normal, self.topLeftAxis);
        float dot7 = Vector3.Dot(normal, self.botLeftAxis);
        float dot8 = Vector3.Dot(normal, self.botRightAxis);

        //Find the range
        float min2 = Mathf.Min(dot5, Mathf.Min(dot6, Mathf.Min(dot7, dot8)));
        float max2 = Mathf.Max(dot5, Mathf.Max(dot6, Mathf.Max(dot7, dot8)));


        //Are the ranges overlapping?
        if (min1 <= max2 && min2 <= max1)
        {
            isOverlapping = true;
        }

        return(isOverlapping);
    }
    private bool IsIntersectingAABB_OBB(AxisAlignBoundingBoxHull2D other)
    {
        bool isIntersecting = false;

        Vector2 otherTL = other.upLeft;
        Vector2 otherTR = other.upRight;
        Vector2 otherBL = other.botLeft;
        Vector2 otherBR = other.botRight;

        Vector2 thisTL = topLeftAxis;
        Vector2 thisTR = topRightAxis;
        Vector2 thisBL = botLeftAxis;
        Vector2 thisBR = botRightAxis;

        //Find the min/max values for the AABB algorithm
        float r1_minX = Mathf.Min(otherTL.x, Mathf.Min(otherTR.x, Mathf.Min(otherBL.x, otherBR.x)));
        float r1_maxX = Mathf.Max(otherTL.x, Mathf.Max(otherTR.x, Mathf.Max(otherBL.x, otherBR.x)));

        float r2_minX = Mathf.Min(thisTL.x, Mathf.Min(thisTR.x, Mathf.Min(thisBL.x, thisBR.x)));
        float r2_maxX = Mathf.Max(thisTL.x, Mathf.Max(thisTR.x, Mathf.Max(thisBL.x, thisBR.x)));

        float r1_minY = Mathf.Min(otherTL.y, Mathf.Min(otherTR.y, Mathf.Min(otherBL.y, otherBR.y)));
        float r1_maxY = Mathf.Max(otherTL.y, Mathf.Max(otherTR.y, Mathf.Max(otherBL.y, otherBR.y)));

        float r2_minY = Mathf.Min(thisTL.y, Mathf.Min(thisTR.y, Mathf.Min(thisBL.y, thisBR.y)));
        float r2_maxY = Mathf.Max(thisTL.y, Mathf.Max(thisTR.y, Mathf.Max(thisBL.y, thisBR.y)));

        if (IsIntersectingAABB(r1_minX, r1_maxX, r1_minY, r1_maxY, r2_minX, r2_maxX, r2_minY, r2_maxY))
        {
            isIntersecting = true;
        }

        return(isIntersecting);
    }
    //Find out if 2 rectangles with orientation are intersecting by using the SAT algorithm
    private bool SATRectangleRectangle(AxisAlignBoundingBoxHull2D other)
    {
        bool isIntersecting = false;

        //We have just 4 normals because the other 4 normals are the same but in another direction
        //So we only need a maximum of 4 tests if we have rectangles
        //It is enough if one side is not overlapping, if so we know the rectangles are not intersecting

        Vector2 otherTL = other.upLeft;
        Vector2 otherTR = other.upRight;
        Vector2 otherBL = other.botLeft;
        Vector2 otherBR = other.botRight;

        Vector2 thisTL = topLeftAxis;
        Vector2 thisTR = topRightAxis;
        Vector2 thisBL = botLeftAxis;
        Vector2 thisBR = botRightAxis;

        //Test 1
        Vector3 normal1 = GetNormal(otherBL, otherTL);

        if (!IsOverlappingABB(normal1, other, this))
        {
            //No intersection is possible!
            return(isIntersecting);
        }

        //Test 2
        Vector3 normal2 = GetNormal(otherTL, otherTR);

        if (!IsOverlappingABB(normal2, other, this))
        {
            return(isIntersecting);
        }

        //Test 3
        Vector3 normal3 = GetNormal(thisBL, thisTL);

        if (!IsOverlappingABB(normal3, other, this))
        {
            return(isIntersecting);
        }

        //Test 4
        Vector3 normal4 = GetNormal(thisTL, thisTR);

        if (!IsOverlappingABB(normal4, other, this))
        {
            return(isIntersecting);
        }

        //If we have come this far, then we know all sides are overlapping
        //So the rectangles are intersecting!
        isIntersecting = true;

        return(isIntersecting);
    }
    public override bool TestCollisionVSAABB(AxisAlignBoundingBoxHull2D other, ref Collision c)
    {
        // calculate closest point by clamping circle center on each dimension
        // Find the vector2 distance between box & circle
        // Normalize that vector
        // multiply the vector by the radius to get the closest point on the circumference
        // Check if closest point is within box bounds
        // pass if closest point vs. circle passes

        return(other.TestCollisionVSCircle(this, ref c));
    }
    public override bool TestCollisionVSAABB(AxisAlignBoundingBoxHull2D other, ref Collision c)
    {
        // Same as OBB vs OBB, but only project to ABB up and right normal
        // check the points
        bool isIntersecting = false;

        //Find out if the rectangles are intersecting by approximating them with rectangles
        //with no rotation and then use AABB intersection
        //Will make it faster if the probability that the rectangles are intersecting is low
        if (!IsIntersectingAABB_OBB(other))
        {
            return(isIntersecting);
        }

        //Find out if the rectangles are intersecting by using the Separating Axis Theorem (SAT)
        isIntersecting = SATRectangleRectangle(other);

        return(isIntersecting);
    }
    public override bool TestCollisionVSAABB(AxisAlignBoundingBoxHull2D other, ref Collision c)
    {
        // for each dimension, max extent of A greater than min extent of B

        // position - 1/2(length or width) for min point in x or y
        float thisXMin = position.x - width * 0.5f;

        // position + 1/2(length or width) for max point in x or y
        float thisXMax = position.x + width * 0.5f;

        // position - 1/2(length or width) for min point in x or y
        float thisYMin = position.y - height * 0.5f;

        // position + 1/2(length or width) for max point in x or y
        float thisYMax = position.y + height * 0.5f;

        // position - 1/2(length or width) for min point in x or y
        float otherXMin = other.position.x - width * 0.5f;

        // position + 1/2(length or width) for max point in x or y
        float otherXMax = other.position.x + width * 0.5f;

        // position - 1/2(length or width) for min point in x or y
        float otherYMin = other.position.y - height * 0.5f;

        // position + 1/2(length or width) for max point in x or y
        float otherYMax = other.position.y + height * 0.5f;


        // check which min is greater, greater min becomes the one, other becomes other
        // if one max.x < other max.x && one max.x > other min.x
        if (otherXMin < thisXMax && thisXMax < otherXMax)
        {
            // if this passes, check same thing with y
            if (otherYMin < thisYMax && thisYMax < otherYMax)
            {
                return(true);
            }
            else if (otherYMin < thisYMin && thisYMin < otherYMax)
            {
                return(true);
            }
        }

        // check which min is greater, greater min becomes the one, other becomes other
        // if one min.x < other max.x && one min.x > other min.x
        if (otherXMin < thisXMin && thisXMin < otherXMax)
        {
            // if this passes, check same thing with y
            if (otherYMin < thisYMax && thisYMax < otherYMax)
            {
                return(true);
            }
            else if (otherYMin < thisYMin && thisYMin < otherYMax)
            {
                return(true);
            }
        }


        return(false);
    }
 public abstract bool TestCollisionVSAABB(AxisAlignBoundingBoxHull2D other, ref Collision c);