aparker314159

02-12-2017, 12:50 PM

I tried building a first-person 3D camera class in C++. My problem is that while I can rotate the camera, if I rotate the x-axis far by looking up or down, the camera flips around and the y-axis ends up inverted. How can I solve this problem?

I've been trying to follow learnopengl. com tutorial to do this, but I decided to learn to use quaternions instead of Euler angles for my camera class.

Here is the code:

#ifndef CAMERA_H

#define CAMERA_H

#include <GL/glew.h>

#include <GLFW/glfw3.h>

#include <glm/glm.hpp>

#include <glm/gtc/matrix_transform.hpp>

#include <glm/gtc/quaternion.hpp>

#include <glm/gtx/quaternion.hpp>

#include <glm/gtx/rotate_vector.hpp>

#define WORLD_UP glm::vec3(0.0f, 1.0f, 0.0f)

#include <iostream>

enum CamDirection {

CAM_FORWARD,

CAM_BACKWARD,

CAM_LEFT,

CAM_RIGHT

};

class Camera {

public:

void cameraUpdate();

glm::mat4 getViewMatrix();

Camera();

Camera(glm::vec3 startPosition);

void move(CamDirection dir, GLfloat deltaTime);

void look(double xOffset, double yOffset);

void update();

private:

glm::vec3 camPos;

glm::vec3 camFront;

glm::vec3 camUp;

glm::vec3 camRight;

glm::quat orientation;

const GLfloat camSpeed = 5.05f;

};

glm::mat4 Camera::getViewMatrix() {

return glm::lookAt(camPos, camPos + camFront, camUp);

}

Camera::Camera():

camPos (glm::vec3(0.0f, 0.0f, 0.0f)),

camFront(glm::vec3(0.0f, 0.0f, -1.0f)),

camUp (WORLD_UP)

{}

Camera::Camera(glm::vec3 startPos):

camPos (startPos),

camFront (glm::vec3(0.0f, 0.0f, -1.0f)),

camUp (WORLD_UP)

{}

void Camera::move(CamDirection dir, GLfloat deltaTime) {

const GLfloat v = camSpeed * deltaTime;

if (dir == CAM_FORWARD)

camPos += v * camFront;

else if (dir == CAM_BACKWARD)

camPos -= v * camFront;

else if (dir == CAM_RIGHT)

camPos += v * camRight;

else

camPos -= v * camRight;

}

void Camera::look(double xOffset, double yOffset) {

glm::quat rotation = glm::angleAxis((GLfloat)xOffset, camUp);

orientation = orientation * rotation;

rotation = glm::angleAxis((GLfloat)yOffset, glm::vec3(-1.0f, 0.0f, 0.0f));

orientation = orientation * rotation;

camFront = camFront * orientation;

orientation = {1, 0, 0, 0};

}

void Camera::update() {

}

#endif // CAMERA_H

Thanks in advance.

I've been trying to follow learnopengl. com tutorial to do this, but I decided to learn to use quaternions instead of Euler angles for my camera class.

Here is the code:

#ifndef CAMERA_H

#define CAMERA_H

#include <GL/glew.h>

#include <GLFW/glfw3.h>

#include <glm/glm.hpp>

#include <glm/gtc/matrix_transform.hpp>

#include <glm/gtc/quaternion.hpp>

#include <glm/gtx/quaternion.hpp>

#include <glm/gtx/rotate_vector.hpp>

#define WORLD_UP glm::vec3(0.0f, 1.0f, 0.0f)

#include <iostream>

enum CamDirection {

CAM_FORWARD,

CAM_BACKWARD,

CAM_LEFT,

CAM_RIGHT

};

class Camera {

public:

void cameraUpdate();

glm::mat4 getViewMatrix();

Camera();

Camera(glm::vec3 startPosition);

void move(CamDirection dir, GLfloat deltaTime);

void look(double xOffset, double yOffset);

void update();

private:

glm::vec3 camPos;

glm::vec3 camFront;

glm::vec3 camUp;

glm::vec3 camRight;

glm::quat orientation;

const GLfloat camSpeed = 5.05f;

};

glm::mat4 Camera::getViewMatrix() {

return glm::lookAt(camPos, camPos + camFront, camUp);

}

Camera::Camera():

camPos (glm::vec3(0.0f, 0.0f, 0.0f)),

camFront(glm::vec3(0.0f, 0.0f, -1.0f)),

camUp (WORLD_UP)

{}

Camera::Camera(glm::vec3 startPos):

camPos (startPos),

camFront (glm::vec3(0.0f, 0.0f, -1.0f)),

camUp (WORLD_UP)

{}

void Camera::move(CamDirection dir, GLfloat deltaTime) {

const GLfloat v = camSpeed * deltaTime;

if (dir == CAM_FORWARD)

camPos += v * camFront;

else if (dir == CAM_BACKWARD)

camPos -= v * camFront;

else if (dir == CAM_RIGHT)

camPos += v * camRight;

else

camPos -= v * camRight;

}

void Camera::look(double xOffset, double yOffset) {

glm::quat rotation = glm::angleAxis((GLfloat)xOffset, camUp);

orientation = orientation * rotation;

rotation = glm::angleAxis((GLfloat)yOffset, glm::vec3(-1.0f, 0.0f, 0.0f));

orientation = orientation * rotation;

camFront = camFront * orientation;

orientation = {1, 0, 0, 0};

}

void Camera::update() {

}

#endif // CAMERA_H

Thanks in advance.