nuclear@1: #include "opengl.h" nuclear@1: #include "camera.h" nuclear@1: nuclear@1: Camera::Camera() nuclear@1: { nuclear@1: inval_cache(); nuclear@1: } nuclear@1: nuclear@1: Camera::~Camera() nuclear@1: { nuclear@1: } nuclear@1: nuclear@1: void Camera::calc_inv_matrix(Matrix4x4 *mat) const nuclear@1: { nuclear@1: *mat = matrix().inverse(); nuclear@1: } nuclear@1: nuclear@1: void Camera::set_glmat(const Matrix4x4 &mat) const nuclear@1: { nuclear@1: #ifdef SINGLE_PRECISION_MATH nuclear@1: if(glLoadTransposeMatrixfARB) { nuclear@1: glLoadTransposeMatrixfARB((float*)&mat); nuclear@1: } else { nuclear@1: Matrix4x4 tmat = mat.transposed(); nuclear@1: glLoadMatrixf((float*)&tmat); nuclear@1: } nuclear@1: #else nuclear@1: if(glLoadTransposeMatrixdARB) { nuclear@1: glLoadTransposeMatrixdARB((double*)&mat); nuclear@1: } else { nuclear@1: Matrix4x4 tmat = mat.transposed(); nuclear@1: glLoadMatrixd((double*)&tmat); nuclear@1: } nuclear@1: #endif nuclear@1: } nuclear@1: nuclear@1: const Matrix4x4 &Camera::matrix() const nuclear@1: { nuclear@1: if(!mcache.valid) { nuclear@1: calc_matrix(&mcache.mat); nuclear@1: mcache.valid = true; nuclear@1: } nuclear@1: return mcache.mat; nuclear@1: } nuclear@1: nuclear@1: const Matrix4x4 &Camera::inv_matrix() const nuclear@1: { nuclear@1: if(!mcache_inv.valid) { nuclear@1: calc_inv_matrix(&mcache_inv.mat); nuclear@1: mcache_inv.valid = true; nuclear@1: } nuclear@1: return mcache_inv.mat; nuclear@1: } nuclear@1: nuclear@1: void Camera::use() const nuclear@1: { nuclear@1: set_glmat(matrix()); nuclear@1: } nuclear@1: nuclear@1: void Camera::use_inverse() const nuclear@1: { nuclear@1: set_glmat(inv_matrix()); nuclear@1: } nuclear@1: nuclear@1: void Camera::input_move(float x, float y, float z) nuclear@1: { nuclear@1: } nuclear@1: nuclear@1: void Camera::input_rotate(float x, float y, float z) nuclear@1: { nuclear@1: } nuclear@1: nuclear@1: void Camera::input_zoom(float factor) nuclear@1: { nuclear@1: } nuclear@1: nuclear@1: nuclear@1: // ---- orbit camera ---- nuclear@1: nuclear@1: OrbitCamera::OrbitCamera() nuclear@1: { nuclear@1: theta = 0.0; nuclear@1: phi = 0.0; nuclear@1: rad = 10.0; nuclear@1: } nuclear@1: nuclear@1: OrbitCamera::~OrbitCamera() nuclear@1: { nuclear@1: } nuclear@1: nuclear@1: void OrbitCamera::calc_matrix(Matrix4x4 *mat) const nuclear@1: { nuclear@1: mat->reset_identity(); nuclear@1: mat->translate(Vector3(0, 0, -rad)); nuclear@1: mat->rotate(Vector3(phi, 0, 0)); nuclear@1: mat->rotate(Vector3(0, theta, 0)); nuclear@1: } nuclear@1: nuclear@1: void OrbitCamera::calc_inv_matrix(Matrix4x4 *mat) const nuclear@1: { nuclear@1: mat->reset_identity(); nuclear@1: mat->rotate(Vector3(0, theta, 0)); nuclear@1: mat->rotate(Vector3(phi, 0, 0)); nuclear@1: mat->translate(Vector3(0, 0, -rad)); nuclear@1: } nuclear@1: nuclear@1: void OrbitCamera::input_rotate(float x, float y, float z) nuclear@1: { nuclear@7: theta += y; nuclear@7: phi += x; nuclear@1: nuclear@7: if(phi < -M_PI / 2) nuclear@7: phi = -M_PI / 2; nuclear@7: if(phi > M_PI) nuclear@7: phi = M_PI; nuclear@1: nuclear@1: inval_cache(); nuclear@1: } nuclear@1: nuclear@1: void OrbitCamera::input_zoom(float factor) nuclear@1: { nuclear@1: rad += factor; nuclear@1: if(rad < 0.0) nuclear@1: rad = 0.0; nuclear@1: nuclear@1: inval_cache(); nuclear@1: } nuclear@1: nuclear@1: nuclear@7: void FpsCamera::calc_matrix(Matrix4x4 *mat) const nuclear@7: { nuclear@7: mat->reset_identity(); nuclear@7: /*mat->translate(Vector3(pos.x, pos.y, pos.z)); nuclear@7: mat->rotate(Vector3(phi, 0, 0)); nuclear@7: mat->rotate(Vector3(0, theta, 0));*/ nuclear@7: } nuclear@7: nuclear@7: void FpsCamera::calc_inv_matrix(Matrix4x4 *mat) const nuclear@7: { nuclear@7: mat->reset_identity(); nuclear@7: mat->rotate(Vector3(phi, 0, 0)); nuclear@7: mat->rotate(Vector3(0, theta, 0)); nuclear@7: mat->translate(Vector3(-pos.x, -pos.y, -pos.z)); nuclear@7: } nuclear@7: nuclear@7: void FpsCamera::input_move(float x, float y, float z) nuclear@7: { nuclear@7: pos.x += x * cos(theta) - z * sin(theta); nuclear@7: pos.z += x * sin(theta) + z * cos(theta); nuclear@7: pos.y += y; nuclear@7: inval_cache(); nuclear@7: } nuclear@7: nuclear@7: nuclear@7: nuclear@1: FlyCamera::FlyCamera() nuclear@1: { nuclear@1: pos.z = 10.0f; nuclear@1: } nuclear@1: nuclear@1: void FlyCamera::calc_matrix(Matrix4x4 *mat) const nuclear@1: { nuclear@1: Matrix3x3 rmat = rot.get_rotation_matrix().transposed(); nuclear@1: Matrix4x4 tmat; nuclear@1: tmat.set_translation(pos); nuclear@1: *mat = tmat * Matrix4x4(rmat); nuclear@1: } nuclear@1: nuclear@1: /*void FlyCamera::calc_inv_matrix(Matrix4x4 *mat) const nuclear@1: { nuclear@1: }*/ nuclear@1: nuclear@1: const Vector3 &FlyCamera::get_position() const nuclear@1: { nuclear@1: return pos; nuclear@1: } nuclear@1: nuclear@1: const Quaternion &FlyCamera::get_rotation() const nuclear@1: { nuclear@1: return rot; nuclear@1: } nuclear@1: nuclear@1: void FlyCamera::input_move(float x, float y, float z) nuclear@1: { nuclear@1: static const Vector3 vfwd(0, 0, 1), vright(1, 0, 0); nuclear@1: nuclear@1: Vector3 k = vfwd.transformed(rot); nuclear@1: Vector3 i = vright.transformed(rot); nuclear@1: Vector3 j = cross_product(k, i); nuclear@1: nuclear@1: pos += i * x + j * y + k * z; nuclear@1: inval_cache(); nuclear@1: } nuclear@1: nuclear@1: void FlyCamera::input_rotate(float x, float y, float z) nuclear@1: { nuclear@1: Vector3 axis(x, y, z); nuclear@1: float axis_len = axis.length(); nuclear@1: rot.rotate(axis / axis_len, axis_len); nuclear@1: rot.normalize(); nuclear@1: nuclear@1: inval_cache(); nuclear@1: }