bloboland

annotate src/camera.cc @ 3:a39c301cdcce

terrain raytracing pretty much done
author John Tsiombikas <nuclear@member.fsf.org>
date Sun, 16 Dec 2012 14:24:16 +0200
parents cfe68befb7cc
children
rev   line source
nuclear@1 1 #include "opengl.h"
nuclear@1 2 #include "camera.h"
nuclear@1 3
nuclear@1 4 Camera::Camera()
nuclear@1 5 {
nuclear@1 6 inval_cache();
nuclear@1 7 }
nuclear@1 8
nuclear@1 9 Camera::~Camera()
nuclear@1 10 {
nuclear@1 11 }
nuclear@1 12
nuclear@1 13 void Camera::calc_inv_matrix(Matrix4x4 *mat) const
nuclear@1 14 {
nuclear@1 15 *mat = matrix().inverse();
nuclear@1 16 }
nuclear@1 17
nuclear@1 18 void Camera::set_glmat(const Matrix4x4 &mat) const
nuclear@1 19 {
nuclear@1 20 #ifdef SINGLE_PRECISION_MATH
nuclear@1 21 if(glLoadTransposeMatrixfARB) {
nuclear@1 22 glLoadTransposeMatrixfARB((float*)&mat);
nuclear@1 23 } else {
nuclear@1 24 Matrix4x4 tmat = mat.transposed();
nuclear@1 25 glLoadMatrixf((float*)&tmat);
nuclear@1 26 }
nuclear@1 27 #else
nuclear@1 28 if(glLoadTransposeMatrixdARB) {
nuclear@1 29 glLoadTransposeMatrixdARB((double*)&mat);
nuclear@1 30 } else {
nuclear@1 31 Matrix4x4 tmat = mat.transposed();
nuclear@1 32 glLoadMatrixd((double*)&tmat);
nuclear@1 33 }
nuclear@1 34 #endif
nuclear@1 35 }
nuclear@1 36
nuclear@1 37 const Matrix4x4 &Camera::matrix() const
nuclear@1 38 {
nuclear@1 39 if(!mcache.valid) {
nuclear@1 40 calc_matrix(&mcache.mat);
nuclear@1 41 mcache.valid = true;
nuclear@1 42 }
nuclear@1 43 return mcache.mat;
nuclear@1 44 }
nuclear@1 45
nuclear@1 46 const Matrix4x4 &Camera::inv_matrix() const
nuclear@1 47 {
nuclear@1 48 if(!mcache_inv.valid) {
nuclear@1 49 calc_inv_matrix(&mcache_inv.mat);
nuclear@1 50 mcache_inv.valid = true;
nuclear@1 51 }
nuclear@1 52 return mcache_inv.mat;
nuclear@1 53 }
nuclear@1 54
nuclear@1 55 void Camera::use() const
nuclear@1 56 {
nuclear@1 57 set_glmat(matrix());
nuclear@1 58 }
nuclear@1 59
nuclear@1 60 void Camera::use_inverse() const
nuclear@1 61 {
nuclear@1 62 set_glmat(inv_matrix());
nuclear@1 63 }
nuclear@1 64
nuclear@1 65 void Camera::input_move(float x, float y, float z)
nuclear@1 66 {
nuclear@1 67 }
nuclear@1 68
nuclear@1 69 void Camera::input_rotate(float x, float y, float z)
nuclear@1 70 {
nuclear@1 71 }
nuclear@1 72
nuclear@1 73 void Camera::input_zoom(float factor)
nuclear@1 74 {
nuclear@1 75 }
nuclear@1 76
nuclear@1 77
nuclear@1 78 // ---- orbit camera ----
nuclear@1 79
nuclear@1 80 OrbitCamera::OrbitCamera()
nuclear@1 81 {
nuclear@1 82 theta = 0.0;
nuclear@1 83 phi = 0.0;
nuclear@1 84 rad = 10.0;
nuclear@1 85
nuclear@1 86 min_phi = -M_PI / 2;
nuclear@1 87 max_phi = M_PI / 2;
nuclear@1 88 }
nuclear@1 89
nuclear@1 90 OrbitCamera::~OrbitCamera()
nuclear@1 91 {
nuclear@1 92 }
nuclear@1 93
nuclear@1 94 void OrbitCamera::set_distance(float dist)
nuclear@1 95 {
nuclear@1 96 rad = dist;
nuclear@1 97 }
nuclear@1 98
nuclear@1 99 #define MIN(a, b) ((a) < (b) ? (a) : (b))
nuclear@1 100 #define MAX(a, b) ((a) > (b) ? (a) : (b))
nuclear@1 101 void OrbitCamera::set_vertical_limits(float a, float b)
nuclear@1 102 {
nuclear@1 103 a = M_PI * a / 180.0;
nuclear@1 104 b = M_PI * b / 180.0;
nuclear@1 105 min_phi = MIN(a, b);
nuclear@1 106 max_phi = MAX(a, b);
nuclear@1 107 }
nuclear@1 108
nuclear@1 109 void OrbitCamera::calc_matrix(Matrix4x4 *mat) const
nuclear@1 110 {
nuclear@1 111 mat->reset_identity();
nuclear@1 112 mat->translate(Vector3(0, 0, -rad));
nuclear@1 113 mat->rotate(Vector3(phi, 0, 0));
nuclear@1 114 mat->rotate(Vector3(0, theta, 0));
nuclear@1 115 }
nuclear@1 116
nuclear@1 117 void OrbitCamera::calc_inv_matrix(Matrix4x4 *mat) const
nuclear@1 118 {
nuclear@1 119 mat->reset_identity();
nuclear@1 120 mat->rotate(Vector3(0, theta, 0));
nuclear@1 121 mat->rotate(Vector3(phi, 0, 0));
nuclear@1 122 mat->translate(Vector3(0, 0, -rad));
nuclear@1 123 }
nuclear@1 124
nuclear@1 125 void OrbitCamera::input_rotate(float x, float y, float z)
nuclear@1 126 {
nuclear@1 127 theta += x;
nuclear@1 128 phi += y;
nuclear@1 129
nuclear@1 130 if(phi < min_phi)
nuclear@1 131 phi = min_phi;
nuclear@1 132 if(phi > max_phi)
nuclear@1 133 phi = max_phi;
nuclear@1 134
nuclear@1 135 inval_cache();
nuclear@1 136 }
nuclear@1 137
nuclear@1 138 void OrbitCamera::input_zoom(float factor)
nuclear@1 139 {
nuclear@1 140 rad += factor;
nuclear@1 141 if(rad < 0.0)
nuclear@1 142 rad = 0.0;
nuclear@1 143
nuclear@1 144 inval_cache();
nuclear@1 145 }
nuclear@1 146
nuclear@1 147 void FpsCamera::calc_matrix(Matrix4x4 *mat) const
nuclear@1 148 {
nuclear@1 149 mat->reset_identity();
nuclear@1 150 mat->translate(Vector3(pos.x, pos.y, pos.z));
nuclear@3 151 mat->rotate(Vector3(0, -theta, 0));
nuclear@3 152 mat->rotate(Vector3(-phi, 0, 0));
nuclear@1 153 }
nuclear@1 154
nuclear@1 155 void FpsCamera::calc_inv_matrix(Matrix4x4 *mat) const
nuclear@1 156 {
nuclear@1 157 mat->reset_identity();
nuclear@1 158 mat->rotate(Vector3(phi, 0, 0));
nuclear@1 159 mat->rotate(Vector3(0, theta, 0));
nuclear@1 160 mat->translate(Vector3(-pos.x, -pos.y, -pos.z));
nuclear@1 161 }
nuclear@1 162
nuclear@1 163 void FpsCamera::input_move(float x, float y, float z)
nuclear@1 164 {
nuclear@1 165 pos.x += x * cos(theta) - z * sin(theta);
nuclear@1 166 pos.z += x * sin(theta) + z * cos(theta);
nuclear@1 167 pos.y += y;
nuclear@1 168 inval_cache();
nuclear@1 169 }
nuclear@1 170
nuclear@1 171 const Vector3 &FpsCamera::get_position() const
nuclear@1 172 {
nuclear@1 173 return pos;
nuclear@1 174 }
nuclear@1 175
nuclear@1 176
nuclear@1 177 FlyCamera::FlyCamera()
nuclear@1 178 {
nuclear@1 179 pos.z = 10.0f;
nuclear@1 180 }
nuclear@1 181
nuclear@1 182 void FlyCamera::calc_matrix(Matrix4x4 *mat) const
nuclear@1 183 {
nuclear@1 184 /*mat->reset_identity();
nuclear@1 185 mat->translate(-pos);
nuclear@1 186 *mat = *mat * Matrix4x4(rot.get_rotation_matrix());
nuclear@1 187 mat->translate(pos);*/
nuclear@1 188 //mat->translate(-pos.transformed(rot));
nuclear@1 189
nuclear@1 190 Matrix3x3 qmat = rot.get_rotation_matrix();
nuclear@1 191
nuclear@1 192 Vector3 ivec = qmat.get_row_vector(0);
nuclear@1 193 Vector3 jvec = qmat.get_row_vector(1);
nuclear@1 194 Vector3 kvec = qmat.get_row_vector(2);
nuclear@1 195
nuclear@1 196 *mat = Matrix4x4(qmat);
nuclear@1 197 /*Vector3 trans_x = ivec * pos;
nuclear@1 198 Vector3 trans_y = jvec * pos;
nuclear@1 199 Vector3 trans_z = kvec * pos;
nuclear@1 200 Vector3 trans = trans_x + trans_y + trans_z;*/
nuclear@1 201 Vector3 trans;
nuclear@1 202 trans.x = dot_product(ivec, pos);
nuclear@1 203 trans.y = dot_product(jvec, pos);
nuclear@1 204 trans.z = dot_product(kvec, pos);
nuclear@1 205 mat->set_column_vector(-trans, 3);
nuclear@1 206 }
nuclear@1 207
nuclear@1 208 /*void FlyCamera::calc_inv_matrix(Matrix4x4 *mat) const
nuclear@1 209 {
nuclear@1 210 mat->set_translation(pos);
nuclear@1 211 *mat = *mat * Matrix4x4(rot.get_rotation_matrix());
nuclear@1 212 }*/
nuclear@1 213
nuclear@1 214 const Vector3 &FlyCamera::get_position() const
nuclear@1 215 {
nuclear@1 216 return pos;
nuclear@1 217 }
nuclear@1 218
nuclear@1 219 const Quaternion &FlyCamera::get_rotation() const
nuclear@1 220 {
nuclear@1 221 return rot;
nuclear@1 222 }
nuclear@1 223
nuclear@1 224 void FlyCamera::input_move(float x, float y, float z)
nuclear@1 225 {
nuclear@1 226 pos += Vector3(x, y, z);
nuclear@1 227 inval_cache();
nuclear@1 228 }
nuclear@1 229
nuclear@1 230 void FlyCamera::input_rotate(float x, float y, float z)
nuclear@1 231 {
nuclear@1 232 Vector3 axis(x, y, z);
nuclear@1 233 float axis_len = axis.length();
nuclear@1 234 rot.rotate(axis / axis_len, axis_len);
nuclear@1 235 rot.normalize();
nuclear@1 236 inval_cache();
nuclear@1 237 }