/* ************************************************************************** */ /* */ /* ::: :::::::: */ /* dda.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: qmennen +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* 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 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)); }