Esempio n. 1
0
    public override bool TestCollisionVsCircle(CircleCollisionHull2D other)
    {
        //collides if distance between centers is <= sum of radii
        //or if you like opptimizations
        //if (distance between center)^2 <= (sum of radii)^2
        // 1. get two centers
        Vector2 circleCenter1 = transform.position;
        Vector2 circleCenter2 = other.transform.position;
        // 2. take diference
        Vector2 distance = circleCenter2 - circleCenter1;
        // 3. distance squared = dot(diff, diff)
        float distSqr = Vector2.Dot(distance, distance);
        // 4. add the radii
        float radiiSum = other.radius + radius;

        // 5. square sum
        radiiSum *= radiiSum;
        // 6. do test. johnny test. it passes if distSq <= sumSq
        if (distSqr < radiiSum)
        {
            Debug.Log("CIRCLE -> CIRCLE");
            return(true);
        }

        return(false);
    }
    // FOR SUCCESSFUL COLLISION, CHANGE COLOR

    public override bool TestCollisionVSCircle(CircleCollisionHull2D other, ref Collision c)
    {
        // find the min and max components of the obb
        float minX = Mathf.Min(topLeftAxis.x, Mathf.Min(topRightAxis.x, Mathf.Min(botLeftAxis.x, botRightAxis.x)));
        float maxX = Mathf.Max(topLeftAxis.x, Mathf.Max(topRightAxis.x, Mathf.Max(botLeftAxis.x, botRightAxis.x)));

        float minY = Mathf.Min(topLeftAxis.y, Mathf.Min(topRightAxis.y, Mathf.Min(botLeftAxis.y, botRightAxis.y)));
        float maxY = Mathf.Max(topLeftAxis.y, Mathf.Max(topRightAxis.y, Mathf.Max(botLeftAxis.y, botRightAxis.y)));

        // calculate closest point by clamping circle center on each dimension
        // Find the vector2 distance between box & circle
        Vector2 diff = (Vector2)transform.position - (Vector2)other.transform.position;

        // Normalize that vector
        // multiply the vector by the radius to get the closest point on the circumference
        diff = diff.normalized * other.radius + (Vector2)other.transform.position;


        Debug.Log(minX + ", " + maxX);
        Debug.Log(minY + ", " + maxY);
        Debug.Log(diff);

        // check for the collision
        return(IsIntersectingCircle(minX, maxX, minY, maxY, diff.x, diff.y));
    }
Esempio n. 3
0
    public override bool TestCollisionVsCircle(CircleCollisionHull2D other)
    {
        //same as above but first...
        //multiply circle center by box inverse matrix

        // 1. get circle center
        Vector4 circleCenter = new Vector4(other.transform.position.x, other.transform.position.y, 0.0f, 1.0f);

        // 2. get box x bounds
        float xMaxBound = transform.localScale.x * 0.5f;
        float xMinBound = -transform.localScale.x * 0.5f;
        // 3. get box y bounds

        float yMaxBound = transform.localScale.y * 0.5f;
        float yMinBound = -transform.localScale.y * 0.5f;

        // 4. multiply circle center world position by box world to local matrix
        circleCenter = transform.InverseTransformPoint(circleCenter);

        // 5. clamp circle center on box x bound
        float circleOnX = circleCenter.x;

        // 6. clamp circle center on box y bound
        float circleOnY = circleCenter.y;

        if (circleCenter.x > xMaxBound)
        {
            circleOnX = xMaxBound;
        }
        else if (circleCenter.x < xMinBound)
        {
            circleOnX = xMinBound;
        }

        if (circleCenter.y > yMaxBound)
        {
            circleOnY = yMaxBound;
        }
        else if (circleCenter.y < yMinBound)
        {
            circleOnY = yMinBound;
        }

        // 7. use clamped point as closest point of box
        Vector2 closestPoint = new Vector2(circleOnX, circleOnY);

        Vector2 distance = closestPoint - new Vector2(circleCenter.x, circleCenter.y);
        float   distSqr  = Vector2.Dot(distance, distance);

        // 8. check if closest point of box is within the circle
        if (distSqr < other.radius * other.radius)
        {
            Debug.Log("OBB -> CIRCLE");
            return(true);
        }

        // 9. do test (if in circle, true, else false)
        return(false);
    }
