108 lines
3.3 KiB
C
108 lines
3.3 KiB
C
/* ************************************************************************** */
|
|
/* */
|
|
/* ::: :::::::: */
|
|
/* dda.c :+: :+: :+: */
|
|
/* +:+ +:+ +:+ */
|
|
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
|
|
/* +#+#+#+#+#+ +#+ */
|
|
/* Created: 2025/05/02 11:58:09 by whaffman #+# #+# */
|
|
/* Updated: 2025/06/10 14:35:17 by qmennen ### ########.fr */
|
|
/* */
|
|
/* ************************************************************************** */
|
|
|
|
#include "cub3d.h"
|
|
#include "vec_math.h"
|
|
#include <math.h>
|
|
|
|
t_vec2 get_delta_dist(t_vec2 ray_dir)
|
|
{
|
|
t_vec2 delta_dist;
|
|
|
|
if (ray_dir.x == 0)
|
|
delta_dist.x = 1e30;
|
|
else
|
|
delta_dist.x = fabs(1 / ray_dir.x);
|
|
if (ray_dir.y == 0)
|
|
delta_dist.y = 1e30;
|
|
else
|
|
delta_dist.y = fabs(1 / ray_dir.y);
|
|
return (delta_dist);
|
|
}
|
|
|
|
t_vec2 get_step(t_vec2 ray_dir)
|
|
{
|
|
t_vec2 step;
|
|
|
|
step.x = 2 * (ray_dir.x >= 0) - 1;
|
|
step.y = 2 * (ray_dir.y >= 0) - 1;
|
|
return (step);
|
|
}
|
|
|
|
t_vec2 get_side_dist(t_vec2 ray_dir, t_vec2 pos, t_vec2 delta_dist)
|
|
{
|
|
const t_vec2 frac_pos = (t_vec2){pos.x - (int)pos.x, pos.y - (int)pos.y};
|
|
const int raydir_x_pos = (ray_dir.x >= 0);
|
|
const int raydir_y_pos = (ray_dir.y >= 0);
|
|
t_vec2 side_dist;
|
|
|
|
side_dist.x = ((1 - raydir_x_pos) * frac_pos.x
|
|
+ raydir_x_pos * (1 - frac_pos.x)) * delta_dist.x;
|
|
side_dist.y = ((1 - raydir_y_pos) * frac_pos.y
|
|
+ raydir_y_pos * (1 - frac_pos.y)) * delta_dist.y;
|
|
return (side_dist);
|
|
}
|
|
|
|
int dda_main(t_vec2 ray_dir, t_vec2_int map_pos, t_vec2 *side_dist, t_map *map)
|
|
{
|
|
const t_vec2 delta_dist = get_delta_dist(ray_dir);
|
|
const t_vec2 step = get_step(ray_dir);
|
|
int side;
|
|
int hit;
|
|
|
|
hit = 0;
|
|
while (hit == 0)
|
|
{
|
|
side = (side_dist->x >= side_dist->y);
|
|
side_dist->x += delta_dist.x * (1 - side);
|
|
side_dist->y += delta_dist.y * side;
|
|
map_pos.x += step.x * (1 - side);
|
|
map_pos.y += step.y * side;
|
|
if (map_pos.x < 0
|
|
|| map_pos.x >= (int) map->width
|
|
|| map_pos.y < 0
|
|
|| map_pos.y >= (int) map->height)
|
|
printf("Out of bounds: %d %d\n", map_pos.x, map_pos.y);
|
|
if (map->grid[map_pos.y][map_pos.x] == TILE_EMPTY)
|
|
map->grid[map_pos.y][map_pos.x] = TILE_VISITED;
|
|
hit = (map->grid[map_pos.y][map_pos.x] == TILE_WALL) - (map->grid[map_pos.y][map_pos.x] == TILE_DOOR);
|
|
}
|
|
side = -1 * (1 - side) + side;
|
|
if (hit == -1)
|
|
side *= 2;
|
|
return (side);
|
|
}
|
|
|
|
// Returns the distance to the wall hit if the wall is hit in y
|
|
// direction the result is negative, if the wall is hit
|
|
// in x direction the result is positive
|
|
double dda(t_render *render, t_vec2 ray_dir, t_vec2 pos, t_map *map)
|
|
{
|
|
const t_vec2 delta_dist = get_delta_dist(ray_dir);
|
|
t_vec2 side_dist;
|
|
int side;
|
|
|
|
side_dist = get_side_dist(ray_dir, pos, delta_dist);
|
|
side = dda_main(ray_dir,
|
|
(t_vec2_int){(int)pos.x, (int)pos.y},
|
|
&side_dist,
|
|
map);
|
|
if (abs(side) == 2)
|
|
{
|
|
render->door = 1;
|
|
side /= 2;
|
|
}
|
|
side = (side + 1)/2;
|
|
return ((1 - side) * (side_dist.x - delta_dist.x)
|
|
- side * (side_dist.y - delta_dist.y));
|
|
}
|