我正在 OpenGL (java LWGJL) 中处理一些简单的 3d 图形,我试图弄清楚如何将偏航、俯仰和滚动转换为我的运动矢量的 x、y 和 z 分量。我知道如何只用俯仰和偏航来做到这一点(如此处所述),但我还没有找到任何解释如何将滚动集成到这个公式中的东西。
我知道偏航和俯仰是在 3d 空间中定义矢量所需的全部,但在这种情况下我也需要滚动。在基本的 WASD 配置中,我将键绑定到相对于相机的不同运动(A本地左侧,W本地向前,SPACE本地向上),因此滚动会影响相机的移动方式(例如,按下Dpi/2 的滚动(默认)向右移动相机(在世界坐标中),但按下D一卷 pi 会在世界坐标中向上移动相机))。
这是我到目前为止的代码:
//b = back
//f = forward
//r = right
//l = left
//u = up
//d = down
private void move()
{
double dX = 0, dY = 0, dZ = 0;
if (f ^ b)
{
dZ += cos(yaw) * cos(pitch) * (b ? 1 : -1);
dX += sin(yaw) * cos(pitch) * (b ? 1 : -1);
dY += -sin(pitch) * (b ? 1 : -1);
}
if (l ^ r)
{
dZ += sin(yaw) * sin(roll) * (l ? 1 : -1);
dX += cos(yaw) * - sin(roll) * (l ? 1 : -1);
dY += cos(roll) * (l ? 1 : -1);
}
if (u ^ d) //this part is particularly screwed up
{
dZ += sin(pitch) * sin(roll) * (u ? 1 : -1);
dX += cos(roll) * (u ? 1 : -1);
dY += cos(pitch) * sin(roll) * (u ? 1 : -1);
}
motion.x = (float) dX;
motion.y = (float) dY;
motion.z = (float) dZ;
if (motion.length() != 0)
{
motion.normalise();
motion.scale(2);
}
x += motion.x;
y += motion.y;
z += motion.z;
这适用于几个旋转,但对于许多它会产生不正确的结果。
所以问题是:
如何修改我的代码,以便它根据我想要的方向(按下什么键)成功计算我的运动矢量的 x、y 和 z 分量,并考虑我的偏航、俯仰和滚动?
我可以使用 raw trig(正如我正在尝试做的那样)、涉及矩阵的解决方案或几乎任何东西。
编辑:
请不要仅仅通过链接到关于欧拉角的维基百科文章来回答。我读过它,但我没有足够强大的数学背景来理解如何将它应用到我的情况中。
编辑#2:
我只使用欧拉角在重新定位相机之间存储我的方向。对于实际的相机操作,我使用旋转矩阵。如果需要,我可以删除欧拉角并只使用矩阵。重要的是我可以从我的方向转换为矢量。
编辑#3:
如评论中所述,通过将我的前向向量乘以我的旋转矩阵找到了一个解决方案:
//b = back
//f = forward
//r = right
//l = left
//u = up
//d = down
private Vector3f motion;
protected void calcMotion()
{
//1 for positive motion along the axis, -1 for negative motion, 0 for no motion
motion.x = r&&!l ? -1 : l ? 1 : 0;
motion.y = u&&!d ? 1 : d ? -1 : 0;
motion.z = f&&!b ? 1 : b ? -1 : 0;
if (motion.length() == 0)
{
return;
}
motion.normalise();
//transform.getRotation() returns a Matrix3f containing the current orientation
Matrix3f.transform(transform.getRotation(), motion, motion);
}
不过,这仍然有问题。