mirror of
https://github.com/orange-cpp/omath.git
synced 2026-04-19 10:23:27 +00:00
Compare commits
2 Commits
a9eff7d320
...
646a920e4c
| Author | SHA1 | Date | |
|---|---|---|---|
| 646a920e4c | |||
| 52687a70c7 |
@@ -14,11 +14,15 @@ namespace omath::collision
|
||||
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>
|
||||
class GjkAlgorithm final
|
||||
{
|
||||
using VectorType = ColliderInterfaceType::VectorType;
|
||||
|
||||
public:
|
||||
[[nodiscard]]
|
||||
static VectorType find_support_vertex(const ColliderInterfaceType& collider_a,
|
||||
@@ -36,7 +40,8 @@ namespace omath::collision
|
||||
|
||||
[[nodiscard]]
|
||||
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});
|
||||
|
||||
@@ -45,11 +50,11 @@ namespace omath::collision
|
||||
|
||||
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);
|
||||
|
||||
if (support.dot(direction) <= 0.f)
|
||||
if (support.dot(direction) <= settings.epsilon)
|
||||
return {false, simplex};
|
||||
|
||||
simplex.push_front(support);
|
||||
@@ -57,6 +62,7 @@ namespace omath::collision
|
||||
if (simplex.handle(direction))
|
||||
return {true, simplex};
|
||||
}
|
||||
return {false, simplex};
|
||||
}
|
||||
};
|
||||
} // namespace omath::collision
|
||||
@@ -60,13 +60,12 @@ namespace omath::collision
|
||||
// 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 VectorType d_local = {
|
||||
m.at(0, 0) * direction.x + m.at(1, 0) * direction.y + m.at(2, 0) * direction.z,
|
||||
m.at(0, 1) * direction.x + m.at(1, 1) * direction.y + m.at(2, 1) * direction.z,
|
||||
m.at(0, 2) * direction.x + m.at(1, 2) * direction.y + m.at(2, 2) * direction.z,
|
||||
m[0, 0] * direction.x + m[1, 0] * direction.y + m[2, 0] * direction.z,
|
||||
m[0, 1] * direction.x + m[1, 1] * direction.y + m[2, 1] * direction.z,
|
||||
m[0, 2] * direction.x + m[1, 2] * direction.y + m[2, 2] * direction.z,
|
||||
};
|
||||
return *std::ranges::max_element(
|
||||
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 *std::ranges::max_element(m_mesh.m_vertex_buffer, [&d_local](const auto& first, const auto& second)
|
||||
{ return first.position.dot(d_local) < second.position.dot(d_local); });
|
||||
}
|
||||
MeshType m_mesh;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user