Example #1
0
        public static unsafe Result BoxSphere(BoxCollider *boxA, SphereCollider *sphereB, MTransform aFromB)
        {
            MTransform aFromBoxA        = new MTransform(boxA->Orientation, boxA->Center);
            float3     posBinA          = Mul(aFromB, sphereB->Center);
            float3     posBinBoxA       = Mul(Inverse(aFromBoxA), posBinA);
            float3     innerHalfExtents = boxA->Size * 0.5f - boxA->ConvexRadius;
            float3     normalInBoxA;
            float      distance;
            {
                // from hkAabb::signedDistanceToPoint(), can optimize a lot
                float3 projection = math.min(posBinBoxA, innerHalfExtents);
                projection = math.max(projection, -innerHalfExtents);
                float3 difference      = projection - posBinBoxA;
                float  distanceSquared = math.lengthsq(difference);

                // Check if the sphere center is inside the box
                if (distanceSquared < 1e-6f)
                {
                    float3 projectionLocal    = projection;
                    float3 absProjectionLocal = math.abs(projectionLocal);
                    float3 del  = absProjectionLocal - innerHalfExtents;
                    int    axis = IndexOfMaxComponent(new float4(del, -float.MaxValue));
                    switch (axis)
                    {
                    case 0: normalInBoxA = new float3(projectionLocal.x < 0.0f ? 1.0f : -1.0f, 0.0f, 0.0f); break;

                    case 1: normalInBoxA = new float3(0.0f, projectionLocal.y < 0.0f ? 1.0f : -1.0f, 0.0f); break;

                    case 2: normalInBoxA = new float3(0.0f, 0.0f, projectionLocal.z < 0.0f ? 1.0f : -1.0f); break;

                    default:
                        normalInBoxA = new float3(1, 0, 0);
                        Assert.IsTrue(false);
                        break;
                    }
                    distance = math.max(del.x, math.max(del.y, del.z));
                }
                else
                {
                    float invDistance = math.rsqrt(distanceSquared);
                    normalInBoxA = difference * invDistance;
                    distance     = distanceSquared * invDistance;
                }
            }

            float3 normalInA = math.mul(aFromBoxA.Rotation, normalInBoxA);

            return(new Result
            {
                NormalInA = normalInA,
                PositionOnAinA = posBinA + normalInA * (distance - boxA->ConvexRadius),
                Distance = distance - (sphereB->Radius + boxA->ConvexRadius)
            });
        }
Example #2
0
 // Create a contact point for a box and a sphere in world space.
 public static unsafe void BoxSphere(
     BoxCollider *boxA, SphereCollider *sphereB,
     MTransform worldFromA, MTransform aFromB, float maxDistance,
     out Manifold manifold)
 {
     DistanceQueries.Result convexDistance = DistanceQueries.BoxSphere(boxA, sphereB, aFromB);
     if (convexDistance.Distance < maxDistance)
     {
         manifold = new Manifold(convexDistance, worldFromA);
     }
     else
     {
         manifold = new Manifold();
     }
 }
            public unsafe void Execute(ref PhysicsCollider collider, ref LevelBorderComponent border,
                                       ref Translation translation)
            {
                // make sure we are dealing with boxes
                if (collider.ColliderPtr->Type != ColliderType.Box)
                {
                    return;
                }

                translation.Value = float3.zero;
                // tweak the physical representation of the box
                // grab the box pointer
                BoxCollider *scPtr   = (BoxCollider *)collider.ColliderPtr;
                var          box     = scPtr->Geometry;
                var          minSize = 0.1f;

                switch (border.Position)
                {
                case BorderPosition.Left:
                    box.Center = new float3(ScreenRect.xMin, ScreenRect.center.y, 0);
                    box.Size   = new float3(minSize, ScreenRect.height, minSize);
                    break;

                case BorderPosition.Right:
                    box.Center = new float3(ScreenRect.xMax, ScreenRect.center.y, 0);
                    box.Size   = new float3(minSize, ScreenRect.height, minSize);
                    break;

                case BorderPosition.Top:
                    box.Center = new float3(ScreenRect.center.x, ScreenRect.yMax, 0);
                    box.Size   = new float3(ScreenRect.width, minSize, minSize);
                    break;

                case BorderPosition.Bottom:
                    box.Center = new float3(ScreenRect.center.x, ScreenRect.yMin, 0);
                    box.Size   = new float3(ScreenRect.width, minSize, minSize);
                    break;
                }

                // update the collider geometry
                box.Orientation = quaternion.identity;
                box.BevelRadius = 0;
                scPtr->Geometry = box;
            }
