#include <stdafx.h> #include "Camera.h" #include "Context.h" namespace fpr { Camera::Camera(glm::vec3 position, glm::quat rotation, float FOV, float near, float far): m_position(position), m_rotation(rotation), m_FOV(FOV), m_near(near), m_far(far) { auto& extent = fpr::Context::Get().GetSwapChain()->GetCurrentExtent(); float aspect_ratio = static_cast<float>((float)extent.width / (float)extent.height); m_projection_matrix = glm::perspective(glm::radians(FOV), aspect_ratio, near, far); m_projection_matrix[1][1] *= -1.f; //INVERTED: Vulkan has inverted Y. //One solution is to invert viewport. Instead, I invert the projection matrix as this requires less overhead. m_view_matrix = glm::transpose(glm::toMat4(rotation)) * glm::translate(glm::mat4(1.0f), -position); } void Camera::Update() { m_view_matrix = glm::transpose(glm::toMat4(m_rotation)) * glm::translate(glm::mat4(1.0f), -m_position); } void Camera::SetPosition(glm::vec3 new_pos) { m_position = new_pos; } void Camera::SetRotation(float amount, glm::vec3 axis_rot) { m_rotation = glm::angleAxis(amount, axis_rot); } void Camera::MoveX(float value) { m_position += m_rotation * fpr::Context::RIGHT_VECTOR * value * m_movement_speed; } void Camera::MoveY(float value) { m_position += m_rotation * fpr::Context::UP_VECTOR * value * m_movement_speed; } void Camera::MoveZ(float value) { m_position += m_rotation * fpr::Context::FORWARD_VECTOR * value * m_movement_speed; } void Camera::RotateX(float value) { value *= m_rotation_speed; glm::quat new_rotation{}; new_rotation.x = sin(value / 2.0f); new_rotation.y = 0.0f; new_rotation.z = 0.0f; new_rotation.w = std::cos(value / 2.0f); m_rotation *= new_rotation; } void Camera::RotateY(float value) { value *= m_rotation_speed; glm::quat new_rotation{}; new_rotation.x = 0; new_rotation.y = sin(value / 2.0f); new_rotation.z = 0; new_rotation.w = std::cos(value / 2.0f); m_rotation = new_rotation * m_rotation; } void Camera::RotateZ(float value) { value *= m_rotation_speed; glm::quat new_rotation{}; new_rotation.x = 0.0f; new_rotation.y = 0.0f; new_rotation.z = sin(value / 2.0f); new_rotation.w = std::cos(value / 2.0f); m_rotation *= new_rotation; } const glm::mat4 Camera::GetViewMatrix() const { return m_view_matrix; } const glm::mat4 Camera::GetProjectionMatrix() const { return m_projection_matrix; } const glm::vec3 Camera::GetPosition() const { return m_position; } } // namespace fpr