Compare commits
No commits in common. "ff43e7c4d63325317294b15a0b2af219805665da" and "ecf5ce17457aeadc3e07e00078669954fea4ae98" have entirely different histories.
ff43e7c4d6
...
ecf5ce1745
4 changed files with 73 additions and 110 deletions
|
@ -6,10 +6,6 @@ Add collision detection with Spheres.
|
||||||
|
|
||||||
Add some more vector/matrix math stuff.
|
Add some more vector/matrix math stuff.
|
||||||
|
|
||||||
Replace Mat3 with Mat4.
|
|
||||||
|
|
||||||
Replace xyz-axis rotation floats in GenericBox with Mat4.
|
|
||||||
|
|
||||||
## Version 1.0.0
|
## Version 1.0.0
|
||||||
|
|
||||||
First version of this library.
|
First version of this library.
|
||||||
|
|
128
src/sc_sacd.cpp
128
src/sc_sacd.cpp
|
@ -65,33 +65,19 @@ std::vector<SC_SACD_Vec3> SC_SACD_Get_Box_Normals(
|
||||||
std::vector<SC_SACD_Vec3> normals;
|
std::vector<SC_SACD_Vec3> normals;
|
||||||
|
|
||||||
normals.emplace_back(SC_SACD_Vec3{1.0F, 0.0F, 0.0F});
|
normals.emplace_back(SC_SACD_Vec3{1.0F, 0.0F, 0.0F});
|
||||||
normals.back() = box->transform * normals.back();
|
normals.back() = SC_SACD_Vec3_Rotate(normals.back(), box->x_radians,
|
||||||
|
box->y_radians, box->z_radians);
|
||||||
|
|
||||||
normals.emplace_back(SC_SACD_Vec3{0.0F, 1.0F, 0.0F});
|
normals.emplace_back(SC_SACD_Vec3{0.0F, 1.0F, 0.0F});
|
||||||
normals.back() = box->transform * normals.back();
|
normals.back() = SC_SACD_Vec3_Rotate(normals.back(), box->x_radians,
|
||||||
|
box->y_radians, box->z_radians);
|
||||||
|
|
||||||
normals.emplace_back(SC_SACD_Vec3{0.0F, 0.0F, 1.0F});
|
normals.emplace_back(SC_SACD_Vec3{0.0F, 0.0F, 1.0F});
|
||||||
normals.back() = box->transform * normals.back();
|
normals.back() = SC_SACD_Vec3_Rotate(normals.back(), box->x_radians,
|
||||||
|
box->y_radians, box->z_radians);
|
||||||
return normals;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<SC_SACD_Vec3> SC_SACD_Get_Box_Normals_Normalized(
|
|
||||||
const SC_SACD_Generic_Box *box) {
|
|
||||||
std::vector<SC_SACD_Vec3> normals;
|
|
||||||
|
|
||||||
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());
|
|
||||||
|
|
||||||
|
// Not normalizing the normals on purpose for optimization. It should already
|
||||||
|
// be normalized as each normal is a rotated unit vector.
|
||||||
return normals;
|
return normals;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,61 +85,55 @@ std::vector<SC_SACD_Vec3> SC_SACD_Get_Box_Corners(
|
||||||
const SC_SACD_Generic_Box *box) {
|
const SC_SACD_Generic_Box *box) {
|
||||||
std::vector<SC_SACD_Vec3> corners;
|
std::vector<SC_SACD_Vec3> corners;
|
||||||
|
|
||||||
corners.push_back(box->transform * SC_SACD_Vec3{-box->width / 2.0F,
|
SC_SACD_Vec3 pos{box->x, box->y, box->z};
|
||||||
-box->height / 2.0F,
|
|
||||||
-box->depth / 2.0F});
|
|
||||||
corners.back().x += box->x;
|
|
||||||
corners.back().y += box->y;
|
|
||||||
corners.back().z += box->z;
|
|
||||||
|
|
||||||
corners.push_back(box->transform * SC_SACD_Vec3{box->width / 2.0F,
|
corners.push_back(
|
||||||
-box->height / 2.0F,
|
SC_SACD_Vec3_Rotate(SC_SACD_Vec3{-box->width / 2.0F, -box->height / 2.0F,
|
||||||
-box->depth / 2.0F});
|
-box->depth / 2.0F},
|
||||||
corners.back().x += box->x;
|
box->x_radians, box->y_radians, box->z_radians) +
|
||||||
corners.back().y += box->y;
|
pos);
|
||||||
corners.back().z += box->z;
|
|
||||||
|
|
||||||
corners.push_back(box->transform * SC_SACD_Vec3{-box->width / 2.0F,
|
corners.push_back(
|
||||||
box->height / 2.0F,
|
SC_SACD_Vec3_Rotate(SC_SACD_Vec3{box->width / 2.0F, -box->height / 2.0F,
|
||||||
-box->depth / 2.0F});
|
-box->depth / 2.0F},
|
||||||
corners.back().x += box->x;
|
box->x_radians, box->y_radians, box->z_radians) +
|
||||||
corners.back().y += box->y;
|
pos);
|
||||||
corners.back().z += box->z;
|
|
||||||
|
|
||||||
corners.push_back(box->transform * SC_SACD_Vec3{box->width / 2.0F,
|
corners.push_back(
|
||||||
box->height / 2.0F,
|
SC_SACD_Vec3_Rotate(SC_SACD_Vec3{-box->width / 2.0F, box->height / 2.0F,
|
||||||
-box->depth / 2.0F});
|
-box->depth / 2.0F},
|
||||||
corners.back().x += box->x;
|
box->x_radians, box->y_radians, box->z_radians) +
|
||||||
corners.back().y += box->y;
|
pos);
|
||||||
corners.back().z += box->z;
|
|
||||||
|
|
||||||
corners.push_back(box->transform * SC_SACD_Vec3{-box->width / 2.0F,
|
corners.push_back(
|
||||||
-box->height / 2.0F,
|
SC_SACD_Vec3_Rotate(SC_SACD_Vec3{box->width / 2.0F, box->height / 2.0F,
|
||||||
box->depth / 2.0F});
|
-box->depth / 2.0F},
|
||||||
corners.back().x += box->x;
|
box->x_radians, box->y_radians, box->z_radians) +
|
||||||
corners.back().y += box->y;
|
pos);
|
||||||
corners.back().z += box->z;
|
|
||||||
|
|
||||||
corners.push_back(box->transform * SC_SACD_Vec3{box->width / 2.0F,
|
corners.push_back(
|
||||||
-box->height / 2.0F,
|
SC_SACD_Vec3_Rotate(SC_SACD_Vec3{-box->width / 2.0F, -box->height / 2.0F,
|
||||||
box->depth / 2.0F});
|
box->depth / 2.0F},
|
||||||
corners.back().x += box->x;
|
box->x_radians, box->y_radians, box->z_radians) +
|
||||||
corners.back().y += box->y;
|
pos);
|
||||||
corners.back().z += box->z;
|
|
||||||
|
|
||||||
corners.push_back(box->transform * SC_SACD_Vec3{-box->width / 2.0F,
|
corners.push_back(
|
||||||
box->height / 2.0F,
|
SC_SACD_Vec3_Rotate(SC_SACD_Vec3{box->width / 2.0F, -box->height / 2.0F,
|
||||||
box->depth / 2.0F});
|
box->depth / 2.0F},
|
||||||
corners.back().x += box->x;
|
box->x_radians, box->y_radians, box->z_radians) +
|
||||||
corners.back().y += box->y;
|
pos);
|
||||||
corners.back().z += box->z;
|
|
||||||
|
|
||||||
corners.push_back(box->transform * SC_SACD_Vec3{box->width / 2.0F,
|
corners.push_back(
|
||||||
box->height / 2.0F,
|
SC_SACD_Vec3_Rotate(SC_SACD_Vec3{-box->width / 2.0F, box->height / 2.0F,
|
||||||
box->depth / 2.0F});
|
box->depth / 2.0F},
|
||||||
corners.back().x += box->x;
|
box->x_radians, box->y_radians, box->z_radians) +
|
||||||
corners.back().y += box->y;
|
pos);
|
||||||
corners.back().z += box->z;
|
|
||||||
|
corners.push_back(
|
||||||
|
SC_SACD_Vec3_Rotate(SC_SACD_Vec3{box->width / 2.0F, box->height / 2.0F,
|
||||||
|
box->depth / 2.0F},
|
||||||
|
box->x_radians, box->y_radians, box->z_radians) +
|
||||||
|
pos);
|
||||||
|
|
||||||
return corners;
|
return corners;
|
||||||
}
|
}
|
||||||
|
@ -246,7 +226,9 @@ int SC_SACD_AABB_Generic_Box_Collision(const SC_SACD_AABB_Box *a,
|
||||||
a_conv.width = a->width;
|
a_conv.width = a->width;
|
||||||
a_conv.height = a->height;
|
a_conv.height = a->height;
|
||||||
a_conv.depth = a->depth;
|
a_conv.depth = a->depth;
|
||||||
a_conv.transform = SC_SACD_Mat4_Identity();
|
a_conv.x_radians = 0.0F;
|
||||||
|
a_conv.y_radians = 0.0F;
|
||||||
|
a_conv.z_radians = 0.0F;
|
||||||
return SC_SACD_Generic_Box_Collision(&a_conv, b);
|
return SC_SACD_Generic_Box_Collision(&a_conv, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -496,7 +478,3 @@ SC_SACD_Vec3 SC_SACD_Closest_Point(const SC_SACD_Vec3 *pos,
|
||||||
SC_SACD_Dot_Product(*dir, *dir);
|
SC_SACD_Dot_Product(*dir, *dir);
|
||||||
return *pos + *dir * alpha;
|
return *pos + *dir * alpha;
|
||||||
}
|
}
|
||||||
|
|
||||||
float SC_SACD_Vec3_Length(const SC_SACD_Vec3 vec) {
|
|
||||||
return std::sqrt(SC_SACD_Dot_Product(vec, vec));
|
|
||||||
}
|
|
||||||
|
|
|
@ -55,8 +55,10 @@ typedef struct SC_SACD_EXPORT SC_SACD_Generic_Box {
|
||||||
float height;
|
float height;
|
||||||
/// z-axis depth.
|
/// z-axis depth.
|
||||||
float depth;
|
float depth;
|
||||||
/// Local transform; expects center of box as origin.
|
/// Rotation about center of box about axis.
|
||||||
SC_SACD_Mat4 transform;
|
float x_radians;
|
||||||
|
float y_radians;
|
||||||
|
float z_radians;
|
||||||
} SC_SACD_Generic_Box;
|
} SC_SACD_Generic_Box;
|
||||||
|
|
||||||
typedef struct SC_SACD_EXPORT SC_SACD_Sphere {
|
typedef struct SC_SACD_EXPORT SC_SACD_Sphere {
|
||||||
|
@ -78,15 +80,12 @@ SC_SACD_EXPORT int SC_SACD_Generic_Box_Collision(const SC_SACD_Generic_Box *a,
|
||||||
SC_SACD_EXPORT int SC_SACD_AABB_Generic_Box_Collision(
|
SC_SACD_EXPORT int SC_SACD_AABB_Generic_Box_Collision(
|
||||||
const SC_SACD_AABB_Box *a, const SC_SACD_Generic_Box *b);
|
const SC_SACD_AABB_Box *a, const SC_SACD_Generic_Box *b);
|
||||||
|
|
||||||
/// Returns non-zero if there is collision.
|
|
||||||
SC_SACD_EXPORT int SC_SACD_Sphere_Collision(const SC_SACD_Sphere *a,
|
SC_SACD_EXPORT int SC_SACD_Sphere_Collision(const SC_SACD_Sphere *a,
|
||||||
const SC_SACD_Sphere *b);
|
const SC_SACD_Sphere *b);
|
||||||
|
|
||||||
/// Returns non-zero if there is collision.
|
|
||||||
SC_SACD_EXPORT int SC_SACD_Sphere_AABB_Box_Collision(
|
SC_SACD_EXPORT int SC_SACD_Sphere_AABB_Box_Collision(
|
||||||
const SC_SACD_Sphere *sphere, const SC_SACD_AABB_Box *box);
|
const SC_SACD_Sphere *sphere, const SC_SACD_AABB_Box *box);
|
||||||
|
|
||||||
/// Returns non-zero if there is collision.
|
|
||||||
SC_SACD_EXPORT int SC_SACD_Sphere_Box_Collision(const SC_SACD_Sphere *sphere,
|
SC_SACD_EXPORT int SC_SACD_Sphere_Box_Collision(const SC_SACD_Sphere *sphere,
|
||||||
const SC_SACD_Generic_Box *box);
|
const SC_SACD_Generic_Box *box);
|
||||||
|
|
||||||
|
@ -104,7 +103,6 @@ SC_SACD_EXPORT SC_SACD_Mat4 SC_SACD_Mat4_Mult(const SC_SACD_Mat4 *a,
|
||||||
SC_SACD_EXPORT SC_SACD_Vec3 SC_SACD_Mat4_Vec3_Mult(const SC_SACD_Mat4 *mat,
|
SC_SACD_EXPORT SC_SACD_Vec3 SC_SACD_Mat4_Vec3_Mult(const SC_SACD_Mat4 *mat,
|
||||||
const SC_SACD_Vec3 vec);
|
const SC_SACD_Vec3 vec);
|
||||||
|
|
||||||
/// Rotates by x-axis first, then y-axis, then finally z-axis.
|
|
||||||
SC_SACD_EXPORT SC_SACD_Vec3 SC_SACD_Vec3_Rotate(const SC_SACD_Vec3 vec,
|
SC_SACD_EXPORT SC_SACD_Vec3 SC_SACD_Vec3_Rotate(const SC_SACD_Vec3 vec,
|
||||||
float x_axis, float y_axis,
|
float x_axis, float y_axis,
|
||||||
float z_axis);
|
float z_axis);
|
||||||
|
@ -123,8 +121,6 @@ SC_SACD_EXPORT SC_SACD_Vec3 SC_SACD_Closest_Point(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);
|
||||||
|
|
||||||
SC_SACD_EXPORT float SC_SACD_Vec3_Length(const SC_SACD_Vec3 vec);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
39
src/test.cpp
39
src/test.cpp
|
@ -96,10 +96,8 @@ int main() {
|
||||||
|
|
||||||
// Test Separating_Axis_Collision check.
|
// Test Separating_Axis_Collision check.
|
||||||
{
|
{
|
||||||
SC_SACD_Generic_Box a{
|
SC_SACD_Generic_Box a{0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F, 0.0F, 0.0F, 0.0F};
|
||||||
0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F, SC_SACD_Mat4_Identity()};
|
SC_SACD_Generic_Box b{0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F, 0.0F, 0.0F, 0.0F};
|
||||||
SC_SACD_Generic_Box b{
|
|
||||||
0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F, SC_SACD_Mat4_Identity()};
|
|
||||||
|
|
||||||
CHECK_TRUE(SC_SACD_Generic_Box_Collision(&a, &b));
|
CHECK_TRUE(SC_SACD_Generic_Box_Collision(&a, &b));
|
||||||
|
|
||||||
|
@ -108,37 +106,37 @@ int main() {
|
||||||
b.x = -1.1F;
|
b.x = -1.1F;
|
||||||
CHECK_FALSE(SC_SACD_Generic_Box_Collision(&a, &b));
|
CHECK_FALSE(SC_SACD_Generic_Box_Collision(&a, &b));
|
||||||
|
|
||||||
a.transform = SC_SACD_Rotation_Mat4_ZAxis(std::numbers::pi_v<float> / 4.0F);
|
a.z_radians = std::numbers::pi_v<float> / 4.0F;
|
||||||
b.transform = a.transform;
|
b.z_radians = a.z_radians;
|
||||||
CHECK_TRUE(SC_SACD_Generic_Box_Collision(&a, &b));
|
CHECK_TRUE(SC_SACD_Generic_Box_Collision(&a, &b));
|
||||||
b.x = 1.1F;
|
b.x = 1.1F;
|
||||||
CHECK_TRUE(SC_SACD_Generic_Box_Collision(&a, &b));
|
CHECK_TRUE(SC_SACD_Generic_Box_Collision(&a, &b));
|
||||||
|
|
||||||
b.x = 0.0F;
|
b.x = 0.0F;
|
||||||
b.y = 1.1F;
|
b.y = 1.1F;
|
||||||
a.transform = SC_SACD_Mat4_Identity();
|
a.z_radians = 0.0F;
|
||||||
b.transform = a.transform;
|
b.z_radians = 0.0F;
|
||||||
CHECK_FALSE(SC_SACD_Generic_Box_Collision(&a, &b));
|
CHECK_FALSE(SC_SACD_Generic_Box_Collision(&a, &b));
|
||||||
b.y = -1.1F;
|
b.y = -1.1F;
|
||||||
CHECK_FALSE(SC_SACD_Generic_Box_Collision(&a, &b));
|
CHECK_FALSE(SC_SACD_Generic_Box_Collision(&a, &b));
|
||||||
|
|
||||||
a.transform = SC_SACD_Rotation_Mat4_ZAxis(std::numbers::pi_v<float> / 4.0F);
|
a.z_radians = std::numbers::pi_v<float> / 4.0F;
|
||||||
b.transform = a.transform;
|
b.z_radians = a.z_radians;
|
||||||
CHECK_TRUE(SC_SACD_Generic_Box_Collision(&a, &b));
|
CHECK_TRUE(SC_SACD_Generic_Box_Collision(&a, &b));
|
||||||
b.y = 1.1F;
|
b.y = 1.1F;
|
||||||
CHECK_TRUE(SC_SACD_Generic_Box_Collision(&a, &b));
|
CHECK_TRUE(SC_SACD_Generic_Box_Collision(&a, &b));
|
||||||
|
|
||||||
b.y = 0.0F;
|
b.y = 0.0F;
|
||||||
a.transform = SC_SACD_Mat4_Identity();
|
a.z_radians = 0.0F;
|
||||||
b.transform = a.transform;
|
b.z_radians = 0.0F;
|
||||||
|
|
||||||
b.z = 1.1F;
|
b.z = 1.1F;
|
||||||
CHECK_FALSE(SC_SACD_Generic_Box_Collision(&a, &b));
|
CHECK_FALSE(SC_SACD_Generic_Box_Collision(&a, &b));
|
||||||
b.z = -1.1F;
|
b.z = -1.1F;
|
||||||
CHECK_FALSE(SC_SACD_Generic_Box_Collision(&a, &b));
|
CHECK_FALSE(SC_SACD_Generic_Box_Collision(&a, &b));
|
||||||
|
|
||||||
a.transform = SC_SACD_Rotation_Mat4_YAxis(std::numbers::pi_v<float> / 4.0F);
|
a.y_radians = std::numbers::pi_v<float> / 4.0F;
|
||||||
b.transform = a.transform;
|
b.y_radians = a.y_radians;
|
||||||
CHECK_TRUE(SC_SACD_Generic_Box_Collision(&a, &b));
|
CHECK_TRUE(SC_SACD_Generic_Box_Collision(&a, &b));
|
||||||
b.z = 1.1F;
|
b.z = 1.1F;
|
||||||
CHECK_TRUE(SC_SACD_Generic_Box_Collision(&a, &b));
|
CHECK_TRUE(SC_SACD_Generic_Box_Collision(&a, &b));
|
||||||
|
@ -238,14 +236,9 @@ int main() {
|
||||||
// Test Sphere/Generic_Box collision check.
|
// Test Sphere/Generic_Box collision check.
|
||||||
{
|
{
|
||||||
SC_SACD_Sphere sphere{0.0F, 0.0F, 0.0F, 1.0F};
|
SC_SACD_Sphere sphere{0.0F, 0.0F, 0.0F, 1.0F};
|
||||||
SC_SACD_Generic_Box box{
|
SC_SACD_Generic_Box box{0.0F, 0.0F, 0.0F,
|
||||||
0.0F,
|
2.0F, 2.0F, 2.0F,
|
||||||
0.0F,
|
0.0F, 0.0F, std::numbers::pi_v<float> / 4.0F};
|
||||||
0.0F,
|
|
||||||
2.0F,
|
|
||||||
2.0F,
|
|
||||||
2.0F,
|
|
||||||
SC_SACD_Rotation_Mat4_ZAxis(std::numbers::pi_v<float> / 4.0F)};
|
|
||||||
|
|
||||||
CHECK_TRUE(SC_SACD_Sphere_Box_Collision(&sphere, &box));
|
CHECK_TRUE(SC_SACD_Sphere_Box_Collision(&sphere, &box));
|
||||||
|
|
||||||
|
@ -571,5 +564,5 @@ int main() {
|
||||||
std::cout << "Checks checked: " << checks_checked << '\n'
|
std::cout << "Checks checked: " << checks_checked << '\n'
|
||||||
<< "Checks passed: " << checks_passed << '\n';
|
<< "Checks passed: " << checks_passed << '\n';
|
||||||
|
|
||||||
return checks_checked == checks_passed ? 0 : 1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue