通过拖动在libGDX中逼真地旋转3D模型

时间:2015-06-07 04:22:32

标签: java android 3d rotation libgdx

我正在尝试在libGDX中创建一个用户可以通过点击(或点击)和拖动来旋转的多维数据集。我希望它感觉好像是在你滑动的方向上拖动立方体的边缘,这让我遇到了问题。我需要模型独立于旋转方式旋转。

例如,如果定位立方体使Y轴垂直延伸,则向右滑动应围绕Y轴旋转立方体。但是,如果另一个轴(比如X轴)在立方体当前位置垂直运行,则相同的手势应该围绕X轴旋转立方体。

当没有轴直接垂直于手势方向时,会出现更复杂的情况。是否需要在多个轴上进行某些旋转组合?

我对完成此任务所需的计算感到困惑,但我确信这是可能的,如果可能通过一种我没有想过的完全替代的方法。任何帮助或见解将不胜感激!

1 个答案:

答案 0 :(得分:1)

在这种情况下,我强烈建议您使用四元数,因为它们对于3D空间中的旋转更加独立。

但是:由于您应该知道屏幕上的滑动方向(一对X,Y屏幕坐标),您应该能够计算出代表手势的矢量。

在libgdx中,您可以通过调用相机的方法获得pickRay

.getPickRay(float screenX, float screenY)

我们需要3D空间中的两个点位于相机和物体的旋转中心之间,它们代表两个屏幕坐标,以便计算该旋转的四元数:

//你不需要规范化射线的方向,因为libgdx为你做了

final Ray ray1 = camera.getPickRay(oldScreenX, oldScreenY);
final Ray ray2 = camera.getPickRay(currentScreenX, currentScreenY);

// instead of 0.1 use some other values, preferably your camera.near value
// you can play with the scale value since it also represents how much of rotation you will get
final Vector3 screen1 = ray1.direction.cpy().scl(0.1).add(ray1.origin);
final Vector3 screen2 = ray2.direction.cpy().scl(0.1).add(ray2.origin);

既然您在3D空间中有两个点,您可以通过涉及对象中心来计算两个表示要执行的旋转的向量:

final Vector3 cross1 = screen1.cpy().sub(myObjectsCenterPosition).nor();
final Vector3 cross2 = screen2.cpy().sub(myObjectsCenterPosition).nor();
final Quaternion rotation = new Quaternion();
rotation.setFromCross(cross1, cross2);

由于您的对象旋转应该有一个四分之一,您可以将新旋转应用于对象的四元数:

myObjectRotation.mulLeft(rotation);

然后根据对象的旋转四元数旋转对象:

myModelInstance.transform.set(myObjectRotation);

我希望我没有忘记任何重要的事情。