#include "omath/collision/epa_algorithm.hpp" #include "omath/collision/simplex.hpp" #include "omath/linear_algebra/vector3.hpp" #include using Vector3f = omath::Vector3; // Minimal collider interface matching Epa's expectations struct DegenerateCollider { using VectorType = Vector3f; // returns furthest point along dir [[nodiscard]] static VectorType find_abs_furthest_vertex_position(const VectorType& dir) noexcept { // Always return points on a small circle in XY plane so some faces become degenerate if (dir.x > 0.5f) return {0.01f, 0.f, 0.f}; if (dir.x < -0.5f) return {-0.01f, 0.f, 0.f}; if (dir.y > 0.5f) return {0.f, 0.01f, 0.f}; if (dir.y < -0.5f) return {0.f, -0.01f, 0.f}; return {0.f, 0.f, 0.01f}; } }; using Epa = omath::collision::Epa; using Simplex = omath::collision::Simplex; TEST(EpaExtra, DegenerateFaceHandled) { // Prepare a simplex with near-collinear points to force degenerate face handling Simplex s; s = { Vector3f{0.01f, 0.f, 0.f}, Vector3f{0.02f, 0.f, 0.f}, Vector3f{0.03f, 0.f, 0.f}, Vector3f{0.0f, 0.0f, 0.01f} }; constexpr DegenerateCollider a; constexpr DegenerateCollider b; Epa::Params params; params.max_iterations = 4; params.tolerance = 1e-6f; const auto result = Epa::solve(a, b, s, params); // The algorithm should either return a valid result or gracefully exit (not crash) if (result) { EXPECT_TRUE(std::isfinite(result->depth)); EXPECT_TRUE(std::isfinite(result->normal.x)); } else { SUCCEED() << "EPA returned nullopt for degenerate input (acceptable)"; } }