diff --git a/calcul_de_vecteur.c b/calcul_de_vecteur.c index 51c2a8e..3c283a4 100644 --- a/calcul_de_vecteur.c +++ b/calcul_de_vecteur.c @@ -36,6 +36,6 @@ float vec3_dot(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, \ - a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x}); + return ((t_vec3){a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y + - a.y * b.x}); } diff --git a/check.c b/check.c index 51003f2..48f4940 100644 --- a/check.c +++ b/check.c @@ -17,7 +17,7 @@ int check_tokens(char **tokens, int 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) { diff --git a/config.c b/config.c index 126947b..de02ecc 100644 --- a/config.c +++ b/config.c @@ -37,9 +37,9 @@ static inline t_scene parsing_line(char *line, t_scene scene) // ----- Parsing du fichier de configuration ----- t_scene load_config(const char *filename) { - int fd; - char *line; - t_scene scene; + int fd; + char *line; + t_scene scene; scene = create_scene(); fd = open(filename, O_RDONLY); diff --git a/main.c b/main.c index c0105f2..da52a16 100644 --- a/main.c +++ b/main.c @@ -14,7 +14,7 @@ static int init_app_config(t_app *app, int argc, char **argv) { - t_scene scene; + t_scene scene; if (argc > 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); return (1); } - app->win = mlx_new_window(app->mlx, app->win_width, - app->win_height, "Raytracer interactif"); + app->win = mlx_new_window(app->mlx, app->win_width, app->win_height, + "Raytracer interactif"); if (!app->win) { 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); return (1); } - app->pixels = (int *)mlx_get_data_addr(app->img, &app->bpp, - &app->size_line, &app->endian); + app->pixels = (int *)mlx_get_data_addr(app->img, &app->bpp, &app->size_line, + &app->endian); if (!app->pixels) { ft_putstr_fd("Erreur mlx_get_data_addr\n", 2); diff --git a/miniRT.h b/miniRT.h index 65ff7fb..1798085 100644 --- a/miniRT.h +++ b/miniRT.h @@ -13,16 +13,16 @@ #ifndef MINIRT_H # define MINIRT_H +# include "float.h" +# include "get_next_line.h" +# include "libft.h" +# include "mlx.h" +# include # include # include # include # include # include -# include -# include "get_next_line.h" -# include "libft.h" -# include "float.h" -# include "mlx.h" // ----- Taille ecran ---- # define WIDTH 640 @@ -97,8 +97,8 @@ typedef struct s_camera float rot_speed; float move_speed; float fov; - float yaw;// vue de gauche a droite - float pitch; // vue de haut en bas en radians + float yaw; // vue de gauche a droite + float pitch; // vue de haut en bas en radians } t_camera; typedef struct s_scene @@ -115,75 +115,74 @@ typedef struct s_scene int numCamera; int numLights; int numAmbient; - char *line_if_exit; - char **token_if_exit; - int fd_if_exit; + char *line_if_exit; + char **token_if_exit; + int fd_if_exit; } t_scene; // ----- Minilibx typedef struct s_app { - void *mlx; - void *win; - void *img; - int *pixels; - int bpp; - int size_line; - int endian; - int win_width; - int win_height; - int key_w; - int key_s; - int key_a; - int key_d; - int key_left; - int key_right; - int key_up; - int key_down; - float mouse_sens; - t_scene scene; + void *mlx; + void *win; + void *img; + int *pixels; + int bpp; + int size_line; + int endian; + int win_width; + int win_height; + int key_w; + int key_s; + int key_a; + int key_d; + int key_left; + int key_right; + int key_up; + int key_down; + float mouse_sens; + t_scene scene; } t_app; - // ----- Calcul typedef struct s_calc { - t_vec3 oc; - float a; - float b; - float c; - float disc; - float sqrtDisc; - float t0; - float t1; - float t; - t_vec3 hitPoint; - t_vec3 d; - t_vec3 v; - float d_dot_v; - float oc_dot_v; - t_vec3 d_perp; - t_vec3 oc_perp; - float t_side; - float y; - float t_cap; - float t_bot; - float t_top; - t_vec3 p; - t_vec3 cp; - float dist; - float t_final; - float proj; - t_vec3 n; - float ndc_x; - float ndc_y; - float aspect; - float scale; - float screen_x; - float screen_y; - t_ray ray; - t_vec3 ray_dir; - t_vec3 color; + t_vec3 oc; + float a; + float b; + float c; + float disc; + float sqrtDisc; + float t0; + float t1; + float t; + t_vec3 hitPoint; + t_vec3 d; + t_vec3 v; + float d_dot_v; + float oc_dot_v; + t_vec3 d_perp; + t_vec3 oc_perp; + float t_side; + float y; + float t_cap; + float t_bot; + float t_top; + t_vec3 p; + t_vec3 cp; + float dist; + float t_final; + float proj; + t_vec3 n; + float ndc_x; + float ndc_y; + float aspect; + float scale; + float screen_x; + float screen_y; + t_ray ray; + t_vec3 ray_dir; + t_vec3 color; } t_calc; // 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_normalize(const char *token, t_scene scene); - // 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 -int check_tokens(char **tokens, int expected); -void check_if_max(t_scene scene, const int to_test, const int max); +int check_tokens(char **tokens, int expected); +void check_if_max(t_scene scene, const int to_test, const int max); // Intersection -float intersectCylinder(t_ray ray, t_cylinder cy, 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); -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); -t_vec3 calcLighting(t_vec3 hitPoint, t_vec3 hitNormal, t_vec3 objColor, t_scene scene); -t_vec3 trace(t_ray ray, t_scene scene); +float intersectCylinder(t_ray ray, t_cylinder cy, 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); +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); +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 -int key_press(int keycode, t_app *app); -int key_release(int keycode, t_app *app); -int mouse_move(int x, int y, t_app *app); +int key_press(int keycode, t_app *app); +int key_release(int keycode, t_app *app); +int mouse_move(int x, int y, t_app *app); // Render -void update_camera(t_app *app); -void render_scene(t_app *app); -int update_frame(t_app *app); +void update_camera(t_app *app); +void render_scene(t_app *app); +int update_frame(t_app *app); // Array -int ft_arraylen(char **array); -void ft_free_array(char **array); +int ft_arraylen(char **array); +void ft_free_array(char **array); // Conversion -float ft_atof(char *str); +float ft_atof(char *str); // Info -void print_vec3(t_vec3 vec); -void print_ray(t_ray ray); -void print_sphere(t_sphere sphere); -void print_plane(t_plane plane); -void print_cylinder(t_cylinder cyl); -void print_light(t_light light); -void print_ambient(t_ambient amb); -void print_camera(t_camera cam); -void print_scene(t_scene scene); +void print_vec3(t_vec3 vec); +void print_ray(t_ray ray); +void print_sphere(t_sphere sphere); +void print_plane(t_plane plane); +void print_cylinder(t_cylinder cyl); +void print_light(t_light light); +void print_ambient(t_ambient amb); +void print_camera(t_camera cam); +void print_scene(t_scene scene); #endif diff --git a/parsing_ambiant.c b/parsing_ambiant.c index 494c09e..159ac8e 100644 --- a/parsing_ambiant.c +++ b/parsing_ambiant.c @@ -12,10 +12,9 @@ #include "miniRT.h" - t_scene parsing_ambiant(t_scene scene) { - char **tokens; + char **tokens; tokens = get_tokens_secure(scene, scene.numAmbient, MAX_AMBIENT, 3); scene.token_if_exit = tokens; diff --git a/parsing_camera.c b/parsing_camera.c index 33e321d..5dd63a3 100644 --- a/parsing_camera.c +++ b/parsing_camera.c @@ -12,9 +12,9 @@ #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); scene.token_if_exit = tokens; diff --git a/parsing_color.c b/parsing_color.c index 2e5522d..51d6d10 100644 --- a/parsing_color.c +++ b/parsing_color.c @@ -29,7 +29,7 @@ static inline int range_is_ok(char **token_color) t_vec3 parse_color(const char *token, t_scene scene) { char **token_color; - t_vec3 color; + t_vec3 color; token_color = ft_split(token, ','); if (!check_tokens(token_color, 3) || !range_is_ok(token_color)) diff --git a/parsing_cylinder.c b/parsing_cylinder.c index 17cc608..582e215 100644 --- a/parsing_cylinder.c +++ b/parsing_cylinder.c @@ -15,7 +15,8 @@ /* float intersectCylinder(Ray ray, Cylinder cy, t_vec3 *hitNormal) { - t_calc calc; + t_calc calc; + char **tokens; calc.d = ray.dir; 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)); 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) 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)); cp = vec3_sub(p, cy.center); - calc.dist = vec3_length(vec3_sub(cp, vec3_scale(calc.v, vec3_dot(cp, calc.v)))); - if (calc.dist <= cy.radius && (calc.t_cap < 0 || t_top < calc.t_cap)) + calc.dist = vec3_length(vec3_sub(cp, vec3_scale(calc.v, vec3_dot(cp, + calc.v)))); + if (calc.dist <= cy.radius && (calc.t_cap < 0 + || t_top < calc.t_cap)) 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); } - return calc.t_final; + return (calc.t_final); }*/ - t_scene parsing_cylindre(t_scene scene) { - char **tokens; - tokens = get_tokens_secure(scene, scene.numCylinders, MAX_CYLINDERS, 6); scene.token_if_exit = tokens; 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].height = ft_atof(tokens[4]); scene.cylinders[scene.numCylinders].color = parse_color(tokens[5], scene); @@ -107,5 +109,3 @@ t_scene parsing_cylindre(t_scene scene) scene.numCylinders++; return (scene); } - - diff --git a/parsing_cylinder_utils.c b/parsing_cylinder_utils.c index d9fd320..5a6246d 100644 --- a/parsing_cylinder_utils.c +++ b/parsing_cylinder_utils.c @@ -13,99 +13,116 @@ #include "miniRT.h" // 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) { - calc->d = ray.dir; - calc->oc = vec3_sub(ray.origin, cy.center); - calc->v = cy.axis; - calc->d_dot_v = vec3_dot(calc->d, calc->v); - calc->oc_dot_v = vec3_dot(calc->oc, calc->v); - calc->d_perp = vec3_sub(calc->d, vec3_scale(calc->v, calc->d_dot_v)); - calc->oc_perp = vec3_sub(calc->oc, vec3_scale(calc->v, calc->oc_dot_v)); - calc->a = vec3_dot(calc->d_perp, calc->d_perp); - calc->b = 2 * vec3_dot(calc->d_perp, calc->oc_perp); - calc->c = vec3_dot(calc->oc_perp, calc->oc_perp) - cy.radius * cy.radius; - calc->disc = calc->b * calc->b - 4 * calc->a * calc->c; - if (calc->disc < 0) - return -1; - calc->sqrtDisc = sqrtf(calc->disc); - calc->t0 = (-calc->b - calc->sqrtDisc) / (2 * calc->a); - calc->t1 = (-calc->b + calc->sqrtDisc) / (2 * calc->a); - return 0; +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->v = cy.axis; + calc->d_dot_v = vec3_dot(calc->d, calc->v); + calc->oc_dot_v = vec3_dot(calc->oc, calc->v); + calc->d_perp = vec3_sub(calc->d, vec3_scale(calc->v, calc->d_dot_v)); + calc->oc_perp = vec3_sub(calc->oc, vec3_scale(calc->v, calc->oc_dot_v)); + calc->a = vec3_dot(calc->d_perp, calc->d_perp); + calc->b = 2 * vec3_dot(calc->d_perp, calc->oc_perp); + calc->c = vec3_dot(calc->oc_perp, calc->oc_perp) - cy.radius * cy.radius; + calc->disc = calc->b * calc->b - 4 * calc->a * calc->c; + if (calc->disc < 0) + return (-1); + calc->sqrtDisc = sqrtf(calc->disc); + calc->t0 = (-calc->b - calc->sqrtDisc) / (2 * calc->a); + calc->t1 = (-calc->b + calc->sqrtDisc) / (2 * calc->a); + return (0); } // Calcule l'intersection sur la surface latérale du cylindre -static void compute_side_intersection(t_cylinder cy, t_calc *calc) { - calc->t_side = -1; - if (calc->t0 > 1e-3f) { - calc->y = calc->oc_dot_v + calc->t0 * calc->d_dot_v; - if (fabs(calc->y) <= cy.height / 2.0f) - calc->t_side = calc->t0; - } - if (calc->t_side < 0 && calc->t1 > 1e-3f) { - 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; - } +static void compute_side_intersection(t_cylinder cy, t_calc *calc) +{ + calc->t_side = -1; + if (calc->t0 > 1e-3f) + { + calc->y = calc->oc_dot_v + calc->t0 * calc->d_dot_v; + if (fabs(calc->y) <= cy.height / 2.0f) + calc->t_side = calc->t0; + } + if (calc->t_side < 0 && calc->t1 > 1e-3f) + { + 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 -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_bot = ((-cy.height / 2.0f) - calc->oc_dot_v) / calc->d_dot_v; - if (calc->t_bot > 1e-3f) { - calc->p = vec3_add(ray.origin, vec3_scale(calc->d, 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)))); - if (calc->dist <= cy.radius) - calc->t_cap = calc->t_bot; - } - calc->t_top = ((cy.height / 2.0f) - calc->oc_dot_v) / calc->d_dot_v; - if (calc->t_top > 1e-3f) { - 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; - } - } +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_bot = ((-cy.height / 2.0f) - calc->oc_dot_v) / calc->d_dot_v; + if (calc->t_bot > 1e-3f) + { + calc->p = vec3_add(ray.origin, vec3_scale(calc->d, 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)))); + if (calc->dist <= cy.radius) + calc->t_cap = calc->t_bot; + } + calc->t_top = ((cy.height / 2.0f) - calc->oc_dot_v) / calc->d_dot_v; + if (calc->t_top > 1e-3f) + { + 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 -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; - else if (calc->t_side > 1e-3f) - calc->t_final = calc->t_side; - else - calc->t_final = calc->t_cap; - return (calc->t_final > 1e-3f) ? calc->t_final : -1; +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; + else if (calc->t_side > 1e-3f) + calc->t_final = calc->t_side; + else + calc->t_final = calc->t_cap; + return ((calc->t_final > 1e-3f) ? calc->t_final : -1); } // Calcule la normale au point d'intersection -static void compute_hit_normal(t_ray ray, t_cylinder cy, t_calc *calc, t_vec3 *hitNormal) { - calc->hitPoint = vec3_add(ray.origin, vec3_scale(calc->d, calc->t_final)); - calc->cp = vec3_sub(calc->hitPoint, cy.center); - calc->proj = vec3_dot(calc->cp, calc->v); - if (fabs(calc->proj) < cy.height / 2.0f - 1e-3f) { - 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); - } +static void compute_hit_normal(t_ray ray, t_cylinder cy, t_calc *calc, + t_vec3 *hitNormal) +{ + calc->hitPoint = vec3_add(ray.origin, vec3_scale(calc->d, calc->t_final)); + calc->cp = vec3_sub(calc->hitPoint, cy.center); + calc->proj = vec3_dot(calc->cp, calc->v); + if (fabs(calc->proj) < cy.height / 2.0f - 1e-3f) + { + 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 -float intersectCylinder(t_ray ray, t_cylinder cy, t_vec3 *hitNormal) { - t_calc calc; - if (init_intersection(ray, cy, &calc) < 0) - return -1; - compute_side_intersection(cy, &calc); - compute_cap_intersection(ray, cy, &calc); - if (select_final_intersection(&calc) < 0) - return -1; - compute_hit_normal(ray, cy, &calc, hitNormal); - return calc.t_final; +float intersectCylinder(t_ray ray, t_cylinder cy, t_vec3 *hitNormal) +{ + t_calc calc; + + if (init_intersection(ray, cy, &calc) < 0) + return (-1); + compute_side_intersection(cy, &calc); + compute_cap_intersection(ray, cy, &calc); + if (select_final_intersection(&calc) < 0) + return (-1); + compute_hit_normal(ray, cy, &calc, hitNormal); + return (calc.t_final); } - - diff --git a/parsing_plane.c b/parsing_plane.c index a9b518c..7ded4ef 100644 --- a/parsing_plane.c +++ b/parsing_plane.c @@ -19,7 +19,8 @@ t_scene parsing_plane(t_scene scene) tokens = get_tokens_secure(scene, scene.numPlanes, MAX_PLANES, 4); scene.token_if_exit = tokens; 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); ft_free_array(tokens); scene.numPlanes++; @@ -40,4 +41,3 @@ float intersectPlane(t_ray ray, t_plane p, t_vec3 *hitNormal) *hitNormal = p.normal; return (t); } - diff --git a/parsing_sphere.c b/parsing_sphere.c index 10f0224..393495f 100644 --- a/parsing_sphere.c +++ b/parsing_sphere.c @@ -29,7 +29,7 @@ t_scene parsing_sphere(t_scene scene) float intersectSphere(t_ray ray, t_sphere s, t_vec3 *hitNormal) { t_calc calc; - + calc.oc = vec3_sub(ray.origin, s.center); calc.a = vec3_dot(ray.dir, ray.dir); calc.b = 2.0f * vec3_dot(calc.oc, ray.dir); @@ -47,4 +47,3 @@ float intersectSphere(t_ray ray, t_sphere s, t_vec3 *hitNormal) *hitNormal = vec3_normalize(vec3_sub(calc.hitPoint, s.center)); return (calc.t); } - diff --git a/parsing_utils.c b/parsing_utils.c index 0fa341c..7b7d2cf 100644 --- a/parsing_utils.c +++ b/parsing_utils.c @@ -12,12 +12,13 @@ #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; 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)) { ft_free_array(tokens); diff --git a/parsing_vector.c b/parsing_vector.c index d90cfa8..898b0fa 100644 --- a/parsing_vector.c +++ b/parsing_vector.c @@ -19,7 +19,8 @@ static inline int range_is_ok(char **token_vector) i = 0; 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); i++; } @@ -29,7 +30,7 @@ static inline int range_is_ok(char **token_vector) t_vec3 parse_vector(const char *token, t_scene scene) { char **token_vector; - t_vec3 vector; + t_vec3 vector; token_vector = ft_split(token, ','); if (!check_tokens(token_vector, 3) || !range_is_ok(token_vector)) diff --git a/peripherique.c b/peripherique.c index 5402530..1eac269 100644 --- a/peripherique.c +++ b/peripherique.c @@ -77,4 +77,3 @@ int mouse_move(int x, int y, t_app *app) last_y = y; return (0); } - diff --git a/print.c b/print.c index 9879dc8..7c1ca31 100644 --- a/print.c +++ b/print.c @@ -12,128 +12,137 @@ #include "miniRT.h" -void print_vec3(t_vec3 vec) { - printf("(x: %.2f, y: %.2f, z: %.2f)", vec.x, vec.y, vec.z); +void print_vec3(t_vec3 vec) +{ + printf("(x: %.2f, y: %.2f, z: %.2f)", vec.x, vec.y, vec.z); } -void print_ray(t_ray ray) { - printf("Rayon d'origine : "); - print_vec3(ray.origin); - printf("\nDirection : "); - print_vec3(ray.dir); - printf("\n"); +void print_ray(t_ray ray) +{ + printf("Rayon d'origine : "); + print_vec3(ray.origin); + printf("\nDirection : "); + print_vec3(ray.dir); + printf("\n"); } -void print_sphere(t_sphere sphere) { - printf("Centre : "); - print_vec3(sphere.center); - printf("\nRayon : %.2f", sphere.radius); - printf("\nCouleur : "); - print_vec3(sphere.color); - printf("\n"); +void print_sphere(t_sphere sphere) +{ + printf("Centre : "); + print_vec3(sphere.center); + printf("\nRayon : %.2f", sphere.radius); + printf("\nCouleur : "); + print_vec3(sphere.color); + printf("\n"); } -void print_plane(t_plane plane) { - printf("Point : "); - print_vec3(plane.point); - printf("\nNormale : "); - print_vec3(plane.normal); - printf("\nCouleur : "); - print_vec3(plane.color); - printf("\n"); +void print_plane(t_plane plane) +{ + printf("Point : "); + print_vec3(plane.point); + printf("\nNormale : "); + print_vec3(plane.normal); + printf("\nCouleur : "); + print_vec3(plane.color); + printf("\n"); } -void print_cylinder(t_cylinder cyl) { - printf("Centre : "); - print_vec3(cyl.center); - printf("\nAxe : "); - print_vec3(cyl.axis); - printf("\nRayon : %.2f", cyl.radius); - printf("\nHauteur : %.2f", cyl.height); - printf("\nCouleur : "); - print_vec3(cyl.color); - printf("\n"); +void print_cylinder(t_cylinder cyl) +{ + printf("Centre : "); + print_vec3(cyl.center); + printf("\nAxe : "); + print_vec3(cyl.axis); + printf("\nRayon : %.2f", cyl.radius); + printf("\nHauteur : %.2f", cyl.height); + printf("\nCouleur : "); + print_vec3(cyl.color); + printf("\n"); } -void print_light(t_light light) { - printf("Position : "); - print_vec3(light.pos); - printf("\nIntensité : %.2f", light.brightness); - printf("\nCouleur : "); - print_vec3(light.color); - printf("\n"); +void print_light(t_light light) +{ + printf("Position : "); + print_vec3(light.pos); + printf("\nIntensité : %.2f", light.brightness); + printf("\nCouleur : "); + print_vec3(light.color); + printf("\n"); } -void print_ambient(t_ambient amb) { - printf("Ratio d'ambiance : %.2f\n", amb.ratio); - printf("Couleur ambiante : "); - print_vec3(amb.color); - printf("\n"); +void print_ambient(t_ambient amb) +{ + printf("Ratio d'ambiance : %.2f\n", amb.ratio); + printf("Couleur ambiante : "); + print_vec3(amb.color); + printf("\n"); } -void print_camera(t_camera cam) { - printf("Position de la caméra : "); - print_vec3(cam.camPos); - printf("\nDirection : "); - print_vec3(cam.camDir); - printf("\nRight : "); - print_vec3(cam.right); - printf("\nUp : "); - print_vec3(cam.up); - printf("\nFOV : %.2f", cam.fov); - printf("\nYaw : %.2f", cam.yaw); - printf("\nPitch : %.2f", cam.pitch); - printf("\n"); +void print_camera(t_camera cam) +{ + printf("Position de la caméra : "); + print_vec3(cam.camPos); + printf("\nDirection : "); + print_vec3(cam.camDir); + printf("\nRight : "); + print_vec3(cam.right); + printf("\nUp : "); + print_vec3(cam.up); + printf("\nFOV : %.2f", cam.fov); + printf("\nYaw : %.2f", cam.yaw); + printf("\nPitch : %.2f", cam.pitch); + printf("\n"); } -void print_scene(t_scene scene) { - int i = 0; - - printf("=== SCENE ===\n"); - - // Ambiance - printf("\n--- Ambiance ---\n"); - print_ambient(scene.ambient); - - // Caméra - if (scene.numCamera > 0) { - printf("\n--- Caméra ---\n"); - print_camera(scene.camera); - } - - // Sphères - printf("\n--- Sphères (%d) ---\n", scene.numSpheres); - i = 0; - while (i < scene.numSpheres) { - printf("\nSphère %d :\n", i); - print_sphere(scene.spheres[i]); - i++; - } - - // Plans - printf("\n--- Plans (%d) ---\n", scene.numPlanes); - i = 0; - while (i < scene.numPlanes) { - printf("\nPlan %d :\n", i); - print_plane(scene.planes[i]); - i++; - } - - // Cylindres - printf("\n--- Cylindres (%d) ---\n", scene.numCylinders); - i = 0; - while (i < scene.numCylinders) { - printf("\nCylindre %d :\n", i); - print_cylinder(scene.cylinders[i]); - i++; - } - - // Lumières - printf("\n--- Lumières (%d) ---\n", scene.numLights); - i = 0; - while (i < scene.numLights) { - printf("\nLumière %d :\n", i); - print_light(scene.lights[i]); - i++; - } +void print_scene(t_scene scene) +{ + int i; + + i = 0; + printf("=== SCENE ===\n"); + // Ambiance + printf("\n--- Ambiance ---\n"); + print_ambient(scene.ambient); + // Caméra + if (scene.numCamera > 0) + { + printf("\n--- Caméra ---\n"); + print_camera(scene.camera); + } + // Sphères + printf("\n--- Sphères (%d) ---\n", scene.numSpheres); + i = 0; + while (i < scene.numSpheres) + { + printf("\nSphère %d :\n", i); + print_sphere(scene.spheres[i]); + i++; + } + // Plans + printf("\n--- Plans (%d) ---\n", scene.numPlanes); + i = 0; + while (i < scene.numPlanes) + { + printf("\nPlan %d :\n", i); + print_plane(scene.planes[i]); + i++; + } + // Cylindres + printf("\n--- Cylindres (%d) ---\n", scene.numCylinders); + i = 0; + while (i < scene.numCylinders) + { + printf("\nCylindre %d :\n", i); + print_cylinder(scene.cylinders[i]); + i++; + } + // Lumières + printf("\n--- Lumières (%d) ---\n", scene.numLights); + i = 0; + while (i < scene.numLights) + { + printf("\nLumière %d :\n", i); + print_light(scene.lights[i]); + i++; + } } diff --git a/render.c b/render.c index 306463b..4ca0788 100644 --- a/render.c +++ b/render.c @@ -14,10 +14,10 @@ static void render_pixel(t_app *app, int x, int y) { - t_calc calc; - unsigned char r; - unsigned char g; - unsigned char b; + t_calc calc; + unsigned char r; + unsigned char g; + unsigned char b; calc.ndc_x = (x + 0.5f) / app->win_width; 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.ray_dir = vec3_add(app->scene.camera.camDir, 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.origin = app->scene.camera.camPos; 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); g = (unsigned char)(fminf(calc.color.y, 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) diff --git a/shadows.c b/shadows.c index 77f4347..32c1bff 100644 --- a/shadows.c +++ b/shadows.c @@ -13,64 +13,81 @@ #include "miniRT.h" // Vérifie les intersections avec les sphères -static bool checkShadowSphere(const t_ray shadowRay, float maxT, float epsilon, t_scene scene) { - int i = 0; - t_vec3 dummy; - float t; - while (i < scene.numSpheres) { - t = intersectSphere(shadowRay, scene.spheres[i], &dummy); - if (t > epsilon && t < maxT) - return true; - i++; - } - return false; +static bool checkShadowSphere(const t_ray shadowRay, float maxT, float epsilon, + t_scene scene) +{ + int i; + t_vec3 dummy; + float t; + + i = 0; + while (i < scene.numSpheres) + { + t = intersectSphere(shadowRay, scene.spheres[i], &dummy); + if (t > epsilon && t < maxT) + return (true); + i++; + } + return (false); } // Vérifie les intersections avec les plans -static bool checkShadowPlane(const t_ray shadowRay, float maxT, float epsilon, t_scene scene) { - int i = 0; - t_vec3 dummy; - float t; - while (i < scene.numPlanes) { - t = intersectPlane(shadowRay, scene.planes[i], &dummy); - if (t > epsilon && t < maxT) - return true; - i++; - } - return false; +static bool checkShadowPlane(const t_ray shadowRay, float maxT, float epsilon, + t_scene scene) +{ + int i; + t_vec3 dummy; + float t; + + i = 0; + while (i < scene.numPlanes) + { + t = intersectPlane(shadowRay, scene.planes[i], &dummy); + if (t > epsilon && t < maxT) + return (true); + i++; + } + return (false); } // Vérifie les intersections avec les cylindres -static bool checkShadowCylinder(const t_ray shadowRay, float maxT, float epsilon, t_scene scene) { - int i = 0; - t_vec3 dummy; - float t; - while (i < scene.numCylinders) { - t = intersectCylinder(shadowRay, scene.cylinders[i], &dummy); - if (t > epsilon && t < maxT) - return true; - i++; - } - return false; +static bool checkShadowCylinder(const t_ray shadowRay, float maxT, + float epsilon, t_scene scene) +{ + int i; + t_vec3 dummy; + float t; + + i = 0; + while (i < scene.numCylinders) + { + 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 -bool isInShadow(t_vec3 hitPoint, t_vec3 lightPos, t_scene scene) { - const float epsilon = 1e-3f; - t_vec3 toLight = vec3_sub(lightPos, hitPoint); - float maxT = vec3_length(toLight); - t_vec3 L = vec3_normalize(toLight); - t_ray shadowRay; - shadowRay.origin = vec3_add(hitPoint, vec3_scale(L, epsilon)); - shadowRay.dir = L; +bool isInShadow(t_vec3 hitPoint, t_vec3 lightPos, t_scene scene) +{ + const float epsilon = 1e-3f; + t_vec3 toLight; + float maxT; + t_vec3 L; + t_ray shadowRay; - if (checkShadowSphere(shadowRay, maxT, epsilon, scene)) - return true; - if (checkShadowPlane(shadowRay, maxT, epsilon, scene)) - return true; - if (checkShadowCylinder(shadowRay, maxT, epsilon, scene)) - return true; - - return false; + toLight = vec3_sub(lightPos, hitPoint); + maxT = vec3_length(toLight); + L = vec3_normalize(toLight); + shadowRay.origin = vec3_add(hitPoint, vec3_scale(L, epsilon)); + shadowRay.dir = L; + if (checkShadowSphere(shadowRay, maxT, epsilon, scene)) + return (true); + if (checkShadowPlane(shadowRay, maxT, epsilon, scene)) + return (true); + if (checkShadowCylinder(shadowRay, maxT, epsilon, scene)) + return (true); + return (false); } - diff --git a/trace.c b/trace.c index 80c270e..90ef603 100644 --- a/trace.c +++ b/trace.c @@ -12,68 +12,115 @@ #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 -bool intersectObjects(t_ray ray, float *tMin, t_vec3 *hitNormal, t_vec3 *objColor, t_scene scene) { - bool hit = false; - float t; - t_vec3 n; - int i = 0; - while (i < scene.numSpheres) { - t = intersectSphere(ray, scene.spheres[i], &n); - if (t > 1e-3f && t < *tMin) { *tMin = t; *hitNormal = n; *objColor = scene.spheres[i].color; hit = true; } - i++; - } - i = 0; - while (i < scene.numPlanes) { - 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++; - } - 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; + hit = false; + i = 0; + while (i < scene.numSpheres) + { + t = intersectSphere(ray, scene.spheres[i], &n); + if (t > 1e-3f && t < *tMin) + { + *tMin = t; + *hitNormal = n; + *objColor = scene.spheres[i].color; + hit = true; + } + i++; + } + i = 0; + while (i < scene.numPlanes) + { + 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++; + } + 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 -t_vec3 calcLighting(t_vec3 hitPoint, t_vec3 hitNormal, t_vec3 objColor, t_scene scene) { - t_vec3 color = vec3_scale(objColor, scene.ambient.ratio); - int i = 0; - while (i < scene.numLights) { - t_light light = scene.lights[i]; - t_vec3 L = vec3_normalize(vec3_sub(light.pos, hitPoint)); - if (!isInShadow(hitPoint, light.pos, scene)) { - float diff = fmaxf(0.0f, vec3_dot(hitNormal, L)); - t_vec3 viewDir = vec3_normalize(vec3_sub(scene.camera.camPos, hitPoint)); - t_vec3 halfDir = vec3_normalize(vec3_add(L, viewDir)); - float 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; +t_vec3 calcLighting(t_vec3 hitPoint, t_vec3 hitNormal, t_vec3 objColor, + t_scene scene) +{ + t_vec3 color; + int i; + t_light light; + t_vec3 L; + float diff; + t_vec3 viewDir; + t_vec3 halfDir; + float spec; + + color = vec3_scale(objColor, scene.ambient.ratio); + i = 0; + while (i < scene.numLights) + { + light = scene.lights[i]; + L = vec3_normalize(vec3_sub(light.pos, hitPoint)); + if (!isInShadow(hitPoint, light.pos, scene)) + { + diff = fmaxf(0.0f, vec3_dot(hitNormal, L)); + 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) -t_vec3 trace(t_ray ray, t_scene scene) { - float tMin = 1e9; - t_vec3 hitNormal = {0, 0, 0}; - t_vec3 objColor = {0, 0, 0}; - if (intersectObjects(ray, &tMin, &hitNormal, &objColor, scene)) { - t_vec3 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) -} +t_vec3 trace(t_ray ray, t_scene scene) +{ + float tMin; + t_vec3 hitNormal; + t_vec3 objColor; + t_vec3 hitPoint; + 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) +} diff --git a/update_camera.c b/update_camera.c index 6cf7472..8c895ad 100644 --- a/update_camera.c +++ b/update_camera.c @@ -26,29 +26,37 @@ static void update_camera_rotation(t_app *app) 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.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.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.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.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) { if (app->key_w) 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) 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) 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) 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)