/// <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); }
public List <GameObject> OverlapBox(OrientedBox box, ObjectOverlapPrecision overlapPrecision = ObjectOverlapPrecision.ObjectBox) { return(_gameObjectSphereTree.OverlapBox(box, overlapPrecision)); }
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); }
public bool OverlapsFullyOrPartially(OrientedBox orientedBox) { Vector3 closestPointToSphereCenter = orientedBox.GetClosestPointToPoint(_center); return((closestPointToSphereCenter - _center).sqrMagnitude <= _radius * _radius); }