Example #4
0
    protected override void OnStartRunning()
    {
        base.OnStartRunning();
        Entities
        .WithoutBurst()
        .ForEach((ref Translation topBoundaryTrans, ref PhysicsCollider collider, in TopBoundaryTag topBoundaryTag) =>
        {
            // make sure we are dealing with spheres
            if (collider.Value.Value.Type != ColliderType.Box)
            {
                return;
            }

            unsafe
            {
                // grab the sphere pointer
                BoxCollider *scPtr = (BoxCollider *)collider.ColliderPtr;

                // update the collider geometry
                var BoxGeometry  = scPtr->Geometry;
                BoxGeometry.Size = new float3(GameManager.Instance.ScreenSizeInWorldSpace.x, 0.1f, 0.1f);;
                scPtr->Geometry  = BoxGeometry;
            }

            topBoundaryTrans.Value = new float3(0, GameManager.Instance.bounds.y, 0);
        }).Run();

        Entities
        .WithoutBurst()
        .ForEach((ref Translation bottomBoundaryTrans, ref PhysicsCollider collider, in BottomBoundaryTag bottomBoundaryTag) =>
        {
            // make sure we are dealing with spheres
            if (collider.Value.Value.Type != ColliderType.Box)
            {
                return;
            }


            unsafe
            {
                // grab the sphere pointer
                BoxCollider *scPtr = (BoxCollider *)collider.ColliderPtr;

                // update the collider geometry
                var BoxGeometry  = scPtr->Geometry;
                BoxGeometry.Size = new float3(GameManager.Instance.ScreenSizeInWorldSpace.x, 0.1f, 0.1f);;
                scPtr->Geometry  = BoxGeometry;
            }

            bottomBoundaryTrans.Value = new float3(0, -GameManager.Instance.bounds.y, 0);
        }).Run();

        Entities
        .WithoutBurst()
        .ForEach((ref Translation leftBoundaryTrans, ref PhysicsCollider collider, in LeftBoundaryTag leftBoundaryTag) =>
        {
            // make sure we are dealing with spheres
            if (collider.Value.Value.Type != ColliderType.Box)
            {
                return;
            }

            unsafe
            {
                // grab the sphere pointer
                BoxCollider *scPtr = (BoxCollider *)collider.ColliderPtr;

                // update the collider geometry
                var BoxGeometry  = scPtr->Geometry;
                BoxGeometry.Size = new float3(0.1f, GameManager.Instance.ScreenSizeInWorldSpace.y, 0.1f);;
                scPtr->Geometry  = BoxGeometry;
            }

            leftBoundaryTrans.Value = new float3(-GameManager.Instance.bounds.x, 0, 0);
        }).Run();

        Entities
        .WithoutBurst()
        .ForEach((ref Translation rightBoundaryTrans, ref PhysicsCollider collider, in RightBoundaryTag rightBoundaryTag) =>
        {
            // make sure we are dealing with spheres
            if (collider.Value.Value.Type != ColliderType.Box)
            {
                return;
            }

            unsafe
            {
                // grab the sphere pointer
                BoxCollider *scPtr = (BoxCollider *)collider.ColliderPtr;

                // update the collider geometry
                var BoxGeometry  = scPtr->Geometry;
                BoxGeometry.Size = new float3(0.1f, GameManager.Instance.ScreenSizeInWorldSpace.y, 0.1f);;
                scPtr->Geometry  = BoxGeometry;
            }

            rightBoundaryTrans.Value = new float3(GameManager.Instance.bounds.x, 0, 0);
        }).Run();
    }
