symmetry

view src/camera.cc @ 0:a90a71a74f0b

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