-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathray_tracing.c
123 lines (112 loc) · 3.42 KB
/
ray_tracing.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ray_tracing.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: jkassand <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2021/10/26 21:24:59 by jkassand #+# #+# */
/* Updated: 2022/02/14 21:36:19 by jkassand ### ########.fr */
/* */
/* ************************************************************************** */
#include "minirt.h"
static void rt_sp_in(t_inter *in, t_vector *ray, t_sphere *sp, t_vector *cam)
{
float dist;
t_sphere *tmp;
in->sp_dist = 0;
tmp = sp;
while (tmp)
{
dist = sp_int(tmp->coord, ray, tmp, cam);
if (dist > 1 && (!in->sp_dist || dist < in->sp_dist))
{
in->sp_dist = dist;
in->sp = tmp;
}
tmp = tmp->next;
}
}
static void rt_pl_in(t_inter *in, t_vector *ray, t_plane *pl, t_vector *cam)
{
float dist;
t_plane *tmp;
in->pl_dist = 0;
tmp = pl;
while (tmp)
{
dist = ray->x * tmp->dir->x + ray->y * tmp->dir->y + \
ray->z * tmp->dir->z;
if (dist)
dist = ((tmp->coord->x - cam->x) * tmp->dir->x + \
(tmp->coord->y - cam->y) * tmp->dir->y + \
(tmp->coord->z - cam->z) * tmp->dir->z) / dist;
if (dist > 1 && (!in->pl_dist || dist < in->pl_dist))
{
in->pl_dist = dist;
in->pl = tmp;
}
tmp = tmp->next;
}
}
void rt_cy_in(t_inter *in, t_vector *ray, t_cylinder *cy, t_vector *cam)
{
float dist;
t_cylinder *tmp;
in->cy_dist = 0;
tmp = cy;
while (tmp)
{
dist = cy_int(tmp->coord, ray, tmp, cam);
if (dist > 1 && (!in->cy_dist || dist < in->cy_dist))
{
in->cy_dist = dist;
in->cy = tmp;
}
tmp = tmp->next;
}
}
static void rt_init(t_raytrace *rt, t_scene *scene)
{
float len_ray;
rt->color = 0;
rt->ray.x = (rt->x - WIDTH / 2) * scene->vp->x;
rt->ray.y = (HEIGHT / 2 - rt->y) * scene->vp->y;
rt->ray.z = -1;
len_ray = sqrtf(rt->ray.x * rt->ray.x + rt->ray.y * rt->ray.y + \
rt->ray.z * rt->ray.z);
rt->ray.x /= len_ray;
rt->ray.y /= len_ray;
rt->ray.z /= len_ray;
rt_sp_in(scene->in, &rt->ray, scene->sp, scene->cam->coord);
rt_pl_in(scene->in, &rt->ray, scene->pl, scene->cam->coord);
rt_cy_in(scene->in, &rt->ray, scene->cy, scene->cam->coord);
rt->sp = scene->in->sp_dist;
rt->pl = scene->in->pl_dist;
rt->cy = scene->in->cy_dist;
}
void ray_tracing(void *mlx_ptr, void *win_ptr, t_scene *scene)
{
t_raytrace rt;
char *dst;
rt.y = -1;
while (++rt.y < HEIGHT)
{
rt.x = -1;
while (++rt.x < WIDTH)
{
rt_init(&rt, scene);
if (rt.sp && ((rt.pl && rt.sp < rt.pl) || !rt.pl)
&& ((rt.cy && rt.sp < rt.cy) || !rt.cy))
rt.color = get_sp_color(scene, &rt.ray, rt.sp);
else if (rt.pl && ((rt.cy && rt.pl < rt.cy) || !rt.cy))
rt.color = get_pl_color(scene, &rt.ray, rt.pl);
else if (rt.cy)
rt.color = get_cy_color(scene, &rt.ray, rt.cy);
dst = scene->img->addr + rt.y * scene->img->line_length + \
rt.x * (scene->img->bits_per_pixel / 8);
*(unsigned int *)dst = rt.color;
}
}
mlx_put_image_to_window(mlx_ptr, win_ptr, scene->img->img, 0, 0);
}