Cub3D/srcs/cast_ray.c
2022-05-05 03:07:10 +02:00

251 lines
6.7 KiB
C

/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* cast_ray.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/05/04 18:08:14 by apommier #+# #+# */
/* Updated: 2022/05/05 02:59:14 by apommier ### ########.fr */
/* */
/* ************************************************************************** */
#include "../includes/Cub3D.h"
void print_ray2(t_data *img, float vx, float vy, float dist)
{
int i = -1;
int red = 0;
red = red << 8;
red +=255;
red = red << 8;
red = red << 8;
while (++i < dist)
{
mlx_pixel_put(img->mlx, img->mlx_win, (img->player.x + (vx) * i) , (img->player.y + (vy) * i) , red);
mlx_pixel_put(img->mlx, img->mlx_win, (img->player.x + (vx) * i) + 1, (img->player.y + (vy) * i) , red);
mlx_pixel_put(img->mlx, img->mlx_win, (img->player.x + (vx) * i) , (img->player.y + (vy) * i) + 1, red);
}
}
int get_color(char one, char two, char three)
{
int color = 0;
color = color << 8;
color += one;
color = color << 8;
color += two;
color = color << 8;
color += three;
return (color);
}
int get_red()
{
int red = 0;
red = red << 8;
red +=255;
red = red << 8;
red = red << 8;
return (red);
}
int get_dark_red()
{
int red = 0;
red = red << 8;
red +=139;
red = red << 8;
red = red << 8;
return (red);
}
void draw_ray3d(t_data *img, float dist, int ray, int type)
{
float line_height;
float line_offset;
int i;
int y;
i = 0;
line_height = img->map.size * 320 / dist;
if (line_height > 320)
line_height = 320;
line_offset = 160 - line_height / 2;
while (i < 8)
{
y = 0;
while (y < line_height)
{
if (type)
mlx_pixel_put(img->mlx, img->mlx_win, ray * 8 + 530 + i, y + line_offset , get_red());
else
mlx_pixel_put(img->mlx, img->mlx_win, ray * 8 + 530 + i, y + line_offset , get_dark_red());
y++;
}
i++;
}
}
void draw_ray(t_data *img)
{
float ray_angle = 0; //ray angle
float ray_y = 0; //where ray touch x
float ray_x = 0; //where ray touch y
float next_x = 0;
float next_y = 0;
float dist_v;
float dist_h;
float dist_f;
float vx = 0;
float vy = 0;
int count = 0;
float aTan = 0;
int nb_ray = -1;
int my = 0;
int mx = 0;
int mp = 0;
(void)dist_f;
//printf("\nENTER DRAW RAY\n");
//while (++k < ft_strlen(img->map.simple_map))
// printf("%d--- %c\n", k, img->map.simple_map[k]);
//printf("map = -%s-\n", img->map.simple_map);
count = 0;
ray_angle = reset_angle(img->player.angle + 30);
//ray_angle = reset_angle(img->player.angle);
while (++nb_ray < 60)
{
//if (nb_ray)
// ray_angle -= 30;
count = 0;
dist_v = -1;
dist_h = -1;
//printf("------RAY N0 %d-------\n", nb_ray);
//printf("player_angle= %f ray_angle= %f\n", img->player.angle, ray_angle);
//----------start vertical ray----------
aTan = tan(deg_to_rad(ray_angle));
if (cos(deg_to_rad(ray_angle)) > 0.001)//looking left
{
ray_x = (((int)img->player.x>>6)<<6) + 64;
ray_y = (img->player.x - ray_x) * aTan + img->player.y;
next_x = 64;
next_y = -next_x * aTan;
}
else if (cos(deg_to_rad(ray_angle)) < -0.001)//looking right
{
ray_x = (((int)img->player.x>>6)<<6) - 0.0001;
ray_y = (img->player.x - ray_x) * aTan + img->player.y;
next_x = -64;
next_y = -next_x * aTan;
}
else
{
ray_x = img->player.x;
ray_y = img->player.y;
count = 8;
}
//if (next_x > 0)
// printf("for hroizon looking left\n");
//else
// printf("for hroizon looking right\n");
//printf("\nray_y= %f ray_x= %f\n", ray_y, ray_x);
//printf("next_y= %f next_x= %f\n", next_y, next_x);
//printf("BASE p_y= %f p_x= %f\n", img->player.y, img->player.x);
while (count < 8)
{
//printf("count = %d\n", count);
mx = (int)(ray_x)>>6;
my = (int)(ray_y)>>6;
mp = my * img->map.x + mx;
//printf("mx=%d my=%d mp= %d\n", mx, my, mp);
if (mp > 0 && mp < img->map.x * img->map.y && img->map.simple_map[mp] == '1')//hit wall
{
count = 8;
//printf("vertical wall\n");
dist_v = cos(deg_to_rad(ray_angle)) * (ray_x-img->player.x) - sin(deg_to_rad(ray_angle)) * (ray_y-img->player.y);
}
else
{
ray_x += next_x;
ray_y += next_y;
count += 1;
}
}
//print_ray2(img, img->player.vx, img->player.vy, dist_v);
vx = ray_x;
vy = ray_y;
//-------start horizontal ray---------
count = 0;
aTan = 1.0 / aTan;
if (sin(deg_to_rad(ray_angle)) > 0.001)//looking up
{
ray_y = (((int)img->player.y>>6)<<6) - 0.0001;
ray_x = (img->player.y - ray_y) * aTan + img->player.x;
next_y = -64;
next_x = -next_y * aTan;
}
else if (sin(deg_to_rad(ray_angle))<-0.001)//looking down
{
ray_y = (((int)img->player.y>>6)<<6) + 64;
ray_x = (img->player.y - ray_y) * aTan + img->player.x;
next_y = 64;
next_x = -next_y * aTan;
}
else
{
ray_x = img->player.x;
ray_y = img->player.y;
count = 8;
}//looking straight left or right
while (count<8)
{
//printf("ray_y= %f ray_x= %f\n", ray_y, ray_x);
mx = (int)(ray_x)>>6;
my = (int)(ray_y)>>6;
mp = my * img->map.x + mx;
//printf("mx=%d my=%d mp= %d\n", mx, my, mp);
if (mp > 0 && mp < img->map.x * img->map.y && img->map.simple_map[mp] == '1')
{
count = 8;
//printf ("horizontal wall\n");
//printf("case: x= %d, y= %d mp= %d\n", mx, my, mp);
dist_h = cos(deg_to_rad(ray_angle)) * (ray_x - img->player.x) - sin(deg_to_rad(ray_angle)) * (ray_y - img->player.y);
}//hit
else
{
ray_x += next_x;
ray_y += next_y;
count += 1;
} //check next horizontal
}
//printf("dist_h= %f dist_v= %f\n", dist_h, dist_v);
vx = cos(deg_to_rad(ray_angle));
vy = -sin(deg_to_rad(ray_angle));
//printf("player.vx= %f vx= %f player.vy= %f vy= %f\n", img->player.vx, vx, img->player.vy, vy);
int wall_type;
if (dist_h != -1 && (dist_h < dist_v || dist_v == -1))
{
print_ray2(img, vx, vy, fabs(dist_h));
dist_f = dist_h;
wall_type = 0;
}
else if (dist_v != -1)
{
dist_f = dist_v;
print_ray2(img, vx, vy, fabs(dist_v));
wall_type = 1;
}
else
dist_f = 0;
int ca = reset_angle(img->player.angle - ray_angle); //fisheye
dist_f = dist_f * cos(deg_to_rad(ca)); //fisheye
draw_ray3d(img, dist_f, nb_ray, wall_type);
ray_angle = reset_angle(ray_angle - 1);
}
}