public static CollisionInfo SphereToPlaneCollision(CollisionHull3D a, CollisionHull3D b)
    {
        // Find the relative centre by transforming the center of the circle to the local space of the AABB
        Vector3 relativeCentre = b.GetComponent <Particle3D>().invTransformMatrix.MultiplyPoint(a.GetPosition());

        Vector3 closestPointToCircle = new Vector3(Math.Max(b.GetMinimumCorner().x, Math.Min(relativeCentre.x, b.GetMaximumCorner().x)), Math.Max(b.GetMinimumCorner().y, Math.Min(relativeCentre.y, b.GetMaximumCorner().y)), Math.Max(b.GetMinimumCorner().z, Math.Min(relativeCentre.z, b.GetMaximumCorner().z)));

        // Calculate the distance between both colliders
        Vector3 distance = relativeCentre - closestPointToCircle;

        // Are the Radii less than or equal to the distance between both circles?
        if (Vector3.Dot(distance, distance) < a.GetDimensions().x *a.GetDimensions().x)
        {
            // If yes, then inform the parents of the complex shape object (if applicable)
            ReportCollisionToParent(a, b);
        }
        else
        {
            // If no, return nothing
            return(null);
        }

        float   penetration       = a.GetDimensions().x - Mathf.Sqrt(Vector3.Dot(distance, distance));
        Vector3 closestPointWorld = b.GetComponent <Particle3D>().transformMatrix.MultiplyPoint(closestPointToCircle);

        // Return result
        return(new CollisionInfo(a, b, penetration, (closestPointWorld - a.GetPosition()).normalized, Vector3.zero, CollisionResolution3D.CalculateSeparatingVelocity(a, b, a.GetPosition(), closestPointWorld)));
    }
    // This function calculate Circle to ABB collisions
    public static CollisionInfo CircleToOBBCollision(CollisionHull3D a, CollisionHull3D b)
    {
        // Find the relative centre by transforming the center of the circle to the local space of the AABB
        Vector3 relativeCentre = b.GetComponent <Particle3D>().invTransformMatrix.MultiplyPoint(a.GetPosition());

        Vector3 closestPointToCircle = new Vector3(Math.Max(b.GetMinimumCorner().x, Math.Min(relativeCentre.x, b.GetMaximumCorner().x)), Math.Max(b.GetMinimumCorner().y, Math.Min(relativeCentre.y, b.GetMaximumCorner().y)), Math.Max(b.GetMinimumCorner().z, Math.Min(relativeCentre.z, b.GetMaximumCorner().z)));

        Vector3 distance        = relativeCentre - closestPointToCircle;
        float   distanceSquared = Vector3.Dot(distance, distance);
        float   penetration     = a.GetDimensions().x - Mathf.Sqrt(distanceSquared);

        // Is the penetration a positive value
        if (penetration >= 0)
        {
            // If yes, then inform the parents of the complex shape object (if applicable)
            ReportCollisionToParent(a, b);
        }
        else
        {
            // If no, return nothing
            return(null);
        }

        // Return full details of the Collision list if the two collide
        return(new CollisionInfo(a, b, penetration, (closestPointToCircle - relativeCentre).normalized, closestPointToCircle, CollisionResolution3D.CalculateSeparatingVelocity(a, b, a.GetPosition(), b.GetPosition())));
    }
Пример #3
0
 private static CollisionInfo resolveVertexFaceBox(CollisionHull3D box1, CollisionHull3D box2, Vector3 toCenter, int bestCase, float bestOverlap, Vector3 halfExtends)
 {
     Vector3 normal = box1.GetComponent<Particle3D>().getObjectToWorld().GetColumn(bestCase);
     Vector4 tempCenter = new Vector4(toCenter.x,toCenter.y,toCenter.z);
     if(Vector4.Dot(box1.GetComponent<Particle3D>().getObjectToWorld().GetColumn(bestCase),tempCenter) > 0)
     {
         normal = normal * -1.0f;
     }
     Vector3 vertex = halfExtends;
     if (Vector4.Dot(box2.GetComponent<Particle3D>().getObjectToWorld().GetColumn(0), normal) < 0)
     {
         vertex.x = -vertex.x;
     }
     if (Vector4.Dot(box2.GetComponent<Particle3D>().getObjectToWorld().GetColumn(1), normal) < 0)
     {
         vertex.y = -vertex.y;
     }
     if (Vector4.Dot(box2.GetComponent<Particle3D>().getObjectToWorld().GetColumn(2), normal) < 0)
     {
         vertex.z = -vertex.z;
     }
     Debug.Log(vertex);
     Vector3 vertexPoint = box1.GetComponent<Particle3D>().getObjectToWorld().MultiplyPoint(vertex);
     return new CollisionInfo(box1, box2, normal, bestOverlap, vertexPoint);
 }
