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