goat3dgfx

view src/camera.cc @ 12:1868c5975f31

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