diff --git a/CMakeLists.txt b/CMakeLists.txt index acda12f..6c226a8 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.0.1 SOVERSION 2) +set_target_properties(SC_3D_CollisionDetectionHelpers PROPERTIES VERSION 2.0.2 SOVERSION 2) if(NOT DEFINED CMAKE_BUILD_TYPE OR "${CMAKE_BUILD_TYPE}" STREQUAL "") message("Defaulting to \"Debug\" build type.") diff --git a/Changelog.md b/Changelog.md index abf6666..825366e 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,5 +1,12 @@ # Changelog +## Version 2.0.2 + +Fix SC_SACD_Translate_Mat4(...). It was missing a "1" in the first element of +the Mat4. + +Made internal function getting normals of a box more robust. + ## Version 2.0.1 Added check in SC_SACD_Sphere_Box_Collision(...) to see if sphere and box has diff --git a/src/sc_sacd.cpp b/src/sc_sacd.cpp index 7f6a218..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; } @@ -488,7 +538,7 @@ SC_SACD_Mat4 SC_SACD_Rotation_Mat4_ZAxis(float z_radians) { } SC_SACD_Mat4 SC_SACD_Translate_Mat4(float x, float y, float z) { - return SC_SACD_Mat4{0.0F, 0.0F, 0.0F, x, 0.0F, 1.0F, 0.0F, y, + return SC_SACD_Mat4{1.0F, 0.0F, 0.0F, x, 0.0F, 1.0F, 0.0F, y, 0.0F, 0.0F, 1.0F, z, 0.0F, 0.0F, 0.0F, 1.0F}; } 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';