diff --git a/Camera.cpp b/Camera.cpp index 4675f76..4c74c14 100644 --- a/Camera.cpp +++ b/Camera.cpp @@ -2,7 +2,7 @@ namespace NB { // Camera class -Camera::Camera(const Vec3& pos, const Vec3& tar, const Vec3& up) : _camera_type(CameraType::None) { +Camera::Camera(const Vec3& pos, const Vec3& tar, const Vec3& up) { _pos = pos; _tar = tar; _world_up = glm::normalize(up); @@ -14,7 +14,7 @@ Camera::Camera(const Vec3& pos, const Vec3& tar, const Vec3& up) : _camera_type( } void Camera::_calcLook() { - _look = glm::lookAt(_pos, _tar, _up); + _look = glm::lookAt(_pos, _tar, (_lock_world_up)?_world_up:_up); } glm::vec3 Camera::normCross(const Vec3& a, const Vec3& b) { @@ -43,6 +43,8 @@ glm::mat4 Camera::getProjectionMatrix() const { return _proj; } glm::mat4 Camera::getFlattenedMatrices() const { return _proj * _look; } +bool Camera::isUpLocked() const { return _lock_world_up; } + void Camera::setProjection(const Mat4& proj) { _proj = proj; } @@ -55,7 +57,7 @@ void Camera::setPos(const Vec3& pos) { void Camera::setTarget(const Vec3& tar) { _tar = tar; _dir = glm::normalize(_tar-_pos); - _right = normCross(_dir, ((LockUp)?_world_up:_up)); + _right = normCross(_dir, _world_up); _up = normCross(_right, _dir); _calcLook(); } @@ -71,15 +73,28 @@ void Camera::setWorldUp(const Vec3& up) { _calcLook(); } -void Camera::resetUp() { - _up = _world_up; +void Camera::lockToWorldUp(bool lock) { + if (!_lock_world_up && lock) { + resetUp(); + } + _lock_world_up = lock; +} +void Camera::resetUp() { + _right = normCross(_dir, _world_up); + _up = normCross(_right, _dir); + _calcLook(); } void Camera::addPos(const Vec3& add) { _pos += add; _dir = glm::normalize(_tar-_pos); - _right = normCross(_dir, ((LockUp)?_world_up:_up)); + if (_lock_world_up) { + _right = normCross(_dir, _world_up); + } else { + _right = normCross(_dir, _up); + _up = normCross(_right, _dir); + } _calcLook(); } @@ -89,41 +104,70 @@ void Camera::panPos(const Vec3& add) { } void Camera::panPosRelative(const Vec3& add) { - panPos(add.x*_right + add.y*_up + add.z*_dir); + panPos(add.x*_right + add.y*((_lock_world_up)?_world_up:_up) + add.z*_dir); } void Camera::addTarget(const Vec3& add) { _tar += add; _dir = glm::normalize(_tar-_pos); - _right = normCross(_dir, (LockUp) ? _world_up : _up); + _right = normCross(_dir, _world_up); _up = normCross(_right, _dir); _calcLook(); } void Camera::roll(float ang) { - if (LockUp) { - return; + if (!_lock_world_up) { + Mat4 rot_mat = glm::rotate(Mat4(1.0f), ang, _dir); + _right = transformVec(rot_mat, _right); + _up = transformVec(rot_mat, _up); + _calcLook(); } - 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); + _up = transformVec(rot_mat, _up); _tar = _pos + _dir; _calcLook(); } void Camera::yaw(float ang) { - Mat4 rot_mat = glm::rotate(Mat4(1.0f), ang, _up); + Mat4 rot_mat = glm::rotate(Mat4(1.0f), ang, ((_lock_world_up)?_world_up:_up)); _dir = transformVec(rot_mat, _dir); - _right = normCross(_dir, _right); + _right = transformVec(rot_mat, _right); + _up = normCross(_right, _dir); _tar = _pos + _dir; _calcLook(); } +// OrthographicCamera class +OrthographicCamera::OrthographicCamera( + const Vec3& pos, + const Vec3& tar, + const Vec3& up, + float left, + float right, + float bottom, + float top, + float near, + float far +) : Camera(pos, tar, up), _leftPlane(left), _rightPlane(right), _bottomPlane(bottom), _topPlane(top), _nearPlane(near), _farPlane(far) { + _proj = glm::ortho(_leftPlane, _rightPlane, _bottomPlane, _topPlane, _nearPlane, _farPlane); +} + +// PerspectiveCamera class +/* PerspectiveCamera::PerspectiveCamera( + const Vec3& pos, + const Vec3& tar, + const Vec3& up, + float left, + float right, + float bottom, + float top, + float near, + float far +) : Camera(pos, tar, up), _leftPlane(left), _rightPlane(right), _bottomPlane(bottom), _topPlane(top), _nearPlane(near), _farPlane(far) { + _proj = glm::ortho(_leftPlane, _rightPlane, _bottomPlane, _topPlane, _nearPlane, _farPlane); +} */ } \ No newline at end of file diff --git a/funcs.cpp b/funcs.cpp index 0fd3157..48a31f7 100644 --- a/funcs.cpp +++ b/funcs.cpp @@ -50,10 +50,10 @@ void processInput(GLFWwindow* window) { cam->resetUp(); } if (glfwGetKey(window, GLFW_KEY_L) == GLFW_PRESS) { - cam->LockUp=true; + cam->lockToWorldUp(true); cam->resetUp(); } if (glfwGetKey(window, GLFW_KEY_O) == GLFW_PRESS) { - cam->LockUp=false; + cam->lockToWorldUp(false); } } \ No newline at end of file diff --git a/include/Camera.h b/include/Camera.h index 50fc54a..4d68b2f 100644 --- a/include/Camera.h +++ b/include/Camera.h @@ -15,12 +15,14 @@ public: typedef glm::vec3 Vec3; typedef glm::mat4 Mat4; - enum CameraType : unsigned char { + enum CameraTypeEnum : unsigned char { None, Orthographic, Perspective }; + const CameraTypeEnum CameraType = CameraTypeEnum::None; + static Vec3 normCross(const Vec3&, const Vec3&); static Vec3 transformVec(const Mat4&, const Vec3&); @@ -30,7 +32,6 @@ public: const Vec3& up =Vec3(0.0f, 1.0f, 0.0f) ); - bool LockUp = true; Vec3 getPos() const; Vec3 getTarget() const; @@ -41,12 +42,14 @@ public: Mat4 getLookMatrix() const; Mat4 getProjectionMatrix() const; Mat4 getFlattenedMatrices() const; + bool isUpLocked() const; void setProjection(const Mat4&); void setPos(const Vec3&); void setTarget(const Vec3&); void setDirection(const Vec3&); void setWorldUp(const Vec3&); + void lockToWorldUp(bool lock); void resetUp(); void addPos(const Vec3&); void panPos(const Vec3&); @@ -65,11 +68,55 @@ protected: Vec3 _right; Mat4 _look; Mat4 _proj; - const CameraType _camera_type; + bool _lock_world_up = true; void _calcLook(); }; +class OrthographicCamera : public Camera { +public: + const CameraTypeEnum CameraType = CameraTypeEnum::Orthographic; + + OrthographicCamera( + const Vec3& pos=Vec3(1.0f, 0.0f, 0.0f), + const Vec3& tar=Vec3(0.0f, 0.0f, 0.0f), + const Vec3& up =Vec3(0.0f, 1.0f, 0.0f), + float left = -1.0f, + float right = 1.0f, + float bottom = -1.0f, + float top = 1.0f, + float near = -1.0f, + float far = 1.0f + ); + +private: + float _leftPlane, _rightPlane, _topPlane, _bottomPlane, _nearPlane, _farPlane; + + using Camera::setProjection; + +}; + +class PerspectiveCamera : public Camera { +public: + const CameraTypeEnum CameraType = CameraTypeEnum::Perspective; + + PerspectiveCamera( + const Vec3& pos=Vec3(1.0f, 0.0f, 0.0f), + const Vec3& tar=Vec3(0.0f, 0.0f, 0.0f), + const Vec3& up =Vec3(0.0f, 1.0f, 0.0f), + float fov = 45.0f, + float aspectRatio = 1.0f, + float near = -1.0f, + float far = 1.0f + ); + +private: + float _fov, _ratio, _nearPlane, _farPlane; + + using Camera::setProjection; + +}; + } #endif // _NB_CAMERA \ No newline at end of file diff --git a/main.cpp b/main.cpp index 43b07e5..8a42d66 100644 --- a/main.cpp +++ b/main.cpp @@ -52,9 +52,9 @@ int main() { myCube.generateVBO(NB::vectorToRaw(vert_data)); myCube.generateEBO(elmt_data); - NB::Camera myCam(glm::vec3(0.0f, 0.0f, -2.0f)); + NB::OrthographicCamera myCam(glm::vec3(0.0f, 0.0f, -2.0f), glm::vec3(0.0), glm::vec3(0.0, 1.0, 0.0), -2, 2, -2, 2, -2, 2); cam = &myCam; - myCam.setProjection(glm::perspective(glm::radians(45.0f), 800.0f/600.0f, 0.1f, 100.0f)); + // myCam.setProjection(glm::perspective(glm::radians(45.0f), 800.0f/600.0f, 0.1f, 100.0f)); glm::mat4 lookMat; // Window loop