project-aster/samples/04_scenes/camera.h

99 lines
2.5 KiB
C++

// =============================================
// Aster: camera.h
// Copyright (c) 2020-2024 Anish Bhobe
// =============================================
#include "aster/aster.h"
struct Camera
{
mat4 m_View;
mat4 m_Perspective;
mat4 m_InverseView;
mat4 m_InversePerspective;
vec3 m_Position;
f32 m_PositionHomogenousPad_ = 1.0f;
void
CalculateInverses()
{
m_InverseView = inverse(m_View);
m_InversePerspective = inverse(m_Perspective);
}
};
struct CameraController
{
constexpr static vec3 UP = vec3(0.0f, 1.0f, 0.0f);
f32 m_Fov;
f32 m_Pitch;
f32 m_Yaw;
f32 m_AspectRatio;
Camera m_Camera;
CameraController(const vec3 &position, const vec3 &target, const f32 vFov, const f32 aspectRatio)
: m_Fov(vFov)
, m_Pitch{0.0f}
, m_Yaw{0.0f}
, m_AspectRatio{aspectRatio}
, m_Camera{
.m_View = lookAt(position, target, UP),
.m_Perspective = glm::perspective(vFov, aspectRatio, 0.1f, 100.0f),
.m_Position = position,
}
{
const vec3 dir = normalize(target - vec3(position));
m_Pitch = asin(dir.y);
m_Yaw = acos(-dir.z / sqrt(1.0f - dir.y * dir.y));
m_Camera.CalculateInverses();
}
void
SetAspectRatio(const f32 aspectRatio)
{
m_AspectRatio = aspectRatio;
m_Camera.m_Perspective = glm::perspective(m_Fov, aspectRatio, 0.1f, 100.0f);
m_Camera.CalculateInverses();
}
void
SetPosition(const vec3 &position)
{
m_Camera.m_Position = vec4(position, 1.0f);
f32 cosPitch = cos(m_Pitch);
const vec3 target = vec3(sin(m_Yaw) * cosPitch, sin(m_Pitch), -cos(m_Yaw) * cosPitch);
m_Camera.m_View = lookAt(position, position + target, UP);
m_Camera.CalculateInverses();
}
void
SetPitchYaw(f32 pitch, f32 yaw)
{
m_Pitch = pitch;
m_Yaw = yaw;
f32 cosPitch = cos(m_Pitch);
const vec3 target = vec3(sin(m_Yaw) * cosPitch, sin(m_Pitch), -cos(m_Yaw) * cosPitch);
const vec3 position = m_Camera.m_Position;
m_Camera.m_View = lookAt(position, position + target, UP);
m_Camera.CalculateInverses();
}
void
SetLookAt(const vec3 &target)
{
const vec3 dir = normalize(target - m_Camera.m_Position);
m_Pitch = acos(dir.y);
m_Yaw = acos(dir.z / sqrt(1.0f - dir.y * dir.y));
m_Camera.m_View = lookAt(m_Camera.m_Position, m_Camera.m_Position + target, UP);
m_Camera.CalculateInverses();
}
};