Вращение одного кватерниона через вращение другого - PullRequest
0 голосов
/ 17 октября 2019

Контекст

Я работаю со Смешанной реальностью и Единством и пытаюсь контролировать вращение 3D-объекта GameObject своими руками.

Вот что у меня естьдо сих пор:

    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, которая начинается, когда встречается оператор if в Update. if проверяет конкретную позу руки, поэтому вращение «начинается», когда руки активны, и «останавливается», когда их нет.

То, что у меня хорошо работает для одного небольшого вращения,но падает, если я хочу несколько раз повернуть объект, потому что вращение _myObject просто соответствует текущему кватерниону, созданному нынешними Vector3 положениями моих рук.

Вопрос

Как я мог повернуть _myObject от его текущего вращения до нового вращения, с точностью до разницы между моими начальными и конечными позициями?

1 Ответ

1 голос
/ 17 октября 2019

В начале каждого кадра кэшируйте вращение и направление левой руки -> справа, затем используйте Quat B * Quat A, чтобы повернуть A на B в мировом пространстве, или используя transform.Rotate с Space.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;

    }
}

Вы можете использовать эту технику, за исключением только кэширования начального вращения и положения стартовой руки, но это часто приводит к неожиданному повороту вдоль локальной оси, проходящей между руками. Использование дельта-кадров для каждого кадра минимизирует это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...