camera_service.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. #include "camera_service.h"
  2. #include "../../render/gl/camera.h"
  3. #include "../core/component.h"
  4. #include "../core/entity.h"
  5. #include "../core/world.h"
  6. #include "../game_config.h"
  7. #include "camera_controller.h"
  8. #include "camera_follow_system.h"
  9. #include "selection_system.h"
  10. #include "units/spawn_type.h"
  11. #include <QVector3D>
  12. #include <algorithm>
  13. #include <cmath>
  14. #include <memory>
  15. namespace Game::Systems {
  16. CameraService::CameraService()
  17. : m_controller(std::make_unique<CameraController>()),
  18. m_followSystem(std::make_unique<CameraFollowSystem>()) {}
  19. CameraService::~CameraService() = default;
  20. void CameraService::move(Render::GL::Camera &camera, float dx, float dz) {
  21. float const dist = camera.get_distance();
  22. float const scale = std::max(0.12F, dist * 0.05F);
  23. m_controller->move(camera, dx * scale, dz * scale);
  24. }
  25. void CameraService::elevate(Render::GL::Camera &camera, float dy) {
  26. float const distance = camera.get_distance();
  27. float const scale = std::clamp(distance * 0.05F, 0.1F, 5.0F);
  28. m_controller->move_up(camera, dy * scale);
  29. }
  30. void CameraService::zoom(Render::GL::Camera &camera, float delta) {
  31. m_controller->zoom_distance(camera, delta);
  32. }
  33. auto CameraService::get_distance(const Render::GL::Camera &camera) -> float {
  34. return camera.get_distance();
  35. }
  36. void CameraService::yaw(Render::GL::Camera &camera, float degrees) {
  37. m_controller->yaw(camera, degrees);
  38. }
  39. void CameraService::orbit(Render::GL::Camera &camera, float yaw_deg,
  40. float pitch_deg) {
  41. if (!std::isfinite(yaw_deg) || !std::isfinite(pitch_deg)) {
  42. return;
  43. }
  44. m_controller->orbit(camera, yaw_deg, pitch_deg);
  45. }
  46. void CameraService::orbit_direction(Render::GL::Camera &camera, int direction,
  47. bool shift) {
  48. const auto &cam_config = Game::GameConfig::instance().camera();
  49. float const step =
  50. shift ? cam_config.orbit_step_shift : cam_config.orbit_step_normal;
  51. float const pitch = step * float(direction);
  52. orbit(camera, 0.0F, pitch);
  53. }
  54. void CameraService::follow_selection(Render::GL::Camera &camera,
  55. Engine::Core::World &world, bool enable) {
  56. m_controller->set_follow_enabled(camera, enable);
  57. if (enable) {
  58. if (auto *selection_system = world.get_system<SelectionSystem>()) {
  59. m_followSystem->snap_to_selection(world, *selection_system, camera);
  60. }
  61. } else {
  62. auto pos = camera.get_position();
  63. auto tgt = camera.get_target();
  64. camera.look_at(pos, tgt, QVector3D(0, 1, 0));
  65. }
  66. }
  67. void CameraService::set_follow_lerp(Render::GL::Camera &camera, float alpha) {
  68. float const a = std::clamp(alpha, 0.0F, 1.0F);
  69. m_controller->set_follow_lerp(camera, a);
  70. }
  71. void CameraService::reset_camera(Render::GL::Camera &camera,
  72. Engine::Core::World &world, int local_owner_id,
  73. unsigned int player_unit_id) {
  74. Engine::Core::Entity *focus_entity = nullptr;
  75. for (auto *e : world.get_entities_with<Engine::Core::UnitComponent>()) {
  76. if (e == nullptr) {
  77. continue;
  78. }
  79. auto *u = e->get_component<Engine::Core::UnitComponent>();
  80. if (u == nullptr) {
  81. continue;
  82. }
  83. if (u->spawn_type == Game::Units::SpawnType::Barracks &&
  84. u->owner_id == local_owner_id && u->health > 0) {
  85. focus_entity = e;
  86. break;
  87. }
  88. }
  89. if ((focus_entity == nullptr) && player_unit_id != 0U) {
  90. focus_entity = world.get_entity(player_unit_id);
  91. }
  92. if (focus_entity != nullptr) {
  93. snap_to_entity(camera, *focus_entity);
  94. }
  95. }
  96. void CameraService::snap_to_entity(Render::GL::Camera &camera,
  97. Engine::Core::Entity &entity) {
  98. if (auto *t = entity.get_component<Engine::Core::TransformComponent>()) {
  99. QVector3D const center(t->position.x, t->position.y, t->position.z);
  100. const auto &cam_config = Game::GameConfig::instance().camera();
  101. camera.set_rts_view(center, cam_config.default_distance,
  102. cam_config.default_pitch, cam_config.default_yaw);
  103. }
  104. }
  105. void CameraService::update_follow(Render::GL::Camera &camera,
  106. Engine::Core::World &world,
  107. bool follow_enabled) {
  108. if (follow_enabled) {
  109. if (auto *selection_system = world.get_system<SelectionSystem>()) {
  110. m_followSystem->update(world, *selection_system, camera);
  111. }
  112. }
  113. }
  114. } // namespace Game::Systems