我目前正在完成相机的实现,其功能与Maya中的相机相同。这部分我陷入了翻滚功能。
问题如下:只要相机的位置与向上矢量(当前定义为(0, 1, 0)
)不平行,滚动功能就可以正常工作。一旦摄像机与此矢量平行(因此它向上或向下看),摄像机就会锁定到位,并且只会围绕向上矢量旋转而不是继续滚动。
这个问题已经被问到here,遗憾的是这个问题没有实际解决方案。作为参考,我也尝试在旋转相机时更新向上矢量,但结果行为不是我要求的(视图因新方向而滚动)。
这是我相机的代码:
using namespace glm;
// point is the position of the cursor in screen coordinates from GLFW
float deltaX = point.x - mImpl->lastPos.x;
float deltaY = point.y - mImpl->lastPos.y;
// Transform from screen coordinates into camera coordinates
Vector4 tumbleVector = Vector4(-deltaX, deltaY, 0, 0);
Matrix4 cameraMatrix = lookAt(mImpl->eye, mImpl->centre, mImpl->up);
Vector4 transformedTumble = inverse(cameraMatrix) * tumbleVector;
// Now compute the two vectors to determine the angle and axis of rotation.
Vector p1 = normalize(mImpl->eye - mImpl->centre);
Vector p2 = normalize((mImpl->eye + Vector(transformedTumble)) - mImpl->centre);
// Get the angle and axis
float theta = 0.1f * acos(dot(p1, p2));
Vector axis = cross(p1, p2);
// Rotate the eye.
mImpl->eye = Vector(rotate(Matrix4(1.0f), theta, axis) * Vector4(mImpl->eye, 0));
我使用的矢量库是GLM。以下是此处使用的自定义类型的快速参考:
typedef glm::vec3 Vector;
typedef glm::vec4 Vector4;
typedef glm::mat4 Matrix4;
typedef glm::vec2 Point2;
mImpl
是一个包含以下成员的PIMPL:
Vector eye, centre, up;
Point2 lastPoint;