Esempio n. 4
0
    public override bool TestCollisionVsCircle(CircleCollisionHull2D other, ref Collision c)
    {
        c.a = this;
        c.b = other;
        // c.status
        // check if sqr distance between the center is less that the square of the radii
        updatePosition();
        other.updatePosition();
        // could use dot product
        float sqrDistance = (position - other.position).SqrMagnitude();
        float sqrRadii    = radius + other.radius;

        sqrRadii *= sqrRadii;

        bool isColiding = sqrDistance <= sqrRadii;

        if (!isColiding)
        {
            return(isColiding);
        }
        //contact point
        // http://paulbourke.net/geometry/circlesphere/
        Vector2 difference = other.position - position; //from position to other.position
        float   distance   = difference.magnitude;
        float   radii      = radius + other.radius;
        // distance = radii
        // Vector2 contact = position + difference;

        // Get point halfway between two centers.
        Vector2 contact = position + difference * (radius / (radius + other.radius)); //
        Vector2 normal  = (position - contact).normalized;                            // vector from contact to center
        float   overlap = radii - distance;                                           // not sure we need this.

        // edge cases - circles overlap completely, or one inside the other.

        c.contactCount            = 1;
        c.contacts                = new CollisionHull2D.Collision.Contact[c.contactCount];
        c.contacts[0].point       = contact;
        c.contacts[0].normal      = normal;
        c.contacts[0].restitution = restitution; // TODO: Is this coefficient or actual number?


        // closing velocity
        // https://gamedev.stackexchange.com/questions/118162/how-to-calculate-the-closing-speed-of-two-objects
        //Vector2 diff = other.position - position;
        //Vector2 velDiff = other.particle2D.getVelocity() - particle2D.getVelocity();
        //float closingSpeed = Vector2.Dot(velDiff, diff) / diff.magnitude;
        //Relative velocity from book
        Vector2 relativeVelocity = particle2D.getVelocity() - other.getParticle2D().getVelocity();
        float   separatingVel    = Vector2.Dot(relativeVelocity, normal); // relativeVelocity * normal

        // https://math.stackexchange.com/questions/13261/how-to-get-a-reflection-vector
        // this would simulate hitting a hard object w/ no velocity loss.
        // Vector2 velReflectedOverN = particle2D.getVelocity() - 2 * Vector2.Dot(particle2D.getVelocity(), normal) * normal;
        // c.closingVelocity =  closingSpeed*velReflectedOverN.normalized;
        c.closingVelocity = -separatingVel * normal; //was -seperatingVel
        c.status          = isColiding;
        return(isColiding);
    }
    public override bool TestCollisionVsCircle(CircleCollisionHull2D other)
    {
        //SEE CIRCLE

        // find closest point to circle on box
        // done by clamping center of circle to be within box dimensions
        // if closest point is within circle, pass! (do circle vs point test)


        // 1. get circle center
        Vector2 circleCenter = other.transform.position;
        float   xMaxBound    = transform.position.x + transform.localScale.x * 0.5f;
        float   xMinBound    = transform.position.x - transform.localScale.x * 0.5f;

        // 3. get box y bounds
        float yMaxBound = transform.position.y + transform.localScale.y * 0.5f;
        float yMinBound = transform.position.y - transform.localScale.y * 0.5f;

        // 4. clamp circle center on box x bound
        // 5. clamp circle center on box y bound

        float circleOnX = circleCenter.x;
        float circleOnY = circleCenter.y;

        if (circleCenter.x > xMaxBound)
        {
            circleOnX = xMaxBound;
        }
        else if (circleCenter.x < xMinBound)
        {
            circleOnX = xMinBound;
        }

        if (circleCenter.y > yMaxBound)
        {
            circleOnY = yMaxBound;
        }
        else if (circleCenter.y < yMinBound)
        {
            circleOnY = yMinBound;
        }

        // 6. use clamped point as closest point of box
        Vector2 closestPoint = new Vector2(circleOnX, circleOnY);
        Vector2 distance     = closestPoint - circleCenter;
        float   distSqr      = Vector2.Dot(distance, distance);

        // 7. check if closest point of box is within the circle
        // 8. do test (if in circle, true, else false)
        if (distSqr < other.radius * other.radius)
        {
            Debug.Log("BOX -> CIRCLE");
            return(true);
        }

        return(false);
    }
    // FOR SUCCESSFUL COLLISION, CHANGE COLOR

    public override bool TestCollisionVSCircle(CircleCollisionHull2D other, ref Collision c)
    {
        //ROB
        // Passes if distance between centers <= sum of radii
        // optimized collision passes if (distance between centers) squared <= (sum of radii) squared
        // 1. Get the two centers
        Vector2 otherCenter = other.thisCenter;

        // 2. difference between centers
        Vector2 distanceVec = otherCenter - thisCenter;

        //float distance = (otherCenter.x - thisCenter.x) * (otherCenter.x - thisCenter.x)
        //               + (otherCenter.y - thisCenter.y) * (otherCenter.y - thisCenter.y);
        //distance *= distance;

        // 3. distance squared = dot(diff, diff)
        float distance = Vector2.Dot(distanceVec, distanceVec);

        // 4. Sum of radii
        float totalRadii = radius + other.radius;

        // 5. square sum
        totalRadii *= totalRadii;

        // 6. Do the test: distSqr <= sumSqr
        if (distance <= totalRadii)
        {
            c.a      = gameObject.GetComponent <CircleCollisionHull2D>();
            c.b      = other;
            c.status = true;

            if (distance <= totalRadii)
            {
                float theta = Mathf.Atan2(distanceVec.y, distanceVec.x);
                // find the point in the center of the overlap between the two circles
                c.contactCount = 1;
                float distanceToContactPoint = ((distance * distance - other.radius * other.radius + radius * radius) / (2 * distance));
                c.contact[0].penetration = radius - distanceToContactPoint;
                c.contact[0].point.x     = thisCenter.x + Mathf.Cos(theta) * distanceToContactPoint;
                // if broken, put in abs inside of sqrt
                c.contact[0].point.y = thisCenter.y + Mathf.Sin(theta) * distanceToContactPoint;
                c.contact[0].normal  = thisCenter - c.contact[0].point;
                c.contact[0].normal.Normalize();
                Debug.DrawLine(thisCenter, thisCenter + c.contact[0].normal);
                c.contact[0].restitutionCoefficient = restitution;
            }
            return(true);
        }

        return(false);
    }
