diff --git a/.idea/editor.xml b/.idea/editor.xml
index 373c50f..fde5348 100644
--- a/.idea/editor.xml
+++ b/.idea/editor.xml
@@ -201,7 +201,7 @@
-
+
@@ -215,7 +215,7 @@
-
+
diff --git a/include/omath/3d_primitives/mesh.hpp b/include/omath/3d_primitives/mesh.hpp
new file mode 100644
index 0000000..e60223e
--- /dev/null
+++ b/include/omath/3d_primitives/mesh.hpp
@@ -0,0 +1,97 @@
+//
+// Created by Vladislav on 09.11.2025.
+//
+#pragma once
+#include "omath/linear_algebra/triangle.hpp"
+#include
+#include
+#include
+#include
+
+namespace omath::primitives
+{
+ template
+ class Mesh final
+ {
+ using Vbo = std::vector>;
+ using Vao = std::vector>;
+
+ public:
+ Vbo m_vertex_buffer;
+ Vao m_vertex_array_object;
+
+ Mesh(Vbo vbo, Vao vao): m_vertex_buffer(std::move(vbo)), m_vertex_array_object(std::move(vao))
+ {
+
+ }
+ void set_origin(const Vector3& new_origin)
+ {
+ m_origin = new_origin;
+ m_to_world_matrix = std::nullopt;
+ }
+
+ void set_scale(const Vector3& 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& get_origin() const
+ {
+ return m_origin;
+ }
+
+ [[nodiscard]]
+ const Vector3& 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 vertex_to_world_space(const Vector3& 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> make_face_in_world_space(const Vao::const_iterator index) const
+ {
+ return {vertex_to_world_space(m_vertex_buffer.at(index->x)),
+ vertex_to_world_space(m_vertex_buffer.at(index->y)),
+ vertex_to_world_space(m_vertex_buffer.at(index->z))};
+ }
+
+ private:
+ Vector3 m_origin;
+ Vector3 m_scale;
+
+ RotationAngles m_rotation_angles;
+
+ mutable std::optional m_to_world_matrix;
+ };
+} // namespace omath::primitives
\ No newline at end of file
diff --git a/include/omath/collision/gjk_algorithm.hpp b/include/omath/collision/gjk_algorithm.hpp
index d494cb1..1380476 100644
--- a/include/omath/collision/gjk_algorithm.hpp
+++ b/include/omath/collision/gjk_algorithm.hpp
@@ -9,25 +9,25 @@
namespace omath::collision
{
- template
+ template>
class GjkAlgorithm final
{
public:
[[nodiscard]]
- static MeshCollider::VertexType find_support_vertex(const ColliderType& collider_a,
+ static ColliderType::VertexType find_support_vertex(const ColliderType& collider_a,
const ColliderType& collider_b,
- const MeshCollider::VertexType& direction)
+ 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 MeshCollider& collider_a, const MeshCollider& collider_b)
+ 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 simplex;
+ Simplex simplex;
simplex.push_front(support);
auto direction = -support;
diff --git a/include/omath/collision/mesh_collider.hpp b/include/omath/collision/mesh_collider.hpp
index c67ab44..618ea52 100644
--- a/include/omath/collision/mesh_collider.hpp
+++ b/include/omath/collision/mesh_collider.hpp
@@ -9,12 +9,14 @@
namespace omath::collision
{
+ template
class MeshCollider
{
public:
- using VertexType = Vector3;
- MeshCollider(const std::vector& vertexes, const VertexType& origin, const VertexType& scale = {1.f, 1.f, 1.f})
- : m_vertexes(vertexes),m_scale(scale), m_origin(origin)
+ using VertexType = Vector3;
+ MeshCollider(const std::vector& vertexes, const VertexType& origin,
+ const VertexType& scale = {1.f, 1.f, 1.f})
+ : m_vertexes(vertexes), m_scale(scale), m_origin(origin)
{
if (m_vertexes.empty())
throw std::runtime_error("Collider cannot have 0 vertexes");
@@ -37,12 +39,14 @@ namespace omath::collision
return *std::ranges::max_element(m_vertexes, [&direction](const auto& first, const auto& second)
{ return first.dot(direction) < second.dot(direction); });
}
+
[[nodiscard]]
Vector3 find_abs_furthest_vertex(const Vector3& direction) const
{
return vertex_to_world_space(find_furthest_vertex(direction));
}
- [[nodiscard]] Vector3 vertex_to_world_space( const Vector3& local_vertex) const
+
+ [[nodiscard]] Vector3 vertex_to_world_space(const Vector3& local_vertex) const
{
auto abs_vec = to_world() * mat_column_from_vector(local_vertex);