Пример #4
0
    static protected CollisionInfo boxTest(CollisionHull3D box1, CollisionHull3D box2, Vector3 toCenter, Vector3 box1HalfExtends, Vector3 box2HalfExtends)
    {
        List <Vector3> allAxis = new List <Vector3>();

        allAxis.Add(box1.GetComponent <Particle3D>().getObjectToWorld().GetColumn(0));
        allAxis.Add(box1.GetComponent <Particle3D>().getObjectToWorld().GetColumn(1));
        allAxis.Add(box1.GetComponent <Particle3D>().getObjectToWorld().GetColumn(2));

        allAxis.Add(box2.GetComponent <Particle3D>().getObjectToWorld().GetColumn(0));
        allAxis.Add(box2.GetComponent <Particle3D>().getObjectToWorld().GetColumn(1));
        allAxis.Add(box2.GetComponent <Particle3D>().getObjectToWorld().GetColumn(2));

        allAxis.Add(Vector3.Cross(box1.GetComponent <Particle3D>().getObjectToWorld().GetColumn(0), box2.GetComponent <Particle3D>().getObjectToWorld().GetColumn(0)));
        allAxis.Add(Vector3.Cross(box1.GetComponent <Particle3D>().getObjectToWorld().GetColumn(0), box2.GetComponent <Particle3D>().getObjectToWorld().GetColumn(1)));
        allAxis.Add(Vector3.Cross(box1.GetComponent <Particle3D>().getObjectToWorld().GetColumn(0), box2.GetComponent <Particle3D>().getObjectToWorld().GetColumn(2)));
        allAxis.Add(Vector3.Cross(box1.GetComponent <Particle3D>().getObjectToWorld().GetColumn(1), box2.GetComponent <Particle3D>().getObjectToWorld().GetColumn(0)));
        allAxis.Add(Vector3.Cross(box1.GetComponent <Particle3D>().getObjectToWorld().GetColumn(1), box2.GetComponent <Particle3D>().getObjectToWorld().GetColumn(1)));
        allAxis.Add(Vector3.Cross(box1.GetComponent <Particle3D>().getObjectToWorld().GetColumn(1), box2.GetComponent <Particle3D>().getObjectToWorld().GetColumn(2)));
        allAxis.Add(Vector3.Cross(box1.GetComponent <Particle3D>().getObjectToWorld().GetColumn(2), box2.GetComponent <Particle3D>().getObjectToWorld().GetColumn(0)));
        allAxis.Add(Vector3.Cross(box1.GetComponent <Particle3D>().getObjectToWorld().GetColumn(2), box2.GetComponent <Particle3D>().getObjectToWorld().GetColumn(1)));
        allAxis.Add(Vector3.Cross(box1.GetComponent <Particle3D>().getObjectToWorld().GetColumn(2), box2.GetComponent <Particle3D>().getObjectToWorld().GetColumn(2)));

        float   bestOverlap = float.MaxValue;
        int     bestCase    = 0; //greater than 6, edge
        Vector3 bestAxis    = Vector3.one;

        for (int i = 0; i < 15; i++)
        {
            Vector3 axis = allAxis[i];
            if (axis.sqrMagnitude < 0.001)
            {
                continue;
            }
            axis = axis.normalized;
            float overlap = penetrationOnAxis(box1, box2, axis, toCenter, box1HalfExtends, box2HalfExtends);
            if (overlap < 0)
            {
                return(null);
            }
            if (overlap < bestOverlap)
            {
                bestOverlap = overlap;
                bestCase    = i;
                bestAxis    = allAxis[bestCase];
            }
        }
        if (bestCase < 3)
        {
            return(resolveVertexFaceBox(box1, box2, toCenter, bestCase, bestOverlap));
        }
        else if (bestCase < 6)
        {
            return(resolveVertexFaceBox(box2, box1, toCenter * -1.0f, bestCase - 3, bestOverlap));
        }
        else
        {
            return(new CollisionInfo(box1, box2, bestAxis, bestOverlap));
        }
    }
Пример #5
0
 // Start is called before the first frame update
 public HullCollision3D(CollisionHull3D a, CollisionHull3D b, Vector3 contactNormal, float penetration, Vector3[] contactPoint)
 {
     this.a             = a;
     this.b             = b;
     restitution        = Mathf.Min(a.m_Restitution, b.m_Restitution);
     this.contactNormal = contactNormal;
     this.penetration   = penetration;
     this.contactPoints = contactPoint;
 }
