From 56a4c0783b10a2e0da71f985c8a96c59fa48871a Mon Sep 17 00:00:00 2001 From: Stephen Seo Date: Mon, 6 May 2024 14:11:41 +0900 Subject: [PATCH] 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';