oculus1

annotate src/camera.cc @ 29:9a973ef0e2a3

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