【openGL2021版】实现FPS的摄像机控制
大家好,我是Lampard猿奋~
欢迎来到船新的openGL基础系列的博客,今天主要是实现FPS式的摄像机控制
(1)实现视角左右旋转
上一篇博客我们已经实现了通过“WASD”对摄像机的前后左右位置进行移动。把摄像机想象成我们的人,那么它除了可以移动之外当然还可以通过转动头部视线来看到不同的东西,我们首先实现实现的左右移动
(1)实现视线变换的方法
我们给carame类声明一个内部方法RotateView。这个方法主要内容为三步,首先是算出当前的视线,然后是根据公式对视线进行换算,最后是更新我们的视线
这个方法需要四个参数,分别是旋转的角度,以及旋转轴的xyz,然后我们就可以根据下图的公式去进换算了,公式在之后的可编程管线博客再去研究,现在先去实现这个方法
C是cos(angle),S是sin(angle),AxAyAz是旋转轴的三个参数,我们照着写就好了
(2)重载*号运算符
在算出tempX,tempY,tempZ之后,再和我们的视线进行点乘就可以得出新视线的xyz了,为了方便,我们和之前那样重载*号运算符
然后我们再对新的视线newDirection进行赋值
(3)测试左右旋转效果
我们先在"A","D"的逻辑中测试左右旋转,假设它们的旋转速度是1,那么每次update旋转的角度就是1*time,而旋转轴我们是Y轴的正方向,可以传入010
我们看一下效果
(2)视线上下旋转
刚才我们实现了左右旋转,接下来我们要实现上下旋转
(1)叉乘得出旋转轴
之前我们的旋转轴是写死了010,沿着Y轴正方向进行左右旋转,而上下旋转就应该沿着我们的x正方向进行旋转。而写死其实是不好的,我们有一个mup的向量其实就是我们头顶(Y方向)的向量,因此我们可以把mup向量的x,y,z传入参数得到的效果是一样的
而x轴我们可以用视线和up向量进行叉乘得出,叉乘我们通过重载^实现
我们替换一下坐标轴就可以实现上下旋转了
我们看一下效果
(3)利用鼠标进行摄像机旋转控制
我们现在已经实现了上下左右的旋转效果,但是还存在两个问题,首先是需要把从键盘控制改到鼠标控制,才能还原我们FPS上的效果,其次是需要根据鼠标滑动的距离,来决定旋转的角度,而不是线性的根据时间运算
(1)把上下左右旋转的方法封装
为了方便,我们先把之前实现的上下左右旋转的方法进行封装,把上下旋转的方法名命为Pitch,左右移动的方法命名为Yaw,它们的参数都是传入一个angel角度就可以了
(2)监听鼠标事件
我们要监听鼠标的点击以及移动状态,从而获得摄像机移动的角度,我设置了一个全局变量originalPos来记录鼠标点击时的位置,然后再根据移动的位置来求出鼠标移动的方向和距离。还设置了一个bRotateView来记录是否正在移动的标记(避免我们正常移动鼠标的时候触发事件)
如果bRotateView为true就是正在移动的时候,我们则对鼠标的移动事件进行监听,主要是算出鼠标移动终点到起点之前的deltaX和deltaY,然后将其除1000使之接近于0,根据极限sinX / X limitx->0 = 1,我们可以认为距离就等于移动的角度,然后调用我们的Yaw和Pitch就好了
最后前后左右移动,鼠标随意旋转都实现了