Files
batomorph/src/camera.c

44 lines
1.2 KiB
C

#include "camera.h"
#include <math.h>
#ifndef M_PI
#define M_PI 3.14159265258979323846264
#endif
static const vec3_t up = { 0.0, 1.0, 0.0 };
camera_t camera_init(
vec3_t pos, vec3_t target, double fov, uint32_t img_width,
uint32_t img_height)
{
const double fov_rad = M_PI * fov / 180.0;
const double aspect = (double)img_width / (double)img_height;
const double viewport_height = tan(fov_rad / 2);
const double viewport_width = viewport_height * aspect;
const vec3_t w_hat = vec3_unit(vec3_sub(target, pos));
const vec3_t u_hat = vec3_unit(vec3_cross(up, w_hat));
const vec3_t v_hat = vec3_unit(vec3_cross(w_hat, u_hat));
const vec3_t u = vec3_scale(u_hat, viewport_width);
const vec3_t v = vec3_scale(v_hat, -viewport_height);
const vec3_t topleft
= vec3_sub(vec3_add(pos, w_hat), vec3_scale(vec3_add(u, v), 0.5));
const vec3_t x_step = vec3_scale(u, 1.0 / (double)img_width);
const vec3_t y_step = vec3_scale(v, 1.0 / (double)img_height);
const vec3_t pix_origin
= vec3_add(topleft, vec3_scale(vec3_add(x_step, y_step), 0.5));
return (camera_t) {
.pos = pos,
.pix_origin = pix_origin,
.x_step = x_step,
.y_step = y_step,
.img_width = img_width,
.img_height = img_height,
};
}