diff --git a/include/omath/collision/epa_algorithm.hpp b/include/omath/collision/epa_algorithm.hpp index 3ba34a4..dc85d57 100644 --- a/include/omath/collision/epa_algorithm.hpp +++ b/include/omath/collision/epa_algorithm.hpp @@ -6,6 +6,7 @@ #include #include #include +#include #include namespace omath::collision @@ -24,12 +25,13 @@ namespace omath::collision class Epa final { public: - explicit Epa( std::pmr::memory_resource* mem_resource = std::pmr::get_default_resource(), + explicit Epa(std::shared_ptr mem_resource = {std::shared_ptr{}, + std::pmr::get_default_resource()}, const int max_iterations = 64, const float tolerance = 1e-4f) - : m_memory_resource(mem_resource), m_max_iterations(max_iterations), m_tolerance(tolerance) + : m_memory_resource(std::move(mem_resource)), m_max_iterations(max_iterations), m_tolerance(tolerance) { } - std::pmr::memory_resource* m_memory_resource; + std::shared_ptr m_memory_resource; int m_max_iterations{64}; float m_tolerance{1e-4f}; using VectorType = ColliderType::VectorType; @@ -53,17 +55,17 @@ namespace omath::collision // Precondition: simplex.size()==4 and contains the origin. [[nodiscard]] - std::optional solve(const ColliderType& a, const ColliderType& b, - const Simplex& simplex, const Params params = {}) + std::optional solve(const ColliderType& a, const ColliderType& b, const Simplex& simplex, + const Params params = {}) { // --- Build initial polytope from simplex (4 points) --- - std::pmr::vector vertexes{m_memory_resource}; + std::pmr::vector vertexes{m_memory_resource.get()}; vertexes.reserve(64); for (std::size_t i = 0; i < simplex.size(); ++i) vertexes.push_back(simplex[i]); // Initial tetra faces (windings corrected in make_face) - std::pmr::vector faces{m_memory_resource}; + std::pmr::vector faces{m_memory_resource.get()}; faces.reserve(128); faces.emplace_back(make_face(vertexes, 0, 1, 2)); faces.emplace_back(make_face(vertexes, 0, 2, 3)); @@ -116,8 +118,8 @@ namespace omath::collision vertexes.push_back(p); // Mark faces visible from p and collect their horizon - std::vector to_delete(faces.size(), 0); - std::vector boundary; + std::pmr::vector to_delete(faces.size(), 0, m_memory_resource.get()); + std::pmr::vector boundary{m_memory_resource.get()}; boundary.reserve(faces.size() * 2); for (int i = 0; i < static_cast(faces.size()); ++i) @@ -135,7 +137,7 @@ namespace omath::collision } // Remove visible faces - std::pmr::vector new_faces; + std::pmr::vector new_faces{m_memory_resource.get()}; new_faces.reserve(faces.size() + boundary.size()); for (int i = 0; i < static_cast(faces.size()); ++i) if (!to_delete[i]) @@ -219,7 +221,7 @@ namespace omath::collision return (f.n.dot(p) - f.d) > 1e-7f; } - static void add_edge_boundary(std::vector& boundary, int a, int b) + static void add_edge_boundary(std::pmr::vector& boundary, int a, int b) { // Keep edges that appear only once; erase if opposite already present auto itb = diff --git a/tests/general/unit_test_epa.cpp b/tests/general/unit_test_epa.cpp index a8e8be7..4e686be 100644 --- a/tests/general/unit_test_epa.cpp +++ b/tests/general/unit_test_epa.cpp @@ -5,6 +5,7 @@ #include "omath/engines/source_engine/mesh.hpp" #include "omath/linear_algebra/vector3.hpp" #include +#include using Mesh = omath::source_engine::Mesh; using Collider = omath::source_engine::MeshCollider; @@ -41,9 +42,10 @@ TEST(UnitTestEpa, TestCollisionTrue) // EPA EPA::Params params; + auto pool = std::make_shared(1024); params.max_iterations = 64; params.tolerance = 1e-4f; - auto epa = EPA().solve(A, B, gjk.simplex, params); + auto epa = EPA(pool).solve(A, B, gjk.simplex, params); ASSERT_TRUE(epa.has_value()) << "EPA should converge"; // Normal is unit @@ -112,12 +114,12 @@ TEST(UnitTestEpa, TestCollisionTrue2) // --- GJK must detect collision and provide simplex --- auto gjk = GJK::is_collide_with_simplex_info(A, B); ASSERT_TRUE(gjk.hit) << "GJK should report collision for overlapping cubes"; - // --- EPA penetration --- EPA::Params params; params.max_iterations = 64; params.tolerance = 1e-4f; - auto epa = EPA().solve(A, B, gjk.simplex, params); + auto pool = std::make_shared(1024); + auto epa = EPA(pool).solve(A, B, gjk.simplex, params); ASSERT_TRUE(epa.has_value()) << "EPA should converge"; // Normal is unit-length