Esempio n. 7
0
    public bool TestCollisionVsCircle(CircleCollisionHull2D other)
    {
        // check if sqr distance between the center is less that the square of the radii
        updatePosition();
        other.updatePosition();
        // could use dot product
        float sqrDistance = (position - other.position).SqrMagnitude();
        float sqrRadii    = radius + other.radius;

        sqrRadii *= sqrRadii;

        bool isColiding = sqrDistance <= sqrRadii;

        return(isColiding);
    }
    // FOR SUCCESSFUL COLLISION, CHANGE COLOR
    public override bool TestCollisionVSCircle(CircleCollisionHull2D other, ref Collision c)
    {
        // cam did this part

        float circleX      = other.thisCenter.x;
        float circleY      = other.thisCenter.y;
        float circleRadius = other.radius;

        float rectX = position.x;
        float rectY = position.y;

        float DeltaX = circleX - Mathf.Max(rectX, Mathf.Min(circleX, rectX + width * 0.5f));
        float DeltaY = circleY - Mathf.Max(rectY, Mathf.Min(circleY, rectY + height * 0.5f));

        return((DeltaX * DeltaX + DeltaY * DeltaY) < (circleRadius * circleRadius));
    }
Esempio n. 9
0
    // Start is called before the first frame update
    public override bool TestCollisionVsCircle(CircleCollisionHull2D other, ref Collision c)
    {
        updatePosition();
        other.updatePosition();
        // find the closest point to the circle on the box.
        // - Clamp the center of the circle to be in dimensions of box, gets closest point?
        Vector2 closest_point;
        Vector2 blCorner = botLeftCorner + position;
        Vector2 trCorner = topRightCorner + position;

        closest_point.x = Mathf.Clamp(other.position.x, blCorner.x, trCorner.x);
        closest_point.y = Mathf.Clamp(other.position.y, blCorner.y, trCorner.y);

        // if closest point is within circle, pass. (point vs circle test). square for efficiency
        bool isColiding = (other.position - closest_point).SqrMagnitude() < other.radius * other.radius;

        return(isColiding);
    }
