Пример #1
0
        /// <summary>
        /// Returns a list of all objects which are overlapped by the specified box.
        /// </summary>
        /// <param name="box">
        /// The box involved in the overlap query.
        /// </param>
        /// <param name="objectOverlapPrecision">
        /// The desired overlap precision. For the moment this is not used.
        /// </param>
        public List <GameObject> OverlapBox(OrientedBox box, ObjectOverlapPrecision objectOverlapPrecision = ObjectOverlapPrecision.ObjectBox)
        {
            // Retrieve all the sphere tree nodes which are overlapped by the box. If no nodes are overlapped,
            // we can return an empty list because it means that no objects could possibly be overlapped either.
            List <SphereTreeNode <GameObject> > allOverlappedNodes = _sphereTree.OverlapBox(box);

            if (allOverlappedNodes.Count == 0)
            {
                return(new List <GameObject>());
            }

            // Loop through all overlapped nodes
            var overlappedObjects = new List <GameObject>();

            foreach (SphereTreeNode <GameObject> node in allOverlappedNodes)
            {
                // Store the node's object for easy access
                GameObject gameObject = node.Data;
                if (gameObject == null)
                {
                    continue;
                }
                if (!gameObject.activeSelf)
                {
                    continue;
                }

                // We need to perform an additional check. Even though the box overlaps the object's node (which is
                // a sphere), we must also check if the box overlaps the object's world oriented box. This allows
                // for better precision.
                OrientedBox objectWorldOrientedBox = gameObject.GetWorldOrientedBox();
                if (box.Intersects(objectWorldOrientedBox))
                {
                    overlappedObjects.Add(gameObject);
                }
            }

            return(overlappedObjects);
        }
        public static bool RaycastSprite(this GameObject gameObject, Ray ray, out GameObjectRayHit objectRayHit)
        {
            objectRayHit = null;

            SpriteRenderer spriteRenderer = gameObject.GetComponent <SpriteRenderer>();

            if (spriteRenderer == null)
            {
                return(false);
            }

            OrientedBox objectWorldOrientedBox = gameObject.GetWorldOrientedBox();

            OrientedBoxRayHit objectBoxRayHit;

            if (objectWorldOrientedBox.Raycast(ray, out objectBoxRayHit))
            {
                SpriteRayHit spriteHit = new SpriteRayHit(ray, objectBoxRayHit.HitEnter, spriteRenderer, objectBoxRayHit.HitPoint, objectBoxRayHit.HitNormal);
                objectRayHit = new GameObjectRayHit(ray, gameObject, null, null, null, spriteHit);
            }

            return(objectRayHit != null);
        }
Пример #3
0
 public List <GameObject> OverlapBox(OrientedBox box, ObjectOverlapPrecision overlapPrecision = ObjectOverlapPrecision.ObjectBox)
 {
     return(_gameObjectSphereTree.OverlapBox(box, overlapPrecision));
 }
