#include "camera.hpp" #include #include #include #include const float zoom_speed_scale = 30.0f; Viewport make_viewport(float win_w, float win_h, float fov_degrees = 45.0f) { return { .fov_degrees = fov_degrees, .width = win_w, .height = win_h }; } glm::mat4 camera_to_projection(Viewport &v) { return glm::infinitePerspective(glm::radians(v.fov_degrees), v.width / v.height, 0.1f); } Camera make_camera(glm::vec3 focus = glm::vec3(0, 0, 0), float distance = 1.0f) { return { .focus = focus, .theta = 0, .phi = 0, .distance = distance }; } void pan_camera(Camera& c, glm::vec2 dxdy) { dxdy.y *= -1; c.focus += camera_to_world(c) * glm::vec4(dxdy, 0, 0) * c.distance / 1000.0f; } void rotate_camera(Camera& c, glm::vec2 dxdy) { c.theta += dxdy.x / 100.0f; c.phi += dxdy.y / 100.0f; } void zoom_camera(Camera& c, float dz) { c.distance = std::max(0.0f, c.distance - (dz * zoom_speed_scale)); } glm::mat4 world_to_camera(Camera& c) { glm::mat4 world_to_focus = glm::translate(glm::mat4(1), c.focus); glm::mat4 rotation_theta = glm::rotate(glm::mat4(1), c.theta, {0, 1, 0}); glm::mat4 rotation_phi = glm::rotate(glm::mat4(1), c.phi, {1, 0, 0}); glm::mat4 rotated_focus_to_camera = glm::translate(glm::mat4(1), { 0, 0, -c.distance }); glm::mat4 res = rotated_focus_to_camera * rotation_phi * rotation_theta * world_to_focus; return res; } glm::mat4 camera_to_world(Camera& c) { return glm::inverse(world_to_camera(c)); }