/* ************************************************************************** */ /* */ /* :::::::: */ /* DDAscratch.c :+: :+: */ /* +:+ */ /* By: whaffman +#+ */ /* +#+ */ /* Created: 2025/05/02 11:58:09 by whaffman #+# #+# */ /* Updated: 2025/05/02 20:26:34 by whaffman ######## odam.nl */ /* */ /* ************************************************************************** */ #include "cub3d.h" #include "vec_math.h" #include t_vec2 get_delta_dist(t_vec2 ray_dir) { t_vec2 delta_dist; delta_dist.x = (ray_dir.x == 0) * 1e30 + (ray_dir.x != 0) * fabs(1 / ray_dir.x); delta_dist.y = (ray_dir.y == 0) * 1e30 + (ray_dir.y != 0) * 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_x_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; hit = (map->grid[map_pos.y][map_pos.x] == TILE_WALL); } 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 float DDA(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); return ((1 - side) * (side_dist.x - delta_dist.x) - side * (side_dist.y - delta_dist.y)); } t_side get_side(t_vec2 ray_dir, float perp_dist) { if(perp_dist > 0) { if (ray_dir.x > 0) return (SIDE_EAST); else return (SIDE_WEST); } else { if (ray_dir.y > 0) return (SIDE_SOUTH); else return (SIDE_NORTH); } } t_render cast_ray(t_game *game, int x) { t_vec2 ray_dir; t_vec2 pos; t_render render; float perp_dist; ray_dir = add(game->player->dir, mul(game->player->camera, (2.0f * x / (float)game->screen->width - 1))); pos = game->player->pos; perp_dist = DDA(ray_dir, pos, game->map); render.perp_dist = fabs(perp_dist); render.side = get_side(ray_dir); render.wall_x = (perp_dist > 0) * (pos.x + ray_dir.x * perp_dist) + (perp_dist <= 0) * (pos.y + ray_dir.y * perp_dist); render.wall_x -= floor(render.wall_x); return (render); } void cast_rays(t_game *game) { int x; t_render render[WIDTH]; x = 0; while (x < game->screen->width) { render[x] = cast_ray(game, x); //ETC x++; } }