Пример #6
0
    public static float checkAxisPenetration(CollisionHull3D a, CollisionHull3D b, Vector3 norm)
    {
        Vector2 aProjValues = a.getMinMaxProjectionValuesOnNorm(norm);
        //Debug.DrawLine(aProjValues.x * norm, aProjValues.y * norm, Color.red);
        Vector2 bProjValues = b.getMinMaxProjectionValuesOnNorm(norm);

        //Debug.DrawLine(bProjValues.x * norm, bProjValues.y * norm, Color.blue);
        return(calculateMinMaxCollisionOverlap(aProjValues, bProjValues));
    }
Пример #7
0
    private static float penetrationOnAxis(CollisionHull3D box1, CollisionHull3D box2, Vector3 axis, Vector3 toCenter, Vector3 box1HalfExtends, Vector3 box2HalfExtends)
    {
        float projectOne = transformToAxis(box1HalfExtends, box1.GetComponent<Particle3D>().getObjectToWorld(), axis);
        float projectTwo = transformToAxis(box2HalfExtends, box2.GetComponent<Particle3D>().getObjectToWorld(), axis);

        float distance = Mathf.Abs(Vector3.Dot(toCenter, axis));

        return projectOne + projectTwo - distance;
    }
    // This function checks for a collision between two objects by projecting onto a specific axis
    public static float CheckOBBAxis(CollisionHull3D shapeA, CollisionHull3D shapeB, Vector3 rotationAxis)
    {
        float one = transformToOBBAxis(shapeA, rotationAxis);
        float two = transformToOBBAxis(shapeB, rotationAxis);

        float distance = Mathf.Abs(Vector3.Dot(shapeB.GetPosition() - shapeA.GetPosition(), rotationAxis));

        return(one + two - distance);
    }
Пример #9
0
    // This function gets the seperating velocity of two particles
    public static float CalculateSeparatingVelocity(CollisionHull3D shapeA, CollisionHull3D shapeB)
    {
        // Find all required values for calculation
        Vector2 differenceOfVelocity = (shapeA.gameObject.GetComponent <Particle3D>().velocity - shapeB.gameObject.GetComponent <Particle3D>().velocity) * -1;
        Vector2 differenceOfPosition = (shapeA.GetPosition() - shapeB.GetPosition()).normalized;

        // Return the dot product of both velocity and position
        return(Vector2.Dot(differenceOfVelocity, differenceOfPosition));
    }
Пример #10
0
    static private CollisionInfo resolveVertexFaceBox(CollisionHull3D box1, CollisionHull3D box2, Vector3 toCenter, int bestCase, float bestOverlap)
    {
        Vector3 normal     = box1.GetComponent <Particle3D>().getObjectToWorld().GetColumn(bestCase);
        Vector4 tempCenter = new Vector4(toCenter.x, toCenter.y, toCenter.z);

        if (Vector4.Dot(box1.GetComponent <Particle3D>().getObjectToWorld().GetColumn(bestCase), tempCenter) > 0)
        {
            normal = normal * -1.0f;
        }
        return(new CollisionInfo(box1, box2, normal, bestOverlap));
    }
 // This function reports two sets of collision hulls to their respective parents (if possible)
 public static void ReportCollisionToParent(CollisionHull3D shapeA, CollisionHull3D shapeB)
 {
     // If yes, then inform the parents of the complex shape object (if applicable)
     if (shapeA.transform.parent != null)
     {
         //shapeA.GetComponentInParent<ParentCollisionScript3D>().ReportCollisionToParent();
     }
     if (shapeB.transform.parent != null)
     {
         //shapeB.GetComponentInParent<ParentCollisionScript3D>().ReportCollisionToParent();
     }
 }
Пример #12
0
        public CollisionInfo(CollisionHull3D shapeA, CollisionHull3D shapeB, Vector3 normal, float penetration)
        {
            RigidBodyA = shapeA.GetComponent <Particle3D>();
            ShapeA     = shapeA;

            RigidBodyB = shapeB.GetComponent <Particle3D>();
            ShapeB     = shapeB;

            RelativeVelocity = RigidBodyB.velocity - RigidBodyA.velocity;

            contacts[0].normal      = normal;
            contacts[0].penetration = penetration;
            contacts[0].restitution = Mathf.Min(RigidBodyA.restitution, RigidBodyB.restitution);
        }
Пример #13
0
    void Resolution()
    {
        foreach (HullCollision col in Collisions)
        {
            if (col.status)
            {
                CollisionHull3D.ResolveCollision(col);
            }
        }

        for (int i = 0; i < Collisions.Count; i++)
        {
            if (Collisions[i].resolved)
            {
                Collisions.RemoveAt(i);
            }
        }
    }
