From 43ade068c9ab55936ccecd877ec83d8580823f72 Mon Sep 17 00:00:00 2001 From: Stephen Seo Date: Thu, 2 May 2024 13:13:43 +0900 Subject: [PATCH] Fix internal getting-normals function Translation could have caused errors getting the three normals for the sides of a box. The internal normals-fetching function was therefore made more robust. --- src/sc_sacd.cpp | 86 ++++++++++++++++++++++++++++++++++++++----------- src/test.cpp | 23 +++++++++++++ 2 files changed, 91 insertions(+), 18 deletions(-) diff --git a/src/sc_sacd.cpp b/src/sc_sacd.cpp index 52d7066..337b466 100644 --- a/src/sc_sacd.cpp +++ b/src/sc_sacd.cpp @@ -63,34 +63,84 @@ SC_SACD_Vec3 operator*(const SC_SACD_Mat4 &mat, const SC_SACD_Vec3 &vec) { std::vector SC_SACD_Get_Box_Normals( const SC_SACD_Generic_Box *box) { std::vector normals; + SC_SACD_Vec3 a, b, c; - normals.emplace_back(SC_SACD_Vec3{1.0F, 0.0F, 0.0F}); - normals.back() = box->transform * normals.back(); + // Facing positive x-axis. + a.x = 0.0F; + a.y = 0.0F; + a.z = 0.0F; - normals.emplace_back(SC_SACD_Vec3{0.0F, 1.0F, 0.0F}); - normals.back() = box->transform * normals.back(); + b.x = 0.0F; + b.y = 1.0F; + b.z = 0.0F; - normals.emplace_back(SC_SACD_Vec3{0.0F, 0.0F, 1.0F}); - normals.back() = box->transform * normals.back(); + c.x = 0.0F; + c.y = 0.0F; + c.z = 1.0F; + + a = box->transform * a; + b = box->transform * b; + c = box->transform * c; + + b = b - a; + c = c - a; + + normals.push_back(SC_SACD_Cross_Product(b, c)); + + // Facing positive y-axis. + a.x = 0.0F; + a.y = 0.0F; + a.z = 0.0F; + + b.x = 1.0F; + b.y = 0.0F; + b.z = 0.0F; + + c.x = 0.0F; + c.y = 0.0F; + c.z = -1.0F; + + a = box->transform * a; + b = box->transform * b; + c = box->transform * c; + + b = b - a; + c = c - a; + + normals.push_back(SC_SACD_Cross_Product(b, c)); + + // Facing positive z-axis. + a.x = 0.0F; + a.y = 0.0F; + a.z = 0.0F; + + b.x = 0.0F; + b.y = 1.0F; + b.z = 0.0F; + + c.x = -1.0F; + c.y = 0.0F; + c.z = 0.0F; + + a = box->transform * a; + b = box->transform * b; + c = box->transform * c; + + b = b - a; + c = c - a; + + normals.push_back(SC_SACD_Cross_Product(b, c)); return normals; } std::vector SC_SACD_Get_Box_Normals_Normalized( const SC_SACD_Generic_Box *box) { - std::vector normals; + std::vector normals = SC_SACD_Get_Box_Normals(box); - normals.emplace_back(SC_SACD_Vec3{1.0F, 0.0F, 0.0F}); - normals.back() = box->transform * normals.back(); - normals.back() = normals.back() / SC_SACD_Vec3_Length(normals.back()); - - normals.emplace_back(SC_SACD_Vec3{0.0F, 1.0F, 0.0F}); - normals.back() = box->transform * normals.back(); - normals.back() = normals.back() / SC_SACD_Vec3_Length(normals.back()); - - normals.emplace_back(SC_SACD_Vec3{0.0F, 0.0F, 1.0F}); - normals.back() = box->transform * normals.back(); - normals.back() = normals.back() / SC_SACD_Vec3_Length(normals.back()); + for (auto &normal : normals) { + normal = normal / std::sqrt(SC_SACD_Dot_Product(normal, normal)); + } return normals; } diff --git a/src/test.cpp b/src/test.cpp index bebaccc..77acd62 100644 --- a/src/test.cpp +++ b/src/test.cpp @@ -568,6 +568,29 @@ int main() { CHECK_FLOAT(result.y, std::sqrt(2.0F)); } } + + // Box collision with transform that has translation. + { + SC_SACD_Generic_Box a = SC_SACD_Generic_Box_Default(); + SC_SACD_Generic_Box b = SC_SACD_Generic_Box_Default(); + + a.width = 1.1F; + a.height = 1.1F; + b.width = 1.1F; + b.height = 1.1F; + a.transform = SC_SACD_Translate_Mat4(-1.0F, 0.0F, 0.0F); + b.transform = SC_SACD_Translate_Mat4(0.0F, -1.0F, 0.0F); + + CHECK_TRUE(SC_SACD_Generic_Box_Collision(&a, &b)); + + a.width = 0.9F; + a.height = 0.9F; + b.width = 0.9F; + b.height = 0.9F; + + CHECK_FALSE(SC_SACD_Generic_Box_Collision(&a, &b)); + } + std::cout << "Checks checked: " << checks_checked << '\n' << "Checks passed: " << checks_passed << '\n';