/// <summary> /// Do the two rectangular prisms (defined by a center, size and rotation) overlap? /// </summary> /// <param name="r1Center"></param> /// <param name="r1Extents"></param> /// <param name="r1Rot"></param> /// <param name="r2Center"></param> /// <param name="r2Extents"></param> /// <param name="r2Rot"></param> /// <returns></returns> public static bool RectangularPrismOverlaps(Vector3 r1Center, Vector3 r1Extents, Quaternion r1Rot, Vector3 r2Center, Vector3 r2Extents, Quaternion r2Rot) { var invRot = Quaternion.Inverse(r1Rot); var invRot2 = Quaternion.Inverse(r2Rot); var axisBounds = new Bounds(invRot * r1Center, r1Extents * 2); var invRotB = new RotationalBounds(axisBounds.center + invRot * (r1Center - r2Center), r2Extents * 2, invRot * r2Rot); #if CUSTOMDEBUG DebugHelper.DrawCube(axisBounds.center, axisBounds.extents, Quaternion.identity, Color.gray, 0); DebugHelper.DrawCube(invRotB.center, invRotB.extents, invRotB.rotation, Color.gray, 0); #endif if (axisBounds.Contains(invRotB.center + invRotB.rotation * new Vector3(invRotB.extents.x, invRotB.extents.y, invRotB.extents.z)) || axisBounds.Contains(invRotB.center + invRotB.rotation * new Vector3(invRotB.extents.x, -invRotB.extents.y, invRotB.extents.z)) || axisBounds.Contains(invRotB.center + invRotB.rotation * new Vector3(invRotB.extents.x, invRotB.extents.y, -invRotB.extents.z)) || axisBounds.Contains(invRotB.center + invRotB.rotation * new Vector3(invRotB.extents.x, -invRotB.extents.y, -invRotB.extents.z)) || axisBounds.Contains(invRotB.center + invRotB.rotation * new Vector3(-invRotB.extents.x, invRotB.extents.y, invRotB.extents.z)) || axisBounds.Contains(invRotB.center + invRotB.rotation * new Vector3(-invRotB.extents.x, -invRotB.extents.y, invRotB.extents.z)) || axisBounds.Contains(invRotB.center + invRotB.rotation * new Vector3(-invRotB.extents.x, invRotB.extents.y, -invRotB.extents.z)) || axisBounds.Contains(invRotB.center + invRotB.rotation * new Vector3(-invRotB.extents.x, -invRotB.extents.y, -invRotB.extents.z))) { return(true); } invRotB.ReduceToTriangles(_triangleCache); // Test x-axis aligned cube var xzRect = new Rect(axisBounds.min.xz(), axisBounds.size.xz()); #if CUSTOMDEBUG DebugHelper.DrawCube(new Vector3(xzRect.center.x, 0, xzRect.center.y), new Vector3(xzRect.width / 2, 0, xzRect.height / 2), Quaternion.identity, Color.black, 0); #endif if (!OverlapUtilites2D.TriangleOverlapsRect(_triangleCache[0].p1.xz(), _triangleCache[0].p2.xz(), _triangleCache[0].p3.xz(), xzRect) && !OverlapUtilites2D.TriangleOverlapsRect(_triangleCache[1].p1.xz(), _triangleCache[1].p2.xz(), _triangleCache[1].p3.xz(), xzRect) && !OverlapUtilites2D.TriangleOverlapsRect(_triangleCache[2].p1.xz(), _triangleCache[2].p2.xz(), _triangleCache[2].p3.xz(), xzRect) && !OverlapUtilites2D.TriangleOverlapsRect(_triangleCache[3].p1.xz(), _triangleCache[3].p2.xz(), _triangleCache[3].p3.xz(), xzRect) && !OverlapUtilites2D.TriangleOverlapsRect(_triangleCache[4].p1.xz(), _triangleCache[4].p2.xz(), _triangleCache[4].p3.xz(), xzRect) && !OverlapUtilites2D.TriangleOverlapsRect(_triangleCache[5].p1.xz(), _triangleCache[5].p2.xz(), _triangleCache[5].p3.xz(), xzRect) && !OverlapUtilites2D.TriangleOverlapsRect(_triangleCache[6].p1.xz(), _triangleCache[6].p2.xz(), _triangleCache[6].p3.xz(), xzRect) && !OverlapUtilites2D.TriangleOverlapsRect(_triangleCache[7].p1.xz(), _triangleCache[7].p2.xz(), _triangleCache[7].p3.xz(), xzRect) && !OverlapUtilites2D.TriangleOverlapsRect(_triangleCache[8].p1.xz(), _triangleCache[8].p2.xz(), _triangleCache[8].p3.xz(), xzRect) && !OverlapUtilites2D.TriangleOverlapsRect(_triangleCache[9].p1.xz(), _triangleCache[0].p2.xz(), _triangleCache[9].p3.xz(), xzRect) && !OverlapUtilites2D.TriangleOverlapsRect(_triangleCache[10].p1.xz(), _triangleCache[10].p2.xz(), _triangleCache[10].p3.xz(), xzRect) && !OverlapUtilites2D.TriangleOverlapsRect(_triangleCache[11].p1.xz(), _triangleCache[11].p2.xz(), _triangleCache[11].p3.xz(), xzRect)) { #if CUSTOMDEBUG foreach (var triangle in _triangleCache) { Debug.DrawLine(triangle.p1.x0z(), triangle.p2.x0z(), Color.red); Debug.DrawLine(triangle.p2.x0z(), triangle.p3.x0z(), Color.red); Debug.DrawLine(triangle.p3.x0z(), triangle.p1.x0z(), Color.red); } #endif return(false); } #if CUSTOMDEBUG else { foreach (var triangle in _triangleCache) { Debug.DrawLine(triangle.p1.x0z(), triangle.p2.x0z(), Color.green); Debug.DrawLine(triangle.p2.x0z(), triangle.p3.x0z(), Color.green); Debug.DrawLine(triangle.p3.x0z(), triangle.p1.x0z(), Color.green); } } #endif var xyRect = new Rect(axisBounds.min.xy(), axisBounds.size.xy()); #if CUSTOMDEBUG DebugHelper.DrawCube(new Vector3(xyRect.center.x, xyRect.center.y, 0), new Vector3(xyRect.width / 2, xyRect.height / 2, 0), Quaternion.identity, Color.black, 0); #endif if (!OverlapUtilites2D.TriangleOverlapsRect(_triangleCache[0].p1.xy(), _triangleCache[0].p2.xy(), _triangleCache[0].p3.xy(), xyRect) && !OverlapUtilites2D.TriangleOverlapsRect(_triangleCache[1].p1.xy(), _triangleCache[1].p2.xy(), _triangleCache[1].p3.xy(), xyRect) && !OverlapUtilites2D.TriangleOverlapsRect(_triangleCache[2].p1.xy(), _triangleCache[2].p2.xy(), _triangleCache[2].p3.xy(), xyRect) && !OverlapUtilites2D.TriangleOverlapsRect(_triangleCache[3].p1.xy(), _triangleCache[3].p2.xy(), _triangleCache[3].p3.xy(), xyRect) && !OverlapUtilites2D.TriangleOverlapsRect(_triangleCache[4].p1.xy(), _triangleCache[4].p2.xy(), _triangleCache[4].p3.xy(), xyRect) && !OverlapUtilites2D.TriangleOverlapsRect(_triangleCache[5].p1.xy(), _triangleCache[5].p2.xy(), _triangleCache[5].p3.xy(), xyRect) && !OverlapUtilites2D.TriangleOverlapsRect(_triangleCache[6].p1.xy(), _triangleCache[6].p2.xy(), _triangleCache[6].p3.xy(), xyRect) && !OverlapUtilites2D.TriangleOverlapsRect(_triangleCache[7].p1.xy(), _triangleCache[7].p2.xy(), _triangleCache[7].p3.xy(), xyRect) && !OverlapUtilites2D.TriangleOverlapsRect(_triangleCache[8].p1.xy(), _triangleCache[8].p2.xy(), _triangleCache[8].p3.xy(), xyRect) && !OverlapUtilites2D.TriangleOverlapsRect(_triangleCache[9].p1.xy(), _triangleCache[0].p2.xy(), _triangleCache[9].p3.xy(), xyRect) && !OverlapUtilites2D.TriangleOverlapsRect(_triangleCache[10].p1.xy(), _triangleCache[10].p2.xy(), _triangleCache[10].p3.xy(), xyRect) && !OverlapUtilites2D.TriangleOverlapsRect(_triangleCache[11].p1.xy(), _triangleCache[11].p2.xy(), _triangleCache[11].p3.xy(), xyRect)) { #if CUSTOMDEBUG foreach (var triangle in _triangleCache) { Debug.DrawLine(triangle.p1.xy0(), triangle.p2.xy0(), Color.red); Debug.DrawLine(triangle.p2.xy0(), triangle.p3.xy0(), Color.red); Debug.DrawLine(triangle.p3.xy0(), triangle.p1.xy0(), Color.red); } #endif return(false); } #if CUSTOMDEBUG else { foreach (var triangle in _triangleCache) { Debug.DrawLine(triangle.p1.xy0(), triangle.p2.xy0(), Color.green); Debug.DrawLine(triangle.p2.xy0(), triangle.p3.xy0(), Color.green); Debug.DrawLine(triangle.p3.xy0(), triangle.p1.xy0(), Color.green); } } #endif var yzRect = new Rect(axisBounds.min.yz(), axisBounds.size.yz()); #if CUSTOMDEBUG DebugHelper.DrawCube(new Vector3(0, yzRect.center.x, yzRect.center.y), new Vector3(0, yzRect.width / 2, yzRect.height / 2), Quaternion.identity, Color.black, 0); #endif if (!OverlapUtilites2D.TriangleOverlapsRect(_triangleCache[0].p1.yz(), _triangleCache[0].p2.yz(), _triangleCache[0].p3.yz(), yzRect) && !OverlapUtilites2D.TriangleOverlapsRect(_triangleCache[1].p1.yz(), _triangleCache[1].p2.yz(), _triangleCache[1].p3.yz(), yzRect) && !OverlapUtilites2D.TriangleOverlapsRect(_triangleCache[2].p1.yz(), _triangleCache[2].p2.yz(), _triangleCache[2].p3.yz(), yzRect) && !OverlapUtilites2D.TriangleOverlapsRect(_triangleCache[3].p1.yz(), _triangleCache[3].p2.yz(), _triangleCache[3].p3.yz(), yzRect) && !OverlapUtilites2D.TriangleOverlapsRect(_triangleCache[4].p1.yz(), _triangleCache[4].p2.yz(), _triangleCache[4].p3.yz(), yzRect) && !OverlapUtilites2D.TriangleOverlapsRect(_triangleCache[5].p1.yz(), _triangleCache[5].p2.yz(), _triangleCache[5].p3.yz(), yzRect) && !OverlapUtilites2D.TriangleOverlapsRect(_triangleCache[6].p1.yz(), _triangleCache[6].p2.yz(), _triangleCache[6].p3.yz(), yzRect) && !OverlapUtilites2D.TriangleOverlapsRect(_triangleCache[7].p1.yz(), _triangleCache[7].p2.yz(), _triangleCache[7].p3.yz(), yzRect) && !OverlapUtilites2D.TriangleOverlapsRect(_triangleCache[8].p1.yz(), _triangleCache[8].p2.yz(), _triangleCache[8].p3.yz(), yzRect) && !OverlapUtilites2D.TriangleOverlapsRect(_triangleCache[9].p1.yz(), _triangleCache[0].p2.yz(), _triangleCache[9].p3.yz(), yzRect) && !OverlapUtilites2D.TriangleOverlapsRect(_triangleCache[10].p1.yz(), _triangleCache[10].p2.yz(), _triangleCache[10].p3.yz(), yzRect) && !OverlapUtilites2D.TriangleOverlapsRect(_triangleCache[11].p1.yz(), _triangleCache[11].p2.yz(), _triangleCache[11].p3.yz(), yzRect)) { #if CUSTOMDEBUG foreach (var triangle in _triangleCache) { Debug.DrawLine(triangle.p1.x0yz(), triangle.p2.x0yz(), Color.red); Debug.DrawLine(triangle.p2.x0yz(), triangle.p3.x0yz(), Color.red); Debug.DrawLine(triangle.p3.x0yz(), triangle.p1.x0yz(), Color.red); } #endif return(false); } #if CUSTOMDEBUG else { foreach (var triangle in _triangleCache) { Debug.DrawLine(triangle.p1.x0yz(), triangle.p2.x0yz(), Color.green); Debug.DrawLine(triangle.p2.x0yz(), triangle.p3.x0yz(), Color.green); Debug.DrawLine(triangle.p3.x0yz(), triangle.p1.x0yz(), Color.green); } } #endif return(true); }