我正试图生成一个视图矩阵,这将作为一个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下面是我得到的一些行为:

发布于 2019-02-26 13:29:26
抽象地说,你的问题是,由俯仰和偏航引起的旋转在构图中并不是封闭的。
更具体地说:想象一下控制第一人称摄像机。往下看,然后向左和右转。当你直视前方时,你的观点将以一种截然不同的方式移动。然而,你的计算,表现得就像摄像机一样。
每一个滴答,你把view从右边乘以一个偏航矩阵,然后是一个基音矩阵。这意味着过一段时间,您的视图矩阵将是许多音调矩阵和偏航矩阵的交替乘积。然而,音高和偏航矩阵不通勤。你真正想要的是在所有偏航矩阵的左边(或者右边,取决于你是让你的视图矩阵从左还是右操作,以及你的矩阵是代表视图到全局还是全局到视图的转换)。
因此,快速解决这个问题的方法是编写view = yrot @ view @ xrot。这样的话,所有的y旋转都会在x旋转的左边结束,一切都会好起来的。好吧,至少有一段时间,但是您的视图矩阵最终可能会累积舍入错误,视图可能会滚动、倾斜或更糟。
我建议您不要重用视图矩阵。相反,只需存储玩家当前的俯仰和偏航,在鼠标运动时更新它,然后每次从俯仰和偏航中直接重新计算视图矩阵。这样你也可以以其他方式使用音高和偏航(例如,你想把音高夹在一定的范围内,以防止玩家倒立或翻筋斗),你也不会在你的矩阵中积累错误。
https://stackoverflow.com/questions/54886220
复制相似问题