From a7dda028aac232a3da7b555f7c2b3019cddd8843 Mon Sep 17 00:00:00 2001 From: Abdelrahman Date: Sun, 4 Feb 2024 19:49:54 +0000 Subject: [PATCH] Implement ability to move and rotate camera --- include/math/math_utils.h | 3 +++ include/vector/vec.h | 1 + src/raytracer/main.c | 16 ++++++++++--- src/vector/vec.c | 48 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 65 insertions(+), 3 deletions(-) diff --git a/include/math/math_utils.h b/include/math/math_utils.h index 4d34e5f..d00f19d 100644 --- a/include/math/math_utils.h +++ b/include/math/math_utils.h @@ -2,6 +2,9 @@ #define MATH_UTILS_H #include "c_cpp_aliases/aliases.h" +#include + +#define RADIANS(DEG) (DEG * (f32)M_PI / 180.0f) f32 clamp(f32 value, f32 min, f32 max); diff --git a/include/vector/vec.h b/include/vector/vec.h index f9a2e26..dfae2fe 100644 --- a/include/vector/vec.h +++ b/include/vector/vec.h @@ -69,5 +69,6 @@ vec3f_t vec_div_num_vec3f_t(vec3f_t v1, f32 num); f32 vec_dot_vec3f_t(vec3f_t v1, vec3f_t v2); f32 vec_magnitude_vec3f_t(vec3f_t v); vec3f_t vec_unit_vec3f_t(vec3f_t v); +vec3f_t vec_rotate_vec3f_t(vec3f_t original, vec3f_t rotation); #endif // !VEC_H diff --git a/src/raytracer/main.c b/src/raytracer/main.c index 0723064..81725eb 100644 --- a/src/raytracer/main.c +++ b/src/raytracer/main.c @@ -3,6 +3,7 @@ #include "vector/vec.h" #include "window/window.h" #include +#include #include #include #include @@ -10,10 +11,18 @@ #define ARR_LEN(ARR) sizeof(ARR) / sizeof(ARR[0]) #define RECURSION_DEPTH 3 +typedef struct { + vec3f_t position; + vec3f_t rotation; +} camera_t; + i32 main(i32 argc, char *argv[]) { colour_t bg = (colour_t){.rgba.r = 27, .rgba.g = 38, .rgba.b = 79, .rgba.a = 255}; - vec3f_t camera = {.x = 0.0f, .y = 0.0f, .z = 0.0f}; + camera_t camera = { + .position = {.x = 0.0f, .y = 0.0f, .z = 0.0f}, + .rotation = {.x = 0.0f, .y = 0.0f, .z = 0.0f}, + }; vec3f_t viewport = {.x = 1.0f, .y = 1.0f, .z = 1.0f}; window_t window = {0}; @@ -107,8 +116,9 @@ i32 main(i32 argc, char *argv[]) { for (i32 y = h_min; y < h_max; ++y) { for (i32 x = w_min; x < w_max; ++x) { vec3f_t direction = window_to_viewport(&window, x, y, viewport); - colour_t colour = trace_ray(camera, direction, 1, INFINITY, &scene, bg, - RECURSION_DEPTH); + vec3f_t rotated = vec_rotate_vec3f_t(direction, camera.rotation); + colour_t colour = trace_ray(camera.position, rotated, 1, INFINITY, + &scene, bg, RECURSION_DEPTH); set_pixel(&window, x, y, colour); } } diff --git a/src/vector/vec.c b/src/vector/vec.c index 8145339..04969e0 100644 --- a/src/vector/vec.c +++ b/src/vector/vec.c @@ -1,6 +1,13 @@ #include "vector/vec.h" +#include "math/math_utils.h" #include +typedef struct { + vec3f_t row0; + vec3f_t row1; + vec3f_t row2; +} mat3x3f_t; + vec2i_t vec_add_vec2i_t(vec2i_t v1, vec2i_t v2) { return (vec2i_t){.x = v1.x + v2.x, .y = v1.y + v2.y}; } @@ -136,3 +143,44 @@ vec3f_t vec_unit_vec3f_t(vec3f_t v) { f32 magnitude = vec_magnitude_vec3f_t(v); return (vec3f_t){v.x / magnitude, v.y / magnitude, v.z / magnitude}; } + +vec3f_t vec_rotate_vec3f_t(vec3f_t original, vec3f_t rotation) { + f32 x_rad = RADIANS(rotation.x); + f32 y_rad = RADIANS(rotation.y); + f32 z_rad = RADIANS(rotation.z); + + f32 cos_x = cosf(x_rad); + f32 sin_x = sinf(x_rad); + + f32 cos_y = cosf(y_rad); + f32 sin_y = sinf(y_rad); + + f32 cos_z = cosf(z_rad); + f32 sin_z = sinf(z_rad); + + f32 row0_col0 = cos_z * cos_y; + f32 row0_col1 = cos_z * sin_y * sin_x - sin_z * cos_x; + f32 row0_col2 = cos_z * sin_y * cos_x + sin_z * sin_x; + + f32 row1_col0 = sin_z * cos_y; + f32 row1_col1 = sin_z * sin_y * sin_x + cos_z * cos_x; + f32 row1_col2 = sin_z * sin_y * cos_x - cos_z * sin_x; + + f32 row2_col0 = -sin_y; + f32 row2_col1 = cos_y * sin_x; + f32 row2_col2 = cos_y * cos_x; + + mat3x3f_t matrix = { + .row0 = {row0_col0, row0_col1, row0_col2}, + .row1 = {row1_col0, row1_col1, row1_col2}, + .row2 = {row2_col0, row2_col1, row2_col2}, + }; + + // clang-format off + return (vec3f_t){ + .x = matrix.row0.x * original.x + matrix.row0.y * original.y + matrix.row0.z * original.z, + .y = matrix.row1.x * original.x + matrix.row1.y * original.y + matrix.row1.z * original.z, + .z = matrix.row2.x * original.x + matrix.row2.y * original.y + matrix.row2.z * original.z, + }; + // clang-format on +}