示例#1
0
    public bool Sphere_Vs_Sphere(Sphere_Collider A, Sphere_Collider B)
    {
        Vector3 A_pos = A.transform.position;
        Vector3 B_pos = B.transform.position;

        Vector3 N = B_pos - A_pos;
        float   R = A.Radius + B.Radius;

        if (N.sqrMagnitude > R * R)
        {
            return(false);
        }

        float D = N.magnitude;

        if (D != 0)
        {
            penetration             = R - D;
            normal_point_of_contact = N / D;
            return(true);
        }
        else
        {
            penetration             = A.Radius;
            normal_point_of_contact = new Vector3(1, 0, 0);
            return(true);
        }
    }
示例#2
0
    public bool AABB_VS_Sphere(AABB_Collider AABB, Sphere_Collider Sphere)
    {
        Vector3 AABB_Position   = AABB.transform.position;
        Vector3 Sphere_Position = Sphere.transform.position;

        Vector3 N = Sphere_Position - AABB_Position;

        Vector3 closest = N;

        float x_extent = (AABB.MaxExtent.x - AABB.MinExtent.x) / 2;
        float y_extent = (AABB.MaxExtent.y - AABB.MinExtent.y) / 2;
        float z_extent = (AABB.MaxExtent.z - AABB.MinExtent.z) / 2;

        closest.x = Mathf.Clamp(closest.x, -x_extent, x_extent);
        closest.y = Mathf.Clamp(closest.y, -y_extent, y_extent);
        closest.z = Mathf.Clamp(closest.z, -z_extent, z_extent);

        bool inside = false;

        if (N == closest)
        {
            inside = true;

            if (Mathf.Abs(N.x) > Mathf.Abs(N.y) && Mathf.Abs(N.x) > Mathf.Abs(N.z))
            {
                if (closest.x > 0)
                {
                    closest.x = x_extent;
                }
                else
                {
                    closest.x = -x_extent;
                }
            }
            else if (Mathf.Abs(N.y) > Mathf.Abs(N.x) && Mathf.Abs(N.y) > Mathf.Abs(N.z))
            {
                if (closest.y > 0)
                {
                    closest.y = y_extent;
                }
                else
                {
                    closest.y = -y_extent;
                }
            }
            else
            {
                if (closest.z > 0)
                {
                    closest.z = z_extent;
                }
                else
                {
                    closest.z = -z_extent;
                }
            }
        }


        Vector3 localnormal = N - closest;
        float   D           = localnormal.sqrMagnitude;
        float   R           = Sphere.Radius;

        if (D > R * R && !inside)
        {
            return(false);
        }

        D = Mathf.Sqrt(D);

        if (inside)
        {
            normal_point_of_contact = -N;
            penetration             = R - D;
        }
        else
        {
            normal_point_of_contact = N;
            penetration             = R - D;
        }

        return(true);
    }
示例#3
0
    public void Solve_Collisions()
    {
        AABB_Collider[] boxColliders = (AABB_Collider[])GameObject.FindObjectsOfType(typeof(AABB_Collider));

        Sphere_Collider[] sphereColliders = (Sphere_Collider[])GameObject.FindObjectsOfType(typeof(Sphere_Collider));

        // Loop for checking all AABB and OBB against other AABB and OBB

        for (int i = 0; i < boxColliders.Length; i++)
        {
            AABB_Collider First_Box = boxColliders[i];

            for (int j = 1; j < boxColliders.Length; j++)
            {
                if (j > i)
                {
                    AABB_Collider Second_Box = boxColliders[j];

                    if (!(First_Box.GetComponent <My_Rigid_Body>().asleep_ == true && Second_Box.GetComponent <My_Rigid_Body>().asleep_ == true))
                    {
                        if (First_Box.GetComponent <My_Rigid_Body>().mass != 0 || Second_Box.GetComponent <My_Rigid_Body>().mass != 0 ||
                            Second_Box.GetComponent <My_Rigid_Body>().mass != 0 || First_Box.GetComponent <My_Rigid_Body>().mass != 0)
                        {
                            if (AABB_VS_AABB(First_Box, Second_Box))
                            {
                                if (OBB_to_OBB(First_Box.GetComponent <OBB_Collider>(), Second_Box.GetComponent <OBB_Collider>()))
                                {
                                    Impulse_for_Two(First_Box.GetComponent <My_Rigid_Body>(), Second_Box.GetComponent <My_Rigid_Body>());
                                }
                            }
                        }
                    }
                }
            }

            // Loop for all AABB and OBB against spheres

            for (int k = 0; k < sphereColliders.Length; k++)
            {
                Sphere_Collider Sphere = sphereColliders[k];

                if (!(First_Box.GetComponent <My_Rigid_Body>().asleep_ == true && Sphere.GetComponent <My_Rigid_Body>().asleep_ == true))
                {
                    if (AABB_VS_Sphere(First_Box, Sphere))
                    {
                        //Debug.Log("Hit");
                        Impulse_for_Two(First_Box.GetComponent <My_Rigid_Body>(), Sphere.GetComponent <My_Rigid_Body>());
                    }
                }
            }
        }

        // Loop for Sphere gainst Sphere

        for (int i = 0; i < sphereColliders.Length; i++)
        {
            Sphere_Collider sphere = sphereColliders[i];

            for (int j = 1; j < sphereColliders.Length; j++)
            {
                if (j > i)
                {
                    Sphere_Collider otherSphere = sphereColliders[j];

                    if (!(sphere.GetComponent <My_Rigid_Body>().asleep_ == true && otherSphere.GetComponent <My_Rigid_Body>().asleep_ == true))
                    {
                        if (Sphere_Vs_Sphere(sphere, otherSphere))
                        {
                            Impulse_for_Two(sphere.GetComponent <My_Rigid_Body>(), otherSphere.GetComponent <My_Rigid_Body>());
                        }
                    }
                }
            }
        }
    }