GraphicsTest/Camera.cpp
2024-11-21 01:09:21 -06:00

129 lines
3.0 KiB
C++

#include "Camera.h"
namespace NB {
// Camera class
Camera::Camera(const Vec3& pos, const Vec3& tar, const Vec3& up) : _camera_type(CameraType::None) {
_pos = pos;
_tar = tar;
_world_up = glm::normalize(up);
_dir = glm::normalize(_tar-_pos);
_right = normCross(_dir, _world_up);
_up = normCross(_right, _dir);
_proj = glm::ortho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f);
_calcLook();
}
void Camera::_calcLook() {
_look = glm::lookAt(_pos, _tar, _up);
}
glm::vec3 Camera::normCross(const Vec3& a, const Vec3& b) {
return glm::normalize(glm::cross(a, b));
}
glm::vec3 Camera::transformVec(const Mat4& mat, const Vec3& vec) {
return Vec3(mat * glm::vec4(vec, 1.0f));
}
glm::vec3 Camera::getPos() const { return _pos; }
glm::vec3 Camera::getTarget() const { return _tar; }
glm::vec3 Camera::getDirection() const { return _dir; }
glm::vec3 Camera::getWorldUp() const { return _world_up; }
glm::vec3 Camera::getUp() const { return _up; }
glm::vec3 Camera::getRight() const { return _right; }
glm::mat4 Camera::getLookMatrix() const { return _look; }
glm::mat4 Camera::getProjectionMatrix() const { return _proj; }
glm::mat4 Camera::getFlattenedMatrices() const { return _proj * _look; }
void Camera::setProjection(const Mat4& proj) {
_proj = proj;
}
void Camera::setPos(const Vec3& pos) {
_pos = pos;
_calcLook();
}
void Camera::setTarget(const Vec3& tar) {
_tar = tar;
_dir = glm::normalize(_tar-_pos);
_right = normCross(_dir, ((LockUp)?_world_up:_up));
_up = normCross(_right, _dir);
_calcLook();
}
void Camera::setDirection(const Vec3& dir) {
setTarget(glm::normalize(dir)+_pos);
}
void Camera::setWorldUp(const Vec3& up) {
_world_up = up;
_right = normCross(_dir, _up);
_up = normCross(_right, _dir);
_calcLook();
}
void Camera::resetUp() {
_up = _world_up;
}
void Camera::addPos(const Vec3& add) {
_pos += add;
_dir = glm::normalize(_tar-_pos);
_right = normCross(_dir, ((LockUp)?_world_up:_up));
_calcLook();
}
void Camera::panPos(const Vec3& add) {
_tar += add;
addPos(add);
}
void Camera::panPosRelative(const Vec3& add) {
panPos(add.x*_right + add.y*_up + add.z*_dir);
}
void Camera::addTarget(const Vec3& add) {
_tar += add;
_dir = glm::normalize(_tar-_pos);
_right = normCross(_dir, (LockUp) ? _world_up : _up);
_up = normCross(_right, _dir);
_calcLook();
}
void Camera::roll(float ang) {
if (LockUp) {
return;
}
Mat4 rot_mat = glm::rotate(Mat4(1.0f), ang, _dir);
_right = transformVec(rot_mat, _right);
_up = normCross(_right, _dir);
_calcLook();
}
void Camera::pitch(float ang) {
Mat4 rot_mat = glm::rotate(Mat4(1.0f), ang, _right);
_dir = transformVec(rot_mat, _dir);
_up = normCross(_right, _dir);
_tar = _pos + _dir;
_calcLook();
}
void Camera::yaw(float ang) {
Mat4 rot_mat = glm::rotate(Mat4(1.0f), ang, _up);
_dir = transformVec(rot_mat, _dir);
_right = normCross(_dir, _right);
_tar = _pos + _dir;
_calcLook();
}
}