camera_service.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  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 <QVector3D>
  11. #include <algorithm>
  12. #include <cmath>
  13. namespace Game {
  14. namespace Systems {
  15. CameraService::CameraService()
  16. : m_controller(std::make_unique<CameraController>()),
  17. m_followSystem(std::make_unique<CameraFollowSystem>()) {}
  18. CameraService::~CameraService() = default;
  19. void CameraService::move(Render::GL::Camera &camera, float dx, float dz) {
  20. float dist = camera.getDistance();
  21. float scale = std::max(0.12f, dist * 0.05f);
  22. m_controller->move(camera, dx * scale, dz * scale);
  23. }
  24. void CameraService::elevate(Render::GL::Camera &camera, float dy) {
  25. float distance = camera.getDistance();
  26. float scale = std::clamp(distance * 0.05f, 0.1f, 5.0f);
  27. m_controller->moveUp(camera, dy * scale);
  28. }
  29. void CameraService::zoom(Render::GL::Camera &camera, float delta) {
  30. m_controller->zoomDistance(camera, delta);
  31. }
  32. float CameraService::getDistance(const Render::GL::Camera &camera) const {
  33. return camera.getDistance();
  34. }
  35. void CameraService::yaw(Render::GL::Camera &camera, float degrees) {
  36. m_controller->yaw(camera, degrees);
  37. }
  38. void CameraService::orbit(Render::GL::Camera &camera, float yawDeg,
  39. float pitchDeg) {
  40. if (!std::isfinite(yawDeg) || !std::isfinite(pitchDeg)) {
  41. return;
  42. }
  43. m_controller->orbit(camera, yawDeg, pitchDeg);
  44. }
  45. void CameraService::orbitDirection(Render::GL::Camera &camera, int direction,
  46. bool shift) {
  47. const auto &camConfig = Game::GameConfig::instance().camera();
  48. float step = shift ? camConfig.orbitStepShift : camConfig.orbitStepNormal;
  49. float pitch = step * float(direction);
  50. orbit(camera, 0.0f, pitch);
  51. }
  52. void CameraService::followSelection(Render::GL::Camera &camera,
  53. Engine::Core::World &world, bool enable) {
  54. m_controller->setFollowEnabled(camera, enable);
  55. if (enable) {
  56. if (auto *selectionSystem = world.getSystem<SelectionSystem>()) {
  57. m_followSystem->snapToSelection(world, *selectionSystem, camera);
  58. }
  59. } else {
  60. auto pos = camera.getPosition();
  61. auto tgt = camera.getTarget();
  62. camera.lookAt(pos, tgt, QVector3D(0, 1, 0));
  63. }
  64. }
  65. void CameraService::setFollowLerp(Render::GL::Camera &camera, float alpha) {
  66. float a = std::clamp(alpha, 0.0f, 1.0f);
  67. m_controller->setFollowLerp(camera, a);
  68. }
  69. void CameraService::resetCamera(Render::GL::Camera &camera,
  70. Engine::Core::World &world, int localOwnerId,
  71. unsigned int playerUnitId) {
  72. Engine::Core::Entity *focusEntity = nullptr;
  73. for (auto *e : world.getEntitiesWith<Engine::Core::UnitComponent>()) {
  74. if (!e) {
  75. continue;
  76. }
  77. auto *u = e->getComponent<Engine::Core::UnitComponent>();
  78. if (!u) {
  79. continue;
  80. }
  81. if (u->spawnType == Game::Units::SpawnType::Barracks &&
  82. u->ownerId == localOwnerId && u->health > 0) {
  83. focusEntity = e;
  84. break;
  85. }
  86. }
  87. if (!focusEntity && playerUnitId != 0) {
  88. focusEntity = world.getEntity(playerUnitId);
  89. }
  90. if (focusEntity) {
  91. snapToEntity(camera, *focusEntity);
  92. }
  93. }
  94. void CameraService::snapToEntity(Render::GL::Camera &camera,
  95. Engine::Core::Entity &entity) {
  96. if (auto *t = entity.getComponent<Engine::Core::TransformComponent>()) {
  97. QVector3D center(t->position.x, t->position.y, t->position.z);
  98. const auto &camConfig = Game::GameConfig::instance().camera();
  99. camera.setRTSView(center, camConfig.defaultDistance, camConfig.defaultPitch,
  100. camConfig.defaultYaw);
  101. }
  102. }
  103. void CameraService::updateFollow(Render::GL::Camera &camera,
  104. Engine::Core::World &world,
  105. bool followEnabled) {
  106. if (followEnabled) {
  107. if (auto *selectionSystem = world.getSystem<SelectionSystem>()) {
  108. m_followSystem->update(world, *selectionSystem, camera);
  109. }
  110. }
  111. }
  112. } // namespace Systems
  113. } // namespace Game