平行于上方向向量时,Arcball摄影机被锁定
Arcball camera locked when parallel to up vector
我目前正在完成相机的实现,该相机的功能与Maya中的相机相同。我陷入翻滚功能的部分。
问题如下:只要摄影机的位置与上方向向量(当前定义为(0, 1, 0)
)不平行,翻滚功能就可以正常工作。一旦摄影机与该向量平行(因此它看起来是直向上或直向下),摄影机就会锁定在适当位置,并且只围绕上向量旋转,而不是继续滚动。
这个问题已经在这里被提出了,不幸的是,这个问题没有实际的解决方案。作为参考,我还尝试在旋转相机时更新向上矢量,但最终的行为不是我所需要的(视图会因新方向而滚动)。
这是我相机的代码:
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;
以下是我的想法。这与万向节锁定有关,万向节锁定发生在欧拉角(以及球面坐标)上。
如果超过最小值(0,-zoom,0)或最大值(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)-(相机向量)。
因此,如果你得到一些deltaX,你就朝着右向量旋转(围绕上向量)并更新它
deltaX的任何影响都不应该改变你的上方向向量。
如果你得到了一些deltaY,你就向上向量(围绕右向量)旋转并更新它。(这对右向量没有影响)。
https://en.wikipedia.org/wiki/Rotation_matrix在旋转矩阵中,从轴和角度可以找到一个重要的公式。
你说u是你想要旋转的向量,θ是你想要绕轴旋转的量。θ的大小与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 .
- 从实时摄影机馈送而不是图像中按形状跟踪对象
- OpenGL ArcBall用于旋转网格
- 在将平截头体从摄影机空间转换为灯光空间以进行阴影映射方面存在主要问题
- 绕摄影机旋转opengl c++/设置旋转中心
- 如何计算摄影机对象的视图矩阵
- 当摄影机参数已知时,OpenCV图像静置
- 几何体着色器计算的线在摄影机移动时消失
- OpenCV将三维坐标投影到二维摄影机坐标
- 平行于上方向向量时,Arcball摄影机被锁定
- OpenCV在尝试从轴摄影机获取图像时出错
- 围绕世界的Y轴旋转摄影机(在O(0,0,0)处)
- 在C++/OpenGL中使模型面向摄影机
- 从vtk渲染计算摄影机空间坐标
- 使用四元数旋转摄影机
- 为什么使用摄影机空间而不是模型空间作为法线
- Opengl摄影机和渲染问题
- OSG:使用AnimationPathManipulator的摄影机飞行
- 遮罩未显示在OpenCV摄影机预览中
- 环绕摄影机(C++,GLM)
- OpenGL-制作跟随摄影机的点光源