-
Notifications
You must be signed in to change notification settings - Fork 2
/
camera.c
124 lines (114 loc) · 3.73 KB
/
camera.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
124
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* camera.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: qloubier <qloubier@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2016/05/28 18:08:25 by snicolet #+# #+# */
/* Updated: 2018/12/28 19:04:34 by snicolet ### ########.fr */
/* */
/* ************************************************************************** */
#include "rt.h"
#include "keyboard.h"
#include "menu.h"
t_obj *rt_obj_getcamera(t_obj *obj)
{
t_obj *x;
t_obj *z;
if (obj->type == CAMERA)
return (obj);
else if (obj)
{
x = obj->childs;
while (x)
{
if (x->type == CAMERA)
return (x);
else if ((z = rt_obj_getcamera(x)))
return (z);
x = x->next;
}
}
return (NULL);
}
void rt_update_camera(t_v2i geometry, t_camera *cam)
{
t_v2d tmp;
cam->fovx = ((double)geometry.x / (double)geometry.y) * cam->fov;
cam->steppx = (t_v2d){cam->fovx / (double)geometry.x,
cam->fov / (double)geometry.y};
cam->rayreset = (t_v4d){
cam->fovx / 2.0,
cam->fov / 2.0,
0.0,
0.0};
tmp = (t_v2d){
((double)geometry.x / (double)geometry.y) * sin((double)cam->fov),
sin((double)cam->fov)};
cam->rayfix = (t_v4d){ tmp.x / 2.0, tmp.y / 2.0,
tmp.x / (double)geometry.x, tmp.y / (double)geometry.y};
}
void camera_rotate(t_rt *rt, const double x, const int dir)
{
t_obj *cam;
struct s_quaternion *q;
cam = rt->root->content;
q = &cam->transform.q;
if (dir & (ROTATE_LEFT | ROTATE_RIGHT))
cam->rotation.y += (dir & ROTATE_LEFT) ? -x : x;
if (dir & (ROTATE_UP | ROTATE_DOWN))
cam->rotation.x += (dir & ROTATE_UP) ? -x : x;
if (dir & ROLL)
cam->rotation.z += (dir & ROLL_LEFT) ? -x : x;
if (dir & ROTATE_LEFT)
*q = geo_quat_mult(*q, geo_quat_rot(cam->transform.axis.y, x));
else if (dir & ROTATE_RIGHT)
*q = geo_quat_mult(*q, geo_quat_rot(cam->transform.axis.y, -x));
if (dir & ROTATE_UP)
*q = geo_quat_mult(*q, geo_quat_rot(cam->transform.axis.x, x));
else if (dir & ROTATE_DOWN)
*q = geo_quat_mult(*q, geo_quat_rot(cam->transform.axis.x, -x));
if (dir & ROLL_LEFT)
*q = geo_quat_mult(*q, geo_quat_rot(cam->transform.axis.z, -x));
else if (dir & ROLL_RIGHT)
*q = geo_quat_mult(*q, geo_quat_rot(cam->transform.axis.z, x));
cam->trans = geo_quat_tomatrix_offset(*q, cam->trans.w);
cam->transform.matrix = cam->trans;
cam->transform.axis = (struct s_world){
.x = geo_apply_v3d(AXIS_X, &cam->trans),
.y = geo_apply_v3d(AXIS_Y, &cam->trans),
.z = geo_apply_v3d(AXIS_Z, &cam->trans)
};
}
void camera_save(t_rt *rt)
{
if (rt->keyboard & MENU)
{
menu_camera_save(rt);
return ;
}
if ((!rt->root) || (!(t_obj*)rt->root->content))
return ;
((t_camera*)((t_obj*)rt->root->content)->content)->origin =
((t_obj*)rt->root->content)->trans;
((t_camera*)((t_obj*)rt->root->content)->content)->origin_rot =
((t_obj*)rt->root->content)->rotation;
}
int camera_reset(t_rt *rt)
{
t_obj *obj;
t_camera *cam;
if (rt->keyboard & MENU)
return (menu_camera_reset(rt));
if (!(obj = rt->root->content))
return (0);
cam = obj->content;
obj->trans = cam->origin;
obj->rotation = cam->origin_rot;
obj->transform.q = geo_quat_from_rot(
(t_v3d){obj->rotation.x, obj->rotation.y, obj->rotation.z});
// obj->trans = geo_quat_tomatrix_offset(cam->q, obj->trans.w);
rt->keyboard |= FORCE_DISPLAY;
return (0);
}