Esempio n. 1
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);
    }
Esempio n. 2
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);
    }
Esempio n. 3
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. 4
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);
    }