Compare commits

..

1 Commits

Author SHA1 Message Date
orange 71e256d033 added static method 2026-06-26 02:04:34 +03:00
4 changed files with 92 additions and 14 deletions
+18 -1
View File
@@ -4,17 +4,23 @@
#pragma once
#include "omath/linear_algebra/vector3.hpp"
#include <array>
namespace omath::primitives
{
enum class UpAxis { X, Y, Z };
template<class Type>
template<class Type, UpAxis Up = UpAxis::Y>
struct Aabb final
{
Vector3<Type> min;
Vector3<Type> max;
[[nodiscard]]
static consteval UpAxis get_up_axis()
{
return Up;
}
[[nodiscard]]
constexpr Vector3<Type> center() const noexcept
{
@@ -57,6 +63,17 @@ namespace omath::primitives
std::unreachable();
}
[[nodiscard]]
constexpr std::array<Vector3<Type>, 8> vertices() const noexcept
{
return {
Vector3<Type>{min.x, min.y, min.z}, Vector3<Type>{max.x, min.y, min.z},
Vector3<Type>{min.x, max.y, min.z}, Vector3<Type>{max.x, max.y, min.z},
Vector3<Type>{min.x, min.y, max.z}, Vector3<Type>{max.x, min.y, max.z},
Vector3<Type>{min.x, max.y, max.z}, Vector3<Type>{max.x, max.y, max.z},
};
}
[[nodiscard]]
constexpr bool is_collide(const Aabb& other) const noexcept
{
+1
View File
@@ -9,6 +9,7 @@ namespace omath::hud
class CanvasBox final
{
public:
CanvasBox() = default;
CanvasBox(Vector2<float> top, Vector2<float> bottom, float ratio = 4.f);
[[nodiscard("You have to use array")]]
+56 -13
View File
@@ -5,11 +5,11 @@
#include "canvas_box.hpp"
#include "entity_overlay_widgets.hpp"
#include "hud_renderer_interface.hpp"
#include "omath/3d_primitives/aabb.hpp"
#include "omath/linear_algebra/vector2.hpp"
#include "omath/utility/color.hpp"
#include <memory>
#include <string_view>
namespace omath::hud
{
class EntityOverlay final
@@ -57,13 +57,17 @@ namespace omath::hud
float offset = 5.f);
// ── Labels ───────────────────────────────────────────────────────
EntityOverlay& add_right_label(const Color& color, float offset, widget::Outlined outlined, const std::string_view& text);
EntityOverlay& add_right_label(const Color& color, float offset, widget::Outlined outlined,
const std::string_view& text);
EntityOverlay& add_left_label(const Color& color, float offset, widget::Outlined outlined, const std::string_view& text);
EntityOverlay& add_left_label(const Color& color, float offset, widget::Outlined outlined,
const std::string_view& text);
EntityOverlay& add_top_label(const Color& color, float offset, widget::Outlined outlined, std::string_view text);
EntityOverlay& add_top_label(const Color& color, float offset, widget::Outlined outlined,
std::string_view text);
EntityOverlay& add_bottom_label(const Color& color, float offset, widget::Outlined outlined, std::string_view text);
EntityOverlay& add_bottom_label(const Color& color, float offset, widget::Outlined outlined,
std::string_view text);
EntityOverlay& add_centered_top_label(const Color& color, float offset, widget::Outlined outlined,
const std::string_view& text);
@@ -72,24 +76,24 @@ namespace omath::hud
const std::string_view& text);
template<typename... Args>
EntityOverlay& add_right_label(const Color& color, const float offset, const widget::Outlined outlined, std::format_string<Args...> fmt,
Args&&... args)
EntityOverlay& add_right_label(const Color& color, const float offset, const widget::Outlined outlined,
std::format_string<Args...> fmt, Args&&... args)
{
return add_right_label(color, offset, outlined,
std::string_view{std::vformat(fmt.get(), std::make_format_args(args...))});
}
template<typename... Args>
EntityOverlay& add_left_label(const Color& color, const float offset, const widget::Outlined outlined, std::format_string<Args...> fmt,
Args&&... args)
EntityOverlay& add_left_label(const Color& color, const float offset, const widget::Outlined outlined,
std::format_string<Args...> fmt, Args&&... args)
{
return add_left_label(color, offset, outlined,
std::string_view{std::vformat(fmt.get(), std::make_format_args(args...))});
}
template<typename... Args>
EntityOverlay& add_top_label(const Color& color, const float offset, const widget::Outlined outlined, std::format_string<Args...> fmt,
Args&&... args)
EntityOverlay& add_top_label(const Color& color, const float offset, const widget::Outlined outlined,
std::format_string<Args...> fmt, Args&&... args)
{
return add_top_label(color, offset, outlined,
std::string_view{std::vformat(fmt.get(), std::make_format_args(args...))});
@@ -112,8 +116,9 @@ namespace omath::hud
}
template<typename... Args>
EntityOverlay& add_centered_bottom_label(const Color& color, const float offset, const widget::Outlined outlined,
std::format_string<Args...> fmt, Args&&... args)
EntityOverlay& add_centered_bottom_label(const Color& color, const float offset,
const widget::Outlined outlined, std::format_string<Args...> fmt,
Args&&... args)
{
return add_centered_bottom_label(color, offset, outlined,
std::string_view{std::vformat(fmt.get(), std::make_format_args(args...))});
@@ -164,6 +169,44 @@ namespace omath::hud
return *this;
}
template<class Camera, class Aabb>
static std::expected<EntityOverlay, std::string>
from_aabb(const Camera& camera, const Aabb& aabb, const float aspect,
const std::shared_ptr<HudRendererInterface>& renderer)
{
Vector3<float> top;
Vector3<float> bottom;
bool has_projected_vertex = false;
for (const auto& vertex: aabb.vertices())
{
if (auto projected = camera.world_to_screen_unclipped(vertex))
{
if (!has_projected_vertex)
{
top = *projected;
bottom = *projected;
has_projected_vertex = true;
continue;
}
if (projected->y < top.y)
top = *projected;
if (projected->y > bottom.y)
bottom = *projected;
}
}
if (!has_projected_vertex)
return std::unexpected("");
auto center = camera.world_to_screen_unclipped(aabb.center());
if (!center)
return std::unexpected("");
return EntityOverlay{{center->x, top.y}, {center->x, bottom.y}, aspect, renderer};
}
private:
// optional<W> dispatch — enables when() conditional widgets
template<typename W>
+17
View File
@@ -162,6 +162,23 @@ TEST(AabbTests, TopAndBottomAreSymmetric)
EXPECT_FLOAT_EQ(box.top<UpAxis::Z>().z, -box.bottom<UpAxis::Z>().z);
}
// --- vertices() ---
TEST(AabbTests, VerticesReturnsAllCorners)
{
constexpr AABB box{{1.f, 2.f, 3.f}, {4.f, 6.f, 8.f}};
constexpr auto v = box.vertices();
EXPECT_EQ(v[0], Vec3(1.f, 2.f, 3.f));
EXPECT_EQ(v[1], Vec3(4.f, 2.f, 3.f));
EXPECT_EQ(v[2], Vec3(1.f, 6.f, 3.f));
EXPECT_EQ(v[3], Vec3(4.f, 6.f, 3.f));
EXPECT_EQ(v[4], Vec3(1.f, 2.f, 8.f));
EXPECT_EQ(v[5], Vec3(4.f, 2.f, 8.f));
EXPECT_EQ(v[6], Vec3(1.f, 6.f, 8.f));
EXPECT_EQ(v[7], Vec3(4.f, 6.f, 8.f));
}
// --- is_collide() ---
TEST(AabbTests, OverlappingBoxesCollide)