Libgdx如何根据手机方向在多个轴上旋转3D模型

4

我试图使用手机的加速计在多个轴上同时旋转3D模型。当我这样做时,我使用setToRotation(),然而这只能一次旋转一个轴。

例如:

  ModelInstance modelInstance = instances.first(); 

  //ROLL
  modelInstance.transform.setToRotation(Vector3.Z, phoneAccel.y*9);
  //PITCH
  modelInstance.transform.setToRotation(Vector3.X, phoneAccel.z*9);

手机处于强制横屏模式。我获取了想要旋转的模型实例。
我根据 Gdx.input.getAccelerometerX/Y/Z() 设置了 Vector3 phoneAccel。
在上面的示例中,这两行代码都可以正常工作,但只能单独使用。当我尝试同时使用它们(一个接一个地)时,第一个旋转(ROLL)被删除了。我原本以为这两个旋转矩阵会累加,即先将 Z 轴应用旋转,然后再将 X 轴应用旋转。
我需要创建自己的累积旋转矩阵,然后在最后应用吗?
有什么想法吗?谢谢。
2个回答

8

Matrix4#setToRotation 方法将删除之前设置的任何变换(比如旋转),因此被称为 "setTo"。如果要向已经旋转的矩阵中添加旋转变换,请使用 rotate 方法。这将对变换进行后置乘。

modelInstance.transform.setToRotation(Vector3.Z, phoneAccel.y*9);
modelInstance.transform.rotate(Vector3.X, phoneAccel.z*9);

然而,如果你想要让旋转互相独立(例如,绕Z轴的旋转不应该影响绕X轴的旋转),那么这个方法就不能产生你想要的结果。为了解决这个问题,你可以使用欧拉角:

modelInstance.transform.setFromEulerAngles(yaw, pitch, roll);

谢谢,setFromEulerAngles 就是我想要的。你知道这个计算背后是否有任何开销,例如任何平方根函数吗? - Jammo
2
没有sqrt,但涉及到几个sin和cos调用(这几乎总是在通过角度设置旋转时发生的)。 - Xoppa
实际上,有一个小问题。这对于旋转来说很好用,但如果我想移动对象(平移),那么这就不起作用了。也许是一个单独的问题,但是我正在使用 setFromEulerAngles(),然后跟着一个 transform.translate(x,y,z),但它没有起作用(没有平移)。如果我在旋转之前进行平移,那么模型会旋转,但是围绕不同的原点旋转。 - Jammo
3
使用 modelInstance.transform.setFromEulerAngles(yaw, pitch, roll).trn(x, y, z);。该代码用于将一个3D模型实例的变换属性设置为旋转角度(yaw、pitch、roll)和平移向量(x、y、z)。 - Xoppa

2
方法setToRotation设置模型为此旋转,正如名称所示。这意味着您“覆盖”了绕Z轴的旋转,并将其设置为仅绕X轴旋转。
有不同的方法可以实现您想要实现的内容:
  • 您可以像@noone说的那样使用 Quaternion
  • 您可以使用 rotate 。如果您这样做,则需要将当前旋转存储在例如 Vector2 中,其中x值是绕Z轴的当前旋转,y值是绕X轴的旋转。
  • 您可以使用自定义轴的 setToRotation ,该轴由 phoneAccel 值构造而成。
setToRotation 方法使您能够定义 Vector3 direction Vector3 face ,定义哪个面应朝向此方向。 例如: modelInstance.transform.setToRotation(Vector3.Z,Vector3.Y)将使其顶部朝向Z方向。使用 Vector3(0,-1,0),底部(也许是脚)将朝向该方向。
希望这很清楚

感谢您的输入。我选择了setFromEulerAngles作为解决方案。 - Jammo
@Jammo,对于你的情况,这是一个不错的版本。我没有记得这个。我只记得使用两个向量的setToRotation,因为我需要它,因为我有一个给定的“方向”向量。 - Robert P

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接