user3067395
user3067395

Reputation: 580

Quaternion-Based-Camera unwanted roll

I'm trying to implement a quaternion-based camera, but when moving around the X and Y axis, the camera produces an unwanted roll on the Z axis. I want to be able to look around freely on all axis. I've read other topics about this problem (for example: http://www.flipcode.com/forums/thread/6525 ), but I'm not getting what is meant by "Fix this by continuously rebuilding the rotation matrix by rotating around the WORLD axis, i.e around <1,0,0>, <0,1,0>, <0,0,1>, not your local coordinates, whatever they might be."

//Camera.hpp
glm::quat rotation;

//Camera.cpp
void Camera::rotate(glm::vec3 vec)
{
    glm::quat paramQuat = glm::quat(vec);
    rotation = paramQuat * rotation;
}

I call the rotate function like this:

cam->rotate(glm::vec3(0, 0.5, 0));

This must have to do with local/world coordinates, right? I'm just not getting it, since I thought quaternions are always based on each other (thus a quaternion can't be in "world" or "local" space?). Also, should i use more than one quaternion for a camera?

Upvotes: 1

Views: 2361

Answers (1)

Der Schmale
Der Schmale

Reputation: 156

As far as I understand it, and from looking at the code you provided, what they mean is that you shouldn't store and apply the rotation incrementally by applying rotate on the rotation quat all the time, but instead keeping track of two quaternions for each axis (X and Y in world space) and calculating the rotation vector as the product of those.

[edit: some added (pseudo)code]

// Camera.cpp
void Camera::SetRotation(glm::quat value)
{
    rotation = value;
}

// controller.cpp --> probably a place where you'd want to translate user input and store your rotational state
xAngle += deltaX;
yAngle += deltaY;
glm::quat rotationX = QuatAxisAngle(X_AXIS, xAngle);
glm::quat rotationY = QuatAxisAngle(Y_AXIS, yAngle);
camera.SetRotation(rotationX * rotationY);

Upvotes: 2

Related Questions