diff --git a/examples/example_hud/gui/main_window.cpp b/examples/example_hud/gui/main_window.cpp index 2f242f6..4a71f0c 100644 --- a/examples/example_hud/gui/main_window.cpp +++ b/examples/example_hud/gui/main_window.cpp @@ -149,6 +149,21 @@ namespace imgui_desktop::gui ImGui::SliderFloat("Offset##ring", &m_ring_offset, 0.f, 15.f); } + if (ImGui::CollapsingHeader("Scan Marker")) + { + ImGui::Checkbox("Show##scan", &m_show_scan); + ImGui::ColorEdit4("Fill##scan", reinterpret_cast(&m_scan_color), ImGuiColorEditFlags_NoInputs); + ImGui::ColorEdit4("Outline##scan", reinterpret_cast(&m_scan_outline), ImGuiColorEditFlags_NoInputs); + ImGui::SliderFloat("Thick##scan", &m_scan_outline_thickness, 0.5f, 5.f); + } + + if (ImGui::CollapsingHeader("Aim Dot")) + { + ImGui::Checkbox("Show##aim", &m_show_aim); + ImGui::ColorEdit4("Color##aim", reinterpret_cast(&m_aim_color), ImGuiColorEditFlags_NoInputs); + ImGui::SliderFloat("Radius##aim", &m_aim_radius, 1.f, 10.f); + } + if (ImGui::CollapsingHeader("Snap Line")) { ImGui::Checkbox("Show##snap", &m_show_snap); @@ -217,6 +232,8 @@ namespace imgui_desktop::gui when(m_show_bottom_labels, Label{omath::Color::from_rgba(200, 200, 0, 255), m_label_offset, m_outlined, "42m"}), }, + when(m_show_aim, AimDot{{m_entity_x, m_entity_top_y+40.f}, m_aim_color, m_aim_radius}), + when(m_show_scan, ScanMarker{m_scan_color, m_scan_outline, m_scan_outline_thickness}), when(m_show_skeleton, Skeleton{m_skel_color, m_skel_thickness}), when(m_show_snap, SnapLine{{vp->Size.x / 2.f, vp->Size.y}, m_snap_color, m_snap_width})); } diff --git a/examples/example_hud/gui/main_window.hpp b/examples/example_hud/gui/main_window.hpp index d7eb540..8b622bf 100644 --- a/examples/example_hud/gui/main_window.hpp +++ b/examples/example_hud/gui/main_window.hpp @@ -67,6 +67,17 @@ namespace imgui_desktop::gui float m_ring_radius = 10.f, m_ring_ratio = 0.65f, m_ring_thickness = 2.5f, m_ring_offset = 5.f; bool m_show_ring = false; + // Scan marker + omath::Color m_scan_color = omath::Color::from_rgba(255, 200, 0, 150); + omath::Color m_scan_outline = omath::Color::from_rgba(255, 200, 0, 255); + float m_scan_outline_thickness = 2.f; + bool m_show_scan = false; + + // Aim dot + omath::Color m_aim_color = omath::Color::from_rgba(255, 0, 0, 255); + float m_aim_radius = 3.f; + bool m_show_aim = false; + // Snap line omath::Color m_snap_color = omath::Color::from_rgba(255, 50, 50, 255); float m_snap_width = 1.5f; diff --git a/include/omath/hud/entity_overlay.hpp b/include/omath/hud/entity_overlay.hpp index 1922ca4..4fe7ed1 100644 --- a/include/omath/hud/entity_overlay.hpp +++ b/include/omath/hud/entity_overlay.hpp @@ -171,6 +171,8 @@ namespace omath::hud void dispatch(const widget::BottomSide& bottom_side); void dispatch(const widget::Skeleton& skeleton); void dispatch(const widget::SnapLine& snap_line); + void dispatch(const widget::ScanMarker& scan_marker); + void dispatch(const widget::AimDot& aim_dot); void draw_progress_ring(const Vector2& center, const widget::ProgressRing& ring); void draw_outlined_text(const Vector2& position, const Color& color, const std::string_view& text); void draw_dashed_line(const Vector2& from, const Vector2& to, const Color& color, float dash_len, diff --git a/include/omath/hud/entity_overlay_widgets.hpp b/include/omath/hud/entity_overlay_widgets.hpp index 8a370cd..db290fb 100644 --- a/include/omath/hud/entity_overlay_widgets.hpp +++ b/include/omath/hud/entity_overlay_widgets.hpp @@ -56,6 +56,21 @@ namespace omath::hud::widget float width; }; + struct ScanMarker + { + Color color; + Color outline{0.f, 0.f, 0.f, 0.f}; + float outline_thickness = 1.f; + }; + + /// Dot at an absolute screen position. + struct AimDot + { + Vector2 position; + Color color; + float radius = 3.f; + }; + // ── Side-agnostic widgets (used inside XxxSide containers) ──────────────── /// A filled bar. `size` is width for left/right sides, height for top/bottom. diff --git a/source/hud/entity_overlay.cpp b/source/hud/entity_overlay.cpp index c5691cf..5330e3f 100644 --- a/source/hud/entity_overlay.cpp +++ b/source/hud/entity_overlay.cpp @@ -577,6 +577,34 @@ namespace omath::hud add_snap_line(snap_line.start, snap_line.color, snap_line.width); } + void EntityOverlay::dispatch(const widget::ScanMarker& scan_marker) + { + const auto box_width = std::abs(m_canvas.top_right_corner.x - m_canvas.top_left_corner.x); + const auto box_height = std::abs(m_canvas.bottom_left_corner.y - m_canvas.top_left_corner.y); + + const auto center_x = (m_canvas.top_left_corner.x + m_canvas.top_right_corner.x) / 2.f; + const auto center_y = m_canvas.top_left_corner.y + box_height * 0.44f; + + const auto side = std::min(box_width, box_height) * 0.5f; + const auto h = side * std::sqrt(3.f) / 2.f; + + const std::array, 3> tri = { + Vector2{center_x, center_y - h * 2.f / 3.f}, + Vector2{center_x - side / 2.f, center_y + h / 3.f}, + Vector2{center_x + side / 2.f, center_y + h / 3.f}, + }; + + m_renderer->add_filled_polyline({tri.data(), tri.size()}, scan_marker.color); + + if (scan_marker.outline.value().w > 0.f) + m_renderer->add_polyline({tri.data(), tri.size()}, scan_marker.outline, scan_marker.outline_thickness); + } + + void EntityOverlay::dispatch(const widget::AimDot& aim_dot) + { + m_renderer->add_filled_circle(aim_dot.position, aim_dot.radius, aim_dot.color); + } + void EntityOverlay::draw_progress_ring(const Vector2& center, const widget::ProgressRing& ring) { constexpr auto pi = std::numbers::pi_v;