]> git.tdb.fi Git - libs/gl.git/blob - source/camera.cpp
Remove dynamic allocation from VertexFormat
[libs/gl.git] / source / camera.cpp
1 #include <cmath>
2 #include "camera.h"
3 #include "matrix.h"
4
5 namespace Msp {
6 namespace GL {
7
8 Camera::Camera():
9         fov(Geometry::Angle<float>::from_turns(0.125)),
10         height(0),
11         aspect(4.0/3.0),
12         clip_near(0.1),
13         clip_far(10),
14         frustum_x(0),
15         frustum_y(0),
16         position(0, 0, 0),
17         look_dir(0, 0, -1),
18         up_dir(0, 1, 0)
19 {
20         update_projection_matrix();
21         update_object_matrix();
22 }
23
24 void Camera::set_field_of_view(const Geometry::Angle<float> &f)
25 {
26         fov = f;
27         update_projection_matrix();
28 }
29
30 void Camera::set_orthographic(float w, float h)
31 {
32         fov = Geometry::Angle<float>::zero();
33         height = h;
34         if(w)
35                 aspect = w/h;
36         update_projection_matrix();
37 }
38
39 void Camera::set_aspect(float a)
40 {
41         aspect = a;
42         update_projection_matrix();
43 }
44
45 void Camera::set_depth_clip(float n, float f)
46 {
47         clip_near = n;
48         clip_far = f;
49         update_projection_matrix();
50 }
51
52 void Camera::set_frustum_axis(float x, float y)
53 {
54         frustum_x = x;
55         frustum_y = y;
56         update_projection_matrix();
57 }
58
59 void Camera::set_frustum_rotation(const Geometry::Angle<float> &r)
60 {
61         rotate = r;
62         update_projection_matrix();
63 }
64
65 void Camera::set_position(const Vector3 &p)
66 {
67         position = p;
68         update_object_matrix();
69 }
70
71 void Camera::set_up_direction(const Vector3 &u)
72 {
73         up_dir = normalize(u);
74         update_object_matrix();
75 }
76
77 void Camera::set_look_direction(const Vector3 &l)
78 {
79         look_dir = normalize(l);
80         update_object_matrix();
81 }
82
83 void Camera::look_at(const Vector3 &p)
84 {
85         set_look_direction(p-position);
86 }
87
88 Vector3 Camera::project(const Vector4 &p) const
89 {
90         Vector4 r = proj_matrix*(view_matrix*p);
91         return r.slice<3>(0)/r.w;
92 }
93
94 Vector3 Camera::project(const Vector3 &p) const
95 {
96         return project(Vector4(p.x, p.y, p.z, 1.0));
97 }
98
99 Vector4 Camera::unproject(const Vector4 &p) const
100 {
101         Vector4 r = invert(proj_matrix)*Vector4(p.x, p.y, p.z, 1.0f);
102         r = object_matrix*Vector4(r.x/r.w, r.y/r.w, r.z/r.w, p.w);
103         return r;
104 }
105
106 Vector3 Camera::unproject(const Vector3 &p) const
107 {
108         return unproject(Vector4(p.x, p.y, p.z, 1.0f)).slice<3>(0);
109 }
110
111 void Camera::apply() const
112 {
113         MatrixStack::projection() = proj_matrix;
114         MatrixStack::modelview() = view_matrix;
115 }
116
117 void Camera::update_projection_matrix()
118 {
119         float frustum_h = (fov!=Geometry::Angle<float>::zero() ? tan(fov/2.0f)*clip_near : height/2);
120         float frustum_w = frustum_h*aspect;
121         float left = frustum_w*(frustum_x-1.0f);
122         float right = frustum_w*(frustum_x+1.0f);
123         float bottom = frustum_h*(frustum_y-1.0f);
124         float top = frustum_h*(frustum_y+1.0f);
125         if(fov>Geometry::Angle<float>::zero())
126                 proj_matrix = Matrix::frustum(left, right, bottom, top, clip_near, clip_far);
127         else
128                 proj_matrix = Matrix::ortho(left, right, bottom, top, clip_near, clip_far);
129         proj_matrix = Matrix::rotation(rotate, Vector3(0, 0, 1))*proj_matrix;
130 }
131
132 void Camera::update_object_matrix()
133 {
134         Vector3 right_dir = normalize(cross(look_dir, up_dir));
135         Vector4 columns[4];
136         columns[0] = compose(right_dir, 0.0f);
137         columns[1] = compose(cross(right_dir, look_dir), 0.0f);
138         columns[2] = compose(-look_dir, 0.0f);
139         columns[3] = compose(position, 1.0f);
140         object_matrix = Matrix::from_columns(columns);
141         view_matrix = invert(object_matrix);
142 }
143
144 } // namespace GL
145 } // namespace Msp