Example #5
0
        // Create contact points for a box and triangle in world space.
        public static unsafe void BoxTriangle(
            BoxCollider *boxA, PolygonCollider *triangleB,
            MTransform worldFromA, MTransform aFromB, float maxDistance,
            out Manifold manifold)
        {
            Assert.IsTrue(triangleB->Vertices.Length == 3);

            // Get triangle in box space
            MTransform aFromBoxA = new MTransform(boxA->Orientation, boxA->Center);
            MTransform boxAFromB = Mul(Inverse(aFromBoxA), aFromB);
            float3     t0        = Mul(boxAFromB, triangleB->ConvexHull.Vertices[0]);
            float3     t1        = Mul(boxAFromB, triangleB->ConvexHull.Vertices[1]);
            float3     t2        = Mul(boxAFromB, triangleB->ConvexHull.Vertices[2]);

            Plane  triPlane       = triangleB->ConvexHull.Planes[0];
            float3 triangleNormal = math.mul(boxAFromB.Rotation, triPlane.Normal);
            FourTransposedPoints vertsB;
            FourTransposedPoints edgesB;
            FourTransposedPoints perpsB;

            CalcTrianglePlanes(t0, t1, t2, triangleNormal, out vertsB, out edgesB, out perpsB);

            float3 halfExtents = boxA->Size * 0.5f + maxDistance;

            // find the closest minkowski plane
            float4 plane;

            {
                // Box face vs triangle vertex
                float4 planeFaceVertex;
                {
                    // get aabb of minkowski diff
                    float3 tMin = math.min(math.min(t0, t1), t2) - halfExtents;
                    float3 tMax = math.max(math.max(t0, t1), t2) + halfExtents;

                    // find the aabb face closest to the origin
                    float3 axis0 = new float3(1, 0, 0);
                    float3 axis1 = axis0.zxy; // 010
                    float3 axis2 = axis0.yzx; // 001

                    float4 planeX = SelectMaxW(new float4(axis0, -tMax.x), new float4(-axis0, tMin.x));
                    float4 planeY = SelectMaxW(new float4(axis1, -tMax.y), new float4(-axis1, tMin.y));
                    float4 planeZ = SelectMaxW(new float4(axis2, -tMax.z), new float4(-axis2, tMin.z));

                    planeFaceVertex = SelectMaxW(planeX, planeY);
                    planeFaceVertex = SelectMaxW(planeFaceVertex, planeZ);
                }

                // Box vertex vs triangle face
                float4 planeVertexFace;
                {
                    // Calculate the triangle normal
                    float triangleOffset  = math.dot(triangleNormal, t0);
                    float expansionOffset = math.dot(math.abs(triangleNormal), halfExtents);
                    planeVertexFace = SelectMaxW(
                        new float4(triangleNormal, -triangleOffset - expansionOffset),
                        new float4(-triangleNormal, triangleOffset - expansionOffset));
                }

                // Edge planes
                float4 planeEdgeEdge = new float4(0, 0, 0, -float.MaxValue);
                {
                    // Test the planes from crossing axis i with each edge of the triangle, for example if i = 1 then n0 is from (0, 1, 0) x (t1 - t0).
                    for (int i = 0, j = 1, k = 2; i < 3; j = k, k = i, i++)
                    {
                        // Normalize the cross product and flip it to point outward from the edge
                        float4 lengthsSq  = edgesB.GetComponent(j) * edgesB.GetComponent(j) + edgesB.GetComponent(k) * edgesB.GetComponent(k);
                        float4 invLengths = math.rsqrt(lengthsSq);
                        float4 dots       = edgesB.GetComponent(j) * perpsB.GetComponent(k) - edgesB.GetComponent(k) * perpsB.GetComponent(j);
                        float4 factors    = invLengths * math.sign(dots);

                        float4 nj        = -edgesB.GetComponent(k) * factors;
                        float4 nk        = edgesB.GetComponent(j) * factors;
                        float4 distances = -nj *vertsB.GetComponent(j) - nk * vertsB.GetComponent(k) - math.abs(nj) * halfExtents[j] - math.abs(nk) * halfExtents[k];

                        // If the box edge is parallel to the triangle face then skip it, the plane is redundant with a vertex-face plane
                        bool4 valid = dots != float4.zero;
                        distances = math.select(Constants.Min4F, distances, valid);

                        float3 n0   = new float3(); n0[i] = 0.0f; n0[j] = nj[0]; n0[k] = nk[0];
                        float3 n1   = new float3(); n1[i] = 0.0f; n1[j] = nj[1]; n1[k] = nk[1];
                        float3 n2   = new float3(); n2[i] = 0.0f; n2[j] = nj[2]; n2[k] = nk[2];
                        float4 temp = SelectMaxW(SelectMaxW(new float4(n0, distances.x), new float4(n1, distances.y)), new float4(n2, distances.z));
                        planeEdgeEdge = SelectMaxW(planeEdgeEdge, temp);
                    }
                }

                plane = SelectMaxW(SelectMaxW(planeFaceVertex, planeVertexFace), planeEdgeEdge);
            }

            manifold = new Manifold();

            // Check for a separating plane TODO.ma could early out as soon as any plane with w>0 is found
            if (plane.w <= 0.0f)
            {
                // Get the normal and supporting faces
                float3 normalInA = math.mul(boxA->Orientation, plane.xyz);
                manifold.Normal = math.mul(worldFromA.Rotation, normalInA);
                int faceIndexA = boxA->ConvexHull.GetSupportingFace(-normalInA);
                int faceIndexB = triangleB->ConvexHull.GetSupportingFace(math.mul(math.transpose(aFromB.Rotation), normalInA));

                // Build manifold
                if (!FaceFace(ref boxA->ConvexHull, ref triangleB->ConvexHull, faceIndexA, faceIndexB, worldFromA, aFromB, normalInA, float.MaxValue, ref manifold))
                {
                    // The closest points are vertices, we need GJK to find them
                    ConvexConvex(
                        ref ((ConvexCollider *)boxA)->ConvexHull, ref ((ConvexCollider *)triangleB)->ConvexHull,
                        worldFromA, aFromB, maxDistance, out manifold);
                }
            }
        }
