Exemple #1
0
        private static bool IsSeparated(ref BurstBoxCollider a, ref BurstBoxCollider b, Vector3 axis)
        {
            // Handles the cross product = {0,0,0} case
            if (axis == Vector3.zero)
            {
                return(false);
            }

            var aMin = float.MaxValue;
            var aMax = float.MinValue;
            var bMin = float.MaxValue;
            var bMax = float.MinValue;

            // For each vertex combination >>

            CalculateMinMax(axis, a.V1, b.V1, ref aMin, ref aMax, ref bMin, ref bMax);
            CalculateMinMax(axis, a.V2, b.V2, ref aMin, ref aMax, ref bMin, ref bMax);
            CalculateMinMax(axis, a.V3, b.V3, ref aMin, ref aMax, ref bMin, ref bMax);
            CalculateMinMax(axis, a.V4, b.V4, ref aMin, ref aMax, ref bMin, ref bMax);
            CalculateMinMax(axis, a.V5, b.V5, ref aMin, ref aMax, ref bMin, ref bMax);
            CalculateMinMax(axis, a.V6, b.V6, ref aMin, ref aMax, ref bMin, ref bMax);
            CalculateMinMax(axis, a.V7, b.V7, ref aMin, ref aMax, ref bMin, ref bMax);
            CalculateMinMax(axis, a.V8, b.V8, ref aMin, ref aMax, ref bMin, ref bMax);

            // One-dimensional intersection test between a and b
            var longSpan = Mathf.Max(aMax, bMax) - Mathf.Min(aMin, bMin);
            var sumSpan  = aMax - aMin + bMax - bMin;

            return(longSpan >= sumSpan); // > to treat touching as intersection
        }
Exemple #2
0
        private static BurstBoxCollider BurstBoxCollider(Vector3 center, Vector3 size, Quaternion rotation, float4x4 matrix)
        {
            var max = size * 0.5f;
            var min = -max;

            var box = new BurstBoxCollider
            {
                Bounds        = new Bounds(center, size),
                Center        = center,
                Right         = rotation * Vector3.right,
                Up            = rotation * Vector3.up,
                Forward       = rotation * Vector3.forward,
                Max           = max,
                Min           = min,
                ToWorldMatrix = matrix,
                ToLocalMatrix = math.inverse(matrix),

                V1 = center + rotation * min,
                V2 = center + rotation * new Vector3(max.x, min.y, min.z),
                V3 = center + rotation * new Vector3(min.x, max.y, min.z),
                V4 = center + rotation * new Vector3(max.x, max.y, min.z),
                V5 = center + rotation * new Vector3(min.x, min.y, max.z),
                V6 = center + rotation * new Vector3(max.x, min.y, max.z),
                V7 = center + rotation * new Vector3(min.x, max.y, max.z),
                V8 = center + rotation * max,
            };

            box.UpdateBounds();
            return(box);
        }
Exemple #3
0
        public static bool BoxSphereIntersects(BurstBoxCollider box, BurstSphereCollider b, out IntersectionInfo info)
        {
            info = new IntersectionInfo();

            var closest         = box.ClosestPosition(b.Center);
            var distToClosest   = Vector3.Distance(b.Center, closest);
            var gapDistance     = distToClosest - b.Radius;
            var centerToClosest = closest - b.Center;
            var overlapVector   = (b.Radius - distToClosest) * centerToClosest.normalized;

            info.GapDistance    = gapDistance;
            info.IsIntersecting = gapDistance <= 0 ? 1 : 0;
            info.PointOnB       = closest + overlapVector;
            info.PointOnA       = closest;

            if (gapDistance <= 0)
            {
                info.PenetrationDirection = overlapVector;
                info.PenetrationDistance  = overlapVector.magnitude;
                return(true);
            }

            info.GapDirection = overlapVector;
            return(false);
        }
