camera_service.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  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. auto *u = e->getComponent<Engine::Core::UnitComponent>();
  77. if (!u)
  78. continue;
  79. if (u->unitType == "barracks" && u->ownerId == localOwnerId &&
  80. u->health > 0) {
  81. focusEntity = e;
  82. break;
  83. }
  84. }
  85. if (!focusEntity && playerUnitId != 0)
  86. focusEntity = world.getEntity(playerUnitId);
  87. if (focusEntity) {
  88. snapToEntity(camera, *focusEntity);
  89. }
  90. }
  91. void CameraService::snapToEntity(Render::GL::Camera &camera,
  92. Engine::Core::Entity &entity) {
  93. if (auto *t = entity.getComponent<Engine::Core::TransformComponent>()) {
  94. QVector3D center(t->position.x, t->position.y, t->position.z);
  95. const auto &camConfig = Game::GameConfig::instance().camera();
  96. camera.setRTSView(center, camConfig.defaultDistance, camConfig.defaultPitch,
  97. camConfig.defaultYaw);
  98. }
  99. }
  100. void CameraService::updateFollow(Render::GL::Camera &camera,
  101. Engine::Core::World &world,
  102. bool followEnabled) {
  103. if (followEnabled) {
  104. if (auto *selectionSystem = world.getSystem<SelectionSystem>()) {
  105. m_followSystem->update(world, *selectionSystem, camera);
  106. }
  107. }
  108. }
  109. } // namespace Systems
  110. } // namespace Game