I think I fixed rolling/non world up camera orientations and added ortho and persp cameras.

This commit is contained in:
NaifBanana 2024-11-22 01:10:25 -06:00
parent bcb8f8f4ea
commit 94785e586c
4 changed files with 115 additions and 24 deletions

View File

@ -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 = normCross(_right, _dir);
_up = transformVec(rot_mat, _up);
_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);
} */
}

View File

@ -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);
}
}

View File

@ -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

View File

@ -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