Пример #1
0
    public static HullCollision OBBOBBCollision(OBBHull boxHull1, OBBHull boxHull2)
    {
        Particle2D A = boxHull1.GetComponent <Particle2D>();
        Particle2D B = boxHull2.GetComponent <Particle2D>();

        Vector3[] shape1Corners;
        Vector3[] shape2Corners;
        shape1Corners = new Vector3[4];
        shape2Corners = new Vector3[4];
        Vector3[] normals      = new Vector3[4];
        float[]   shape1MinMax = new float[2];
        float[]   shape2MinMax = new float[2];

        shape1Corners = getRotatedCorners(boxHull1);
        shape2Corners = getRotatedCorners(boxHull2);

        normals[0] = getUpNormal(-boxHull1.currentRotation);
        normals[1] = getRightNormal(-boxHull1.currentRotation);
        normals[2] = getUpNormal(-boxHull2.currentRotation);
        normals[3] = getRightNormal(-boxHull2.currentRotation);

        HullCollision col = new HullCollision();

        col.a = boxHull1;
        col.b = boxHull2;
        Vector3 range = (boxHull2.transform.position + boxHull2.offset) - (boxHull1.transform.position + boxHull1.offset);
        //float xOverlap = boxHull1.halfX + boxHull2.halfX - Mathf.Abs(range.x);
        //float yOverlap = boxHull1.halfY + boxHull2.halfY - Mathf.Abs(range.y);

        //TRANSPORTATION

        //col.penetration = new Vector3(xOverlap, yOverlap);

        //Vector3 closingVel = A.velocity - B.velocity;
        Vector3 closingVel = B.velocity - A.velocity;

        col.closingVelocity = closingVel;

        HullCollision.Contact con0 = new HullCollision.Contact();
        con0.point       = new Vector3(Mathf.Clamp(range.x, -boxHull1.halfX, boxHull1.halfX), Mathf.Clamp(range.y, -boxHull1.halfY, boxHull1.halfY));
        con0.restitution = Mathf.Min(boxHull1.restitution, boxHull2.restitution);
        con0.normal      = range.normalized;

        for (int i = 0; i < normals.Length; i++)
        {
            //Debug.Log("testing corner" + i);

            shape1MinMax = SatTest(normals[i], shape1Corners);
            shape2MinMax = SatTest(normals[i], shape2Corners);
            if (!Overlap(shape1MinMax[0], shape1MinMax[1], shape2MinMax[0], shape2MinMax[1]))
            {
                //Debug.Log("falure");
                col.status = false;
                return(col);
            }
        }
        col.status      = true;
        col.contacts[0] = con0;
        return(col);
    }
Пример #2
0
    static protected bool AABBVSOBB(AABBHull AABB, OBBHull OBB)
    {
        Vector2 AABBMinTransform = OBB.transform.InverseTransformPoint(AABB.min + AABB.center);
        Vector2 AABBMaxTransform = OBB.transform.InverseTransformPoint(AABB.max + AABB.center);

        //Debug.DrawLine(AABBMinTransform, AABBMaxTransform, Color.red);
        //Debug.DrawLine(OBB.min, OBB.max, Color.green);
        //Debug.DrawLine(AABB.center, OBB.center, Color.yellow);

        if (AABB.max.x + AABB.center.x >= OBB.min.x + OBB.center.x && OBB.max.x + OBB.center.x >= AABB.min.x + AABB.center.x)
        {
            if (AABB.max.y + AABB.center.y >= OBB.min.y + OBB.center.y && OBB.max.y + OBB.center.y >= AABB.min.y + AABB.center.y)
            {
                /*if (obbMinTransform.x > obbMaxTransform.x && obbMinTransform.y > obbMaxTransform.y)
                 * {
                 *  Vector2 temp = obbMinTransform;
                 *  obbMinTransform = obbMaxTransform;
                 *  obbMaxTransform = temp;
                 * }*/


                if (AABBMaxTransform.x + AABB.center.x >= OBB.min.x + OBB.center.x && OBB.max.x + OBB.center.x >= AABBMinTransform.x + AABB.center.x)
                {
                    if (AABBMaxTransform.y + AABB.center.y >= OBB.min.x + OBB.center.y && OBB.max.x + OBB.center.y >= AABBMinTransform.y + AABB.center.y)
                    {
                        return(true);
                    }
                }
            }
        }
        return(false);
    }