Пример #14
0
    public override CollisionInfo CollisionTests(CollisionHull3D other)
    {
        switch (other.hullType)
        {
        case CollisionHull3D.PhysDetect.Circle:
            return(CollisionHull3D.CircleOBB(other as CircleCollision3D, this));

        case CollisionHull3D.PhysDetect.AABB:
            return(CollisionHull3D.AABBOBB(other as AxisAllignedBoundingBoxCollision3D, this));

        case CollisionHull3D.PhysDetect.OBB:
            return(CollisionHull3D.OBBOBB(this, other as ObjectBoundingBoxCollision3D));

        default:
            break;
        }

        return(null);
    }
Пример #15
0
    public override CollisionInfo TestCollision(CollisionHull3D other)
    {
        switch (other.HullType)
        {
        case CollisionHull3D.CollisionType.Circle:
            return(CollisionHull3D.CircleVSOBB(other as CircleHull, this));

        case CollisionHull3D.CollisionType.AABB:
            return(CollisionHull3D.AABBVSOBB(other as AABBHull, this));

        case CollisionHull3D.CollisionType.OBB:
            return(CollisionHull3D.OBBVSOBB(this, other as OBBHull));

        default:
            break;
        }

        return(null);
    }
Пример #16
0
 public override HullCollision3D DetectCollision(CollisionHull3D other)
 {
     if (other is SphereHull3D)
     {
         return(DetectCollision(other as SphereHull3D, this));
     }
     else if (other is AABBHull3D)
     {
         return(DetectCollision(this, other as AABBHull3D));
     }
     else if (other is OBBHull3D)
     {
         return(DetectCollision(this, other as OBBHull3D));
     }
     else
     {
         throw new System.Exception("Sphere + " + other.GetType() + " are not compatible, add it");
     }
 }
        // This function intializes the collision info class based on given information
        public CollisionInfo(CollisionHull3D _a, CollisionHull3D _b, float _penetration, Vector3 _normal, Vector3 _contactPoint, float _seperatingVelocity)
        {
            // Is collision A's collision type have less priority to collision B?
            if (_a.collisionType > _b.collisionType)
            {
                // If yes, then switch their priorities
                a = _b;
                b = _a;
            }
            else
            {
                // If no, then keep them as so
                a = _a;
                b = _b;
            }


            // Based on collision hulls, calculate the rest of the values
            normal             = _normal;
            separatingVelocity = _seperatingVelocity;
            penetration        = _penetration;
        }
        // This function intializes the collision info class based on given information
        public CollisionInfo(CollisionHull3D _a, CollisionHull3D _b, float _penetration)
        {
            // Is collision A's collision type have less priority to collision B?
            if (_a.collisionType > _b.collisionType)
            {
                // If yes, then switch their priorities
                a = _b;
                b = _a;
            }
            else
            {
                // If no, then keep them as so
                a = _a;
                b = _b;
            }


            // Based on collision hulls, calculate the rest of the values
            normal             = (b.GetPosition() - a.GetPosition()).normalized;
            separatingVelocity = CollisionResolution3D.CalculateSeparatingVelocity(a, b, a.GetPosition(), b.GetPosition());
            penetration        = _penetration;
        }
    // This function computes circle to circle collisions
    public static CollisionInfo CircleToCircleCollision(CollisionHull3D a, CollisionHull3D b)
    {
        // Calculate the distance between both colliders
        Vector3 distance = a.GetPosition() - b.GetPosition();

        float penetration = a.GetDimensions().x + b.GetDimensions().x *(a.GetDimensions().x + b.GetDimensions().x) - Vector3.Dot(distance, distance);

        // Are the Radii less than or equal to the distance between both circles?
        if (penetration > 0)
        {
            // If yes, then inform the parents of the complex shape object (if applicable)
            ReportCollisionToParent(a, b);
        }
        else
        {
            // If no, return nothing
            return(null);
        }

        // Return result
        return(new CollisionInfo(a, b, penetration));
    }
