From e8298cb5aa36066a36dbc2c89ca7116948fde08b Mon Sep 17 00:00:00 2001 From: "re.kovalev" Date: Wed, 4 May 2022 12:35:58 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9A=D0=BB=D0=B0=D1=81=D1=81=20=D0=BA=D0=B0?= =?UTF-8?q?=D0=BC=D0=B5=D1=80=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/Camera.h | 45 +++++++++++++++++++ src/Camera.cpp | 110 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 155 insertions(+) create mode 100644 include/Camera.h create mode 100644 src/Camera.cpp diff --git a/include/Camera.h b/include/Camera.h new file mode 100644 index 0000000..94e73f3 --- /dev/null +++ b/include/Camera.h @@ -0,0 +1,45 @@ +#ifndef CAMERA_H +#define CAMERA_H + +#include + +// Ближняя граница области отсечения +#define CAMERA_NEAR 0.1f +// Дальняя граница области отсечения +#define CAMERA_FAR 100.0f +// Вектор, задающий верх для камеры +#define CAMERA_UP_VECTOR glm::vec3(0.0f, 1.0f, 0.0f) +// Стандартный угол обзора +#define CAMERA_FOVy 60.0f + +class Camera +{ + public: + Camera(float aspect, const glm::vec3 &position = glm::vec3(0.0f, 0.0f, 0.0f), const glm::vec2 &xyOffset = glm::vec2(0.0f, 0.0f), float fovy = CAMERA_FOVy); // Конструктор камеры с проекцией перспективы + Camera(float width, float height, const glm::vec3 &position = glm::vec3(0.0f, 0.0f, 0.0f), const glm::vec2 &xyOffset = glm::vec2(0.0f, 0.0f)); // Конструктор ортографической камеры + virtual ~Camera(); // Деструктор + const glm::mat4& getProjection(); // Возвращает ссылку на константную матрицу проекции + const glm::mat4& getView(); // Возвращает ссылку на константную матрицу вида + void rotate(const glm::vec2 &xyOffset); // Поворачивает камеру на dx и dy пикселей + void move(const glm::vec3 &posOffset); // Сдвигает камеру на указанный вектор (dx,dy,dz) + void setPosition(const glm::vec3 &position); // Устанавливает местоположение + void setRotation(const glm::vec2 &xyOffset); // Устанавливает угол поворота камеры + void setPerspective(float fov, float aspect); // Устанавливает заданную матрицу перспективы + void setOrtho(float width, float height); // Устанавливает заданную ортографическую матрицу + void setSensitivity(float sensitivity); // Изменяет чувствительность мыши + protected: + Camera(const glm::vec3 &position, const glm::vec2 &xyOffset); // Приватный констуктор камеры без перспективы + void recalcTarget(); // Пересчет цели, на которую смотрит камера + void recalcView(); // Пересчет матрицы вида + + glm::vec3 position; // Местоположение камеры + glm::vec3 target; // Цель, на которую смотрит камера + glm::vec2 currentRotation; // Текущий поворот камеры + glm::mat4 projection; // Матрица проекции + glm::mat4 view; // Матрица вида + bool requiredRecalcView; // Необходимость пересчета матрицы вида камеры + float sensitivity; // Чувствительность мыши +}; + + +#endif // CAMERA_H \ No newline at end of file diff --git a/src/Camera.cpp b/src/Camera.cpp new file mode 100644 index 0000000..0987017 --- /dev/null +++ b/src/Camera.cpp @@ -0,0 +1,110 @@ +#include "Camera.h" + +#include +#include + +// Приватный констуктор камеры без перспективы +Camera::Camera(const glm::vec3 &pos, const glm::vec2 &xyOffset) +: position(pos), currentRotation(xyOffset) +{ + requiredRecalcView = true; + recalcTarget(); +} + +// Конструктор камеры с проекцией перспективы +Camera::Camera(float aspect, const glm::vec3 &position, const glm::vec2 &xyOffset, float fovy) +: Camera(position, xyOffset) +{ + setPerspective(fovy, aspect); +} + +// Конструктор ортографической камеры +Camera::Camera(float width, float height, const glm::vec3 &position, const glm::vec2 &xyOffset) +: Camera(position, xyOffset) +{ + setOrtho(width, height); +} + +// Деструктор +Camera::~Camera() { } + +// Пересчет цели, на которую смотрит камера +void Camera::recalcTarget() +{ + target.x = cos(glm::radians(currentRotation.x)) * cos(glm::radians(currentRotation.y)); + target.y = sin(glm::radians(currentRotation.x)); + target.z = cos(glm::radians(currentRotation.x)) * sin(glm::radians(currentRotation.y)); + + requiredRecalcView = true; +} + +// Пересчет матрицы вида +void Camera::recalcView() +{ + view = glm::lookAt(position, target, CAMERA_UP_VECTOR); + requiredRecalcView = false; +} + +// Возвращает ссылку на константную матрицу проекции +const glm::mat4& Camera::getProjection() +{ + return projection; +} + +// Возвращает ссылку на константную матрицу вида +const glm::mat4& Camera::getView() +{ + if (requiredRecalcView) + recalcView(); + return view; +} + +// Поворачивает камеру на dx и dy пикселей +void Camera::rotate(const glm::vec2 &xyOffset) +{ + currentRotation += xyOffset * sensitivity; + + recalcTarget(); + requiredRecalcView = true; +} + +// Сдвигает камеру на указанный вектор (dx,dy,dz)м +void Camera::move(const glm::vec3 &posOffset) +{ + position += posOffset; + + requiredRecalcView = true; +} + +// Устанавливает местоположение +void Camera::setPosition(const glm::vec3 &pos) +{ + position = pos; + + requiredRecalcView = true; +} + +// Устанавливает угол поворота камеры +void Camera::setRotation(const glm::vec2 &xyOffset) +{ + currentRotation = xyOffset; + recalcTarget(); +} + +// Устанавливает заданную матрицу перспективы +void Camera::setPerspective(float fovy, float aspect) +{ + projection = glm::perspective(glm::radians(fovy), aspect, CAMERA_NEAR, CAMERA_FAR); +} + +// Устанавливает заданную ортографическую матрицу +void Camera::setOrtho(float width, float height) +{ + projection = glm::ortho(0.0f, width, 0.0f, height, CAMERA_NEAR, CAMERA_FAR); +} + +// Изменяет чувствительность мыши +void Camera::setSensitivity(float sens) +{ + sensitivity = sens; +}