diff --git a/intersect_objects.c b/intersect_objects.c new file mode 100644 index 0000000..882e283 --- /dev/null +++ b/intersect_objects.c @@ -0,0 +1,112 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* intersect_objects.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: yantoine +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/02/19 16:07:55 by yantoine #+# #+# */ +/* Updated: 2025/02/19 16:16:52 by yantoine ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "miniRT.h" + +static bool intersect_spheres(const t_ray ray, t_hit *hit, t_sphere *spheres, + int numSpheres) +{ + int i; + bool hitAny; + t_vec3 n; + float t; + + i = 0; + hitAny = false; + while (i < numSpheres) + { + t = intersect_sphere(ray, spheres[i], &n); + if (t > 1e-3f && t < hit->t) + { + hit->t = t; + hit->normal = n; + hit->color = spheres[i].color; + hitAny = true; + } + i++; + } + return (hitAny); +} + +static bool intersect_planes(const t_ray ray, t_hit *hit, t_plane *planes, + int numPlanes) +{ + int i; + bool hitAny; + t_vec3 n; + float t; + + i = 0; + hitAny = false; + while (i < numPlanes) + { + t = intersect_plane(ray, planes[i], &n); + if (t > 1e-3f && t < hit->t) + { + hit->t = t; + hit->normal = n; + hit->color = planes[i].color; + hitAny = true; + } + i++; + } + return (hitAny); +} + +static bool intersect_cylinders(const t_ray ray, t_hit *hit, + t_cylinder *cylinders, int numCylinders) +{ + int i; + bool hitAny; + t_vec3 n; + float t; + + i = 0; + hitAny = false; + while (i < numCylinders) + { + t = intersect_cylinder(ray, cylinders[i], &n); + if (t > 1e-3f && t < hit->t) + { + hit->t = t; + hit->normal = n; + hit->color = cylinders[i].color; + hitAny = true; + } + i++; + } + return (hitAny); +} + +bool intersect_objects(float *tMin, t_vec3 *hitNormal, t_vec3 *objColor, + t_scene scene) +{ + t_hit hit; + bool hitFound; + + hitFound = false; + hit.t = *tMin; + if (intersect_spheres(scene.ray, &hit, scene.spheres, scene.numSpheres)) + hitFound = true; + if (intersect_planes(scene.ray, &hit, scene.planes, scene.numPlanes)) + hitFound = true; + if (intersect_cylinders(scene.ray, &hit, scene.cylinders, + scene.numCylinders)) + hitFound = true; + if (hitFound) + { + *tMin = hit.t; + *hitNormal = hit.normal; + *objColor = hit.color; + } + return (hitFound); +} diff --git a/miniRT b/miniRT new file mode 100755 index 0000000..88699d4 Binary files /dev/null and b/miniRT differ diff --git a/miniRT.h b/miniRT.h index ee70f85..81392e7 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/18 20:43:16 by yantoine ### ########.fr */ +/* Updated: 2025/02/19 16:27:24 by yantoine ### ########.fr */ /* */ /* ************************************************************************** */ @@ -88,6 +88,13 @@ typedef struct s_ambient t_vec3 color; } t_ambient; +typedef struct s_hit +{ + float t; + t_vec3 normal; + t_vec3 color; +} t_hit; + typedef struct s_camera { t_vec3 camPos; @@ -184,6 +191,13 @@ typedef struct s_calc t_ray ray; t_vec3 ray_dir; t_vec3 color; + t_light light; + t_vec3 l; + float diff; + t_vec3 view_dir; + t_vec3 half_dir; + float spec; + } t_calc; // Calcul de vecteur @@ -224,7 +238,7 @@ float intersect_sphere(t_ray ray, t_sphere s, t_vec3 *hitNormal); bool is_in_shadow(t_vec3 hitPoint, t_vec3 lightPos, t_scene scene); bool intersect_objects(float *tMin, t_vec3 *hitNormal, t_vec3 *objColor, t_scene scene); -t_vec3 calcLighting(t_vec3 hitPoint, t_vec3 hitNormal, t_vec3 objColor, +t_vec3 calc_lighting(t_vec3 hitPoint, t_vec3 hitNormal, t_vec3 objColor, t_scene scene); t_vec3 trace(t_ray ray, t_scene scene); diff --git a/tags b/tags index ae2698d..7da3771 100644 --- a/tags +++ b/tags @@ -284,7 +284,7 @@ bpp3 minilibx-linux/test/main.c /^int bpp3;$/;" v typeref:typename:int bpp4 minilibx-linux/test/main.c /^int bpp4;$/;" v typeref:typename:int brightness miniRT.h /^ float brightness;$/;" m struct:s_light typeref:typename:float c miniRT.h /^ float c;$/;" m struct:s_calc typeref:typename:float -calcLighting trace.c /^t_vec3 calcLighting(t_vec3 hitPoint, t_vec3 hitNormal, t_vec3 objColor,$/;" f typeref:typename:t_vec3 +calc_lighting trace.c /^t_vec3 calc_lighting(t_vec3 hitPoint, t_vec3 hitNormal, t_vec3 objColor,$/;" f typeref:typename:t_vec3 camDir miniRT.h /^ t_vec3 camDir;$/;" m struct:s_camera typeref:typename:t_vec3 camPos miniRT.h /^ t_vec3 camPos;$/;" m struct:s_camera typeref:typename:t_vec3 camera miniRT.h /^ t_camera camera;$/;" m struct:s_scene typeref:typename:t_camera @@ -311,6 +311,7 @@ color miniRT.h /^ t_vec3 color;$/;" m struct:s_cylinder typeref:typename:t_vec3 color miniRT.h /^ t_vec3 color;$/;" m struct:s_light typeref:typename:t_vec3 color miniRT.h /^ t_vec3 color;$/;" m struct:s_plane typeref:typename:t_vec3 color miniRT.h /^ t_vec3 color;$/;" m struct:s_sphere typeref:typename:t_vec3 +color miniRT.h /^ t_vec3 color;$/;" m struct:s_hit typeref:typename:t_vec3 color minilibx-linux/mlx_int.h /^ int color;$/;" m struct:s_col_name typeref:typename:int color_map_1 minilibx-linux/test/main.c /^int color_map_1(void *win,int w,int h)$/;" f typeref:typename:int color_map_2 minilibx-linux/test/main.c /^int color_map_2(unsigned char *data,int bpp,int sl,int w,int h,int endian, int type)$/;" f typeref:typename:int @@ -332,6 +333,7 @@ data3 minilibx-linux/test/main.c /^char *data3;$/;" v typeref:typename:char * data4 minilibx-linux/test/main.c /^char *data4;$/;" v typeref:typename:char * decrgb minilibx-linux/mlx_int.h /^ int decrgb[6];$/;" m struct:s_xvar typeref:typename:int[6] depth minilibx-linux/mlx_int.h /^ int depth;$/;" m struct:s_xvar typeref:typename:int +diff miniRT.h /^ float diff;$/;" m struct:s_calc typeref:typename:float dir miniRT.h /^ t_vec3 dir;$/;" m struct:s_ray typeref:typename:t_vec3 disc miniRT.h /^ float disc;$/;" m struct:s_calc typeref:typename:float display minilibx-linux/mlx_int.h /^ Display *display;$/;" m struct:s_xvar typeref:typename:Display * @@ -419,6 +421,7 @@ gnl_ft_strchr libft/gnl_utils.c /^char *gnl_ft_strchr(char *s, int c)$/;" f type gnl_ft_strjoin libft/gnl_utils.c /^char *gnl_ft_strjoin(char *s1, char *s2)$/;" f typeref:typename:char * gnl_ft_strlen libft/gnl_utils.c /^size_t gnl_ft_strlen(char *s)$/;" f typeref:typename:size_t gnl_read_fd libft/gnl.c /^char *gnl_read_fd(int fd, char *str)$/;" f typeref:typename:char * +half_dir miniRT.h /^ t_vec3 half_dir;$/;" m struct:s_calc typeref:typename:t_vec3 height miniRT.h /^ float height;$/;" m struct:s_cylinder typeref:typename:float height minilibx-linux/mlx_int.h /^ int height;$/;" m struct:s_img typeref:typename:int hitPoint miniRT.h /^ t_vec3 hitPoint;$/;" m struct:s_calc typeref:typename:t_vec3 @@ -434,10 +437,13 @@ img miniRT.h /^ void *img;$/;" m struct:s_app typeref:typename:void * init_app_config main.c /^static int init_app_config(t_app *app, int argc, char **argv)$/;" f typeref:typename:int file: init_intersection parsing_cylinder_utils.c /^int init_intersection(t_ray ray, t_cylinder cy, t_calc *calc)$/;" f typeref:typename:int init_mlx_and_image main.c /^static int init_mlx_and_image(t_app *app)$/;" f typeref:typename:int file: -interesct_objects trace.c /^bool interesct_objects(float *tMin, t_vec3 *hitNormal,$/;" f typeref:typename:bool intersect_cylinder parsing_cylinder_utils2.c /^float intersect_cylinder(t_ray ray, t_cylinder cy, t_vec3 *hitNormal)$/;" f typeref:typename:float +intersect_cylinders intersect_objects.c /^static bool intersect_cylinders(const t_ray ray, t_hit *hit,$/;" f typeref:typename:bool file: +intersect_objects intersect_objects.c /^bool intersect_objects(float *tMin, t_vec3 *hitNormal, t_vec3 *objColor,$/;" f typeref:typename:bool intersect_plane parsing_plane.c /^float intersect_plane(t_ray ray, t_plane p, t_vec3 *hitNormal)$/;" f typeref:typename:float +intersect_planes intersect_objects.c /^static bool intersect_planes(const t_ray ray, t_hit *hit, t_plane *planes,$/;" f typeref:typename:bool file: intersect_sphere parsing_sphere.c /^float intersect_sphere(t_ray ray, t_sphere s, t_vec3 *hitNormal)$/;" f typeref:typename:float +intersect_spheres intersect_objects.c /^static bool intersect_spheres(const t_ray ray, t_hit *hit, t_sphere *spheres,$/;" f typeref:typename:bool file: is_in_shadow shadows.c /^bool is_in_shadow(t_vec3 hitPoint, t_vec3 lightPos, t_scene scene)$/;" f typeref:typename:bool key_a miniRT.h /^ int key_a;$/;" m struct:s_app typeref:typename:int key_d miniRT.h /^ int key_d;$/;" m struct:s_app typeref:typename:int @@ -454,7 +460,9 @@ key_w miniRT.h /^ int key_w;$/;" m struct:s_app typeref:typename:int key_win1 minilibx-linux/test/main.c /^int key_win1(int key,void *p)$/;" f typeref:typename:int key_win2 minilibx-linux/test/main.c /^int key_win2(int key,void *p)$/;" f typeref:typename:int key_win3 minilibx-linux/test/main.c /^int key_win3(int key,void *p)$/;" f typeref:typename:int +l miniRT.h /^ t_vec3 l;$/;" m struct:s_calc typeref:typename:t_vec3 len_word libft/ft_split.c /^static size_t len_word(char *s, char c, size_t start)$/;" f typeref:typename:size_t file: +light miniRT.h /^ t_light light;$/;" m struct:s_calc typeref:typename:t_light lights miniRT.h /^ t_light lights[MAX_LIGHTS];$/;" m struct:s_scene typeref:typename:t_light[] line_if_exit miniRT.h /^ char *line_if_exit;$/;" m struct:s_scene typeref:typename:char * load_config config.c /^t_scene load_config(const char *filename)$/;" f typeref:typename:t_scene @@ -559,6 +567,7 @@ ndc_x miniRT.h /^ float ndc_x;$/;" m struct:s_calc typeref:typename:float ndc_y miniRT.h /^ float ndc_y;$/;" m struct:s_calc typeref:typename:float next minilibx-linux/mlx_int.h /^ struct s_win_list *next;$/;" m struct:s_win_list typeref:struct:s_win_list * normal miniRT.h /^ t_vec3 normal;$/;" m struct:s_plane typeref:typename:t_vec3 +normal miniRT.h /^ t_vec3 normal;$/;" m struct:s_hit typeref:typename:t_vec3 numAmbient miniRT.h /^ int numAmbient;$/;" m struct:s_scene typeref:typename:int numCamera miniRT.h /^ int numCamera;$/;" m struct:s_scene typeref:typename:int numCylinders miniRT.h /^ int numCylinders;$/;" m struct:s_scene typeref:typename:int @@ -624,6 +633,7 @@ s_camera miniRT.h /^typedef struct s_camera$/;" s s_col_name minilibx-linux/mlx_int.h /^struct s_col_name$/;" s s_cylinder miniRT.h /^typedef struct s_cylinder$/;" s s_event_list minilibx-linux/mlx_int.h /^typedef struct s_event_list$/;" s +s_hit miniRT.h /^typedef struct s_hit$/;" s s_img minilibx-linux/mlx_int.h /^typedef struct s_img$/;" s s_info libft/libft.h /^struct s_info$/;" s s_light miniRT.h /^typedef struct s_light$/;" s @@ -655,10 +665,12 @@ sl1 minilibx-linux/test/main.c /^int sl1;$/;" v typeref:typename:int sl2 minilibx-linux/test/main.c /^int sl2;$/;" v typeref:typename:int sl3 minilibx-linux/test/main.c /^int sl3;$/;" v typeref:typename:int sl4 minilibx-linux/test/main.c /^int sl4;$/;" v typeref:typename:int +spec miniRT.h /^ float spec;$/;" m struct:s_calc typeref:typename:float spheres miniRT.h /^ t_sphere spheres[MAX_SPHERES];$/;" m struct:s_scene typeref:typename:t_sphere[] sqrtDisc miniRT.h /^ float sqrtDisc;$/;" m struct:s_calc typeref:typename:float strlcpy_is_not_posix minilibx-linux/mlx_xpm.c /^unsigned int strlcpy_is_not_posix(char *dest, char *src, unsigned int size)$/;" f typeref:typename:unsigned int t miniRT.h /^ float t;$/;" m struct:s_calc typeref:typename:float +t miniRT.h /^ float t;$/;" m struct:s_hit typeref:typename:float t0 miniRT.h /^ float t0;$/;" m struct:s_calc typeref:typename:float t1 miniRT.h /^ float t1;$/;" m struct:s_calc typeref:typename:float t_ambient miniRT.h /^} t_ambient;$/;" t typeref:struct:s_ambient @@ -670,6 +682,7 @@ t_cap miniRT.h /^ float t_cap;$/;" m struct:s_calc typeref:typename:float t_cylinder miniRT.h /^} t_cylinder;$/;" t typeref:struct:s_cylinder t_event_list minilibx-linux/mlx_int.h /^} t_event_list;$/;" t typeref:struct:s_event_list t_final miniRT.h /^ float t_final;$/;" m struct:s_calc typeref:typename:float +t_hit miniRT.h /^} t_hit;$/;" t typeref:struct:s_hit t_img minilibx-linux/mlx_int.h /^} t_img;$/;" t typeref:struct:s_img t_info libft/libft.h /^typedef struct s_info t_info;$/;" t typeref:struct:s_info t_light miniRT.h /^} t_light;$/;" t typeref:struct:s_light @@ -705,6 +718,7 @@ vec3_mul calcul_de_vecteur2.c /^t_vec3 vec3_mul(t_vec3 a, t_vec3 b)$/;" f typere vec3_normalize calcul_de_vecteur2.c /^t_vec3 vec3_normalize(t_vec3 a)$/;" f typeref:typename:t_vec3 vec3_scale calcul_de_vecteur.c /^t_vec3 vec3_scale(t_vec3 a, float s)$/;" f typeref:typename:t_vec3 vec3_sub calcul_de_vecteur.c /^t_vec3 vec3_sub(t_vec3 a, t_vec3 b)$/;" f typeref:typename:t_vec3 +view_dir miniRT.h /^ t_vec3 view_dir;$/;" m struct:s_calc typeref:typename:t_vec3 visual minilibx-linux/mlx_int.h /^ Visual *visual;$/;" m struct:s_xvar typeref:typename:Visual * width minilibx-linux/mlx_int.h /^ int width;$/;" m struct:s_img typeref:typename:int win miniRT.h /^ void *win;$/;" m struct:s_app typeref:typename:void * diff --git a/trace.c b/trace.c index bfbd2d9..649e837 100644 --- a/trace.c +++ b/trace.c @@ -6,104 +6,45 @@ /* By: yantoine +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/17 19:07:07 by yantoine #+# #+# */ -/* Updated: 2025/02/18 20:34:28 by yantoine ### ########.fr */ +/* Updated: 2025/02/19 16:30:27 by yantoine ### ########.fr */ /* */ /* ************************************************************************** */ #include "miniRT.h" -// Renvoie true si le rayon intersecte un objet, et met à jour tMin, -//hitNormal et objColor -bool interesct_objects(float *tMin, t_vec3 *hitNormal, - t_vec3 *objColor, t_scene scene) -{ - bool hit; - float t; - t_vec3 n; - int i; - - hit = false; - i = 0; - while (i < scene.numSpheres) - { - t = intersect_sphere(scene.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 = intersect_plane(scene.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 = intersect_cylinder(scene.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 calc_lighting(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; + t_calc calc; - color = vec3_scale(objColor, scene.ambient.ratio); + calc.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 (!is_in_shadow(hitPoint, light.pos, scene)) + calc.light = scene.lights[i]; + calc.l = vec3_normalize(vec3_sub(calc.light.pos, hitPoint)); + if (!is_in_shadow(hitPoint, calc.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)); + calc.diff = fmaxf(0.0f, vec3_dot(hitNormal, calc.l)); + calc.view_dir = vec3_normalize(vec3_sub(scene.camera.camPos, hitPoint)); + calc.half_dir = vec3_normalize(vec3_add(calc.l, calc.view_dir)); + calc.spec = powf(fmaxf(0.0f, vec3_dot(hitNormal, calc.half_dir)), 32.0f); + calc.color = vec3_add(calc.color, vec3_scale(vec3_mul(objColor, calc.light.color), + calc.diff * calc.light.brightness)); + calc.color = vec3_add(calc.color, vec3_scale((t_vec3){1, 1, 1}, calc.spec + * calc.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); + if (calc.color.x > 1.0f) + calc.color.x = 1.0f; + if (calc.color.y > 1.0f) + calc.color.y = 1.0f; + if (calc.color.z > 1.0f) + calc.color.z = 1.0f; + return (calc.color); } // Fonction principale de lancer de rayon (trace) @@ -118,10 +59,10 @@ t_vec3 trace(t_ray ray, t_scene scene) hitNormal = (t_vec3){0, 0, 0}; objColor = (t_vec3){0, 0, 0}; scene.ray = ray; - if (interesct_objects(&tMin, &hitNormal, &objColor, scene)) + if (intersect_objects(&tMin, &hitNormal, &objColor, scene)) { hitPoint = vec3_add(scene.ray.origin, vec3_scale(scene.ray.dir, tMin)); - return (calcLighting(hitPoint, hitNormal, objColor, scene)); + return (calc_lighting(hitPoint, hitNormal, objColor, scene)); } - return ((t_vec3){0.2f, 0.7f, 1.0f}); // Couleur de fond (ciel) + return ((t_vec3){0, 0, 0}); // Couleur de fond (ciel) }