From 143d8e78437336136bf397b05e02410ccde185a4 Mon Sep 17 00:00:00 2001 From: assiduous Date: Tue, 8 Dec 2020 11:45:19 -0800 Subject: MathLib: added CheckBox2DBox2DOverlap function --- Common/interface/AdvancedMath.hpp | 32 ++++++++++++ Tests/DiligentCoreTest/src/Common/MathLibTest.cpp | 64 +++++++++++++++++++++++ 2 files changed, 96 insertions(+) diff --git a/Common/interface/AdvancedMath.hpp b/Common/interface/AdvancedMath.hpp index 8d1119e5..11af8e34 100644 --- a/Common/interface/AdvancedMath.hpp +++ b/Common/interface/AdvancedMath.hpp @@ -935,6 +935,38 @@ void RasterizeTriangle(Vector2 V0, } } + +/// Checks if two 2D-boxes overlap. + +/// \tparam [in] AllowTouch - Whether to consider two boxes overlapping if +/// they only touch at their boundaries or corners. +/// \tparam [in] T - Component type. +/// +/// \param [in] Box0Min - Min corner of the first box. +/// \param [in] Box0Max - Max corner of the first box. +/// \param [in] Box1Min - Min corner of the second box. +/// \param [in] Box1Max - Max corner of the second box. +/// +/// \return true if the bounding boxes overlap, and false otherwise. +template +bool CheckBox2DBox2DOverlap(const Vector2& Box0Min, + const Vector2& Box0Max, + const Vector2& Box1Min, + const Vector2& Box1Max) +{ + VERIFY_EXPR(Box0Max.x >= Box0Min.x && Box0Max.y >= Box0Min.y && + Box1Max.x >= Box1Min.x && Box1Max.y >= Box1Min.y); + if (AllowTouch) + { + return !(Box0Min.x > Box1Max.x || Box1Min.x > Box0Max.x || Box0Min.y > Box1Max.y || Box1Min.y > Box0Max.y); + } + else + { + return !(Box0Min.x >= Box1Max.x || Box1Min.x >= Box0Max.x || Box0Min.y >= Box1Max.y || Box1Min.y >= Box0Max.y); + } +} + + } // namespace Diligent namespace std diff --git a/Tests/DiligentCoreTest/src/Common/MathLibTest.cpp b/Tests/DiligentCoreTest/src/Common/MathLibTest.cpp index 9c3d620f..3723f52a 100644 --- a/Tests/DiligentCoreTest/src/Common/MathLibTest.cpp +++ b/Tests/DiligentCoreTest/src/Common/MathLibTest.cpp @@ -1962,4 +1962,68 @@ TEST(Common_AdvancedMath, TransformBoundBox) } } +TEST(Common_AdvancedMath, CheckBox2DBox2DOverlap) +{ + // clang-format off + // Self-intersection + EXPECT_TRUE(CheckBox2DBox2DOverlap (uint2(0, 0), uint2(1, 1), uint2(0, 0), uint2(1, 1))); + EXPECT_TRUE(CheckBox2DBox2DOverlap(uint2(0, 0), uint2(1, 1), uint2(0, 0), uint2(1, 1))); + + // One box fully inside another + EXPECT_TRUE(CheckBox2DBox2DOverlap (uint2(0, 0), uint2(10, 10), uint2(1, 1), uint2( 2, 2))); + EXPECT_TRUE(CheckBox2DBox2DOverlap (uint2(1, 1), uint2( 2, 2), uint2(0, 0), uint2(10, 10))); + EXPECT_TRUE(CheckBox2DBox2DOverlap(uint2(0, 0), uint2(10, 10), uint2(1, 1), uint2( 2, 2))); + EXPECT_TRUE(CheckBox2DBox2DOverlap(uint2(1, 1), uint2( 2, 2 ), uint2(0, 0), uint2(10, 10))); + + // Touching corners + EXPECT_TRUE (CheckBox2DBox2DOverlap (int2(0, 0), int2(10, 10), int2(-1, -1), int2( 0, 0))); + EXPECT_FALSE(CheckBox2DBox2DOverlap(int2(0, 0), int2(10, 10), int2(-1, -1), int2( 0, 0))); + EXPECT_TRUE (CheckBox2DBox2DOverlap (int2(0, 0), int2(10, 10), int2(-1, 10), int2( 0, 11))); + EXPECT_FALSE(CheckBox2DBox2DOverlap(int2(0, 0), int2(10, 10), int2(-1, 10), int2( 0, 11))); + EXPECT_TRUE (CheckBox2DBox2DOverlap (int2(0, 0), int2(10, 10), int2(10, 10), int2(11, 11))); + EXPECT_FALSE(CheckBox2DBox2DOverlap(int2(0, 0), int2(10, 10), int2(10, 10), int2(11, 11))); + EXPECT_TRUE (CheckBox2DBox2DOverlap (int2(0, 0), int2(10, 10), int2(10, -1), int2(11, 0))); + EXPECT_FALSE(CheckBox2DBox2DOverlap(int2(0, 0), int2(10, 10), int2(10, -1), int2(11, 0))); + + // Intersections + EXPECT_TRUE(CheckBox2DBox2DOverlap (float2(0, 0), float2(10, 10), float2(-1, -1), float2( 1, 1))); + EXPECT_TRUE(CheckBox2DBox2DOverlap(float2(0, 0), float2(10, 10), float2(-1, -1), float2( 1, 1))); + EXPECT_TRUE(CheckBox2DBox2DOverlap (float2(0, 0), float2(10, 10), float2(-1, 9), float2( 1, 11))); + EXPECT_TRUE(CheckBox2DBox2DOverlap(float2(0, 0), float2(10, 10), float2(-1, 9), float2( 1, 11))); + EXPECT_TRUE(CheckBox2DBox2DOverlap (float2(0, 0), float2(10, 10), float2( 9, 9), float2(11, 11))); + EXPECT_TRUE(CheckBox2DBox2DOverlap(float2(0, 0), float2(10, 10), float2( 9, 9), float2(11, 11))); + EXPECT_TRUE(CheckBox2DBox2DOverlap (float2(0, 0), float2(10, 10), float2( 9, -1), float2(11, 1))); + EXPECT_TRUE(CheckBox2DBox2DOverlap(float2(0, 0), float2(10, 10), float2( 9, -1), float2(11, 1))); + + // No intersections + EXPECT_FALSE(CheckBox2DBox2DOverlap (float2(0, 0), float2(10, 10), float2(-2, -2), float2(-1, -1))); + EXPECT_FALSE(CheckBox2DBox2DOverlap(float2(0, 0), float2(10, 10), float2(-2, -2), float2(-1, -1))); + EXPECT_FALSE(CheckBox2DBox2DOverlap (float2(0, 0), float2(10, 10), float2(-2, 5), float2(-1, 6))); + EXPECT_FALSE(CheckBox2DBox2DOverlap(float2(0, 0), float2(10, 10), float2(-2, 5), float2(-1, 6))); + EXPECT_FALSE(CheckBox2DBox2DOverlap (float2(0, 0), float2(10, 10), float2(-2, 11), float2(-1, 12))); + EXPECT_FALSE(CheckBox2DBox2DOverlap(float2(0, 0), float2(10, 10), float2(-2, 11), float2(-1, 12))); + EXPECT_FALSE(CheckBox2DBox2DOverlap (float2(0, 0), float2(10, 10), float2( 5, 11), float2( 6, 12))); + EXPECT_FALSE(CheckBox2DBox2DOverlap(float2(0, 0), float2(10, 10), float2( 5, 11), float2( 6, 12))); + EXPECT_FALSE(CheckBox2DBox2DOverlap (float2(0, 0), float2(10, 10), float2(11, 11), float2(12, 12))); + EXPECT_FALSE(CheckBox2DBox2DOverlap(float2(0, 0), float2(10, 10), float2(11, 11), float2(12, 12))); + EXPECT_FALSE(CheckBox2DBox2DOverlap (float2(0, 0), float2(10, 10), float2(11, 5), float2(12, 6))); + EXPECT_FALSE(CheckBox2DBox2DOverlap(float2(0, 0), float2(10, 10), float2(11, 5), float2(12, 6))); + EXPECT_FALSE(CheckBox2DBox2DOverlap (float2(0, 0), float2(10, 10), float2(11, -2), float2(12, -1))); + EXPECT_FALSE(CheckBox2DBox2DOverlap(float2(0, 0), float2(10, 10), float2(11, -2), float2(12, -1))); + EXPECT_FALSE(CheckBox2DBox2DOverlap (float2(0, 0), float2(10, 10), float2( 5, -2), float2( 6, -1))); + EXPECT_FALSE(CheckBox2DBox2DOverlap(float2(0, 0), float2(10, 10), float2( 5, -2), float2( 6, -1))); + + // Touching boundaries + EXPECT_TRUE (CheckBox2DBox2DOverlap (double2(0, 0), double2(10, 10), double2(-2, 5), double2( 0, 6))); + EXPECT_FALSE(CheckBox2DBox2DOverlap(double2(0, 0), double2(10, 10), double2(-2, 5), double2( 0, 6))); + EXPECT_TRUE (CheckBox2DBox2DOverlap (double2(0, 0), double2(10, 10), double2( 5, 10), double2( 6, 12))); + EXPECT_FALSE(CheckBox2DBox2DOverlap(double2(0, 0), double2(10, 10), double2( 5, 10), double2( 6, 12))); + EXPECT_TRUE (CheckBox2DBox2DOverlap (double2(0, 0), double2(10, 10), double2(10, 5), double2(12, 6))); + EXPECT_FALSE(CheckBox2DBox2DOverlap(double2(0, 0), double2(10, 10), double2(10, 5), double2(12, 6))); + EXPECT_TRUE (CheckBox2DBox2DOverlap (double2(0, 0), double2(10, 10), double2( 5, -2), double2( 6, 0))); + EXPECT_FALSE(CheckBox2DBox2DOverlap(double2(0, 0), double2(10, 10), double2( 5, -2), double2( 6, 0))); + + // clang-format on +} + } // namespace -- cgit v1.2.3