예제 #1
0
    public static HullCollision CircleAABBCollision(CircleHull circleHull, AABBHull boxHull)
    {
        Particle2D A = boxHull.GetComponent <Particle2D>();
        Particle2D B = circleHull.GetComponent <Particle2D>();

        Vector3 closestPoint = new Vector3(0.0f, 0.0f);
        Vector3 range        = (circleHull.transform.position + circleHull.offset) - (boxHull.transform.position + boxHull.offset);


        closestPoint = new Vector3(Mathf.Clamp(range.x, -boxHull.halfX, boxHull.halfX), Mathf.Clamp(range.y, -boxHull.halfY, boxHull.halfY));

        HullCollision col = new HullCollision();

        col.a = boxHull;
        col.b = circleHull;
        Vector3 closingVel  = B.velocity - A.velocity;
        Vector3 penetration = range - (closestPoint - circleHull.transform.position + circleHull.offset);

        col.closingVelocity = closingVel;
        col.penetration     = penetration;

        HullCollision.Contact con0 = new HullCollision.Contact();
        con0.point       = closestPoint;
        con0.restitution = Mathf.Min(boxHull.restitution, circleHull.restitution);

        Vector3 collisionNormal = new Vector3();


        if ((range - closestPoint).magnitude - circleHull.radius < 0)
        {
            if (con0.point.x == boxHull.halfX)//added mathf
            {
                collisionNormal = new Vector3(1.0f, 0.0f);
            }
            if (con0.point.x == -boxHull.halfX)//added mathf
            {
                collisionNormal = new Vector3(-1.0f, 0.0f);
            }
            if (con0.point.y == boxHull.halfY)
            {
                collisionNormal = new Vector3(0.0f, 1.0f);
            }
            if (con0.point.y == -boxHull.halfY)
            {
                collisionNormal = new Vector3(0.0f, -1.0f);
            }

            con0.normal = collisionNormal;

            col.status      = true;
            col.contacts[0] = con0;
        }
        else
        {
            col.status = false;
        }

        return(col);
    }
예제 #2
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);
    }
예제 #3
0
    protected static CollisionInfo CircleVSCircle(CircleHull circle1, CircleHull circle2)
    {
        float radiusSum = circle1.radius + circle2.radius;
        float totalRadius = (circle1.radius + circle2.radius) * (circle1.radius + circle2.radius);
        Vector3 centerDiff = (circle2.GetCenter() - circle1.GetCenter());
        float distanceSQ = Vector3.Dot(centerDiff, centerDiff);

        if (distanceSQ > totalRadius)
        {
            return null;
        }
        float distance = Mathf.Sqrt(distanceSQ);
        return new CollisionInfo(circle1, circle2, centerDiff / distance, radiusSum - distance,(circle1.GetCenter() + centerDiff * 0.5f));
    }
예제 #4
0
    static public bool CircleVSCircle(CircleHull circle1, CircleHull circle2)
    {
        float   totalRadius = (circle1.radius + circle2.radius); //* (circle1.radius + circle2.radius);
        Vector2 distance    = (circle2.GetCenter() - circle1.GetCenter());

        if (Vector2.Dot(distance, distance) <= totalRadius)
        {
            return(true);
        }
        else
        {
            return(false);
        }
    }
예제 #5
0
    protected static CollisionInfo CircleVSAABB(CircleHull circle, AABBHull AABB)
    {
        Vector3 circleBox = new Vector3(Mathf.Max(AABB.min.x + AABB.center.x, Mathf.Min(circle.GetCenter().x, AABB.max.x + AABB.center.x)),
            Mathf.Max(AABB.min.y + AABB.center.y, Mathf.Min(circle.GetCenter().y, AABB.max.y + AABB.center.y)),
            Mathf.Max(AABB.min.z + AABB.center.z, Mathf.Min(circle.GetCenter().z, AABB.max.z + AABB.center.z)));

        Vector3 distanceVec = circle.GetCenter() - circleBox;
        float distanceSQ = Vector3.Dot(distanceVec, distanceVec);
        if (distanceSQ > (circle.radius * circle.radius))
        {
            return null;
        }
        float distance = Mathf.Sqrt(distanceSQ);
        return new CollisionInfo(circle, AABB, -distanceVec.normalized, circle.radius - distance, circleBox);
    }
예제 #6
0
    static protected bool CircleVSAABB(CircleHull circle, AABBHull AABB)
    {
        Vector2 circleBox = new Vector2(Mathf.Max(AABB.min.x + AABB.center.x, Mathf.Min(circle.GetCenter().x, AABB.max.x + AABB.center.x)),
                                        Mathf.Max(AABB.min.y + AABB.center.y, Mathf.Min(circle.GetCenter().y, AABB.max.y + AABB.center.y)));

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

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

        return(false);
    }
예제 #7
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);
    }
예제 #8
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));
    }
예제 #9
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
    }
예제 #10
0
    public static HullCollision CircleCircleCollision(CircleHull circleHull1, CircleHull circleHull2)
    {
        // *IMPORTANT* for circle and square the collision only wirks with obejct1 - object 2 and not viceversa, must be a prob in clollision resolution
        Vector3 c1Offset = circleHull1.offset;
        Vector3 c2Offset = circleHull2.offset;

        Vector3 range   = (circleHull2.transform.position + c2Offset) - (circleHull1.transform.position + c1Offset); // make sure offsets arent screwing things up
        float   overlap = (circleHull2.radius + circleHull1.radius) - range.magnitude;

        HullCollision col = new HullCollision();

        col.a           = circleHull1;
        col.b           = circleHull2;
        col.penetration = range * overlap;

        HullCollision.Contact con0 = new HullCollision.Contact();
        con0.point       = (range.normalized * circleHull1.radius);
        con0.point      += new Vector3(circleHull1.transform.position.x, circleHull1.transform.position.y);
        con0.normal      = range.normalized;
        con0.restitution = Mathf.Min(circleHull1.restitution, circleHull2.restitution);

        col.contacts[0] = con0;

        Particle2D c1 = circleHull1.GetComponentInParent <Particle2D>();
        Particle2D c2 = circleHull2.GetComponentInParent <Particle2D>();

        Vector3 closingVel = c2.velocity - c1.velocity; // started as c1 -c2

        col.closingVelocity = closingVel;

        if (overlap > 0)
        {
            col.status = true;
            return(col);
        }
        else
        {
            col.status = false;
            return(col);
        }
    }
예제 #11
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
    }