oculus1

view src/camera.cc @ 11:39ec672a5158

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