diff --git a/include/Camera.h b/include/Camera.h index 2979409..3357cba 100644 --- a/include/Camera.h +++ b/include/Camera.h @@ -18,6 +18,7 @@ class Camera Camera(float aspect, const glm::vec3 &position = glm::vec3(0.0f, 0.0f, 0.0f), const glm::vec2 &xyOffset = glm::vec2(90.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(90.0f, 0.0f)); // Конструктор ортографической камеры virtual ~Camera(); // Деструктор + const glm::mat4& getVP(); // Возвращает ссылку на константную матрицу произведения матриц вида и проекции const glm::mat4& getProjection(); // Возвращает ссылку на константную матрицу проекции const glm::mat4& getView(); // Возвращает ссылку на константную матрицу вида void rotate(const glm::vec2 &xyOffset); // Поворачивает камеру на dx и dy пикселей @@ -31,12 +32,15 @@ class Camera Camera(const glm::vec3 &position, const glm::vec2 &xyOffset); // Защищенный (protected) констуктор камеры без перспективы void recalcTarget(); // Пересчет цели, на которую смотрит камера void recalcView(); // Пересчет матрицы вида + void recalcVP(); // Пересчет произведения матриц glm::vec3 position; // Местоположение камеры glm::vec3 target; // Цель, на которую смотрит камера glm::vec2 currentRotation; // Текущий поворот камеры glm::mat4 projection; // Матрица проекции glm::mat4 view; // Матрица вида + glm::mat4 vp; // Матрица произведения вида и проекции + bool requiredRecalcVP; // Необходимость пересчета матрицы вида и проекции камеры bool requiredRecalcView; // Необходимость пересчета матрицы вида камеры float sensitivity; // Чувствительность мыши }; diff --git a/src/Camera.cpp b/src/Camera.cpp index 2a62b32..fb9943e 100644 --- a/src/Camera.cpp +++ b/src/Camera.cpp @@ -41,6 +41,7 @@ void Camera::recalcTarget() target.z = sin(glm::radians(currentRotation.x)) * cos(glm::radians(currentRotation.y)); requiredRecalcView = true; + requiredRecalcVP = true; } // Пересчет матрицы вида @@ -50,6 +51,13 @@ void Camera::recalcView() requiredRecalcView = false; } +// Пересчет произведения матриц +void Camera::recalcVP() +{ + vp = projection * view; + requiredRecalcVP = false; +} + // Возвращает ссылку на константную матрицу проекции const glm::mat4& Camera::getProjection() { @@ -64,6 +72,18 @@ const glm::mat4& Camera::getView() return view; } +// Возвращает ссылку на константную матрицу вида +const glm::mat4& Camera::getVP() +{ + if (requiredRecalcVP) + { + if (requiredRecalcView) + recalcView(); + recalcVP(); + } + return vp; +} + // Поворачивает камеру на dx и dy пикселей void Camera::rotate(const glm::vec2 &xyOffset) { @@ -71,6 +91,7 @@ void Camera::rotate(const glm::vec2 &xyOffset) recalcTarget(); requiredRecalcView = true; + requiredRecalcVP = true; } // Сдвигает камеру на указанный вектор (dx,dy,dz) @@ -79,6 +100,7 @@ void Camera::move(const glm::vec3 &posOffset) position += posOffset; requiredRecalcView = true; + requiredRecalcVP = true; } // Устанавливает местоположение @@ -87,6 +109,7 @@ void Camera::setPosition(const glm::vec3 &pos) position = pos; requiredRecalcView = true; + requiredRecalcVP = true; } // Устанавливает угол поворота камеры @@ -100,12 +123,14 @@ void Camera::setRotation(const glm::vec2 &xyOffset) void Camera::setPerspective(float fovy, float aspect) { projection = glm::perspective(glm::radians(fovy), aspect, CAMERA_NEAR, CAMERA_FAR); + requiredRecalcVP = true; } // Устанавливает заданную ортографическую матрицу void Camera::setOrtho(float width, float height) { projection = glm::ortho(0.0f, width, 0.0f, height, CAMERA_NEAR, CAMERA_FAR); + requiredRecalcVP = true; } // Изменяет чувствительность мыши