Exemple #4
0
        public static bool BoxSphereIntersects(BurstBoxCollider box, BurstSphereCollider sphere)
        {
            var closestPosition = box.ClosestPosition(sphere.Center + sphere.Offset);
            var distance        = Vector3.Distance(sphere.Center + sphere.Offset, closestPosition);

            return(distance - sphere.Radius * sphere.Scale <= 0);
        }
        public static Vector3 ClosestPosition(this BurstBoxCollider box, Vector3 worldPosition, float4x4 toLocal)
        {
            var localPosition = math.transform(toLocal, worldPosition);
            var closest       = box.ClosestLocalPosition(localPosition);

            return(math.transform(math.inverse(box.ToWorldMatrix), closest));
        }
        public static Vector3 ClosestPosition(this BurstBoxCollider box, Vector3 worldPosition, float4x4 toLocal, float4x4 toWorld)
        {
            var localSphereCenter = math.transform(toLocal, worldPosition);
            var closest           = box.ClosestLocalPosition(localSphereCenter);

            return(math.transform(toWorld, closest));
        }
        public static bool Contains(this BurstBoxCollider box, Vector3 worldPosition, float4x4 matrix)
        {
            var localPosition = math.transform(matrix, worldPosition);

            return(localPosition.x > box.Min.x && localPosition.x < box.Max.x &&
                   localPosition.y > box.Min.y && localPosition.y < box.Max.y &&
                   localPosition.z > box.Min.z && localPosition.z < box.Max.z);
        }
        public static bool Contains(this BurstBoxCollider box, Vector3 worldPosition)
        {
            var localPosition = box.GetLocalPosition(worldPosition);

            return(localPosition.x > box.Min.x && localPosition.x < box.Max.x &&
                   localPosition.y > box.Min.y && localPosition.y < box.Max.y &&
                   localPosition.z > box.Min.z && localPosition.z < box.Max.z);
        }
        private static Vector3 ClosestLocalPosition(this BurstBoxCollider box, float3 localPosition)
        {
            var closestX = Mathf.Max(box.Min.x, Mathf.Min(localPosition.x, box.Max.x));
            var closestY = Mathf.Max(box.Min.y, Mathf.Min(localPosition.y, box.Max.y));
            var closestZ = Mathf.Max(box.Min.z, Mathf.Min(localPosition.z, box.Max.z));
            var closest  = new Vector3(closestX, closestY, closestZ);

            return(closest);
        }
Exemple #10
0
        public void Update(Collider collider)
        {
            if (collider is SphereCollider sphere)
            {
                Sphere = BurstColliderFactory.CreateSphere(sphere);
            }

            if (collider is BoxCollider box)
            {
                Box = BurstColliderFactory.CreateBox(box);
            }
        }
 public static void UpdateBounds(this BurstBoxCollider box)
 {
     box.Bounds = new Bounds();
     box.Bounds.Encapsulate(box.V1);
     box.Bounds.Encapsulate(box.V2);
     box.Bounds.Encapsulate(box.V3);
     box.Bounds.Encapsulate(box.V4);
     box.Bounds.Encapsulate(box.V5);
     box.Bounds.Encapsulate(box.V6);
     box.Bounds.Encapsulate(box.V7);
     box.Bounds.Encapsulate(box.V8);
 }
