bloboland
diff src/camera.cc @ 1:cfe68befb7cc
some progress
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sat, 15 Dec 2012 23:43:03 +0200 |
parents | |
children | a39c301cdcce |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/camera.cc Sat Dec 15 23:43:03 2012 +0200 1.3 @@ -0,0 +1,237 @@ 1.4 +#include "opengl.h" 1.5 +#include "camera.h" 1.6 + 1.7 +Camera::Camera() 1.8 +{ 1.9 + inval_cache(); 1.10 +} 1.11 + 1.12 +Camera::~Camera() 1.13 +{ 1.14 +} 1.15 + 1.16 +void Camera::calc_inv_matrix(Matrix4x4 *mat) const 1.17 +{ 1.18 + *mat = matrix().inverse(); 1.19 +} 1.20 + 1.21 +void Camera::set_glmat(const Matrix4x4 &mat) const 1.22 +{ 1.23 +#ifdef SINGLE_PRECISION_MATH 1.24 + if(glLoadTransposeMatrixfARB) { 1.25 + glLoadTransposeMatrixfARB((float*)&mat); 1.26 + } else { 1.27 + Matrix4x4 tmat = mat.transposed(); 1.28 + glLoadMatrixf((float*)&tmat); 1.29 + } 1.30 +#else 1.31 + if(glLoadTransposeMatrixdARB) { 1.32 + glLoadTransposeMatrixdARB((double*)&mat); 1.33 + } else { 1.34 + Matrix4x4 tmat = mat.transposed(); 1.35 + glLoadMatrixd((double*)&tmat); 1.36 + } 1.37 +#endif 1.38 +} 1.39 + 1.40 +const Matrix4x4 &Camera::matrix() const 1.41 +{ 1.42 + if(!mcache.valid) { 1.43 + calc_matrix(&mcache.mat); 1.44 + mcache.valid = true; 1.45 + } 1.46 + return mcache.mat; 1.47 +} 1.48 + 1.49 +const Matrix4x4 &Camera::inv_matrix() const 1.50 +{ 1.51 + if(!mcache_inv.valid) { 1.52 + calc_inv_matrix(&mcache_inv.mat); 1.53 + mcache_inv.valid = true; 1.54 + } 1.55 + return mcache_inv.mat; 1.56 +} 1.57 + 1.58 +void Camera::use() const 1.59 +{ 1.60 + set_glmat(matrix()); 1.61 +} 1.62 + 1.63 +void Camera::use_inverse() const 1.64 +{ 1.65 + set_glmat(inv_matrix()); 1.66 +} 1.67 + 1.68 +void Camera::input_move(float x, float y, float z) 1.69 +{ 1.70 +} 1.71 + 1.72 +void Camera::input_rotate(float x, float y, float z) 1.73 +{ 1.74 +} 1.75 + 1.76 +void Camera::input_zoom(float factor) 1.77 +{ 1.78 +} 1.79 + 1.80 + 1.81 +// ---- orbit camera ---- 1.82 + 1.83 +OrbitCamera::OrbitCamera() 1.84 +{ 1.85 + theta = 0.0; 1.86 + phi = 0.0; 1.87 + rad = 10.0; 1.88 + 1.89 + min_phi = -M_PI / 2; 1.90 + max_phi = M_PI / 2; 1.91 +} 1.92 + 1.93 +OrbitCamera::~OrbitCamera() 1.94 +{ 1.95 +} 1.96 + 1.97 +void OrbitCamera::set_distance(float dist) 1.98 +{ 1.99 + rad = dist; 1.100 +} 1.101 + 1.102 +#define MIN(a, b) ((a) < (b) ? (a) : (b)) 1.103 +#define MAX(a, b) ((a) > (b) ? (a) : (b)) 1.104 +void OrbitCamera::set_vertical_limits(float a, float b) 1.105 +{ 1.106 + a = M_PI * a / 180.0; 1.107 + b = M_PI * b / 180.0; 1.108 + min_phi = MIN(a, b); 1.109 + max_phi = MAX(a, b); 1.110 +} 1.111 + 1.112 +void OrbitCamera::calc_matrix(Matrix4x4 *mat) const 1.113 +{ 1.114 + mat->reset_identity(); 1.115 + mat->translate(Vector3(0, 0, -rad)); 1.116 + mat->rotate(Vector3(phi, 0, 0)); 1.117 + mat->rotate(Vector3(0, theta, 0)); 1.118 +} 1.119 + 1.120 +void OrbitCamera::calc_inv_matrix(Matrix4x4 *mat) const 1.121 +{ 1.122 + mat->reset_identity(); 1.123 + mat->rotate(Vector3(0, theta, 0)); 1.124 + mat->rotate(Vector3(phi, 0, 0)); 1.125 + mat->translate(Vector3(0, 0, -rad)); 1.126 +} 1.127 + 1.128 +void OrbitCamera::input_rotate(float x, float y, float z) 1.129 +{ 1.130 + theta += x; 1.131 + phi += y; 1.132 + 1.133 + if(phi < min_phi) 1.134 + phi = min_phi; 1.135 + if(phi > max_phi) 1.136 + phi = max_phi; 1.137 + 1.138 + inval_cache(); 1.139 +} 1.140 + 1.141 +void OrbitCamera::input_zoom(float factor) 1.142 +{ 1.143 + rad += factor; 1.144 + if(rad < 0.0) 1.145 + rad = 0.0; 1.146 + 1.147 + inval_cache(); 1.148 +} 1.149 + 1.150 +void FpsCamera::calc_matrix(Matrix4x4 *mat) const 1.151 +{ 1.152 + mat->reset_identity(); 1.153 + mat->translate(Vector3(pos.x, pos.y, pos.z)); 1.154 + mat->rotate(Vector3(0, theta, 0)); 1.155 + mat->rotate(Vector3(phi, 0, 0)); 1.156 +} 1.157 + 1.158 +void FpsCamera::calc_inv_matrix(Matrix4x4 *mat) const 1.159 +{ 1.160 + mat->reset_identity(); 1.161 + mat->rotate(Vector3(phi, 0, 0)); 1.162 + mat->rotate(Vector3(0, theta, 0)); 1.163 + mat->translate(Vector3(-pos.x, -pos.y, -pos.z)); 1.164 +} 1.165 + 1.166 +void FpsCamera::input_move(float x, float y, float z) 1.167 +{ 1.168 + pos.x += x * cos(theta) - z * sin(theta); 1.169 + pos.z += x * sin(theta) + z * cos(theta); 1.170 + pos.y += y; 1.171 + inval_cache(); 1.172 +} 1.173 + 1.174 +const Vector3 &FpsCamera::get_position() const 1.175 +{ 1.176 + return pos; 1.177 +} 1.178 + 1.179 + 1.180 +FlyCamera::FlyCamera() 1.181 +{ 1.182 + pos.z = 10.0f; 1.183 +} 1.184 + 1.185 +void FlyCamera::calc_matrix(Matrix4x4 *mat) const 1.186 +{ 1.187 + /*mat->reset_identity(); 1.188 + mat->translate(-pos); 1.189 + *mat = *mat * Matrix4x4(rot.get_rotation_matrix()); 1.190 + mat->translate(pos);*/ 1.191 + //mat->translate(-pos.transformed(rot)); 1.192 + 1.193 + Matrix3x3 qmat = rot.get_rotation_matrix(); 1.194 + 1.195 + Vector3 ivec = qmat.get_row_vector(0); 1.196 + Vector3 jvec = qmat.get_row_vector(1); 1.197 + Vector3 kvec = qmat.get_row_vector(2); 1.198 + 1.199 + *mat = Matrix4x4(qmat); 1.200 + /*Vector3 trans_x = ivec * pos; 1.201 + Vector3 trans_y = jvec * pos; 1.202 + Vector3 trans_z = kvec * pos; 1.203 + Vector3 trans = trans_x + trans_y + trans_z;*/ 1.204 + Vector3 trans; 1.205 + trans.x = dot_product(ivec, pos); 1.206 + trans.y = dot_product(jvec, pos); 1.207 + trans.z = dot_product(kvec, pos); 1.208 + mat->set_column_vector(-trans, 3); 1.209 +} 1.210 + 1.211 +/*void FlyCamera::calc_inv_matrix(Matrix4x4 *mat) const 1.212 +{ 1.213 + mat->set_translation(pos); 1.214 + *mat = *mat * Matrix4x4(rot.get_rotation_matrix()); 1.215 +}*/ 1.216 + 1.217 +const Vector3 &FlyCamera::get_position() const 1.218 +{ 1.219 + return pos; 1.220 +} 1.221 + 1.222 +const Quaternion &FlyCamera::get_rotation() const 1.223 +{ 1.224 + return rot; 1.225 +} 1.226 + 1.227 +void FlyCamera::input_move(float x, float y, float z) 1.228 +{ 1.229 + pos += Vector3(x, y, z); 1.230 + inval_cache(); 1.231 +} 1.232 + 1.233 +void FlyCamera::input_rotate(float x, float y, float z) 1.234 +{ 1.235 + Vector3 axis(x, y, z); 1.236 + float axis_len = axis.length(); 1.237 + rot.rotate(axis / axis_len, axis_len); 1.238 + rot.normalize(); 1.239 + inval_cache(); 1.240 +}