安卓.如何沿它所面对的方向移动对象(使用 Vector3 和四元数)

2022-01-12 00:00:00 opengl-es android java libgdx

我正在使用 libGDX(实际上对它来说很新)和 Android.我想将 3d 对象朝它所面对的方向移动(使用一些速度).我认为这是一个基本问题,但找不到直接的答案.我有一个表示对象旋转(方向)的四元数,我有一个表示对象位置的 Vector3.问题是如何使用来自四元数的信息更新位置 Vector3,以便在四元数表示的方向上移动对象.(另一种方法是从四元数中提取滚动俯仰和偏航,并通过应用三角计算获得新坐标.但我认为必须有一种方法可以使用 Vector3 和 Quat 来实现.)

I'm using libGDX (quite new to it in fact) and Android. And I want to move 3d object in the direction it is facing (using some speed). I thinks it's a basic question but can't find a straight nswer for it. I have a Quaternion representing object rotation(direction) and I have a Vector3 representing the object position. The question is how to update the position Vector3 using info from Quaternion in order to move object in the direction represented by Quaternion. (An alternative to this is extract roll pitch and yaw from Quaternion and get the new coords by applying trigonometric calculations. But i think there must be a way to achieve this using Vector3 and Quat.)

推荐答案

四元数用于指定旋转.您首先需要指定不应用旋转时的方向.例如,如果您想在未应用旋转时沿 X 轴移动:

Quaternion is used to specify a rotation. You first need to specify the direction when no rotation is applied. For example if you want to move along the X axis when no rotation is applied:

Vector3 baseDirection = new Vector3(1,0,0);

确保基准方向是标准化的(长度=1),您可以使用nor()方法以确保安全:

Make sure the base direction is normalized (length = 1),you can use the nor() method to be safe:

Vector3 baseDirection = new Vector3(1,0,0).nor();

接下来您需要使用四元数旋转方向:

Next you'll need to rotate the direction using the Quaternion:

Vector3 direction = new Vector3();
Quaternion rotation = your_quaternion;
direction.set(baseDirection);
direction.mul(rotation);

现在您已经有了方向,您可以按照您想要移动的量对其进行缩放.您可能希望每帧都执行此操作,具体取决于自上一帧以来经过的时间.

Now that you have the direction, you can scale it with the amount you want to move it. You'll probably want to do this every frame and depending on the time elapsed since the last frame.

final float speed = 5f; // 5 units per second
Vector3 translation = new Vector3();
translation.set(direction);
translation.scl(speed * Gdx.graphics.getDeltaTime());

最后你需要将翻译添加到位置

Finally you need to add the translation to the position

position.add(translation);

当然,根据您的实际实现,您可以批处理多个操作,例如:

Of course, depending on your actual implementation you can batch multiple operations, e.g.:

translation.set(baseDirection).mul(rotation).scl(speed * Gdx.graphics.getDeltaTime());
position.add(translation);

更新:从 Xoppa 的评论中添加工作代码:

Update: Adding working code from Xoppa's comment:

translation.set(baseDirection).rot(modelInstance.transform).nor().scl(speed * delta)

相关文章