当我尝试改变方向时,我的相机会围绕一个点旋转。如果我旋转我的相机,比如在 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]
最后,我将它乘以模型视图矩阵堆栈,然后渲染我的所有对象。我很确定这个数学是正确的,但它不会产生我期望的结果。显然,前向向量和右向向量是问题所在,所以我唯一的问题是为什么它们是错误的,如果我想得到我期望的结果,应该如何设置它们。谢谢。
编辑:我从这个人的四元数相机类中找到了解决方案。首先,我像以前一样构造一个旋转矩阵,然后我从第一列、第二列和第三列(分别为 xa、ya 和 za)中获取矩阵的列向量。然后我像这样设置矩阵的平移分量:
[... ... ... -xa.dotProduct(cameraPos)]
|... ... ... -ya.dotProduct(cameraPos)|
|... ... ... -za.dotProduct(cameraPos)|
[... ... ... ... ]
然后可以将生成的矩阵乘以模型视图矩阵堆栈,并且可以完美运行。