public static bool checkAxis(OBBHull2D a, AABBHull2D b, Vector2 norm)
    {
        Vector2 aProjValues = getMinMaxProjectionValuesOnNorm(a, norm);
        Vector2 bProjValues = getMinMaxProjectionValuesOnNorm(b, norm);

        Debug.DrawLine(aProjValues.x * norm, aProjValues.y * norm, Color.blue); //this is dumb useful, the projected line
        Debug.DrawLine(bProjValues.x * norm, bProjValues.y * norm, Color.red);  //this is dumb useful, the projected line

        return(detectCollisionFromMinMax(aProjValues, bProjValues));
    }
    /*
     * Circle V OBB
     */
    public static bool detectCollision(CircleHull2D circle, OBBHull2D square)
    {
        Vector2 closestPoint = square.GetClosestPoint(circle.position);

        Debug.DrawLine(new Vector3(closestPoint.x, closestPoint.y, 0), circle.position);
        if (circle.radius > Vector2.Distance(circle.position, closestPoint))
        {
            return(true);
        }
        return(false);
    }
 /*
  * VERIFIED WORKING, based off OBB v OBB Collision
  */
 public static bool detectCollision(OBBHull2D a, AABBHull2D b)
 {
     if (checkAxis(a, b, a.getXNormal()) &&
         checkAxis(a, b, a.getYNormal()) &&
         checkAxis(a, b, Vector2.left) &&
         checkAxis(a, b, Vector2.up))
     {
         return(true);
     }
     return(false);
 }
 /*
  * Verified Working, possible error in using 4 checkaxis, i think i missed a check somewhere deeper in the code
  */
 public static bool detectCollision(OBBHull2D lft, OBBHull2D rgt)
 {
     //check each axis on each side, need to make better
     if (checkAxis(lft, rgt, lft.getXNormal()) &&
         checkAxis(lft, rgt, lft.getYNormal()) &&
         checkAxis(lft, rgt, rgt.getXNormal()) &&
         checkAxis(lft, rgt, rgt.getYNormal()))
     {
         return(true);
     }
     return(false);
 }
    public static Vector2 getMinMaxProjectionValuesOnNorm(OBBHull2D box, Vector2 norm)
    {
        float a, b, c, d;
        int   axis = norm.x != 0 ? 0 : 1; //just to make a scaler, but in case the x axis is zero, and if they are both zero then what the hell u doing with a normal (0,0)

        a = proj(box.getTopLeftPos(), norm)[axis] / norm[axis];
        b = proj(box.getTopRightPos(), norm)[axis] / norm[axis];
        c = proj(box.getBottomLeftPos(), norm)[axis] / norm[axis];
        d = proj(box.getBottomRightPos(), norm)[axis] / norm[axis];
        float min = Mathf.Min(new float[] { a, b, c, d });
        float max = Mathf.Max(new float[] { a, b, c, d });

        return(new Vector2(min, max));
    }
    public static float checkAxisPenetration(OBBHull2D a, AABBHull2D b, Vector2 norm)
    {
        Vector2 aProjValues = getMinMaxProjectionValuesOnNorm(a, norm);
        Vector2 bProjValues = getMinMaxProjectionValuesOnNorm(b, norm);

        Debug.DrawLine(aProjValues.x * norm, aProjValues.y * norm, Color.blue); //this is dumb useful, the projected line
        Debug.DrawLine(bProjValues.x * norm, bProjValues.y * norm, Color.red);  //this is dumb useful, the projected line

        if (!detectCollisionFromMinMax(aProjValues, bProjValues))
        {
            return(0.0f);
        }
        else
        {
            return(calculateMinMaxCollisionOverlap(aProjValues, bProjValues));
        }
    }
    public static HullCollision2D detectCollisionResponse(OBBHull2D a, OBBHull2D b)
    {
        Dictionary <Vector2, float> axisValues = new Dictionary <Vector2, float>(); //norm to the overlap value

        axisValues.Add(a.getXNormal(), checkAxisPenetration(a, b, a.getXNormal()));
        axisValues.Add(a.getYNormal(), checkAxisPenetration(a, b, a.getYNormal()));
        if (a.rotation != b.rotation)
        {
            axisValues.Add(b.getXNormal(), checkAxisPenetration(a, b, b.getXNormal()));
            axisValues.Add(b.getYNormal(), checkAxisPenetration(a, b, b.getYNormal()));
        }
        Dictionary <Vector2, float> .Enumerator enumerator = axisValues.GetEnumerator();
        enumerator.MoveNext();
        Vector2 pos = a.position;
        KeyValuePair <Vector2, float> bestPenetration = enumerator.Current; //need to set one to compare too, no null value to just allow all checking in the for loop

        if (bestPenetration.Value == 0.0f)
        {
            return(null);
        }
        while (enumerator.MoveNext())
        {
            if (Mathf.Abs(enumerator.Current.Value) < Mathf.Abs(bestPenetration.Value))
            {
                bestPenetration = enumerator.Current;
            }
            if (bestPenetration.Value == 0.0f)
            {
                return(null);
            }
        }
        HullCollision2D collision;
        Vector2         norm = bestPenetration.Key;

        if (bestPenetration.Value <= 0.0f) //ooh this was an easy thing to miss
        {
            norm *= -1.0f;
        }

        collision = new HullCollision2D(a, b, norm, Mathf.Abs(bestPenetration.Value));
        //collision.contactPoint = pos;
        return(collision);
    }
    public static HullCollision2D detectCollisionResponse(OBBHull2D a, AABBHull2D b)
    {
        Dictionary <Vector2, float> axisValues = new Dictionary <Vector2, float>(); //norm to the overlap value

        axisValues.Add(Vector2.up, checkAxisPenetration(a, b, Vector2.up));
        axisValues.Add(Vector2.right, checkAxisPenetration(a, b, Vector2.right));
        if (a.rotation != 0.0f)
        {
            axisValues.Add(a.getXNormal(), checkAxisPenetration(a, b, a.getXNormal()));
            axisValues.Add(a.getYNormal(), checkAxisPenetration(a, b, a.getYNormal()));
        }
        Dictionary <Vector2, float> .Enumerator enumerator = axisValues.GetEnumerator();
        enumerator.MoveNext();
        KeyValuePair <Vector2, float> bestPenetration = enumerator.Current; //need to set one to compare too, no null value to just allow all checking in the for loop

        if (bestPenetration.Value == 0.0f)
        {
            return(null);
        }
        while (enumerator.MoveNext())
        {
            if (Mathf.Abs(enumerator.Current.Value) < Mathf.Abs(bestPenetration.Value))
            {
                bestPenetration = enumerator.Current;
            }
            if (bestPenetration.Value == 0.0f)
            {
                return(null);
            }
        }
        HullCollision2D collision;
        Vector2         norm = bestPenetration.Key;


        if (Vector2.Dot(a.velocity, norm) >= 0.0f)
        {
            norm *= -1.0f;
        }


        collision = new HullCollision2D(a, b, norm, Mathf.Abs(bestPenetration.Value));
        return(collision);
    }
    //TODO
    public static HullCollision2D detectCollisionResponse(CircleHull2D circle, OBBHull2D square)
    {
        Vector2 closestPointSquare = square.GetClosestPoint(circle.position);
        Vector2 closestPointCircle = circle.GetClosestPoint(closestPointSquare);

        Debug.DrawLine(new Vector3(closestPointSquare.x, closestPointSquare.y, 0), new Vector3(closestPointCircle.x, closestPointCircle.y, 0));
        if (circle.radius > Vector2.Distance(circle.position, closestPointSquare))
        {
            Vector2         penNorm = closestPointSquare - closestPointCircle;
            HullCollision2D collision;
            if (penNorm.x > 0.0f)
            {
                collision = new HullCollision2D(circle, square, penNorm.normalized, penNorm.magnitude);
            }
            else
            {
                collision = new HullCollision2D(circle, square, penNorm.normalized, penNorm.magnitude);
            }
            return(collision);
        }
        return(null);
    }