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