【问题标题】:Realistic rotation of a 3D model in libGDX by dragging通过拖动在 libGDX 中实现 3D 模型的真实旋转
【发布时间】:2015-08-21 18:59:06
【问题描述】:

我正在尝试在 libGDX 中创建一个立方体,用户可以通过点击(或单击)和拖动来旋转它。我希望它感觉好像立方体的边缘被拖向您滑动的方向,这让我想到了我的问题。我需要模型独立于它已经旋转的方式旋转。

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

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

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

【问题讨论】:

    标签: java android 3d rotation libgdx


    【解决方案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);
    

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

    【讨论】:

    • Matrix4.setToRotation 不接受四元数作为参数。另外,oldScreenX 和 oldScreenY 是初始触摸的位置,而 currentScreenx 和 currentScreenY 是移动后的当前触摸位置吗?
    • 确实如此!抱歉,请改用 myMatrix.set(quaternion)。同样是的,你是对的,但不要忘记在每一帧之后更新 oldScreenX 和 oldScreenY,这样你总是得到每一帧的手势移动矢量,而不是整个手势。
    猜你喜欢
    • 1970-01-01
    • 2017-10-02
    • 2016-07-19
    • 2010-12-18
    • 2022-08-21
    • 1970-01-01
    • 2019-12-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多