goat3dgfx

annotate 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
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