public static bool Intersects(this Bounds bounds1, Matrix4x4 localToWorld1, Matrix4x4 worldToLocal1, Bounds bounds2, Matrix4x4 localToWorld2, Matrix4x4 worldToLocal2) { //Matrix4x4 worldToLocal1 = Matrix4x4.Inverse(localToWorld1); //Matrix4x4 worldToLocal2 = Matrix4x4.Inverse(localToWorld2); Vector3[] bounds1Points = worldToLocal2.MultiplyPoints(localToWorld1.MultiplyPoints(bounds1.EnumeratePoints())).ToArray(); Vector3[] bounds2Points = worldToLocal1.MultiplyPoints(localToWorld2.MultiplyPoints(bounds2.EnumeratePoints())).ToArray(); // This is redundant, because this will return true in a subset of cases // with edge intersections, but Unity's methods are not in C# and might be faster. // Requires profiling. if (bounds1.ContainsAny(bounds2Points) || bounds2.ContainsAny(bounds1Points)) { return(true); } Func <Vector3, Vector3, Bounds, bool> edgeIntersectsBounds = (point1, point2, bounds) => { Ray ray = new Ray(point1, point2 - point1); if (!bounds.IntersectRay(ray)) { return(false); } return(true); /* * ray.origin = point2; * ray.direction = -ray.direction; * return bounds.IntersectRay(ray);*/ }; Func <Vector3[], Bounds, bool> pointsContainIntersectingEdge = (points, bounds) => { for (int i = 0; i < points.Length - 1; i++) { if (points.Skip(i + 1).Any(p => edgeIntersectsBounds(points[i], p, bounds))) { return(true); } } return(false); }; return(pointsContainIntersectingEdge(bounds2Points, bounds1) || pointsContainIntersectingEdge(bounds1Points, bounds2)); }
public static bool Intersects(this Bounds bounds1, Transform transform1, Bounds bounds2, Transform transform2) { Vector3[] bounds1Points = transform2.InverseTransformPoints(bounds1.EnumeratePoints(), transform1).ToArray(); Vector3[] bounds2Points = transform1.InverseTransformPoints(bounds2.EnumeratePoints(), transform2).ToArray(); if (bounds1.ContainsAny(bounds2Points) || bounds2.ContainsAny(bounds1Points)) { return(true); } Func <Vector3, Vector3, Bounds, bool> edgeIntersectsBounds = (point1, point2, bounds) => { Ray ray = new Ray(point1, point2 - point1); if (!bounds.IntersectRay(ray)) { return(false); } // return true; ray.origin = point2; ray.direction = -ray.direction; return(bounds.IntersectRay(ray)); }; Func <Vector3[], Bounds, bool> pointsContainIntersectingEdge = (points, bounds) => { for (int i = 0; i < points.Length - 1; i++) { if (points.Skip(i + 1).Any(p => edgeIntersectsBounds(points[i], p, bounds))) { return(true); } } return(false); }; return(pointsContainIntersectingEdge(bounds2Points, bounds1) || pointsContainIntersectingEdge(bounds1Points, bounds2)); }