/* ************************************************************************** */ /* */ /* ::: :::::::: */ /* ft_raycasting.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: rbousset +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/02/14 17:22:57 by rbousset #+# #+# */ /* Updated: 2020/02/14 17:23:42 by rbousset ### ########lyon.fr */ /* */ /* ************************************************************************** */ #include #include #include #include #include #include void ft_calc_sprite(t_cub *cl) { cl->sprites.s_x = cl->sprites.s_pos_x - cl->plist->pos_x; cl->sprites.s_y = cl->sprites.s_pos_y - cl->plist->pos_y; cl->sprites.inv_c_m = 1.0 / (cl->plist->plane_x * cl->plist->dir_y - cl->plist->dir_x * cl->plist->plane_y); cl->sprites.sprite_transform_x = cl->sprites.inv_c_m * (cl->plist->dir_y * cl->sprites.s_x - cl->plist->dir_x * cl->sprites.s_y); cl->sprites.sprite_transform_y = cl->sprites.inv_c_m * (-cl->plist->plane_y * cl->sprites.s_x + cl->plist->plane_x * cl->sprites.s_y); cl->sprites.s_screen_x = (int)((cl->wlist->x_size / 2) * (1 + cl->sprites.sprite_transform_x / cl->sprites.sprite_transform_y)); cl->sprites.s_h = abs((int)(cl->wlist->y_size * cl->sprites.sprite_transform_y)); ft_calc_sprite_norme(cl); } void ft_calc_sprite_norme(t_cub *cl) { cl->sprites.s_start_y = -cl->sprites.s_h / 2 + cl->wlist->y_size / 2; if (cl->sprites.s_start_y < 0) cl->sprites.s_start_y = 0; cl->sprites.s_end_y = cl->sprites.s_h / 2 + cl->wlist->y_size / 2; if (cl->sprites.s_end_y > (int)cl->wlist->y_size) cl->sprites.s_end_y = cl->wlist->y_size - 1; cl->sprites.s_w = abs((int)(cl->wlist->y_size / cl->sprites.sprite_transform_y)); /*sprite width*/ cl->sprites.s_start_x = -cl->sprites.s_w / 2 + cl->sprites.s_screen_x; if (cl->sprites.s_start_x < 0) cl->sprites.s_start_x = 0; cl->sprites.s_end_x = cl->sprites.s_w / 2 + cl->sprites.s_screen_x; printf("%d\n", cl->sprites.s_w); if (cl->sprites.s_end_x > (int)cl->wlist->x_size) cl->sprites.s_end_x = cl->wlist->x_size - 1; /*ft_printf("start x: %d\nend x : %d\n", cl->sprites.s_start_x, cl->sprites.s_end_x);*/ /*ft_printf("start y: %d\nend y : %d\n", cl->sprites.s_start_y, cl->sprites.s_end_y);*/ /*ft_draw_sprite(cl);*/ } void ft_calc_tex(t_cub *clist) { if (clist->rlist.side == 0) clist->rlist.wall_hit_x = (clist->plist->pos_x) + clist->rlist.wall_dist * clist->rlist.y_ray_dir; else clist->rlist.wall_hit_x = (clist->plist->pos_y) + clist->rlist.wall_dist * clist->rlist.x_ray_dir; clist->rlist.wall_hit_x -= floor(clist->rlist.wall_hit_x); clist->tlist[clist->w_side].tex_x = (int)(clist->rlist.wall_hit_x * (double)clist->tlist[clist->w_side].img_w); if (clist->rlist.side == 0 && clist->rlist.x_ray_dir > 0) clist->tlist[clist->w_side].tex_x = clist->tlist[clist->w_side].img_w - clist->tlist[clist->w_side].tex_x - 1; else if (clist->rlist.side == 1 && clist->rlist.y_ray_dir < 0) clist->tlist[clist->w_side].tex_x = clist->tlist[clist->w_side].img_w - clist->tlist[clist->w_side].tex_x - 1; } static void ft_initray(t_cub *cl, uint16_t i) { t_win *wl; t_player *pl; wl = cl->wlist; pl = cl->plist; pl->cam_x = 2 * i / (float)(wl->x_size) - 1; cl->rlist.x_ray_pos = pl->pos_y; cl->rlist.y_ray_pos = pl->pos_x; cl->rlist.x_ray_dir = pl->dir_x + pl->plane_x * pl->cam_x; cl->rlist.y_ray_dir = pl->dir_y + pl->plane_y * pl->cam_x; cl->rlist.sqx = (int16_t)cl->rlist.x_ray_pos; cl->rlist.sqy = (int16_t)cl->rlist.y_ray_pos; ft_detect(cl); if (cl->rlist.side == 0) { cl->rlist.wall_dist = (cl->rlist.sqx - cl->rlist.x_ray_pos + (1 - cl->mlist->x_step) / 2) / cl->rlist.x_ray_dir; } else cl->rlist.wall_dist = (cl->rlist.sqy - cl->rlist.y_ray_pos + (1 - cl->mlist->y_step) / 2) / cl->rlist.y_ray_dir; } void ft_castray(t_cub *cl) { uint16_t i; t_win *wl; i = 0; wl = cl->wlist; while (i < wl->x_size) { ft_initray(cl, i); cl->rlist.line_h = (int16_t)(wl->y_size / cl->rlist.wall_dist); cl->rlist.wall_t = -cl->rlist.line_h / 2 + wl->y_size / 2; if (cl->rlist.wall_t < 0) cl->rlist.wall_t = 0; cl->rlist.wall_b = cl->rlist.line_h / 2 + wl->y_size / 2; if (cl->rlist.wall_b >= (float)wl->y_size) cl->rlist.wall_b = wl->y_size - 1; ft_choose_tex(cl); ft_calc_tex(cl); ft_draw_verline(cl, i, cl->rlist.wall_t, cl->rlist.wall_b); i++; } }