From 82d4613b933fa72498f70f79731589bf407f1f96 Mon Sep 17 00:00:00 2001 From: Stephen Seo Date: Mon, 6 May 2024 13:51:02 +0900 Subject: [PATCH 1/7] Refactoring using std::array not std::vector Getting corners of a box will always return 8 Vec3's, so the return type was changed from std::vector to std::array. --- src/sc_sacd.cpp | 107 ++++++++++++++++++++++++------------------------ 1 file changed, 54 insertions(+), 53 deletions(-) diff --git a/src/sc_sacd.cpp b/src/sc_sacd.cpp index f6f8e94..d6dc6a4 100644 --- a/src/sc_sacd.cpp +++ b/src/sc_sacd.cpp @@ -146,67 +146,68 @@ std::array SC_SACD_Get_Box_Normals_Normalized( return normals; } -std::vector SC_SACD_Get_Box_Corners( +std::array SC_SACD_Get_Box_Corners( const SC_SACD_Generic_Box *box) { - std::vector corners; + SC_SACD_Vec3 corner_0 = + box->transform * + SC_SACD_Vec3{-box->width / 2.0F, -box->height / 2.0F, -box->depth / 2.0F}; + corner_0.x += box->x; + corner_0.y += box->y; + corner_0.z += box->z; - corners.push_back(box->transform * SC_SACD_Vec3{-box->width / 2.0F, - -box->height / 2.0F, - -box->depth / 2.0F}); - corners.back().x += box->x; - corners.back().y += box->y; - corners.back().z += box->z; + SC_SACD_Vec3 corner_1 = + box->transform * + SC_SACD_Vec3{box->width / 2.0F, -box->height / 2.0F, -box->depth / 2.0F}; + corner_1.x += box->x; + corner_1.y += box->y; + corner_1.z += box->z; - corners.push_back(box->transform * SC_SACD_Vec3{box->width / 2.0F, - -box->height / 2.0F, - -box->depth / 2.0F}); - corners.back().x += box->x; - corners.back().y += box->y; - corners.back().z += box->z; + SC_SACD_Vec3 corner_2 = + box->transform * + SC_SACD_Vec3{-box->width / 2.0F, box->height / 2.0F, -box->depth / 2.0F}; + corner_2.x += box->x; + corner_2.y += box->y; + corner_2.z += box->z; - corners.push_back(box->transform * SC_SACD_Vec3{-box->width / 2.0F, - box->height / 2.0F, - -box->depth / 2.0F}); - corners.back().x += box->x; - corners.back().y += box->y; - corners.back().z += box->z; + SC_SACD_Vec3 corner_3 = + box->transform * + SC_SACD_Vec3{box->width / 2.0F, box->height / 2.0F, -box->depth / 2.0F}; + corner_3.x += box->x; + corner_3.y += box->y; + corner_3.z += box->z; - corners.push_back(box->transform * SC_SACD_Vec3{box->width / 2.0F, - box->height / 2.0F, - -box->depth / 2.0F}); - corners.back().x += box->x; - corners.back().y += box->y; - corners.back().z += box->z; + SC_SACD_Vec3 corner_4 = + box->transform * + SC_SACD_Vec3{-box->width / 2.0F, -box->height / 2.0F, box->depth / 2.0F}; + corner_4.x += box->x; + corner_4.y += box->y; + corner_4.z += box->z; - corners.push_back(box->transform * SC_SACD_Vec3{-box->width / 2.0F, - -box->height / 2.0F, - box->depth / 2.0F}); - corners.back().x += box->x; - corners.back().y += box->y; - corners.back().z += box->z; + SC_SACD_Vec3 corner_5 = + box->transform * + SC_SACD_Vec3{box->width / 2.0F, -box->height / 2.0F, box->depth / 2.0F}; + corner_5.x += box->x; + corner_5.y += box->y; + corner_5.z += box->z; - corners.push_back(box->transform * SC_SACD_Vec3{box->width / 2.0F, - -box->height / 2.0F, - box->depth / 2.0F}); - corners.back().x += box->x; - corners.back().y += box->y; - corners.back().z += box->z; + SC_SACD_Vec3 corner_6 = + box->transform * + SC_SACD_Vec3{-box->width / 2.0F, box->height / 2.0F, box->depth / 2.0F}; + corner_6.x += box->x; + corner_6.y += box->y; + corner_6.z += box->z; - corners.push_back(box->transform * SC_SACD_Vec3{-box->width / 2.0F, - box->height / 2.0F, - box->depth / 2.0F}); - corners.back().x += box->x; - corners.back().y += box->y; - corners.back().z += box->z; + SC_SACD_Vec3 corner_7 = + box->transform * + SC_SACD_Vec3{box->width / 2.0F, box->height / 2.0F, box->depth / 2.0F}; + corner_7.x += box->x; + corner_7.y += box->y; + corner_7.z += box->z; - corners.push_back(box->transform * SC_SACD_Vec3{box->width / 2.0F, - box->height / 2.0F, - box->depth / 2.0F}); - corners.back().x += box->x; - corners.back().y += box->y; - corners.back().z += box->z; - - return corners; + return { + corner_0, corner_1, corner_2, corner_3, + corner_4, corner_5, corner_6, corner_7, + }; } struct SC_SACD_MinMax { @@ -217,7 +218,7 @@ std::vector SC_SACD_Get_Box_MinMax( const SC_SACD_Generic_Box *box, const std::span normals) { std::vector minmaxes; - std::vector corners = SC_SACD_Get_Box_Corners(box); + auto corners = SC_SACD_Get_Box_Corners(box); // Assuming normals are not normalized, and will not normalize anyway. // MinMax count should be same as normals count. From a40fc777629a4968388ded281ada46f251c436de Mon Sep 17 00:00:00 2001 From: Stephen Seo Date: Mon, 6 May 2024 13:52:53 +0900 Subject: [PATCH 2/7] Update Changelog --- Changelog.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Changelog.md b/Changelog.md index 4952563..903dd40 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,5 +1,9 @@ # Changelog +## Upcoming Changes + +Refactoring of internally used function. + ## Version 2.1.0 Refactoring of internally used function(s). From 56a4c0783b10a2e0da71f985c8a96c59fa48871a Mon Sep 17 00:00:00 2001 From: Stephen Seo Date: Mon, 6 May 2024 14:11:41 +0900 Subject: [PATCH 3/7] Impl Sphere/GenericBox to AABB --- src/sc_sacd.cpp | 55 +++++++++++++++++++++++++++++++++++++++++++++++++ src/sc_sacd.h | 4 ++++ src/test.cpp | 48 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 107 insertions(+) diff --git a/src/sc_sacd.cpp b/src/sc_sacd.cpp index d6dc6a4..070f4e8 100644 --- a/src/sc_sacd.cpp +++ b/src/sc_sacd.cpp @@ -572,3 +572,58 @@ SC_SACD_Vec3 SC_SACD_Closest_Point(const SC_SACD_Vec3 *pos, float SC_SACD_Vec3_Length(const SC_SACD_Vec3 vec) { return std::sqrt(SC_SACD_Dot_Product(vec, vec)); } + +SC_SACD_AABB_Box SC_SACD_Sphere_To_AABB(const SC_SACD_Sphere s) { + SC_SACD_AABB_Box aabb{}; + + aabb.x = s.x; + aabb.y = s.y; + aabb.z = s.z; + + aabb.width = s.radius * 2.0F; + aabb.height = s.radius * 2.0F; + aabb.depth = s.radius * 2.0F; + + return aabb; +} + +SC_SACD_AABB_Box SC_SACD_Generic_Box_To_AABB(const SC_SACD_Generic_Box s) { + SC_SACD_AABB_Box aabb{}; + + auto corners = SC_SACD_Get_Box_Corners(&s); + + SC_SACD_Vec3 min{INFINITY, INFINITY, INFINITY}; + SC_SACD_Vec3 max{-INFINITY, -INFINITY, -INFINITY}; + + for (const auto &corner : corners) { + if (corner.x < min.x) { + min.x = corner.x; + } + if (corner.y < min.y) { + min.y = corner.y; + } + if (corner.z < min.z) { + min.z = corner.z; + } + + if (corner.x > max.x) { + max.x = corner.x; + } + if (corner.y > max.y) { + max.y = corner.y; + } + if (corner.z > max.z) { + max.z = corner.z; + } + } + + aabb.width = max.x - min.x; + aabb.height = max.y - min.y; + aabb.depth = max.z - min.z; + + aabb.x = min.x + aabb.width / 2.0F; + aabb.y = min.y + aabb.height / 2.0F; + aabb.z = min.z + aabb.depth / 2.0F; + + return aabb; +} diff --git a/src/sc_sacd.h b/src/sc_sacd.h index e0bddb5..b18dcef 100644 --- a/src/sc_sacd.h +++ b/src/sc_sacd.h @@ -133,6 +133,10 @@ SC_SACD_EXPORT SC_SACD_Vec3 SC_SACD_Closest_Point(const SC_SACD_Vec3 *pos, SC_SACD_EXPORT float SC_SACD_Vec3_Length(const SC_SACD_Vec3 vec); +SC_SACD_EXPORT SC_SACD_AABB_Box SC_SACD_Sphere_To_AABB(const SC_SACD_Sphere s); +SC_SACD_EXPORT SC_SACD_AABB_Box +SC_SACD_Generic_Box_To_AABB(const SC_SACD_Generic_Box s); + #ifdef __cplusplus } #endif diff --git a/src/test.cpp b/src/test.cpp index a759639..83b08ea 100644 --- a/src/test.cpp +++ b/src/test.cpp @@ -633,6 +633,54 @@ int main() { CHECK_TRUE(SC_SACD_Generic_Box_Collision(&a, &b)); } + // Test Sphere/GenericBox to AABB. + { + SC_SACD_Sphere s{10.0F, 10.0F, 10.0F, 5.0F}; + + SC_SACD_AABB_Box aabb = SC_SACD_Sphere_To_AABB(s); + CHECK_FLOAT(aabb.x, s.x); + CHECK_FLOAT(aabb.y, s.y); + CHECK_FLOAT(aabb.z, s.z); + CHECK_FLOAT(aabb.width, s.radius * 2.0F); + CHECK_FLOAT(aabb.height, s.radius * 2.0F); + CHECK_FLOAT(aabb.depth, s.radius * 2.0F); + + SC_SACD_Generic_Box box = SC_SACD_Generic_Box_Default(); + box.x = 20.0F; + box.y = 20.0F; + box.z = 20.0F; + + aabb = SC_SACD_Generic_Box_To_AABB(box); + CHECK_FLOAT(aabb.x, box.x); + CHECK_FLOAT(aabb.y, box.y); + CHECK_FLOAT(aabb.z, box.z); + CHECK_FLOAT(aabb.width, box.width); + CHECK_FLOAT(aabb.height, box.height); + CHECK_FLOAT(aabb.depth, box.depth); + + box.transform = + SC_SACD_Rotation_Mat4_ZAxis(std::numbers::pi_v / 4.0F); + + aabb = SC_SACD_Generic_Box_To_AABB(box); + CHECK_FLOAT(aabb.x, box.x); + CHECK_FLOAT(aabb.y, box.y); + CHECK_FLOAT(aabb.z, box.z); + CHECK_FLOAT(aabb.width, std::sqrt(2.0F) * 2.0F); + CHECK_FLOAT(aabb.height, std::sqrt(2.0F) * 2.0F); + CHECK_FLOAT(aabb.depth, box.depth); + + auto translate = SC_SACD_Translate_Mat4(-5.0F, -4.0F, 1.0F); + box.transform = SC_SACD_Mat4_Mult(&translate, &box.transform); + + aabb = SC_SACD_Generic_Box_To_AABB(box); + CHECK_FLOAT(aabb.x, box.x - 5.0F); + CHECK_FLOAT(aabb.y, box.y - 4.0F); + CHECK_FLOAT(aabb.z, box.z + 1.0F); + CHECK_FLOAT(aabb.width, std::sqrt(2.0F) * 2.0F); + CHECK_FLOAT(aabb.height, std::sqrt(2.0F) * 2.0F); + CHECK_FLOAT(aabb.depth, box.depth); + } + std::cout << "Checks checked: " << checks_checked << '\n' << "Checks passed: " << checks_passed << '\n'; From 531b17a60be402dfda4e5a3a416119b6edbe150b Mon Sep 17 00:00:00 2001 From: Stephen Seo Date: Mon, 6 May 2024 14:12:06 +0900 Subject: [PATCH 4/7] Update Changelog --- Changelog.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Changelog.md b/Changelog.md index 903dd40..56aa80b 100644 --- a/Changelog.md +++ b/Changelog.md @@ -4,6 +4,8 @@ Refactoring of internally used function. +Add functions to convert Sphere and GenericBox to AABB. + ## Version 2.1.0 Refactoring of internally used function(s). From ef52303a6a840cf7a1aef9ff9718a95a60211c14 Mon Sep 17 00:00:00 2001 From: Stephen Seo Date: Mon, 6 May 2024 14:12:30 +0900 Subject: [PATCH 5/7] Bump version to 2.2.0 Added new functions/features, so bump minor version number. --- CMakeLists.txt | 2 +- Changelog.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index da2d589..b9ae890 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ set(SC_3D_CollisionDetectionHelpers_HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/src/sc_ add_library(SC_3D_CollisionDetectionHelpers ${SC_3D_CollisionDetectionHelpers_SOURCES}) -set_target_properties(SC_3D_CollisionDetectionHelpers PROPERTIES VERSION 2.1.0 SOVERSION 2) +set_target_properties(SC_3D_CollisionDetectionHelpers PROPERTIES VERSION 2.2.0 SOVERSION 2) target_compile_features(SC_3D_CollisionDetectionHelpers PUBLIC cxx_std_20) if(NOT DEFINED CMAKE_BUILD_TYPE OR "${CMAKE_BUILD_TYPE}" STREQUAL "") diff --git a/Changelog.md b/Changelog.md index 56aa80b..53d66f2 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,6 +1,6 @@ # Changelog -## Upcoming Changes +## Version 2.2.0 Refactoring of internally used function. From 1d44827f96b3862e2c25bc11bf9b6b80218321e1 Mon Sep 17 00:00:00 2001 From: Stephen Seo Date: Mon, 6 May 2024 14:28:23 +0900 Subject: [PATCH 6/7] Add combine AABB function New function that creates a new AABB that encompasses the two given AABBs. --- src/sc_sacd.cpp | 52 +++++++++++++++++++++++++++++++++++++++++++++++++ src/sc_sacd.h | 4 ++++ src/test.cpp | 15 ++++++++++++++ 3 files changed, 71 insertions(+) diff --git a/src/sc_sacd.cpp b/src/sc_sacd.cpp index 070f4e8..62a7d40 100644 --- a/src/sc_sacd.cpp +++ b/src/sc_sacd.cpp @@ -627,3 +627,55 @@ SC_SACD_AABB_Box SC_SACD_Generic_Box_To_AABB(const SC_SACD_Generic_Box s) { return aabb; } + +SC_SACD_AABB_Box SC_SACD_AABB_Combine(const SC_SACD_AABB_Box a, + const SC_SACD_AABB_Box b) { + SC_SACD_Vec3 min, max; + + // Populate min values. + + float temp_a = a.x - a.width / 2.0F; + float temp_b = b.x - b.width / 2.0F; + + min.x = temp_a < temp_b ? temp_a : temp_b; + + temp_a = a.y - a.height / 2.0F; + temp_b = b.y - b.height / 2.0F; + + min.y = temp_a < temp_b ? temp_a : temp_b; + + temp_a = a.z - a.depth / 2.0F; + temp_b = b.z - b.depth / 2.0F; + + min.z = temp_a < temp_b ? temp_a : temp_b; + + // Populate max values. + + temp_a = a.x + a.width / 2.0F; + temp_b = b.x + b.width / 2.0F; + + max.x = temp_a > temp_b ? temp_a : temp_b; + + temp_a = a.y + a.height / 2.0F; + temp_b = b.y + b.height / 2.0F; + + max.y = temp_a > temp_b ? temp_a : temp_b; + + temp_a = a.z + a.depth / 2.0F; + temp_b = b.z + b.depth / 2.0F; + + max.z = temp_a > temp_b ? temp_a : temp_b; + + // Populate the result. + + temp_a = max.x - min.x; + temp_b = max.y - min.y; + float temp_c = max.z - min.z; + + return SC_SACD_AABB_Box{min.x + temp_a / 2.0F, + min.y + temp_b / 2.0F, + min.z + temp_c / 2.0F, + temp_a, + temp_b, + temp_c}; +} diff --git a/src/sc_sacd.h b/src/sc_sacd.h index b18dcef..bf5725d 100644 --- a/src/sc_sacd.h +++ b/src/sc_sacd.h @@ -137,6 +137,10 @@ SC_SACD_EXPORT SC_SACD_AABB_Box SC_SACD_Sphere_To_AABB(const SC_SACD_Sphere s); SC_SACD_EXPORT SC_SACD_AABB_Box SC_SACD_Generic_Box_To_AABB(const SC_SACD_Generic_Box s); +/// Combines AABB's such that the new AABB encompasses the two AABB's. +SC_SACD_EXPORT SC_SACD_AABB_Box SC_SACD_AABB_Combine(const SC_SACD_AABB_Box a, + const SC_SACD_AABB_Box b); + #ifdef __cplusplus } #endif diff --git a/src/test.cpp b/src/test.cpp index 83b08ea..4986e1a 100644 --- a/src/test.cpp +++ b/src/test.cpp @@ -681,6 +681,21 @@ int main() { CHECK_FLOAT(aabb.depth, box.depth); } + // Test combining AABB. + { + SC_SACD_AABB_Box a{5.0F, 5.0F, 5.0F, 2.0F, 2.0F, 2.0F}; + + SC_SACD_AABB_Box b{-3.0F, -3.0F, -3.0F, 2.0F, 2.0F, 2.0F}; + + auto combined = SC_SACD_AABB_Combine(a, b); + CHECK_FLOAT(combined.x, (7.0F - 5.0F) / 2.0F); + CHECK_FLOAT(combined.y, (7.0F - 5.0F) / 2.0F); + CHECK_FLOAT(combined.z, (7.0F - 5.0F) / 2.0F); + CHECK_FLOAT(combined.width, 10.0F); + CHECK_FLOAT(combined.height, 10.0F); + CHECK_FLOAT(combined.depth, 10.0F); + } + std::cout << "Checks checked: " << checks_checked << '\n' << "Checks passed: " << checks_passed << '\n'; From 8f7243cb24cfc3c28dc142fb7dec1af066a51f59 Mon Sep 17 00:00:00 2001 From: Stephen Seo Date: Mon, 6 May 2024 14:28:59 +0900 Subject: [PATCH 7/7] Update Changelog --- Changelog.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Changelog.md b/Changelog.md index 53d66f2..9abdf54 100644 --- a/Changelog.md +++ b/Changelog.md @@ -6,6 +6,8 @@ Refactoring of internally used function. Add functions to convert Sphere and GenericBox to AABB. +Add function to combine two AABBs. + ## Version 2.1.0 Refactoring of internally used function(s).