| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- #include "cloak_renderer.h"
- #include "../../geom/transforms.h"
- #include "../../gl/primitives.h"
- #include "../../humanoid/humanoid_specs.h"
- #include "../../humanoid/rig.h"
- #include "../../submitter.h"
- #include <QMatrix4x4>
- #include <QVector3D>
- #include <algorithm>
- #include <cmath>
- #include <numbers>
- namespace Render::GL {
- CloakRenderer::CloakRenderer(const CloakConfig &config) : m_config(config) {
- m_back_mesh = create_plane_mesh(1.0F, 1.0F, 16);
- m_shoulder_mesh = create_plane_mesh(1.0F, 1.0F, 12);
- }
- void CloakRenderer::set_config(const CloakConfig &config) { m_config = config; }
- void CloakRenderer::render(const DrawContext &ctx, const BodyFrames &frames,
- const HumanoidPalette &palette,
- const HumanoidAnimationContext &anim,
- ISubmitter &submitter) {
- (void)anim;
- (void)palette;
- const AttachmentFrame &torso = frames.torso;
- const AttachmentFrame &shoulder_l = frames.shoulder_l;
- const AttachmentFrame &shoulder_r = frames.shoulder_r;
- if (torso.radius <= 0.0F) {
- return;
- }
- QVector3D const cloak_color = palette.cloth;
- QVector3D const trim_color = palette.metal;
- QVector3D up = torso.up.normalized();
- QVector3D right = torso.right.normalized();
- QVector3D forward = torso.forward.normalized();
- QVector3D back = -forward;
- float const torso_r = torso.radius;
- float shoulder_span = (shoulder_r.origin - shoulder_l.origin).length();
- if (shoulder_span < 1e-4F) {
- shoulder_span = torso_r * 3.0F;
- }
- QVector3D shoulder_mid = (shoulder_l.origin + shoulder_r.origin) * 0.5F;
- {
- float cape_width = shoulder_span * 1.6F * m_config.width_scale;
- float cape_depth = torso_r * 1.8F;
- QVector3D cape_anchor = shoulder_mid + up * (torso_r * 0.82F);
- QMatrix4x4 cape_model;
- cape_model.translate(cape_anchor);
- float yaw = std::atan2(forward.x(), forward.z());
- cape_model.rotate(yaw * 180.0F / static_cast<float>(std::numbers::pi), 0.0F,
- 1.0F, 0.0F);
- cape_model.scale(cape_width, 1.0F, cape_depth);
- submitter.mesh(m_shoulder_mesh.get(), ctx.model * cape_model, cloak_color,
- nullptr, 1.0F, m_config.shoulder_material_id);
- }
- {
- float drape_width = shoulder_span * 1.22F * m_config.width_scale;
- float drape_length = torso_r * 4.2F * m_config.length_scale;
- QVector3D drape_anchor =
- shoulder_mid + up * (torso_r * 0.62F) + back * (torso_r * 0.96F);
- QMatrix4x4 drape_model;
- drape_model.translate(drape_anchor);
- QMatrix4x4 drape_orient;
- drape_orient.setColumn(0, QVector4D(right, 0.0F));
- drape_orient.setColumn(1, QVector4D(back, 0.0F));
- drape_orient.setColumn(2, QVector4D(-up, 0.0F));
- drape_orient.setColumn(3, QVector4D(0.0F, 0.0F, 0.0F, 1.0F));
- drape_model = drape_model * drape_orient;
- drape_model.translate(0.0F, 0.0F, drape_length * 0.5F);
- float const drape_bottom_flare = 0.35F;
- float const drape_shear = drape_bottom_flare * 0.35F;
- QMatrix4x4 flare;
- flare.setToIdentity();
- flare(0, 2) = drape_shear;
- drape_model = drape_model * flare;
- drape_model.scale(drape_width, 1.0F, drape_length);
- submitter.mesh(m_back_mesh.get(), ctx.model * drape_model, cloak_color,
- nullptr, 1.0F, m_config.back_material_id);
- }
- if (m_config.show_clasp) {
- QVector3D clasp_pos =
- shoulder_mid + up * (torso_r * 0.5F) + forward * (torso_r * 0.2F);
- submitter.mesh(
- get_unit_sphere(),
- Render::Geom::sphere_at(ctx.model, clasp_pos, torso_r * 0.12F),
- trim_color, nullptr, 1.0F, 1);
- }
- }
- } // namespace Render::GL
|