为什么我的相机会用这个数学围绕一个点旋转?

use*_*938 5 c++ opengl camera quaternions

当我尝试更改方向时,我的相机围绕一个点旋转.如果我旋转我的相机,比如Y轴上30度,而不是相机向右看30度,相机会围绕它正在看的点旋转.

o is the camera, A and B are 3D models. The lines show line-of-sight.
This is what I expect:
     A    B
     | > /
     |  /
     | /
     |/
     o

This is what actually happens:
     A    B
     |\
     | \
     |  \
     | > \
          o
Run Code Online (Sandbox Code Playgroud)

现在,根据我的理解,为了移动相机,我必须以相反的量移动世界.因此,如果我想在Z轴上移动+1,我将在Z轴上平移世界-1.因为我使用四元数来表示方向,所以我使用相机四元数的逆(因为方向总是单位四元数,我通过使用共轭而不是计算逆来优化)来旋转适当数量的世界.

这是我如何将四元数转换为矩阵,其中q是反转的四元数:

[1 - 2 * (q.y * q.y + q.z * q.z)   2 * (q.x * q.y - q.w * q.z)       2 * (q.x * q.z + q.w * q.y)         0]
|2 * (q.x * q.y + q.w * q.z)       1 - 2 * (q.x * q.x + q.z * q.z)   2 * (q.y * q.z - q.w * q.x)         0|
|2 * (q.x * q.z - q.w * q.y)       2 * (q.y * q.z + q.w * q.z)       1 - 2 * (q.x * q.x + q.y * q.y)     0|
[0                                 0                                 0                                   1]
Run Code Online (Sandbox Code Playgroud)

之后,我设置矩阵的转换组件:

[...   ...   ...  -x]
|...   ...   ...  -y|
|...   ...   ...  -z|
[0     0     0     1]
Run Code Online (Sandbox Code Playgroud)

最后,我将它乘以模型视图矩阵堆栈,然后渲染我的所有对象.我很确定这个数学是正确的,但它不会产生我期待的结果.很明显,向前和向右的向量是问题,所以我唯一的问题是它们为什么是错的,如果我想得到我期望的结果,应该如何设置它们.谢谢.

编辑:我找到了这个家伙的四元数相机类的解决方案.首先,我构建一个旋转矩阵,就像我之前做的那样,但后来我从第一列,第二列和第三列(分别为xa,ya和za)获取矩阵的列向量.然后我像这样设置矩阵的平移分量:

[...  ...  ...  -xa.dotProduct(cameraPos)]
|...  ...  ...  -ya.dotProduct(cameraPos)|
|...  ...  ...  -za.dotProduct(cameraPos)|
[...  ...  ...  ...                      ]
Run Code Online (Sandbox Code Playgroud)

然后,生成的矩阵可以乘以模型视图矩阵堆栈,并且它可以完美地工作.

dat*_*olf 2

\n

编辑:我从这个人的四元数相机类中找到了解决方案。首先,我像之前一样构造一个 \n 旋转矩阵,但然后我从第一、第二和第三列(分别为 xa、\n ya 和 za)获取矩阵的列\n 向量。然后我设置矩阵的平移分量,如下所示:

\n\n
[...  ...  ...  -xa.dotProduct(cameraPos)]\n|...  ...  ...  -ya.dotProduct(cameraPos)|\n|...  ...  ...  -za.dotProduct(cameraPos)|\n[...  ...  ...  ...                      ]\n
Run Code Online (Sandbox Code Playgroud)\n\n

然后可以将得到的矩阵乘到模型视图矩阵堆栈上,并且效果很好。

\n
\n\n

是的,这正是我所建议的,只是有点不同。你必须明白,OpenGL没有相机,而是你只是将世界移动到相反的方向,所以你需要找到逆变换矩阵。

\n\n

相机只是旋转和移动。这使得事情变得非常简单。平移的逆矩阵只是符号相反的相同向量,旋转矩阵的逆矩阵是它的转置(交换列和行)。现在看看 OpenGL 使用的齐次变换矩阵:

\n\n
R t\n0 1\n
Run Code Online (Sandbox Code Playgroud)\n\n

左上3\xc3\x973是旋转部分,最右一列是平移向量。我想剩下的你自己已经想好了。

\n