55#include < cmath>
66#include < cstdint>
77#include < limits>
8+ #include < memory>
89#include < queue>
10+ #include < utility>
911#include < vector>
12+ #include < memory_resource>
1013
1114namespace omath ::collision
1215{
@@ -46,17 +49,19 @@ namespace omath::collision
4649 // Precondition: simplex.size()==4 and contains the origin.
4750 [[nodiscard]]
4851 static std::optional<Result> solve (const ColliderType& a, const ColliderType& b,
49- const Simplex<VectorType>& simplex, const Params params = {})
52+ const Simplex<VectorType>& simplex, const Params params = {},
53+ std::shared_ptr<std::pmr::memory_resource> mem_resource = {
54+ std::shared_ptr<void >{}, std::pmr::get_default_resource ()})
5055 {
5156 // --- Build initial polytope from simplex (4 points) ---
52- std::vector<VectorType> vertexes;
53- vertexes.reserve (64 );
57+ std::pmr:: vector<VectorType> vertexes{mem_resource. get ()} ;
58+ vertexes.reserve (simplex. size () );
5459 for (std::size_t i = 0 ; i < simplex.size (); ++i)
55- vertexes.push_back (simplex[i]);
60+ vertexes.emplace_back (simplex[i]);
5661
5762 // Initial tetra faces (windings corrected in make_face)
58- std::vector<Face> faces;
59- faces.reserve (128 );
63+ std::pmr:: vector<Face> faces{mem_resource. get ()} ;
64+ faces.reserve (4 );
6065 faces.emplace_back (make_face (vertexes, 0 , 1 , 2 ));
6166 faces.emplace_back (make_face (vertexes, 0 , 2 , 3 ));
6267 faces.emplace_back (make_face (vertexes, 0 , 3 , 1 ));
@@ -83,7 +88,7 @@ namespace omath::collision
8388 const int fidx = heap.top ().idx ;
8489 const Face f = faces[fidx];
8590
86- // Get farthest point in face normal direction
91+ // Get the furthest point in face normal direction
8792 const VectorType p = support_point (a, b, f.n );
8893 const float p_dist = f.n .dot (p);
8994
@@ -105,11 +110,11 @@ namespace omath::collision
105110
106111 // Add new vertex
107112 const int new_idx = static_cast <int >(vertexes.size ());
108- vertexes.push_back (p);
113+ vertexes.emplace_back (p);
109114
110115 // Mark faces visible from p and collect their horizon
111- std::vector<char > to_delete (faces.size (), 0 );
112- std::vector<Edge> boundary;
116+ std::pmr:: vector<bool > to_delete (faces.size (), false , mem_resource. get ()); // uses single bits
117+ std::pmr:: vector<Edge> boundary{mem_resource. get ()} ;
113118 boundary.reserve (faces.size () * 2 );
114119
115120 for (int i = 0 ; i < static_cast <int >(faces.size ()); ++i)
@@ -119,24 +124,24 @@ namespace omath::collision
119124 if (visible_from (faces[i], p))
120125 {
121126 const auto & rf = faces[i];
122- to_delete[i] = 1 ;
127+ to_delete[i] = true ;
123128 add_edge_boundary (boundary, rf.i0 , rf.i1 );
124129 add_edge_boundary (boundary, rf.i1 , rf.i2 );
125130 add_edge_boundary (boundary, rf.i2 , rf.i0 );
126131 }
127132 }
128133
129134 // Remove visible faces
130- std::vector<Face> new_faces;
135+ std::pmr:: vector<Face> new_faces{mem_resource. get ()} ;
131136 new_faces.reserve (faces.size () + boundary.size ());
132137 for (int i = 0 ; i < static_cast <int >(faces.size ()); ++i)
133138 if (!to_delete[i])
134- new_faces.push_back (faces[i]);
139+ new_faces.emplace_back (faces[i]);
135140 faces.swap (new_faces);
136141
137142 // Stitch new faces around the horizon
138143 for (const auto & e : boundary)
139- faces.push_back (make_face (vertexes, e.a , e.b , new_idx));
144+ faces.emplace_back (make_face (vertexes, e.a , e.b , new_idx));
140145
141146 // Rebuild heap after topology change
142147 heap = rebuild_heap (faces);
@@ -188,42 +193,42 @@ namespace omath::collision
188193 };
189194 struct HeapCmp final
190195 {
191- bool operator ()(const HeapItem& lhs, const HeapItem& rhs) const noexcept
196+ [[nodiscard]]
197+ static bool operator ()(const HeapItem& lhs, const HeapItem& rhs) noexcept
192198 {
193199 return lhs.d > rhs.d ; // min-heap by distance
194200 }
195201 };
196202 using Heap = std::priority_queue<HeapItem, std::vector<HeapItem>, HeapCmp>;
197203
198204 [[nodiscard]]
199- static Heap rebuild_heap (const std::vector<Face>& faces)
205+ static Heap rebuild_heap (const std::pmr:: vector<Face>& faces)
200206 {
201207 Heap h;
202208 for (int i = 0 ; i < static_cast <int >(faces.size ()); ++i)
203- h.push ({ faces[i].d , i} );
209+ h.emplace ( faces[i].d , i);
204210 return h;
205211 }
206212
207213 [[nodiscard]]
208214 static bool visible_from (const Face& f, const VectorType& p)
209215 {
210216 // positive if p is in front of the face
211- return ( f.n .dot (p) - f.d ) > 1e-7f ;
217+ return f.n .dot (p) - f.d > 1e-7f ;
212218 }
213219
214- static void add_edge_boundary (std::vector<Edge>& boundary, int a, int b)
220+ static void add_edge_boundary (std::pmr:: vector<Edge>& boundary, int a, int b)
215221 {
216222 // Keep edges that appear only once; erase if opposite already present
217- auto itb =
218- std::find_if (boundary.begin (), boundary.end (), [&](const Edge& e) { return e.a == b && e.b == a; });
223+ auto itb = std::ranges::find_if (boundary, [&](const Edge& e) { return e.a == b && e.b == a; });
219224 if (itb != boundary.end ())
220225 boundary.erase (itb); // internal edge cancels out
221226 else
222- boundary.push_back ({ a, b} ); // horizon edge (directed)
227+ boundary.emplace_back ( a, b); // horizon edge (directed)
223228 }
224229
225230 [[nodiscard]]
226- static Face make_face (const std::vector<VectorType>& vertexes, int i0, int i1, int i2)
231+ static Face make_face (const std::pmr:: vector<VectorType>& vertexes, int i0, int i1, int i2)
227232 {
228233 const VectorType& a0 = vertexes[i0];
229234 const VectorType& a1 = vertexes[i1];
0 commit comments