I’m trying to create a fly-through camera in OpenGL. It should be able to rotate in all axes by moving the mouse.At the moment, it can only rotate in around the x-axis. And it can only rotate in the y-axis after I do a 180 rotation in the z-axis

The camera starts with an orientation of (w,x,y,z)(0,0,1,0). Changing the initial orientation of the camera causes it to change the axis it can rotate ( eg. if it initially can only rotate in the x-axis it will only be able to rotate in y-axis after changing the orientation).

Manually changing the rotation around the y-axis without the mouse (shown below) does not seem to work either.

```
glm::vec3 worldUp = glm::vec3(0, 1, 0);
camera->Rotate(20.0f, worldUp);
```

video:

https://drive.google.com/file/d/15JU631-23FvuOAoxS0GiJ7-Ex09Eu39L/view

snippet of camera.cpp

```
Camera::Camera(glm::vec3 _position, glm::vec3 _forward, glm::vec3 _up)
{
//assume given right vector may not be orthogonal to forward
std::cerr << "" << std::endl;
std::cerr << "constructor" << std::endl;
position = _position;
forward = glm::normalize(_forward);
right = glm::normalize(glm::cross(_up,forward));
glm::vec3 up = glm::normalize(glm::cross(forward, right));
SetOrientation(glm::mat3(right, up, forward));
std::cerr << "orientation " + glm::to_string(orientation) << std::endl;
}
Camera::~Camera()
{
}
glm::mat4 Camera::GetViewMatrix()
{
return glm::translate(glm::mat4_cast(orientation), position);
}
void Camera::SetOrientation(glm::mat3 rotationMat)
{
orientation = glm::quat_cast(rotationMat);
orientation = glm::normalize(orientation);
updateVectors();
}
void Camera::Rotate(float degrees, glm::vec3 axis)
{
axis = glm::normalize(axis);
//construct rotation quaternion
glm::quat rotationQuat = glm::quat(glm::cos(glm::radians(degrees)), glm::sin(glm::radians(degrees))*axis);
rotationQuat = glm::normalize(rotationQuat);
// p' = q x p x q*
orientation = rotationQuat * orientation * glm::conjugate(rotationQuat);
orientation = glm::normalize(orientation);
updateVectors();
}
void Camera::updateVectors()
{
//update forward and right values
forward = glm::vec3(
2.0f * (orientation.x * orientation.z + orientation.w * orientation.y),
2.0f * (orientation.y * orientation.z - orientation.w * orientation.x),
1.0f - 2.0f * (orientation.x * orientation.x + orientation.y * orientation.y)
);
right = glm::vec3(
(1.0f - 2.0f * (orientation.y * orientation.y + orientation.z * orientation.z)),
(2.0f * (orientation.x * orientation.y + orientation.w * orientation.z)),
(2.0f * (orientation.x * orientation.z - orientation.w * orientation.y))
);
forward = glm::normalize(forward);
right = glm::normalize(right);
}
```

snippet of camera.h

```
class Camera
{
public:
Camera(glm::vec3 _position, glm::vec3 _forward, glm::vec3 _right);
~Camera();
glm::mat4 GetViewMatrix();
void SetOrientation(glm::mat3 rotationMat);
void Rotate(float degrees, glm::vec3 axis);
void Translate(glm::vec3 translation);
void Move(CameraMoveDirection direction, float distanceInDirection);
glm::vec3 GetForward();
glm::vec3 GetRight();
glm::vec3 GetUp();
glm::vec3 GetPosition();
glm::quat GetOrientation();
private:
void updateVectors();
glm::vec3 position;
glm::vec3 forward;
glm::vec3 right;
glm::quat orientation;
};
```

How i rotate the camera.

```
void mouse_callback(GLFWwindow* window, double xpos, double ypos)
{
if (firstMouse)
{
lastX = xpos;
lastY = ypos;
firstMouse = false;
}
float xoffset = lastX - xpos;
float yoffset = ypos - lastY;
lastX = xpos;
lastY = ypos;
float sensitivity = 0.01f;
xoffset *= sensitivity;
yoffset *= sensitivity;
glm::vec3 absUp = glm::vec3(0, 1, 0);
camera->Rotate(xoffset, absUp);
camera->Rotate(yoffset, camera->GetRight());
}
```

initial values of the camera

```
glm::vec3 cameraPos = glm::vec3(0, 0,5.0f);
glm::vec3 cameraLookAt = glm::vec3(0, 0, 0.0f);
glm::vec3 cameraDirection = glm::normalize(cameraLookAt - cameraPos);
glm::vec3 rawUpDir = glm::vec3(0, 1, 0);
camera = new Camera(cameraPos, cameraDirection, rawUpDir);
```