arm_guards_renderer.cpp 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. #include "arm_guards_renderer.h"
  2. #include "../../geom/math_utils.h"
  3. #include "../../geom/transforms.h"
  4. #include "../../gl/primitives.h"
  5. #include "../../humanoid/humanoid_specs.h"
  6. #include "../../submitter.h"
  7. #include <QMatrix4x4>
  8. #include <QVector3D>
  9. #include <cmath>
  10. namespace Render::GL {
  11. using Render::Geom::cylinder_between;
  12. using Render::Geom::sphere_at;
  13. ArmGuardsRenderer::ArmGuardsRenderer(const ArmGuardsConfig &config)
  14. : m_config(config) {}
  15. void ArmGuardsRenderer::render(const DrawContext &ctx, const BodyFrames &frames,
  16. const HumanoidPalette &,
  17. const HumanoidAnimationContext &,
  18. ISubmitter &submitter) {
  19. QVector3D elbow_l = frames.shoulder_l.origin +
  20. (frames.hand_l.origin - frames.shoulder_l.origin) * 0.55F;
  21. QVector3D elbow_r = frames.shoulder_r.origin +
  22. (frames.hand_r.origin - frames.shoulder_r.origin) * 0.55F;
  23. renderArmGuard(ctx, elbow_l, frames.hand_l.origin, submitter);
  24. renderArmGuard(ctx, elbow_r, frames.hand_r.origin, submitter);
  25. }
  26. void ArmGuardsRenderer::renderArmGuard(const DrawContext &ctx,
  27. const QVector3D &elbow,
  28. const QVector3D &wrist,
  29. ISubmitter &submitter) {
  30. QVector3D const guard_color = m_config.leather_color;
  31. QVector3D const strap_color = m_config.strap_color;
  32. QVector3D const arm_dir = (wrist - elbow).normalized();
  33. float const arm_length = (wrist - elbow).length();
  34. if (arm_length < 0.01F) {
  35. return;
  36. }
  37. float const guard_start = 0.15F;
  38. float const guard_end = 0.15F + m_config.guard_length;
  39. QVector3D const guard_top = elbow + arm_dir * (arm_length * guard_start);
  40. QVector3D const guard_bot =
  41. elbow + arm_dir * std::min(arm_length * guard_end, arm_length * 0.85F);
  42. constexpr int segments = 5;
  43. for (int i = 0; i < segments; ++i) {
  44. float const t = float(i) / float(segments - 1);
  45. QVector3D const pos = guard_top * (1.0F - t) + guard_bot * t;
  46. float const r = 0.026F - t * 0.004F;
  47. submitter.mesh(get_unit_sphere(), sphere_at(ctx.model, pos, r),
  48. guard_color * (1.0F - t * 0.08F), nullptr, 1.0F);
  49. }
  50. if (m_config.include_straps) {
  51. QVector3D const strap_1 = guard_top + arm_dir * 0.02F;
  52. QVector3D const strap_2 =
  53. guard_top + arm_dir * (guard_end - guard_start) * arm_length * 0.5F;
  54. QVector3D const strap_3 = guard_bot - arm_dir * 0.02F;
  55. for (const auto &strap_pos : {strap_1, strap_2, strap_3}) {
  56. submitter.mesh(get_unit_sphere(), sphere_at(ctx.model, strap_pos, 0.010F),
  57. strap_color, nullptr, 1.0F);
  58. }
  59. }
  60. }
  61. } // namespace Render::GL