diff --git a/examples/example_hud/gui/main_window.cpp b/examples/example_hud/gui/main_window.cpp index 2dd4021..f36db28 100644 --- a/examples/example_hud/gui/main_window.cpp +++ b/examples/example_hud/gui/main_window.cpp @@ -237,6 +237,44 @@ namespace imgui_desktop::gui const auto* vp = ImGui::GetMainViewport(); const DashedBar dbar{m_bar_color, m_bar_outline_color, m_bar_bg_color, m_bar_width, m_bar_value, m_bar_dash_len, m_bar_dash_gap, m_bar_offset}; + const float entity_height = m_entity_bottom_y - m_entity_top_y; + const float entity_half_width = entity_height / m_entity_aspect; + const auto joint = [&](const float x, const float y) + { + return omath::Vector2{m_entity_x + (x * 2.f - 1.f) * entity_half_width, + m_entity_top_y + y * entity_height}; + }; + const auto head = joint(0.5f, 0.1f); + const auto neck = joint(0.5f, 0.22f); + const auto torso = joint(0.5f, 0.5f); + const auto left_shoulder = joint(0.3f, 0.25f); + const auto right_shoulder = joint(0.7f, 0.25f); + const auto left_elbow = joint(0.18f, 0.42f); + const auto right_elbow = joint(0.82f, 0.42f); + const auto left_hand = joint(0.1f, 0.58f); + const auto right_hand = joint(0.9f, 0.58f); + const auto left_hip = joint(0.4f, 0.55f); + const auto right_hip = joint(0.6f, 0.55f); + const auto left_knee = joint(0.36f, 0.75f); + const auto right_knee = joint(0.64f, 0.75f); + const auto left_foot = joint(0.3f, 0.95f); + const auto right_foot = joint(0.7f, 0.95f); + const std::array skeleton_bones = { + Bone{head, neck}, + Bone{neck, torso}, + Bone{neck, left_shoulder}, + Bone{left_shoulder, left_elbow}, + Bone{left_elbow, left_hand}, + Bone{neck, right_shoulder}, + Bone{right_shoulder, right_elbow}, + Bone{right_elbow, right_hand}, + Bone{torso, left_hip}, + Bone{left_hip, left_knee}, + Bone{left_knee, left_foot}, + Bone{torso, right_hip}, + Bone{right_hip, right_knee}, + Bone{right_knee, right_foot}, + }; const auto animated_color = [&](const omath::Color& color, const float hue_offset) { if (!m_animate_gradients) @@ -341,7 +379,7 @@ namespace imgui_desktop::gui }, 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_skeleton, Skeleton{skeleton_bones, m_skel_color, m_skel_thickness}), when(m_show_proj, ProjectileAim{{m_proj_pos_x, m_proj_pos_y}, m_proj_color, m_proj_size, diff --git a/include/omath/hud/entity_overlay.hpp b/include/omath/hud/entity_overlay.hpp index feeb0d9..2be1615 100644 --- a/include/omath/hud/entity_overlay.hpp +++ b/include/omath/hud/entity_overlay.hpp @@ -184,6 +184,7 @@ namespace omath::hud EntityOverlay& add_snap_line(const Vector2& start_pos, const Color& color, float width); EntityOverlay& add_skeleton(const Color& color, float thickness = 1.f); + EntityOverlay& add_skeleton(std::span bones, const Color& color, float thickness = 1.f); // ── Declarative interface ───────────────────────────────────────── /// Pass any combination of widget:: descriptor structs (and std::optional diff --git a/include/omath/hud/entity_overlay_widgets.hpp b/include/omath/hud/entity_overlay_widgets.hpp index 32f1505..3cca92d 100644 --- a/include/omath/hud/entity_overlay_widgets.hpp +++ b/include/omath/hud/entity_overlay_widgets.hpp @@ -6,11 +6,14 @@ #include "omath/linear_algebra/vector2.hpp" #include "omath/utility/color.hpp" #include +#include #include #include +#include #include #include #include +#include namespace omath::hud::widget { @@ -106,10 +109,37 @@ namespace omath::hud::widget float thickness = 1.f; }; + struct Bone + { + Vector2 start; + Vector2 end; + }; + struct Skeleton { + std::vector bones; Color color; float thickness = 1.f; + + Skeleton(const Color& color, const float thickness = 1.f): color(color), thickness(thickness) + { + } + + Skeleton(const std::span bones, const Color& color, const float thickness = 1.f) + : bones(bones.begin(), bones.end()), color(color), thickness(thickness) + { + } + + Skeleton(const std::initializer_list bones, const Color& color, const float thickness = 1.f) + : bones(bones), color(color), thickness(thickness) + { + } + + template + Skeleton(const std::array& bones, const Color& color, const float thickness = 1.f) + : Skeleton(std::span{bones}, color, thickness) + { + } }; struct SnapLine { diff --git a/source/hud/entity_overlay.cpp b/source/hud/entity_overlay.cpp index dc8f1b0..3835dd2 100644 --- a/source/hud/entity_overlay.cpp +++ b/source/hud/entity_overlay.cpp @@ -337,6 +337,14 @@ namespace omath::hud return *this; } + EntityOverlay& EntityOverlay::add_skeleton(const std::span bones, const Color& color, + const float thickness) + { + for (const auto& bone : bones) + m_renderer->add_line(bone.start, bone.end, color, thickness); + return *this; + } + void EntityOverlay::draw_dashed_line(const Vector2& from, const Vector2& to, const Color& color, const float dash_len, const float gap_len, const float thickness) const { @@ -848,7 +856,10 @@ namespace omath::hud void EntityOverlay::dispatch(const widget::Skeleton& skeleton) { - add_skeleton(skeleton.color, skeleton.thickness); + if (skeleton.bones.empty()) + add_skeleton(skeleton.color, skeleton.thickness); + else + add_skeleton(skeleton.bones, skeleton.color, skeleton.thickness); } void EntityOverlay::dispatch(const widget::SnapLine& snap_line)