Files
FGL-Engine/src/engine/Camera.cpp
2024-01-09 08:29:46 -05:00

116 lines
4.1 KiB
C++

//
// Created by kj16609 on 11/28/23.
//
#include "Camera.hpp"
#include <cassert>
#include <limits>
namespace fgl::engine
{
void Camera::setOrthographicProjection( float left, float right, float top, float bottom, float near, float far )
{
projection_matrix = glm::mat4 { 1.0f };
projection_matrix[ 0 ][ 0 ] = 2.0f / ( right - left );
projection_matrix[ 1 ][ 1 ] = 2.0f / ( bottom - top );
projection_matrix[ 2 ][ 2 ] = 1.0f / ( far - near );
projection_matrix[ 3 ][ 0 ] = -( right + left ) / ( right - left );
projection_matrix[ 3 ][ 1 ] = -( bottom + top ) / ( bottom - top );
projection_matrix[ 3 ][ 2 ] = -near / ( far - near );
}
void Camera::setPerspectiveProjection( float fovy, float aspect, float near, float far )
{
assert( glm::abs( aspect - std::numeric_limits< float >::epsilon() ) > 0 );
const float tan_half_fovy { std::tan( fovy / 2.0f ) };
projection_matrix = glm::mat4 { 0.0f };
projection_matrix[ 0 ][ 0 ] = 1.0f / ( aspect * tan_half_fovy );
projection_matrix[ 1 ][ 1 ] = 1.0f / ( tan_half_fovy );
projection_matrix[ 2 ][ 2 ] = far / ( far - near );
projection_matrix[ 2 ][ 3 ] = 1.0f;
projection_matrix[ 3 ][ 2 ] = -( far * near ) / ( far - near );
}
void Camera::setViewDirection( glm::vec3 position, glm::vec3 direction, glm::vec3 up )
{
const glm::vec3 w { glm::normalize( direction ) };
const glm::vec3 u { glm::normalize( glm::cross( w, up ) ) };
const glm::vec3 v { glm::cross( w, u ) };
view_matrix = glm::mat4 { 1.0f };
view_matrix[ 0 ][ 0 ] = u.x;
view_matrix[ 1 ][ 0 ] = u.y;
view_matrix[ 2 ][ 0 ] = u.z;
view_matrix[ 0 ][ 1 ] = v.x;
view_matrix[ 1 ][ 1 ] = v.y;
view_matrix[ 2 ][ 1 ] = v.z;
view_matrix[ 0 ][ 2 ] = w.x;
view_matrix[ 1 ][ 2 ] = w.y;
view_matrix[ 2 ][ 2 ] = w.z;
view_matrix[ 3 ][ 0 ] = -glm::dot( u, position );
view_matrix[ 3 ][ 1 ] = -glm::dot( v, position );
view_matrix[ 3 ][ 2 ] = -glm::dot( w, position );
inverse_view_matrix = glm::mat4 { 1.0f };
inverse_view_matrix[ 0 ][ 0 ] = u.x;
inverse_view_matrix[ 0 ][ 1 ] = u.y;
inverse_view_matrix[ 0 ][ 2 ] = u.z;
inverse_view_matrix[ 1 ][ 0 ] = v.x;
inverse_view_matrix[ 1 ][ 1 ] = v.y;
inverse_view_matrix[ 1 ][ 2 ] = v.z;
inverse_view_matrix[ 2 ][ 0 ] = w.x;
inverse_view_matrix[ 2 ][ 1 ] = w.y;
inverse_view_matrix[ 2 ][ 2 ] = w.z;
inverse_view_matrix[ 3 ][ 0 ] = position.x;
inverse_view_matrix[ 3 ][ 1 ] = position.y;
inverse_view_matrix[ 3 ][ 2 ] = position.z;
}
void Camera::setViewTarget( glm::vec3 position, glm::vec3 target, glm::vec3 up )
{
setViewDirection( position, target - position, up );
}
void Camera::setViewYXZ( glm::vec3 position, glm::vec3 rotation )
{
const float c3 { glm::cos( rotation.z ) };
const float s3 { glm::sin( rotation.z ) };
const float c2 { glm::cos( rotation.x ) };
const float s2 { glm::sin( rotation.x ) };
const float c1 { glm::cos( rotation.y ) };
const float s1 { glm::sin( rotation.y ) };
const glm::vec3 u { ( c1 * c3 + s1 * s2 * s3 ), ( c2 * s3 ), ( c1 * s2 * s3 - c3 * s1 ) };
const glm::vec3 v { ( c3 * s1 * s2 - c1 * s3 ), ( c2 * c3 ), ( c1 * c3 * s2 + s1 * s3 ) };
const glm::vec3 w { ( c2 * s1 ), ( -s2 ), ( c1 * c2 ) };
view_matrix = glm::mat4 { 1.0f };
view_matrix[ 0 ][ 0 ] = u.x;
view_matrix[ 1 ][ 0 ] = u.y;
view_matrix[ 2 ][ 0 ] = u.z;
view_matrix[ 0 ][ 1 ] = v.x;
view_matrix[ 1 ][ 1 ] = v.y;
view_matrix[ 2 ][ 1 ] = v.z;
view_matrix[ 0 ][ 2 ] = w.x;
view_matrix[ 1 ][ 2 ] = w.y;
view_matrix[ 2 ][ 2 ] = w.z;
view_matrix[ 3 ][ 0 ] = -glm::dot( u, position );
view_matrix[ 3 ][ 1 ] = -glm::dot( v, position );
view_matrix[ 3 ][ 2 ] = -glm::dot( w, position );
inverse_view_matrix = glm::mat4 { 1.0f };
inverse_view_matrix[ 0 ][ 0 ] = u.x;
inverse_view_matrix[ 0 ][ 1 ] = u.y;
inverse_view_matrix[ 0 ][ 2 ] = u.z;
inverse_view_matrix[ 1 ][ 0 ] = v.x;
inverse_view_matrix[ 1 ][ 1 ] = v.y;
inverse_view_matrix[ 1 ][ 2 ] = v.z;
inverse_view_matrix[ 2 ][ 0 ] = w.x;
inverse_view_matrix[ 2 ][ 1 ] = w.y;
inverse_view_matrix[ 2 ][ 2 ] = w.z;
inverse_view_matrix[ 3 ][ 0 ] = position.x;
inverse_view_matrix[ 3 ][ 1 ] = position.y;
inverse_view_matrix[ 3 ][ 2 ] = position.z;
}
} // namespace fgl::engine