Esempio n. 10
0
 // Start is called before the first frame update
 void Start()
 {
     collider        = gameObject.AddComponent <CircleCollisionHull2D>();
     collider.radius = radius;
     collider.FakeStart();
 }
Esempio n. 11
0
 public abstract bool TestCollisionVSCircle(CircleCollisionHull2D other, ref Collision c);
Esempio n. 12
0
 public abstract bool TestCollisionVsCircle(CircleCollisionHull2D other);
Esempio n. 13
0
 public virtual bool TestCollisionVsCircle(CircleCollisionHull2D other, ref Collision c)
 {
     return(false);
 }
Esempio n. 14
0
    public override bool TestCollisionVsCircle(CircleCollisionHull2D other, ref Collision c)
    {
        // See circle
        updatePosition();
        other.updatePosition();
        // same as above, but first
        // multiply circle center by invs world matrix of box to move to box space

        // neither of the these work.
        // Vector2 transformedPosition = transform.localToWorldMatrix.inverse * other.position;
        //Matrix4x4 trs = Matrix4x4.TRS(transform.position, transform.rotation, Vector3.one);
        // Vector2 transformedPosition = (trs* new Vector4(other.position.x, other.position.y, 0, 0));
        // Vector2 transformedPosition = other.position;

        // Vector2 closest_point;
        // Vector2 blc = Vector2.zero, trc = Vector2.zero; // bot left and top right of OBB
        // getDimensions(ref blc, ref trc);

        // //With above code works except for position and rotation.
        // //blc += position;
        // //trc += position;

        // // This fixes position but not rotation.
        //// blc = botLeftTranslated();
        // // trc = topRightTranslated();
        // // These aren't the right corners?

        // closest_point.x = Mathf.Clamp(transformedPosition.x, blc.x, trc.x);
        // closest_point.y = Mathf.Clamp(transformedPosition.y, blc.y, trc.y);

        // // if closest point is within circle, pass. (point vs circle test). square for efficiency
        // bool isColiding = (transformedPosition - closest_point).SqrMagnitude() < other.radius * other.radius; ;
        // return isColiding;

        // =========== Attempt 2 ============= //
        //  project circle center and this points onto axii
        // if circle point is within radius of point on both axii then true, else false.
        // can use clamp here too

        // Project circle and corners onto up axis
        Vector2 circleProj = project(other.position, transform.up);
        Vector2 corner1    = topRightTranslated();
        Vector2 corner2    = botRightTranslated();
        // should be able to ignore other two corners along axis because they'll be the same.
        Vector2 c1proj = project(corner1, transform.up);
        Vector2 c2proj = project(corner2, transform.up);
        // clamp circle proj to get closest point
        Vector2 closestPoint;

        closestPoint.x = Mathf.Clamp(circleProj.x, Mathf.Min(c1proj.x, c2proj.x), Mathf.Max(c1proj.x, c2proj.x));
        closestPoint.y = Mathf.Clamp(circleProj.y, Mathf.Min(c1proj.y, c2proj.y), Mathf.Max(c1proj.y, c2proj.y));
        // compare closest point to projected point.
        bool isCollidingOnUp = (circleProj - closestPoint).SqrMagnitude() < other.radius * other.radius;

        // repeat for right axis
        circleProj     = project(other.position, transform.right);
        corner1        = topLeftTranslated();
        corner2        = topRightTranslated();
        c1proj         = project(corner1, transform.right);
        c2proj         = project(corner2, transform.right);
        closestPoint.x = Mathf.Clamp(circleProj.x, Mathf.Min(c1proj.x, c2proj.x), Mathf.Max(c1proj.x, c2proj.x));
        closestPoint.y = Mathf.Clamp(circleProj.y, Mathf.Min(c1proj.y, c2proj.y), Mathf.Max(c1proj.y, c2proj.y));
        bool isCollidingOnRight = (circleProj - closestPoint).SqrMagnitude() < other.radius * other.radius;

        return(isCollidingOnRight && isCollidingOnUp);
    }