Пример #20
0
    // return a collision instead of a bool
    // or use ref to pass a collision
    public static bool TestCollision(CollisionHull3D a, CollisionHull3D b, out Collision collision)
    {
        switch (b.type)
        {
        case CollisionHullType3D.SPHERE:
        {
            return(a.TestCollisionVsCircle((Sphere)b, out collision));
        }

        case CollisionHullType3D.AABB:
        {
            return(a.TestCollisionVsAABB((AABB)b, out collision));
        }

        case CollisionHullType3D.OBB:
        {
            return(a.TestCollisionVsOBB((OBB)b, out collision));
        }
        }
        collision = null;
        return(false);
    }
 // Update is called once per frame
 void Update()
 {
     CollisionHull3D.Collision col;
     for (int j = 0; j < collisionHulls.Count; ++j)
     {
         for (int k = j + 1; k < collisionHulls.Count; ++k)
         {
             if (collisionHulls[j] != collisionHulls[k])
             {
                 if (CollisionHull3D.TestCollision(collisionHulls[j], collisionHulls[k], out col))
                 {
                     collisionHulls[j].gameObject.GetComponent <Renderer>().material = redMaterial;
                     collisionHulls[k].gameObject.GetComponent <Renderer>().material = redMaterial;
                 }
                 else
                 {
                     collisionHulls[j].gameObject.GetComponent <Renderer>().material = normalMaterial;
                     collisionHulls[k].gameObject.GetComponent <Renderer>().material = normalMaterial;
                 }
             }
         }
     }
 }
    // This function calculates OBB to OBB colisions
    public static CollisionInfo OBBToOBBCollision(CollisionHull3D a, CollisionHull3D b)
    {
        List <float>   overlaps = new List <float>();
        List <Vector3> axes     = new List <Vector3>();

        // Get the transform values for each axis for each shape
        Vector3 x1 = a.GetComponent <Particle3D>().transformMatrix.GetColumn(0);
        Vector3 y1 = a.GetComponent <Particle3D>().transformMatrix.GetColumn(1);
        Vector3 z1 = a.GetComponent <Particle3D>().transformMatrix.GetColumn(2);

        Vector3 x2 = b.GetComponent <Particle3D>().transformMatrix.GetColumn(0);
        Vector3 y2 = b.GetComponent <Particle3D>().transformMatrix.GetColumn(1);
        Vector3 z2 = b.GetComponent <Particle3D>().transformMatrix.GetColumn(2);

        // Go through and check through all overlapping axes

        // Face/Face Object 1
        overlaps.Add(CheckOBBAxis(a, b, x1));
        axes.Add(x1);
        if (overlaps[overlaps.Count - 1] < 0)
        {
            return(null);
        }

        overlaps.Add(CheckOBBAxis(a, b, y1));
        axes.Add(y1);
        if (overlaps[overlaps.Count - 1] < 0)
        {
            return(null);
        }

        overlaps.Add(CheckOBBAxis(a, b, z1));
        axes.Add(z1);
        if (overlaps[overlaps.Count - 1] < 0)
        {
            return(null);
        }


        // Face/Face Object 2
        overlaps.Add(CheckOBBAxis(a, b, x2));
        axes.Add(x2);
        if (overlaps[overlaps.Count - 1] < 0)
        {
            return(null);
        }

        overlaps.Add(CheckOBBAxis(a, b, y2));
        axes.Add(y2);
        if (overlaps[overlaps.Count - 1] < 0)
        {
            return(null);
        }

        overlaps.Add(CheckOBBAxis(a, b, z2));
        axes.Add(z2);
        if (overlaps[overlaps.Count - 1] < 0)
        {
            return(null);
        }


        // Edge/Edge
        overlaps.Add(CheckOBBAxis(a, b, Vector3.Cross(x1, x2)));
        axes.Add(Vector3.Cross(x1, x2));
        if (overlaps[overlaps.Count - 1] < 0)
        {
            return(null);
        }

        overlaps.Add(CheckOBBAxis(a, b, Vector3.Cross(x1, y2)));
        axes.Add(Vector3.Cross(x1, y2));
        if (overlaps[overlaps.Count - 1] < 0)
        {
            return(null);
        }

        overlaps.Add(CheckOBBAxis(a, b, Vector3.Cross(x1, z2)));
        axes.Add(Vector3.Cross(x1, z2));
        if (overlaps[overlaps.Count - 1] < 0)
        {
            return(null);
        }

        overlaps.Add(CheckOBBAxis(a, b, Vector3.Cross(y1, x2)));
        axes.Add(Vector3.Cross(y1, x2));
        if (overlaps[overlaps.Count - 1] < 0)
        {
            return(null);
        }

        overlaps.Add(CheckOBBAxis(a, b, Vector3.Cross(y1, y2)));
        axes.Add(Vector3.Cross(y1, y2));
        if (overlaps[overlaps.Count - 1] < 0)
        {
            return(null);
        }

        overlaps.Add(CheckOBBAxis(a, b, Vector3.Cross(y1, z2)));
        axes.Add(Vector3.Cross(y1, z2));
        if (overlaps[overlaps.Count - 1] < 0)
        {
            return(null);
        }

        overlaps.Add(CheckOBBAxis(a, b, Vector3.Cross(z1, x2)));
        axes.Add(Vector3.Cross(z1, x2));
        if (overlaps[overlaps.Count - 1] < 0)
        {
            return(null);
        }

        overlaps.Add(CheckOBBAxis(a, b, Vector3.Cross(z1, y2)));
        axes.Add(Vector3.Cross(z1, y2));
        if (overlaps[overlaps.Count - 1] < 0)
        {
            return(null);
        }

        overlaps.Add(CheckOBBAxis(a, b, Vector3.Cross(z1, z2)));
        axes.Add(Vector3.Cross(z1, z2));
        if (overlaps[overlaps.Count - 1] < 0)
        {
            return(null);
        }

        float bestOverlap = Mathf.Infinity;
        int   bestIndex   = 0;

        for (int i = 0; i < overlaps.Count; i++)
        {
            if (overlaps[i] < bestOverlap)
            {
                bestOverlap = overlaps[i];
                bestIndex   = i;
            }
        }

        if (bestIndex > 2)
        {
            Vector3 normal = axes[bestIndex];
            Vector3 axis   = axes[bestIndex];
            if (Vector3.Dot(axis, (b.GetPosition() - a.GetPosition())) > 0)
            {
                axis *= -1;
            }

            Vector3 vertex = a.GetDimensions();

            if (Vector3.Dot(a.GetComponent <Particle3D>().transformMatrix.GetColumn(0), normal) > 0)
            {
                vertex.x = -vertex.x;
            }
            if (Vector3.Dot(a.GetComponent <Particle3D>().transformMatrix.GetColumn(1), normal) > 0)
            {
                vertex.y = -vertex.y;
            }
            if (Vector3.Dot(a.GetComponent <Particle3D>().transformMatrix.GetColumn(2), normal) > 0)
            {
                vertex.z = -vertex.z;
            }

            vertex = a.GetComponent <Particle3D>().invTransformMatrix.MultiplyPoint(vertex);

            // If all axis are overlaping, then we have a collision
            ReportCollisionToParent(a, b);
            return(new CollisionInfo(a, b, CollisionResolution.GetFinalPenetration(overlaps), normal, vertex, CollisionResolution3D.CalculateSeparatingVelocity(a, b, a.GetPosition(), b.GetPosition())));
        }
        else if (bestIndex > 5)
        {
            Vector3 normal = axes[bestIndex];
            Vector3 axis   = axes[bestIndex];
            if (Vector3.Dot(axis, (a.GetPosition() - b.GetPosition())) > 0)
            {
                axis *= -1;
            }

            Vector3 vertex = b.GetDimensions();

            if (Vector3.Dot(b.GetComponent <Particle3D>().transformMatrix.GetColumn(0), normal) > 0)
            {
                vertex.x = -vertex.x;
            }
            if (Vector3.Dot(b.GetComponent <Particle3D>().transformMatrix.GetColumn(1), normal) > 0)
            {
                vertex.y = -vertex.y;
            }
            if (Vector3.Dot(b.GetComponent <Particle3D>().transformMatrix.GetColumn(2), normal) > 0)
            {
                vertex.z = -vertex.z;
            }

            vertex = b.GetComponent <Particle3D>().invTransformMatrix.MultiplyPoint(vertex);

            // If all axis are overlaping, then we have a collision
            ReportCollisionToParent(a, b);
            return(new CollisionInfo(a, b, CollisionResolution.GetFinalPenetration(overlaps), normal, vertex, CollisionResolution3D.CalculateSeparatingVelocity(a, b, a.GetPosition(), b.GetPosition())));
        }
        else
        {
            int index    = bestIndex - 6;
            int oneIndex = index / 3;
            int twoIndex = index % 3;

            Vector3 oneAxis = axes[oneIndex];
            Vector3 twoAxis = axes[twoIndex];

            Vector3 axis = axes[bestIndex].normalized;

            if (Vector3.Dot(axis, b.GetPosition() - a.GetPosition()) > 0)
            {
                axis *= -1;
            }

            Vector3 pointOnOneEdge = a.GetDimensions();
            Vector3 pointOnTwoEdge = b.GetDimensions();

            if (oneIndex == 0)
            {
                pointOnOneEdge.x = 0;
            }
            else if (Vector2.Dot(x1, axis) > 0)
            {
                pointOnOneEdge.x = -pointOnOneEdge.x;
            }

            if (twoIndex == 3)
            {
                pointOnTwoEdge.x = 0;
            }
            else if (Vector2.Dot(x2, axis) > 0)
            {
                pointOnTwoEdge.x = -pointOnTwoEdge.x;
            }

            if (oneIndex == 1)
            {
                pointOnOneEdge.y = 0;
            }
            else if (Vector2.Dot(y1, axis) > 0)
            {
                pointOnOneEdge.y = -pointOnOneEdge.y;
            }

            if (twoIndex == 4)
            {
                pointOnTwoEdge.y = 0;
            }
            else if (Vector2.Dot(y2, axis) > 0)
            {
                pointOnTwoEdge.y = -pointOnTwoEdge.y;
            }

            if (oneIndex == 2)
            {
                pointOnOneEdge.z = 0;
            }
            else if (Vector2.Dot(z1, axis) > 0)
            {
                pointOnOneEdge.z = -pointOnOneEdge.z;
            }

            if (twoIndex == 5)
            {
                pointOnTwoEdge.z = 0;
            }
            else if (Vector2.Dot(z2, axis) > 0)
            {
                pointOnTwoEdge.z = -pointOnTwoEdge.z;
            }

            pointOnOneEdge = a.GetComponent <Particle3D>().invTransformMatrix.MultiplyPoint(pointOnOneEdge);
            pointOnTwoEdge = b.GetComponent <Particle3D>().invTransformMatrix.MultiplyPoint(pointOnTwoEdge);

            Vector3 contactPoint = GetCollisionPoint(pointOnOneEdge, oneAxis, a.GetDimensions().x, pointOnTwoEdge, twoAxis, b.GetDimensions().x, bestIndex > 2);

            ReportCollisionToParent(a, b);
            return(new CollisionInfo(a, b, CollisionResolution.GetFinalPenetration(overlaps), axis, contactPoint, CollisionResolution3D.CalculateSeparatingVelocity(a, b, a.GetPosition(), b.GetPosition())));
        }
    }
