nuclear@5: #include "opengl.h" nuclear@5: #include "camera.h" nuclear@5: nuclear@5: Camera::Camera() nuclear@5: { nuclear@5: inval_cache(); nuclear@5: } nuclear@5: nuclear@5: Camera::~Camera() nuclear@5: { nuclear@5: } nuclear@5: nuclear@5: void Camera::calc_inv_matrix(Matrix4x4 *mat) const nuclear@5: { nuclear@5: *mat = matrix().inverse(); nuclear@5: } nuclear@5: nuclear@5: void Camera::set_glmat(const Matrix4x4 &mat) const nuclear@5: { nuclear@5: #ifdef SINGLE_PRECISION_MATH nuclear@5: if(glLoadTransposeMatrixfARB) { nuclear@5: glLoadTransposeMatrixfARB((float*)&mat); nuclear@5: } else { nuclear@5: Matrix4x4 tmat = mat.transposed(); nuclear@5: glLoadMatrixf((float*)&tmat); nuclear@5: } nuclear@5: #else nuclear@5: if(glLoadTransposeMatrixdARB) { nuclear@5: glLoadTransposeMatrixdARB((double*)&mat); nuclear@5: } else { nuclear@5: Matrix4x4 tmat = mat.transposed(); nuclear@5: glLoadMatrixd((double*)&tmat); nuclear@5: } nuclear@5: #endif nuclear@5: } nuclear@5: nuclear@5: const Matrix4x4 &Camera::matrix() const nuclear@5: { nuclear@5: if(!mcache.valid) { nuclear@5: calc_matrix(&mcache.mat); nuclear@5: mcache.valid = true; nuclear@5: } nuclear@5: return mcache.mat; nuclear@5: } nuclear@5: nuclear@5: const Matrix4x4 &Camera::inv_matrix() const nuclear@5: { nuclear@5: if(!mcache_inv.valid) { nuclear@5: calc_inv_matrix(&mcache_inv.mat); nuclear@5: mcache_inv.valid = true; nuclear@5: } nuclear@5: return mcache_inv.mat; nuclear@5: } nuclear@5: nuclear@5: void Camera::use() const nuclear@5: { nuclear@5: set_glmat(matrix()); nuclear@5: } nuclear@5: nuclear@5: void Camera::use_inverse() const nuclear@5: { nuclear@5: set_glmat(inv_matrix()); nuclear@5: } nuclear@5: nuclear@5: void Camera::input_move(float x, float y, float z) nuclear@5: { nuclear@5: } nuclear@5: nuclear@5: void Camera::input_rotate(float x, float y, float z) nuclear@5: { nuclear@5: } nuclear@5: nuclear@5: void Camera::input_zoom(float factor) nuclear@5: { nuclear@5: } nuclear@5: nuclear@5: nuclear@5: // ---- orbit camera ---- nuclear@5: nuclear@5: OrbitCamera::OrbitCamera() nuclear@5: { nuclear@5: theta = 0.0; nuclear@5: phi = 0.0; nuclear@5: rad = 10.0; nuclear@5: } nuclear@5: nuclear@5: OrbitCamera::~OrbitCamera() nuclear@5: { nuclear@5: } nuclear@5: nuclear@5: void OrbitCamera::calc_matrix(Matrix4x4 *mat) const nuclear@5: { nuclear@5: mat->reset_identity(); nuclear@5: mat->translate(Vector3(0, 0, -rad)); nuclear@5: mat->rotate(Vector3(phi, 0, 0)); nuclear@5: mat->rotate(Vector3(0, theta, 0)); nuclear@5: } nuclear@5: nuclear@5: void OrbitCamera::calc_inv_matrix(Matrix4x4 *mat) const nuclear@5: { nuclear@5: mat->reset_identity(); nuclear@5: mat->rotate(Vector3(0, theta, 0)); nuclear@5: mat->rotate(Vector3(phi, 0, 0)); nuclear@5: mat->translate(Vector3(0, 0, -rad)); nuclear@5: } nuclear@5: nuclear@5: void OrbitCamera::input_rotate(float x, float y, float z) nuclear@5: { nuclear@5: theta += x; nuclear@5: phi += y; nuclear@5: nuclear@5: if(phi < -M_PI / 2) nuclear@5: phi = -M_PI / 2; nuclear@5: if(phi > M_PI) nuclear@5: phi = M_PI; nuclear@5: nuclear@5: inval_cache(); nuclear@5: } nuclear@5: nuclear@5: void OrbitCamera::input_zoom(float factor) nuclear@5: { nuclear@5: rad += factor; nuclear@5: if(rad < 0.0) nuclear@5: rad = 0.0; nuclear@5: nuclear@5: inval_cache(); nuclear@5: } nuclear@5: nuclear@5: nuclear@5: FlyCamera::FlyCamera() nuclear@5: { nuclear@5: pos.z = 10.0f; nuclear@5: } nuclear@5: nuclear@5: void FlyCamera::calc_matrix(Matrix4x4 *mat) const nuclear@5: { nuclear@5: /*mat->reset_identity(); nuclear@5: mat->translate(-pos); nuclear@5: *mat = *mat * Matrix4x4(rot.get_rotation_matrix()); nuclear@5: mat->translate(pos);*/ nuclear@5: //mat->translate(-pos.transformed(rot)); nuclear@5: nuclear@5: Matrix3x3 qmat = rot.get_rotation_matrix(); nuclear@5: nuclear@5: Vector3 ivec = qmat.get_row_vector(0); nuclear@5: Vector3 jvec = qmat.get_row_vector(1); nuclear@5: Vector3 kvec = qmat.get_row_vector(2); nuclear@5: nuclear@5: *mat = Matrix4x4(qmat); nuclear@5: /*Vector3 trans_x = ivec * pos; nuclear@5: Vector3 trans_y = jvec * pos; nuclear@5: Vector3 trans_z = kvec * pos; nuclear@5: Vector3 trans = trans_x + trans_y + trans_z;*/ nuclear@5: Vector3 trans; nuclear@5: trans.x = dot_product(ivec, pos); nuclear@5: trans.y = dot_product(jvec, pos); nuclear@5: trans.z = dot_product(kvec, pos); nuclear@5: mat->set_column_vector(-trans, 3); nuclear@5: } nuclear@5: nuclear@5: /*void FlyCamera::calc_inv_matrix(Matrix4x4 *mat) const nuclear@5: { nuclear@5: mat->set_translation(pos); nuclear@5: *mat = *mat * Matrix4x4(rot.get_rotation_matrix()); nuclear@5: }*/ nuclear@5: nuclear@5: const Vector3 &FlyCamera::get_position() const nuclear@5: { nuclear@5: return pos; nuclear@5: } nuclear@5: nuclear@5: const Quaternion &FlyCamera::get_rotation() const nuclear@5: { nuclear@5: return rot; nuclear@5: } nuclear@5: nuclear@5: void FlyCamera::input_move(float x, float y, float z) nuclear@5: { nuclear@5: pos += Vector3(x, y, z); nuclear@5: inval_cache(); nuclear@5: } nuclear@5: nuclear@5: void FlyCamera::input_rotate(float x, float y, float z) nuclear@5: { nuclear@5: Vector3 axis(x, y, z); nuclear@5: float axis_len = axis.length(); nuclear@5: rot.rotate(axis / axis_len, axis_len); nuclear@5: rot.normalize(); nuclear@5: inval_cache(); nuclear@5: }