Fix internal getting-normals function

Translation could have caused errors getting the three normals for the
sides of a box. The internal normals-fetching function was therefore
made more robust.
This commit is contained in:
Stephen Seo 2024-05-02 13:13:43 +09:00
parent 22f7663f38
commit 43ade068c9
2 changed files with 91 additions and 18 deletions

View file

@ -63,34 +63,84 @@ SC_SACD_Vec3 operator*(const SC_SACD_Mat4 &mat, const SC_SACD_Vec3 &vec) {
std::vector<SC_SACD_Vec3> 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; std::vector<SC_SACD_Vec3> normals;
SC_SACD_Vec3 a, b, c;
normals.emplace_back(SC_SACD_Vec3{1.0F, 0.0F, 0.0F}); // Facing positive x-axis.
normals.back() = box->transform * normals.back(); a.x = 0.0F;
a.y = 0.0F;
a.z = 0.0F;
normals.emplace_back(SC_SACD_Vec3{0.0F, 1.0F, 0.0F}); b.x = 0.0F;
normals.back() = box->transform * normals.back(); b.y = 1.0F;
b.z = 0.0F;
normals.emplace_back(SC_SACD_Vec3{0.0F, 0.0F, 1.0F}); c.x = 0.0F;
normals.back() = box->transform * normals.back(); 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; return normals;
} }
std::vector<SC_SACD_Vec3> 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) {
std::vector<SC_SACD_Vec3> normals; std::vector<SC_SACD_Vec3> normals = SC_SACD_Get_Box_Normals(box);
normals.emplace_back(SC_SACD_Vec3{1.0F, 0.0F, 0.0F}); for (auto &normal : normals) {
normals.back() = box->transform * normals.back(); normal = normal / std::sqrt(SC_SACD_Dot_Product(normal, normal));
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());
return normals; return normals;
} }

View file

@ -568,6 +568,29 @@ int main() {
CHECK_FLOAT(result.y, std::sqrt(2.0F)); 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' std::cout << "Checks checked: " << checks_checked << '\n'
<< "Checks passed: " << checks_passed << '\n'; << "Checks passed: " << checks_passed << '\n';