0

I'm currently in the process of finishing the implementation for a camera that functions in the same way as the camera in Maya. The part I'm stuck in the tumble functionality.

The problem is the following: the tumble feature works fine so long as the position of the camera is not parallel with the up vector (currently defined to be (0, 1, 0)). As soon as the camera becomes parallel with this vector (so it is looking straight up or down), the camera locks in place and will only rotate around the up vector instead of continuing to roll.

This question has already been asked here, unfortunately there is no actual solution to the problem. For reference, I also tried updating the up vector as I rotated the camera, but the resulting behaviour is not what I require (the view rolls as a result of the new orientation).

Here's the code for my camera:

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));

The vector library I'm using is GLM. Here's a quick reference on the custom types used here:

typedef glm::vec3 Vector;
typedef glm::vec4 Vector4;
typedef glm::mat4 Matrix4;
typedef glm::vec2 Point2;

mImpl is a PIMPL that contains the following members:

Vector eye, centre, up;
Point2 lastPoint;
4

1 回答 1

0

这是我的想法。它与万向节锁有关,这与欧拉角(以及球坐标)有关。

如果你超过了你的 minimum(0, -zoom,0) 或 maxima(0, zoom,0) 你必须切换一个布尔值。该布尔值将告诉您是否必须将 deltaY 视为正数。

它也可能只是由奇点引起的,因此只需将极角值限制在 89.99° 和 -89.99° 之间。

你的问题可以这样解决。

因此,如果您的相机正好位于对象的 (0, zoom,0) 上方或下方 (0, -zoom,0),则相机只会滚动。(我还假设您的对象位于 (0,0,0) 并且向上向量设置为 (0,1,0)。)

可能有一些数学技巧可以解决这个问题,不过我会用线性代数来解决。

你需要引入一个新的右向量。如果你做一个叉积,你会得到相机向量。相机向量 = 上向量 x 相机向量。想象一下这些向量从 (0,0,0) 开始,然后很容易地得到你的相机位置,只需做这个减法 (0,0,0)-(camera-vector)。

因此,如果你得到一些 deltaX,你会向右向量(围绕上向量)旋转并更新它。

deltaX 的任何影响都不应改变您的向上向量。

如果你得到一些 deltaY,你会朝上向量(围绕右向量)旋转并更新它。(这对右向量没有影响)。

https://en.wikipedia.org/wiki/Rotation_matrix在 Rotation matrix from axis and angle 你可以找到一个重要的公式。

你说 u 是你想要旋转的向量,而 theta 是你想要旋转的量。theta 的大小与 deltaX/Y 成正比。

例如:我们从 deltaX 获得输入,所以我们围绕上向量旋转。

up-vector:= (0,1,0)

right-vector:= (0,0,-1)

cam-vector:= (0,1,0)

theta:=-1*30° // -1 due to the positive mathematical direction of rotation


R={[cos(-30°),0,-sin(-30°)],[0,1,0],[sin(-30°),0,cos(-30°)]}

new-cam-vector=R*cam-vector // normal matrix multiplication

还有一件事要做:更新右向量。

right-vector=camera-vector x up-vector .
于 2016-04-11T05:07:22.810 回答