Skip to content

Commit 9efabd8

Browse files
authored
Merge pull request #102 from orange-cpp/feature/gjk_algorithm
Feature/gjk algorithm
2 parents 10ebf6e + 8f225c5 commit 9efabd8

File tree

24 files changed

+757
-12
lines changed

24 files changed

+757
-12
lines changed

.idea/editor.xml

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
//
2+
// Created by Vladislav on 09.11.2025.
3+
//
4+
#pragma once
5+
#include "omath/linear_algebra/triangle.hpp"
6+
#include <omath/linear_algebra/mat.hpp>
7+
#include <omath/linear_algebra/vector3.hpp>
8+
#include <utility>
9+
#include <vector>
10+
11+
namespace omath::primitives
12+
{
13+
template<class Mat4X4, class RotationAngles, class MeshTypeTrait, class Type = float>
14+
class Mesh final
15+
{
16+
public:
17+
using NumericType = Type;
18+
19+
private:
20+
using Vbo = std::vector<Vector3<NumericType>>;
21+
using Vao = std::vector<Vector3<std::size_t>>;
22+
23+
public:
24+
Vbo m_vertex_buffer;
25+
Vao m_vertex_array_object;
26+
27+
Mesh(Vbo vbo, Vao vao, const Vector3<NumericType> scale = {1, 1, 1,})
28+
: m_vertex_buffer(std::move(vbo)), m_vertex_array_object(std::move(vao)), m_scale(scale)
29+
{
30+
}
31+
void set_origin(const Vector3<NumericType>& new_origin)
32+
{
33+
m_origin = new_origin;
34+
m_to_world_matrix = std::nullopt;
35+
}
36+
37+
void set_scale(const Vector3<NumericType>& new_scale)
38+
{
39+
m_scale = new_scale;
40+
m_to_world_matrix = std::nullopt;
41+
}
42+
43+
void set_rotation(const RotationAngles& new_rotation_angles)
44+
{
45+
m_rotation_angles = new_rotation_angles;
46+
m_to_world_matrix = std::nullopt;
47+
}
48+
49+
[[nodiscard]]
50+
const Vector3<NumericType>& get_origin() const
51+
{
52+
return m_origin;
53+
}
54+
55+
[[nodiscard]]
56+
const Vector3<NumericType>& get_scale() const
57+
{
58+
return m_scale;
59+
}
60+
61+
[[nodiscard]]
62+
const RotationAngles& get_rotation_angles() const
63+
{
64+
return m_rotation_angles;
65+
}
66+
67+
[[nodiscard]]
68+
const Mat4X4& get_to_world_matrix() const
69+
{
70+
if (m_to_world_matrix)
71+
return m_to_world_matrix.value();
72+
m_to_world_matrix =
73+
mat_translation(m_origin) * mat_scale(m_scale) * MeshTypeTrait::rotation_matrix(m_rotation_angles);
74+
75+
return m_to_world_matrix.value();
76+
}
77+
78+
[[nodiscard]]
79+
Vector3<float> vertex_to_world_space(const Vector3<float>& vertex) const
80+
{
81+
auto abs_vec = get_to_world_matrix() * mat_column_from_vector(vertex);
82+
83+
return {abs_vec.at(0, 0), abs_vec.at(1, 0), abs_vec.at(2, 0)};
84+
}
85+
86+
[[nodiscard]]
87+
Triangle<Vector3<float>> make_face_in_world_space(const Vao::const_iterator vao_iterator) const
88+
{
89+
return {vertex_to_world_space(m_vertex_buffer.at(vao_iterator->x)),
90+
vertex_to_world_space(m_vertex_buffer.at(vao_iterator->y)),
91+
vertex_to_world_space(m_vertex_buffer.at(vao_iterator->z))};
92+
}
93+
94+
private:
95+
Vector3<NumericType> m_origin;
96+
Vector3<NumericType> m_scale;
97+
98+
RotationAngles m_rotation_angles;
99+
100+
mutable std::optional<Mat4X4> m_to_world_matrix;
101+
};
102+
} // namespace omath::primitives
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
//
2+
// Created by Vlad on 11/9/2025.
3+
//
4+
5+
#pragma once
6+
#include "mesh_collider.hpp"
7+
#include "omath/linear_algebra/vector3.hpp"
8+
#include "simplex.hpp"
9+
10+
namespace omath::collision
11+
{
12+
template<class ColliderType>
13+
class GjkAlgorithm final
14+
{
15+
public:
16+
[[nodiscard]]
17+
static ColliderType::VertexType find_support_vertex(const ColliderType& collider_a,
18+
const ColliderType& collider_b,
19+
const ColliderType::VertexType& direction)
20+
{
21+
return collider_a.find_abs_furthest_vertex(direction) - collider_b.find_abs_furthest_vertex(-direction);
22+
}
23+
24+
[[nodiscard]]
25+
static bool is_collide(const ColliderType& collider_a, const ColliderType& collider_b)
26+
{
27+
// Get initial support point in any direction
28+
auto support = find_support_vertex(collider_a, collider_b, {1, 0, 0});
29+
30+
Simplex<typename ColliderType::VertexType> simplex;
31+
simplex.push_front(support);
32+
33+
auto direction = -support;
34+
35+
while (true)
36+
{
37+
support = find_support_vertex(collider_a, collider_b, direction);
38+
39+
if (support.dot(direction) <= 0.f)
40+
return false;
41+
42+
simplex.push_front(support);
43+
44+
if (simplex.handle(direction))
45+
return true;
46+
}
47+
}
48+
};
49+
} // namespace omath::collision
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
//
2+
// Created by Vlad on 11/9/2025.
3+
//
4+
5+
#pragma once
6+
#include "omath/linear_algebra/vector3.hpp"
7+
8+
namespace omath::collision
9+
{
10+
template<class MeshType>
11+
class MeshCollider
12+
{
13+
public:
14+
using NumericType = typename MeshType::NumericType;
15+
16+
using VertexType = Vector3<NumericType>;
17+
explicit MeshCollider(MeshType mesh): m_mesh(std::move(mesh))
18+
{
19+
}
20+
21+
[[nodiscard]]
22+
const Vector3<float>& find_furthest_vertex(const Vector3<float>& direction) const
23+
{
24+
return *std::ranges::max_element(m_mesh.m_vertex_buffer, [&direction](const auto& first, const auto& second)
25+
{ return first.dot(direction) < second.dot(direction); });
26+
}
27+
28+
[[nodiscard]]
29+
Vector3<float> find_abs_furthest_vertex(const Vector3<float>& direction) const
30+
{
31+
return m_mesh.vertex_to_world_space(find_furthest_vertex(direction));
32+
}
33+
34+
private:
35+
MeshType m_mesh;
36+
};
37+
} // namespace omath::collision

0 commit comments

Comments
 (0)