44 lines
1.2 KiB
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,
|
|
};
|
|
}
|