繁体   English   中英

在3D世界中移动-OpenGL

[英]Moving in 3D world - OpenGL

因此,我目前正在研究某些游戏元素,包括OpenGL中一些类似于引擎的内容,并且我遇到了这个问题。 (处理3D世界)我正在用鼠标获取世界旋转角度,如下所示:

int prevX = mouse.x;
int prevY = mouse.y;

GetCursorPos(&mouse);

cam.xRot -= atan(prevX-mouse.x);
cam.yRot -= atan(prevY-mouse.y);

似乎运作良好。 (实际上,xRot的意思是绕Y轴旋转,而yRot绕x轴旋转)相机旋转很好。 然后我开始研究相对于相机的运动。 经过一些绘图和绝望的尝试,我来到了这里:

//W
if (keys[57])
       {
           cam.z += cos(angleY)*cos(angleX)*cam.speed;
           cam.x -= cos(angleY)*sin(angleX)*cam.speed;
           cam.y += sin(angleY);
       }
//S
if (keys[53])
       {
          cam.z -= cos(angleY)*cos(angleX)*cam.speed;
          cam.x += cos(angleY)*sin(angleX)*cam.speed;
          cam.y -= sin(angleY);
       }
//A
if (keys[41])
       {
          cam.z += sin(angleX)*cam.speed;
          cam.x += cos(angleX)*cam.speed;
       }
//D
if (keys[44])
       {
          cam.z -= cos(angleY)*sin(angleX)*cam.speed;
          cam.x -= cos(angleY)*cos(angleX)*cam.speed;
       }

它也可以工作,但是问题是当我绕z轴(深度1)旋转相机时。 我尝试了一些组合等,但似乎没有任何效果。 我想念什么? 我像上面这样计算方程式:当我将其作为2D时,只是x和z,并且我想向前移动相机以零角度旋转,所以我只需要沿z轴方向移动,这是肯定的,所以让我们使用那里最大的功能=> cos。 当我旋转90度并需要向前移动时,我需要在x轴上移动,所以我们使用sin因为我们需要相反的方向。 该手柄的2D效果很好。 现在,我需要添加z轴,因此我可能只是通过第二个角度的cos限制x和y的值(yRot或围绕x旋转的角度,如果需要的话),并使它成为y轴上的实际运动。 是的,工作正常,但正如我所说,当我绕着z旋转并基本切换y和x轴时出现问题。 怎么办呢? :d

哦,顺便说一句,我读了其他一些教程,我注意到有些人对矢量等使用不同的方式。今天的游戏中有什么通用的方式? 我真的不喜欢这么经常使用测角功能。 也许我的方法不是最好的方法吧?

当涉及到摄像机管理时,大多数人似乎使它变得比原来困难得多。 关键是矩阵数学。

考虑具有世界矩阵W的对象,该世界矩阵由旋转和平移部分组成。 如果我们想将这个对象向右移动,我们可以将一个对应的转换矩阵乘以W (注意,所有进一步的解释都假定OpenGL表示法带有列向量和列主矩阵):

W* = W * T(x, 0, 0)

重要的是乘法顺序。 如果将平移矩阵乘以右侧,它将在对象的局部坐标系中移动对象。 如果将其乘以左侧,它将在全局坐标系中移动它。 类似地,我们可以乘以旋转矩阵以在对象的局部坐标系中旋转对象:

W** = W* * Rx(phi)

现在,摄像机的视图矩阵有点棘手,因为它实际上是一个倒置矩阵。 因此,如果您有视图矩阵V ,则必须将逆矩阵乘以左侧:

V*  = T(-x, 0, 0) * V
V** = Rx(-phi) * V*
//...

但是,这一问题是上矢量的固定。 如果绕局部y轴执行旋转,则向上方向可能会更改。 我们可以计算一个自适应矩阵,这样可以避免这种情况,但是仅从两个角度重新计算整个旋转矩阵可能会容易得多。 重新计算矩阵后,必须将其重新放置在旧位置(全局位置,因此将转换矩阵乘以左侧)。 计算旧位置需要一些数学运算(因为矩阵是倒数的):

pos = -tx * first row - ty * second row - tz * third row
where tx is the entry in the first row, last column
      ty is the entry in the second row, last column
      tz is the entry in the third row, last column

摘要

如果要保持灵活的摄像机表示,请存储视图矩阵和两个旋转角度。 如果要移动相机,只需将转换矩阵相乘即可​​。 如果要围绕局部X轴旋转摄像机,请更改角度并乘以旋转矩阵。 如果要绕局部y轴旋转,请更改角度并重新计算整个矩阵,包括重新定位。

您当前的解决方案基本上是这样做的,因为三角测量结果恰好是矩阵在相关位置的输入。 但是,正如您所看到的,维护起来非常麻烦,如果要允许第三次轮换,则必须更改整个代码。

拥抱矩阵数学!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM