基于鼠标移动的旋转四元数(OpenGL和Java)

我正在使用OpenGL编写游戏(LWJGL绑定,具体而言)。 包括相机在内的每个实体都有一个代表其旋转的四元数。 我已经想出了如何将四元数应用于当前的OpenGL矩阵,并且一切都很好。 我遇到的问题是让相机随鼠标旋转。

现在,每一帧,游戏都会抓住鼠标在一个轴上移动的数量,然后将该数量应用于四元数以便相机旋转。 这里是旋转四元数的代码,我会发布它,因为我认为这是问题所在(虽然我总是对这类东西错误):

    public void rotateX(float amount){
        Quaternion rot = new Quaternion(1.0f, 0.0f, 0.0f, (float)Math.toRadians(amount));
        Quaternion.mul(rot, rotation, rotation);
        rotation.normalise();
    }

这种方法应该是围绕X轴旋转四元数。 '旋转'是代表实体旋转的四元数。 'amount'是我想要旋转四元数的量(即鼠标移动的量)。 “腐”是连同转换为弧度(我想这里的目标是给它一个角度 - 说,10度 - 并将它沿着由所述给定轴线转动四元数的数量的AW值X轴的归一化矢量角度)。 使用Quaternion.mul将新四元数乘以旋转四元数,然后将结果存储为旋转四元数。 我不知道规范化是否必要,因为'腐烂'是正常的,'旋转'应该已经归一化了。

的旋转Y和rotateZ方法做同样的事情,不同的是改变矢量关于“腐”(0.0,1.0,0.0 y和0.0,0.0,1.0 z)表示。

当游戏开始并且相机正在向下看负Z轴时,代码看起来工作正常。 您可以一直旋转Y轴围绕X轴旋转。 但是,只要你试图旋转相机而不看Z轴,一切都变得非常棘手(我甚至无法形容它,它旋转非常奇怪)。

我的最终目标是要有一些东西用来在没有向上矢量的空间中控制一艘船。 因此,当您将鼠标移动到Y轴上时,无论船舶处于何种角度,它都会改变船的俯仰(沿X轴旋转)。 同样,当您在X轴上移动鼠标时,它会改变偏航(沿Y轴旋转)。 我可能会以这种错误的方式进行,我可能只需要向正确的方向推(或推)。

如果你需要更多关于任何东西的细节(我的渲染是如何完成的,我想要做的其他数学)就问一下,然后我会把它解决。 我我使用欧拉角时,明白了一切(这显然是一大禁忌的3D应用程序的开发......希望有人会告诉我,我才沉没了大量的时间到让他们的工作),但只要我切换到四元数,我真的很快进入了我的脑海。 过去几个月我一直在玩这个代码并阅读关于四元数的内容,试图让它起作用,但我还没有真正得到任何地方:'(

非常非常令人沮丧......开始后悔试图在3D> _ <中做出一些事情


Quaternion rot = new Quaternion(1.0f, 0.0f, 0.0f, (float)Math.toRadians(amount));

好的,这是错误的。

采用四个浮点数的构造函数假定它们表示一个实际的四元数。 你给那个构造函数不是一个四元数; 这是一个vec3轴和你期望旋转的角度。

你不能将它们推入四元类,并希望得到一个合法的四元数。

你的四元类应该有一个构造函数或者其他一些从一个角度和一个旋转轴创建一个四元数的方法。 但根据您链接到的文档,它不会。 所以你必须自己做。

四元数不是一个vec3轴,第四个值是一个角度。 单位四元数表示方位的变化是vec3,它是旋转轴*旋转角度的一半的正弦,标量分量是旋转角度的一半的余弦。 这假设旋转角度被限制在[-pi / 2,pi / 2]的范围内。

因此,你想要的是这样的:

float radHalfAngle = ... / 2.0; //See below
float sinVal = Math.Sin(radHalfAngle);
float cosVal = Math.Cos(radHalfAngle);
float xVal = 1.0f * sinVal;
float yVal = 0.0f * sinVal;  //Here for completeness.
float zVal = 0.0f * sinVal;  //Here for completeness.
Quaternion rot = new Quaternion(xVal, yVal, zVal, cosVal);

此外,直接将amount转换为弧度并不合理,特别是如果amount只是鼠标移动的像素坐标增量。 您需要在鼠标移动的距离和要旋转的距离之间进行某种转换。 对于toRadians来说,并不是你想要的那种规模。

还有一件事。 就像你在这里所做的那样,左乘法rot将围绕相机空间X轴执行旋转。 如果你想要一个关于世界空间X轴的旋转,你需要正确地乘以它。

链接地址: http://www.djcxy.com/p/14343.html

上一篇: Rotating quaternions based on mouse movement (OpenGL and Java)

下一篇: Rotating OpenGL scene in 2 axes