gma*_*gno 1 python opengl camera rotation
我正在尝试生成一个像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
Run Code Online (Sandbox Code Playgroud)
小智 5
抽象地说,你的问题是由俯仰和偏航引起的旋转在组成下不是封闭的.
更具体地说:想象一下控制第一人称相机.向下看,然后向左和向右转.你的观点将以一种非常不同的方式移动,而不是在你直视前方时转动.但是,您的计算就像摄像机的行为一样.
每个刻度线,您view从右侧乘以偏航矩阵,然后是音高矩阵.这意味着一段时间后,您的视图矩阵将成为许多俯仰和偏航矩阵的交替产物.但是,俯仰和偏航矩阵不通勤.你真正想要的是在所有偏航矩阵的左边(或者在右边,根据你是否让你的视图矩阵从左边或右边操作,以及你的矩阵是否代表视图到 - 全局或全局到视图转换).
所以快速解决这个问题就是写view = yrot @ view @ xrot.这样,你所有的y旋转都会在x旋转的左边结束,一切都会好的.好吧,至少有一段时间,但是你的视图矩阵可能最终累积舍入误差,并且视图可能会变得卷曲或倾斜或更糟.
我建议您根本不重用视图矩阵.相反,只需存储玩家当前的俯仰和偏航,在鼠标移动时更新它,然后每次直接从俯仰和偏航重新计算视图矩阵.这样你也可以通过其他方式使用俯仰和偏航(例如你想要将音高限制在一定的范围内,以防止你的玩家做倒立或翻筋斗),你也不会在矩阵中累积错误.