Пример #3
0
    static Vector3[] getRotatedCorners(OBBHull newHull)
    {
        Vector3[] returnPoints = new Vector3[4];
        returnPoints[0] = getRotatedPoint(new Vector3(newHull.transform.position.x - newHull.halfX, newHull.transform.position.y - newHull.halfY), newHull.transform.position, newHull.currentRotation);
        returnPoints[1] = getRotatedPoint(new Vector3(newHull.transform.position.x - newHull.halfX, newHull.transform.position.y + newHull.halfY), newHull.transform.position, newHull.currentRotation);
        returnPoints[2] = getRotatedPoint(new Vector3(newHull.transform.position.x + newHull.halfX, newHull.transform.position.y - newHull.halfY), newHull.transform.position, newHull.currentRotation);
        returnPoints[3] = getRotatedPoint(new Vector3(newHull.transform.position.x + newHull.halfX, newHull.transform.position.y + newHull.halfY), newHull.transform.position, newHull.currentRotation);

        return(returnPoints);
    }
Пример #4
0
    public static HullCollision CircleOBBCollision(CircleHull circleHull, OBBHull OBBHull)
    {
        Particle2D A = circleHull.GetComponent <Particle2D>();
        Particle2D B = OBBHull.GetComponent <Particle2D>();

        Vector3[] OBBCorners;

        OBBCorners = new Vector3[2];//was 4
        Vector3[] normals      = new Vector3[2];
        float[]   OBBMinMax    = new float[2];
        float[]   circleMinMax = new float[2];

        OBBCorners = getRotatedCorners(OBBHull);

        normals[0] = getUpNormal(-OBBHull.currentRotation);
        normals[1] = getRightNormal(-OBBHull.currentRotation);
        //normals[2] = getUpNormal(-OBBHull2.currentRotation);
        //normals[3] = getRightNormal(-boxHull2.currentRotation);

        HullCollision col = new HullCollision();

        col.a = circleHull;
        col.b = OBBHull;
        Vector3 range = (OBBHull.transform.position + OBBHull.offset) - (circleHull.transform.position + circleHull.offset);

        Vector3 rotatedRange = getRotatedPoint(range, new Vector3(0.0f, 0.0f), -OBBHull.currentRotation);// 2 circleHull.transform.position
        Vector3 point        = new Vector3(Mathf.Clamp(rotatedRange.x, -OBBHull.halfX, OBBHull.halfX), Mathf.Clamp(rotatedRange.y, -OBBHull.halfY, OBBHull.halfY));
        //Debug.Log("range " + range);
        //Debug.Log("rotrange " + rotatedRange);

        //float xOverlap = boxHull1.halfX + boxHull2.halfX - Mathf.Abs(range.x);
        //float yOverlap = boxHull1.halfY + boxHull2.halfY - Mathf.Abs(range.y);

        //col.penetration = new Vector3(xOverlap, yOverlap);

        Vector3 closingVel = B.velocity - A.velocity;

        col.closingVelocity = closingVel;

        HullCollision.Contact con0 = new HullCollision.Contact();
        con0.point       = new Vector3(Mathf.Clamp(range.x, -OBBHull.halfX, OBBHull.halfX), Mathf.Clamp(range.y, -OBBHull.halfY, OBBHull.halfY));
        con0.restitution = Mathf.Min(OBBHull.restitution, circleHull.restitution);
        con0.normal      = range.normalized;
        //Debug.Log("point " + point);

        col.status = false;
        if ((rotatedRange - point).magnitude - circleHull.radius < 0)
        {
            col.status      = true;
            col.contacts[0] = con0;
        }
        return(col);
    }
