예제 #1
0
        public CollisionInfo(ObjectBoundingBoxCollision3D colA, AxisAllignedBoundingBoxCollision3D colB, Vector3 normal, float penetration)
        {
            RigidBodyA = colA.GetComponent <Particle3D>();
            RigidBodyB = colB.GetComponent <Particle3D>();


            RelativeVelocity = RigidBodyB.velocity - RigidBodyA.velocity;

            contacts[0].normal      = normal;
            contacts[0].penetration = penetration;
            contacts[0].restitution = Mathf.Min(RigidBodyA.restitution, RigidBodyB.restitution);
        }
예제 #2
0
    static public CollisionInfo CircleAABB(CircleCollision3D circle, AxisAllignedBoundingBoxCollision3D rect)
    {
        //Vector3 halfExtend = (rect.posMax - rect.posMin) / 2;

        // clamp(value, min, max) - limits value to the range min..max
        Vector3 circleBox = new Vector3(
            Mathf.Max(rect.posMin.x + rect.center.x, Mathf.Min(circle.center.x, rect.posMax.x + rect.center.x)),
            Mathf.Max(rect.posMin.y + rect.center.y, Mathf.Min(circle.center.y, rect.posMax.y + rect.center.y)),
            Mathf.Max(rect.posMin.z + rect.center.z, Mathf.Min(circle.center.z, rect.posMax.z + rect.center.z)));
        // Find the closest point to the circle within the rectangle
        float closestX = Mathf.Clamp(circle.center.x, -rect.halfExtends.x, rect.halfExtends.x);
        float closestY = Mathf.Clamp(circle.center.y, -rect.halfExtends.y, rect.halfExtends.y);
        float closestZ = Mathf.Clamp(circle.center.z, -rect.halfExtends.z, rect.halfExtends.z);

        Vector3 closestPoint = new Vector3(closestX, closestY, closestZ);

        // Calculate the distance between the circle's center and this closest point
        //float distanceX = circle.center.x - closestX;
        //float distanceY = circle.center.y - closestY;
        //float distanceZ = circle.center.z - closestZ;
        Vector3 disVec = circle.center - circleBox;

        //Vector3 distanceComplete = closestPoint - closestPoint; //possibly change to circle vox
        // If the distance is less than the circle's radius, an intersection occurs
        //float distSq = Vector3.Dot(distanceComplete, distanceComplete);
        float distSq = Vector3.Dot(disVec, disVec);

        //float distanceSquared = (distanceX * distanceX) + (distanceY * distanceY) + (distanceZ * distanceZ);
        float distance = Mathf.Sqrt(distSq);

        //Debug.DrawLine(closestPoint, circle.center);

        if (distSq <= (circle.radius * circle.radius))
        {
            //Debug.Log("square circ collision)");
            //return new CollisionInfo(circle, rect, -distanceComplete.normalized, circle.radius - distance);
            return(new CollisionInfo(circle, rect, -disVec.normalized, circle.radius - distance));
        }
        return(null);
        //return distanceSquared < (circle.radius * circle.radius);
    }
예제 #3
0
    static public CollisionInfo AABBAABB(AxisAllignedBoundingBoxCollision3D colA, AxisAllignedBoundingBoxCollision3D colB)
    {
        //test if max0>=min1 and max1>=min0
        Vector3 distance  = colB.center - colA.center;
        float   x_overlap = colA.halfExtends.x + colB.halfExtends.x - Mathf.Abs(distance.x);

        if (x_overlap > 0.0f)
        {
            float y_overlap = colA.halfExtends.y + colB.halfExtends.y - Mathf.Abs(distance.y);
            if (y_overlap > 0.0f)
            {
                float z_overlap = colA.halfExtends.z + colB.halfExtends.z - Mathf.Abs(distance.z);
                if (z_overlap > 0.0f)
                {
                    float minOverlap = Mathf.Min(x_overlap, y_overlap, z_overlap);
                    if (minOverlap == x_overlap)
                    {
                        //Debug.Log("Square square collision");
                        return(new CollisionInfo(colA, colB, distance.x < 0.0f ? -Vector3.right : Vector3.right, x_overlap));
                    }
                    else if (minOverlap == y_overlap)
                    {
                        //Debug.Log("Square square collision");

                        return(new CollisionInfo(colA, colB, distance.y < 0.0f ? -Vector3.up : Vector3.up, y_overlap));
                    }
                    else if (minOverlap == z_overlap)
                    {
                        //Debug.Log("Square square collision");

                        return(new CollisionInfo(colA, colB, distance.z < 0.0f ? -Vector3.forward : Vector3.forward, z_overlap));
                    }
                }
            }
        }


        return(null);
    }
예제 #4
0
    static public CollisionInfo AABBOBB(AxisAllignedBoundingBoxCollision3D colA, ObjectBoundingBoxCollision3D colB)
    {
        List <Vector3> allAxis = new List <Vector3>();

        allAxis.AddRange(colA.normAxis);
        allAxis.AddRange(colB.normAxis);

        foreach (var axis in allAxis)
        {
            float AABBMin = float.MaxValue;
            float AABBMax = float.MinValue;

            foreach (var vert in colA.verticeCheck)
            {
                float dotValue = (vert.x * axis.x + vert.y * axis.y);
                if (dotValue < AABBMin)
                {
                    AABBMin = dotValue;
                }
                if (dotValue > AABBMax)
                {
                    AABBMax = dotValue;
                }
            }

            float OBBMin = float.MaxValue;
            float OBBMax = float.MinValue;
            foreach (var vert in colB.verticeCheck)
            {
                float dotValue = (vert.x * axis.x + vert.y * axis.y);
                if (dotValue < OBBMin)
                {
                    OBBMin = dotValue;
                }
                if (dotValue > OBBMax)
                {
                    OBBMax = dotValue;
                }
            }

            if (!(AABBMax < OBBMin && OBBMax < AABBMin))
            {
                Vector3 AtoB      = colB.center - colA.center;
                float   x_overlap = colA.halfExtends.x + colB.halfExtends.x - Mathf.Abs(AtoB.x);

                if (x_overlap > 0.0f)
                {
                    float y_overlap = colA.halfExtends.y + colB.halfExtends.y - Mathf.Abs(AtoB.y);
                    if (y_overlap > 0.0f)
                    {
                        if (x_overlap < y_overlap)
                        {
                            //Debug.Log("ABB OBB");
                            return(new CollisionInfo(colA, colB, AtoB.x < 0.0f ? -Vector3.right : Vector3.right, x_overlap));
                        }
                        else
                        {
                            //Debug.Log("ABB OBB");
                            return(new CollisionInfo(colA, colB, AtoB.y < 0.0f ? -Vector3.up : Vector3.up, y_overlap));
                        }
                    }
                }
            }
        }
        return(null);
    }