public static bool BoxPlaneCollisionOccured(PSI_Collider_Box boxCol, PSI_Collider_Plane planeCol, out Vector3 point)
    {
        // Projecting the box vertices onto the plane. If a the vertex that is closest
        // to the plane intersects it then the box and plane are colliding.
        var   boxVerts         = boxCol.GetVertices();
        float overlap          = float.PositiveInfinity;
        bool  collisionOccured = false;

        point = Vector3.zero;
        for (int i = 0; i < boxVerts.Length; i++)
        {
            float distanceToPlane;
            if (!planeCol.PosIsWithinPlaneBounds(boxVerts[i], out distanceToPlane))
            {
                continue;
            }

            if (distanceToPlane <= 0f && Mathf.Abs(distanceToPlane) < boxCol.pSize.magnitude)
            {
                collisionOccured = true;
                if (distanceToPlane < overlap)
                {
                    overlap = distanceToPlane;
                }
            }
        }

        if (collisionOccured)
        {
            // Resolve any overlap between the box and the plane.
            ResolveCollisionOverlaps(boxCol, planeCol, -planeCol.pNormal.normalized, overlap);

            // Getting the collision point by averaging the closest box verts to the plane.
            boxVerts = boxCol.GetVertices();
            int touchingVertexCount = 0;
            for (int i = 0; i < boxVerts.Length; i++)
            {
                float distanceToPlane;
                if (!planeCol.PosIsWithinPlaneBounds(boxVerts[i], out distanceToPlane))
                {
                    continue;
                }

                if (distanceToPlane <= 0.01f)
                {
                    point += boxVerts[i];
                    touchingVertexCount++;
                }
            }
            point /= (float)touchingVertexCount;

            // Calculate and apply the collision impulse to the box.
            ApplyImpulses(boxCol, planeCol, -planeCol.pNormal.normalized, point);

            // Apply friction to the box.
            ApplyFriction(boxCol, planeCol, point);

            return(true);
        }
        return(false);
    }
    public static bool BoxBoxCollisionOccured(PSI_Collider_Box col1, PSI_Collider_Box col2, out Vector3 point)
    {
        point = Vector3.zero;

        // Determine the axis to check during SAT.
        var col1Axes    = col1.GetAxes();
        var col2Axes    = col2.GetAxes();
        var axesToCheck = new Vector3[]
        {
            col1Axes[0],
            col1Axes[1],
            col1Axes[2],
            col2Axes[0],
            col2Axes[1],
            col2Axes[2],
            Vector3.Cross(col1Axes[0], col2Axes[0]),
            Vector3.Cross(col1Axes[0], col2Axes[1]),
            Vector3.Cross(col1Axes[0], col2Axes[2]),
            Vector3.Cross(col1Axes[1], col2Axes[0]),
            Vector3.Cross(col1Axes[1], col2Axes[1]),
            Vector3.Cross(col1Axes[1], col2Axes[2]),
            Vector3.Cross(col1Axes[2], col2Axes[0]),
            Vector3.Cross(col1Axes[2], col2Axes[1]),
            Vector3.Cross(col1Axes[2], col2Axes[2])
        };

        // Determine the verts to check during SAT.
        var col1Verts = col1.GetVertices();
        var col2Verts = col2.GetVertices();

        // Determine if the boxes are colliding using SAT.
        Vector3 minOverlapAxis = Vector3.zero;
        float   minOverlap     = 0f;
        bool    isColliding    = CheckForOverlapUsingSAT(axesToCheck, col2Verts, col1Verts, out minOverlapAxis, out minOverlap) ||
                                 CheckForOverlapUsingSAT(axesToCheck, col1Verts, col2Verts, out minOverlapAxis, out minOverlap);

        if (isColliding)
        {
            // Estimate the collision point by converting the box faces to planes and projecting the vertices of the other
            // box onto them. The projection points with the smallest distance are averaged to give the collision point.
            var   facePlanes       = new PSI_Plane[][] { col1.GetFacePlanes(), col2.GetFacePlanes() };
            var   verts            = new Vector3[][] { col1Verts, col2Verts };
            var   contactPoints    = new List <Vector3>();
            float contactPointDist = float.PositiveInfinity;
            for (int i = 0; i < 2; i++)
            {
                foreach (var plane in facePlanes[i])
                {
                    foreach (var vert in verts[1 - i])
                    {
                        float projectionDist = float.PositiveInfinity;
                        if (plane.PointProjectsOntoPlane(vert, out projectionDist))
                        {
                            projectionDist = Mathf.Abs(projectionDist);
                            if (Mathf.Abs(projectionDist - contactPointDist) < float.Epsilon)
                            {
                                contactPoints.Add(vert);
                            }
                            else if (projectionDist < contactPointDist)
                            {
                                contactPoints.Clear();
                                contactPoints.Add(vert);
                                contactPointDist = projectionDist;
                            }
                        }
                    }
                }
            }
            point = Vector3.zero;
            foreach (var contactPoint in contactPoints)
            {
                point += contactPoint;
            }
            point /= contactPoints.Count;

            // Resolve any overlap between the boxes.
            var collisionAxis = CorrectCollisionAxisDirection(col2.pPosition, col1.pPosition, minOverlapAxis);
            ResolveCollisionOverlaps(col1, col2, collisionAxis, minOverlap);

            // Calculate and apply the collision impulse to the boxes.
            ApplyImpulses(col1, col2, collisionAxis, point);

            return(true);
        }
        return(false);
    }