8 changed files with 223 additions and 84 deletions
@ -0,0 +1,70 @@ |
|||
// Copyright 2022 Simon Boyé
|
|||
|
|||
#include <Camera.h> |
|||
|
|||
|
|||
Camera::Camera() noexcept |
|||
: m_left(-1) |
|||
, m_right(1) |
|||
, m_top(-1) |
|||
, m_bottom(1) |
|||
, m_near(0.1) |
|||
, m_far(100) |
|||
, m_position(Vector3::Zero()) |
|||
, m_direction(Vector3::UnitZ()) |
|||
, m_down(Vector3::UnitY()) |
|||
{} |
|||
|
|||
Camera::~Camera() = default; |
|||
|
|||
|
|||
void Camera::set_projection(Real h_fov, Real width_height_ratio) noexcept { |
|||
const Real hx = std::tan(h_fov / Real(2)); |
|||
const Real hy = hx / width_height_ratio; |
|||
set_projection( |
|||
-hx, hx, |
|||
-hy, hy |
|||
); |
|||
} |
|||
|
|||
void Camera::update_aspect_ratio(Real width_height_ratio) noexcept { |
|||
const Real prev_ratio = (m_right - m_left) / (m_bottom - m_top); |
|||
const Real next_ratio = width_height_ratio; |
|||
|
|||
const Real sx = (Real(1) + Real(1) / prev_ratio) / (Real(1) + Real(1) / next_ratio); |
|||
const Real sy = (Real(1) + prev_ratio) / (Real(1) + next_ratio); |
|||
|
|||
m_left *= sx; |
|||
m_right *= sx; |
|||
m_top *= sy; |
|||
m_bottom *= sy; |
|||
} |
|||
|
|||
|
|||
Matrix3 Camera::basis() const noexcept { |
|||
Matrix3 basis; |
|||
basis << m_down.cross(m_direction), m_down, m_direction; |
|||
return basis; |
|||
} |
|||
|
|||
Matrix4 Camera::view_matrix() const noexcept { |
|||
Matrix3 linear_view; |
|||
linear_view << |
|||
m_down.cross(m_direction).transpose(), |
|||
m_down.transpose(), |
|||
m_direction.transpose(); |
|||
Matrix4 view; |
|||
view << linear_view, linear_view * -m_position, |
|||
Vector4::UnitW().transpose(); |
|||
return view; |
|||
} |
|||
|
|||
Matrix4 Camera::projection_matrix() const noexcept { |
|||
return ::projection_matrix( |
|||
m_near * m_left, m_near * m_right, |
|||
m_near * m_top, m_near * m_bottom, |
|||
m_near, m_far |
|||
); |
|||
} |
|||
|
|||
|
|||
@ -0,0 +1,92 @@ |
|||
// Copyright 2022 Simon Boyé
|
|||
#pragma once |
|||
|
|||
#include <core/math.h> |
|||
|
|||
|
|||
class Camera { |
|||
public: |
|||
Camera() noexcept; |
|||
~Camera(); |
|||
|
|||
inline Real left() const noexcept { |
|||
return m_left; |
|||
} |
|||
|
|||
inline Real right() const noexcept { |
|||
return m_right; |
|||
} |
|||
|
|||
inline Real top() const noexcept { |
|||
return m_top; |
|||
} |
|||
|
|||
inline Real bottom() const noexcept { |
|||
return m_bottom; |
|||
} |
|||
|
|||
void set_projection(Real left, Real right, Real top, Real bottom) noexcept { |
|||
m_left = left; |
|||
m_right = right; |
|||
m_top = top; |
|||
m_bottom = bottom; |
|||
} |
|||
void set_projection(Real h_fov, Real width_height_ratio) noexcept; |
|||
void update_aspect_ratio(Real width_height_ratio) noexcept; |
|||
|
|||
|
|||
inline Real near() const noexcept { |
|||
return m_near; |
|||
} |
|||
|
|||
inline Real far() const noexcept { |
|||
return m_far; |
|||
} |
|||
|
|||
void set_clip_distances(Real near, Real far) noexcept { |
|||
m_near = near; |
|||
m_far = far; |
|||
} |
|||
|
|||
|
|||
inline Vector3 position() const noexcept { |
|||
return m_position; |
|||
} |
|||
|
|||
inline void set_position(const Vector3& position) noexcept { |
|||
m_position = position; |
|||
} |
|||
|
|||
inline Vector3 direction() const noexcept { |
|||
return m_direction; |
|||
} |
|||
|
|||
inline void set_direction(const Vector3& direction) noexcept { |
|||
m_direction = direction; |
|||
} |
|||
|
|||
inline Vector3 down() const noexcept { |
|||
return m_down; |
|||
} |
|||
|
|||
inline void set_down(const Vector3& down) noexcept { |
|||
m_down = down; |
|||
} |
|||
|
|||
Matrix3 basis() const noexcept; |
|||
Matrix4 view_matrix() const noexcept; |
|||
Matrix4 projection_matrix() const noexcept; |
|||
|
|||
private: |
|||
Real m_left; |
|||
Real m_right; |
|||
Real m_top; |
|||
Real m_bottom; |
|||
|
|||
Real m_near; |
|||
Real m_far; |
|||
|
|||
Vector3 m_position; |
|||
Vector3 m_direction; |
|||
Vector3 m_down; |
|||
}; |
|||
Loading…
Reference in new issue