129 lines
3.0 KiB
C++
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();
|
|
}
|
|
|
|
} |