Example #6
0
        // Create contact points for a pair of boxes in world space.
        public static unsafe void BoxBox(
            BoxCollider *boxA, BoxCollider *boxB,
            MTransform worldFromA, MTransform aFromB, float maxDistance,
            out Manifold manifold)
        {
            manifold = new Manifold();

            // Get transforms with box center at origin
            MTransform bFromBoxB    = new MTransform(boxB->Orientation, boxB->Center);
            MTransform aFromBoxA    = new MTransform(boxA->Orientation, boxA->Center);
            MTransform boxAFromBoxB = Mul(Inverse(aFromBoxA), Mul(aFromB, bFromBoxB));
            MTransform boxBFromBoxA = Inverse(boxAFromBoxB);

            float3 halfExtentsA = boxA->Size * 0.5f;
            float3 halfExtentsB = boxB->Size * 0.5f;

            // Test planes of each box against the other's vertices
            float3 normal; // in BoxA-space
            float  distance;

            {
                float3 normalA = new float3(1, 0, 0);
                float3 normalB = new float3(1, 0, 0);
                float  distA   = 0.0f;
                float  distB   = 0.0f;
                if (!PointPlanes(boxAFromBoxB, halfExtentsA, halfExtentsB, maxDistance, ref normalA, ref distA) ||
                    !PointPlanes(boxBFromBoxA, halfExtentsB, halfExtentsA, maxDistance, ref normalB, ref distB))
                {
                    return;
                }

                normalB = math.mul(boxAFromBoxB.Rotation, normalB);
                bool aGreater = distA > distB;
                normal   = math.select(-normalB, normalA, (bool3)aGreater);
                distance = math.select(distB, distA, aGreater);
            }

            // Test edge pairs
            {
                float3 edgeA = new float3(1.0f, 0.0f, 0.0f);
                for (int i = 0; i < 3; i++)
                {
                    for (int j = 0; j < 3; j++)
                    {
                        float3 edgeB;
                        switch (j)
                        {
                        case 0: edgeB = boxAFromBoxB.Rotation.c0; break;

                        case 1: edgeB = boxAFromBoxB.Rotation.c1; break;

                        case 2: edgeB = boxAFromBoxB.Rotation.c2; break;

                        default: edgeB = new float3(0.0f); break;
                        }
                        float3 dir = math.cross(edgeA, edgeB);

                        // hack around parallel edges
                        if (math.all(math.abs(dir) < new float3(1e-5f)))
                        {
                            continue;
                        }

                        float3 edgeNormal  = math.normalize(dir);
                        float3 supportA    = math.select(halfExtentsA, -halfExtentsA, dir < new float3(0.0f));
                        float  maxA        = math.abs(math.dot(supportA, edgeNormal));
                        float  minA        = -maxA;
                        float3 dirInB      = math.mul(boxBFromBoxA.Rotation, dir);
                        float3 supportBinB = math.select(halfExtentsB, -halfExtentsB, dirInB < new float3(0.0f));
                        float3 supportB    = math.mul(boxAFromBoxB.Rotation, supportBinB);
                        float  offsetB     = math.abs(math.dot(supportB, edgeNormal));
                        float  centerB     = math.dot(boxAFromBoxB.Translation, edgeNormal);
                        float  maxB        = centerB + offsetB;
                        float  minB        = centerB - offsetB;

                        float2 diffs = new float2(minB - maxA, minA - maxB); // positive normal, negative normal
                        if (math.all(diffs > new float2(maxDistance)))
                        {
                            return;
                        }

                        if (diffs.x > distance)
                        {
                            distance = diffs.x;
                            normal   = -edgeNormal;
                        }

                        if (diffs.y > distance)
                        {
                            distance = diffs.y;
                            normal   = edgeNormal;
                        }
                    }

                    edgeA = edgeA.zxy;
                }
            }

            if (distance < maxDistance)
            {
                // Get the normal and supporting faces
                float3 normalInA = math.mul(boxA->Orientation, normal);
                manifold.Normal = math.mul(worldFromA.Rotation, normalInA);
                int faceIndexA = boxA->ConvexHull.GetSupportingFace(-normalInA);
                int faceIndexB = boxB->ConvexHull.GetSupportingFace(math.mul(math.transpose(aFromB.Rotation), normalInA));

                // Build manifold
                if (!FaceFace(ref boxA->ConvexHull, ref boxB->ConvexHull, faceIndexA, faceIndexB, worldFromA, aFromB, normalInA, distance, ref manifold))
                {
                    // The closest points are vertices, we need GJK to find them
                    ConvexConvex(
                        ref ((ConvexCollider *)boxA)->ConvexHull, ref ((ConvexCollider *)boxB)->ConvexHull,
                        worldFromA, aFromB, maxDistance, out manifold);
                }
            }
        }
