summaryrefslogtreecommitdiff
path: root/camera.h
blob: 0dad35d22e92f0f6ce81223f62888f58d2ec38eb (plain)
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
mat4 camera_get_view_mat(camera_t camera)
{
	mat4 view = mat4_make_transl(v3_inv(camera.position));
	view = mat4_rotate(view, camera.angles);
	return view;
}

void camera_get_vecs(camera_t camera, v3 *left, v3 *up, v3 *front)
{
	f32 angle = deg2rad(camera.angles.x);
	f32 cp = fcos(angle);
	f32 sp = fsin(angle);

	angle = deg2rad(camera.angles.y);
	f32 cy = fcos(angle);
	f32 sy = fsin(angle);

	angle = deg2rad(camera.angles.z);
	f32 cr = fcos(angle);
	f32 sr = fsin(angle);

	*left = (v3){cy*cr, -cy*sr, sy};
	*up = (v3){sp*sy*cr+cp*sr, -sp*sy*sr+cp*cr, -sp*cy};
	*front = (v3){-cp*sy*cr+sp*sr, cp*sy*sr+sp*cr, cp*cy};
}

mat4 camera_lookat(camera_t camera, v3 target, v3 world_up)
{
	v3 front = v3_norm(v3_sub(camera.position, target));
	v3 right = v3_norm(v3_cross(world_up, front));
	v3 up = v3_cross(front, right);

	mat4 translate = mat4_make_transl(v3_inv(camera.position));
	mat4 rotate = mat4_transp(mat4_make_rotate(right, up, front));
	mat4 result = mat4_mul(rotate, translate);

	return result;
}

mat4 ortho(f32 l, f32 r, f32 b, f32 t, f32 n, f32 f)
{
	mat4 ortho = MAT4_IDENTITY;
	ortho.c0.x = 2.0f/(r-l);
	ortho.c1.y = 2.0f/(t-b);
	ortho.c2.z = -2.0f/(f-n);
	ortho.c3.x = -(r+l)/(r-l);
	ortho.c3.y = -(t+b)/(t-b);
	ortho.c3.z = -(f+n)/(f-n);
	return ortho;
}

mat4 perspective(camera_t camera, f32 aspect_ratio)
{
	f32 n = camera.near;
	f32 f = camera.far;

	f32 r = n*ftan(deg2rad(camera.fov/2.0f));
	f32 t = r/aspect_ratio;

	mat4 perspective = MAT4_IDENTITY;
	perspective.c0.x = n/r;
	perspective.c1.y = n/t;
	perspective.c2.z = -(f+n)/(f-n);
	perspective.c2.w = -1.0f;
	perspective.c3.z = (-2.0f*f*n)/(f-n);
	perspective.c3.w = 0.0f;

	return perspective;
}