goat3dgfx

view src/camera.cc @ 29:9d581abd0bfb

merged
author John Tsiombikas <nuclear@member.fsf.org>
date Sun, 02 Mar 2014 02:18:15 +0200
parents 1868c5975f31
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 }
46 void Camera::use_inverse() const
47 {
48 set_view_matrix(inv_matrix());
49 }
51 void Camera::input_move(float x, float y, float z)
52 {
53 }
55 void Camera::input_rotate(float x, float y, float z)
56 {
57 }
59 void Camera::input_zoom(float factor)
60 {
61 }
64 // ---- orbit camera ----
66 OrbitCamera::OrbitCamera()
67 {
68 theta = 0.0;
69 phi = 0.0;
70 rad = 10.0;
71 }
73 OrbitCamera::~OrbitCamera()
74 {
75 }
77 void OrbitCamera::calc_matrix(Matrix4x4 *mat) const
78 {
79 mat->reset_identity();
80 mat->translate(Vector3(0, 0, -rad));
81 mat->rotate(Vector3(phi, 0, 0));
82 mat->rotate(Vector3(0, theta, 0));
83 mat->rotate(Vector3(0, 0, roll));
84 }
86 void OrbitCamera::calc_inv_matrix(Matrix4x4 *mat) const
87 {
88 mat->reset_identity();
89 mat->rotate(Vector3(0, 0, roll));
90 mat->rotate(Vector3(0, theta, 0));
91 mat->rotate(Vector3(phi, 0, 0));
92 mat->translate(Vector3(0, 0, -rad));
93 }
95 void OrbitCamera::input_rotate(float x, float y, float z)
96 {
97 theta += y;
98 phi += x;
99 roll += z;
101 if(phi < -M_PI / 2)
102 phi = -M_PI / 2;
103 if(phi > M_PI)
104 phi = M_PI;
106 inval_cache();
107 }
109 void OrbitCamera::input_zoom(float factor)
110 {
111 rad += factor;
112 if(rad < 0.0)
113 rad = 0.0;
115 inval_cache();
116 }
118 void FpsCamera::calc_matrix(Matrix4x4 *mat) const
119 {
120 mat->reset_identity();
121 mat->translate(Vector3(pos.x, pos.y, pos.z));
122 mat->rotate(Vector3(0, theta, 0));
123 mat->rotate(Vector3(phi, 0, 0));
124 mat->rotate(Vector3(0, 0, roll));
125 }
127 void FpsCamera::calc_inv_matrix(Matrix4x4 *mat) const
128 {
129 mat->reset_identity();
130 mat->rotate(Vector3(0, 0, roll));
131 mat->rotate(Vector3(phi, 0, 0));
132 mat->rotate(Vector3(0, theta, 0));
133 mat->translate(Vector3(-pos.x, -pos.y, -pos.z));
134 }
136 void FpsCamera::input_move(float x, float y, float z)
137 {
138 pos.x += x * cos(theta) - z * sin(theta);
139 pos.z += x * sin(theta) + z * cos(theta);
140 pos.y += y;
141 inval_cache();
142 }
144 const Vector3 &FpsCamera::get_position() const
145 {
146 return pos;
147 }
150 FlyCamera::FlyCamera()
151 {
152 pos.z = 10.0f;
153 }
155 void FlyCamera::calc_matrix(Matrix4x4 *mat) const
156 {
157 Matrix3x3 rmat = rot.get_rotation_matrix().transposed();
158 Matrix4x4 tmat;
159 tmat.set_translation(pos);
160 *mat = tmat * Matrix4x4(rmat);
161 }
163 /*void FlyCamera::calc_inv_matrix(Matrix4x4 *mat) const
164 {
165 }*/
167 const Vector3 &FlyCamera::get_position() const
168 {
169 return pos;
170 }
172 const Quaternion &FlyCamera::get_rotation() const
173 {
174 return rot;
175 }
177 void FlyCamera::input_move(float x, float y, float z)
178 {
179 static const Vector3 vfwd(0, 0, 1), vright(1, 0, 0);
181 Vector3 k = vfwd.transformed(rot);
182 Vector3 i = vright.transformed(rot);
183 Vector3 j = cross_product(k, i);
185 pos += i * x + j * y + k * z;
186 inval_cache();
187 }
189 void FlyCamera::input_rotate(float x, float y, float z)
190 {
191 Vector3 axis(x, y, z);
192 float axis_len = axis.length();
193 rot.rotate(axis / axis_len, axis_len);
194 rot.normalize();
196 inval_cache();
197 }
200 // --- VR additions ---
201 VRFpsCamera::VRFpsCamera()
202 {
203 neck_eye_dist = 0.14; // default neck->eye distance 14cm
204 }
206 void VRFpsCamera::calc_matrix(Matrix4x4 *mat) const
207 {
208 mat->reset_identity();
209 mat->translate(Vector3(pos.x, pos.y, pos.z));
210 mat->rotate(Vector3(0, theta, 0));
211 mat->rotate(Vector3(phi, 0, 0));
212 mat->rotate(Vector3(0, 0, roll));
213 mat->translate(Vector3(0, neck_eye_dist, 0));
214 }
216 void VRFpsCamera::calc_inv_matrix(Matrix4x4 *mat) const
217 {
218 mat->reset_identity();
219 mat->translate(Vector3(0, -neck_eye_dist, 0));
220 mat->rotate(Vector3(0, 0, roll));
221 mat->rotate(Vector3(phi, 0, 0));
222 mat->rotate(Vector3(0, theta, 0));
223 mat->translate(Vector3(-pos.x, -pos.y, -pos.z));
224 }
226 void VRFpsCamera::track_vr()
227 {
228 float euler[3];
229 vr_get_rotation_euler(euler);
231 // input_rotate invalidates cache
232 input_rotate(prev_angles[0] - euler[0], prev_angles[1] - euler[1], prev_angles[2] - euler[2]);
234 prev_angles[0] = euler[0];
235 prev_angles[1] = euler[1];
236 prev_angles[2] = euler[2];
237 }