Я пытаюсь реализовать камеру на основе кватернионов, но при перемещении вокруг оси X и Y камера создает нежелательный рулон по оси Z. Я хочу иметь возможность свободно оглядываться по всей оси. Я читал другие темы об этой проблеме (например: http://www.flipcode.com/forums/thread/6525), но я не понимаю, что подразумевается под "Исправить это, непрерывно перестраивая матрицу поворота на вращаясь вокруг оси WORLD, т.е. около <1,0,0>, <0,1,0>, <0,0,1>, а не ваши локальные координаты, какими бы они ни были. "
//Camera.hpp
glm::quat rotation;
//Camera.cpp
void Camera::rotate(glm::vec3 vec)
{
glm::quat paramQuat = glm::quat(vec);
rotation = paramQuat * rotation;
}
Я вызываю функцию rotate следующим образом:
cam->rotate(glm::vec3(0, 0.5, 0));
Это должно быть связано с локальными/мировыми координатами, верно? Я просто не понимаю, так как я думал, что кватернионы всегда основаны друг на друге (таким образом, кватернион не может находиться в "мире" или "местном" пространстве?). Кроме того, следует ли использовать более одного кватерниона для камеры?
Насколько я понимаю, и, глядя на код, который вы указали, они подразумевают, что вы не должны хранить и применять ротацию постепенно, применяя поворот на квартете вращения все время, но вместо этого отслеживая два кватерниона для каждая ось (X и Y в мировом пространстве) и вычисление вектора вращения как произведение этих величин.
[edit: некоторый добавленный (псевдо) код]
// 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);