/ src / ray.c
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  }