Files
LivePlotter/src/camera.cpp

50 lines
1.6 KiB
C++

#include "camera.hpp"
#include <glm/ext/matrix_clip_space.hpp>
#include <glm/ext/matrix_transform.hpp>
#include <glm/geometric.hpp>
#include <glm/trigonometric.hpp>
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)); }