I think I fixed rolling/non world up camera orientations and added ortho and persp cameras.
This commit is contained in:
parent
bcb8f8f4ea
commit
94785e586c
78
Camera.cpp
78
Camera.cpp
@ -2,7 +2,7 @@
|
|||||||
namespace NB {
|
namespace NB {
|
||||||
|
|
||||||
// Camera class
|
// 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;
|
_pos = pos;
|
||||||
_tar = tar;
|
_tar = tar;
|
||||||
_world_up = glm::normalize(up);
|
_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() {
|
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) {
|
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; }
|
glm::mat4 Camera::getFlattenedMatrices() const { return _proj * _look; }
|
||||||
|
|
||||||
|
bool Camera::isUpLocked() const { return _lock_world_up; }
|
||||||
|
|
||||||
void Camera::setProjection(const Mat4& proj) {
|
void Camera::setProjection(const Mat4& proj) {
|
||||||
_proj = proj;
|
_proj = proj;
|
||||||
}
|
}
|
||||||
@ -55,7 +57,7 @@ void Camera::setPos(const Vec3& pos) {
|
|||||||
void Camera::setTarget(const Vec3& tar) {
|
void Camera::setTarget(const Vec3& tar) {
|
||||||
_tar = tar;
|
_tar = tar;
|
||||||
_dir = glm::normalize(_tar-_pos);
|
_dir = glm::normalize(_tar-_pos);
|
||||||
_right = normCross(_dir, ((LockUp)?_world_up:_up));
|
_right = normCross(_dir, _world_up);
|
||||||
_up = normCross(_right, _dir);
|
_up = normCross(_right, _dir);
|
||||||
_calcLook();
|
_calcLook();
|
||||||
}
|
}
|
||||||
@ -71,15 +73,28 @@ void Camera::setWorldUp(const Vec3& up) {
|
|||||||
_calcLook();
|
_calcLook();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Camera::resetUp() {
|
void Camera::lockToWorldUp(bool lock) {
|
||||||
_up = _world_up;
|
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) {
|
void Camera::addPos(const Vec3& add) {
|
||||||
_pos += add;
|
_pos += add;
|
||||||
_dir = glm::normalize(_tar-_pos);
|
_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();
|
_calcLook();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,41 +104,70 @@ void Camera::panPos(const Vec3& add) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Camera::panPosRelative(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) {
|
void Camera::addTarget(const Vec3& add) {
|
||||||
_tar += add;
|
_tar += add;
|
||||||
_dir = glm::normalize(_tar-_pos);
|
_dir = glm::normalize(_tar-_pos);
|
||||||
_right = normCross(_dir, (LockUp) ? _world_up : _up);
|
_right = normCross(_dir, _world_up);
|
||||||
_up = normCross(_right, _dir);
|
_up = normCross(_right, _dir);
|
||||||
_calcLook();
|
_calcLook();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Camera::roll(float ang) {
|
void Camera::roll(float ang) {
|
||||||
if (LockUp) {
|
if (!_lock_world_up) {
|
||||||
return;
|
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) {
|
void Camera::pitch(float ang) {
|
||||||
Mat4 rot_mat = glm::rotate(Mat4(1.0f), ang, _right);
|
Mat4 rot_mat = glm::rotate(Mat4(1.0f), ang, _right);
|
||||||
_dir = transformVec(rot_mat, _dir);
|
_dir = transformVec(rot_mat, _dir);
|
||||||
_up = normCross(_right, _dir);
|
_up = transformVec(rot_mat, _up);
|
||||||
_tar = _pos + _dir;
|
_tar = _pos + _dir;
|
||||||
_calcLook();
|
_calcLook();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Camera::yaw(float ang) {
|
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);
|
_dir = transformVec(rot_mat, _dir);
|
||||||
_right = normCross(_dir, _right);
|
_right = transformVec(rot_mat, _right);
|
||||||
|
_up = normCross(_right, _dir);
|
||||||
_tar = _pos + _dir;
|
_tar = _pos + _dir;
|
||||||
_calcLook();
|
_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);
|
||||||
|
} */
|
||||||
}
|
}
|
||||||
@ -50,10 +50,10 @@ void processInput(GLFWwindow* window) {
|
|||||||
cam->resetUp();
|
cam->resetUp();
|
||||||
}
|
}
|
||||||
if (glfwGetKey(window, GLFW_KEY_L) == GLFW_PRESS) {
|
if (glfwGetKey(window, GLFW_KEY_L) == GLFW_PRESS) {
|
||||||
cam->LockUp=true;
|
cam->lockToWorldUp(true);
|
||||||
cam->resetUp();
|
cam->resetUp();
|
||||||
}
|
}
|
||||||
if (glfwGetKey(window, GLFW_KEY_O) == GLFW_PRESS) {
|
if (glfwGetKey(window, GLFW_KEY_O) == GLFW_PRESS) {
|
||||||
cam->LockUp=false;
|
cam->lockToWorldUp(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -15,12 +15,14 @@ public:
|
|||||||
typedef glm::vec3 Vec3;
|
typedef glm::vec3 Vec3;
|
||||||
typedef glm::mat4 Mat4;
|
typedef glm::mat4 Mat4;
|
||||||
|
|
||||||
enum CameraType : unsigned char {
|
enum CameraTypeEnum : unsigned char {
|
||||||
None,
|
None,
|
||||||
Orthographic,
|
Orthographic,
|
||||||
Perspective
|
Perspective
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const CameraTypeEnum CameraType = CameraTypeEnum::None;
|
||||||
|
|
||||||
static Vec3 normCross(const Vec3&, const Vec3&);
|
static Vec3 normCross(const Vec3&, const Vec3&);
|
||||||
static Vec3 transformVec(const Mat4&, const Vec3&);
|
static Vec3 transformVec(const Mat4&, const Vec3&);
|
||||||
|
|
||||||
@ -30,7 +32,6 @@ public:
|
|||||||
const Vec3& up =Vec3(0.0f, 1.0f, 0.0f)
|
const Vec3& up =Vec3(0.0f, 1.0f, 0.0f)
|
||||||
);
|
);
|
||||||
|
|
||||||
bool LockUp = true;
|
|
||||||
|
|
||||||
Vec3 getPos() const;
|
Vec3 getPos() const;
|
||||||
Vec3 getTarget() const;
|
Vec3 getTarget() const;
|
||||||
@ -41,12 +42,14 @@ public:
|
|||||||
Mat4 getLookMatrix() const;
|
Mat4 getLookMatrix() const;
|
||||||
Mat4 getProjectionMatrix() const;
|
Mat4 getProjectionMatrix() const;
|
||||||
Mat4 getFlattenedMatrices() const;
|
Mat4 getFlattenedMatrices() const;
|
||||||
|
bool isUpLocked() const;
|
||||||
|
|
||||||
void setProjection(const Mat4&);
|
void setProjection(const Mat4&);
|
||||||
void setPos(const Vec3&);
|
void setPos(const Vec3&);
|
||||||
void setTarget(const Vec3&);
|
void setTarget(const Vec3&);
|
||||||
void setDirection(const Vec3&);
|
void setDirection(const Vec3&);
|
||||||
void setWorldUp(const Vec3&);
|
void setWorldUp(const Vec3&);
|
||||||
|
void lockToWorldUp(bool lock);
|
||||||
void resetUp();
|
void resetUp();
|
||||||
void addPos(const Vec3&);
|
void addPos(const Vec3&);
|
||||||
void panPos(const Vec3&);
|
void panPos(const Vec3&);
|
||||||
@ -65,11 +68,55 @@ protected:
|
|||||||
Vec3 _right;
|
Vec3 _right;
|
||||||
Mat4 _look;
|
Mat4 _look;
|
||||||
Mat4 _proj;
|
Mat4 _proj;
|
||||||
const CameraType _camera_type;
|
bool _lock_world_up = true;
|
||||||
|
|
||||||
void _calcLook();
|
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
|
#endif // _NB_CAMERA
|
||||||
4
main.cpp
4
main.cpp
@ -52,9 +52,9 @@ int main() {
|
|||||||
myCube.generateVBO(NB::vectorToRaw(vert_data));
|
myCube.generateVBO(NB::vectorToRaw(vert_data));
|
||||||
myCube.generateEBO(elmt_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;
|
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;
|
glm::mat4 lookMat;
|
||||||
|
|
||||||
// Window loop
|
// Window loop
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user