通过旋转另一个四元数来旋转一个四元数

Rotating one quaternion via the rotation of another

上下文

我正在使用混合现实和 Unity,并试图用我的双手控制游戏对象的 3d 旋转。

这是我目前的情况:

    Vector3 _lefthand = new Vector3(Left.x, Left.y, Left.z);
    Vector3 _righthand = new Vector3(Right.x, Right.y, Right.z);
    _myObject.transform.rotation = Quaternion.FromToRotation(Vector3.right, _righthand - _lefthand));

该块包含在 IEnumerator 协程中,该协程在满足 Update 中的 if 语句时启动。 if 检查特定的手部姿势,因此当手部姿势处于活动状态时旋转 'starts',当手部姿势不活动时旋转 'stops'。

我有的对于一个小的旋转效果很好,但是如果我想旋转物体几次就会失败,因为 _myObject 的旋转刚好匹配当前创建的当前四元数 Vector3 我手的位置。

问题

我如何将 _myObject 当前旋转 旋转到新的旋转,我的手开始和结束位置之间的差异幅度?

在每帧开始时,缓存旋转和左手 -> 右手方向然后使用 Quat B * Quat A 在世界 space 中将 A 旋转 B 或使用 transform.RotateSpace.World.

IEnumerator DoRotate()
{        
    Vector3 previousLeftHand = new Vector3(Left.x, Left.y, Left.z);
    Vector3 previousRightHand = new Vector3(Right.x, Right.y, Right.z);  

    Vector3 previousFromLeftToRight = previousRightHand - previousLeftHand;

    while (!doneFlag)
    {
        yield return null;

        Vector3 newLeftHand = new Vector3(Left.x, Left.y, Left.z);
        Vector3 newRightHand = new Vector3(Right.x, Right.y, Right.z);

        Vector3 newFromLeftToRight = newRightHand - newLeftHand;

        Quaternion deltaRotationWorld = Quaternion.FromToRotation(
                previousFromLeftToRight, newFromLeftToRight);

        _myObject.transform.rotation = deltaRotationWorld * _myObject.transform.rotation;
        // or _myObject.transform.Rotate(deltaRotationWorld, Space.World);

        previousFromLeftToRight = newFromLeftToRight;

    }
}

除了仅缓存起始旋转和起始手位置外,您可以使用此技术,但它通常会导致沿局部轴在手之间进行意外旋转。使用每帧增量可以最大限度地减少这种情况。