Exemple #12
0
        //public class ConvexPolyhedron
        //{
        //    public Face[] Faces;
        //    public Vector3[] Vertices;
        //    public Vector3[] Edges;

        //    public class Face
        //    {
        //        public Vector3 Normal;
        //        public Vector3 Vertex;
        //    }

        //    //public class Edge
        //    //{

        //    //}
        //}

        //public static bool Intersects(ConvexPolyhedron C0, ConvexPolyhedron C1)
        //{
        //    if (IsFaceSeparation(C0, C1))
        //        return false;

        //    if (IsFaceSeparation(C1, C0))
        //        return false;

        //    for (int i = 0; i < C0.Edges.Length; i++)
        //    {
        //        for (int j = 0; j < C1.Edges.Length; j++)
        //        {
        //            var edgePoint0 = C0.Edges[i];
        //            var edgePoint1 = C1.Edges[j];

        //            var axis = Vector3.Cross(edgePoint0, edgePoint1);

        //            var side0 = WhichSide(C0.Vertices, axis, edgePoint0);
        //            if (side0 == 0)
        //            {
        //                continue;
        //            }

        //            var side1 = WhichSide(C1.Vertices, axis, edgePoint0);
        //            if (side1 == 0)
        //            {
        //                continue;
        //            }

        //            if (side0 * side1 < 0)
        //            {
        //                return false;
        //            }
        //        }
        //    }
        //}

        //private static bool IsFaceSeparation(ConvexPolyhedron C0, ConvexPolyhedron C1)
        //{
        //    for (int i = 0; i < C0.Faces.Length; i++)
        //    {
        //        var normal = C0.Faces[i].Normal;
        //        var vertex = C0.Faces[i].Vertex;
        //        if (WhichSide(C1.Vertices, normal, vertex) > 0)
        //        {
        //            return true;
        //        }
        //    }
        //    return false;
        //}

        //public static int WhichSide(Vector3[] vertices, Vector3 d, Vector3 p)
        //{
        //    var positive = 0;
        //    var negative = 0;
        //    for (int i = 0; i < C.N; i++)
        //    {
        //        var t = Vector3.Dot(d, vertices[i] - p);
        //        if (t > 0) positive++;
        //        else if (t < 0) negative++;
        //        if (positive == 0 && negative == 0) return 0;
        //    }
        //    return positive == 0 ? 0 : positive > 0 ? 1 : -1;
        //}

        public static bool BoxBoxIntersects(BurstBoxCollider a, BurstBoxCollider b)
        {
            // For each Axis/Normal project and check for separation

            // Source https://gamedev.stackexchange.com/questions/44500/how-many-and-which-axes-to-use-for-3d-obb-collision-with-sat

            if (IsSeparated(ref a, ref b, a.Right))
            {
                return(false);
            }
            if (IsSeparated(ref a, ref b, a.Up))
            {
                return(false);
            }
            if (IsSeparated(ref a, ref b, a.Forward))
            {
                return(false);
            }
            if (IsSeparated(ref a, ref b, b.Right))
            {
                return(false);
            }
            if (IsSeparated(ref a, ref b, b.Up))
            {
                return(false);
            }
            if (IsSeparated(ref a, ref b, b.Forward))
            {
                return(false);
            }

            if (IsSeparated(ref a, ref b, Vector3.Cross(a.Right, b.Right)))
            {
                return(false);
            }
            if (IsSeparated(ref a, ref b, Vector3.Cross(a.Right, b.Up)))
            {
                return(false);
            }
            if (IsSeparated(ref a, ref b, Vector3.Cross(a.Right, b.Forward)))
            {
                return(false);
            }
            if (IsSeparated(ref a, ref b, Vector3.Cross(a.Up, b.Right)))
            {
                return(false);
            }
            if (IsSeparated(ref a, ref b, Vector3.Cross(a.Up, b.Up)))
            {
                return(false);
            }
            if (IsSeparated(ref a, ref b, Vector3.Cross(a.Up, b.Forward)))
            {
                return(false);
            }
            if (IsSeparated(ref a, ref b, Vector3.Cross(a.Forward, b.Right)))
            {
                return(false);
            }
            if (IsSeparated(ref a, ref b, Vector3.Cross(a.Forward, b.Up)))
            {
                return(false);
            }
            if (IsSeparated(ref a, ref b, Vector3.Cross(a.Forward, b.Forward)))
            {
                return(false);
            }

            return(true);
        }
 public static Vector3 GetWorldPosition(this BurstBoxCollider box, Vector3 localPosition)
 {
     return(math.transform(box.ToWorldMatrix, localPosition));
 }
 public static Vector3 ClosestPosition(this BurstBoxCollider box, Vector3 worldPosition)
 {
     return(ClosestPosition(box, worldPosition, box.ToLocalMatrix, box.ToWorldMatrix));
 }
 public static BurstBaseCollider ToBaseCollider(this BurstBoxCollider box) => new BurstBaseCollider
 {
     Type = BurstColliderType.Box,
     Box  = box
 };