shield_roman.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. #include "shield_roman.h"
  2. #include "../../geom/transforms.h"
  3. #include "../../gl/primitives.h"
  4. #include "../../humanoid/rig.h"
  5. #include "../../submitter.h"
  6. #include <QMatrix4x4>
  7. #include <QVector3D>
  8. #include <algorithm>
  9. #include <cmath>
  10. #include <numbers>
  11. namespace Render::GL {
  12. using Render::Geom::cylinder_between;
  13. using Render::Geom::sphere_at;
  14. RomanShieldRenderer::RomanShieldRenderer() {
  15. ShieldRenderConfig config;
  16. config.shield_color = {0.65F, 0.15F, 0.15F};
  17. config.trim_color = {0.78F, 0.70F, 0.45F};
  18. config.metal_color = {0.72F, 0.73F, 0.78F};
  19. config.shield_radius = 0.18F;
  20. config.shield_aspect = 1.3F;
  21. config.has_cross_decal = false;
  22. set_config(config);
  23. }
  24. void RomanShieldRenderer::render(const DrawContext &ctx,
  25. const BodyFrames &frames,
  26. const HumanoidPalette &palette,
  27. const HumanoidAnimationContext &,
  28. ISubmitter &submitter) {
  29. constexpr float k_shield_yaw_degrees = -70.0F;
  30. QMatrix4x4 rot;
  31. rot.rotate(k_shield_yaw_degrees, 0.0F, 1.0F, 0.0F);
  32. const QVector3D n = rot.map(QVector3D(0.0F, 0.0F, 1.0F));
  33. const QVector3D axis_x = rot.map(QVector3D(1.0F, 0.0F, 0.0F));
  34. const QVector3D axis_y = rot.map(QVector3D(0.0F, 1.0F, 0.0F));
  35. float const shield_width = 0.45F;
  36. float const shield_height = 1.0F;
  37. QVector3D shield_center = frames.hand_l.origin +
  38. axis_x * (-shield_width * 0.45F) + axis_y * 0.08F +
  39. n * 0.06F;
  40. QVector3D const shield_color{0.68F, 0.14F, 0.12F};
  41. QVector3D const trim_color{0.88F, 0.75F, 0.42F};
  42. QVector3D const metal_color{0.82F, 0.84F, 0.88F};
  43. QMatrix4x4 shield_body = ctx.model;
  44. shield_body.translate(shield_center);
  45. shield_body.rotate(90.0F, 0.0F, 1.0F, 0.0F);
  46. shield_body.rotate(k_shield_yaw_degrees, 0.0F, 1.0F, 0.0F);
  47. shield_body.scale(shield_width * 0.005F, shield_height * 0.5F, 0.24F);
  48. submitter.mesh(get_unit_cube(), shield_body, shield_color, nullptr, 1.0F, 4);
  49. float const rim_thickness = 0.020F;
  50. QVector3D top_left = shield_center + axis_y * (shield_height * 0.5F) -
  51. axis_x * (shield_width * 0.5F);
  52. QVector3D top_right = shield_center + axis_y * (shield_height * 0.5F) +
  53. axis_x * (shield_width * 0.5F);
  54. submitter.mesh(
  55. get_unit_cylinder(),
  56. cylinder_between(ctx.model, top_left, top_right, rim_thickness),
  57. trim_color, nullptr, 1.0F, 4);
  58. QVector3D bot_left = shield_center - axis_y * (shield_height * 0.5F) -
  59. axis_x * (shield_width * 0.5F);
  60. QVector3D bot_right = shield_center - axis_y * (shield_height * 0.5F) +
  61. axis_x * (shield_width * 0.5F);
  62. submitter.mesh(
  63. get_unit_cylinder(),
  64. cylinder_between(ctx.model, bot_left, bot_right, rim_thickness),
  65. trim_color, nullptr, 1.0F, 4);
  66. float const boss_radius = 0.08F;
  67. submitter.mesh(get_unit_sphere(),
  68. sphere_at(ctx.model, shield_center + n * 0.05F, boss_radius),
  69. metal_color, nullptr, 1.0F, 4);
  70. QVector3D const grip_a = shield_center - axis_x * 0.06F - n * 0.03F;
  71. QVector3D const grip_b = shield_center + axis_x * 0.06F - n * 0.03F;
  72. submitter.mesh(get_unit_cylinder(),
  73. cylinder_between(ctx.model, grip_a, grip_b, 0.012F),
  74. palette.leather, nullptr, 1.0F, 0);
  75. }
  76. } // namespace Render::GL