Пример #5
0
    static protected bool OBBVSOBB(OBBHull OBB1, OBBHull OBB2)
    {
        List <Vector2> allAxis = new List <Vector2>();

        allAxis.AddRange(OBB1.NormalAxis);
        allAxis.AddRange(OBB2.NormalAxis);

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

            foreach (var vert in OBB1.Vertices)
            {
                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 OBB2.Vertices)
            {
                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))
            {
                return(false);
            }
        }

        return(true);
    }
Пример #6
0
    static protected bool CircleVSOBB(CircleHull circle, OBBHull OBB)
    {
        Vector2 halfExtend  = (OBB.max - OBB.min) / 2;
        Vector2 circleInOBB = OBB.transform.InverseTransformPoint(circle.GetCenter());
        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);

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

        return(false);
    }
Пример #7
0
    static protected CollisionInfo CircleVSOBB(CircleHull circle, OBBHull OBB)
    {
        Vector2 halfExtend  = (OBB.max - OBB.min) / 2;
        Vector2 circleInOBB = OBB.transform.InverseTransformPoint(circle.GetCenter());
        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);

        if (distanceSQ > (circle.radius * circle.radius))
        {
            return(null);
        }

        float distance = Mathf.Sqrt(distanceSQ);

        return(new CollisionInfo(circle, OBB, OBB.transform.TransformVector(-distanceVec).normalized, circle.radius - distance));
    }
Пример #8
0
    protected static CollisionInfo CircleVSOBB(CircleHull circle, OBBHull OBB)
    {
        Vector3 halfExtend = OBB.halfExtends;
        Vector3 circleInOBB = OBB.GetComponent<Particle3D>().getWorldToObject().MultiplyPoint(circle.GetCenter());
        Vector3 circleBox = new Vector3(Mathf.Max(-halfExtend.x, Mathf.Min(circleInOBB.x, halfExtend.x)),
            Mathf.Max(-halfExtend.y, Mathf.Min(circleInOBB.y, halfExtend.y)),
            Mathf.Max(-halfExtend.z, Mathf.Min(circleInOBB.z, halfExtend.z)));

        Vector3 distanceVec = circleInOBB - circleBox;
        float distanceSQ = Vector3.Dot(distanceVec, distanceVec);
        if (distanceSQ > (circle.radius * circle.radius))
        {
            return null;
        }
        Vector3 closestPt = new Vector3(0f,0f,0f);
        float dist;
        // Clamp each coordinate to the box.
        dist = circleInOBB.x;
        if (dist > OBB.halfExtends.x) dist = OBB.halfExtends.x;
        if (dist < -OBB.halfExtends.x) dist = -OBB.halfExtends.x;
        closestPt.x = dist;
        dist = circleInOBB.y;
        if (dist > OBB.halfExtends.y) dist = OBB.halfExtends.y;
        if (dist < -OBB.halfExtends.y) dist = -OBB.halfExtends.y;
        closestPt.y = dist;
        dist = circleInOBB.z;
        if (dist > OBB.halfExtends.z) dist = OBB.halfExtends.z;
        if (dist < -OBB.halfExtends.z) dist = -OBB.halfExtends.z;
        closestPt.z = dist;
        // Check to see if we’re in contact.
        dist = (closestPt - circleInOBB).sqrMagnitude;
        if (dist > circle.radius * circle.radius)
            return null;
        // Compile the contact.
        Vector3 closestPtWorld = OBB.GetComponent<Particle3D>().getObjectToWorld().MultiplyPoint(closestPt);
        //place contact point in world space
        float distance = Mathf.Sqrt(distanceSQ);
        //Debug.LogError(closestPtWorld);
        return new CollisionInfo(circle, OBB, (-distanceVec).normalized, (circle.radius - distance),closestPtWorld);
        //OBB.GetComponent<Particle3D>().getObjectToWorld().MultiplyPoint(-distanceVec).normalized this failed to work, removing it fixed it
    }
