Пример #1
0
    public static bool SpherePlaneCollisionOccured(PSI_Collider_Sphere sphereCol, PSI_Collider_Plane planeCol, out Vector3 point)
    {
        // Determine the signed distance to from the sphere to its projected point on the plane.
        float distToProjectedPoint = Vector3.Dot(planeCol.pNormal, (sphereCol.pPosition - planeCol.pPosition));

        // Determine the spheres projected point on the plane.
        point = sphereCol.pPosition - distToProjectedPoint * planeCol.pNormal;

        // Generate 4 triangles between the corners of the plane and the projected point.
        var planeVerts = planeCol.GetVertices();
        var triangles  = new Vector3[4, 3];

        for (int i = 0; i < 4; i++)
        {
            triangles[i, 0] = point;
            triangles[i, 1] = planeVerts[i];
            triangles[i, 2] = planeVerts[(i == 3) ? 0 : i + 1];
        }

        // Sum the area of the traingles.
        float totalTriArea = 0.0f;

        for (int i = 0; i < 4; i++)
        {
            float a = Vector3.Distance(triangles[i, 0], triangles[i, 1]);
            float b = Vector3.Distance(triangles[i, 1], triangles[i, 2]);
            float c = Vector3.Distance(triangles[i, 2], triangles[i, 0]);
            float s = (a + b + c) / 2;
            totalTriArea += Mathf.Sqrt(s * (s - a) * (s - b) * (s - c));
        }

        // Determine if a collision occured by checking if the sphere is overlapping with the plane and the projected point
        // is within the extents of the plane by checking the sum area of the triangles is equal to the size of the plane.
        bool isColliding = Mathf.Abs(totalTriArea - planeCol.pArea) < 0.01f && Mathf.Abs(distToProjectedPoint) <= sphereCol.pRadius;

        if (isColliding)
        {
            // Resolve any overlap between the sphere and the plane.
            var collisionAxis = CorrectCollisionAxisDirection(planeCol.pPosition, sphereCol.pPosition, point - sphereCol.pPosition);
            var overlap       = collisionAxis.magnitude - sphereCol.pRadius;
            ResolveCollisionOverlaps(sphereCol, planeCol, collisionAxis, overlap);

            // Calculate and apply the collision impulse to the sphere.
            ApplyImpulses(sphereCol, planeCol, collisionAxis, point);

            // Apply friction to the sphere.
            ApplyFriction(sphereCol, planeCol, point);

            return(true);
        }
        return(false);
    }
Пример #2
0
    //----------------------------------------Public Functions---------------------------------------

    public static bool SphereSphereCollisionCheck(PSI_Collider_Sphere col1, PSI_Collider_Sphere col2, out Vector3 point)
    {
        // Determine if the sphere are colliding by doing a distance check.
        var collisionVector = col2.pPosition - col1.pPosition;

        point = col1.pPosition + collisionVector / 2f;
        bool isColliding = collisionVector.magnitude <= Mathf.Abs(col1.pRadius) + Mathf.Abs(col2.pRadius);

        if (isColliding)
        {
            // Resolve any overlap between the spheres.
            var collisionAxis = CorrectCollisionAxisDirection(col1.pPosition, col2.pPosition, collisionVector);
            var overlap       = collisionAxis.magnitude - (col1.pRadius + col2.pRadius);
            ResolveCollisionOverlaps(col1, col2, collisionVector, overlap);

            // Calculate and apply the collision impulse to the spheres.
            ApplyImpulses(col1, col2, collisionVector, point);

            return(true);
        }
        return(false);
    }
Пример #3
0
    public static bool SphereBoxCollisionOccured(PSI_Collider_Sphere sphereCol, PSI_Collider_Box boxCol, out Vector3 point)
    {
        // Get the closest point on the surface of the box to the sphere.
        point = boxCol.GetClosestPointOnBox(sphereCol.pPosition);

        // Do a distance check to see if the sphere and box are colliding.
        var  collisionVector = point - sphereCol.pPosition;
        bool isColliding     = collisionVector.magnitude <= Mathf.Abs(sphereCol.pRadius);

        if (isColliding)
        {
            // Resolve any overlap between the sphere and the box.
            var   collisionAxis = CorrectCollisionAxisDirection(boxCol.pPosition, sphereCol.pPosition, collisionVector);
            float overlap       = collisionVector.magnitude - sphereCol.pRadius;
            ResolveCollisionOverlaps(sphereCol, boxCol, collisionAxis, overlap);

            // Calculate and apply the collision impulse to the sphere and the box.
            ApplyImpulses(sphereCol, boxCol, collisionAxis, point);

            return(true);
        }

        return(false);
    }
Пример #4
0
    //------------------------------------Private Functions-------------------------------------

    private void CheckForCollision(PSI_Collider col1, PSI_Collider col2)
    {
        bool          collisionOccurred = false;
        PSI_Collision collision         = new PSI_Collision();

        collision.col1 = col1;
        collision.col2 = col2;

        // Sphere on sphere.
        if (col1.pType == ColliderType.Sphere && col2.pType == ColliderType.Sphere)
        {
            collisionOccurred = PSI_PhysicsUtils.SphereSphereCollisionCheck((PSI_Collider_Sphere)col1, (PSI_Collider_Sphere)col2, out collision.point);
        }

        // Sphere on plane.
        if ((col1.pType == ColliderType.Sphere && col2.pType == ColliderType.Plane) ||
            (col1.pType == ColliderType.Plane && col2.pType == ColliderType.Sphere))
        {
            PSI_Collider_Sphere sphere = (PSI_Collider_Sphere)((col1.pType == ColliderType.Sphere) ? col1 : col2);
            PSI_Collider_Plane  plane  = (PSI_Collider_Plane)((col1.pType == ColliderType.Sphere) ? col2 : col1);
            if (PSI_PhysicsUtils.SpherePlaneCollisionOccured(sphere, plane, out collision.point))
            {
                collisionOccurred = true;
            }
        }

        // Sphere on box.
        if ((col1.pType == ColliderType.Sphere && col2.pType == ColliderType.Box) ||
            (col1.pType == ColliderType.Box && col2.pType == ColliderType.Sphere))
        {
            PSI_Collider_Sphere sphere = (PSI_Collider_Sphere)((col1.pType == ColliderType.Sphere) ? col1 : col2);
            PSI_Collider_Box    box    = (PSI_Collider_Box)((col1.pType == ColliderType.Sphere) ? col2 : col1);
            if (PSI_PhysicsUtils.SphereBoxCollisionOccured(sphere, box, out collision.point))
            {
                collisionOccurred = true;
            }
        }

        // Box on box.
        if ((col1.pType == ColliderType.Box && col2.pType == ColliderType.Box))
        {
            if (PSI_PhysicsUtils.BoxBoxCollisionOccured((PSI_Collider_Box)col1, (PSI_Collider_Box)col2, out collision.point))
            {
                collisionOccurred = true;
            }
        }

        // Box on plane.
        if ((col1.pType == ColliderType.Box && col2.pType == ColliderType.Plane) ||
            (col1.pType == ColliderType.Plane && col2.pType == ColliderType.Box))
        {
            PSI_Collider_Box   box   = (PSI_Collider_Box)((col1.pType == ColliderType.Box) ? col1 : col2);
            PSI_Collider_Plane plane = (PSI_Collider_Plane)((col1.pType == ColliderType.Box) ? col2 : col1);
            if (PSI_PhysicsUtils.BoxPlaneCollisionOccured(box, plane, out collision.point))
            {
                collisionOccurred = true;
            }
        }

        if (collisionOccurred)
        {
            mCollisionData.Add(collision);
        }
    }