Example #7
0
        // Dispatch any pair of convex colliders
        public static unsafe Result ConvexConvex(Collider *convexA, Collider *convexB, MTransform aFromB)
        {
            Result result;
            bool   flip = false;

            switch (convexA->Type)
            {
            case ColliderType.Sphere:
                SphereCollider *sphereA = (SphereCollider *)convexA;
                switch (convexB->Type)
                {
                case ColliderType.Sphere:
                    result = SphereSphere(sphereA, (SphereCollider *)convexB, aFromB);
                    break;

                case ColliderType.Capsule:
                    CapsuleCollider *capsuleB = (CapsuleCollider *)convexB;
                    result = CapsuleSphere(capsuleB->Vertex0, capsuleB->Vertex1, capsuleB->Radius, sphereA->Center, sphereA->Radius, Inverse(aFromB));
                    flip   = true;
                    break;

                case ColliderType.Triangle:
                    PolygonCollider *triangleB = (PolygonCollider *)convexB;
                    result = TriangleSphere(
                        triangleB->Vertices[0], triangleB->Vertices[1], triangleB->Vertices[2], triangleB->Planes[0].Normal,
                        sphereA->Center, sphereA->Radius, Inverse(aFromB));
                    flip = true;
                    break;

                case ColliderType.Quad:
                    PolygonCollider *quadB = (PolygonCollider *)convexB;
                    result = QuadSphere(
                        quadB->Vertices[0], quadB->Vertices[1], quadB->Vertices[2], quadB->Vertices[3], quadB->Planes[0].Normal,
                        sphereA->Center, sphereA->Radius, Inverse(aFromB));
                    flip = true;
                    break;

                case ColliderType.Box:
                    result = BoxSphere((BoxCollider *)convexB, sphereA, Inverse(aFromB));
                    flip   = true;
                    break;

                case ColliderType.Cylinder:
                case ColliderType.Convex:
                    result = ConvexConvex(ref sphereA->ConvexHull, ref ((ConvexCollider *)convexB)->ConvexHull, aFromB);
                    break;

                default:
                    throw new NotImplementedException();
                }
                break;

            case ColliderType.Capsule:
                CapsuleCollider *capsuleA = (CapsuleCollider *)convexA;
                switch (convexB->Type)
                {
                case ColliderType.Sphere:
                    SphereCollider *sphereB = (SphereCollider *)convexB;
                    result = CapsuleSphere(capsuleA->Vertex0, capsuleA->Vertex1, capsuleA->Radius, sphereB->Center, sphereB->Radius, aFromB);
                    break;

                case ColliderType.Capsule:
                    result = CapsuleCapsule(capsuleA, (CapsuleCollider *)convexB, aFromB);
                    break;

                case ColliderType.Triangle:
                    result = CapsuleTriangle(capsuleA, (PolygonCollider *)convexB, aFromB);
                    break;

                case ColliderType.Box:
                case ColliderType.Quad:
                case ColliderType.Cylinder:
                case ColliderType.Convex:
                    result = ConvexConvex(ref capsuleA->ConvexHull, ref ((ConvexCollider *)convexB)->ConvexHull, aFromB);
                    break;

                default:
                    throw new NotImplementedException();
                }
                break;

            case ColliderType.Triangle:
                PolygonCollider *triangleA = (PolygonCollider *)convexA;
                switch (convexB->Type)
                {
                case ColliderType.Sphere:
                    SphereCollider *sphereB = (SphereCollider *)convexB;
                    result = TriangleSphere(
                        triangleA->Vertices[0], triangleA->Vertices[1], triangleA->Vertices[2], triangleA->Planes[0].Normal,
                        sphereB->Center, sphereB->Radius, aFromB);
                    break;

                case ColliderType.Capsule:
                    result = CapsuleTriangle((CapsuleCollider *)convexB, triangleA, Inverse(aFromB));
                    flip   = true;
                    break;

                case ColliderType.Box:
                case ColliderType.Triangle:
                case ColliderType.Quad:
                case ColliderType.Cylinder:
                case ColliderType.Convex:
                    result = ConvexConvex(ref triangleA->ConvexHull, ref ((ConvexCollider *)convexB)->ConvexHull, aFromB);
                    break;

                default:
                    throw new NotImplementedException();
                }
                break;

            case ColliderType.Box:
                BoxCollider *boxA = (BoxCollider *)convexA;
                switch (convexB->Type)
                {
                case ColliderType.Sphere:
                    result = BoxSphere(boxA, (SphereCollider *)convexB, aFromB);
                    break;

                case ColliderType.Capsule:
                case ColliderType.Box:
                case ColliderType.Triangle:
                case ColliderType.Quad:
                case ColliderType.Cylinder:
                case ColliderType.Convex:
                    result = ConvexConvex(ref boxA->ConvexHull, ref ((ConvexCollider *)convexB)->ConvexHull, aFromB);
                    break;

                default:
                    throw new NotImplementedException();
                }
                break;

            case ColliderType.Quad:
            case ColliderType.Cylinder:
            case ColliderType.Convex:
                result = ConvexConvex(ref ((ConvexCollider *)convexA)->ConvexHull, ref ((ConvexCollider *)convexB)->ConvexHull, aFromB);
                break;

            default:
                throw new NotImplementedException();
            }

            if (flip)
            {
                result.PositionOnAinA = Mul(aFromB, result.PositionOnBinA);
                result.NormalInA      = math.mul(aFromB.Rotation, -result.NormalInA);
            }

            return(result);
        }
            public void CollideWithSolid(Entity solidAgentEntity,
                                         Entity solidEntity,
                                         ref RigidBody solidAgentRigidBody,
                                         ref RigidBody solidRigidBody)
            {
                Translation solidAgentTranslation = TranslationGroup[solidAgentEntity];
                Rotation    solidAgentRotation    = RotationGroup[solidAgentEntity];


                Translation solidTranslation = TranslationGroup[solidEntity];
                Rotation    solidRotation    = RotationGroup[solidEntity];

                //The solid agent is guaranteed to be a solid agent.
                //We assume anything the solid agent collides with is a solid.
                //Triggers, for example, will not be triggered here - only collisions happen here

                BoxCollider *solidBoxCollider = (BoxCollider *)solidRigidBody.Collider;

                //Flatten out the translation, since the rigid body caster seems bugged?
                //TODO check into this with later updates to UnityPhysics
                BoxCollider *updatedBoxCollider = (BoxCollider *)BoxCollider.Create(
                    new BoxGeometry
                {
                    BevelRadius = solidBoxCollider->BevelRadius,
                    Center      = solidBoxCollider->Center + solidTranslation.Value,
                    Orientation = solidRotation.Value,
                    Size        = solidBoxCollider->Size
                },
                    solidBoxCollider->Filter,
                    solidBoxCollider->Material).GetUnsafePtr();

                RigidBody updatedSolidRigidBody = new RigidBody
                {
                    CustomTags    = solidRigidBody.CustomTags,
                    Collider      = (Collider *)updatedBoxCollider,
                    Entity        = solidRigidBody.Entity,
                    WorldFromBody = new RigidTransform(quaternion.identity, float3.zero)
                };

                //Collision Check
                ColliderCastInput colliderCastInput = new ColliderCastInput
                {
                    Collider    = solidAgentRigidBody.Collider,
                    Start       = solidAgentTranslation.Value,
                    End         = solidAgentTranslation.Value,
                    Orientation = solidAgentRotation.Value
                };


                ColliderCastHit colliderCastHit;
                bool            isSolidAgentCollided = updatedSolidRigidBody.CastCollider(colliderCastInput, out colliderCastHit);

                if (isSolidAgentCollided)
                {
                    bool isGroundCollided    = false;
                    bool isCeilingCollided   = false;
                    bool isLeftWallCollided  = false;
                    bool isRightWallCollided = false;

                    if (colliderCastHit.SurfaceNormal.y >= SurfaceNormalEdgeThreshold)
                    {
                        isGroundCollided = true;
                    }
                    else if (colliderCastHit.SurfaceNormal.y <= -SurfaceNormalEdgeThreshold)
                    {
                        isCeilingCollided = true;
                    }
                    else if (colliderCastHit.SurfaceNormal.x >= SurfaceNormalEdgeThreshold)
                    {
                        isLeftWallCollided = true;
                    }
                    else if (colliderCastHit.SurfaceNormal.x <= -SurfaceNormalEdgeThreshold)
                    {
                        isRightWallCollided = true;
                    }



                    if (isGroundCollided ||
                        isCeilingCollided ||
                        isLeftWallCollided ||
                        isRightWallCollided)
                    {
                        SolidAgent solidAgent = SolidAgentGroup[solidAgentEntity];

                        if (isGroundCollided)
                        {
                            solidAgent.IsGroundCollided    = true;
                            solidAgent.GroundSurfaceNormal = colliderCastHit.SurfaceNormal.y;
                        }

                        if (isCeilingCollided)
                        {
                            solidAgent.IsCeilingCollided    = true;
                            solidAgent.CeilingSurfaceNormal = colliderCastHit.SurfaceNormal.y;
                        }

                        if (isLeftWallCollided)
                        {
                            solidAgent.IsLeftWallCollided    = true;
                            solidAgent.LeftWallSurfaceNormal = colliderCastHit.SurfaceNormal.x;
                        }

                        if (isRightWallCollided)
                        {
                            solidAgent.IsRightWallCollided    = true;
                            solidAgent.RightWallSurfaceNormal = colliderCastHit.SurfaceNormal.x;
                        }

                        SolidAgentGroup[solidAgentEntity] = solidAgent;
                    }
                }
            }