Пример #23
0
 /*struct Collision
  * {
  *  bool status;
  * }*/
 abstract public CollisionInfo CollisionTests(CollisionHull3D other);
Пример #24
0
    void NarrowCollisionCheck()
    {
        HullCollision col;

        for (int i = 0; i < Collisions.Count; i++)
        {
            col = Collisions[i];

            if (col.a.GetHullType() == CollisionHull3D.hullType.Sphere)
            {
                if (col.b.GetHullType() == CollisionHull3D.hullType.Sphere) // sphere sphere
                {
                    CollisionHull3D.SphereSphereCollision(col);
                    if (col.status)
                    {
                        col.a.gameObject.GetComponent <Renderer>().material.color = Color.green;
                        col.b.gameObject.GetComponent <Renderer>().material.color = Color.green;
                    }
                }
                else if (col.b.GetHullType() == CollisionHull3D.hullType.AABB) // sphere aabb
                {
                    CollisionHull3D.SphereAABBCollision(col);
                    if (col.status)
                    {
                        col.a.gameObject.GetComponent <Renderer>().material.color = Color.green;
                        col.b.gameObject.GetComponent <Renderer>().material.color = Color.green;
                    }
                }
                else if (col.b.GetHullType() == CollisionHull3D.hullType.OBB) // sphere obb
                {
                    CollisionHull3D.SphereOBBCollision(col);
                    if (col.status)
                    {
                        col.a.gameObject.GetComponent <Renderer>().material.color = Color.green;
                        col.b.gameObject.GetComponent <Renderer>().material.color = Color.green;
                    }
                }
            }
            else if (col.a.GetHullType() == CollisionHull3D.hullType.AABB)
            {
                if (col.b.GetHullType() == CollisionHull3D.hullType.Sphere) // aabb sphere
                {
                    CollisionHull3D.SphereAABBCollision(col);
                    if (col.status)
                    {
                        col.a.gameObject.GetComponent <Renderer>().material.color = Color.green;
                        col.b.gameObject.GetComponent <Renderer>().material.color = Color.green;
                    }
                }
                else if (col.b.GetHullType() == CollisionHull3D.hullType.AABB) // aabb aabb
                {
                    CollisionHull3D.AABBAABBCollision(col);
                    if (col.status)
                    {
                        col.a.gameObject.GetComponent <Renderer>().material.color = Color.green;
                        col.b.gameObject.GetComponent <Renderer>().material.color = Color.green;
                    }
                }

                /*
                 * else if (col.b.GetHullType() == CollisionHull3D.hullType.OBB) // aabb obb
                 * {
                 *  CollisionHull3D.AABBOBBCollision(col);
                 *  if (col.status)
                 *  {
                 *      col.a.gameObject.GetComponent<Renderer>().material.color = Color.green;
                 *      col.b.gameObject.GetComponent<Renderer>().material.color = Color.green;
                 *  }
                 * }*/
            }
            else if (col.a.GetHullType() == CollisionHull3D.hullType.OBB) //
            {
                if (col.b.GetHullType() == CollisionHull3D.hullType.Sphere)
                {
                    CollisionHull3D.SphereOBBCollision(col);
                    if (col.status)
                    {
                        col.a.gameObject.GetComponent <Renderer>().material.color = Color.green;
                        col.b.gameObject.GetComponent <Renderer>().material.color = Color.green;
                    }
                }

                /*
                 * else if (col.b.GetHullType() == CollisionHull3D.hullType.AABB)
                 * {
                 *  CollisionHull3D.AABBOBBCollision(col);
                 *  if (col.status)
                 *  {
                 *
                 *  }
                 * }
                 * else if (col.b.GetHullType() == CollisionHull3D.hullType.OBB)
                 * {
                 *  //Debug.Log("entered OBBOBB collision checker");
                 *  CollisionHull3D.OBBOBBCollision(col);
                 *  if (col.status)
                 *  {
                 *
                 *  }
                 * }*/
            }
        }
    }
