#include "camera.h" #include // IWYU pragma: keep #include #include Camera::Camera(glm::vec3 pos, float fov, float aspect, float zNear, float zFar) : position {pos}, forward {::north}, up {::up}, fov {fov}, aspect {aspect}, near {zNear}, far {zFar}, projection {glm::perspective(fov, aspect, zNear, zFar)} { updateView(); } Ray Camera::unProject(const glm::vec2 & mouse) const { static constexpr const glm::vec4 screen {0, 0, 1, 1}; return {position, glm::normalize(glm::unProject(mouse ^ 1, unView, projection, screen))}; } void Camera::updateView() { view = glm::lookAt(position, position + forward, up); unView = glm::lookAt(::origin, forward, up); viewProjection = projection * view; inverseViewProjection = glm::inverse(viewProjection); } glm::vec3 Camera::upFromForward(const glm::vec3 & forward) { const auto right = glm::cross(forward, ::down); return glm::cross(forward, right); } std::array Camera::extentsAtDist(const float dist) const { const auto depth = -(2.f * (dist - near) * far) / (dist * (near - far)) - 1.f; static constexpr const std::array extents {-1.F, 1.F}; std::array out {}; auto outitr = out.begin(); for (auto x : extents) { for (auto y : extents) { const glm::vec4 in {x, y, depth, 1.f}; const auto out = inverseViewProjection * in; *outitr++ = out / out.w; } } return out; }