Пример #9
0
    static protected CollisionInfo CircleVSOBB(CircleHull circle, OBBHull OBB)
    {
        Vector3 halfExtend  = OBB.halfExtends;
        Vector3 circleInOBB = OBB.GetComponent <Particle3D>().getWorldToObject().MultiplyPoint(circle.GetCenter());
        Vector3 circleBox   = new Vector3(Mathf.Max(-halfExtend.x, Mathf.Min(circleInOBB.x, halfExtend.x)),
                                          Mathf.Max(-halfExtend.y, Mathf.Min(circleInOBB.y, halfExtend.y)),
                                          Mathf.Max(-halfExtend.z, Mathf.Min(circleInOBB.z, halfExtend.z)));

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

        if (distanceSQ > (circle.radius * circle.radius))
        {
            return(null);
        }
        //place contact point in world space
        float distance = Mathf.Sqrt(distanceSQ);

        return(new CollisionInfo(circle, OBB, (-distanceVec).normalized, (circle.radius - distance)));
        //OBB.GetComponent<Particle3D>().getObjectToWorld().MultiplyPoint(-distanceVec).normalized this failed to work, removing it fixed it
    }
Пример #10
0
    static protected CollisionInfo OBBVSOBB(OBBHull OBB1, OBBHull OBB2)
    {
        List <Vector2> allAxis = new List <Vector2>();

        allAxis.AddRange(OBB1.NormalAxis);
        allAxis.AddRange(OBB2.NormalAxis);

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

            foreach (var vert in OBB1.Vertices)
            {
                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 OBB2.Vertices)
            {
                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 = OBB2.center - OBB1.center;



                float x_overlap = OBB1.halfExtends.x + OBB2.halfExtends.x - Mathf.Abs(AtoB.x);

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

        return(null);
    }
Пример #11
0
    static protected CollisionInfo AABBVSOBB(AABBHull AABB, OBBHull OBB)
    {
        List <Vector2> allAxis = new List <Vector2>();

        allAxis.AddRange(AABB.NormalAxis);
        allAxis.AddRange(OBB.NormalAxis);

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

            foreach (var vert in AABB.Vertices)
            {
                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 OBB.Vertices)
            {
                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 OBBExtend = (OBB.RotMax - OBB.RotMin) / 2f;
                Vector2 AtoB      = OBB.center - AABB.center;
                float   x_overlap = AABB.halfExtends.x + OBBExtend.x - Mathf.Abs(AtoB.x);

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

        return(null);
    }
Пример #12
0
 // Start is called before the first frame update
 void Start()
 {
     thrust       = GetComponent <Particle2D>();
     hull         = GetComponent <OBBHull>();
     bulletPrefab = Resources.Load("Bullet") as GameObject;
 }
Пример #13
0
 protected static CollisionInfo AABBVSOBB(AABBHull AABB, OBBHull OBB)
 {
     Vector3 toCenter = AABB.center - OBB.center;
     return boxTest(AABB, OBB, toCenter, AABB.halfExtends, OBB.halfExtends);
 }
Пример #14
0
 protected static CollisionInfo OBBVSOBB(OBBHull OBB1, OBBHull OBB2)
 {
     Vector3 toCenter = OBB1.center - OBB2.center;
     return boxTest(OBB1,OBB2, toCenter,OBB1.halfExtends,OBB2.halfExtends);
 }
Пример #15
0
 static public bool OBBVSOBB(OBBHull OBB1, OBBHull OBB2)
 {
     //project onto both axis, get new min and max for both, then aabb test
     return(false);
 }