Преобразование углов Эйлера между системами с разными осями координат (Unity и Threejs)

1

Я пытаюсь преобразовать повороты угла Эйлера между Unity и Threejs. С этим связаны две основные проблемы.

Задача 1:

Unity и Threejs имеют разные системы координат

Единство:

Изображение 174551

Threejs

Изображение 174551

Проблема 2:

Unity делает математику euler в порядке ZXY, тогда как Threejs по умолчанию - XYZ. Я нашел некоторые формулы на стороне Threejs для создания углов Эйлера, используя другой порядок умножения, но я хотел бы знать математику за этим, чтобы я мог идти туда и обратно между двумя системами. Я также не уверен, как разные системы координат играют в эту математику преобразования.

ИЗМЕНИТЬ 1

Я нашел этот пост о преобразовании Quarterion Unity в Threejs:

Преобразование Unity преобразуется в поворот THREE.js

Тем не менее, я не смог заставить этот код работать для перехода в противоположном направлении от Threejs к Unity, который мне нужен.

  • 0
    Является ли переключение между системами координат столь же простым, как Z * -1?
Теги:
unity3d
math
three.js
euler-angles

2 ответа

0
Лучший ответ

Наконец, я нашел решение для этого, используя ссылки ниже. Там может быть более легкое решение, но ничто другое, что я пробовал, дало мне предполагаемый эффект. Стоит отметить, что это было проверено с помощью камеры Threejs, которая -z обращена к тому, где +y работает. Моя единственная камера -z обращена к +y вверх. Если у вас есть камера +z, которая распространена в Unity, просто загрузите GameObject в пустой GameObject и примените поворот Euler на 180 градусов к пустому GameObject. Это также предполагает, что поворот триггера Эйлера является стандартным XYZ-упорядочением.

http://answers.unity3d.com/storage/temp/12048-lefthandedtorighthanded.pdf

http://en.wikipedia.org/wiki/Euler_angles

http://forum.unity3d.com/threads/how-to-assign-matrix4x4-to-transform.121966/

    /// <summary>
    /// Converts the given XYZ euler rotation taken from Threejs to a Unity Euler rotation
    /// </summary>
    public static Vector3 ConvertThreejsEulerToUnity(Vector3 eulerThreejs)
    {
        eulerThreejs.x *= -1;
        eulerThreejs.z *= -1;
        Matrix4x4 threejsMatrix = CreateRotationalMatrixThreejs(ref eulerThreejs);

        Matrix4x4 unityMatrix = threejsMatrix;
        unityMatrix.m02 *= -1;
        unityMatrix.m12 *= -1;
        unityMatrix.m20 *= -1;
        unityMatrix.m21 *= -1;

        Quaternion rotation = ExtractRotationFromMatrix(ref unityMatrix);
        Vector3 eulerRotation = rotation.eulerAngles;
        return eulerRotation;
    }

    /// <summary>
    /// Creates a rotation matrix for the given threejs euler rotation
    /// </summary>
    private static Matrix4x4 CreateRotationalMatrixThreejs(ref Vector3 eulerThreejs)
    {
        float c1 = Mathf.Cos(eulerThreejs.x);
        float c2 = Mathf.Cos(eulerThreejs.y);
        float c3 = Mathf.Cos(eulerThreejs.z);
        float s1 = Mathf.Sin(eulerThreejs.x);
        float s2 = Mathf.Sin(eulerThreejs.y);
        float s3 = Mathf.Sin(eulerThreejs.z);
        Matrix4x4 threejsMatrix = new Matrix4x4();
        threejsMatrix.m00 = c2 * c3;
        threejsMatrix.m01 = -c2 * s3;
        threejsMatrix.m02 = s2;
        threejsMatrix.m10 = c1 * s3 + c3 * s1 * s2;
        threejsMatrix.m11 = c1 * c3 - s1 * s2 * s3;
        threejsMatrix.m12 = -c2 * s1;
        threejsMatrix.m20 = s1 * s3 - c1 * c3 * s2;
        threejsMatrix.m21 = c3 * s1 + c1 * s2 * s3;
        threejsMatrix.m22 = c1 * c2;
        threejsMatrix.m33 = 1;
        return threejsMatrix;
    }

    /// <summary>
    /// Extract rotation quaternion from transform matrix.
    /// </summary>
    /// <param name="matrix">Transform matrix. This parameter is passed by reference
    /// to improve performance; no changes will be made to it.</param>
    /// <returns>
    /// Quaternion representation of rotation transform.
    /// </returns>
    public static Quaternion ExtractRotationFromMatrix(ref Matrix4x4 matrix)
    {
        Vector3 forward;
        forward.x = matrix.m02;
        forward.y = matrix.m12;
        forward.z = matrix.m22;

        Vector3 upwards;
        upwards.x = matrix.m01;
        upwards.y = matrix.m11;
        upwards.z = matrix.m21;

        return Quaternion.LookRotation(forward, upwards);
    }
0

Задача 1:

Конечно, я только миновал по математике, но я считаю, что вы просто должны сделать прямое сопоставление для точек:

(X, Y, Z) => (X, Y, -Z)

И это должно работать в обоих направлениях.

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

  • 0
    Это не будет работать, поскольку мы говорим о вращениях в этих двух системах. Если бы мы говорили о разнице положения, это могло бы сработать, но не сработало бы для поворотов по Эйлеру.
  • 0
    Вы смотрели на матрицы вращения тогда? Я считаю, что это может быть хорошим способом разрешения обоих конфликтов, поскольку их можно использовать для абстрагирования порядка вращения. Тогда вам просто нужно оставить простые преобразования координат.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню