예제 #1
0
    void DrawSelectedObject()
    {
        if (_lineMaterial == null)
        {
            return;
        }

        NewBoxCollider box = _selectedObject.GetComponent <NewBoxCollider> ();

        if (box != null)
        {
            DrawCube(box.origin.dots, 1f);
            DrawCube(box.origin.dots, 1.0005f);
            DrawCube(box.origin.dots, 1.0006f);
            DrawCube(box.origin.dots, 1.0007f);
            DrawCube(box.origin.dots, 1.0008f);

            return;
        }

        NewSphereCollider sphere = _selectedObject.GetComponent <NewSphereCollider> ();

        if (sphere != null)
        {
            DrawSphere(sphere.radius, sphere.transform.position);

            return;
        }
    }
예제 #2
0
    public bool SphereToSphere(NewSphereCollider sphereA, NewSphereCollider sphereB)
    {
        // reference https://developer.mozilla.org/en-US/docs/Games/Techniques/3D_collision_detection
        float distance = Mathf.Sqrt(
            (sphereA.transform.position.x - sphereB.transform.position.x) * (sphereA.transform.position.x - sphereB.transform.position.x) +
            (sphereA.transform.position.y - sphereB.transform.position.y) * (sphereA.transform.position.y - sphereB.transform.position.y) +
            (sphereA.transform.position.z - sphereB.transform.position.z) * (sphereA.transform.position.z - sphereB.transform.position.z));

        return(distance < (sphereA.radius + sphereB.radius));
    }
예제 #3
0
    public CollisionData SphereToSphereManifold(NewSphereCollider sphereA, NewSphereCollider sphereB)
    {
        // reference: https://gamedevelopment.tutsplus.com/tutorials/how-to-create-a-custom-2d-physics-engine-the-basics-and-impulse-resolution--gamedev-6331

        // Manifold Initialisation
        CollisionData manifold = new CollisionData();

        manifold.bodyA       = sphereA.transform.gameObject.GetComponent <NewRigidBody>();
        manifold.bodyB       = sphereB.transform.gameObject.GetComponent <NewRigidBody>();
        manifold.bodyAobj    = sphereA.transform.gameObject;
        manifold.bodyBobj    = sphereB.transform.gameObject;
        manifold.normal      = Vector3.zero;
        manifold.penetration = 0.0f;

        // Exit if no collision
        manifold.wasCollision = SphereToSphere(sphereA, sphereB);
        if (manifold.wasCollision == false)
        {
            return(manifold);
        }

        Vector3 relativePosition = sphereB.transform.position - sphereA.transform.position;

        float distance = Mathf.Sqrt(
            (sphereA.transform.position.x - sphereB.transform.position.x) * (sphereA.transform.position.x - sphereB.transform.position.x) +
            (sphereA.transform.position.y - sphereB.transform.position.y) * (sphereA.transform.position.y - sphereB.transform.position.y) +
            (sphereA.transform.position.z - sphereB.transform.position.z) * (sphereA.transform.position.z - sphereB.transform.position.z));

        // Ensure there is a distance to avoid / 0 error
        manifold.contacts = new List <Vector3>();
        if (distance != 0.0f)
        {
            manifold.penetration = (sphereA.radius + sphereB.radius) - distance;
            manifold.normal      = relativePosition / distance;
            manifold.contacts.Add(sphereA.transform.position);
        }
        // Avoid / 0 error
        else
        {
            manifold.penetration = sphereA.radius;
            manifold.normal      = new Vector3(0.0f, 1.0f, 0.0f);        // Consistent value (randomly chosen)
            manifold.contacts.Add(manifold.normal * sphereA.radius + sphereA.transform.position);
        }

        return(manifold);
    }
