diff --git a/.gitmodules b/.gitmodules index 1cba40a..4fe2200 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "libft"] path = libft url = git@github.com:H3XploR/libft.git +[submodule "minilibx-linux"] + path = minilibx-linux + url = https://github.com/42Paris/minilibx-linux.git diff --git a/array.c b/array.c new file mode 100644 index 0000000..7db6111 --- /dev/null +++ b/array.c @@ -0,0 +1,36 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_arraylen.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: yantoine +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/02/17 21:10:10 by yantoine #+# #+# */ +/* Updated: 2025/02/17 21:21:30 by yantoine ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "miniRT.h" + +int ft_arraylen(char **array) +{ + int i; + + i = 0; + while (array[i]) + i++; + return (i); +} + +void ft_free_array(char **array) +{ + int i; + + i = 0; + while (array[i]) + { + free(array[i]); + i++; + } + free(array); +} diff --git a/check.c b/check.c index 37e274b..51003f2 100644 --- a/check.c +++ b/check.c @@ -6,24 +6,24 @@ /* By: yantoine +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/14 18:28:42 by yantoine #+# #+# */ -/* Updated: 2025/02/14 20:15:29 by yantoine ### ########.fr */ +/* Updated: 2025/02/17 21:07:31 by yantoine ### ########.fr */ /* */ /* ************************************************************************** */ #include "miniRT.h" -inline int check_tokens(char **tokens, int expected) +int check_tokens(char **tokens, int expected) { return (tokens && ft_arraylen(tokens) == expected); } -inline 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) { printf("error:\n"); close(scene.fd_if_exit); - free(scene->line_if_exit); + free(scene.line_if_exit); exit(1); } } diff --git a/config.c b/config.c index 06fe65b..4776fce 100644 --- a/config.c +++ b/config.c @@ -6,56 +6,56 @@ /* By: yantoine +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/14 01:41:17 by yantoine #+# #+# */ -/* Updated: 2025/02/15 19:56:05 by yantoine ### ########.fr */ +/* Updated: 2025/02/17 21:52:57 by yantoine ### ########.fr */ /* */ /* ************************************************************************** */ #include "miniRT.h" -static inline t_scene parsing_line(const char *line, t_scene scene) +static inline t_scene parsing_line(char *line, t_scene scene) { - scene->line_if_exit = line; + scene.line_if_exit = line; if (line[0] == '#') - return ; + return (scene); else if (line[0] == 'A') - parsing_ambiant(line, scene); + scene = parsing_ambiant(scene); else if (line[0] == 'C') - parsing_camera(line, scene); + scene = parsing_camera(scene); else if (line[0] == 'L') - parsing_light(line, scene); + scene = parsing_light(scene); else if (ft_strncmp(line, "sp", 2) == 0) - parsing_sphere(line, scene); + scene = parsing_sphere(scene); else if (ft_strncmp(line, "pl", 2) == 0) - parsing_plane(line, scene); + scene = parsing_plane(scene); else if (ft_strncmp(line, "cy", 2) == 0) - parsing_cylindre(line, scene); + scene = parsing_cylindre(scene); else printf("Erreur : ligne non reconnue\n"); + return (scene); } // ----- Parsing du fichier de configuration ----- t_scene load_config(const char *filename) { int fd; - char line[256]; - const char *line; + char *line; t_scene scene; - scene = create_scene(void); - fd = open(filename, "r"); + scene = create_scene(); + fd = open(filename, O_RDONLY); if (!fd) { printf("Erreur : impossible d'ouvrir %s\n", filename); - return ; + return (scene); } scene.fd_if_exit = fd; while (1) { - line = (const char *)get_next_line(fd); + line = get_next_line(fd); if (!line) break ; - free(line); parsing_line(line, scene); + free(line); } return (scene); } diff --git a/config.rt b/config.rt new file mode 100644 index 0000000..9f9fafd --- /dev/null +++ b/config.rt @@ -0,0 +1,33 @@ +# **************************************************************************** # +# # +# ::: :::::::: # +# config.rt :+: :+: :+: # +# +:+ +:+ +:+ # +# By: yantoine +#+ +:+ +#+ # +# +#+#+#+#+#+ +#+ # +# Created: 2025/02/13 19:27:37 by yantoine #+# #+# # +# Updated: 2025/02/13 19:37:39 by yantoine ### ########.fr # +# # +# **************************************************************************** # + +# Ambient lighting (ratio et couleur) +A 0 255,255,255 + +# Camera : position à (0,0,20) et orientée vers (0,0,-1) avec un FOV de 70° +C 10,20,20 0,0,-1 70 + +# Light : source lumineuse forte placée au-dessus de la scène +L 11,40,-30 1 255,255,255 + +# Sphere : une sphère rouge centrée à (0,0,0) avec un diamètre de 10 +sp 0,0,0 10 255,0,0 +sp 10,10,10 10 0,0,100 + +# Plane : un plan vert servant de sol, passant par (0,-5,0) et avec une normale vers le haut +pl 0,-5,0 0,1,0 100,55,0 + +# Cylinder : un cylindre bleu placé à (10,0,0), avec un axe vertical (0,1,0), +# un diamètre de 8 et une hauteur de 20 +cy 10,0,0 0.5,0,0 8 20 0,0,255 +cy 10,0,0 0,1,0 8 20 0,0,255 + diff --git a/frame.c b/frame.c index f0cb924..2e8fc9e 100644 --- a/frame.c +++ b/frame.c @@ -6,16 +6,16 @@ /* By: yantoine +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/17 19:30:45 by yantoine #+# #+# */ -/* Updated: 2025/02/17 19:30:59 by yantoine ### ########.fr */ +/* Updated: 2025/02/17 21:55:36 by yantoine ### ########.fr */ /* */ /* ************************************************************************** */ #include "miniRT.h" -int update_frame(t_app *app) +int update_frame(t_app *app, t_scene scene) { update_camera(app); - render_scene(app); + render_scene(app, scene); mlx_put_image_to_window(app->mlx, app->win, app->img, 0, 0); return (0); } diff --git a/ft_atof.c b/ft_atof.c new file mode 100644 index 0000000..011dda8 --- /dev/null +++ b/ft_atof.c @@ -0,0 +1,44 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_atof.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: yantoine +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/02/17 21:19:17 by yantoine #+# #+# */ +/* Updated: 2025/02/17 21:20:13 by yantoine ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "miniRT.h" + +float ft_atof(char *str) +{ + float res; + float dec; + int sign; + + res = 0; + dec = 0; + sign = 1; + if (*str == '-') + { + sign = -1; + str++; + } + while (*str >= '0' && *str <= '9') + { + res = res * 10 + *str - '0'; + str++; + } + if (*str == '.') + { + str++; + while (*str >= '0' && *str <= '9') + { + dec = dec * 10 + *str - '0'; + str++; + } + } + return (sign * (res + dec / pow(10, ft_strlen(str)))); +} diff --git a/main.c b/main.c index 7ed4719..305406f 100644 --- a/main.c +++ b/main.c @@ -6,7 +6,7 @@ /* By: yantoine +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/17 19:54:03 by yantoine #+# #+# */ -/* Updated: 2025/02/17 19:58:12 by yantoine ### ########.fr */ +/* Updated: 2025/02/17 22:09:13 by yantoine ### ########.fr */ /* */ /* ************************************************************************** */ @@ -75,6 +75,7 @@ int main(int argc, char **argv) { t_app app; + ft_bzero(&app, sizeof(t_app)); init_app_config(&app, argc, argv); if (init_mlx_and_image(&app)) return (1); diff --git a/makefile b/makefile new file mode 100644 index 0000000..f30115c --- /dev/null +++ b/makefile @@ -0,0 +1,45 @@ +NAME = miniRT + +MINILIBX = minilibx-linux/libmlx.a +LIBFT = libft/libft.a + +SRC = $(wildcard *.c) +DIR_OBJ = obj +OBJ = $(addprefix $(DIR_OBJ)/, $(notdir $(SRC:.c=.o))) + +CC = cc +CFLAGS = -fsanitize=address -g3 -Wall -Wextra -Werror +INCLUDES = -I. -Ilibft -Iminilibx-linux +LDFLAGS = -Llibft -Lminilibx-linux +LDLIBS = -lft -lmlx -lXext -lX11 -lm -lbsd + +$(NAME): $(OBJ) $(LIBFT) $(MINILIBX) + $(CC) $(CFLAGS) $(LDFLAGS) -o $(NAME) $(OBJ) $(LDLIBS) + +$(DIR_OBJ)/%.o: %.c | $(DIR_OBJ) + $(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@ + +$(DIR_OBJ): + mkdir -p $(DIR_OBJ) + +$(LIBFT): + @make -C libft all + +$(MINILIBX): + @make -C minilibx-linux + +all: $(NAME) + +clean: + @make -C libft clean + @rm -rf $(DIR_OBJ) + +fclean: clean + @rm -rf $(NAME) + @make -C libft fclean + @make -C minilibx-linux clean + +re: fclean all + +.PHONY: all clean fclean re + diff --git a/miniRT.h b/miniRT.h index 0380308..74c5f8a 100644 --- a/miniRT.h +++ b/miniRT.h @@ -6,7 +6,7 @@ /* By: yantoine +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/13 20:02:36 by yantoine #+# #+# */ -/* Updated: 2025/02/17 19:53:54 by yantoine ### ########.fr */ +/* Updated: 2025/02/17 21:55:55 by yantoine ### ########.fr */ /* */ /* ************************************************************************** */ @@ -14,13 +14,15 @@ # define MINIRT_H # include -#include "mlx.h" # include # include # include # include +# include +# include "get_next_line.h" # include "libft.h" # include "float.h" +# include "mlx.h" // ----- Taille ecran ---- # define WIDTH 320 @@ -34,83 +36,6 @@ # define MAX_AMBIENT 1 # define MAX_CAMERA 1 -// ----- 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 move_speed; - float rot_speed; - float mouse_sens; - t_vec3 cam_pos; - t_vec3 cam_dir; - t_vec3 right; - t_vec3 cam_up; - float fov; - float yaw; - float pitch; -} 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_vec3 ray_dir; - t_vec3 color; - unsigned char r; - unsigned char g; - unsigned char b; -} t_calc; - // ----- Espace 3d typedef struct s_vec3 { @@ -159,8 +84,8 @@ typedef struct s_light typedef struct s_ambient { - float ambient_ratio; - t_vec3 ambient_color; + float ratio; + t_vec3 color; } t_ambient; typedef struct s_camera @@ -183,13 +108,88 @@ typedef struct s_scene int numSpheres; int numPlanes; int numCylinders; + int numCamera; int numLights; int numAmbient; - const char *line_if_exit; - const int fd_if_exit; - const char **token_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 move_speed; + float rot_speed; + float mouse_sens; + t_vec3 cam_pos; + t_vec3 cam_dir; + t_vec3 right; + t_vec3 cam_up; + float fov; + float yaw; + float pitch; +} 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_calc; + // Calcul de vecteur t_vec3 vec3_add(t_vec3 a, t_vec3 b); t_vec3 vec3_sub(t_vec3 a, t_vec3 b); @@ -203,29 +203,32 @@ t_vec3 vec3_mul(t_vec3 a, t_vec3 b); // Config de scene t_scene create_scene(void); t_scene load_config(const char *filename); -t_scene parsing_ambiant(const char *line, t_scene scene); -t_scene parsing_camera(const char *line, t_scene scene); -t_scene parsing_light(const char *line, t_scene scene); -t_scene parsing_sphere(const char *line, t_scene scene); -t_scene parsing_plane(const char *line, t_scene scene); -t_scene parsing_cylindre(const char *line, t_scene scene); +t_scene parsing_ambiant(t_scene scene); +t_scene parsing_camera(t_scene scene); +t_scene parsing_light(t_scene scene); +t_scene parsing_sphere(t_scene scene); +t_scene parsing_plane(t_scene scene); +t_scene parsing_cylindre(t_scene scene); 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 -inline 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 -inline int check_tokens(char **tokens, const int to_test, int expected); -inline 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(Ray ray, Cylinder cy, t_vec3 *hitNormal); -float intersectPlane(Ray ray, Plane p, t_vec3 *hitNormal); -float intersectSphere(Ray ray, Sphere s, t_vec3 *hitNormal); -bool isInShadow(t_vec3 hitPoint, t_vec3 lightPos); +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); @@ -234,6 +237,12 @@ 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 render_scene(t_app *app, t_scene scene); +int update_frame(t_app *app, t_scene scene); + +// Array +int ft_arraylen(char **array); +void ft_free_array(char **array); +// Conversion +float ft_atof(char *str); #endif diff --git a/minilibx-linux b/minilibx-linux new file mode 160000 index 0000000..7dc53a4 --- /dev/null +++ b/minilibx-linux @@ -0,0 +1 @@ +Subproject commit 7dc53a411a7d4ae286c60c6229bd1e395b0efb82 diff --git a/parsing_ambiant.c b/parsing_ambiant.c index f928de4..494c09e 100644 --- a/parsing_ambiant.c +++ b/parsing_ambiant.c @@ -6,19 +6,21 @@ /* By: yantoine +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/14 18:04:39 by yantoine #+# #+# */ -/* Updated: 2025/02/14 20:52:08 by yantoine ### ########.fr */ +/* Updated: 2025/02/17 21:53:34 by yantoine ### ########.fr */ /* */ /* ************************************************************************** */ #include "miniRT.h" -t_scene parsing_ambiant(const char *line, t_scene scene) +t_scene parsing_ambiant(t_scene scene) { - const char **tokens = get_tokens_secure(scene, scene.numAmbient, MAX_AMBIENT, 3); + char **tokens; + + tokens = get_tokens_secure(scene, scene.numAmbient, MAX_AMBIENT, 3); scene.token_if_exit = tokens; - scene.ambient.ambient_ratio = ft_atof(tokens[1]); - scene.ambient.ambient_color = parse_color(tokens[2], scene); + scene.ambient.ratio = ft_atof(tokens[1]); + scene.ambient.color = parse_color(tokens[2], scene); ft_free_array(tokens); scene.numAmbient++; return (scene); diff --git a/parsing_camera.c b/parsing_camera.c index f8d4c0c..33e321d 100644 --- a/parsing_camera.c +++ b/parsing_camera.c @@ -6,21 +6,23 @@ /* By: yantoine +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/14 20:02:29 by yantoine #+# #+# */ -/* Updated: 2025/02/15 19:43:52 by yantoine ### ########.fr */ +/* Updated: 2025/02/17 21:24:12 by yantoine ### ########.fr */ /* */ /* ************************************************************************** */ #include "miniRT.h" -t_scene parsing_camera(const char *line, t_scene scene) +t_scene parsing_camera(t_scene scene) { - const char **tokens = get_tokens_secure(scene, scene.numCamera, MAX_CAMERA, 4); + char **tokens; + + tokens = get_tokens_secure(scene, scene.numCamera, MAX_CAMERA, 4); scene.token_if_exit = tokens; scene.camera.camPos = parse_vector(tokens[1], scene); scene.camera.camDir = parse_vector_normalize(tokens[2], scene); scene.camera.fov = ft_atof(tokens[3]); - scene.camera.yaw = atan2f(camDir.x, -camDir.z); - scene.camera.pitch = asinf(camDir.y); + scene.camera.yaw = atan2f(scene.camera.camDir.x, -scene.camera.camDir.z); + scene.camera.pitch = asinf(scene.camera.camDir.y); ft_free_array(tokens); scene.numCamera++; return (scene); diff --git a/parsing_color.c b/parsing_color.c index 850218e..2e5522d 100644 --- a/parsing_color.c +++ b/parsing_color.c @@ -6,7 +6,7 @@ /* By: yantoine +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/14 20:05:49 by yantoine #+# #+# */ -/* Updated: 2025/02/15 19:23:20 by yantoine ### ########.fr */ +/* Updated: 2025/02/17 21:25:34 by yantoine ### ########.fr */ /* */ /* ************************************************************************** */ @@ -28,21 +28,22 @@ static inline int range_is_ok(char **token_color) t_vec3 parse_color(const char *token, t_scene scene) { - const char **token_color = ft_split(token, ','); + char **token_color; t_vec3 color; + token_color = ft_split(token, ','); if (!check_tokens(token_color, 3) || !range_is_ok(token_color)) { - ft_free_array(tokens_color); + ft_free_array(token_color); ft_free_array(scene.token_if_exit); ft_putendl_fd("error", 2); free(scene.line_if_exit); - close(scene.fd); + close(scene.fd_if_exit); exit(1); } color.x = ft_atof(token_color[0]) / 255; color.y = ft_atof(token_color[1]) / 255; color.z = ft_atof(token_color[2]) / 255; - ft_free_array(tokens_color); + ft_free_array(token_color); return (color); } diff --git a/parsing_cylinder.c b/parsing_cylinder.c index cdf4b87..17cc608 100644 --- a/parsing_cylinder.c +++ b/parsing_cylinder.c @@ -6,7 +6,7 @@ /* By: yantoine +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/15 19:54:13 by yantoine #+# #+# */ -/* Updated: 2025/02/17 18:55:52 by yantoine ### ########.fr */ +/* Updated: 2025/02/17 22:02:43 by yantoine ### ########.fr */ /* */ /* ************************************************************************** */ @@ -92,14 +92,16 @@ float intersectCylinder(Ray ray, Cylinder cy, t_vec3 *hitNormal) return calc.t_final; }*/ -t_scene parsing_cylinder(const char *line, t_scene scene) +t_scene parsing_cylindre(t_scene scene) { - const char **tokens = get_tokens_secure(scene, scene.numCylinders, MAX_CYLINDERS, 6); + 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].radius = parse_float(tokens[3], scene); - scene.cylinders[scene.numCylinders].height = parse_float(tokens[4], 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); ft_free_array(tokens); scene.numCylinders++; diff --git a/parsing_cylinder_utils.c b/parsing_cylinder_utils.c index 5312ee1..d9fd320 100644 --- a/parsing_cylinder_utils.c +++ b/parsing_cylinder_utils.c @@ -6,14 +6,14 @@ /* By: yantoine +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/17 18:54:45 by yantoine #+# #+# */ -/* Updated: 2025/02/17 18:54:46 by yantoine ### ########.fr */ +/* Updated: 2025/02/17 21:28:56 by yantoine ### ########.fr */ /* */ /* ************************************************************************** */ #include "miniRT.h" // Initialise les variables de calcul et les coefficients du polynôme d'intersection -static int init_intersection(Ray ray, 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->v = cy.axis; @@ -34,7 +34,7 @@ static int init_intersection(Ray ray, Cylinder cy, t_calc *calc) { } // Calcule l'intersection sur la surface latérale du cylindre -static void compute_side_intersection(Ray ray, 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->y = calc->oc_dot_v + calc->t0 * calc->d_dot_v; @@ -49,7 +49,7 @@ static void compute_side_intersection(Ray ray, Cylinder cy, t_calc *calc) { } // Calcule l'intersection sur les capuchons supérieur et inférieur -static void compute_cap_intersection(Ray ray, 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_bot = ((-cy.height / 2.0f) - calc->oc_dot_v) / calc->d_dot_v; @@ -83,7 +83,7 @@ static float select_final_intersection(t_calc *calc) { } // Calcule la normale au point d'intersection -static void compute_hit_normal(Ray ray, Cylinder cy, t_calc *calc, t_vec3 *hitNormal) { +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); @@ -96,11 +96,11 @@ static void compute_hit_normal(Ray ray, Cylinder cy, t_calc *calc, t_vec3 *hitNo } // Fonction principale d'intersection du cylindre -float intersectCylinder(Ray ray, 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) return -1; - compute_side_intersection(ray, cy, &calc); + compute_side_intersection(cy, &calc); compute_cap_intersection(ray, cy, &calc); if (select_final_intersection(&calc) < 0) return -1; diff --git a/parsing_light.c b/parsing_light.c index f175fff..9b06b15 100644 --- a/parsing_light.c +++ b/parsing_light.c @@ -6,18 +6,20 @@ /* By: yantoine +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/15 19:39:08 by yantoine #+# #+# */ -/* Updated: 2025/02/15 19:44:19 by yantoine ### ########.fr */ +/* Updated: 2025/02/17 21:29:55 by yantoine ### ########.fr */ /* */ /* ************************************************************************** */ -#include "minRT.h" +#include "miniRT.h" -t_scene parsing_light(const char *line, t_scene scene) +t_scene parsing_light(t_scene scene) { - const char **tokens = get_tokens_secure(scene, scene.numLights, MAX_LIGHTS, 4); + char **tokens; + + tokens = get_tokens_secure(scene, scene.numLights, MAX_LIGHTS, 4); scene.token_if_exit = tokens; scene.lights[scene.numLights].pos = parse_vector(tokens[1], scene); - scene.lights[scene.numLights].brightness = ft_atof(tokens[2], scene); + scene.lights[scene.numLights].brightness = ft_atof(tokens[2]); scene.lights[scene.numLights].color = parse_color(tokens[3], scene); ft_free_array(tokens); scene.numLights++; diff --git a/parsing_plane.c b/parsing_plane.c index efe6cce..a9b518c 100644 --- a/parsing_plane.c +++ b/parsing_plane.c @@ -6,15 +6,17 @@ /* By: yantoine +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/15 19:49:41 by yantoine #+# #+# */ -/* Updated: 2025/02/17 17:49:28 by yantoine ### ########.fr */ +/* Updated: 2025/02/17 21:30:47 by yantoine ### ########.fr */ /* */ /* ************************************************************************** */ #include "miniRT.h" -t_scene parsing_plane(const char *line, t_scene scene) +t_scene parsing_plane(t_scene scene) { - const char **tokens = get_tokens_secure(scene, scene.numPlanes, MAX_PLANES, 4); + char **tokens; + + 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); @@ -24,7 +26,7 @@ t_scene parsing_plane(const char *line, t_scene scene) return (scene); } -float intersectPlane(Ray ray, Plane p, t_vec3 *hitNormal) +float intersectPlane(t_ray ray, t_plane p, t_vec3 *hitNormal) { float denom; float t; diff --git a/parsing_sphere.c b/parsing_sphere.c index 159ede0..10f0224 100644 --- a/parsing_sphere.c +++ b/parsing_sphere.c @@ -6,33 +6,35 @@ /* By: yantoine +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/15 19:46:16 by yantoine #+# #+# */ -/* Updated: 2025/02/17 17:31:42 by yantoine ### ########.fr */ +/* Updated: 2025/02/17 21:31:36 by yantoine ### ########.fr */ /* */ /* ************************************************************************** */ #include "miniRT.h" -t_scene parsing_sphere(const char *line, t_scene scene) +t_scene parsing_sphere(t_scene scene) { - const char **tokens = get_tokens_secure(scene, scene.numSpheres, MAX_SPHERES, 4); + char **tokens; + + tokens = get_tokens_secure(scene, scene.numSpheres, MAX_SPHERES, 4); scene.token_if_exit = tokens; scene.spheres[scene.numSpheres].center = parse_vector(tokens[1], scene); - scene.spheres[scene.numSpheres].radius = ft_atof(tokens[2], scene) / 2.0f; + scene.spheres[scene.numSpheres].radius = ft_atof(tokens[2]) / 2.0f; scene.spheres[scene.numSpheres].color = parse_color(tokens[3], scene); ft_free_array(tokens); scene.numSpheres++; return (scene); } -float intersectSphere(Ray ray, Sphere s, t_vec3 *hitNormal) +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); - c = vec3_dot(calc.oc, calc.oc) - s.radius * s.radius; - calc.disc = calc.b * calc.b - 4 * calc.a * c; + calc.c = vec3_dot(calc.oc, calc.oc) - s.radius * s.radius; + calc.disc = calc.b * calc.b - 4 * calc.a * calc.c; if (calc.disc < 0) return (-1); calc.sqrtDisc = sqrtf(calc.disc); diff --git a/parsing_utils.c b/parsing_utils.c index bbfa1af..0fa341c 100644 --- a/parsing_utils.c +++ b/parsing_utils.c @@ -6,24 +6,24 @@ /* By: yantoine +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/14 20:23:21 by yantoine #+# #+# */ -/* Updated: 2025/02/14 20:48:49 by yantoine ### ########.fr */ +/* Updated: 2025/02/17 21:34:12 by yantoine ### ########.fr */ /* */ /* ************************************************************************** */ #include "miniRT.h" - -inline 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) { - const int result_if_max = check_if_max(scene, numObject, numObjectMax); - const char **tokens = ft_split(scene.line_if_exit, ' '); + char **tokens; + check_if_max(scene, numObject, numObjectMax); + tokens = ft_split(scene.line_if_exit, ' '); if (!check_tokens(tokens, supposed_nb_token)) { ft_free_array(tokens); ft_putendl_fd("error", 2); free(scene.line_if_exit); - close(scene.fd); + close(scene.fd_if_exit); exit(1); } return (tokens); diff --git a/parsing_vector.c b/parsing_vector.c index 9ed280f..d90cfa8 100644 --- a/parsing_vector.c +++ b/parsing_vector.c @@ -6,7 +6,7 @@ /* By: yantoine +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/15 19:16:01 by yantoine #+# #+# */ -/* Updated: 2025/02/15 19:36:24 by yantoine ### ########.fr */ +/* Updated: 2025/02/17 21:35:12 by yantoine ### ########.fr */ /* */ /* ************************************************************************** */ @@ -28,9 +28,10 @@ static inline int range_is_ok(char **token_vector) t_vec3 parse_vector(const char *token, t_scene scene) { - const char **token_vector = ft_split(token, ','); + char **token_vector; t_vec3 vector; + token_vector = ft_split(token, ','); if (!check_tokens(token_vector, 3) || !range_is_ok(token_vector)) { ft_free_array(token_vector); @@ -43,7 +44,7 @@ t_vec3 parse_vector(const char *token, t_scene scene) vector.x = ft_atof(token_vector[0]); vector.y = ft_atof(token_vector[1]); vector.z = ft_atof(token_vector[2]); - ft_free_array(tokens_vector); + ft_free_array(token_vector); return (vector); } diff --git a/raytracer_formatted.c b/raytracer_formatted.c deleted file mode 100644 index 89212f8..0000000 --- a/raytracer_formatted.c +++ /dev/null @@ -1,681 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* raytracer_formatted.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: yantoine +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2025/02/13 19:56:17 by yantoine #+# #+# */ -/* Updated: 2025/02/17 17:18:17 by yantoine ### ########.fr */ -/* */ -/* ************************************************************************** */ - -/* - *Raytracer interactif en un seul fichier C avec lecture d'un fichier de configuration (.rt) - * - *Compilation (exemple sous Linux) : - * gcc raytracer.c -lSDL2 -lm -O2 -o raytracer - * - *Utilisation : - * ./raytracer config.rt - *Si aucun fichier n'est passé en argument, une scène par défaut est utilisée. - */ - - -// Ambient et caméra (JE GARDE POUR FAIRE LA FONCTION UN EXEMPLE) - -float ambient_ratio = 0.1f; -t_vec3 ambient_color = {0.1f, 0.1f, 0.1f}; -t_vec3 camPos = {0.0f, 0.0f, 0.0f}; -t_vec3 camDir = {0.0f, 0.0f, -1.0f}; -float fov = 90.0f; -float yaw = 0.0f;// vue de gauche a droite -float pitch = 0.0f; // vue de haut en bas en radians - -// ----- Parsing du fichier de configuration ----- -void load_config(const char *filename) -{ -//---- Jlaisse pour contextualiser ----- - while (fgets(line, sizeof(line), fp)) - { - // Ignore les lignes vides ou commençant par # - if (line[0] == '\n' || line[0] == '#') - continue ; - // Ambient lighting: A ratio R,G,B - if (line[0] == 'A') - { - int r, g, b; - if (sscanf(line, "A %f %d,%d,%d", &ratio, &r, &g, &b) == 4) - { - ambient_ratio = ratio; - ambient_color = (t_vec3){r / 255.0f, g / 255.0f, b / 255.0f}; - printf("Ambiance : ratio=%.2f, color=(%d,%d,%d)\n", ratio, r, g, - b); - } - } - // Camera: C pos_x,pos_y,pos_z norm_x,norm_y,norm_z FOV - else if (line[0] == 'C') - { - float px, py, pz, nx, ny, nz, f; - if (sscanf(line, "C %f,%f,%f %f,%f,%f %f", &px, &py, &pz, &nx, &ny, - &nz, &f) == 7) - { - camPos = (t_vec3){px, py, pz}; - camDir = vec3_normalize((t_vec3){nx, ny, nz}); - fov = f; - yaw = atan2f(camDir.x, -camDir.z); - pitch = asinf(camDir.y); - printf("Camera : pos=(%.2f,%.2f,%.2f), dir=(%.2f,%.2f,%.2f), - fov=%.2f\n", px, py, pz, nx, ny, nz, f); - } - } - // Light: L pos_x,pos_y,pos_z brightness R,G,B - else if (line[0] == 'L') - { - float lx, ly, lz, bright; - int r, g, b; - if (sscanf(line, "L %f,%f,%f %f %d,%d,%d", &lx, &ly, &lz, &bright, - &r, &g, &b) == 7) - { - if (numLights < MAX_LIGHTS) - { - lights[numLights].pos = (t_vec3){lx, ly, lz}; - lights[numLights].brightness = bright; - lights[numLights].color = (t_vec3){r / 255.0f, g / 255.0f, b - / 255.0f}; - numLights++; - printf("Light : pos=(%.2f,%.2f,%.2f), bright=%.2f, - color=(%d,%d,%d)\n", lx, ly, lz, bright, r, g, b); - } - } - } - // Sphere: sp pos_x,pos_y,pos_z diameter R,G,B - else if (strncmp(line, "sp", 2) == 0) - { - float cx, cy, cz, diam; - int r, g, b; - if (sscanf(line, "sp %f,%f,%f %f %d,%d,%d", &cx, &cy, &cz, &diam, - &r, &g, &b) == 7) - { - if (numSpheres < MAX_SPHERES) - { - spheres[numSpheres].center = (t_vec3){cx, cy, cz}; - spheres[numSpheres].radius = diam / 2.0f; - spheres[numSpheres].color = (t_vec3){r / 255.0f, g / 255.0f, - b / 255.0f}; - numSpheres++; - printf("Sphere : center=(%.2f,%.2f,%.2f), diam=%.2f, - color=(%d,%d,%d)\n", cx, cy, cz, diam, r, g, b); - } - } - } - // Plane: pl pos_x,pos_y,pos_z norm_x,norm_y,norm_z R,G,B - else if (strncmp(line, "pl", 2) == 0) - { - float px, py, pz, nx, ny, nz; - int r, g, b; - // Correction : nous attendons 9 éléments (3 + 3 + 3) - if (sscanf(line, "pl %f,%f,%f %f,%f,%f %d,%d,%d", &px, &py, &pz, - &nx, &ny, &nz, &r, &g, &b) == 9) - { - if (numPlanes < MAX_PLANES) - { - planes[numPlanes].point = (t_vec3){px, py, pz}; - planes[numPlanes].normal = vec3_normalize((t_vec3){nx, ny, - nz}); - planes[numPlanes].color = (t_vec3){r / 255.0f, g / 255.0f, b - / 255.0f}; - numPlanes++; - printf("Plane : point=(%.2f,%.2f,%.2f), - normal=(%.2f,%.2f,%.2f), color=(%d,%d,%d)\n", px, py, - pz, nx, ny, nz, r, g, b); - } - } - } - // Cylinder: cy pos_x,pos_y,pos_z axis_x,axis_y,axis_z diameter height R,G,B - else if (strncmp(line, "cy", 2) == 0) - { - float cx, cy, cz, ax, ay, az, diam, height; - int r, g, b; - // Correction : nous attendons 11 éléments (3 + 3 + 1 + 1 + 3) - if (sscanf(line, "cy %f,%f,%f %f,%f,%f %f %f %d,%d,%d", &cx, &cy, - &cz, &ax, &ay, &az, &diam, &height, &r, &g, &b) == 11) - { - if (numCylinders < MAX_CYLINDERS) - { - cylinders[numCylinders].center = (t_vec3){cx, cy, cz}; - cylinders[numCylinders].axis = vec3_normalize((t_vec3){ax, - ay, az}); - cylinders[numCylinders].radius = diam / 2.0f; - cylinders[numCylinders].height = height; - cylinders[numCylinders].color = (t_vec3){r / 255.0f, g - / 255.0f, b / 255.0f}; - numCylinders++; - printf("Cylinder : center=(%.2f,%.2f,%.2f), - axis=(%.2f,%.2f,%.2f), diam=%.2f, height=%.2f, - color=(%d,%d,%d)\n", cx, cy, cz, ax, ay, az, diam, - height, r, g, b); - } - } - } - } - fclose(fp); -} - -// ----- Fonctions d'intersection ----- -float intersectSphere(Ray ray, Sphere s, t_vec3 *hitNormal) -{ - - oc = vec3_sub(ray.origin, s.center); - a = vec3_dot(ray.dir, ray.dir); - b = 2.0f * vec3_dot(oc, ray.dir); - c = vec3_dot(oc, oc) - s.radius * s.radius; - disc = b * b - 4 * a * c; - if (disc < 0) - return (-1); - sqrtDisc = sqrtf(disc); - t0 = (-b - sqrtDisc) / (2 * a); - t1 = (-b + sqrtDisc) / (2 * a); - t = (t0 > 1e-3f) ? t0 : t1; - if (t < 1e-3f) - return (-1); - hitPoint = vec3_add(ray.origin, vec3_scale(ray.dir, t)); - *hitNormal = vec3_normalize(vec3_sub(hitPoint, s.center)); - return (t); -} - -float intersectPlane(Ray ray, Plane p, t_vec3 *hitNormal) -{ - float denom; - float t; - - denom = vec3_dot(p.normal, ray.dir); - if (fabs(denom) < 1e-6f) - return (-1); - t = vec3_dot(vec3_sub(p.point, ray.origin), p.normal) / denom; - if (t < 1e-3f) - return (-1); - *hitNormal = p.normal; - return (t); -} - -// Intersection d'un cylindre orienté arbitrairement (version simplifiée) -float intersectCylinder(Ray ray, Cylinder cy, t_vec3 *hitNormal) -{ - t_vec3 d; - t_vec3 oc; - t_vec3 v; - float d_dot_v; - float oc_dot_v; - t_vec3 d_perp; - t_vec3 oc_perp; - float a; - float b; - float c; - float disc; - float sqrtDisc; - float t0; - float t1; - float t_side; - float y; - float y; - float t_cap; - float t_bot; - t_vec3 p; - t_vec3 cp; - float dist; - float t_top; - t_vec3 p; - t_vec3 cp; - float dist; - float t_final; - t_vec3 hitPoint; - t_vec3 cp; - float proj; - t_vec3 n; - - d = ray.dir; - oc = vec3_sub(ray.origin, cy.center); - v = cy.axis; - d_dot_v = vec3_dot(d, v); - oc_dot_v = vec3_dot(oc, v); - d_perp = vec3_sub(d, vec3_scale(v, d_dot_v)); - oc_perp = vec3_sub(oc, vec3_scale(v, oc_dot_v)); - a = vec3_dot(d_perp, d_perp); - b = 2 * vec3_dot(d_perp, oc_perp); - c = vec3_dot(oc_perp, oc_perp) - cy.radius * cy.radius; - disc = b * b - 4 * a * c; - if (disc < 0) - return (-1); - sqrtDisc = sqrtf(disc); - t0 = (-b - sqrtDisc) / (2 * a); - t1 = (-b + sqrtDisc) / (2 * a); - t_side = -1; - if (t0 > 1e-3f) - { - y = oc_dot_v + t0 * d_dot_v; - if (fabs(y) <= cy.height / 2.0f) - t_side = t0; - } - if (t_side < 0 && t1 > 1e-3f) - { - y = oc_dot_v + t1 * d_dot_v; - if (fabs(y) <= cy.height / 2.0f) - t_side = t1; - } - t_cap = -1; - if (fabs(d_dot_v) > 1e-6f) - { - t_bot = ((-cy.height / 2.0f) - oc_dot_v) / d_dot_v; - if (t_bot > 1e-3f) - { - p = vec3_add(ray.origin, vec3_scale(d, t_bot)); - cp = vec3_sub(p, cy.center); - dist = vec3_length(vec3_sub(cp, vec3_scale(v, vec3_dot(cp, v)))); - if (dist <= cy.radius) - t_cap = t_bot; - } - t_top = ((cy.height / 2.0f) - oc_dot_v) / d_dot_v; - if (t_top > 1e-3f) - { - p = vec3_add(ray.origin, vec3_scale(d, t_top)); - cp = vec3_sub(p, cy.center); - dist = vec3_length(vec3_sub(cp, vec3_scale(v, vec3_dot(cp, v)))); - if (dist <= cy.radius && (t_cap < 0 || t_top < t_cap)) - t_cap = t_top; - } - } - t_final = -1; - if (t_side > 1e-3f && t_cap > 1e-3f) - t_final = (t_side < t_cap) ? t_side : t_cap; - else if (t_side > 1e-3f) - t_final = t_side; - else - t_final = t_cap; - if (t_final < 1e-3f) - return (-1); - hitPoint = vec3_add(ray.origin, vec3_scale(d, t_final)); - cp = vec3_sub(hitPoint, cy.center); - proj = vec3_dot(cp, v); - if (fabs(proj) < cy.height / 2.0f - 1e-3f) - { - n = vec3_sub(cp, vec3_scale(v, proj)); - *hitNormal = vec3_normalize(n); - } - else - { - *hitNormal = (proj > 0) ? v : vec3_scale(v, -1); - } - return t_final; -} - -// ----- Test d'ombre ----- -bool isInShadow(t_vec3 hitPoint, t_vec3 lightPos) -{ - t_vec3 toLight; - float maxT; - t_vec3 L; - const float epsilon = 1e-3f; - Ray shadowRay; - t_vec3 dummy; - float t; - - toLight = vec3_sub(lightPos, hitPoint); - maxT = vec3_length(toLight); - L = vec3_normalize(toLight); - shadowRay = {vec3_add(hitPoint, vec3_scale(L, epsilon)), L}; - for (int i = 0; i < numSpheres; i++) - { - t = intersectSphere(shadowRay, spheres[i], &dummy); - if (t > epsilon && t < maxT) - return true; - } - for (int i = 0; i < numPlanes; i++) - { - t = intersectPlane(shadowRay, planes[i], &dummy); - if (t > epsilon && t < maxT) - return true; - } - for (int i = 0; i < numCylinders; i++) - { - t = intersectCylinder(shadowRay, cylinders[i], &dummy); - if (t > epsilon && t < maxT) - return true; - } - return false; -} - -// ----- Lancer de rayon (ray tracing) ----- -t_vec3 trace(Ray ray) -{ - float tMin; - t_vec3 hitNormal; - t_vec3 objColor; - bool hitSomething; - float t; - t_vec3 n; - t_vec3 n; - t_vec3 n; - t_vec3 hitPoint; - t_vec3 finalColor; - Light light; - t_vec3 L; - float diff; - t_vec3 viewDir; - t_vec3 halfDir; - float spec; - - tMin = 1e9; - hitNormal = {0, 0, 0}; - objColor = {0, 0, 0}; - hitSomething = false; - for (int i = 0; i < numSpheres; i++) - { - t = intersectSphere(ray, spheres[i], &n); - if (t > 1e-3f && t < tMin) - { - tMin = t; - hitNormal = n; - objColor = spheres[i].color; - hitSomething = true; - } - } - for (int i = 0; i < numPlanes; i++) - { - t = intersectPlane(ray, planes[i], &n); - if (t > 1e-3f && t < tMin) - { - tMin = t; - hitNormal = n; - objColor = planes[i].color; - hitSomething = true; - } - } - for (int i = 0; i < numCylinders; i++) - { - t = intersectCylinder(ray, cylinders[i], &n); - if (t > 1e-3f && t < tMin) - { - tMin = t; - hitNormal = n; - objColor = cylinders[i].color; - hitSomething = true; - } - } - if (hitSomething) - { - hitPoint = vec3_add(ray.origin, vec3_scale(ray.dir, tMin)); - finalColor = vec3_scale(objColor, ambient_ratio); - for (int i = 0; i < numLights; i++) - { - light = lights[i]; - L = vec3_normalize(vec3_sub(light.pos, hitPoint)); - if (isInShadow(hitPoint, light.pos)) - continue ; - diff = fmaxf(0.0f, vec3_dot(hitNormal, L)); - viewDir = vec3_normalize(vec3_sub(camPos, hitPoint)); - halfDir = vec3_normalize(vec3_add(L, viewDir)); - spec = powf(fmaxf(0.0f, vec3_dot(hitNormal, halfDir)), 32.0f); - finalColor = vec3_add(finalColor, vec3_scale(vec3_mul(objColor, - light.color), diff * light.brightness)); - finalColor = vec3_add(finalColor, vec3_scale((t_vec3){1, 1, 1}, spec - * light.brightness)); - } - if (finalColor.x > 1.0f) - finalColor.x = 1.0f; - if (finalColor.y > 1.0f) - finalColor.y = 1.0f; - if (finalColor.z > 1.0f) - finalColor.z = 1.0f; - return finalColor; - } - return (t_vec3){0.2f, 0.7f, 1.0f}; // Fond (ciel) -} - -// ----- Main ----- -int main(int argc, char *argv[]) -{ - SDL_Window *window; - SDL_Renderer *renderer; - SDL_Texture *texture; - Uint32 *pixels; - bool running; - SDL_Event event; - const float moveSpeed = 0.5f; - const float rotSpeed = 0.03f; - const float mouseSensitivity = 0.002f; - bool key_w = false, key_s = false, key_a = false, key_d; - bool key_left = false, key_right = false, key_up = false, - key_down; - t_vec3 right; - t_vec3 camUp; - float ndc_x; - float ndc_y; - float aspect; - float scale; - float screen_x; - float screen_y; - t_vec3 rayDir; - Ray ray; - t_vec3 color; - Uint8 r; - Uint8 g; - Uint8 b; - - // Chargement de la config si un fichier est passé en argument - if (argc > 1) - load_config(argv[1]); - // Scène par défaut si aucune config n'a été chargée - if (numSpheres == 0 && numPlanes == 0 && numCylinders == 0 - && numLights == 0) - { - spheres[0].center = (t_vec3){0, 0, 0}; - spheres[0].radius = 1.0f; - spheres[0].color = (t_vec3){1, 0, 0}; - numSpheres = 1; - planes[0].point = (t_vec3){0, -5, 0}; - planes[0].normal = (t_vec3){0, 1, 0}; - planes[0].color = (t_vec3){0, 1, 0}; - numPlanes = 1; - cylinders[0].center = (t_vec3){10, 0, 0}; - cylinders[0].axis = (t_vec3){0, 1, 0}; - cylinders[0].radius = 4.0f; - cylinders[0].height = 20.0f; - cylinders[0].color = (t_vec3){0, 0, 1}; - numCylinders = 1; - lights[0].pos = (t_vec3){0, 50, 20}; - lights[0].brightness = 1.0f; - lights[0].color = (t_vec3){1, 1, 1}; - numLights = 1; - ambient_ratio = 0.3f; - ambient_color = (t_vec3){1, 1, 1}; - camPos = (t_vec3){0, 0, 20}; - camDir = vec3_normalize((t_vec3){0, 0, -1}); - fov = 70.0f; - yaw = atan2f(camDir.x, -camDir.z); - pitch = asinf(camDir.y); - } - if (SDL_Init(SDL_INIT_VIDEO) < 0) - { - fprintf(stderr, "Erreur SDL_Init: %s\n", SDL_GetError()); - return 1; - } - window = SDL_CreateWindow("Raytracer interactif", SDL_WINDOWPOS_CENTERED, - SDL_WINDOWPOS_CENTERED, WIDTH * 2, HEIGHT * 2, SDL_WINDOW_SHOWN); - if (!window) - { - fprintf(stderr, "Erreur SDL_CreateWindow: %s\n", SDL_GetError()); - SDL_Quit(); - return 1; - } - SDL_SetRelativeMouseMode(SDL_TRUE); - renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); - if (!renderer) - { - fprintf(stderr, "Erreur SDL_CreateRenderer: %s\n", SDL_GetError()); - SDL_DestroyWindow(window); - SDL_Quit(); - return 1; - } - texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, - SDL_TEXTUREACCESS_STREAMING, WIDTH, HEIGHT); - if (!texture) - { - fprintf(stderr, "Erreur SDL_CreateTexture: %s\n", SDL_GetError()); - SDL_DestroyRenderer(renderer); - SDL_DestroyWindow(window); - SDL_Quit(); - return 1; - } - pixels = malloc(WIDTH * HEIGHT * sizeof(Uint32)); - if (!pixels) - { - fprintf(stderr, "Erreur d'allocation mémoire.\n"); - SDL_DestroyTexture(texture); - SDL_DestroyRenderer(renderer); - SDL_DestroyWindow(window); - SDL_Quit(); - return 1; - } - running = true; - key_w = false, key_s = false, key_a = false, key_d = false; - key_left = false, key_right = false, key_up = false, key_down = false; - while (running) - { - while (SDL_PollEvent(&event)) - { - if (event.type == SDL_QUIT) - running = false; - else if (event.type == SDL_KEYDOWN) - { - switch (event.key.keysym.sym) - { - case SDLK_ESCAPE: - running = false; - break ; - case SDLK_w: - key_w = true; - break ; - case SDLK_s: - key_s = true; - break ; - case SDLK_a: - key_a = true; - break ; - case SDLK_d: - key_d = true; - break ; - case SDLK_LEFT: - key_left = true; - break ; - case SDLK_RIGHT: - key_right = true; - break ; - case SDLK_UP: - key_up = true; - break ; - case SDLK_DOWN: - key_down = true; - break ; - default: - break ; - } - } - else if (event.type == SDL_KEYUP) - { - switch (event.key.keysym.sym) - { - case SDLK_w: - key_w = false; - break ; - case SDLK_s: - key_s = false; - break ; - case SDLK_a: - key_a = false; - break ; - case SDLK_d: - key_d = false; - break ; - case SDLK_LEFT: - key_left = false; - break ; - case SDLK_RIGHT: - key_right = false; - break ; - case SDLK_UP: - key_up = false; - break ; - case SDLK_DOWN: - key_down = false; - break ; - default: - break ; - } - } - else if (event.type == SDL_MOUSEMOTION) - { - yaw += event.motion.xrel * mouseSensitivity; - pitch -= event.motion.yrel * mouseSensitivity; - } - } - if (key_left) - yaw -= rotSpeed; - if (key_right) - yaw += rotSpeed; - if (key_up) - pitch += rotSpeed; - if (key_down) - pitch -= rotSpeed; - if (pitch > 1.57f - 0.01f) - pitch = 1.57f - 0.01f; - if (pitch < -1.57f + 0.01f) - pitch = -1.57f + 0.01f; - camDir.x = cosf(pitch) * sinf(yaw); - camDir.y = sinf(pitch); - camDir.z = -cosf(pitch) * cosf(yaw); - camDir = vec3_normalize(camDir); - right = {cosf(yaw), 0, sinf(yaw)}; - right = vec3_normalize(right); - camUp = vec3_normalize(vec3_cross(right, camDir)); - if (key_w) - camPos = vec3_add(camPos, vec3_scale(camDir, moveSpeed)); - if (key_s) - camPos = vec3_sub(camPos, vec3_scale(camDir, moveSpeed)); - if (key_a) - camPos = vec3_sub(camPos, vec3_scale(right, moveSpeed)); - if (key_d) - camPos = vec3_add(camPos, vec3_scale(right, moveSpeed)); - for (int y = 0; y < HEIGHT; y++) - { - for (int x = 0; x < WIDTH; x++) - { - ndc_x = (x + 0.5f) / WIDTH; - ndc_y = (y + 0.5f) / HEIGHT; - aspect = (float)WIDTH / HEIGHT; - scale = tanf((fov * 0.5f) * (M_PI / 180.0f)); - screen_x = (2 * ndc_x - 1) * aspect * scale; - screen_y = (1 - 2 * ndc_y) * scale; - rayDir = vec3_add(camDir, vec3_add(vec3_scale(right, screen_x), - vec3_scale(camUp, screen_y))); - rayDir = vec3_normalize(rayDir); - ray = {camPos, rayDir}; - color = trace(ray); - r = (Uint8)(fminf(color.x, 1.0f) * 255); - g = (Uint8)(fminf(color.y, 1.0f) * 255); - b = (Uint8)(fminf(color.z, 1.0f) * 255); - pixels[y * WIDTH + x] = (255 << 24) | (r << 16) | (g << 8) | b; - } - } - SDL_UpdateTexture(texture, NULL, pixels, WIDTH * sizeof(Uint32)); - SDL_RenderClear(renderer); - SDL_RenderCopy(renderer, texture, NULL, NULL); - SDL_RenderPresent(renderer); - } - free(pixels); - SDL_DestroyTexture(texture); - SDL_DestroyRenderer(renderer); - SDL_DestroyWindow(window); - SDL_Quit(); - return 0; -} diff --git a/render.c b/render.c index 293566d..5000631 100644 --- a/render.c +++ b/render.c @@ -6,15 +6,18 @@ /* By: yantoine +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/17 19:24:30 by yantoine #+# #+# */ -/* Updated: 2025/02/17 19:52:46 by yantoine ### ########.fr */ +/* Updated: 2025/02/17 21:54:39 by yantoine ### ########.fr */ /* */ /* ************************************************************************** */ #include "miniRT.h" -static void render_pixel(t_app *app, int x, int y) +static void render_pixel(t_app *app, int x, int y, t_scene scene) { 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; @@ -28,14 +31,14 @@ static void render_pixel(t_app *app, int x, int y) calc.ray_dir = vec3_normalize(calc.ray_dir); calc.ray.origin = app->cam_pos; calc.ray.dir = calc.ray_dir; - calc.color = trace(calc.ray); - calc.r = (unsigned char)(fminf(calc.color.x, 1.0f) * 255); - calc.g = (unsigned char)(fminf(calc.color.y, 1.0f) * 255); - calc.b = (unsigned char)(fminf(calc.color.z, 1.0f) * 255); - app->pixels[y * app->win_width + x] = (255 << 24) | (calc.r << 16) | (calc.g << 8) | calc.b; + calc.color = trace(calc.ray, scene); + 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; } -void render_scene(t_app *app) +void render_scene(t_app *app, t_scene scene) { int y; int x; @@ -46,7 +49,7 @@ void render_scene(t_app *app) x = 0; while (x < app->win_width) { - render_pixel(app, x, y); + render_pixel(app, x, y, scene); x++; } y++; diff --git a/scene.c b/scene.c index d59a8c8..76d8149 100644 --- a/scene.c +++ b/scene.c @@ -6,7 +6,7 @@ /* By: yantoine +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/13 21:23:32 by yantoine #+# #+# */ -/* Updated: 2025/02/13 21:26:52 by yantoine ### ########.fr */ +/* Updated: 2025/02/17 21:39:27 by yantoine ### ########.fr */ /* */ /* ************************************************************************** */ @@ -16,6 +16,6 @@ t_scene create_scene(void) { t_scene scene; - scene = ft_bzero(sizeof(t_scene)); + ft_bzero(&scene, sizeof(t_scene)); return (scene); } diff --git a/shadows.c b/shadows.c index 3871d8f..77f4347 100644 --- a/shadows.c +++ b/shadows.c @@ -6,19 +6,19 @@ /* By: yantoine +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/17 18:58:42 by yantoine #+# #+# */ -/* Updated: 2025/02/17 19:03:01 by yantoine ### ########.fr */ +/* Updated: 2025/02/17 21:44:07 by yantoine ### ########.fr */ /* */ /* ************************************************************************** */ #include "miniRT.h" // Vérifie les intersections avec les sphères -static bool checkShadowSphere(const Ray shadowRay, float maxT, float epsilon) { +static bool checkShadowSphere(const t_ray shadowRay, float maxT, float epsilon, t_scene scene) { int i = 0; t_vec3 dummy; float t; - while (i < numSpheres) { - t = intersectSphere(shadowRay, spheres[i], &dummy); + while (i < scene.numSpheres) { + t = intersectSphere(shadowRay, scene.spheres[i], &dummy); if (t > epsilon && t < maxT) return true; i++; @@ -27,12 +27,12 @@ static bool checkShadowSphere(const Ray shadowRay, float maxT, float epsilon) { } // Vérifie les intersections avec les plans -static bool checkShadowPlane(const Ray shadowRay, float maxT, float epsilon) { +static bool checkShadowPlane(const t_ray shadowRay, float maxT, float epsilon, t_scene scene) { int i = 0; t_vec3 dummy; float t; - while (i < numPlanes) { - t = intersectPlane(shadowRay, planes[i], &dummy); + while (i < scene.numPlanes) { + t = intersectPlane(shadowRay, scene.planes[i], &dummy); if (t > epsilon && t < maxT) return true; i++; @@ -41,12 +41,12 @@ static bool checkShadowPlane(const Ray shadowRay, float maxT, float epsilon) { } // Vérifie les intersections avec les cylindres -static bool checkShadowCylinder(const Ray shadowRay, float maxT, float epsilon) { +static bool checkShadowCylinder(const t_ray shadowRay, float maxT, float epsilon, t_scene scene) { int i = 0; t_vec3 dummy; float t; - while (i < numCylinders) { - t = intersectCylinder(shadowRay, cylinders[i], &dummy); + while (i < scene.numCylinders) { + t = intersectCylinder(shadowRay, scene.cylinders[i], &dummy); if (t > epsilon && t < maxT) return true; i++; @@ -55,20 +55,20 @@ static bool checkShadowCylinder(const Ray shadowRay, float maxT, float epsilon) } // Fonction principale qui détermine si le point est dans l'ombre -bool isInShadow(t_vec3 hitPoint, t_vec3 lightPos) { +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); - Ray shadowRay; + t_ray shadowRay; shadowRay.origin = vec3_add(hitPoint, vec3_scale(L, epsilon)); - shadowRay.direction = L; + shadowRay.dir = L; - if (checkShadowSphere(shadowRay, maxT, epsilon)) + if (checkShadowSphere(shadowRay, maxT, epsilon, scene)) return true; - if (checkShadowPlane(shadowRay, maxT, epsilon)) + if (checkShadowPlane(shadowRay, maxT, epsilon, scene)) return true; - if (checkShadowCylinder(shadowRay, maxT, epsilon)) + if (checkShadowCylinder(shadowRay, maxT, epsilon, scene)) return true; return false; diff --git a/tags b/tags index 5e223c7..985c9ab 100644 --- a/tags +++ b/tags @@ -35,6 +35,12 @@ !_TAG_KIND_DESCRIPTION!C++ t,typedef /typedefs/ !_TAG_KIND_DESCRIPTION!C++ u,union /union names/ !_TAG_KIND_DESCRIPTION!C++ v,variable /variable definitions/ +!_TAG_KIND_DESCRIPTION!Make I,makefile /makefiles/ +!_TAG_KIND_DESCRIPTION!Make m,macro /macros/ +!_TAG_KIND_DESCRIPTION!Make t,target /targets/ +!_TAG_KIND_DESCRIPTION!Man S,subsection /sub sections/ +!_TAG_KIND_DESCRIPTION!Man s,section /sections/ +!_TAG_KIND_DESCRIPTION!Man t,title /titles/ !_TAG_KIND_DESCRIPTION!Markdown S,subsection /level 2 sections/ !_TAG_KIND_DESCRIPTION!Markdown T,l4subsection /level 4 sections/ !_TAG_KIND_DESCRIPTION!Markdown c,chapter /chapters/ @@ -43,13 +49,28 @@ !_TAG_KIND_DESCRIPTION!Markdown s,section /sections/ !_TAG_KIND_DESCRIPTION!Markdown t,subsubsection /level 3 sections/ !_TAG_KIND_DESCRIPTION!Markdown u,l5subsection /level 5 sections/ +!_TAG_KIND_DESCRIPTION!Perl c,constant /constants/ +!_TAG_KIND_DESCRIPTION!Perl f,format /formats/ +!_TAG_KIND_DESCRIPTION!Perl l,label /labels/ +!_TAG_KIND_DESCRIPTION!Perl p,package /packages/ +!_TAG_KIND_DESCRIPTION!Perl s,subroutine /subroutines/ +!_TAG_KIND_DESCRIPTION!Sh a,alias /aliases/ +!_TAG_KIND_DESCRIPTION!Sh f,function /functions/ +!_TAG_KIND_DESCRIPTION!Sh h,heredoc /label for here document/ +!_TAG_KIND_DESCRIPTION!Sh s,script /script files/ +!_TAG_KIND_DESCRIPTION!Yaml a,anchor /anchors/ !_TAG_OUTPUT_EXCMD mixed /number, pattern, mixed, or combineV2/ !_TAG_OUTPUT_FILESEP slash /slash or backslash/ !_TAG_OUTPUT_MODE u-ctags /u-ctags or e-ctags/ !_TAG_OUTPUT_VERSION 0.0 /current.age/ !_TAG_PARSER_VERSION!C 1.1 /current.age/ !_TAG_PARSER_VERSION!C++ 1.1 /current.age/ +!_TAG_PARSER_VERSION!Make 0.0 /current.age/ +!_TAG_PARSER_VERSION!Man 0.0 /current.age/ !_TAG_PARSER_VERSION!Markdown 1.1 /current.age/ +!_TAG_PARSER_VERSION!Perl 0.0 /current.age/ +!_TAG_PARSER_VERSION!Sh 0.0 /current.age/ +!_TAG_PARSER_VERSION!Yaml 0.0 /current.age/ !_TAG_PATTERN_LENGTH_LIMIT 96 /0 for no limit/ !_TAG_PROC_CWD /home/null/Documents/better_ray_tracer/ // !_TAG_PROGRAM_AUTHOR Universal Ctags Team // @@ -69,109 +90,480 @@ !_TAG_ROLE_DESCRIPTION!C++!module imported /imported with "imported ..."/ !_TAG_ROLE_DESCRIPTION!C++!module partOwner /used for specifying a partition/ !_TAG_ROLE_DESCRIPTION!C++!partition imported /imported with "imported ..."/ +!_TAG_ROLE_DESCRIPTION!Make!makefile included /included/ +!_TAG_ROLE_DESCRIPTION!Make!makefile optional /optionally included/ +!_TAG_ROLE_DESCRIPTION!Sh!heredoc endmarker /end marker/ +!_TAG_ROLE_DESCRIPTION!Sh!script loaded /loaded/ +!_TAG_ROLE_DESCRIPTION!Yaml!anchor alias /alias/ +$(DIR_OBJ) makefile /^$(DIR_OBJ):$/;" t +$(DIR_OBJ)/%.o makefile /^$(DIR_OBJ)\/%.o: %.c | $(DIR_OBJ)$/;" t +$(LIBFT) makefile /^$(LIBFT):$/;" t +$(MINILIBX) makefile /^$(MINILIBX):$/;" t +$(NAME) libft/Makefile /^$(NAME): $(OBJS)$/;" t +$(NAME) makefile /^$(NAME): $(OBJ) $(LIBFT) $(MINILIBX)$/;" t +$(NAME) minilibx-linux/Makefile.mk /^$(NAME) : $(OBJ)$/;" t +$(NAME) minilibx-linux/test/Makefile.mk /^$(NAME): $(OBJ)$/;" t +$(OBJ_DIR)/%.o minilibx-linux/Makefile.mk /^$(OBJ_DIR)\/%.o: %.c$/;" t +%.o libft/Makefile /^%.o: %.c$/;" t +AR libft/Makefile /^AR = ar rcs$/;" m +AUTHOR minilibx-linux/man/man1/mlx.1 /^.SH AUTHOR$/;" s title:MiniLibX +AUTHOR minilibx-linux/man/man1/mlx_loop.1 /^.SH AUTHOR$/;" s title:MiniLibX +AUTHOR minilibx-linux/man/man1/mlx_new_image.1 /^.SH AUTHOR$/;" s title:MiniLibX +AUTHOR minilibx-linux/man/man1/mlx_new_window.1 /^.SH AUTHOR$/;" s title:MiniLibX +AUTHOR minilibx-linux/man/man1/mlx_pixel_put.1 /^.SH AUTHOR$/;" s title:MiniLibX +AUTHOR minilibx-linux/man/man3/mlx.3 /^.SH AUTHOR$/;" s title:MiniLibX +AUTHOR minilibx-linux/man/man3/mlx_loop.3 /^.SH AUTHOR$/;" s title:MiniLibX +AUTHOR minilibx-linux/man/man3/mlx_new_image.3 /^.SH AUTHOR$/;" s title:MiniLibX +AUTHOR minilibx-linux/man/man3/mlx_new_window.3 /^.SH AUTHOR$/;" s title:MiniLibX +AUTHOR minilibx-linux/man/man3/mlx_pixel_put.3 /^.SH AUTHOR$/;" s title:MiniLibX +BUFFER_SIZE libft/get_next_line.h /^# define BUFFER_SIZE /;" d +CC libft/Makefile /^CC = cc$/;" m +CC makefile /^CC = cc$/;" m +CC minilibx-linux/Makefile.mk /^ CC = clang$/;" m +CC minilibx-linux/Makefile.mk /^CC = gcc$/;" m +CC minilibx-linux/test/Makefile.mk /^ CC = gcc$/;" m +CC minilibx-linux/test/Makefile.mk /^ CC = clang$/;" m +CFLAGS libft/Makefile /^CFLAGS = -Wall -Wextra -Werror -g3$/;" m +CFLAGS makefile /^CFLAGS = -fsanitize=address -g3 -Wall -Wextra -Werror$/;" m +CFLAGS minilibx-linux/Makefile.mk /^CFLAGS = -O3 -I$(INC)$/;" m +CFLAGS minilibx-linux/test/Makefile.mk /^CFLAGS= -I$(INC) -O3 -I.. -g$/;" m +CHAR libft/libft.h /^# define CHAR /;" d +COLOR MANAGEMENT minilibx-linux/man/man1/mlx_pixel_put.1 /^.SH COLOR MANAGEMENT$/;" s title:MiniLibX +COLOR MANAGEMENT minilibx-linux/man/man3/mlx_pixel_put.3 /^.SH COLOR MANAGEMENT$/;" s title:MiniLibX +DEC libft/libft.h /^# define DEC /;" d +DESCRIPTION minilibx-linux/man/man1/mlx.1 /^.SH DESCRIPTION$/;" s title:MiniLibX +DESCRIPTION minilibx-linux/man/man1/mlx_loop.1 /^.SH DESCRIPTION$/;" s title:MiniLibX +DESCRIPTION minilibx-linux/man/man1/mlx_new_image.1 /^.SH DESCRIPTION$/;" s title:MiniLibX +DESCRIPTION minilibx-linux/man/man1/mlx_new_window.1 /^.SH DESCRIPTION$/;" s title:MiniLibX +DESCRIPTION minilibx-linux/man/man1/mlx_pixel_put.1 /^.SH DESCRIPTION$/;" s title:MiniLibX +DESCRIPTION minilibx-linux/man/man3/mlx.3 /^.SH DESCRIPTION$/;" s title:MiniLibX +DESCRIPTION minilibx-linux/man/man3/mlx_loop.3 /^.SH DESCRIPTION$/;" s title:MiniLibX +DESCRIPTION minilibx-linux/man/man3/mlx_new_image.3 /^.SH DESCRIPTION$/;" s title:MiniLibX +DESCRIPTION minilibx-linux/man/man3/mlx_new_window.3 /^.SH DESCRIPTION$/;" s title:MiniLibX +DESCRIPTION minilibx-linux/man/man3/mlx_pixel_put.3 /^.SH DESCRIPTION$/;" s title:MiniLibX +DIR_OBJ makefile /^DIR_OBJ = obj$/;" m +ENV_DISPLAY minilibx-linux/mlx_int.h /^# define ENV_DISPLAY /;" d +EOF minilibx-linux/configure /^cat < +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/17 19:07:07 by yantoine #+# #+# */ -/* Updated: 2025/02/17 19:10:35 by yantoine ### ########.fr */ +/* Updated: 2025/02/17 21:51:30 by yantoine ### ########.fr */ /* */ /* ************************************************************************** */ @@ -15,41 +15,41 @@ #include "miniRT.h" // Renvoie true si le rayon intersecte un objet, et met à jour tMin, hitNormal et objColor -bool intersectObjects(Ray ray, float *tMin, t_vec3 *hitNormal, t_vec3 *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 < numSpheres) { - t = intersectSphere(ray, spheres[i], &n); - if (t > 1e-3f && t < *tMin) { *tMin = t; *hitNormal = n; *objColor = spheres[i].color; hit = true; } + 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 < numPlanes) { - t = intersectPlane(ray, planes[i], &n); - if (t > 1e-3f && t < *tMin) { *tMin = t; *hitNormal = n; *objColor = planes[i].color; hit = true; } + 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 < numCylinders) { - t = intersectCylinder(ray, cylinders[i], &n); - if (t > 1e-3f && t < *tMin) { *tMin = t; *hitNormal = n; *objColor = cylinders[i].color; hit = true; } + 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_vec3 color = vec3_scale(objColor, ambient_ratio); +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 < numLights) { - Light light = lights[i]; + 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)) { + if (!isInShadow(hitPoint, light.pos, scene)) { float diff = fmaxf(0.0f, vec3_dot(hitNormal, L)); - t_vec3 viewDir = vec3_normalize(vec3_sub(camPos, hitPoint)); + 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), @@ -66,13 +66,13 @@ t_vec3 calcLighting(t_vec3 hitPoint, t_vec3 hitNormal, t_vec3 objColor) { } // Fonction principale de lancer de rayon (trace) -t_vec3 trace(Ray ray) { +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)) { + if (intersectObjects(ray, &tMin, &hitNormal, &objColor, scene)) { t_vec3 hitPoint = vec3_add(ray.origin, vec3_scale(ray.dir, tMin)); - return calcLighting(hitPoint, hitNormal, objColor); + return calcLighting(hitPoint, hitNormal, objColor, scene); } return (t_vec3){0.2f, 0.7f, 1.0f}; // Couleur de fond (ciel) }