Пример #25
0
 protected override bool TestCollisionVsCircle(Sphere other, out Collision collision)
 {
     return(CollisionHull3D.TestCollision(other, this, out collision));
 }
 public static float transformToOBBAxis(CollisionHull3D shape, Vector3 rotationAxis)
 {
     return(shape.GetDimensions().x *Mathf.Abs(Vector3.Dot(shape.GetComponent <Particle3D>().transformMatrix.GetColumn(0), rotationAxis)) +
            shape.GetDimensions().y *Mathf.Abs(Vector3.Dot(shape.GetComponent <Particle3D>().transformMatrix.GetColumn(1), rotationAxis)) +
            shape.GetDimensions().z *Mathf.Abs(Vector3.Dot(shape.GetComponent <Particle3D>().transformMatrix.GetColumn(2), rotationAxis)));
 }
 // Inserts a particle to the particle list
 public void InsertToParticleList(CollisionHull3D collision)
 {
     particles.Add(collision);
 }
    // This function computes AABB to AABB collisions
    public static CollisionInfo AABBToAABBCollision(CollisionHull3D a, CollisionHull3D b)
    {
        // Get the penetration values for both axes
        float penetration = 0.0f;

        // Calculate half extents along x axis for each object
        float a_extent = a.GetDimensions().x;
        float b_extent = b.GetDimensions().x;

        // Get the distance between a and b
        Vector3 n = (b.GetPosition() - a.GetPosition());

        n = new Vector3(Mathf.Abs(n.x), Mathf.Abs(n.y), Mathf.Abs(n.z));

        // Calculate overlap on x axis
        float x_overlap = a_extent + b_extent - Mathf.Abs(n.x);

        // SAT test on x axis
        if (x_overlap > 0)
        {
            // Calculate half extents along x axis for each object
            a_extent = a.GetDimensions().y;
            b_extent = b.GetDimensions().y;

            // Calculate overlap on y axis
            float y_overlap = a_extent + b_extent - Mathf.Abs(n.y);

            // SAT test on y axis
            if (y_overlap > 0)
            {
                a_extent = a.GetDimensions().z;
                b_extent = b.GetDimensions().z;

                float z_overlap = a_extent + b_extent - Mathf.Abs(n.z);

                if (z_overlap > 0)
                {
                    // Find out which axis is axis of least penetration
                    if (x_overlap > y_overlap && y_overlap < z_overlap)
                    {
                        // If it is Y, then return Y's overlap
                        penetration = y_overlap;
                    }
                    else if (x_overlap < y_overlap && x_overlap < z_overlap)
                    {
                        penetration = x_overlap;
                    }
                    else
                    {
                        // If it is Y, then return X's overlap
                        penetration = z_overlap;
                    }
                }
            }
        }

        // Do the two checks pass?
        if (penetration > 0)
        {
            // If yes, then inform the parents of the complex shape object (if applicable)
            ReportCollisionToParent(a, b);
        }
        else
        {
            // If no, return nothing
            return(null);
        }

        // Return full details of the Collision list if the two collide
        return(new CollisionInfo(a, b, penetration));
    }
 public static CollisionInfo PlaneToPlaneCollision(CollisionHull3D a, CollisionHull3D b)
 {
     return(null);
 }
Пример #30
0
 public abstract CollisionInfo TestCollision(CollisionHull3D other);