예제 #4
0
    public bool SphereToBox(NewSphereCollider sphere, NewBoxCollider box)
    {
        // reference https://developer.mozilla.org/en-US/docs/Games/Techniques/3D_collision_detection

        // find the closest point on the box to the center of the sphere
        Vector3 closestPoint = Vector3.zero;

        closestPoint.x = Mathf.Max(box.minBounds.x, Mathf.Min(sphere.transform.position.x, box.maxBounds.x));
        closestPoint.y = Mathf.Max(box.minBounds.y, Mathf.Min(sphere.transform.position.y, box.maxBounds.y));
        closestPoint.z = Mathf.Max(box.minBounds.z, Mathf.Min(sphere.transform.position.z, box.maxBounds.z));

        // distance between closest point and center of the sphere
        float distance = Mathf.Sqrt(
            (closestPoint.x - sphere.transform.position.x) * (closestPoint.x - sphere.transform.position.x) +
            (closestPoint.y - sphere.transform.position.y) * (closestPoint.y - sphere.transform.position.y) +
            (closestPoint.z - sphere.transform.position.z) * (closestPoint.z - sphere.transform.position.z));

        return(distance < sphere.radius);
    }
예제 #5
0
    public CollisionData BoxToSphereManifold(NewBoxCollider box, NewSphereCollider sphere)
    {
        // reference: https://gamedevelopment.tutsplus.com/tutorials/how-to-create-a-custom-2d-physics-engine-the-basics-and-impulse-resolution--gamedev-6331
        // (NOTE reference is in 2d, had to add 3D as well as my own manifold stuff)

        // Initialise manifold
        CollisionData manifold = new CollisionData();

        manifold.bodyA        = box.transform.gameObject.GetComponent <NewRigidBody> ();
        manifold.bodyB        = sphere.transform.gameObject.GetComponent <NewRigidBody> ();
        manifold.bodyAobj     = box.transform.gameObject;
        manifold.bodyBobj     = sphere.transform.gameObject;
        manifold.normal       = Vector3.zero;
        manifold.penetration  = 0.0f;
        manifold.wasCollision = false;


        Vector3 relativePosition = sphere.transform.position - box.transform.position;

        // Closest point on A to center of B
        Vector3 closestPoint = Vector3.zero;

        closestPoint.x = Mathf.Max(box.minBounds.x, Mathf.Min(sphere.transform.position.x, box.maxBounds.x));
        closestPoint.y = Mathf.Max(box.minBounds.y, Mathf.Min(sphere.transform.position.y, box.maxBounds.y));
        closestPoint.z = Mathf.Max(box.minBounds.z, Mathf.Min(sphere.transform.position.z, box.maxBounds.z));


        // If Circle is inside Box
        bool inside = false;

        if (relativePosition == closestPoint)
        {
            inside = true;

            // Find closest axis
            if (Mathf.Abs(relativePosition.x) > Mathf.Abs(relativePosition.y) && Mathf.Abs(relativePosition.x) > Mathf.Abs(relativePosition.z))
            {
                // Clamp to closest extent
                if (closestPoint.x > 0.0f)
                {
                    closestPoint.x = box.extents.x;
                }
                else
                {
                    closestPoint.x = -box.extents.x;
                }
            }
            // y-axis is shorter
            else if (Mathf.Abs(relativePosition.y) > Mathf.Abs(relativePosition.z))
            {
                // Clamp to closest extent
                if (closestPoint.y > 0.0f)
                {
                    closestPoint.y = box.extents.y;
                }
                else
                {
                    closestPoint.y = -box.extents.y;
                }
            }
            // z-axis is shorter
            else
            {
                // Clamp to closest extent
                if (closestPoint.z > 0.0f)
                {
                    closestPoint.z = box.extents.z;
                }
                else
                {
                    closestPoint.z = -box.extents.z;
                }
            }
        }


        Vector3 normal = sphere.transform.position - closestPoint;

        float distance = (closestPoint.x - sphere.transform.position.x) * (closestPoint.x - sphere.transform.position.x) +
                         (closestPoint.y - sphere.transform.position.y) * (closestPoint.y - sphere.transform.position.y) +
                         (closestPoint.z - sphere.transform.position.z) * (closestPoint.z - sphere.transform.position.z);


        // If no collision then return
        manifold.wasCollision = (Mathf.Sqrt(distance) < sphere.radius);
        if (manifold.wasCollision == false)
        {
            return(manifold);
        }


        distance = Mathf.Sqrt(distance);


        // Flip collision normal if inside
        if (inside == true)
        {
            manifold.normal = Vector3.Normalize(-normal);
        }
        else
        {
            manifold.normal = Vector3.Normalize(normal);
        }


        manifold.penetration = sphere.radius - distance;

        // Contact point
        manifold.contacts = new List <Vector3> ();
        manifold.contacts.Add(closestPoint);

        return(manifold);
    }