我试图生成一个视图矩阵,将作为一个FPS相机的行为,但相反,我得到辊。分享我的python代码,以防有人发现问题所在:
import numpy as np
class Camera():
def __init__(self):
self.sens = np.array([0.002, 0.002]) # mouse sensitivity (x, y)
self.angpos = np.array([0.0, 0.0]) # (pitch, yaw)
def mouse_move(self, pos, rel):
self.angpos = rel[::-1]*self.sens # mouse relative motion (delta-x, delta-y)
ya = self.angpos[1]
yrot = np.array([
[ np.cos(ya), 0.0, np.sin(ya), 0.0],
[ 0.0, 1.0, 0.0, 0.0],
[-np.sin(ya), 0.0, np.cos(ya), 0.0],
[0.0, 0.0, 0.0, 1.0]
])
xa = self.angpos[0]
xrot = np.array([
[ 1.0, 0.0, 0.0, 0.0 ],
[ 0.0, np.cos(xa), -np.sin(xa), 0.0 ],
[ 0.0, np.sin(xa), np.cos(xa), 0.0 ],
[ 0.0, 0.0, 0.0, 1.0 ],
])
return yrot @ xrot # view matrix
# this is the callback for mouse movement. `pos` is absolute mouse
# position in the screen and `rel` is the position relative to previous call
# def mouseMotionEvent(self, pos, rel):
# view = self.cam.mouse_move(pos, rel) # self.cam is an instance of Camera
# self.view = view @ self.view
# return True
抽象地说,你的问题是俯仰和偏航引起的旋转在合成下是不闭合的。你知道吗
更具体地说:想象一下控制第一人称相机。往下看,然后向左和向右拐。你的视野会以一种完全不同的方式移动,而不是你在向前看的时候转向。然而,你的计算就像照相机的行为一样。你知道吗
每一个记号,你从右边乘以
view
一个偏航矩阵,然后再乘以一个俯仰矩阵。这意味着一段时间后,视图矩阵将是许多俯仰和偏航矩阵的交替乘积。但是,俯仰矩阵和偏航矩阵不能相互转换。实际上,您需要将所有俯仰矩阵放在所有偏航矩阵的左侧(或者放在右侧,这取决于您是让视图矩阵从左侧还是右侧操作,以及您的矩阵是表示视图到全局还是全局到视图变换)。你知道吗所以一个快速的解决方法就是写
view = yrot @ view @ xrot
。这样,你所有的y轴旋转都在x轴旋转的左边,一切都会好起来。嗯,至少有一段时间,但是视图矩阵最终可能会累积舍入错误,视图可能会滚动、倾斜或更糟。你知道吗我建议您不要重用视图矩阵。相反,只要存储玩家当前的俯仰和偏航,在鼠标移动时更新它,然后每次直接从俯仰和偏航重新计算视图矩阵。通过这种方式,你也可以在其他方面使用俯仰和偏航(例如,你想将俯仰限制在一定范围内,以防止你的球员做倒立或空翻),你也不会在矩阵中累积错误。你知道吗
相关问题 更多 >
编程相关推荐