Quaternion-Based-Camera unwanted roll

2019-09-05 21:58发布

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?

1条回答
可以哭但决不认输i
2楼-- · 2019-09-05 22:03

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);
查看更多
登录 后发表回答