如何使用四元数 (Three.js) 通过模型与相机的当前方向调整所需的旋转?



我有一个具有单个模型的Three.js Web应用程序。 我用鼠标旋转模型。 这是通过记录鼠标按下和鼠标向上事件之间随时间推移的 X/Y 移动量并使用增量 X/Y 值围绕所需轴(X Y 或 Z)旋转模型来完成的。 我不改变相机的视角或方向。

对于鼠标 Y 移动,我围绕 X 轴旋转模型,在 YZ 平面上旋转。 当模型处于其原始状态且四元数值为 (0, 0, 0 1) 时,这非常有用,因为我希望模型的顶部在向上移动鼠标时远离相机(我)旋转,当我向下移动鼠标时向相机

但是,在模型旋转后,我当然会失去这种运动视角。 例如,如果我将模型围绕 Y 轴旋转整整 180 度(水平翻转),感知到的运动就会反转。 向上移动鼠标会将模型移向相机,向下移动鼠标会使模型远离相机。

我的问题是,如何调整旋转操作以保持所需的感知运动,而不管模型的四元数值如何由于运动而变化? 也就是说,在给定模型当前四元数的情况下,我需要采取哪些步骤/操作来补偿模型的当前方向,以便在移动鼠标时获得与模型相同的感知运动?

我使用以下代码来旋转模型,其中对象是模型,轴是所需的(纯 X、Y 或 Z),弧度是所需的旋转角度:

function rotateAroundObjectAxis(object, axis, radians)
{
    var rotObjectMatrix = new THREE.Matrix4();
    rotObjectMatrix.makeRotationAxis(axis.normalize(), radians);
    object.matrix.multiply(rotObjectMatrix);
    object.rotation.setFromRotationMatrix(object.matrix);
}

您希望从旋转对象的角度进行旋转,因此需要将旋转左乘。

因此,如果最终的 MVP 矩阵来自perspective*view*model那么您需要在模型和视图矩阵之间插入旋转。

function rotateAroundObjectAxis(object, axis, radians)
{
    var rotObjectMatrix = new THREE.Matrix4();
    rotObjectMatrix.makeRotationAxis(axis.normalize(), radians);
    rotObjectMatrix.multiply(object.matrix);
    object.matrix = rotObjectMatrix;
    object.rotation.setFromRotationMatrix(object.matrix);
}

最新更新