add mesh class

This commit is contained in:
2025-11-09 21:28:00 +03:00
parent e2378bfa8b
commit e5d8e1c953
4 changed files with 112 additions and 11 deletions

View File

@@ -0,0 +1,97 @@
//
// 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 NumericType = float>
class Mesh final
{
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): m_vertex_buffer(std::move(vbo)), m_vertex_array_object(std::move(vao))
{
}
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 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<NumericType> m_origin;
Vector3<NumericType> m_scale;
RotationAngles m_rotation_angles;
mutable std::optional<Mat4X4> m_to_world_matrix;
};
} // namespace omath::primitives

View File

@@ -9,25 +9,25 @@
namespace omath::collision
{
template<class ColliderType = MeshCollider>
template<class ColliderType = MeshCollider<>>
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<MeshCollider::VertexType> simplex;
Simplex<typename ColliderType::VertexType> simplex;
simplex.push_front(support);
auto direction = -support;

View File

@@ -9,12 +9,14 @@
namespace omath::collision
{
template<class NumericType = float>
class MeshCollider
{
public:
using VertexType = Vector3<float>;
MeshCollider(const std::vector<VertexType>& 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<NumericType>;
MeshCollider(const std::vector<VertexType>& 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<float> find_abs_furthest_vertex(const Vector3<float>& direction) const
{
return vertex_to_world_space(find_furthest_vertex(direction));
}
[[nodiscard]] Vector3<float> vertex_to_world_space( const Vector3<float>& local_vertex) const
[[nodiscard]] Vector3<float> vertex_to_world_space(const Vector3<float>& local_vertex) const
{
auto abs_vec = to_world() * mat_column_from_vector(local_vertex);