Merge branch 'dev', version 2.1.0
All checks were successful
Run UnitTest / build-and-run-UnitTest (push) Successful in 5s
All checks were successful
Run UnitTest / build-and-run-UnitTest (push) Successful in 5s
This commit is contained in:
commit
7e4041e50f
5 changed files with 95 additions and 33 deletions
|
@ -6,7 +6,8 @@ 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.0.2 SOVERSION 2)
|
set_target_properties(SC_3D_CollisionDetectionHelpers PROPERTIES VERSION 2.1.0 SOVERSION 2)
|
||||||
|
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 "")
|
||||||
message("Defaulting to \"Debug\" build type.")
|
message("Defaulting to \"Debug\" build type.")
|
||||||
|
|
|
@ -1,5 +1,13 @@
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## Version 2.1.0
|
||||||
|
|
||||||
|
Refactoring of internally used function(s).
|
||||||
|
|
||||||
|
This library now requires a compiler that supports C++20.
|
||||||
|
|
||||||
|
Add SC_SACD_Scale_Mat4(...) fn.
|
||||||
|
|
||||||
## Version 2.0.2
|
## Version 2.0.2
|
||||||
|
|
||||||
Fix SC_SACD_Translate_Mat4(...). It was missing a "1" in the first element of
|
Fix SC_SACD_Translate_Mat4(...). It was missing a "1" in the first element of
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
#include "sc_sacd.h"
|
#include "sc_sacd.h"
|
||||||
|
|
||||||
// Standard library includes.
|
// Standard library includes.
|
||||||
|
#include <array>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
#include <span>
|
||||||
#include <stdfloat>
|
#include <stdfloat>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
@ -60,9 +62,8 @@ SC_SACD_Vec3 operator*(const SC_SACD_Mat4 &mat, const SC_SACD_Vec3 &vec) {
|
||||||
vec.x * mat.z0 + vec.y * mat.z1 + vec.z * mat.z2 + mat.z3};
|
vec.x * mat.z0 + vec.y * mat.z1 + vec.z * mat.z2 + mat.z3};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<SC_SACD_Vec3> SC_SACD_Get_Box_Normals(
|
std::array<SC_SACD_Vec3, 3> SC_SACD_Get_Box_Normals(
|
||||||
const SC_SACD_Generic_Box *box) {
|
const SC_SACD_Generic_Box *box) {
|
||||||
std::vector<SC_SACD_Vec3> normals;
|
|
||||||
SC_SACD_Vec3 a, b, c;
|
SC_SACD_Vec3 a, b, c;
|
||||||
|
|
||||||
// Facing positive x-axis.
|
// Facing positive x-axis.
|
||||||
|
@ -85,7 +86,7 @@ std::vector<SC_SACD_Vec3> SC_SACD_Get_Box_Normals(
|
||||||
b = b - a;
|
b = b - a;
|
||||||
c = c - a;
|
c = c - a;
|
||||||
|
|
||||||
normals.push_back(SC_SACD_Cross_Product(b, c));
|
auto normal_x = SC_SACD_Cross_Product(b, c);
|
||||||
|
|
||||||
// Facing positive y-axis.
|
// Facing positive y-axis.
|
||||||
a.x = 0.0F;
|
a.x = 0.0F;
|
||||||
|
@ -107,7 +108,7 @@ std::vector<SC_SACD_Vec3> SC_SACD_Get_Box_Normals(
|
||||||
b = b - a;
|
b = b - a;
|
||||||
c = c - a;
|
c = c - a;
|
||||||
|
|
||||||
normals.push_back(SC_SACD_Cross_Product(b, c));
|
auto normal_y = SC_SACD_Cross_Product(b, c);
|
||||||
|
|
||||||
// Facing positive z-axis.
|
// Facing positive z-axis.
|
||||||
a.x = 0.0F;
|
a.x = 0.0F;
|
||||||
|
@ -129,14 +130,14 @@ std::vector<SC_SACD_Vec3> SC_SACD_Get_Box_Normals(
|
||||||
b = b - a;
|
b = b - a;
|
||||||
c = c - a;
|
c = c - a;
|
||||||
|
|
||||||
normals.push_back(SC_SACD_Cross_Product(b, c));
|
auto normal_z = SC_SACD_Cross_Product(b, c);
|
||||||
|
|
||||||
return normals;
|
return {normal_x, normal_y, normal_z};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<SC_SACD_Vec3> SC_SACD_Get_Box_Normals_Normalized(
|
std::array<SC_SACD_Vec3, 3> SC_SACD_Get_Box_Normals_Normalized(
|
||||||
const SC_SACD_Generic_Box *box) {
|
const SC_SACD_Generic_Box *box) {
|
||||||
std::vector<SC_SACD_Vec3> normals = SC_SACD_Get_Box_Normals(box);
|
auto normals = SC_SACD_Get_Box_Normals(box);
|
||||||
|
|
||||||
for (auto &normal : normals) {
|
for (auto &normal : normals) {
|
||||||
normal = normal / std::sqrt(SC_SACD_Dot_Product(normal, normal));
|
normal = normal / std::sqrt(SC_SACD_Dot_Product(normal, normal));
|
||||||
|
@ -213,7 +214,7 @@ struct SC_SACD_MinMax {
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<SC_SACD_MinMax> SC_SACD_Get_Box_MinMax(
|
std::vector<SC_SACD_MinMax> SC_SACD_Get_Box_MinMax(
|
||||||
const SC_SACD_Generic_Box *box, const std::vector<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);
|
std::vector<SC_SACD_Vec3> corners = SC_SACD_Get_Box_Corners(box);
|
||||||
|
@ -272,9 +273,14 @@ int SC_SACD_AABB_Box_Collision(const SC_SACD_AABB_Box *a,
|
||||||
int SC_SACD_Generic_Box_Collision(const SC_SACD_Generic_Box *a,
|
int SC_SACD_Generic_Box_Collision(const SC_SACD_Generic_Box *a,
|
||||||
const SC_SACD_Generic_Box *b) {
|
const SC_SACD_Generic_Box *b) {
|
||||||
// Get all normals.
|
// Get all normals.
|
||||||
std::vector<SC_SACD_Vec3> normals = SC_SACD_Get_Box_Normals(a);
|
std::vector<SC_SACD_Vec3> normals;
|
||||||
for (const auto &normal : SC_SACD_Get_Box_Normals(b)) {
|
{
|
||||||
normals.push_back(normal);
|
for (const auto &normal : SC_SACD_Get_Box_Normals(a)) {
|
||||||
|
normals.push_back(normal);
|
||||||
|
}
|
||||||
|
for (const auto &normal : SC_SACD_Get_Box_Normals(b)) {
|
||||||
|
normals.push_back(normal);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get all minmaxes.
|
// Get all minmaxes.
|
||||||
|
@ -344,27 +350,25 @@ int SC_SACD_Sphere_Box_Collision(const SC_SACD_Sphere *sphere,
|
||||||
// First check plane where normal = box_pos - sphere_pos.
|
// First check plane where normal = box_pos - sphere_pos.
|
||||||
|
|
||||||
SC_SACD_Vec3 sphere_pos{sphere->x, sphere->y, sphere->z};
|
SC_SACD_Vec3 sphere_pos{sphere->x, sphere->y, sphere->z};
|
||||||
SC_SACD_Vec3 sphere_box_normal =
|
std::array<SC_SACD_Vec3, 1> sphere_box_normal = {
|
||||||
SC_SACD_Vec3{box->x, box->y, box->z} - sphere_pos;
|
SC_SACD_Vec3{box->x, box->y, box->z} - sphere_pos};
|
||||||
if (sphere_box_normal.x < 0.0001F && sphere_box_normal.x > -0.0001F &&
|
if (sphere_box_normal[0].x < 0.0001F && sphere_box_normal[0].x > -0.0001F &&
|
||||||
sphere_box_normal.y < 0.0001F && sphere_box_normal.y > -0.0001F &&
|
sphere_box_normal[0].y < 0.0001F && sphere_box_normal[0].y > -0.0001F &&
|
||||||
sphere_box_normal.z < 0.0001F && sphere_box_normal.z > -0.0001F) {
|
sphere_box_normal[0].z < 0.0001F && sphere_box_normal[0].z > -0.0001F) {
|
||||||
// Sphere center is box center.
|
// Sphere center is box center.
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
sphere_box_normal =
|
sphere_box_normal[0] =
|
||||||
sphere_box_normal /
|
sphere_box_normal[0] / std::sqrt(SC_SACD_Dot_Product(
|
||||||
std::sqrt(SC_SACD_Dot_Product(sphere_box_normal, sphere_box_normal));
|
sphere_box_normal[0], sphere_box_normal[0]));
|
||||||
|
|
||||||
std::vector<SC_SACD_Vec3> normals{sphere_box_normal};
|
|
||||||
|
|
||||||
std::vector<SC_SACD_MinMax> box_minmaxes =
|
std::vector<SC_SACD_MinMax> box_minmaxes =
|
||||||
SC_SACD_Get_Box_MinMax(box, normals);
|
SC_SACD_Get_Box_MinMax(box, sphere_box_normal);
|
||||||
|
|
||||||
float projected_0 = SC_SACD_Dot_Product(
|
float projected_0 = SC_SACD_Dot_Product(
|
||||||
sphere_box_normal, sphere_pos + sphere_box_normal * sphere->radius);
|
sphere_box_normal[0], sphere_pos + sphere_box_normal[0] * sphere->radius);
|
||||||
float projected_1 = SC_SACD_Dot_Product(
|
float projected_1 = SC_SACD_Dot_Product(
|
||||||
sphere_box_normal, sphere_pos - sphere_box_normal * sphere->radius);
|
sphere_box_normal[0], sphere_pos - sphere_box_normal[0] * sphere->radius);
|
||||||
if (projected_0 < projected_1) {
|
if (projected_0 < projected_1) {
|
||||||
if (box_minmaxes[0].max < projected_0 ||
|
if (box_minmaxes[0].max < projected_0 ||
|
||||||
box_minmaxes[0].min > projected_1) {
|
box_minmaxes[0].min > projected_1) {
|
||||||
|
@ -377,13 +381,13 @@ int SC_SACD_Sphere_Box_Collision(const SC_SACD_Sphere *sphere,
|
||||||
|
|
||||||
// Next check the planes for the 3 normals of the box.
|
// Next check the planes for the 3 normals of the box.
|
||||||
|
|
||||||
normals = SC_SACD_Get_Box_Normals(box);
|
auto box_normals = SC_SACD_Get_Box_Normals(box);
|
||||||
box_minmaxes = SC_SACD_Get_Box_MinMax(box, normals);
|
box_minmaxes = SC_SACD_Get_Box_MinMax(box, box_normals);
|
||||||
for (unsigned int i = 0; i < normals.size(); ++i) {
|
for (unsigned int i = 0; i < box_normals.size(); ++i) {
|
||||||
projected_0 = SC_SACD_Dot_Product(normals[i],
|
projected_0 = SC_SACD_Dot_Product(
|
||||||
sphere_pos + normals[i] * sphere->radius);
|
box_normals[i], sphere_pos + box_normals[i] * sphere->radius);
|
||||||
projected_1 = SC_SACD_Dot_Product(normals[i],
|
projected_1 = SC_SACD_Dot_Product(
|
||||||
sphere_pos - normals[i] * sphere->radius);
|
box_normals[i], sphere_pos - box_normals[i] * sphere->radius);
|
||||||
if (projected_0 < projected_1) {
|
if (projected_0 < projected_1) {
|
||||||
if (box_minmaxes[i].max < projected_0 ||
|
if (box_minmaxes[i].max < projected_0 ||
|
||||||
box_minmaxes[i].min > projected_1) {
|
box_minmaxes[i].min > projected_1) {
|
||||||
|
@ -542,6 +546,11 @@ SC_SACD_Mat4 SC_SACD_Translate_Mat4(float x, float y, float z) {
|
||||||
0.0F, 0.0F, 1.0F, z, 0.0F, 0.0F, 0.0F, 1.0F};
|
0.0F, 0.0F, 1.0F, z, 0.0F, 0.0F, 0.0F, 1.0F};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SC_SACD_Mat4 SC_SACD_Scale_Mat4(float x, float y, float z) {
|
||||||
|
return SC_SACD_Mat4{x, 0.0F, 0.0F, 0.0F, 0.0F, y, 0.0F, 0.0F,
|
||||||
|
0.0F, 0.0F, z, 0.0F, 0.0F, 0.0F, 0.0F, 1.0F};
|
||||||
|
}
|
||||||
|
|
||||||
SC_SACD_Vec3 SC_SACD_Closest_Point_Dir_Normalized(const SC_SACD_Vec3 *pos,
|
SC_SACD_Vec3 SC_SACD_Closest_Point_Dir_Normalized(const SC_SACD_Vec3 *pos,
|
||||||
const SC_SACD_Vec3 *dir,
|
const SC_SACD_Vec3 *dir,
|
||||||
const SC_SACD_Vec3 *point) {
|
const SC_SACD_Vec3 *point) {
|
||||||
|
|
|
@ -119,6 +119,8 @@ SC_SACD_EXPORT SC_SACD_Mat4 SC_SACD_Rotation_Mat4_ZAxis(float z_radians);
|
||||||
|
|
||||||
SC_SACD_EXPORT SC_SACD_Mat4 SC_SACD_Translate_Mat4(float x, float y, float z);
|
SC_SACD_EXPORT SC_SACD_Mat4 SC_SACD_Translate_Mat4(float x, float y, float z);
|
||||||
|
|
||||||
|
SC_SACD_EXPORT SC_SACD_Mat4 SC_SACD_Scale_Mat4(float x, float y, float z);
|
||||||
|
|
||||||
/// This variant of Closest_Point expects "dir" to be a unit vector.
|
/// This variant of Closest_Point expects "dir" to be a unit vector.
|
||||||
SC_SACD_EXPORT SC_SACD_Vec3 SC_SACD_Closest_Point_Dir_Normalized(
|
SC_SACD_EXPORT SC_SACD_Vec3 SC_SACD_Closest_Point_Dir_Normalized(
|
||||||
const SC_SACD_Vec3 *pos, const SC_SACD_Vec3 *dir,
|
const SC_SACD_Vec3 *pos, const SC_SACD_Vec3 *dir,
|
||||||
|
|
42
src/test.cpp
42
src/test.cpp
|
@ -591,6 +591,48 @@ int main() {
|
||||||
CHECK_FALSE(SC_SACD_Generic_Box_Collision(&a, &b));
|
CHECK_FALSE(SC_SACD_Generic_Box_Collision(&a, &b));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Box with Scale Mat4.
|
||||||
|
{
|
||||||
|
SC_SACD_Generic_Box a = SC_SACD_Generic_Box_Default();
|
||||||
|
SC_SACD_Generic_Box b = SC_SACD_Generic_Box_Default();
|
||||||
|
|
||||||
|
a.x = 1.1F;
|
||||||
|
b.x = -1.1F;
|
||||||
|
CHECK_FALSE(SC_SACD_Generic_Box_Collision(&a, &b));
|
||||||
|
|
||||||
|
a.transform = SC_SACD_Scale_Mat4(2.0F, 1.0F, 1.0F);
|
||||||
|
CHECK_TRUE(SC_SACD_Generic_Box_Collision(&a, &b));
|
||||||
|
|
||||||
|
a.transform = SC_SACD_Scale_Mat4(-2.0F, 1.0F, 1.0F);
|
||||||
|
CHECK_TRUE(SC_SACD_Generic_Box_Collision(&a, &b));
|
||||||
|
|
||||||
|
a.x = 0.0F;
|
||||||
|
b.x = 0.0F;
|
||||||
|
a.y = 1.1F;
|
||||||
|
b.y = -1.1F;
|
||||||
|
a.transform = SC_SACD_Mat4_Identity();
|
||||||
|
CHECK_FALSE(SC_SACD_Generic_Box_Collision(&a, &b));
|
||||||
|
|
||||||
|
a.transform = SC_SACD_Scale_Mat4(1.0F, 2.0F, 1.0F);
|
||||||
|
CHECK_TRUE(SC_SACD_Generic_Box_Collision(&a, &b));
|
||||||
|
|
||||||
|
a.transform = SC_SACD_Scale_Mat4(1.0F, -2.0F, 1.0F);
|
||||||
|
CHECK_TRUE(SC_SACD_Generic_Box_Collision(&a, &b));
|
||||||
|
|
||||||
|
a.y = 0.0F;
|
||||||
|
b.y = 0.0F;
|
||||||
|
a.z = 1.1F;
|
||||||
|
b.z = -1.1F;
|
||||||
|
a.transform = SC_SACD_Mat4_Identity();
|
||||||
|
CHECK_FALSE(SC_SACD_Generic_Box_Collision(&a, &b));
|
||||||
|
|
||||||
|
a.transform = SC_SACD_Scale_Mat4(1.0F, 1.0F, 2.0F);
|
||||||
|
CHECK_TRUE(SC_SACD_Generic_Box_Collision(&a, &b));
|
||||||
|
|
||||||
|
a.transform = SC_SACD_Scale_Mat4(1.0F, 1.0F, -2.0F);
|
||||||
|
CHECK_TRUE(SC_SACD_Generic_Box_Collision(&a, &b));
|
||||||
|
}
|
||||||
|
|
||||||
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