bloboland
view src/camera.cc @ 3:a39c301cdcce
terrain raytracing pretty much done
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sun, 16 Dec 2012 14:24:16 +0200 |
parents | cfe68befb7cc |
children |
line source
1 #include "opengl.h"
2 #include "camera.h"
4 Camera::Camera()
5 {
6 inval_cache();
7 }
9 Camera::~Camera()
10 {
11 }
13 void Camera::calc_inv_matrix(Matrix4x4 *mat) const
14 {
15 *mat = matrix().inverse();
16 }
18 void Camera::set_glmat(const Matrix4x4 &mat) const
19 {
20 #ifdef SINGLE_PRECISION_MATH
21 if(glLoadTransposeMatrixfARB) {
22 glLoadTransposeMatrixfARB((float*)&mat);
23 } else {
24 Matrix4x4 tmat = mat.transposed();
25 glLoadMatrixf((float*)&tmat);
26 }
27 #else
28 if(glLoadTransposeMatrixdARB) {
29 glLoadTransposeMatrixdARB((double*)&mat);
30 } else {
31 Matrix4x4 tmat = mat.transposed();
32 glLoadMatrixd((double*)&tmat);
33 }
34 #endif
35 }
37 const Matrix4x4 &Camera::matrix() const
38 {
39 if(!mcache.valid) {
40 calc_matrix(&mcache.mat);
41 mcache.valid = true;
42 }
43 return mcache.mat;
44 }
46 const Matrix4x4 &Camera::inv_matrix() const
47 {
48 if(!mcache_inv.valid) {
49 calc_inv_matrix(&mcache_inv.mat);
50 mcache_inv.valid = true;
51 }
52 return mcache_inv.mat;
53 }
55 void Camera::use() const
56 {
57 set_glmat(matrix());
58 }
60 void Camera::use_inverse() const
61 {
62 set_glmat(inv_matrix());
63 }
65 void Camera::input_move(float x, float y, float z)
66 {
67 }
69 void Camera::input_rotate(float x, float y, float z)
70 {
71 }
73 void Camera::input_zoom(float factor)
74 {
75 }
78 // ---- orbit camera ----
80 OrbitCamera::OrbitCamera()
81 {
82 theta = 0.0;
83 phi = 0.0;
84 rad = 10.0;
86 min_phi = -M_PI / 2;
87 max_phi = M_PI / 2;
88 }
90 OrbitCamera::~OrbitCamera()
91 {
92 }
94 void OrbitCamera::set_distance(float dist)
95 {
96 rad = dist;
97 }
99 #define MIN(a, b) ((a) < (b) ? (a) : (b))
100 #define MAX(a, b) ((a) > (b) ? (a) : (b))
101 void OrbitCamera::set_vertical_limits(float a, float b)
102 {
103 a = M_PI * a / 180.0;
104 b = M_PI * b / 180.0;
105 min_phi = MIN(a, b);
106 max_phi = MAX(a, b);
107 }
109 void OrbitCamera::calc_matrix(Matrix4x4 *mat) const
110 {
111 mat->reset_identity();
112 mat->translate(Vector3(0, 0, -rad));
113 mat->rotate(Vector3(phi, 0, 0));
114 mat->rotate(Vector3(0, theta, 0));
115 }
117 void OrbitCamera::calc_inv_matrix(Matrix4x4 *mat) const
118 {
119 mat->reset_identity();
120 mat->rotate(Vector3(0, theta, 0));
121 mat->rotate(Vector3(phi, 0, 0));
122 mat->translate(Vector3(0, 0, -rad));
123 }
125 void OrbitCamera::input_rotate(float x, float y, float z)
126 {
127 theta += x;
128 phi += y;
130 if(phi < min_phi)
131 phi = min_phi;
132 if(phi > max_phi)
133 phi = max_phi;
135 inval_cache();
136 }
138 void OrbitCamera::input_zoom(float factor)
139 {
140 rad += factor;
141 if(rad < 0.0)
142 rad = 0.0;
144 inval_cache();
145 }
147 void FpsCamera::calc_matrix(Matrix4x4 *mat) const
148 {
149 mat->reset_identity();
150 mat->translate(Vector3(pos.x, pos.y, pos.z));
151 mat->rotate(Vector3(0, -theta, 0));
152 mat->rotate(Vector3(-phi, 0, 0));
153 }
155 void FpsCamera::calc_inv_matrix(Matrix4x4 *mat) const
156 {
157 mat->reset_identity();
158 mat->rotate(Vector3(phi, 0, 0));
159 mat->rotate(Vector3(0, theta, 0));
160 mat->translate(Vector3(-pos.x, -pos.y, -pos.z));
161 }
163 void FpsCamera::input_move(float x, float y, float z)
164 {
165 pos.x += x * cos(theta) - z * sin(theta);
166 pos.z += x * sin(theta) + z * cos(theta);
167 pos.y += y;
168 inval_cache();
169 }
171 const Vector3 &FpsCamera::get_position() const
172 {
173 return pos;
174 }
177 FlyCamera::FlyCamera()
178 {
179 pos.z = 10.0f;
180 }
182 void FlyCamera::calc_matrix(Matrix4x4 *mat) const
183 {
184 /*mat->reset_identity();
185 mat->translate(-pos);
186 *mat = *mat * Matrix4x4(rot.get_rotation_matrix());
187 mat->translate(pos);*/
188 //mat->translate(-pos.transformed(rot));
190 Matrix3x3 qmat = rot.get_rotation_matrix();
192 Vector3 ivec = qmat.get_row_vector(0);
193 Vector3 jvec = qmat.get_row_vector(1);
194 Vector3 kvec = qmat.get_row_vector(2);
196 *mat = Matrix4x4(qmat);
197 /*Vector3 trans_x = ivec * pos;
198 Vector3 trans_y = jvec * pos;
199 Vector3 trans_z = kvec * pos;
200 Vector3 trans = trans_x + trans_y + trans_z;*/
201 Vector3 trans;
202 trans.x = dot_product(ivec, pos);
203 trans.y = dot_product(jvec, pos);
204 trans.z = dot_product(kvec, pos);
205 mat->set_column_vector(-trans, 3);
206 }
208 /*void FlyCamera::calc_inv_matrix(Matrix4x4 *mat) const
209 {
210 mat->set_translation(pos);
211 *mat = *mat * Matrix4x4(rot.get_rotation_matrix());
212 }*/
214 const Vector3 &FlyCamera::get_position() const
215 {
216 return pos;
217 }
219 const Quaternion &FlyCamera::get_rotation() const
220 {
221 return rot;
222 }
224 void FlyCamera::input_move(float x, float y, float z)
225 {
226 pos += Vector3(x, y, z);
227 inval_cache();
228 }
230 void FlyCamera::input_rotate(float x, float y, float z)
231 {
232 Vector3 axis(x, y, z);
233 float axis_len = axis.length();
234 rot.rotate(axis / axis_len, axis_len);
235 rot.normalize();
236 inval_cache();
237 }