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