faire la norme

This commit is contained in:
H3XploR
2025-02-17 23:52:47 +01:00
parent 960a2ad8ae
commit c6c13573cb
20 changed files with 539 additions and 440 deletions
+2 -2
View File
@@ -36,6 +36,6 @@ float vec3_dot(t_vec3 a, t_vec3 b)
t_vec3 vec3_cross(t_vec3 a, t_vec3 b) t_vec3 vec3_cross(t_vec3 a, t_vec3 b)
{ {
return ((t_vec3){a.y * b.z - a.z * b.y, \ return ((t_vec3){a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y
a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x}); - a.y * b.x});
} }
+1 -1
View File
@@ -17,7 +17,7 @@ int check_tokens(char **tokens, int expected)
return (tokens && ft_arraylen(tokens) == expected); return (tokens && ft_arraylen(tokens) == expected);
} }
void check_if_max(t_scene scene, const int to_test, const int max) void check_if_max(t_scene scene, const int to_test, const int max)
{ {
if (to_test >= max) if (to_test >= max)
{ {
+3 -3
View File
@@ -37,9 +37,9 @@ static inline t_scene parsing_line(char *line, t_scene scene)
// ----- Parsing du fichier de configuration ----- // ----- Parsing du fichier de configuration -----
t_scene load_config(const char *filename) t_scene load_config(const char *filename)
{ {
int fd; int fd;
char *line; char *line;
t_scene scene; t_scene scene;
scene = create_scene(); scene = create_scene();
fd = open(filename, O_RDONLY); fd = open(filename, O_RDONLY);
+5 -5
View File
@@ -14,7 +14,7 @@
static int init_app_config(t_app *app, int argc, char **argv) static int init_app_config(t_app *app, int argc, char **argv)
{ {
t_scene scene; t_scene scene;
if (argc > 1) if (argc > 1)
scene = load_config(argv[1]); scene = load_config(argv[1]);
@@ -32,8 +32,8 @@ static int init_mlx_and_image(t_app *app)
ft_putstr_fd("Erreur mlx_init\n", 2); ft_putstr_fd("Erreur mlx_init\n", 2);
return (1); return (1);
} }
app->win = mlx_new_window(app->mlx, app->win_width, app->win = mlx_new_window(app->mlx, app->win_width, app->win_height,
app->win_height, "Raytracer interactif"); "Raytracer interactif");
if (!app->win) if (!app->win)
{ {
ft_putstr_fd("Erreur mlx_new_window\n", 2); ft_putstr_fd("Erreur mlx_new_window\n", 2);
@@ -45,8 +45,8 @@ static int init_mlx_and_image(t_app *app)
ft_putstr_fd("Erreur mlx_new_image\n", 2); ft_putstr_fd("Erreur mlx_new_image\n", 2);
return (1); return (1);
} }
app->pixels = (int *)mlx_get_data_addr(app->img, &app->bpp, app->pixels = (int *)mlx_get_data_addr(app->img, &app->bpp, &app->size_line,
&app->size_line, &app->endian); &app->endian);
if (!app->pixels) if (!app->pixels)
{ {
ft_putstr_fd("Erreur mlx_get_data_addr\n", 2); ft_putstr_fd("Erreur mlx_get_data_addr\n", 2);
+96 -95
View File
@@ -13,16 +13,16 @@
#ifndef MINIRT_H #ifndef MINIRT_H
# define MINIRT_H # define MINIRT_H
# include "float.h"
# include "get_next_line.h"
# include "libft.h"
# include "mlx.h"
# include <fcntl.h>
# include <math.h> # include <math.h>
# include <stdbool.h> # include <stdbool.h>
# include <stdio.h> # include <stdio.h>
# include <stdlib.h> # include <stdlib.h>
# include <string.h> # include <string.h>
# include <fcntl.h>
# include "get_next_line.h"
# include "libft.h"
# include "float.h"
# include "mlx.h"
// ----- Taille ecran ---- // ----- Taille ecran ----
# define WIDTH 640 # define WIDTH 640
@@ -97,8 +97,8 @@ typedef struct s_camera
float rot_speed; float rot_speed;
float move_speed; float move_speed;
float fov; float fov;
float yaw;// vue de gauche a droite float yaw; // vue de gauche a droite
float pitch; // vue de haut en bas en radians float pitch; // vue de haut en bas en radians
} t_camera; } t_camera;
typedef struct s_scene typedef struct s_scene
@@ -115,75 +115,74 @@ typedef struct s_scene
int numCamera; int numCamera;
int numLights; int numLights;
int numAmbient; int numAmbient;
char *line_if_exit; char *line_if_exit;
char **token_if_exit; char **token_if_exit;
int fd_if_exit; int fd_if_exit;
} t_scene; } t_scene;
// ----- Minilibx // ----- Minilibx
typedef struct s_app typedef struct s_app
{ {
void *mlx; void *mlx;
void *win; void *win;
void *img; void *img;
int *pixels; int *pixels;
int bpp; int bpp;
int size_line; int size_line;
int endian; int endian;
int win_width; int win_width;
int win_height; int win_height;
int key_w; int key_w;
int key_s; int key_s;
int key_a; int key_a;
int key_d; int key_d;
int key_left; int key_left;
int key_right; int key_right;
int key_up; int key_up;
int key_down; int key_down;
float mouse_sens; float mouse_sens;
t_scene scene; t_scene scene;
} t_app; } t_app;
// ----- Calcul // ----- Calcul
typedef struct s_calc typedef struct s_calc
{ {
t_vec3 oc; t_vec3 oc;
float a; float a;
float b; float b;
float c; float c;
float disc; float disc;
float sqrtDisc; float sqrtDisc;
float t0; float t0;
float t1; float t1;
float t; float t;
t_vec3 hitPoint; t_vec3 hitPoint;
t_vec3 d; t_vec3 d;
t_vec3 v; t_vec3 v;
float d_dot_v; float d_dot_v;
float oc_dot_v; float oc_dot_v;
t_vec3 d_perp; t_vec3 d_perp;
t_vec3 oc_perp; t_vec3 oc_perp;
float t_side; float t_side;
float y; float y;
float t_cap; float t_cap;
float t_bot; float t_bot;
float t_top; float t_top;
t_vec3 p; t_vec3 p;
t_vec3 cp; t_vec3 cp;
float dist; float dist;
float t_final; float t_final;
float proj; float proj;
t_vec3 n; t_vec3 n;
float ndc_x; float ndc_x;
float ndc_y; float ndc_y;
float aspect; float aspect;
float scale; float scale;
float screen_x; float screen_x;
float screen_y; float screen_y;
t_ray ray; t_ray ray;
t_vec3 ray_dir; t_vec3 ray_dir;
t_vec3 color; t_vec3 color;
} t_calc; } t_calc;
// Calcul de vecteur // Calcul de vecteur
@@ -209,49 +208,51 @@ t_vec3 parse_color(const char *token, t_scene scene);
t_vec3 parse_vector(const char *token, t_scene scene); t_vec3 parse_vector(const char *token, t_scene scene);
t_vec3 parse_vector_normalize(const char *token, t_scene scene); t_vec3 parse_vector_normalize(const char *token, t_scene scene);
// Parsing utils // Parsing utils
char **get_tokens_secure(t_scene scene, const int numObject, const int numObjectMax, const int supposed_nb_token); char **get_tokens_secure(t_scene scene, const int numObject,
const int numObjectMax, const int supposed_nb_token);
// Check // Check
int check_tokens(char **tokens, int expected); int check_tokens(char **tokens, int expected);
void check_if_max(t_scene scene, const int to_test, const int max); void check_if_max(t_scene scene, const int to_test, const int max);
// Intersection // Intersection
float intersectCylinder(t_ray ray, t_cylinder cy, t_vec3 *hitNormal); float intersectCylinder(t_ray ray, t_cylinder cy, t_vec3 *hitNormal);
float intersectPlane(t_ray ray, t_plane p, t_vec3 *hitNormal); float intersectPlane(t_ray ray, t_plane p, t_vec3 *hitNormal);
float intersectSphere(t_ray ray, t_sphere s, t_vec3 *hitNormal); float intersectSphere(t_ray ray, t_sphere s, t_vec3 *hitNormal);
bool isInShadow(t_vec3 hitPoint, t_vec3 lightPos, t_scene scene); bool isInShadow(t_vec3 hitPoint, t_vec3 lightPos, t_scene scene);
bool intersectObjects(t_ray ray, float *tMin, t_vec3 *hitNormal, t_vec3 *objColor, t_scene scene); bool intersectObjects(t_ray ray, float *tMin, t_vec3 *hitNormal,
t_vec3 calcLighting(t_vec3 hitPoint, t_vec3 hitNormal, t_vec3 objColor, t_scene scene); t_vec3 *objColor, t_scene scene);
t_vec3 trace(t_ray ray, t_scene scene); t_vec3 calcLighting(t_vec3 hitPoint, t_vec3 hitNormal, t_vec3 objColor,
t_scene scene);
t_vec3 trace(t_ray ray, t_scene scene);
// Peripherique // Peripherique
int key_press(int keycode, t_app *app); int key_press(int keycode, t_app *app);
int key_release(int keycode, t_app *app); int key_release(int keycode, t_app *app);
int mouse_move(int x, int y, t_app *app); int mouse_move(int x, int y, t_app *app);
// Render // Render
void update_camera(t_app *app); void update_camera(t_app *app);
void render_scene(t_app *app); void render_scene(t_app *app);
int update_frame(t_app *app); int update_frame(t_app *app);
// Array // Array
int ft_arraylen(char **array); int ft_arraylen(char **array);
void ft_free_array(char **array); void ft_free_array(char **array);
// Conversion // Conversion
float ft_atof(char *str); float ft_atof(char *str);
// Info // Info
void print_vec3(t_vec3 vec); void print_vec3(t_vec3 vec);
void print_ray(t_ray ray); void print_ray(t_ray ray);
void print_sphere(t_sphere sphere); void print_sphere(t_sphere sphere);
void print_plane(t_plane plane); void print_plane(t_plane plane);
void print_cylinder(t_cylinder cyl); void print_cylinder(t_cylinder cyl);
void print_light(t_light light); void print_light(t_light light);
void print_ambient(t_ambient amb); void print_ambient(t_ambient amb);
void print_camera(t_camera cam); void print_camera(t_camera cam);
void print_scene(t_scene scene); void print_scene(t_scene scene);
#endif #endif
+1 -2
View File
@@ -12,10 +12,9 @@
#include "miniRT.h" #include "miniRT.h"
t_scene parsing_ambiant(t_scene scene) t_scene parsing_ambiant(t_scene scene)
{ {
char **tokens; char **tokens;
tokens = get_tokens_secure(scene, scene.numAmbient, MAX_AMBIENT, 3); tokens = get_tokens_secure(scene, scene.numAmbient, MAX_AMBIENT, 3);
scene.token_if_exit = tokens; scene.token_if_exit = tokens;
+2 -2
View File
@@ -12,9 +12,9 @@
#include "miniRT.h" #include "miniRT.h"
t_scene parsing_camera(t_scene scene) t_scene parsing_camera(t_scene scene)
{ {
char **tokens; char **tokens;
tokens = get_tokens_secure(scene, scene.numCamera, MAX_CAMERA, 4); tokens = get_tokens_secure(scene, scene.numCamera, MAX_CAMERA, 4);
scene.token_if_exit = tokens; scene.token_if_exit = tokens;
+1 -1
View File
@@ -29,7 +29,7 @@ static inline int range_is_ok(char **token_color)
t_vec3 parse_color(const char *token, t_scene scene) t_vec3 parse_color(const char *token, t_scene scene)
{ {
char **token_color; char **token_color;
t_vec3 color; t_vec3 color;
token_color = ft_split(token, ','); token_color = ft_split(token, ',');
if (!check_tokens(token_color, 3) || !range_is_ok(token_color)) if (!check_tokens(token_color, 3) || !range_is_ok(token_color))
+11 -11
View File
@@ -15,7 +15,8 @@
/* /*
float intersectCylinder(Ray ray, Cylinder cy, t_vec3 *hitNormal) float intersectCylinder(Ray ray, Cylinder cy, t_vec3 *hitNormal)
{ {
t_calc calc; t_calc calc;
char **tokens;
calc.d = ray.dir; calc.d = ray.dir;
calc.oc = vec3_sub(ray.origin, cy.center); calc.oc = vec3_sub(ray.origin, cy.center);
@@ -54,7 +55,8 @@ float intersectCylinder(Ray ray, Cylinder cy, t_vec3 *hitNormal)
{ {
p = vec3_add(ray.origin, vec3_scale(calc.d, calc.t_bot)); p = vec3_add(ray.origin, vec3_scale(calc.d, calc.t_bot));
cp = vec3_sub(p, cy.center); cp = vec3_sub(p, cy.center);
calc.dist = vec3_length(vec3_sub(cp, vec3_scale(calc.v, vec3_dot(cp, calc.v)))); calc.dist = vec3_length(vec3_sub(cp, vec3_scale(calc.v, vec3_dot(cp,
calc.v))));
if (calc.dist <= cy.radius) if (calc.dist <= cy.radius)
calc.t_cap = calc.t_bot; calc.t_cap = calc.t_bot;
} }
@@ -63,8 +65,10 @@ float intersectCylinder(Ray ray, Cylinder cy, t_vec3 *hitNormal)
{ {
p = vec3_add(ray.origin, vec3_scale(calc.d, t_top)); p = vec3_add(ray.origin, vec3_scale(calc.d, t_top));
cp = vec3_sub(p, cy.center); cp = vec3_sub(p, cy.center);
calc.dist = vec3_length(vec3_sub(cp, vec3_scale(calc.v, vec3_dot(cp, calc.v)))); calc.dist = vec3_length(vec3_sub(cp, vec3_scale(calc.v, vec3_dot(cp,
if (calc.dist <= cy.radius && (calc.t_cap < 0 || t_top < calc.t_cap)) calc.v))));
if (calc.dist <= cy.radius && (calc.t_cap < 0
|| t_top < calc.t_cap))
calc.t_cap = t_top; calc.t_cap = t_top;
} }
} }
@@ -89,17 +93,15 @@ float intersectCylinder(Ray ray, Cylinder cy, t_vec3 *hitNormal)
{ {
*hitNormal = (calc.proj > 0) ? calc.v : vec3_scale(calc.v, -1); *hitNormal = (calc.proj > 0) ? calc.v : vec3_scale(calc.v, -1);
} }
return calc.t_final; return (calc.t_final);
}*/ }*/
t_scene parsing_cylindre(t_scene scene) t_scene parsing_cylindre(t_scene scene)
{ {
char **tokens;
tokens = get_tokens_secure(scene, scene.numCylinders, MAX_CYLINDERS, 6); tokens = get_tokens_secure(scene, scene.numCylinders, MAX_CYLINDERS, 6);
scene.token_if_exit = tokens; scene.token_if_exit = tokens;
scene.cylinders[scene.numCylinders].center = parse_vector(tokens[1], scene); scene.cylinders[scene.numCylinders].center = parse_vector(tokens[1], scene);
scene.cylinders[scene.numCylinders].axis = parse_vector_normalize(tokens[2], scene); scene.cylinders[scene.numCylinders].axis = parse_vector_normalize(tokens[2],
scene);
scene.cylinders[scene.numCylinders].radius = ft_atof(tokens[3]); scene.cylinders[scene.numCylinders].radius = ft_atof(tokens[3]);
scene.cylinders[scene.numCylinders].height = ft_atof(tokens[4]); scene.cylinders[scene.numCylinders].height = ft_atof(tokens[4]);
scene.cylinders[scene.numCylinders].color = parse_color(tokens[5], scene); scene.cylinders[scene.numCylinders].color = parse_color(tokens[5], scene);
@@ -107,5 +109,3 @@ t_scene parsing_cylindre(t_scene scene)
scene.numCylinders++; scene.numCylinders++;
return (scene); return (scene);
} }
+97 -80
View File
@@ -13,99 +13,116 @@
#include "miniRT.h" #include "miniRT.h"
// Initialise les variables de calcul et les coefficients du polynôme d'intersection // Initialise les variables de calcul et les coefficients du polynôme d'intersection
static int init_intersection(t_ray ray, t_cylinder cy, t_calc *calc) { static int init_intersection(t_ray ray, t_cylinder cy, t_calc *calc)
calc->d = ray.dir; {
calc->oc = vec3_sub(ray.origin, cy.center); calc->d = ray.dir;
calc->v = cy.axis; calc->oc = vec3_sub(ray.origin, cy.center);
calc->d_dot_v = vec3_dot(calc->d, calc->v); calc->v = cy.axis;
calc->oc_dot_v = vec3_dot(calc->oc, calc->v); calc->d_dot_v = vec3_dot(calc->d, calc->v);
calc->d_perp = vec3_sub(calc->d, vec3_scale(calc->v, calc->d_dot_v)); calc->oc_dot_v = vec3_dot(calc->oc, calc->v);
calc->oc_perp = vec3_sub(calc->oc, vec3_scale(calc->v, calc->oc_dot_v)); calc->d_perp = vec3_sub(calc->d, vec3_scale(calc->v, calc->d_dot_v));
calc->a = vec3_dot(calc->d_perp, calc->d_perp); calc->oc_perp = vec3_sub(calc->oc, vec3_scale(calc->v, calc->oc_dot_v));
calc->b = 2 * vec3_dot(calc->d_perp, calc->oc_perp); calc->a = vec3_dot(calc->d_perp, calc->d_perp);
calc->c = vec3_dot(calc->oc_perp, calc->oc_perp) - cy.radius * cy.radius; calc->b = 2 * vec3_dot(calc->d_perp, calc->oc_perp);
calc->disc = calc->b * calc->b - 4 * calc->a * calc->c; calc->c = vec3_dot(calc->oc_perp, calc->oc_perp) - cy.radius * cy.radius;
if (calc->disc < 0) calc->disc = calc->b * calc->b - 4 * calc->a * calc->c;
return -1; if (calc->disc < 0)
calc->sqrtDisc = sqrtf(calc->disc); return (-1);
calc->t0 = (-calc->b - calc->sqrtDisc) / (2 * calc->a); calc->sqrtDisc = sqrtf(calc->disc);
calc->t1 = (-calc->b + calc->sqrtDisc) / (2 * calc->a); calc->t0 = (-calc->b - calc->sqrtDisc) / (2 * calc->a);
return 0; calc->t1 = (-calc->b + calc->sqrtDisc) / (2 * calc->a);
return (0);
} }
// Calcule l'intersection sur la surface latérale du cylindre // Calcule l'intersection sur la surface latérale du cylindre
static void compute_side_intersection(t_cylinder cy, t_calc *calc) { static void compute_side_intersection(t_cylinder cy, t_calc *calc)
calc->t_side = -1; {
if (calc->t0 > 1e-3f) { calc->t_side = -1;
calc->y = calc->oc_dot_v + calc->t0 * calc->d_dot_v; if (calc->t0 > 1e-3f)
if (fabs(calc->y) <= cy.height / 2.0f) {
calc->t_side = calc->t0; calc->y = calc->oc_dot_v + calc->t0 * calc->d_dot_v;
} if (fabs(calc->y) <= cy.height / 2.0f)
if (calc->t_side < 0 && calc->t1 > 1e-3f) { calc->t_side = calc->t0;
calc->y = calc->oc_dot_v + calc->t1 * calc->d_dot_v; }
if (fabs(calc->y) <= cy.height / 2.0f) if (calc->t_side < 0 && calc->t1 > 1e-3f)
calc->t_side = calc->t1; {
} calc->y = calc->oc_dot_v + calc->t1 * calc->d_dot_v;
if (fabs(calc->y) <= cy.height / 2.0f)
calc->t_side = calc->t1;
}
} }
// Calcule l'intersection sur les capuchons supérieur et inférieur // Calcule l'intersection sur les capuchons supérieur et inférieur
static void compute_cap_intersection(t_ray ray, t_cylinder cy, t_calc *calc) { static void compute_cap_intersection(t_ray ray, t_cylinder cy, t_calc *calc)
calc->t_cap = -1; {
if (fabs(calc->d_dot_v) > 1e-6f) { calc->t_cap = -1;
calc->t_bot = ((-cy.height / 2.0f) - calc->oc_dot_v) / calc->d_dot_v; if (fabs(calc->d_dot_v) > 1e-6f)
if (calc->t_bot > 1e-3f) { {
calc->p = vec3_add(ray.origin, vec3_scale(calc->d, calc->t_bot)); calc->t_bot = ((-cy.height / 2.0f) - calc->oc_dot_v) / calc->d_dot_v;
calc->cp = vec3_sub(calc->p, cy.center); if (calc->t_bot > 1e-3f)
calc->dist = vec3_length(vec3_sub(calc->cp, vec3_scale(calc->v, vec3_dot(calc->cp, calc->v)))); {
if (calc->dist <= cy.radius) calc->p = vec3_add(ray.origin, vec3_scale(calc->d, calc->t_bot));
calc->t_cap = calc->t_bot; calc->cp = vec3_sub(calc->p, cy.center);
} calc->dist = vec3_length(vec3_sub(calc->cp, vec3_scale(calc->v,
calc->t_top = ((cy.height / 2.0f) - calc->oc_dot_v) / calc->d_dot_v; vec3_dot(calc->cp, calc->v))));
if (calc->t_top > 1e-3f) { if (calc->dist <= cy.radius)
calc->p = vec3_add(ray.origin, vec3_scale(calc->d, calc->t_top)); calc->t_cap = calc->t_bot;
calc->cp = vec3_sub(calc->p, cy.center); }
calc->dist = vec3_length(vec3_sub(calc->cp, vec3_scale(calc->v, vec3_dot(calc->cp, calc->v)))); calc->t_top = ((cy.height / 2.0f) - calc->oc_dot_v) / calc->d_dot_v;
if (calc->dist <= cy.radius && (calc->t_cap < 0 || calc->t_top < calc->t_cap)) if (calc->t_top > 1e-3f)
calc->t_cap = calc->t_top; {
} calc->p = vec3_add(ray.origin, vec3_scale(calc->d, calc->t_top));
} calc->cp = vec3_sub(calc->p, cy.center);
calc->dist = vec3_length(vec3_sub(calc->cp, vec3_scale(calc->v,
vec3_dot(calc->cp, calc->v))));
if (calc->dist <= cy.radius && (calc->t_cap < 0
|| calc->t_top < calc->t_cap))
calc->t_cap = calc->t_top;
}
}
} }
// Sélectionne l'intersection la plus proche entre la surface latérale et les capuchons // Sélectionne l'intersection la plus proche entre la surface latérale et les capuchons
static float select_final_intersection(t_calc *calc) { static float select_final_intersection(t_calc *calc)
if (calc->t_side > 1e-3f && calc->t_cap > 1e-3f) {
calc->t_final = (calc->t_side < calc->t_cap) ? calc->t_side : calc->t_cap; if (calc->t_side > 1e-3f && calc->t_cap > 1e-3f)
else if (calc->t_side > 1e-3f) calc->t_final = (calc->t_side < calc->t_cap) ? calc->t_side : calc->t_cap;
calc->t_final = calc->t_side; else if (calc->t_side > 1e-3f)
else calc->t_final = calc->t_side;
calc->t_final = calc->t_cap; else
return (calc->t_final > 1e-3f) ? calc->t_final : -1; calc->t_final = calc->t_cap;
return ((calc->t_final > 1e-3f) ? calc->t_final : -1);
} }
// Calcule la normale au point d'intersection // Calcule la normale au point d'intersection
static void compute_hit_normal(t_ray ray, t_cylinder cy, t_calc *calc, t_vec3 *hitNormal) { static void compute_hit_normal(t_ray ray, t_cylinder cy, t_calc *calc,
calc->hitPoint = vec3_add(ray.origin, vec3_scale(calc->d, calc->t_final)); t_vec3 *hitNormal)
calc->cp = vec3_sub(calc->hitPoint, cy.center); {
calc->proj = vec3_dot(calc->cp, calc->v); calc->hitPoint = vec3_add(ray.origin, vec3_scale(calc->d, calc->t_final));
if (fabs(calc->proj) < cy.height / 2.0f - 1e-3f) { calc->cp = vec3_sub(calc->hitPoint, cy.center);
calc->n = vec3_sub(calc->cp, vec3_scale(calc->v, calc->proj)); calc->proj = vec3_dot(calc->cp, calc->v);
*hitNormal = vec3_normalize(calc->n); if (fabs(calc->proj) < cy.height / 2.0f - 1e-3f)
} else { {
*hitNormal = (calc->proj > 0) ? calc->v : vec3_scale(calc->v, -1); calc->n = vec3_sub(calc->cp, vec3_scale(calc->v, calc->proj));
} *hitNormal = vec3_normalize(calc->n);
}
else
{
*hitNormal = (calc->proj > 0) ? calc->v : vec3_scale(calc->v, -1);
}
} }
// Fonction principale d'intersection du cylindre // Fonction principale d'intersection du cylindre
float intersectCylinder(t_ray ray, t_cylinder cy, t_vec3 *hitNormal) { float intersectCylinder(t_ray ray, t_cylinder cy, t_vec3 *hitNormal)
t_calc calc; {
if (init_intersection(ray, cy, &calc) < 0) t_calc calc;
return -1;
compute_side_intersection(cy, &calc); if (init_intersection(ray, cy, &calc) < 0)
compute_cap_intersection(ray, cy, &calc); return (-1);
if (select_final_intersection(&calc) < 0) compute_side_intersection(cy, &calc);
return -1; compute_cap_intersection(ray, cy, &calc);
compute_hit_normal(ray, cy, &calc, hitNormal); if (select_final_intersection(&calc) < 0)
return calc.t_final; return (-1);
compute_hit_normal(ray, cy, &calc, hitNormal);
return (calc.t_final);
} }
+2 -2
View File
@@ -19,7 +19,8 @@ t_scene parsing_plane(t_scene scene)
tokens = get_tokens_secure(scene, scene.numPlanes, MAX_PLANES, 4); tokens = get_tokens_secure(scene, scene.numPlanes, MAX_PLANES, 4);
scene.token_if_exit = tokens; scene.token_if_exit = tokens;
scene.planes[scene.numPlanes].point = parse_vector(tokens[1], scene); scene.planes[scene.numPlanes].point = parse_vector(tokens[1], scene);
scene.planes[scene.numPlanes].normal = parse_vector_normalize(tokens[2], scene); scene.planes[scene.numPlanes].normal = parse_vector_normalize(tokens[2],
scene);
scene.planes[scene.numPlanes].color = parse_color(tokens[3], scene); scene.planes[scene.numPlanes].color = parse_color(tokens[3], scene);
ft_free_array(tokens); ft_free_array(tokens);
scene.numPlanes++; scene.numPlanes++;
@@ -40,4 +41,3 @@ float intersectPlane(t_ray ray, t_plane p, t_vec3 *hitNormal)
*hitNormal = p.normal; *hitNormal = p.normal;
return (t); return (t);
} }
-1
View File
@@ -47,4 +47,3 @@ float intersectSphere(t_ray ray, t_sphere s, t_vec3 *hitNormal)
*hitNormal = vec3_normalize(vec3_sub(calc.hitPoint, s.center)); *hitNormal = vec3_normalize(vec3_sub(calc.hitPoint, s.center));
return (calc.t); return (calc.t);
} }
+3 -2
View File
@@ -12,12 +12,13 @@
#include "miniRT.h" #include "miniRT.h"
char **get_tokens_secure(t_scene scene, const int numObject, const int numObjectMax, const int supposed_nb_token) char **get_tokens_secure(t_scene scene, const int numObject,
const int numObjectMax, const int supposed_nb_token)
{ {
char **tokens; char **tokens;
check_if_max(scene, numObject, numObjectMax); check_if_max(scene, numObject, numObjectMax);
tokens = ft_split(scene.line_if_exit, ' '); tokens = ft_split(scene.line_if_exit, ' ');
if (!check_tokens(tokens, supposed_nb_token)) if (!check_tokens(tokens, supposed_nb_token))
{ {
ft_free_array(tokens); ft_free_array(tokens);
+3 -2
View File
@@ -19,7 +19,8 @@ static inline int range_is_ok(char **token_vector)
i = 0; i = 0;
while (i < 3) while (i < 3)
{ {
if (ft_atof(token_vector[i]) < -FLT_MAX || ft_atof(token_vector[i]) > FLT_MAX) if (ft_atof(token_vector[i]) < -FLT_MAX
|| ft_atof(token_vector[i]) > FLT_MAX)
return (0); return (0);
i++; i++;
} }
@@ -29,7 +30,7 @@ static inline int range_is_ok(char **token_vector)
t_vec3 parse_vector(const char *token, t_scene scene) t_vec3 parse_vector(const char *token, t_scene scene)
{ {
char **token_vector; char **token_vector;
t_vec3 vector; t_vec3 vector;
token_vector = ft_split(token, ','); token_vector = ft_split(token, ',');
if (!check_tokens(token_vector, 3) || !range_is_ok(token_vector)) if (!check_tokens(token_vector, 3) || !range_is_ok(token_vector))
-1
View File
@@ -77,4 +77,3 @@ int mouse_move(int x, int y, t_app *app)
last_y = y; last_y = y;
return (0); return (0);
} }
+116 -107
View File
@@ -12,128 +12,137 @@
#include "miniRT.h" #include "miniRT.h"
void print_vec3(t_vec3 vec) { void print_vec3(t_vec3 vec)
printf("(x: %.2f, y: %.2f, z: %.2f)", vec.x, vec.y, vec.z); {
printf("(x: %.2f, y: %.2f, z: %.2f)", vec.x, vec.y, vec.z);
} }
void print_ray(t_ray ray) { void print_ray(t_ray ray)
printf("Rayon d'origine : "); {
print_vec3(ray.origin); printf("Rayon d'origine : ");
printf("\nDirection : "); print_vec3(ray.origin);
print_vec3(ray.dir); printf("\nDirection : ");
printf("\n"); print_vec3(ray.dir);
printf("\n");
} }
void print_sphere(t_sphere sphere) { void print_sphere(t_sphere sphere)
printf("Centre : "); {
print_vec3(sphere.center); printf("Centre : ");
printf("\nRayon : %.2f", sphere.radius); print_vec3(sphere.center);
printf("\nCouleur : "); printf("\nRayon : %.2f", sphere.radius);
print_vec3(sphere.color); printf("\nCouleur : ");
printf("\n"); print_vec3(sphere.color);
printf("\n");
} }
void print_plane(t_plane plane) { void print_plane(t_plane plane)
printf("Point : "); {
print_vec3(plane.point); printf("Point : ");
printf("\nNormale : "); print_vec3(plane.point);
print_vec3(plane.normal); printf("\nNormale : ");
printf("\nCouleur : "); print_vec3(plane.normal);
print_vec3(plane.color); printf("\nCouleur : ");
printf("\n"); print_vec3(plane.color);
printf("\n");
} }
void print_cylinder(t_cylinder cyl) { void print_cylinder(t_cylinder cyl)
printf("Centre : "); {
print_vec3(cyl.center); printf("Centre : ");
printf("\nAxe : "); print_vec3(cyl.center);
print_vec3(cyl.axis); printf("\nAxe : ");
printf("\nRayon : %.2f", cyl.radius); print_vec3(cyl.axis);
printf("\nHauteur : %.2f", cyl.height); printf("\nRayon : %.2f", cyl.radius);
printf("\nCouleur : "); printf("\nHauteur : %.2f", cyl.height);
print_vec3(cyl.color); printf("\nCouleur : ");
printf("\n"); print_vec3(cyl.color);
printf("\n");
} }
void print_light(t_light light) { void print_light(t_light light)
printf("Position : "); {
print_vec3(light.pos); printf("Position : ");
printf("\nIntensité : %.2f", light.brightness); print_vec3(light.pos);
printf("\nCouleur : "); printf("\nIntensité : %.2f", light.brightness);
print_vec3(light.color); printf("\nCouleur : ");
printf("\n"); print_vec3(light.color);
printf("\n");
} }
void print_ambient(t_ambient amb) { void print_ambient(t_ambient amb)
printf("Ratio d'ambiance : %.2f\n", amb.ratio); {
printf("Couleur ambiante : "); printf("Ratio d'ambiance : %.2f\n", amb.ratio);
print_vec3(amb.color); printf("Couleur ambiante : ");
printf("\n"); print_vec3(amb.color);
printf("\n");
} }
void print_camera(t_camera cam) { void print_camera(t_camera cam)
printf("Position de la caméra : "); {
print_vec3(cam.camPos); printf("Position de la caméra : ");
printf("\nDirection : "); print_vec3(cam.camPos);
print_vec3(cam.camDir); printf("\nDirection : ");
printf("\nRight : "); print_vec3(cam.camDir);
print_vec3(cam.right); printf("\nRight : ");
printf("\nUp : "); print_vec3(cam.right);
print_vec3(cam.up); printf("\nUp : ");
printf("\nFOV : %.2f", cam.fov); print_vec3(cam.up);
printf("\nYaw : %.2f", cam.yaw); printf("\nFOV : %.2f", cam.fov);
printf("\nPitch : %.2f", cam.pitch); printf("\nYaw : %.2f", cam.yaw);
printf("\n"); printf("\nPitch : %.2f", cam.pitch);
printf("\n");
} }
void print_scene(t_scene scene) { void print_scene(t_scene scene)
int i = 0; {
int i;
printf("=== SCENE ===\n"); i = 0;
printf("=== SCENE ===\n");
// Ambiance // Ambiance
printf("\n--- Ambiance ---\n"); printf("\n--- Ambiance ---\n");
print_ambient(scene.ambient); print_ambient(scene.ambient);
// Caméra
// Caméra if (scene.numCamera > 0)
if (scene.numCamera > 0) { {
printf("\n--- Caméra ---\n"); printf("\n--- Caméra ---\n");
print_camera(scene.camera); print_camera(scene.camera);
} }
// Sphères
// Sphères printf("\n--- Sphères (%d) ---\n", scene.numSpheres);
printf("\n--- Sphères (%d) ---\n", scene.numSpheres); i = 0;
i = 0; while (i < scene.numSpheres)
while (i < scene.numSpheres) { {
printf("\nSphère %d :\n", i); printf("\nSphère %d :\n", i);
print_sphere(scene.spheres[i]); print_sphere(scene.spheres[i]);
i++; i++;
} }
// Plans
// Plans printf("\n--- Plans (%d) ---\n", scene.numPlanes);
printf("\n--- Plans (%d) ---\n", scene.numPlanes); i = 0;
i = 0; while (i < scene.numPlanes)
while (i < scene.numPlanes) { {
printf("\nPlan %d :\n", i); printf("\nPlan %d :\n", i);
print_plane(scene.planes[i]); print_plane(scene.planes[i]);
i++; i++;
} }
// Cylindres
// Cylindres printf("\n--- Cylindres (%d) ---\n", scene.numCylinders);
printf("\n--- Cylindres (%d) ---\n", scene.numCylinders); i = 0;
i = 0; while (i < scene.numCylinders)
while (i < scene.numCylinders) { {
printf("\nCylindre %d :\n", i); printf("\nCylindre %d :\n", i);
print_cylinder(scene.cylinders[i]); print_cylinder(scene.cylinders[i]);
i++; i++;
} }
// Lumières
// Lumières printf("\n--- Lumières (%d) ---\n", scene.numLights);
printf("\n--- Lumières (%d) ---\n", scene.numLights); i = 0;
i = 0; while (i < scene.numLights)
while (i < scene.numLights) { {
printf("\nLumière %d :\n", i); printf("\nLumière %d :\n", i);
print_light(scene.lights[i]); print_light(scene.lights[i]);
i++; i++;
} }
} }
+7 -6
View File
@@ -14,10 +14,10 @@
static void render_pixel(t_app *app, int x, int y) static void render_pixel(t_app *app, int x, int y)
{ {
t_calc calc; t_calc calc;
unsigned char r; unsigned char r;
unsigned char g; unsigned char g;
unsigned char b; unsigned char b;
calc.ndc_x = (x + 0.5f) / app->win_width; calc.ndc_x = (x + 0.5f) / app->win_width;
calc.ndc_y = (y + 0.5f) / app->win_height; calc.ndc_y = (y + 0.5f) / app->win_height;
@@ -27,7 +27,7 @@ static void render_pixel(t_app *app, int x, int y)
calc.screen_y = (1 - 2 * calc.ndc_y) * calc.scale; calc.screen_y = (1 - 2 * calc.ndc_y) * calc.scale;
calc.ray_dir = vec3_add(app->scene.camera.camDir, calc.ray_dir = vec3_add(app->scene.camera.camDir,
vec3_add(vec3_scale(app->scene.camera.right, calc.screen_x), vec3_add(vec3_scale(app->scene.camera.right, calc.screen_x),
vec3_scale(app->scene.camera.up, calc.screen_y))); vec3_scale(app->scene.camera.up, calc.screen_y)));
calc.ray_dir = vec3_normalize(calc.ray_dir); calc.ray_dir = vec3_normalize(calc.ray_dir);
calc.ray.origin = app->scene.camera.camPos; calc.ray.origin = app->scene.camera.camPos;
calc.ray.dir = calc.ray_dir; calc.ray.dir = calc.ray_dir;
@@ -35,7 +35,8 @@ static void render_pixel(t_app *app, int x, int y)
r = (unsigned char)(fminf(calc.color.x, 1.0f) * 255); r = (unsigned char)(fminf(calc.color.x, 1.0f) * 255);
g = (unsigned char)(fminf(calc.color.y, 1.0f) * 255); g = (unsigned char)(fminf(calc.color.y, 1.0f) * 255);
b = (unsigned char)(fminf(calc.color.z, 1.0f) * 255); b = (unsigned char)(fminf(calc.color.z, 1.0f) * 255);
app->pixels[y * app->win_width + x] = (255 << 24) | (r << 16) | (g << 8) | b; app->pixels[y * app->win_width
+ x] = (255 << 24) | (r << 16) | (g << 8) | b;
} }
void render_scene(t_app *app) void render_scene(t_app *app)
+67 -50
View File
@@ -13,64 +13,81 @@
#include "miniRT.h" #include "miniRT.h"
// Vérifie les intersections avec les sphères // Vérifie les intersections avec les sphères
static bool checkShadowSphere(const t_ray shadowRay, float maxT, float epsilon, t_scene scene) { static bool checkShadowSphere(const t_ray shadowRay, float maxT, float epsilon,
int i = 0; t_scene scene)
t_vec3 dummy; {
float t; int i;
while (i < scene.numSpheres) { t_vec3 dummy;
t = intersectSphere(shadowRay, scene.spheres[i], &dummy); float t;
if (t > epsilon && t < maxT)
return true; i = 0;
i++; while (i < scene.numSpheres)
} {
return false; t = intersectSphere(shadowRay, scene.spheres[i], &dummy);
if (t > epsilon && t < maxT)
return (true);
i++;
}
return (false);
} }
// Vérifie les intersections avec les plans // Vérifie les intersections avec les plans
static bool checkShadowPlane(const t_ray shadowRay, float maxT, float epsilon, t_scene scene) { static bool checkShadowPlane(const t_ray shadowRay, float maxT, float epsilon,
int i = 0; t_scene scene)
t_vec3 dummy; {
float t; int i;
while (i < scene.numPlanes) { t_vec3 dummy;
t = intersectPlane(shadowRay, scene.planes[i], &dummy); float t;
if (t > epsilon && t < maxT)
return true; i = 0;
i++; while (i < scene.numPlanes)
} {
return false; t = intersectPlane(shadowRay, scene.planes[i], &dummy);
if (t > epsilon && t < maxT)
return (true);
i++;
}
return (false);
} }
// Vérifie les intersections avec les cylindres // Vérifie les intersections avec les cylindres
static bool checkShadowCylinder(const t_ray shadowRay, float maxT, float epsilon, t_scene scene) { static bool checkShadowCylinder(const t_ray shadowRay, float maxT,
int i = 0; float epsilon, t_scene scene)
t_vec3 dummy; {
float t; int i;
while (i < scene.numCylinders) { t_vec3 dummy;
t = intersectCylinder(shadowRay, scene.cylinders[i], &dummy); float t;
if (t > epsilon && t < maxT)
return true; i = 0;
i++; while (i < scene.numCylinders)
} {
return false; t = intersectCylinder(shadowRay, scene.cylinders[i], &dummy);
if (t > epsilon && t < maxT)
return (true);
i++;
}
return (false);
} }
// Fonction principale qui détermine si le point est dans l'ombre // Fonction principale qui détermine si le point est dans l'ombre
bool isInShadow(t_vec3 hitPoint, t_vec3 lightPos, t_scene scene) { bool isInShadow(t_vec3 hitPoint, t_vec3 lightPos, t_scene scene)
const float epsilon = 1e-3f; {
t_vec3 toLight = vec3_sub(lightPos, hitPoint); const float epsilon = 1e-3f;
float maxT = vec3_length(toLight); t_vec3 toLight;
t_vec3 L = vec3_normalize(toLight); float maxT;
t_ray shadowRay; t_vec3 L;
shadowRay.origin = vec3_add(hitPoint, vec3_scale(L, epsilon)); t_ray shadowRay;
shadowRay.dir = L;
if (checkShadowSphere(shadowRay, maxT, epsilon, scene)) toLight = vec3_sub(lightPos, hitPoint);
return true; maxT = vec3_length(toLight);
if (checkShadowPlane(shadowRay, maxT, epsilon, scene)) L = vec3_normalize(toLight);
return true; shadowRay.origin = vec3_add(hitPoint, vec3_scale(L, epsilon));
if (checkShadowCylinder(shadowRay, maxT, epsilon, scene)) shadowRay.dir = L;
return true; if (checkShadowSphere(shadowRay, maxT, epsilon, scene))
return (true);
return false; if (checkShadowPlane(shadowRay, maxT, epsilon, scene))
return (true);
if (checkShadowCylinder(shadowRay, maxT, epsilon, scene))
return (true);
return (false);
} }
+104 -57
View File
@@ -12,68 +12,115 @@
#include "miniRT.h" #include "miniRT.h"
#include "miniRT.h" // Renvoie true si le rayon intersecte un objet, et met à jour tMin,
hitNormal et objColor
bool intersectObjects(t_ray ray, float *tMin, t_vec3 *hitNormal,
t_vec3 *objColor, t_scene scene)
{
bool hit;
float t;
t_vec3 n;
int i;
// Renvoie true si le rayon intersecte un objet, et met à jour tMin, hitNormal et objColor hit = false;
bool intersectObjects(t_ray ray, float *tMin, t_vec3 *hitNormal, t_vec3 *objColor, t_scene scene) { i = 0;
bool hit = false; while (i < scene.numSpheres)
float t; {
t_vec3 n; t = intersectSphere(ray, scene.spheres[i], &n);
int i = 0; if (t > 1e-3f && t < *tMin)
while (i < scene.numSpheres) { {
t = intersectSphere(ray, scene.spheres[i], &n); *tMin = t;
if (t > 1e-3f && t < *tMin) { *tMin = t; *hitNormal = n; *objColor = scene.spheres[i].color; hit = true; } *hitNormal = n;
i++; *objColor = scene.spheres[i].color;
} hit = true;
i = 0; }
while (i < scene.numPlanes) { i++;
t = intersectPlane(ray, scene.planes[i], &n); }
if (t > 1e-3f && t < *tMin) { *tMin = t; *hitNormal = n; *objColor = scene.planes[i].color; hit = true; } i = 0;
i++; while (i < scene.numPlanes)
} {
i = 0; t = intersectPlane(ray, scene.planes[i], &n);
while (i < scene.numCylinders) { if (t > 1e-3f && t < *tMin)
t = intersectCylinder(ray, scene.cylinders[i], &n); {
if (t > 1e-3f && t < *tMin) { *tMin = t; *hitNormal = n; *objColor = scene.cylinders[i].color; hit = true; } *tMin = t;
i++; *hitNormal = n;
} *objColor = scene.planes[i].color;
return hit; hit = true;
}
i++;
}
i = 0;
while (i < scene.numCylinders)
{
t = intersectCylinder(ray, scene.cylinders[i], &n);
if (t > 1e-3f && t < *tMin)
{
*tMin = t;
*hitNormal = n;
*objColor = scene.cylinders[i].color;
hit = true;
}
i++;
}
return (hit);
} }
// Calcule l'éclairage (ambiant, diffus et spéculaire) sur un point d'impact // Calcule l'éclairage (ambiant, diffus et spéculaire) sur un point d'impact
t_vec3 calcLighting(t_vec3 hitPoint, t_vec3 hitNormal, t_vec3 objColor, t_scene scene) { t_vec3 calcLighting(t_vec3 hitPoint, t_vec3 hitNormal, t_vec3 objColor,
t_vec3 color = vec3_scale(objColor, scene.ambient.ratio); t_scene scene)
int i = 0; {
while (i < scene.numLights) { t_vec3 color;
t_light light = scene.lights[i]; int i;
t_vec3 L = vec3_normalize(vec3_sub(light.pos, hitPoint)); t_light light;
if (!isInShadow(hitPoint, light.pos, scene)) { t_vec3 L;
float diff = fmaxf(0.0f, vec3_dot(hitNormal, L)); float diff;
t_vec3 viewDir = vec3_normalize(vec3_sub(scene.camera.camPos, hitPoint)); t_vec3 viewDir;
t_vec3 halfDir = vec3_normalize(vec3_add(L, viewDir)); t_vec3 halfDir;
float spec = powf(fmaxf(0.0f, vec3_dot(hitNormal, halfDir)), 32.0f); float spec;
color = vec3_add(color, vec3_scale(vec3_mul(objColor, light.color),
diff * light.brightness)); color = vec3_scale(objColor, scene.ambient.ratio);
color = vec3_add(color, vec3_scale((t_vec3){1, 1, 1}, i = 0;
spec * light.brightness)); while (i < scene.numLights)
} {
i++; light = scene.lights[i];
} L = vec3_normalize(vec3_sub(light.pos, hitPoint));
if (color.x > 1.0f) color.x = 1.0f; if (!isInShadow(hitPoint, light.pos, scene))
if (color.y > 1.0f) color.y = 1.0f; {
if (color.z > 1.0f) color.z = 1.0f; diff = fmaxf(0.0f, vec3_dot(hitNormal, L));
return color; viewDir = vec3_normalize(vec3_sub(scene.camera.camPos, hitPoint));
halfDir = vec3_normalize(vec3_add(L, viewDir));
spec = powf(fmaxf(0.0f, vec3_dot(hitNormal, halfDir)), 32.0f);
color = vec3_add(color, vec3_scale(vec3_mul(objColor, light.color),
diff * light.brightness));
color = vec3_add(color, vec3_scale((t_vec3){1, 1, 1}, spec
* light.brightness));
}
i++;
}
if (color.x > 1.0f)
color.x = 1.0f;
if (color.y > 1.0f)
color.y = 1.0f;
if (color.z > 1.0f)
color.z = 1.0f;
return (color);
} }
// Fonction principale de lancer de rayon (trace) // Fonction principale de lancer de rayon (trace)
t_vec3 trace(t_ray ray, t_scene scene) { t_vec3 trace(t_ray ray, t_scene scene)
float tMin = 1e9; {
t_vec3 hitNormal = {0, 0, 0}; float tMin;
t_vec3 objColor = {0, 0, 0}; t_vec3 hitNormal;
if (intersectObjects(ray, &tMin, &hitNormal, &objColor, scene)) { t_vec3 objColor;
t_vec3 hitPoint = vec3_add(ray.origin, vec3_scale(ray.dir, tMin)); t_vec3 hitPoint;
return calcLighting(hitPoint, hitNormal, objColor, scene);
}
return (t_vec3){0.2f, 0.7f, 1.0f}; // Couleur de fond (ciel)
}
tMin = 1e9;
hitNormal = {0, 0, 0};
objColor = {0, 0, 0};
if (intersectObjects(ray, &tMin, &hitNormal, &objColor, scene))
{
hitPoint = vec3_add(ray.origin, vec3_scale(ray.dir, tMin));
return (calcLighting(hitPoint, hitNormal, objColor, scene));
}
return ((t_vec3){0.2f, 0.7f, 1.0f}); // Couleur de fond (ciel)
}
+16 -8
View File
@@ -26,29 +26,37 @@ static void update_camera_rotation(t_app *app)
app->scene.camera.pitch = 1.57f - 0.01f; app->scene.camera.pitch = 1.57f - 0.01f;
if (app->scene.camera.pitch < -1.57f + 0.01f) if (app->scene.camera.pitch < -1.57f + 0.01f)
app->scene.camera.pitch = -1.57f + 0.01f; app->scene.camera.pitch = -1.57f + 0.01f;
app->scene.camera.camDir.x = cosf(app->scene.camera.pitch) * sinf(app->scene.camera.yaw); app->scene.camera.camDir.x = cosf(app->scene.camera.pitch)
* sinf(app->scene.camera.yaw);
app->scene.camera.camDir.y = sinf(app->scene.camera.pitch); app->scene.camera.camDir.y = sinf(app->scene.camera.pitch);
app->scene.camera.camDir.z = -cosf(app->scene.camera.pitch) * cosf(app->scene.camera.yaw); app->scene.camera.camDir.z = -cosf(app->scene.camera.pitch)
* cosf(app->scene.camera.yaw);
app->scene.camera.camDir = vec3_normalize(app->scene.camera.camDir); app->scene.camera.camDir = vec3_normalize(app->scene.camera.camDir);
app->scene.camera.right = (t_vec3){cosf(app->scene.camera.yaw), 0, sinf(app->scene.camera.yaw)}; app->scene.camera.right = (t_vec3){cosf(app->scene.camera.yaw), 0,
sinf(app->scene.camera.yaw)};
app->scene.camera.right = vec3_normalize(app->scene.camera.right); app->scene.camera.right = vec3_normalize(app->scene.camera.right);
app->scene.camera.up = vec3_normalize(vec3_cross(app->scene.camera.right, app->scene.camera.camDir)); app->scene.camera.up = vec3_normalize(vec3_cross(app->scene.camera.right,
app->scene.camera.camDir));
} }
static void update_camera_movement(t_app *app) static void update_camera_movement(t_app *app)
{ {
if (app->key_w) if (app->key_w)
app->scene.camera.camPos = vec3_add(app->scene.camera.camPos, app->scene.camera.camPos = vec3_add(app->scene.camera.camPos,
vec3_scale(app->scene.camera.camDir, app->scene.camera.move_speed)); vec3_scale(app->scene.camera.camDir,
app->scene.camera.move_speed));
if (app->key_s) if (app->key_s)
app->scene.camera.camPos = vec3_sub(app->scene.camera.camPos, app->scene.camera.camPos = vec3_sub(app->scene.camera.camPos,
vec3_scale(app->scene.camera.camDir, app->scene.camera.move_speed)); vec3_scale(app->scene.camera.camDir,
app->scene.camera.move_speed));
if (app->key_a) if (app->key_a)
app->scene.camera.camPos = vec3_sub(app->scene.camera.camPos, app->scene.camera.camPos = vec3_sub(app->scene.camera.camPos,
vec3_scale(app->scene.camera.right, app->scene.camera.move_speed)); vec3_scale(app->scene.camera.right,
app->scene.camera.move_speed));
if (app->key_d) if (app->key_d)
app->scene.camera.camPos = vec3_add(app->scene.camera.camPos, app->scene.camera.camPos = vec3_add(app->scene.camera.camPos,
vec3_scale(app->scene.camera.right, app->scene.camera.move_speed)); vec3_scale(app->scene.camera.right,
app->scene.camera.move_speed));
} }
void update_camera(t_app *app) void update_camera(t_app *app)