switched to shared_ptr

This commit is contained in:
2025-12-03 13:30:05 +03:00
parent 918858e255
commit d4d8f70fff
2 changed files with 18 additions and 14 deletions

View File

@@ -6,6 +6,7 @@
#include <cstdint> #include <cstdint>
#include <limits> #include <limits>
#include <queue> #include <queue>
#include <utility>
#include <vector> #include <vector>
namespace omath::collision namespace omath::collision
@@ -24,12 +25,13 @@ namespace omath::collision
class Epa final class Epa final
{ {
public: public:
explicit Epa( std::pmr::memory_resource* mem_resource = std::pmr::get_default_resource(), explicit Epa(std::shared_ptr<std::pmr::memory_resource> mem_resource = {std::shared_ptr<void>{},
std::pmr::get_default_resource()},
const int max_iterations = 64, const float tolerance = 1e-4f) 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<std::pmr::memory_resource> m_memory_resource;
int m_max_iterations{64}; int m_max_iterations{64};
float m_tolerance{1e-4f}; float m_tolerance{1e-4f};
using VectorType = ColliderType::VectorType; using VectorType = ColliderType::VectorType;
@@ -53,17 +55,17 @@ namespace omath::collision
// Precondition: simplex.size()==4 and contains the origin. // Precondition: simplex.size()==4 and contains the origin.
[[nodiscard]] [[nodiscard]]
std::optional<Result> solve(const ColliderType& a, const ColliderType& b, std::optional<Result> solve(const ColliderType& a, const ColliderType& b, const Simplex<VectorType>& simplex,
const Simplex<VectorType>& simplex, const Params params = {}) const Params params = {})
{ {
// --- Build initial polytope from simplex (4 points) --- // --- Build initial polytope from simplex (4 points) ---
std::pmr::vector<VectorType> vertexes{m_memory_resource}; std::pmr::vector<VectorType> vertexes{m_memory_resource.get()};
vertexes.reserve(64); vertexes.reserve(64);
for (std::size_t i = 0; i < simplex.size(); ++i) for (std::size_t i = 0; i < simplex.size(); ++i)
vertexes.push_back(simplex[i]); vertexes.push_back(simplex[i]);
// Initial tetra faces (windings corrected in make_face) // Initial tetra faces (windings corrected in make_face)
std::pmr::vector<Face> faces{m_memory_resource}; std::pmr::vector<Face> faces{m_memory_resource.get()};
faces.reserve(128); faces.reserve(128);
faces.emplace_back(make_face(vertexes, 0, 1, 2)); faces.emplace_back(make_face(vertexes, 0, 1, 2));
faces.emplace_back(make_face(vertexes, 0, 2, 3)); faces.emplace_back(make_face(vertexes, 0, 2, 3));
@@ -116,8 +118,8 @@ namespace omath::collision
vertexes.push_back(p); vertexes.push_back(p);
// Mark faces visible from p and collect their horizon // Mark faces visible from p and collect their horizon
std::vector<char> to_delete(faces.size(), 0); std::pmr::vector<char> to_delete(faces.size(), 0, m_memory_resource.get());
std::vector<Edge> boundary; std::pmr::vector<Edge> boundary{m_memory_resource.get()};
boundary.reserve(faces.size() * 2); boundary.reserve(faces.size() * 2);
for (int i = 0; i < static_cast<int>(faces.size()); ++i) for (int i = 0; i < static_cast<int>(faces.size()); ++i)
@@ -135,7 +137,7 @@ namespace omath::collision
} }
// Remove visible faces // Remove visible faces
std::pmr::vector<Face> new_faces; std::pmr::vector<Face> new_faces{m_memory_resource.get()};
new_faces.reserve(faces.size() + boundary.size()); new_faces.reserve(faces.size() + boundary.size());
for (int i = 0; i < static_cast<int>(faces.size()); ++i) for (int i = 0; i < static_cast<int>(faces.size()); ++i)
if (!to_delete[i]) if (!to_delete[i])
@@ -219,7 +221,7 @@ namespace omath::collision
return (f.n.dot(p) - f.d) > 1e-7f; return (f.n.dot(p) - f.d) > 1e-7f;
} }
static void add_edge_boundary(std::vector<Edge>& boundary, int a, int b) static void add_edge_boundary(std::pmr::vector<Edge>& boundary, int a, int b)
{ {
// Keep edges that appear only once; erase if opposite already present // Keep edges that appear only once; erase if opposite already present
auto itb = auto itb =

View File

@@ -5,6 +5,7 @@
#include "omath/engines/source_engine/mesh.hpp" #include "omath/engines/source_engine/mesh.hpp"
#include "omath/linear_algebra/vector3.hpp" #include "omath/linear_algebra/vector3.hpp"
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <memory_resource>
using Mesh = omath::source_engine::Mesh; using Mesh = omath::source_engine::Mesh;
using Collider = omath::source_engine::MeshCollider; using Collider = omath::source_engine::MeshCollider;
@@ -41,9 +42,10 @@ TEST(UnitTestEpa, TestCollisionTrue)
// EPA // EPA
EPA::Params params; EPA::Params params;
auto pool = std::make_shared<std::pmr::monotonic_buffer_resource>(1024);
params.max_iterations = 64; params.max_iterations = 64;
params.tolerance = 1e-4f; 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"; ASSERT_TRUE(epa.has_value()) << "EPA should converge";
// Normal is unit // Normal is unit
@@ -112,12 +114,12 @@ TEST(UnitTestEpa, TestCollisionTrue2)
// --- GJK must detect collision and provide simplex --- // --- GJK must detect collision and provide simplex ---
auto gjk = GJK::is_collide_with_simplex_info(A, B); auto gjk = GJK::is_collide_with_simplex_info(A, B);
ASSERT_TRUE(gjk.hit) << "GJK should report collision for overlapping cubes"; ASSERT_TRUE(gjk.hit) << "GJK should report collision for overlapping cubes";
// --- EPA penetration --- // --- EPA penetration ---
EPA::Params params; EPA::Params params;
params.max_iterations = 64; params.max_iterations = 64;
params.tolerance = 1e-4f; params.tolerance = 1e-4f;
auto epa = EPA().solve(A, B, gjk.simplex, params); auto pool = std::make_shared<std::pmr::monotonic_buffer_resource>(1024);
auto epa = EPA(pool).solve(A, B, gjk.simplex, params);
ASSERT_TRUE(epa.has_value()) << "EPA should converge"; ASSERT_TRUE(epa.has_value()) << "EPA should converge";
// Normal is unit-length // Normal is unit-length