spear_pose_utils.h 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. #pragma once
  2. #include "../entity/renderer_constants.h"
  3. #include "../gl/humanoid/animation/animation_inputs.h"
  4. #include "../gl/humanoid/humanoid_types.h"
  5. #include <QVector3D>
  6. #include <algorithm>
  7. #include <cmath>
  8. namespace Render::GL {
  9. inline auto
  10. compute_spear_direction(const AnimationInputs &anim_inputs) -> QVector3D {
  11. auto normalize = [](QVector3D dir) {
  12. if (dir.lengthSquared() > 1e-6F) {
  13. dir.normalize();
  14. }
  15. return dir;
  16. };
  17. QVector3D spear_dir = normalize(QVector3D(0.05F, 0.55F, 0.85F));
  18. if (anim_inputs.is_in_hold_mode || anim_inputs.is_exiting_hold) {
  19. float const t = anim_inputs.is_in_hold_mode
  20. ? 1.0F
  21. : (1.0F - anim_inputs.hold_exit_progress);
  22. QVector3D const braced_dir = normalize(QVector3D(0.05F, 0.40F, 0.91F));
  23. spear_dir = normalize(spear_dir * (1.0F - t) + braced_dir * t);
  24. } else if (anim_inputs.is_attacking && anim_inputs.is_melee) {
  25. float const attack_phase =
  26. std::fmod(anim_inputs.time * SPEARMAN_INV_ATTACK_CYCLE_TIME, 1.0F);
  27. if (attack_phase >= 0.30F && attack_phase < 0.50F) {
  28. float const t = (attack_phase - 0.30F) / 0.20F;
  29. QVector3D const attack_dir = normalize(QVector3D(0.03F, -0.15F, 1.0F));
  30. spear_dir = normalize(spear_dir * (1.0F - t) + attack_dir * t);
  31. }
  32. }
  33. return spear_dir;
  34. }
  35. inline auto compute_offhand_spear_grip(
  36. const HumanoidPose &pose, const HumanoidAnimationContext &anim_ctx,
  37. const QVector3D &main_hand_pos, bool main_is_left, float along_offset,
  38. float y_drop = 0.05F, float lateral_offset = 0.05F) -> QVector3D {
  39. QVector3D const spear_dir = compute_spear_direction(anim_ctx.inputs);
  40. QVector3D offhand = main_hand_pos + spear_dir * along_offset;
  41. QVector3D right_axis = pose.shoulder_r - pose.shoulder_l;
  42. right_axis.setY(0.0F);
  43. if (right_axis.lengthSquared() < 1e-6F) {
  44. right_axis = QVector3D(1.0F, 0.0F, 0.0F);
  45. } else {
  46. right_axis.normalize();
  47. }
  48. offhand += (main_is_left ? right_axis : -right_axis) * lateral_offset;
  49. offhand.setY(offhand.y() - y_drop);
  50. QVector3D torso_center = (pose.shoulder_l + pose.shoulder_r) * 0.5F;
  51. torso_center.setY(offhand.y());
  52. offhand = offhand * 0.65F + torso_center * 0.35F;
  53. return offhand;
  54. }
  55. } // namespace Render::GL