roman_greaves.cpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. #include "roman_greaves.h"
  2. #include "../../geom/transforms.h"
  3. #include "../../gl/primitives.h"
  4. #include "../../humanoid/humanoid_specs.h"
  5. #include "../../humanoid/style_palette.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. using Render::GL::Humanoid::saturate_color;
  14. void RomanGreavesRenderer::render(const DrawContext &ctx,
  15. const BodyFrames &frames,
  16. const HumanoidPalette &palette,
  17. const HumanoidAnimationContext &anim,
  18. ISubmitter &submitter) {
  19. (void)anim;
  20. using HP = HumanProportions;
  21. QVector3D const greaves_color =
  22. saturate_color(palette.metal * QVector3D(0.95F, 0.88F, 0.68F));
  23. auto render_greave = [&](const AttachmentFrame &shin) {
  24. float const shin_r = shin.radius;
  25. float const shin_length = HP::LOWER_LEG_LEN;
  26. float const greave_start = shin_length * 0.10F;
  27. float const greave_end = shin_length * 0.92F;
  28. float const greave_len = greave_end - greave_start;
  29. QVector3D greave_top = shin.origin + shin.up * (shin_length - greave_start);
  30. QVector3D greave_bottom =
  31. shin.origin + shin.up * (shin_length - greave_end);
  32. QVector3D const &plate_up = shin.up;
  33. QVector3D const &plate_forward = shin.forward;
  34. QVector3D const &plate_right = shin.right;
  35. constexpr int NUM_SEGMENTS = 3;
  36. float const angles[NUM_SEGMENTS] = {-0.8F, 0.0F, 0.8F};
  37. float const greave_offset = shin_r * 1.08F;
  38. float const greave_thickness = 0.006F;
  39. float const segment_width = shin_r * 0.55F;
  40. for (int seg = 0; seg < NUM_SEGMENTS; ++seg) {
  41. float angle = angles[seg];
  42. float cos_a = std::cos(angle);
  43. float sin_a = std::sin(angle);
  44. QVector3D segment_offset = plate_forward * (greave_offset * cos_a) +
  45. plate_right * (greave_offset * sin_a);
  46. QVector3D segment_top = greave_top + segment_offset;
  47. QVector3D segment_bottom = greave_bottom + segment_offset;
  48. QVector3D segment_center = (segment_top + segment_bottom) * 0.5F;
  49. QVector3D segment_normal =
  50. (plate_forward * cos_a + plate_right * sin_a).normalized();
  51. QVector3D seg_tangent =
  52. QVector3D::crossProduct(plate_up, segment_normal).normalized();
  53. QMatrix4x4 seg_transform = ctx.model;
  54. seg_transform.translate(segment_center);
  55. QMatrix4x4 orient;
  56. orient.setColumn(0, QVector4D(seg_tangent, 0.0F));
  57. orient.setColumn(1, QVector4D(plate_up, 0.0F));
  58. orient.setColumn(2, QVector4D(segment_normal, 0.0F));
  59. orient.setColumn(3, QVector4D(0.0F, 0.0F, 0.0F, 1.0F));
  60. seg_transform = seg_transform * orient;
  61. seg_transform.scale(segment_width, greave_len * 0.5F, greave_thickness);
  62. submitter.mesh(get_unit_cube(), seg_transform, greaves_color, nullptr,
  63. 1.0F, 5);
  64. }
  65. };
  66. render_greave(frames.shin_l);
  67. render_greave(frames.shin_r);
  68. }
  69. } // namespace Render::GL