#include "Camera3D.h" #include 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) ); } }