// ============================================= // 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(); } };