roman_light_helmet.cpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. #include "roman_light_helmet.h"
  2. #include "../../geom/transforms.h"
  3. #include "../../gl/primitives.h"
  4. #include "../../humanoid/humanoid_math.h"
  5. #include "../../humanoid/rig.h"
  6. #include "../../humanoid/style_palette.h"
  7. #include "../../submitter.h"
  8. #include <QMatrix4x4>
  9. #include <QVector3D>
  10. #include <cmath>
  11. namespace Render::GL {
  12. using Render::Geom::cone_from_to;
  13. using Render::Geom::cylinder_between;
  14. using Render::Geom::sphere_at;
  15. using Render::GL::Humanoid::saturate_color;
  16. void RomanLightHelmetRenderer::render(const DrawContext &ctx,
  17. const BodyFrames &frames,
  18. const HumanoidPalette &palette,
  19. const HumanoidAnimationContext &anim,
  20. ISubmitter &submitter) {
  21. (void)anim;
  22. AttachmentFrame head = frames.head;
  23. float const head_r = head.radius;
  24. if (head_r <= 0.0F) {
  25. return;
  26. }
  27. auto headPoint = [&](const QVector3D &normalized) -> QVector3D {
  28. return HumanoidRendererBase::frame_local_position(head, normalized);
  29. };
  30. QVector3D const helmet_color =
  31. saturate_color(palette.metal * QVector3D(1.15F, 0.92F, 0.68F));
  32. QVector3D const helmet_accent = helmet_color * 1.14F;
  33. QVector3D const helmet_top = headPoint(QVector3D(0.0F, 1.28F, 0.0F));
  34. QVector3D const helmet_bot = headPoint(QVector3D(0.0F, 0.08F, 0.0F));
  35. float const helmet_r = head_r * 1.08F;
  36. submitter.mesh(get_unit_cylinder(),
  37. cylinder_between(ctx.model, helmet_bot, helmet_top, helmet_r),
  38. helmet_color, nullptr, 1.0F, 2);
  39. QVector3D const apex_pos = headPoint(QVector3D(0.0F, 1.48F, 0.0F));
  40. submitter.mesh(
  41. get_unit_cone(),
  42. cone_from_to(ctx.model, helmet_top, apex_pos, helmet_r * 0.97F),
  43. helmet_accent, nullptr, 1.0F, 2);
  44. auto ring = [&](float y_offset, float r_scale, const QVector3D &col) {
  45. QVector3D const center = headPoint(QVector3D(0.0F, y_offset, 0.0F));
  46. float const h = head_r * 0.018F;
  47. QVector3D const a = center + head.up * (h * 0.5F);
  48. QVector3D const b = center - head.up * (h * 0.5F);
  49. submitter.mesh(get_unit_cylinder(),
  50. cylinder_between(ctx.model, a, b, helmet_r * r_scale), col,
  51. nullptr, 1.0F, 2);
  52. };
  53. ring(0.35F, 1.06F, helmet_accent);
  54. ring(0.95F, 1.02F, helmet_color * 1.04F);
  55. QVector3D const neck_guard_top = headPoint(QVector3D(0.0F, 0.03F, -0.85F));
  56. QVector3D const neck_guard_bot = headPoint(QVector3D(0.0F, -0.32F, -0.92F));
  57. submitter.mesh(get_unit_cylinder(),
  58. cylinder_between(ctx.model, neck_guard_bot, neck_guard_top,
  59. helmet_r * 0.86F),
  60. helmet_color * 0.90F, nullptr, 1.0F, 2);
  61. QVector3D const crest_base = apex_pos;
  62. QVector3D const crest_mid = crest_base + head.up * 0.09F;
  63. QVector3D const crest_top = crest_mid + head.up * 0.12F;
  64. submitter.mesh(get_unit_cylinder(),
  65. cylinder_between(ctx.model, crest_base, crest_mid, 0.018F),
  66. helmet_accent, nullptr, 1.0F, 2);
  67. submitter.mesh(get_unit_cone(),
  68. cone_from_to(ctx.model, crest_mid, crest_top, 0.042F),
  69. QVector3D(0.88F, 0.18F, 0.18F), nullptr, 1.0F, 0);
  70. submitter.mesh(get_unit_sphere(), sphere_at(ctx.model, crest_top, 0.020F),
  71. helmet_accent, nullptr, 1.0F, 2);
  72. }
  73. } // namespace Render::GL