#include "camera.h" #include #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, }; }