Newer
Older
ForwardPlusRenderer / src / Camera.cpp
#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; //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