Compare commits

..

No commits in common. "7e4041e50fcec154535d44fa732d60b9bdaf81b9" and "5a1413bda92de2582332c390abe3088ea5125278" have entirely different histories.

5 changed files with 33 additions and 95 deletions

View file

@ -6,8 +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.0.2 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.")

View file

@ -1,13 +1,5 @@
# 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

View file

@ -1,9 +1,7 @@
#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>
@ -62,8 +60,9 @@ 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::array<SC_SACD_Vec3, 3> SC_SACD_Get_Box_Normals( std::vector<SC_SACD_Vec3> 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.
@ -86,7 +85,7 @@ std::array<SC_SACD_Vec3, 3> SC_SACD_Get_Box_Normals(
b = b - a; b = b - a;
c = c - a; c = c - a;
auto normal_x = SC_SACD_Cross_Product(b, c); normals.push_back(SC_SACD_Cross_Product(b, c));
// Facing positive y-axis. // Facing positive y-axis.
a.x = 0.0F; a.x = 0.0F;
@ -108,7 +107,7 @@ std::array<SC_SACD_Vec3, 3> SC_SACD_Get_Box_Normals(
b = b - a; b = b - a;
c = c - a; c = c - a;
auto normal_y = SC_SACD_Cross_Product(b, c); normals.push_back(SC_SACD_Cross_Product(b, c));
// Facing positive z-axis. // Facing positive z-axis.
a.x = 0.0F; a.x = 0.0F;
@ -130,14 +129,14 @@ std::array<SC_SACD_Vec3, 3> SC_SACD_Get_Box_Normals(
b = b - a; b = b - a;
c = c - a; c = c - a;
auto normal_z = SC_SACD_Cross_Product(b, c); normals.push_back(SC_SACD_Cross_Product(b, c));
return {normal_x, normal_y, normal_z}; return normals;
} }
std::array<SC_SACD_Vec3, 3> SC_SACD_Get_Box_Normals_Normalized( std::vector<SC_SACD_Vec3> SC_SACD_Get_Box_Normals_Normalized(
const SC_SACD_Generic_Box *box) { const SC_SACD_Generic_Box *box) {
auto normals = SC_SACD_Get_Box_Normals(box); std::vector<SC_SACD_Vec3> 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));
@ -214,7 +213,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::span<SC_SACD_Vec3> normals) { const SC_SACD_Generic_Box *box, const std::vector<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);
@ -273,14 +272,9 @@ 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; std::vector<SC_SACD_Vec3> normals = SC_SACD_Get_Box_Normals(a);
{ for (const auto &normal : SC_SACD_Get_Box_Normals(b)) {
for (const auto &normal : SC_SACD_Get_Box_Normals(a)) { normals.push_back(normal);
normals.push_back(normal);
}
for (const auto &normal : SC_SACD_Get_Box_Normals(b)) {
normals.push_back(normal);
}
} }
// Get all minmaxes. // Get all minmaxes.
@ -350,25 +344,27 @@ 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};
std::array<SC_SACD_Vec3, 1> sphere_box_normal = { SC_SACD_Vec3 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[0].x < 0.0001F && sphere_box_normal[0].x > -0.0001F && if (sphere_box_normal.x < 0.0001F && sphere_box_normal.x > -0.0001F &&
sphere_box_normal[0].y < 0.0001F && sphere_box_normal[0].y > -0.0001F && sphere_box_normal.y < 0.0001F && sphere_box_normal.y > -0.0001F &&
sphere_box_normal[0].z < 0.0001F && sphere_box_normal[0].z > -0.0001F) { sphere_box_normal.z < 0.0001F && sphere_box_normal.z > -0.0001F) {
// Sphere center is box center. // Sphere center is box center.
return 1; return 1;
} }
sphere_box_normal[0] = sphere_box_normal =
sphere_box_normal[0] / std::sqrt(SC_SACD_Dot_Product( sphere_box_normal /
sphere_box_normal[0], sphere_box_normal[0])); std::sqrt(SC_SACD_Dot_Product(sphere_box_normal, sphere_box_normal));
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, sphere_box_normal); SC_SACD_Get_Box_MinMax(box, normals);
float projected_0 = SC_SACD_Dot_Product( float projected_0 = SC_SACD_Dot_Product(
sphere_box_normal[0], sphere_pos + sphere_box_normal[0] * sphere->radius); sphere_box_normal, sphere_pos + sphere_box_normal * sphere->radius);
float projected_1 = SC_SACD_Dot_Product( float projected_1 = SC_SACD_Dot_Product(
sphere_box_normal[0], sphere_pos - sphere_box_normal[0] * sphere->radius); sphere_box_normal, sphere_pos - sphere_box_normal * 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) {
@ -381,13 +377,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.
auto box_normals = SC_SACD_Get_Box_Normals(box); normals = SC_SACD_Get_Box_Normals(box);
box_minmaxes = SC_SACD_Get_Box_MinMax(box, box_normals); box_minmaxes = SC_SACD_Get_Box_MinMax(box, normals);
for (unsigned int i = 0; i < box_normals.size(); ++i) { for (unsigned int i = 0; i < normals.size(); ++i) {
projected_0 = SC_SACD_Dot_Product( projected_0 = SC_SACD_Dot_Product(normals[i],
box_normals[i], sphere_pos + box_normals[i] * sphere->radius); sphere_pos + normals[i] * sphere->radius);
projected_1 = SC_SACD_Dot_Product( projected_1 = SC_SACD_Dot_Product(normals[i],
box_normals[i], sphere_pos - box_normals[i] * sphere->radius); sphere_pos - 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) {
@ -546,11 +542,6 @@ 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) {

View file

@ -119,8 +119,6 @@ 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,

View file

@ -591,48 +591,6 @@ 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';