Exemplo n.º 1
0
    static public bool OBBOBB(ObjectBoundingBoxCollision2D rectA, ObjectBoundingBoxCollision2D rectB)
    {
        //grab 4 axis of both shapes
        // grab all vertices of both shapes, then put them onto each axis of both shapes
        //
        Vector2 rightA = new Vector2(Mathf.Cos(rectA.zRot), -Mathf.Sin(rectA.zRot));
        Vector2 upA    = new Vector2(Mathf.Sin(rectA.zRot), Mathf.Cos(rectA.zRot));
        Vector2 rightB = new Vector2(Mathf.Cos(rectB.zRot), -Mathf.Sin(rectB.zRot));
        Vector2 upB    = new Vector2(Mathf.Sin(rectB.zRot), Mathf.Cos(rectB.zRot));

        if (OBBTest(rightA, rectA, rectB))
        {
            if (OBBTest(upA, rectA, rectB))
            {
                if (OBBTest(rightB, rectB, rectA))
                {
                    if (OBBTest(upB, rectB, rectB))
                    {
                        return(true);
                    }
                }
            }
        }
        return(false);
    }
Exemplo n.º 2
0
        public CollisionInfo(CircleCollision2D colA, ObjectBoundingBoxCollision2D colB, Vector2 normal, float penetration)
        {
            RigidBodyA = colA.GetComponent <Particle2D>();
            RigidBodyB = colB.GetComponent <Particle2D>();


            RelativeVelocity = RigidBodyB.velocity - RigidBodyA.velocity;

            contacts[0].normal      = normal;
            contacts[0].penetration = penetration;
            contacts[0].restitution = Mathf.Min(RigidBodyA.restitution, RigidBodyB.restitution);
        }
Exemplo n.º 3
0
    static public bool CircleOBB(CircleCollision2D circle, ObjectBoundingBoxCollision2D rect)
    {
        //transform circle into obb space transform.InverseTransformPoint(cirecle.postion);
        //then do circle AABB
        Vector2 halfExtend  = (rect.posMax - rect.posMin) / 2;
        Vector2 circleInOBB = rect.transform.InverseTransformPoint(circle.center);
        Vector2 circleBox   = new Vector2(Mathf.Max(-halfExtend.x, Mathf.Min(circleInOBB.x, halfExtend.x)),
                                          Mathf.Max(-halfExtend.y, Mathf.Min(circleInOBB.y, halfExtend.y)));

        Vector2 distance   = circleInOBB - circleBox;
        float   distanceSQ = Vector2.Dot(distance, distance);

        Debug.DrawLine(circleBox, circle.center);


        if (distanceSQ <= (circle.radius * circle.radius))
        {
            return(true);
        }

        return(false);
    }
Exemplo n.º 4
0
    static private bool OBBTest(Vector2 norm, ObjectBoundingBoxCollision2D proj, ObjectBoundingBoxCollision2D main)
    {
        //top left is min.x, max y
        //bottom right is max.x, min.y

        Vector2 Max1;
        Vector2 Min1;
        Vector2 Max2;
        Vector2 Min2;


        Vector2 p1 = Vector2.Dot(proj.topRight, norm) * norm;
        Vector2 p2 = Vector2.Dot(proj.botLeft, norm) * norm;
        Vector2 p3 = Vector2.Dot(new Vector2(proj.topRight.x, proj.botLeft.y), norm) * norm;
        Vector2 p4 = Vector2.Dot(proj.botLeft, norm) * norm;

        if (p1.x <= p3.x && p1.y <= p3.y)
        {
            p1 = p3;
        }
        if (p2.x >= p4.x && p2.y >= p4.y)
        {
            p2 = p4;
        }

        Max1 = p1;
        Min1 = p2;

        Max2 = Vector2.Dot(main.topRight, norm) * norm;
        Min2 = Vector2.Dot(main.botLeft, norm) * norm;

        if (Max1.x >= Min2.x && Max1.y >= Min2.y && Max2.x >= Min1.x && Max2.y >= Min1.y)
        {
            return(true);
        }
        return(false);
    }
Exemplo n.º 5
0
    static public bool AABBOBB(AxisAllignedBoundingBoxCollision2D colA, ObjectBoundingBoxCollision2D colB)
    {
        //AxisAllignedBoundingBoxCollision2D
        //transform min and max into obb space, then do AABB AABB

        if (colA.posMax.x >= colB.posMin.x && colB.posMax.x >= colA.posMin.x)
        {
            if (colA.posMax.y >= colB.posMin.y && colB.posMax.y >= colA.posMin.y)
            {
                //return true;
                Vector2 abbMinTrans = colB.transform.InverseTransformPoint(colA.posMin);
                Vector2 abbMaxTrans = colB.transform.InverseTransformPoint(colA.posMax);

                if (abbMaxTrans.x >= colB.posMin.x && colB.posMax.x >= abbMinTrans.x)
                {
                    if (abbMaxTrans.y >= colB.posMin.y && colB.posMax.y >= abbMinTrans.y)
                    {
                        return(true);
                    }
                }
            }
        }
        return(false);
    }
Exemplo n.º 6
0
    static public CollisionInfo CircleOBB(CircleCollision2D circle, ObjectBoundingBoxCollision2D rect)
    {
        //transform circle into obb space transform.InverseTransformPoint(cirecle.postion);
        //then do circle AABB
        Vector2 halfExtend  = (rect.posMax - rect.posMin) / 2;
        Vector2 circleInOBB = rect.transform.InverseTransformPoint(circle.center);
        Vector2 circleBox   = new Vector2(Mathf.Max(-halfExtend.x, Mathf.Min(circleInOBB.x, halfExtend.x)),
                                          Mathf.Max(-halfExtend.y, Mathf.Min(circleInOBB.y, halfExtend.y)));

        Vector2 distanceVec = circleInOBB - circleBox;
        float   distanceSQ  = Vector2.Dot(distanceVec, distanceVec);

        //Debug.DrawLine(circleBox, circle.center);


        if (distanceSQ <= (circle.radius * circle.radius))
        {
            //return true;
            float distance = Mathf.Sqrt(distanceSQ);
            return(new CollisionInfo(circle, rect, rect.transform.TransformVector(-distanceVec).normalized, circle.radius - distance));
        }

        return(null);
    }
