charcoal/OpenGLEngine/Camera3D.cpp
2018-09-12 17:03:46 -04:00

83 lines
2.0 KiB
C++

#include "Camera3D.h"
#include <glm/gtc/matrix_transform.hpp>
namespace charcoal
{
Camera3D::Camera3D(
float fov_y,
float aspect_ratio,
float znear,
float zfar,
const vec3& position,
const vec3& forward,
const vec3& up,
const vec3& right
)
{
update_frustum(fov_y, aspect_ratio, znear, zfar);
update_position(position);
update_orientation(forward, up, right);
}
void Camera3D::update_frustum(float fov_y, float aspect_ratio, float znear, float zfar)
{
m_projection_matrix = glm::perspective(fov_y, aspect_ratio, znear, zfar);
}
void Camera3D::update_position(const vec3& position)
{
m_position = position;
}
void Camera3D::update_orientation(const vec3& forward, const vec3& up, const vec3& right)
{
vec3 real_forward;
vec3 real_up;
vec3 real_right;
if (right == vec3(0.0f))
real_right = glm::normalize(glm::cross(forward, up));
else
real_right = right;
real_forward = glm::normalize(forward);
real_up = glm::cross(real_right, real_forward);
m_forward = vec4(real_forward, 0.0f);
m_up = vec4(real_up, 0.0f);
m_right = vec4(real_right, 0.0f);
}
void Camera3D::direct_update_orientation(const vec3& forward, const vec3& up, const vec3& right)
{
m_forward = vec4(forward, 0.0f);
m_up = vec4(up, 0.0f);
m_right = vec4(right, 0.0f);
}
void Camera3D::translate(const vec3& translation)
{
m_position += translation;
}
void Camera3D::rotate(const vec3& axis, float angle)
{
mat4 rotation = glm::rotate(mat4(1.0f), angle, axis);
m_forward = rotation * m_forward;
m_up = rotation * m_up;
m_right = rotation * m_right;
}
void Camera3D::prerender()
{
// This works but it mirrors the scene left and right?
m_view_matrix = mat4(
vec4(m_right.x, m_up.x, -m_forward.x, 0.0f),
vec4(m_right.y, m_up.y, -m_forward.y, 0.0f),
vec4(m_right.z, m_up.z, -m_forward.z, 0.0f),
vec4(-glm::dot(vec3(m_right), m_position), -glm::dot(vec3(m_up), m_position), glm::dot(vec3(m_forward), m_position), 1.0f)
);
}
}