Compare commits

..

2 Commits

Author SHA1 Message Date
646a920e4c fixed potential deadlock 2026-02-27 08:47:46 +03:00
52687a70c7 fixed formating 2026-02-27 07:41:05 +03:00
2 changed files with 15 additions and 10 deletions

View File

@@ -14,11 +14,15 @@ namespace omath::collision
Simplex<VertexType> simplex; // valid only if hit == true and size==4 Simplex<VertexType> simplex; // valid only if hit == true and size==4
}; };
struct GjkSettings final
{
float epsilon = 1e-6f;
std::size_t max_iterations = 64;
};
template<class ColliderInterfaceType> template<class ColliderInterfaceType>
class GjkAlgorithm final class GjkAlgorithm final
{ {
using VectorType = ColliderInterfaceType::VectorType; using VectorType = ColliderInterfaceType::VectorType;
public: public:
[[nodiscard]] [[nodiscard]]
static VectorType find_support_vertex(const ColliderInterfaceType& collider_a, static VectorType find_support_vertex(const ColliderInterfaceType& collider_a,
@@ -36,7 +40,8 @@ namespace omath::collision
[[nodiscard]] [[nodiscard]]
static GjkHitInfo<VectorType> is_collide_with_simplex_info(const ColliderInterfaceType& collider_a, static GjkHitInfo<VectorType> is_collide_with_simplex_info(const ColliderInterfaceType& collider_a,
const ColliderInterfaceType& collider_b) const ColliderInterfaceType& collider_b,
const GjkSettings& settings = {})
{ {
auto support = find_support_vertex(collider_a, collider_b, VectorType{1, 0, 0}); auto support = find_support_vertex(collider_a, collider_b, VectorType{1, 0, 0});
@@ -45,11 +50,11 @@ namespace omath::collision
auto direction = -support; auto direction = -support;
while (true) for (std::size_t iteration = 0; iteration < settings.max_iterations; ++iteration)
{ {
support = find_support_vertex(collider_a, collider_b, direction); support = find_support_vertex(collider_a, collider_b, direction);
if (support.dot(direction) <= 0.f) if (support.dot(direction) <= settings.epsilon)
return {false, simplex}; return {false, simplex};
simplex.push_front(support); simplex.push_front(support);
@@ -57,6 +62,7 @@ namespace omath::collision
if (simplex.handle(direction)) if (simplex.handle(direction))
return {true, simplex}; return {true, simplex};
} }
return {false, simplex};
} }
}; };
} // namespace omath::collision } // namespace omath::collision

View File

@@ -60,12 +60,11 @@ namespace omath::collision
// d_local[j] = sum_i M.at(i,j) * d[i] (i.e. column j of M dotted with d) // d_local[j] = sum_i M.at(i,j) * d[i] (i.e. column j of M dotted with d)
const auto& m = m_mesh.get_to_world_matrix(); const auto& m = m_mesh.get_to_world_matrix();
const VectorType d_local = { const VectorType d_local = {
m.at(0, 0) * direction.x + m.at(1, 0) * direction.y + m.at(2, 0) * direction.z, m[0, 0] * direction.x + m[1, 0] * direction.y + m[2, 0] * direction.z,
m.at(0, 1) * direction.x + m.at(1, 1) * direction.y + m.at(2, 1) * direction.z, m[0, 1] * direction.x + m[1, 1] * direction.y + m[2, 1] * direction.z,
m.at(0, 2) * direction.x + m.at(1, 2) * direction.y + m.at(2, 2) * direction.z, m[0, 2] * direction.x + m[1, 2] * direction.y + m[2, 2] * direction.z,
}; };
return *std::ranges::max_element( return *std::ranges::max_element(m_mesh.m_vertex_buffer, [&d_local](const auto& first, const auto& second)
m_mesh.m_vertex_buffer, [&d_local](const auto& first, const auto& second)
{ return first.position.dot(d_local) < second.position.dot(d_local); }); { return first.position.dot(d_local) < second.position.dot(d_local); });
} }
MeshType m_mesh; MeshType m_mesh;