3#include <glm/gtc/matrix_transform.hpp>
27static_assert(
sizeof(ViewTransform) == 128,
28 "ViewTransform must be exactly 128 bytes (Vulkan minimum push constant size)");
40static_assert(
sizeof(RenderTransform) == 3 *
sizeof(glm::mat4));
51 const glm::vec3& target,
52 const glm::vec3& up = glm::vec3(0.0F, 1.0F, 0.0F))
54 return { .
view = glm::lookAt(eye, target, up) };
71 return { .
projection = glm::perspective(fov_radians, aspect, near, far) };
85 float left,
float right,
86 float bottom,
float top,
87 float near = -1.0F,
float far = 1.0F)
89 return { .
projection = glm::ortho(left, right, bottom, top, near, far) };
104 const glm::vec3& eye,
105 const glm::vec3& target,
110 const glm::vec3& up = glm::vec3(0.0F, 1.0F, 0.0F))
113 .
view = glm::lookAt(eye, target, up),
114 .projection = glm::perspective(fov_radians, aspect, near, far)
127 double window_x,
double window_y,
131 (
static_cast<float>(window_x) /
static_cast<float>(
width)) * 2.0F - 1.0F,
132 1.0F - (
static_cast<float>(window_y) /
static_cast<float>(
height)) * 2.0F,
144 double window_x,
double window_y,
147 const float aspect =
static_cast<float>(
width) /
static_cast<float>(
height);
148 float x = (
static_cast<float>(window_x) /
static_cast<float>(
width)) * 2.0F - 1.0F;
149 float y = 1.0F - (
static_cast<float>(window_y) /
static_cast<float>(
height)) * 2.0F;
150 if (aspect >= 1.0F) {
155 return { x, y, 0.0F };
166 const glm::vec3& ndc,
170 (ndc.x + 1.0F) * 0.5F *
static_cast<float>(
width),
171 (1.0F - ndc.y) * 0.5F *
static_cast<float>(
height)
180 return static_cast<float>(
width) /
static_cast<float>(
height);
187 double window_x,
double window_y,
190 return window_x >= 0.0
191 && window_x < static_cast<double>(
width)
193 && window_y < static_cast<double>(
height);
214 const glm::vec2& ndc_size,
217 const auto px =
static_cast<uint32_t
>(ndc_size.x * 0.5F *
static_cast<float>(
width));
218 const auto py =
static_cast<uint32_t
>(ndc_size.y * 0.5F *
static_cast<float>(
height));
219 return { std::max(
px, 1U), std::max(
py, 1U) };
ViewTransform look_at(const glm::vec3 &eye, const glm::vec3 &target, const glm::vec3 &up=glm::vec3(0.0F, 1.0F, 0.0F))
Construct view matrix from eye position, target, and up vector.
glm::vec2 to_window(const glm::vec3 &ndc, uint32_t width, uint32_t height)
Convert NDC to window pixel coordinates.
ViewTransform look_at_perspective(const glm::vec3 &eye, const glm::vec3 &target, float fov_radians, float aspect, float near, float far, const glm::vec3 &up=glm::vec3(0.0F, 1.0F, 0.0F))
Construct complete ViewTransform from look-at and perspective parameters.
float aspect_ratio(uint32_t width, uint32_t height)
Aspect ratio from pixel dimensions.
ViewTransform ortho(float left, float right, float bottom, float top, float near=-1.0F, float far=1.0F)
Construct orthographic projection matrix.
glm::uvec2 ndc_size_to_pixels(const AABB2D ®ion, uint32_t width, uint32_t height)
Convert an NDC AABB's extent to integer pixel dimensions.
bool in_bounds(double window_x, double window_y, uint32_t width, uint32_t height)
Check if a window-space point is within bounds.
glm::vec3 to_ndc(double window_x, double window_y, uint32_t width, uint32_t height)
Convert window pixel coordinates to NDC.
glm::vec3 to_ndc_aspect(double window_x, double window_y, uint32_t width, uint32_t height)
Convert window pixel coordinates to NDC, corrected for aspect ratio.
ViewTransform perspective(float fov_radians, float aspect, float near, float far)
Construct perspective projection matrix.