2015-03-31 2 views
1

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

Задача 1:

Единство и Threejs имеют различные системы координат

Unity:

enter image description here

Threejs

enter image description here

Задача 2:

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

EDIT 1

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

Convert Unity transforms to THREE.js rotations

Однако, я не был в состоянии получить этот код, чтобы работать продвигается в противоположном направлении Тридж к Единству, которое мне нужно.

+0

ли листать между системами координат так просто, как Z * -1? – Donnelle

ответ

0

Я нашел решение этой проблемы, используя следующие ссылки. Там может быть более легкое решение, но ничто другое, что я пробовал, дало мне предполагаемый эффект. Стоит отметить, что это было проверено с помощью камеры Threejs, которая равна -z, где + y. Моя единственная камера -z обращена к + y вверх. Если у вас есть камера с обратной связью + z, которая распространена в Unity, просто передайте GameObject в пустой GameObject и примените поворот Эйлера на 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:

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

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

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

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

+0

Это не сработает, поскольку мы говорим о поворотах в этих двух системах. Если бы мы говорили о различиях в позициях, это могло бы сработать, но это не сработало бы для поворота углов Эйлера. – Matt

+0

Вы заглянули в матрицы вращения? Я считаю, что это может быть хорошим способом разрешения обоих конфликтов, поскольку они могут использоваться для абстрактного упорядочения поворота. Тогда вам нужно просто оставить простые преобразования координат. – CShannon

+0

Я искал вращение матрицы. Я смог получить углы Эйлера из Threejs в матрицу вращения, используя эту вики: http://en.wikipedia.org/wiki/Euler_angles На этом этапе я попытался преобразовать матрицу из правой руки влево с использованием: http://stackoverflow.com/questions/1263072/changing-a-matrix-from-right-handed-to-left-handed-coordinate-system На этом этапе я попытался извлечь вращение как кватернион обратно из матрицы. Один из последних двух шагов не работал, поскольку повороты не выстраиваются в линию. Проверьте мое редактирование, если сможете – Matt