camera.h 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. #pragma once
  2. #include <QMatrix4x4>
  3. #include <QPointF>
  4. #include <QVector3D>
  5. namespace Render::GL {
  6. namespace CameraDefaults {
  7. inline constexpr float k_default_rts_distance = 10.0F;
  8. inline constexpr float k_default_rts_angle = 45.0F;
  9. inline constexpr float k_default_rts_yaw = 45.0F;
  10. inline constexpr float k_default_fov = 45.0F;
  11. inline constexpr float k_default_aspect_ratio = 16.0F / 9.0F;
  12. inline constexpr float k_default_far_plane = 200.0F;
  13. inline constexpr float k_default_ortho_size = 10.0F;
  14. inline constexpr float k_default_pitch_min = -85.0F;
  15. } // namespace CameraDefaults
  16. class Camera {
  17. friend void solve_constraints(Render::GL::Camera *self,
  18. bool allowTargetShift);
  19. public:
  20. Camera();
  21. void set_position(const QVector3D &position);
  22. void set_target(const QVector3D &target);
  23. void set_up(const QVector3D &up);
  24. void look_at(const QVector3D &position, const QVector3D &target,
  25. const QVector3D &up);
  26. void set_perspective(float fov, float aspect, float near_plane,
  27. float far_plane);
  28. void set_orthographic(float left, float right, float bottom, float top,
  29. float near_plane, float far_plane);
  30. void move_forward(float distance);
  31. void move_right(float distance);
  32. void move_up(float distance);
  33. void zoom(float delta);
  34. void zoom_distance(float delta);
  35. void rotate(float yaw, float pitch);
  36. void pan(float right_dist, float forward_dist);
  37. void elevate(float dy);
  38. void yaw(float degrees);
  39. void orbit(float yaw_deg, float pitch_deg);
  40. void update(float dt);
  41. auto screen_to_ground(qreal sx, qreal sy, qreal screenW, qreal screenH,
  42. QVector3D &outWorld) const -> bool;
  43. auto world_to_screen(const QVector3D &world, qreal screenW, qreal screenH,
  44. QPointF &outScreen) const -> bool;
  45. void set_follow_enabled(bool enable) { m_followEnabled = enable; }
  46. [[nodiscard]] auto is_follow_enabled() const -> bool {
  47. return m_followEnabled;
  48. }
  49. void set_follow_lerp(float alpha) { m_followLerp = alpha; }
  50. void set_follow_offset(const QVector3D &off) { m_followOffset = off; }
  51. void capture_follow_offset() { m_followOffset = m_position - m_target; }
  52. void update_follow(const QVector3D &targetCenter);
  53. void set_rts_view(const QVector3D &center,
  54. float distance = CameraDefaults::k_default_rts_distance,
  55. float angle = CameraDefaults::k_default_rts_angle,
  56. float yaw_deg = CameraDefaults::k_default_rts_yaw);
  57. void
  58. set_top_down_view(const QVector3D &center,
  59. float distance = CameraDefaults::k_default_rts_distance);
  60. void apply_soft_boundaries(bool isPanning = false);
  61. [[nodiscard]] auto get_view_matrix() const -> QMatrix4x4;
  62. [[nodiscard]] auto get_projection_matrix() const -> QMatrix4x4;
  63. [[nodiscard]] auto get_view_projection_matrix() const -> QMatrix4x4;
  64. [[nodiscard]] auto get_target() const -> const QVector3D & {
  65. return m_target;
  66. }
  67. [[nodiscard]] auto get_up_vector() const -> const QVector3D & { return m_up; }
  68. [[nodiscard]] auto get_right_vector() const -> const QVector3D & {
  69. return m_right;
  70. }
  71. [[nodiscard]] auto get_forward_vector() const -> const QVector3D & {
  72. return m_front;
  73. }
  74. [[nodiscard]] auto get_position() const -> const QVector3D & {
  75. return m_position;
  76. }
  77. [[nodiscard]] auto get_distance() const -> float;
  78. [[nodiscard]] auto get_pitch_deg() const -> float;
  79. [[nodiscard]] auto get_fov() const -> float { return m_fov; }
  80. [[nodiscard]] auto get_aspect() const -> float { return m_aspect; }
  81. [[nodiscard]] auto get_near() const -> float { return m_near_plane; }
  82. [[nodiscard]] auto get_far() const -> float { return m_far_plane; }
  83. [[nodiscard]] auto is_in_frustum(const QVector3D &center,
  84. float radius) const -> bool;
  85. private:
  86. QVector3D m_position{0.0F, 0.0F, 0.0F};
  87. QVector3D m_target{0.0F, 0.0F, -1.0F};
  88. QVector3D m_up{0.0F, 1.0F, 0.0F};
  89. QVector3D m_front{0.0F, 0.0F, -1.0F};
  90. QVector3D m_right{1.0F, 0.0F, 0.0F};
  91. QVector3D m_lastPosition;
  92. bool m_isPerspective = true;
  93. float m_fov = CameraDefaults::k_default_fov;
  94. float m_aspect = CameraDefaults::k_default_aspect_ratio;
  95. float m_near_plane = 1.0F;
  96. float m_far_plane = CameraDefaults::k_default_far_plane;
  97. float m_orthoLeft = -CameraDefaults::k_default_ortho_size;
  98. float m_orthoRight = CameraDefaults::k_default_ortho_size;
  99. float m_orthoBottom = -CameraDefaults::k_default_ortho_size;
  100. float m_orthoTop = CameraDefaults::k_default_ortho_size;
  101. bool m_followEnabled = false;
  102. QVector3D m_followOffset{0, 0, 0};
  103. float m_followLerp = 0.15F;
  104. float m_ground_y = 0.0F;
  105. float m_min_height = 0.5F;
  106. float m_pitchMinDeg = CameraDefaults::k_default_pitch_min;
  107. float m_pitchMaxDeg = -5.0F;
  108. bool m_orbitPending = false;
  109. float m_orbitStartYaw = 0.0F;
  110. float m_orbitStartPitch = 0.0F;
  111. float m_orbitTargetYaw = 0.0F;
  112. float m_orbitTargetPitch = 0.0F;
  113. float m_orbitTime = 0.0F;
  114. float m_orbitDuration = 0.12F;
  115. void update_vectors();
  116. void clamp_above_ground();
  117. static void compute_yaw_pitch_from_offset(const QVector3D &off,
  118. float &yaw_deg, float &pitch_deg);
  119. };
  120. } // namespace Render::GL