mirror of
https://github.com/orange-cpp/omath.git
synced 2026-02-12 22:53:27 +00:00
added mesh class, added mesh trair
This commit is contained in:
@@ -10,9 +10,13 @@
|
||||
|
||||
namespace omath::primitives
|
||||
{
|
||||
template<class Mat4X4, class RotationAngles, class MeshTypeTrait, class NumericType = float>
|
||||
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>>;
|
||||
|
||||
@@ -20,9 +24,9 @@ namespace omath::primitives
|
||||
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))
|
||||
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)
|
||||
{
|
||||
@@ -78,12 +82,13 @@ namespace omath::primitives
|
||||
|
||||
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
|
||||
Triangle<Vector3<float>> make_face_in_world_space(const Vao::const_iterator vao_iterator) 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))};
|
||||
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:
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
namespace omath::collision
|
||||
{
|
||||
template<class ColliderType = MeshCollider<>>
|
||||
template<class ColliderType>
|
||||
class GjkAlgorithm final
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -5,52 +5,39 @@
|
||||
#pragma once
|
||||
#include "omath/engines/source_engine/traits/pred_engine_trait.hpp"
|
||||
#include "omath/linear_algebra/vector3.hpp"
|
||||
#include <omath/3d_primitives/mesh.hpp>
|
||||
#include <vector>
|
||||
|
||||
namespace omath::collision
|
||||
{
|
||||
template<class NumericType = float>
|
||||
template<class MeshType>
|
||||
class MeshCollider
|
||||
{
|
||||
public:
|
||||
using NumericType = MeshType::NumericType;
|
||||
|
||||
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)
|
||||
explicit MeshCollider(MeshType mesh): m_mesh(std::move(mesh))
|
||||
{
|
||||
if (m_vertexes.empty())
|
||||
throw std::runtime_error("Collider cannot have 0 vertexes");
|
||||
}
|
||||
std::vector<Vector3<float>> m_vertexes;
|
||||
Vector3<float> m_scale;
|
||||
|
||||
Vector3<float> m_origin;
|
||||
source_engine::ViewAngles m_rotation;
|
||||
|
||||
[[nodiscard]]
|
||||
source_engine::Mat4X4 to_world() const
|
||||
{
|
||||
return mat_translation(m_origin) * mat_scale(m_scale) * source_engine::rotation_matrix(m_rotation);
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
const Vector3<float>& find_furthest_vertex(const Vector3<float>& direction) const
|
||||
{
|
||||
return *std::ranges::max_element(m_vertexes, [&direction](const auto& first, const auto& second)
|
||||
{ return first.dot(direction) < second.dot(direction); });
|
||||
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 vertex_to_world_space(find_furthest_vertex(direction));
|
||||
return m_mesh.vertex_to_world_space(find_furthest_vertex(direction));
|
||||
}
|
||||
|
||||
[[nodiscard]] Vector3<float> vertex_to_world_space(const Vector3<float>& local_vertex) const
|
||||
{
|
||||
auto abs_vec = to_world() * mat_column_from_vector(local_vertex);
|
||||
|
||||
return {abs_vec.at(0, 0), abs_vec.at(1, 0), abs_vec.at(2, 0)};
|
||||
}
|
||||
private:
|
||||
MeshType m_mesh;
|
||||
};
|
||||
} // namespace omath::collision
|
||||
13
include/omath/engines/source_engine/collider.hpp
Normal file
13
include/omath/engines/source_engine/collider.hpp
Normal file
@@ -0,0 +1,13 @@
|
||||
//
|
||||
// Created by Vladislav on 09.11.2025.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
#include "mesh.hpp"
|
||||
#include "omath/3d_primitives/mesh.hpp"
|
||||
#include "omath/collision/mesh_collider.hpp"
|
||||
|
||||
namespace omath::source_engine
|
||||
{
|
||||
using MeshCollider = collision::MeshCollider<Mesh>;
|
||||
}
|
||||
12
include/omath/engines/source_engine/mesh.hpp
Normal file
12
include/omath/engines/source_engine/mesh.hpp
Normal file
@@ -0,0 +1,12 @@
|
||||
//
|
||||
// Created by Vladislav on 09.11.2025.
|
||||
//
|
||||
#pragma once
|
||||
#include "constants.hpp"
|
||||
#include "omath/3d_primitives/mesh.hpp"
|
||||
#include "traits/mesh_trait.hpp"
|
||||
|
||||
namespace omath::source_engine
|
||||
{
|
||||
using Mesh = primitives::Mesh<Mat4X4, ViewAngles, MeshTrait, float>;
|
||||
}
|
||||
18
include/omath/engines/source_engine/traits/mesh_trait.hpp
Normal file
18
include/omath/engines/source_engine/traits/mesh_trait.hpp
Normal file
@@ -0,0 +1,18 @@
|
||||
//
|
||||
// Created by Vladislav on 09.11.2025.
|
||||
//
|
||||
#pragma once
|
||||
#include <omath/engines/source_engine/constants.hpp>
|
||||
#include <omath/engines/source_engine/formulas.hpp>
|
||||
namespace omath::source_engine
|
||||
{
|
||||
class MeshTrait final
|
||||
{
|
||||
public:
|
||||
[[nodiscard]]
|
||||
static Mat4X4 rotation_matrix(const ViewAngles& rotation)
|
||||
{
|
||||
return source_engine::rotation_matrix(rotation);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -1,16 +1,15 @@
|
||||
//
|
||||
// Created by Vlad on 11/9/2025.
|
||||
//
|
||||
#include "omath/engines/source_engine/collider.hpp"
|
||||
#include <gtest/gtest.h>
|
||||
#include <omath/collision/mesh_collider.hpp>
|
||||
|
||||
|
||||
|
||||
TEST(UnitTestColider, CheckToWorld)
|
||||
{
|
||||
const std::vector<omath::Vector3<float>> mesh = {{1.f, 1.f, 1.f}, {-1.f, -1.f, -1.f}};
|
||||
|
||||
const omath::collision::MeshCollider collider(mesh, {0.f, 2.f, 0.f});
|
||||
omath::source_engine::Mesh mesh = {std::vector<omath::Vector3<float>>{{1.f, 1.f, 1.f}, {-1.f, -1.f, -1.f}}, {}};
|
||||
mesh.set_origin({0, 2, 0});
|
||||
const omath::source_engine::MeshCollider collider(mesh);
|
||||
|
||||
const auto vertex = collider.find_abs_furthest_vertex({1.f, 0.f, 0.f});
|
||||
|
||||
@@ -19,8 +18,8 @@ TEST(UnitTestColider, CheckToWorld)
|
||||
|
||||
TEST(UnitTestColider, FindFurthestVertex)
|
||||
{
|
||||
const std::vector<omath::Vector3<float>> mesh = {{1.f, 1.f, 1.f}, {-1.f, -1.f, -1.f}};
|
||||
const omath::collision::MeshCollider collider(mesh, {0.f, 0.f, 0.f});
|
||||
const omath::source_engine::Mesh mesh = {{{1.f, 1.f, 1.f}, {-1.f, -1.f, -1.f}}, {}};
|
||||
const omath::source_engine::MeshCollider collider(mesh);
|
||||
const auto vertex = collider.find_furthest_vertex({1.f, 0.f, 0.f});
|
||||
EXPECT_EQ(vertex, omath::Vector3<float>(1.f, 1.f, 1.f));
|
||||
}
|
||||
|
||||
@@ -1,47 +1,55 @@
|
||||
//
|
||||
// Created by Vlad on 11/9/2025.
|
||||
//
|
||||
#include "omath/engines/source_engine/collider.hpp"
|
||||
#include <gtest/gtest.h>
|
||||
#include <omath/collision/gjk_algorithm.hpp>
|
||||
|
||||
#include <omath/engines/source_engine/mesh.hpp>
|
||||
namespace
|
||||
{
|
||||
const std::vector<omath::Vector3<float>> mesh = {
|
||||
{-1.f, -1.f, -1.f},
|
||||
{-1.f, -1.f, 1.f},
|
||||
{-1.f, 1.f, -1.f},
|
||||
{-1.f, 1.f, 1.f},
|
||||
{ 1.f, 1.f, 1.f}, // x = +1 vertices (put {1,1,1} first in case your support breaks ties by first-hit)
|
||||
{ 1.f, 1.f, -1.f},
|
||||
{ 1.f, -1.f, 1.f},
|
||||
{ 1.f, -1.f, -1.f}
|
||||
};
|
||||
const omath::source_engine::Mesh mesh = {
|
||||
{{-1.f, -1.f, -1.f},
|
||||
{-1.f, -1.f, 1.f},
|
||||
{-1.f, 1.f, -1.f},
|
||||
{-1.f, 1.f, 1.f},
|
||||
{1.f, 1.f, 1.f}, // x = +1 vertices (put {1,1,1} first in case your support breaks ties by first-hit)
|
||||
{1.f, 1.f, -1.f},
|
||||
{1.f, -1.f, 1.f},
|
||||
{1.f, -1.f, -1.f}},
|
||||
{}};
|
||||
}
|
||||
TEST(UnitTestGjk, TestCollisionTrue)
|
||||
{
|
||||
const omath::collision::MeshCollider collider_a(mesh, {0.f, 0.f, 0.f});
|
||||
const omath::collision::MeshCollider collider_b(mesh, {0.f, 0.5f, 0.f});
|
||||
|
||||
const auto result = omath::collision::GjkAlgorithm<>::is_collide(collider_a, collider_b);
|
||||
const omath::source_engine::MeshCollider collider_a(mesh);
|
||||
|
||||
auto mesh_b = mesh;
|
||||
mesh_b.set_origin({0.f, 0.5f, 0.f});
|
||||
const omath::source_engine::MeshCollider collider_b(mesh_b);
|
||||
|
||||
const auto result =
|
||||
omath::collision::GjkAlgorithm<omath::source_engine::MeshCollider>::is_collide(collider_a, collider_b);
|
||||
|
||||
EXPECT_TRUE(result);
|
||||
}
|
||||
TEST(UnitTestGjk, TestCollisionFalse)
|
||||
{
|
||||
const omath::collision::MeshCollider collider_a(mesh, {0.f, 0.f, 0.f});
|
||||
const omath::collision::MeshCollider collider_b(mesh, {0.f, 2.1f, 0.f});
|
||||
const omath::source_engine::MeshCollider collider_a(mesh);
|
||||
auto mesh_b = mesh;
|
||||
mesh_b.set_origin({0.f, 2.1f, 0.f});
|
||||
const omath::source_engine::MeshCollider collider_b(mesh_b);
|
||||
|
||||
const auto result = omath::collision::GjkAlgorithm<>::is_collide(collider_a, collider_b);
|
||||
const auto result = omath::collision::GjkAlgorithm<omath::source_engine::MeshCollider>::is_collide(collider_a, collider_b);
|
||||
|
||||
EXPECT_FALSE(result);
|
||||
}
|
||||
|
||||
TEST(UnitTestGjk, TestCollisionEqualOrigin)
|
||||
{
|
||||
const omath::collision::MeshCollider collider_a(mesh, {0.f, 0.f, 0.f});
|
||||
const omath::collision::MeshCollider collider_b(mesh, {0.f, 0.f, 0.f});
|
||||
const omath::source_engine::MeshCollider collider_a(mesh);
|
||||
const omath::source_engine::MeshCollider collider_b(mesh);
|
||||
|
||||
const auto result = omath::collision::GjkAlgorithm<>::is_collide(collider_a, collider_b);
|
||||
const auto result = omath::collision::GjkAlgorithm<omath::source_engine::MeshCollider>::is_collide(collider_a, collider_b);
|
||||
|
||||
EXPECT_TRUE(result);
|
||||
}
|
||||
Reference in New Issue
Block a user