Exemplo n.º 7
0
    static public CollisionInfo OBBOBB(ObjectBoundingBoxCollision2D rectA, ObjectBoundingBoxCollision2D rectB)
    {
        List <Vector2> allAxis = new List <Vector2>();

        allAxis.AddRange(rectA.normAxis);
        allAxis.AddRange(rectB.normAxis);

        foreach (var axis in allAxis)
        {
            float OBB1Min = float.MaxValue;
            float OBB1Max = float.MinValue;

            foreach (var vert in rectA.verticeCheck)
            {
                float dotValue = (vert.x * axis.x + vert.y * axis.y);
                if (dotValue < OBB1Min)
                {
                    OBB1Min = dotValue;
                }
                if (dotValue > OBB1Max)
                {
                    OBB1Max = dotValue;
                }
            }

            float OBB2Min = float.MaxValue;
            float OBB2Max = float.MinValue;
            foreach (var vert in rectB.verticeCheck)
            {
                float dotValue = (vert.x * axis.x + vert.y * axis.y);
                if (dotValue < OBB2Min)
                {
                    OBB2Min = dotValue;
                }
                if (dotValue > OBB2Max)
                {
                    OBB2Max = dotValue;
                }
            }

            if (!(OBB1Max < OBB2Min && OBB2Max < OBB1Min))
            {
                Vector2 AtoB      = rectB.center - rectA.center;
                float   x_overlap = rectA.halfExtends.x + rectB.halfExtends.x - Mathf.Abs(AtoB.x);

                if (x_overlap > 0.0f)
                {
                    float y_overlap = rectA.halfExtends.y + rectB.halfExtends.y - Mathf.Abs(AtoB.y);
                    if (y_overlap > 0.0f)
                    {
                        if (x_overlap < y_overlap)
                        {
                            return(new CollisionInfo(rectA, rectB, AtoB.x < 0.0f ? -Vector2.right : Vector2.right, x_overlap));
                        }
                        else
                        {
                            return(new CollisionInfo(rectA, rectB, AtoB.y < 0.0f ? -Vector2.up : Vector2.up, y_overlap));
                        }
                    }
                }
            }
        }

        return(null);
    }
Exemplo n.º 8
0
    static public CollisionInfo AABBOBB(AxisAllignedBoundingBoxCollision2D colA, ObjectBoundingBoxCollision2D colB)
    {
        //AxisAllignedBoundingBoxCollision2D
        //transform min and max into obb space, then do AABB AABB

        //if (colA.posMax.x >= colB.posMin.x && colB.posMax.x >= colA.posMin.x)
        //{
        //    if (colA.posMax.y >= colB.posMin.y && colB.posMax.y >= colA.posMin.y)
        //    {
        //        //return true;
        //        Vector2 abbMinTrans = colB.transform.InverseTransformPoint(colA.posMin);
        //        Vector2 abbMaxTrans = colB.transform.InverseTransformPoint(colA.posMax);

        //        if (abbMaxTrans.x >= colB.posMin.x && colB.posMax.x >= abbMinTrans.x)
        //        {
        //            if (abbMaxTrans.y >= colB.posMin.y && colB.posMax.y >= abbMinTrans.y)
        //            {
        //                return true;

        //            }
        //        }

        //    }
        //}
        //return false;
        List <Vector2> allAxis = new List <Vector2>();

        allAxis.AddRange(colA.normAxis);
        allAxis.AddRange(colB.normAxis);

        foreach (var axis in allAxis)
        {
            float AABBMin = float.MaxValue;
            float AABBMax = float.MinValue;

            foreach (var vert in colA.verticeCheck)
            {
                float dotValue = (vert.x * axis.x + vert.y * axis.y);
                if (dotValue < AABBMin)
                {
                    AABBMin = dotValue;
                }
                if (dotValue > AABBMax)
                {
                    AABBMax = dotValue;
                }
            }

            float OBBMin = float.MaxValue;
            float OBBMax = float.MinValue;
            foreach (var vert in colB.verticeCheck)
            {
                float dotValue = (vert.x * axis.x + vert.y * axis.y);
                if (dotValue < OBBMin)
                {
                    OBBMin = dotValue;
                }
                if (dotValue > OBBMax)
                {
                    OBBMax = dotValue;
                }
            }

            if (!(AABBMax < OBBMin && OBBMax < AABBMin))
            {
                Vector2 AtoB      = colB.center - colA.center;
                float   x_overlap = colA.halfExtends.x + colB.halfExtends.x - Mathf.Abs(AtoB.x);

                if (x_overlap > 0.0f)
                {
                    float y_overlap = colA.halfExtends.y + colB.halfExtends.y - Mathf.Abs(AtoB.y);
                    if (y_overlap > 0.0f)
                    {
                        if (x_overlap < y_overlap)
                        {
                            return(new CollisionInfo(colA, colB, AtoB.x < 0.0f ? -Vector2.right : Vector2.right, x_overlap));
                        }
                        else
                        {
                            return(new CollisionInfo(colA, colB, AtoB.y < 0.0f ? -Vector2.up : Vector2.up, y_overlap));
                        }
                    }
                }
            }
        }
        return(null);
    }