Merge branch 'dev', version 2.2.0
All checks were successful
Run UnitTest / build-and-run-UnitTest (push) Successful in 4s
All checks were successful
Run UnitTest / build-and-run-UnitTest (push) Successful in 4s
This commit is contained in:
commit
5f33fedae4
5 changed files with 241 additions and 54 deletions
|
@ -6,7 +6,7 @@ set(SC_3D_CollisionDetectionHelpers_HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/src/sc_
|
||||||
|
|
||||||
add_library(SC_3D_CollisionDetectionHelpers ${SC_3D_CollisionDetectionHelpers_SOURCES})
|
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)
|
target_compile_features(SC_3D_CollisionDetectionHelpers PUBLIC cxx_std_20)
|
||||||
|
|
||||||
if(NOT DEFINED CMAKE_BUILD_TYPE OR "${CMAKE_BUILD_TYPE}" STREQUAL "")
|
if(NOT DEFINED CMAKE_BUILD_TYPE OR "${CMAKE_BUILD_TYPE}" STREQUAL "")
|
||||||
|
|
|
@ -1,5 +1,13 @@
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## Version 2.2.0
|
||||||
|
|
||||||
|
Refactoring of internally used function.
|
||||||
|
|
||||||
|
Add functions to convert Sphere and GenericBox to AABB.
|
||||||
|
|
||||||
|
Add function to combine two AABBs.
|
||||||
|
|
||||||
## Version 2.1.0
|
## Version 2.1.0
|
||||||
|
|
||||||
Refactoring of internally used function(s).
|
Refactoring of internally used function(s).
|
||||||
|
|
214
src/sc_sacd.cpp
214
src/sc_sacd.cpp
|
@ -146,67 +146,68 @@ std::array<SC_SACD_Vec3, 3> SC_SACD_Get_Box_Normals_Normalized(
|
||||||
return normals;
|
return normals;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<SC_SACD_Vec3> SC_SACD_Get_Box_Corners(
|
std::array<SC_SACD_Vec3, 8> SC_SACD_Get_Box_Corners(
|
||||||
const SC_SACD_Generic_Box *box) {
|
const SC_SACD_Generic_Box *box) {
|
||||||
std::vector<SC_SACD_Vec3> 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,
|
SC_SACD_Vec3 corner_1 =
|
||||||
-box->height / 2.0F,
|
box->transform *
|
||||||
-box->depth / 2.0F});
|
SC_SACD_Vec3{box->width / 2.0F, -box->height / 2.0F, -box->depth / 2.0F};
|
||||||
corners.back().x += box->x;
|
corner_1.x += box->x;
|
||||||
corners.back().y += box->y;
|
corner_1.y += box->y;
|
||||||
corners.back().z += box->z;
|
corner_1.z += box->z;
|
||||||
|
|
||||||
corners.push_back(box->transform * SC_SACD_Vec3{box->width / 2.0F,
|
SC_SACD_Vec3 corner_2 =
|
||||||
-box->height / 2.0F,
|
box->transform *
|
||||||
-box->depth / 2.0F});
|
SC_SACD_Vec3{-box->width / 2.0F, box->height / 2.0F, -box->depth / 2.0F};
|
||||||
corners.back().x += box->x;
|
corner_2.x += box->x;
|
||||||
corners.back().y += box->y;
|
corner_2.y += box->y;
|
||||||
corners.back().z += box->z;
|
corner_2.z += box->z;
|
||||||
|
|
||||||
corners.push_back(box->transform * SC_SACD_Vec3{-box->width / 2.0F,
|
SC_SACD_Vec3 corner_3 =
|
||||||
box->height / 2.0F,
|
box->transform *
|
||||||
-box->depth / 2.0F});
|
SC_SACD_Vec3{box->width / 2.0F, box->height / 2.0F, -box->depth / 2.0F};
|
||||||
corners.back().x += box->x;
|
corner_3.x += box->x;
|
||||||
corners.back().y += box->y;
|
corner_3.y += box->y;
|
||||||
corners.back().z += box->z;
|
corner_3.z += box->z;
|
||||||
|
|
||||||
corners.push_back(box->transform * SC_SACD_Vec3{box->width / 2.0F,
|
SC_SACD_Vec3 corner_4 =
|
||||||
box->height / 2.0F,
|
box->transform *
|
||||||
-box->depth / 2.0F});
|
SC_SACD_Vec3{-box->width / 2.0F, -box->height / 2.0F, box->depth / 2.0F};
|
||||||
corners.back().x += box->x;
|
corner_4.x += box->x;
|
||||||
corners.back().y += box->y;
|
corner_4.y += box->y;
|
||||||
corners.back().z += box->z;
|
corner_4.z += box->z;
|
||||||
|
|
||||||
corners.push_back(box->transform * SC_SACD_Vec3{-box->width / 2.0F,
|
SC_SACD_Vec3 corner_5 =
|
||||||
-box->height / 2.0F,
|
box->transform *
|
||||||
box->depth / 2.0F});
|
SC_SACD_Vec3{box->width / 2.0F, -box->height / 2.0F, box->depth / 2.0F};
|
||||||
corners.back().x += box->x;
|
corner_5.x += box->x;
|
||||||
corners.back().y += box->y;
|
corner_5.y += box->y;
|
||||||
corners.back().z += box->z;
|
corner_5.z += box->z;
|
||||||
|
|
||||||
corners.push_back(box->transform * SC_SACD_Vec3{box->width / 2.0F,
|
SC_SACD_Vec3 corner_6 =
|
||||||
-box->height / 2.0F,
|
box->transform *
|
||||||
box->depth / 2.0F});
|
SC_SACD_Vec3{-box->width / 2.0F, box->height / 2.0F, box->depth / 2.0F};
|
||||||
corners.back().x += box->x;
|
corner_6.x += box->x;
|
||||||
corners.back().y += box->y;
|
corner_6.y += box->y;
|
||||||
corners.back().z += box->z;
|
corner_6.z += box->z;
|
||||||
|
|
||||||
corners.push_back(box->transform * SC_SACD_Vec3{-box->width / 2.0F,
|
SC_SACD_Vec3 corner_7 =
|
||||||
box->height / 2.0F,
|
box->transform *
|
||||||
box->depth / 2.0F});
|
SC_SACD_Vec3{box->width / 2.0F, box->height / 2.0F, box->depth / 2.0F};
|
||||||
corners.back().x += box->x;
|
corner_7.x += box->x;
|
||||||
corners.back().y += box->y;
|
corner_7.y += box->y;
|
||||||
corners.back().z += box->z;
|
corner_7.z += box->z;
|
||||||
|
|
||||||
corners.push_back(box->transform * SC_SACD_Vec3{box->width / 2.0F,
|
return {
|
||||||
box->height / 2.0F,
|
corner_0, corner_1, corner_2, corner_3,
|
||||||
box->depth / 2.0F});
|
corner_4, corner_5, corner_6, corner_7,
|
||||||
corners.back().x += box->x;
|
};
|
||||||
corners.back().y += box->y;
|
|
||||||
corners.back().z += box->z;
|
|
||||||
|
|
||||||
return corners;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SC_SACD_MinMax {
|
struct SC_SACD_MinMax {
|
||||||
|
@ -217,7 +218,7 @@ std::vector<SC_SACD_MinMax> SC_SACD_Get_Box_MinMax(
|
||||||
const SC_SACD_Generic_Box *box, const std::span<SC_SACD_Vec3> normals) {
|
const SC_SACD_Generic_Box *box, const std::span<SC_SACD_Vec3> normals) {
|
||||||
std::vector<SC_SACD_MinMax> minmaxes;
|
std::vector<SC_SACD_MinMax> minmaxes;
|
||||||
|
|
||||||
std::vector<SC_SACD_Vec3> 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.
|
// Assuming normals are not normalized, and will not normalize anyway.
|
||||||
// MinMax count should be same as normals count.
|
// MinMax count should be same as normals count.
|
||||||
|
@ -571,3 +572,110 @@ SC_SACD_Vec3 SC_SACD_Closest_Point(const SC_SACD_Vec3 *pos,
|
||||||
float SC_SACD_Vec3_Length(const SC_SACD_Vec3 vec) {
|
float SC_SACD_Vec3_Length(const SC_SACD_Vec3 vec) {
|
||||||
return std::sqrt(SC_SACD_Dot_Product(vec, 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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};
|
||||||
|
}
|
||||||
|
|
|
@ -133,6 +133,14 @@ 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 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);
|
||||||
|
|
||||||
|
/// 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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
63
src/test.cpp
63
src/test.cpp
|
@ -633,6 +633,69 @@ int main() {
|
||||||
CHECK_TRUE(SC_SACD_Generic_Box_Collision(&a, &b));
|
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<float> / 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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'
|
std::cout << "Checks checked: " << checks_checked << '\n'
|
||||||
<< "Checks passed: " << checks_passed << '\n';
|
<< "Checks passed: " << checks_passed << '\n';
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue