ray.c
1 /* ************************************************************************** */ 2 /* */ 3 /* ::: :::::::: */ 4 /* ray.c :+: :+: :+: */ 5 /* +:+ +:+ +:+ */ 6 /* By: ll-hotel <ll-hotel@student.42.fr> +#+ +:+ +#+ */ 7 /* +#+#+#+#+#+ +#+ */ 8 /* Created: 2024/08/01 13:08:58 by ll-hotel #+# #+# */ 9 /* Updated: 2024/11/12 17:41:53 by omougel ### ########.fr */ 10 /* */ 11 /* ************************************************************************** */ 12 13 #include "cub3D.h" 14 #include "ft_basics.h" 15 #include "vec2f.h" 16 #include <math.h> 17 18 static void ray_take_step(t_ray *ray, int *map_x, int *map_y); 19 20 void ray_init_dda(t_ray *ray, t_player *player, int x) 21 { 22 const float screen_ratio = ((2.f * x) / SCREEN_WIDTH) - 1.f; 23 const int map_x = floorf(player->pos.x); 24 const int map_y = floorf(player->pos.y); 25 26 ft_memset(ray, 0, sizeof(*ray)); 27 ray->dir.x = -player->dir.x + player->camera.x * screen_ratio; 28 ray->dir.y = -player->dir.y + player->camera.y * screen_ratio; 29 ray->deltadist.x = ft_absf(1.f / ray->dir.x); 30 ray->deltadist.y = ft_absf(1.f / ray->dir.y); 31 ray->step.x = (ray->dir.x < 0) - (ray->dir.x >= 0); 32 ray->step.y = (ray->dir.y < 0) - (ray->dir.y >= 0); 33 if (ray->dir.x >= 0) 34 ray->side_dist.x = (player->pos.x - map_x) * ray->deltadist.x; 35 else 36 ray->side_dist.x = (map_x + 1 - player->pos.x) * ray->deltadist.x; 37 if (ray->dir.y >= 0) 38 ray->side_dist.y = (player->pos.y - map_y) * ray->deltadist.y; 39 else 40 ray->side_dist.y = (map_y + 1 - player->pos.y) * ray->deltadist.y; 41 } 42 43 void ray_perform_dda(t_ray *ray, t_cube *cube) 44 { 45 int hit; 46 int map_x; 47 int map_y; 48 49 hit = 0; 50 map_x = (int)cube->player.pos.x; 51 map_y = (int)cube->player.pos.y; 52 while (hit == 0) 53 { 54 ray_take_step(ray, &map_x, &map_y); 55 if (0 <= map_x && map_x < cube->map.width && \ 56 0 <= map_y && map_y < cube->map.height) 57 hit = (cube->map.cells[map_y][map_x] == WALL); 58 else 59 hit = 1; 60 } 61 if (ray->side == EAST || ray->side == WEST) 62 ray->perpwalldist = ray->side_dist.x - ray->deltadist.x; 63 else 64 ray->perpwalldist = ray->side_dist.y - ray->deltadist.y; 65 if (ray->perpwalldist <= 0.f) 66 ray->perpwalldist = 0.001f; 67 ray->wall_height = (SCREEN_HEIGHT / ray->perpwalldist) * 0.5f; 68 } 69 70 void ray_find_drawing_limits(t_ray *ray) 71 { 72 ray->drawstart = (SCREEN_HEIGHT - ray->wall_height) * 0.5; 73 if (ray->drawstart < 0) 74 ray->drawstart = 0; 75 ray->drawend = SCREEN_HEIGHT - ray->drawstart - 1; 76 } 77 78 static void ray_take_step(t_ray *ray, int *map_x, int *map_y) 79 { 80 if (ray->side_dist.x < ray->side_dist.y) 81 { 82 ray->side_dist.x += ray->deltadist.x; 83 *map_x += ray->step.x; 84 ray->side = EAST; 85 if (ray->step.x > 0) 86 ray->side = WEST; 87 } 88 else 89 { 90 ray->side_dist.y += ray->deltadist.y; 91 *map_y += ray->step.y; 92 ray->side = SOUTH; 93 if (ray->step.y > 0) 94 ray->side = NORTH; 95 } 96 }