Example #1
0
    // This function calculates OBB to OBB colisions
    public static CollisionInfo OBBToOBBCollision(CollisionHull2D a, CollisionHull2D b)
    {
        // Compute the R hat and U hat for both collision hulls
        Vector2 ARHat = new Vector2(Mathf.Abs(Mathf.Cos(a.GetRotation())), Mathf.Abs(-Mathf.Sin(a.GetRotation())));
        Vector2 BRHat = new Vector2(Mathf.Abs(Mathf.Cos(b.GetRotation())), Mathf.Abs(-Mathf.Sin(b.GetRotation())));
        Vector2 AUHat = new Vector2(Mathf.Abs(Mathf.Sin(a.GetRotation())), Mathf.Abs(Mathf.Cos(a.GetRotation())));
        Vector2 BUHat = new Vector2(Mathf.Abs(Mathf.Sin(b.GetRotation())), Mathf.Abs(Mathf.Cos(b.GetRotation())));

        // Create a list of all penetrations on each axis
        List <float> overlaps = new List <float>();

        // Do axis checks
        overlaps.Add(CheckOBBAxis(a, b, ARHat));

        // Does the check pass?
        if (overlaps[0] == Mathf.Infinity)
        {
            // If no, return nothing
            return(null);
        }

        // Do axis checks
        overlaps.Add(CheckOBBAxis(a, b, AUHat));

        // Does the check pass?
        if (overlaps[1] == Mathf.Infinity)
        {
            // If no, return nothing
            return(null);
        }

        // Do axis checks
        overlaps.Add(CheckOBBAxis(a, b, BRHat));

        // Does the check pass?
        if (overlaps[2] == Mathf.Infinity)
        {
            // If no, return nothing
            return(null);
        }

        // Do axis checks
        overlaps.Add(CheckOBBAxis(a, b, AUHat));

        // Do the axis checks pass?
        if (overlaps[3] != Mathf.Infinity)
        {
            // If yes, then inform the parents of the complex shape object (if applicable)
            ReportCollisionToParent(a, b);
        }
        else
        {
            // If no, return nothing
            return(null);
        }

        // Return full details of the Collision list if the two collide
        return(new CollisionInfo(a, b, CollisionResolution.GetFinalPenetration(overlaps)));
    }
Example #2
0
    // This function checks for a collision between two objects by projecting onto a specific axis
    public static float CheckOBBAxis(CollisionHull2D shapeA, CollisionHull2D shapeB, Vector2 rotationAxis)
    {
        // Create a list of all points from the OBB hull for shape A
        List <Vector2> shapeAPoints = new List <Vector2>();

        shapeAPoints.Add(new Vector2(shapeA.GetPosition().x + shapeA.GetDimensions().x, shapeA.GetPosition().y + shapeA.GetDimensions().y));
        shapeAPoints.Add(new Vector2(shapeA.GetPosition().x - shapeA.GetDimensions().x, shapeA.GetPosition().y - shapeA.GetDimensions().y));
        shapeAPoints.Add(new Vector2(shapeA.GetPosition().x - shapeA.GetDimensions().x, shapeA.GetPosition().y + shapeA.GetDimensions().y));
        shapeAPoints.Add(new Vector2(shapeA.GetPosition().x + shapeA.GetDimensions().x, shapeA.GetPosition().y - shapeA.GetDimensions().y));

        // Create a list of all points from the OBB hull for shape B
        List <Vector2> shapeBPoints = new List <Vector2>();

        shapeBPoints.Add(new Vector2(shapeB.GetPosition().x + shapeB.GetDimensions().x, shapeB.GetPosition().y + shapeB.GetDimensions().y));
        shapeBPoints.Add(new Vector2(shapeB.GetPosition().x - shapeB.GetDimensions().x, shapeB.GetPosition().y - shapeB.GetDimensions().y));
        shapeBPoints.Add(new Vector2(shapeB.GetPosition().x - shapeB.GetDimensions().x, shapeB.GetPosition().y + shapeB.GetDimensions().y));
        shapeBPoints.Add(new Vector2(shapeB.GetPosition().x + shapeB.GetDimensions().x, shapeB.GetPosition().y - shapeB.GetDimensions().y));

        // Initialized shape minimums and maximums
        float shapeAMin = Mathf.Infinity;
        float shapeAMax = -Mathf.Infinity;
        float shapeBMin = Mathf.Infinity;
        float shapeBMax = -Mathf.Infinity;

        // Set the total minimum and maximums
        float totalMin;
        float totalMax;

        // Initialize all points for axis checks
        for (int i = 0; i < shapeAPoints.Count; i++)
        {
            // Rotate original point
            shapeAPoints[i] = new Vector2(Mathf.Cos(shapeA.GetRotation()) * (shapeAPoints[i].x - shapeA.GetPosition().x) - Mathf.Sin(shapeA.GetRotation()) * (shapeAPoints[i].y - shapeA.GetPosition().y) + shapeA.GetPosition().x,
                                          Mathf.Sin(shapeA.GetRotation()) * (shapeAPoints[i].x - shapeA.GetPosition().x) + Mathf.Cos(shapeA.GetRotation()) * (shapeAPoints[i].y - shapeA.GetPosition().y) + shapeA.GetPosition().y);

            // Project point
            float temp = Vector2.Dot(shapeAPoints[i], rotationAxis);

            // Is the point less than the minimum?
            if (temp < shapeAMin)
            {
                // If yes, set it to the new minimum
                shapeAMin = temp;
            }

            // Is the point greater than the maximum?
            if (temp > shapeAMax)
            {
                // If yes, set it to the new maximum
                shapeAMax = temp;
            }

            // Rotate original point
            shapeBPoints[i] = new Vector2(Mathf.Cos(shapeB.GetRotation()) * (shapeBPoints[i].x - shapeB.GetPosition().x) - Mathf.Sin(shapeB.GetRotation()) * (shapeBPoints[i].y - shapeB.GetPosition().y) + shapeB.GetPosition().x,
                                          Mathf.Sin(shapeB.GetRotation()) * (shapeBPoints[i].x - shapeB.GetPosition().x) + Mathf.Cos(shapeB.GetRotation()) * (shapeBPoints[i].y - shapeB.GetPosition().y) + shapeB.GetPosition().y);

            // Project point
            temp = Vector2.Dot(shapeBPoints[i], rotationAxis);

            // Is the point less than the minimum?
            if (temp < shapeBMin)
            {
                // If yes, set it to the new minimum
                shapeBMin = temp;
            }

            // Is the point greater than the maximum
            if (temp > shapeBMax)
            {
                // If yes, set it to the new maximum
                shapeBMax = temp;
            }
        }


        // Is the B shape min greater than the A shape maximum
        if (shapeBMin > shapeAMin)
        {
            // If yes, set A to the new minimum
            totalMin = shapeAMin;
        }
        else
        {
            // If no, set B to the new minimum
            totalMin = shapeBMin;
        }

        // Is the A shape maximum greater than the B shape maximum
        if (shapeBMax < shapeAMax)
        {
            // If yes, set A to the new maximum
            totalMax = shapeAMax;
        }
        else
        {
            // If no, set B to the new maximum
            totalMax = shapeBMax;
        }

        // Do axis checks
        bool axisCheck = shapeAMin <= shapeBMax && shapeBMin <= shapeAMax;

        // Does the check pass?
        if (axisCheck)
        {
            // If yes, then return the penetration
            return(totalMin - totalMax);
        }
        else
        {
            // If no, return nothing
            return(Mathf.Infinity);
        }
    }