Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .idea/editor.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

102 changes: 102 additions & 0 deletions include/omath/3d_primitives/mesh.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
//
// Created by Vladislav on 09.11.2025.
//
#pragma once
#include "omath/linear_algebra/triangle.hpp"
#include <omath/linear_algebra/mat.hpp>
#include <omath/linear_algebra/vector3.hpp>
#include <utility>
#include <vector>

namespace omath::primitives
{
template<class Mat4X4, class RotationAngles, class MeshTypeTrait, class Type = float>
class Mesh final
{
public:
using NumericType = Type;

private:
using Vbo = std::vector<Vector3<NumericType>>;
using Vao = std::vector<Vector3<std::size_t>>;

public:
Vbo m_vertex_buffer;
Vao m_vertex_array_object;

Mesh(Vbo vbo, Vao vao, const Vector3<NumericType> scale = {1, 1, 1,})
: m_vertex_buffer(std::move(vbo)), m_vertex_array_object(std::move(vao)), m_scale(scale)
{
}
void set_origin(const Vector3<NumericType>& new_origin)
{
m_origin = new_origin;
m_to_world_matrix = std::nullopt;
}

void set_scale(const Vector3<NumericType>& new_scale)
{
m_scale = new_scale;
m_to_world_matrix = std::nullopt;
}

void set_rotation(const RotationAngles& new_rotation_angles)
{
m_rotation_angles = new_rotation_angles;
m_to_world_matrix = std::nullopt;
}

[[nodiscard]]
const Vector3<NumericType>& get_origin() const
{
return m_origin;
}

[[nodiscard]]
const Vector3<NumericType>& get_scale() const
{
return m_scale;
}

[[nodiscard]]
const RotationAngles& get_rotation_angles() const
{
return m_rotation_angles;
}

[[nodiscard]]
const Mat4X4& get_to_world_matrix() const
{
if (m_to_world_matrix)
return m_to_world_matrix.value();
m_to_world_matrix =
mat_translation(m_origin) * mat_scale(m_scale) * MeshTypeTrait::rotation_matrix(m_rotation_angles);

return m_to_world_matrix.value();
}

[[nodiscard]]
Vector3<float> vertex_to_world_space(const Vector3<float>& vertex) const
{
auto abs_vec = get_to_world_matrix() * mat_column_from_vector(vertex);

return {abs_vec.at(0, 0), abs_vec.at(1, 0), abs_vec.at(2, 0)};
}

[[nodiscard]]
Triangle<Vector3<float>> make_face_in_world_space(const Vao::const_iterator vao_iterator) const
{
return {vertex_to_world_space(m_vertex_buffer.at(vao_iterator->x)),
vertex_to_world_space(m_vertex_buffer.at(vao_iterator->y)),
vertex_to_world_space(m_vertex_buffer.at(vao_iterator->z))};
}

private:
Vector3<NumericType> m_origin;
Vector3<NumericType> m_scale;

RotationAngles m_rotation_angles;

mutable std::optional<Mat4X4> m_to_world_matrix;
};
} // namespace omath::primitives
49 changes: 49 additions & 0 deletions include/omath/collision/gjk_algorithm.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
//
// Created by Vlad on 11/9/2025.
//

#pragma once
#include "mesh_collider.hpp"
#include "omath/linear_algebra/vector3.hpp"
#include "simplex.hpp"

namespace omath::collision
{
template<class ColliderType>
class GjkAlgorithm final
{
public:
[[nodiscard]]
static ColliderType::VertexType find_support_vertex(const ColliderType& collider_a,
const ColliderType& collider_b,
const ColliderType::VertexType& direction)
{
return collider_a.find_abs_furthest_vertex(direction) - collider_b.find_abs_furthest_vertex(-direction);
}

[[nodiscard]]
static bool is_collide(const ColliderType& collider_a, const ColliderType& collider_b)
{
// Get initial support point in any direction
auto support = find_support_vertex(collider_a, collider_b, {1, 0, 0});

Simplex<typename ColliderType::VertexType> simplex;
simplex.push_front(support);

auto direction = -support;

while (true)
{
support = find_support_vertex(collider_a, collider_b, direction);

if (support.dot(direction) <= 0.f)
return false;

simplex.push_front(support);

if (simplex.handle(direction))
return true;
}
}
};
} // namespace omath::collision
37 changes: 37 additions & 0 deletions include/omath/collision/mesh_collider.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
//
// Created by Vlad on 11/9/2025.
//

#pragma once
#include "omath/linear_algebra/vector3.hpp"

namespace omath::collision
{
template<class MeshType>
class MeshCollider
{
public:
using NumericType = typename MeshType::NumericType;

using VertexType = Vector3<NumericType>;
explicit MeshCollider(MeshType mesh): m_mesh(std::move(mesh))
{
}

[[nodiscard]]
const Vector3<float>& find_furthest_vertex(const Vector3<float>& direction) const
{
return *std::ranges::max_element(m_mesh.m_vertex_buffer, [&direction](const auto& first, const auto& second)
{ return first.dot(direction) < second.dot(direction); });
}

[[nodiscard]]
Vector3<float> find_abs_furthest_vertex(const Vector3<float>& direction) const
{
return m_mesh.vertex_to_world_space(find_furthest_vertex(direction));
}

private:
MeshType m_mesh;
};
} // namespace omath::collision
Loading
Loading