当我尝试更改方向时,我的相机围绕一个点旋转。如果我旋转我的相机,比如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
现在,根据我的理解,为了移动相机,我必须以相反的量移动世界。因此,如果我想在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]
之后,我设置矩阵的转换组件:
[... ... ... -x]
|... ... ... -y|
|... ... ... -z|
[0 0 0 1]
最后我将它乘以模型 - 视图矩阵堆栈,然后渲染我的所有对象。 我很确定这个数学是正确的,但它不会产生我期待的结果。很明显,向前和向右的向量是问题,所以我唯一的问题是它们为什么是错的,如果我想得到我期望的结果,应该如何设置它们。感谢。
编辑: 我找到了this guy's quaternion camera class的解决方案。首先,我构建一个旋转矩阵,就像我之前做的那样,但后来我从第一列,第二列和第三列(分别为xa,ya和za)获取矩阵的列向量。然后我像这样设置矩阵的平移分量:
[... ... ... -xa.dotProduct(cameraPos)]
|... ... ... -ya.dotProduct(cameraPos)|
|... ... ... -za.dotProduct(cameraPos)|
[... ... ... ... ]
然后可以将得到的矩阵乘以模型视图矩阵堆栈,并且它可以完美地工作。
答案 0 :(得分:1)
编辑:我找到了这个人的四元数相机类的解决方案。首先,我构建一个 像我之前做的旋转矩阵,但后来我拿了专栏 第一,第二和第三列矩阵的向量(xa, 你和za分别)。然后我设置了翻译组件 像这样的矩阵:[... ... ... -xa.dotProduct(cameraPos)] |... ... ... -ya.dotProduct(cameraPos)| |... ... ... -za.dotProduct(cameraPos)| [... ... ... ... ]
然后可以将得到的矩阵乘以模型视图矩阵 堆栈,它完美地运作。
是的,这正是我所建议的,只是有点不同。你必须明白,OpenGL没有摄像头,而是你只是向相反的方向移动世界,所以你需要找到逆变换矩阵。
相机只是旋转并移动。这使事情变得非常简单。平移的tnverse是具有相反符号的相同向量,旋转矩阵的倒数是它的转置(列和行交换)。现在看一下像OpenGL这样的同质变换矩阵:
R t
0 1
左上3×3是旋转部分,最右边的列是平移矢量。我想你已经想到的其余部分了。
答案 1 :(得分:0)
老实说,试图找到一个矩阵来乘以模块视图矩阵非常复杂且非常容易出错。有很多混乱和特殊情况。例如,如果你向上看90度,你的两个轴会变得相同。一个合乎逻辑的问题是:如果你向后滚动,那么你通过顶点,你的向上矢量应该倒置,对吧?但如果错过了0.0001度呢?然后你应该转过头去,这样你的向上矢量仍然在上升。
在我看来,最好的方法是从另一个角度来解决问题。我们假设有两种情况:
完成所有这些后,您只需致电gluLookAt
。