2015-03-31 1 views
1

Je tente de convertir les rotations d'angle euler entre Unity et Threejs. Il y a deux problèmes principaux avec ceci.Convertir des angles d'Euler entre des systèmes avec différents axes de coordonnées (Unity et Threejs)

Problème 1:

unité et Threejs ont différents systèmes de coordonnées

Unité:

enter image description here

Threejs

enter image description here

Problème 2:

unité fait math euler dans le ZXY de commande alors que les valeurs par défaut Threejs à XYZ. J'ai trouvé quelques formules du côté de Threejs pour créer des angles d'Euler en utilisant un ordre différent de multiplication, mais j'aimerais connaître les maths derrière ceci afin que je puisse aller et venir entre les deux systèmes. Je ne suis pas sûr comment les différents systèmes de coordonnées jouent dans cette maths de conversion.

EDIT 1

Je trouve ce poste de débordement de pile sur la conversion d'une unité quaternion Threejs:

Convert Unity transforms to THREE.js rotations

Cependant, je n'ai pas pu obtenir ce code à travailler pour aller le direction opposée de Threejs à l'Unité qui est ce dont j'ai besoin.

+0

feuillette entre les systèmes de coordonnées aussi simple que Z * -1? – Donnelle

Répondre

0

J'ai finalement trouvé une solution à cela en utilisant les liens ci-dessous. Il peut y avoir une solution plus facile, mais rien d'autre que j'ai essayé ne m'a donné l'effet escompté. Il est à noter que cela a été testé avec une caméra de Threejs -z face où + y est en place. Mon appareil photo est -z face à face avec + y vers le haut. Si vous avez un + z face à la caméra, ce qui est courant dans Unity, il suffit d'associer le GameObject à un GameObject vide et d'appliquer une rotation d'Euler de 180 degrés au GameObject vide. Cela suppose également que la rotation de Threejs Euler est l'ordre XYZ par défaut.

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

Problème 1:

Accordé Je ne minored en mathématiques, mais je crois que vous devriez simplement pouvoir faire une correspondance droite comme suit pour les points:

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

Et cela devrait fonctionner dans les deux sens. Autant que je me souvienne une fois que vous avez converti entre les coordonnées, le calcul devrait être le même, assurez-vous de travailler tous dans un système ou l'autre pour vous faciliter la vie. Vous pouvez ensuite exporter les résultats au besoin.

+0

Cela ne fonctionnera pas car nous parlons de rotations dans ces deux systèmes. Si nous parlions de différences de position, cela pourrait fonctionner mais cela ne fonctionnerait pas pour les rotations d'angle euler. – Matt

+0

Avez-vous regardé dans les matrices de rotation alors? Je crois que cela pourrait être un bon moyen de résoudre les deux conflits, car ils peuvent être utilisés pour résumer l'ordre des rotations. Alors vous devriez juste être laissé avec de simples conversions de coordonnées. – CShannon

+0

J'ai étudié des matrices de rotation. J'ai pu obtenir les angles d'Euler de Threejs dans une matrice de rotation en utilisant ce wiki: http://en.wikipedia.org/wiki/Euler_angles À ce stade, j'ai essayé de convertir la matrice d'une droite vers la gauche système de coordonnées à l'aide de: http://stackoverflow.com/questions/1263072/changing-a-matrix-from-right-handed-to-lefthandle-coordinate-system À ce stade, j'ai tenté d'extraire le rotation comme un quaternion de la matrice. L'une des deux dernières étapes n'a cependant pas fonctionné car les rotations ne s'alignent pas. Vérifiez ma modification si vous le pouvez – Matt