Пример #4
0
        public bool Intersects(OrientedBox otherBox)
        {
            Vector3 thisScale  = Scale;
            Vector3 otherScale = otherBox.Scale;

            // Negative scale causes problems
            Scale          = thisScale.GetVectorWithAbsComponents();
            otherBox.Scale = otherScale.GetVectorWithAbsComponents();

            Matrix4x4 transformMatrix = TransformMatrix;
            Vector3   A0 = transformMatrix.GetAxis(0);
            Vector3   A1 = transformMatrix.GetAxis(1);
            Vector3   A2 = transformMatrix.GetAxis(2);

            Vector3[] A = new Vector3[] { A0, A1, A2 };

            Matrix4x4 otherTransformMatrix = otherBox.TransformMatrix;
            Vector3   B0 = otherTransformMatrix.GetAxis(0);
            Vector3   B1 = otherTransformMatrix.GetAxis(1);
            Vector3   B2 = otherTransformMatrix.GetAxis(2);

            Vector3[] B = new Vector3[] { B0, B1, B2 };

            // Note: We're using column major matrices.
            float[,] R = new float[3, 3];
            for (int row = 0; row < 3; ++row)
            {
                for (int column = 0; column < 3; ++column)
                {
                    R[row, column] = Vector3.Dot(A[row], B[column]);
                }
            }

            Vector3 scaledExtents = ScaledExtents;
            Vector3 AEx           = new Vector3(scaledExtents.x, scaledExtents.y, scaledExtents.z);

            scaledExtents = otherBox.ScaledExtents;
            Vector3 BEx = new Vector3(scaledExtents.x, scaledExtents.y, scaledExtents.z);

            // Construct absolute rotation error matrix to account for cases when 2 local axes are parallel
            const float epsilon = 1e-4f;

            float[,] absR = new float[3, 3];
            for (int row = 0; row < 3; ++row)
            {
                for (int column = 0; column < 3; ++column)
                {
                    absR[row, column] = Mathf.Abs(R[row, column]) + epsilon;
                }
            }

            Vector3 trVector = otherBox.Center - Center;
            Vector3 t        = new Vector3(Vector3.Dot(trVector, A0), Vector3.Dot(trVector, A1), Vector3.Dot(trVector, A2));

            // Test extents projection on this box's local axes (A0, A1, A2)
            for (int axisIndex = 0; axisIndex < 3; ++axisIndex)
            {
                float bExtents = BEx[0] * absR[axisIndex, 0] + BEx[1] * absR[axisIndex, 1] + BEx[2] * absR[axisIndex, 2];
                if (Mathf.Abs(t[axisIndex]) > AEx[axisIndex] + bExtents)
                {
                    return(false);
                }
            }

            // Test extents projection on the other box's local axes (B0, B1, B2)
            for (int axisIndex = 0; axisIndex < 3; ++axisIndex)
            {
                float aExtents = AEx[0] * absR[0, axisIndex] + AEx[1] * absR[1, axisIndex] + AEx[2] * absR[2, axisIndex];
                if (Mathf.Abs(t[0] * R[0, axisIndex] +
                              t[1] * R[1, axisIndex] +
                              t[2] * R[2, axisIndex]) > aExtents + BEx[axisIndex])
                {
                    return(false);
                }
            }

            // Test axis A0 x B0
            float ra = AEx[1] * absR[2, 0] + AEx[2] * absR[1, 0];
            float rb = BEx[1] * absR[0, 2] + BEx[2] * absR[0, 1];

            if (Mathf.Abs(t[2] * R[1, 0] - t[1] * R[2, 0]) > ra + rb)
            {
                return(false);
            }

            // Test axis A0 x B1
            ra = AEx[1] * absR[2, 1] + AEx[2] * absR[1, 1];
            rb = BEx[0] * absR[0, 2] + BEx[2] * absR[0, 0];
            if (Mathf.Abs(t[2] * R[1, 1] - t[1] * R[2, 1]) > ra + rb)
            {
                return(false);
            }

            // Test axis A0 x B2
            ra = AEx[1] * absR[2, 2] + AEx[2] * absR[1, 2];
            rb = BEx[0] * absR[0, 1] + BEx[1] * absR[0, 0];
            if (Mathf.Abs(t[2] * R[1, 2] - t[1] * R[2, 2]) > ra + rb)
            {
                return(false);
            }

            // Test axis A1 x B0
            ra = AEx[0] * absR[2, 0] + AEx[2] * absR[0, 0];
            rb = BEx[1] * absR[1, 2] + BEx[2] * absR[1, 1];
            if (Mathf.Abs(t[0] * R[2, 0] - t[2] * R[0, 0]) > ra + rb)
            {
                return(false);
            }

            // Test axis A1 x B1
            ra = AEx[0] * absR[2, 1] + AEx[2] * absR[0, 1];
            rb = BEx[0] * absR[1, 2] + BEx[2] * absR[1, 0];
            if (Mathf.Abs(t[0] * R[2, 1] - t[2] * R[0, 1]) > ra + rb)
            {
                return(false);
            }

            // Test axis A1 x B2
            ra = AEx[0] * absR[2, 2] + AEx[2] * absR[0, 2];
            rb = BEx[0] * absR[1, 1] + BEx[1] * absR[1, 0];
            if (Mathf.Abs(t[0] * R[2, 2] - t[2] * R[0, 2]) > ra + rb)
            {
                return(false);
            }

            // Test axis A2 x B0
            ra = AEx[0] * absR[1, 0] + AEx[1] * absR[0, 0];
            rb = BEx[1] * absR[2, 2] + BEx[2] * absR[2, 1];
            if (Math.Abs(t[1] * R[0, 0] - t[0] * R[1, 0]) > ra + rb)
            {
                return(false);
            }

            // Test axis A2 x B1
            ra = AEx[0] * absR[1, 1] + AEx[1] * absR[0, 1];
            rb = BEx[0] * absR[2, 2] + BEx[2] * absR[2, 0];
            if (Math.Abs(t[1] * R[0, 1] - t[0] * R[1, 1]) > ra + rb)
            {
                return(false);
            }

            // Test axis A2 x B2
            ra = AEx[0] * absR[1, 2] + AEx[1] * absR[0, 2];
            rb = BEx[0] * absR[2, 1] + BEx[1] * absR[2, 0];
            if (Math.Abs(t[1] * R[0, 2] - t[0] * R[1, 2]) > ra + rb)
            {
                return(false);
            }

            Scale          = thisScale;
            otherBox.Scale = otherScale;

            return(true);
        }
Пример #5
0
        public bool OverlapsFullyOrPartially(OrientedBox orientedBox)
        {
            Vector3 closestPointToSphereCenter = orientedBox.GetClosestPointToPoint(_center);

            return((closestPointToSphereCenter - _center).sqrMagnitude <= _radius * _radius);
        }