cub3d/src/raycast/ray.c

115 lines
3.3 KiB
C

/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ray.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: kcolin <kcolin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/07/31 11:55:41 by kcolin #+# #+# */
/* Updated: 2025/08/20 12:48:06 by tchampio ### ########.fr */
/* */
/* ************************************************************************** */
#include "ray.h"
#include "raycaster.h"
#include "../player/player.h"
#include "../consts.h"
#include "../cub3d_data.h"
#include <float.h>
#include <math.h>
#include "../map/collision.h"
void init_ray(t_ray *ray, int pos_x, t_player *player)
{
ray->plane = 2 * pos_x / (double)WIDTH - 1;
ray->dir_x = player->dir_x + player->plane_x * ray->plane;
ray->dir_y = player->dir_y + player->plane_y * ray->plane;
ray->map_x = (int)player->x;
ray->map_y = (int)player->y;
ray->delta_dist_x = fabs(1 / ray->dir_x);
ray->delta_dist_y = fabs(1 / ray->dir_y);
}
void ray_calculate_step(t_ray *ray, t_player *player)
{
if (ray->dir_x < 0)
{
ray->step_x = -1;
ray->side_dist_x = (player->x - ray->map_x) * ray->delta_dist_x;
}
else
{
ray->step_x = 1;
ray->side_dist_x = (ray->map_x + 1.0 - player->x) * ray->delta_dist_x;
}
if (ray->dir_y < 0)
{
ray->step_y = -1;
ray->side_dist_y = (player->y - ray->map_y) * ray->delta_dist_y;
}
else
{
ray->step_y = 1;
ray->side_dist_y = (ray->map_y + 1.0 - player->y) * ray->delta_dist_y;
}
}
void calculate_wall_dist(t_ray *ray, t_mapdata *map)
{
while (true)
{
if (ray->side_dist_x < ray->side_dist_y)
{
ray->side_dist_x += ray->delta_dist_x;
ray->map_x += ray->step_x;
ray->side = NORTH;
}
else
{
ray->side_dist_y += ray->delta_dist_y;
ray->map_y += ray->step_y;
ray->side = SOUTH;
}
if (blocks_view(map, ray->map_x, ray->map_y))
break ;
}
if (ray->side == NORTH)
ray->wall_dist = ray->side_dist_x - ray->delta_dist_x;
else
ray->wall_dist = ray->side_dist_y - ray->delta_dist_y;
}
void calculate_wall_height(t_ray *ray, t_player *player)
{
if (ray->wall_dist <= FLT_EPSILON)
ray->wall_dist = 0.1;
ray->wall_height = (int)(HEIGHT / ray->wall_dist);
ray->draw_start = -ray->wall_height / 2 + HEIGHT / 2;
if (ray->draw_start < 0)
ray->draw_start = 0;
ray->draw_end = ray->wall_height / 2 + HEIGHT / 2;
if (ray->draw_end >= HEIGHT)
ray->draw_end = HEIGHT - 1;
if (ray->side == NORTH)
ray->wall_x = player->y + ray->wall_dist * ray->dir_y;
else
ray->wall_x = player->x + ray->wall_dist * ray->dir_x;
ray->wall_x -= floor(ray->wall_x);
}
void raycaster(t_cub3d_data *data, t_ray *ray)
{
int x;
x = 0;
while (x < WIDTH)
{
init_ray(ray, x, &data->player);
ray_calculate_step(ray, &data->player);
calculate_wall_dist(ray, data->map);
calculate_wall_height(ray, &data->player);
render_walls(data, ray, x);
data->zbuffer[x] = ray->wall_dist;
x++;
}
}