2014-05-10 3 views
1

J'essaye de comprendre comment convertir les quaternions de Collada (de Assimp) pour la rotation d'animation, de nouveau dans les rotations d'Euler pour FBX. Je suis sûr que c'est un algorithme simple, je ne peux pas trouver le bon ... tous ceux que j'essaie sont faux, qui sont habituellement appelés ToEulerXYZ. Peut-être parce que ces rotations sont X, puis Y, puis Z, au lieu de simultanées? Quelqu'un dans le savoir peut probablement aider facilement.Convertir le quaternion en Euler

Voici mes échantillons d'essai - J'introduis les angles d'euler, puis j'exporte la collada et obtiens le quaternion équivalent. Je voudrais faire le contraire (et de quaternion, euler euler). Notez, que je suis conscient n'aura pas toujours la même valeur, mais juste besoin de valeurs qui donnent la même rotation.

valeurs de l'échantillon: Euler X, Y, Z quaternion X, Y, Z, W

0,0,0-> 0,0,0,1

0.000000,0.000000, 45.000000-> 0,0,0.38268346,0.92387956

45,0,45-> 0,35355338, 0,14644660, 0.35355338,0.85355341

45,45,0 0,35355338, 0.35355338, -0.14644660,0.85355341

45,45,45-> 0.19134171,0.46193978,0.19134171,0.84462321

30,45,60-> 0.022260016,0.43967974,0.36042345,0.82236314

Si cette aide, Assimp génère quaternion cette façon (sous licence Assimp):

    angle = 60 * float(AI_MATH_PI)/180.0f; 
        axis = aiVector3D(0.0f, 0.0f, 1.0f); 
        aiMatrix4x4::Rotation(angle, axis, rot); 
        res *= rot; 

        angle = 45 * float(AI_MATH_PI)/180.0f; 
        axis = aiVector3D(0.0f, 1.0f, 0.0f); 
        aiMatrix4x4::Rotation(angle, axis, rot); 
        res *= rot; 

        angle = 30 * float(AI_MATH_PI)/180.0f; 
        axis = aiVector3D(1.0f, 0.0f, 0.0f); 
        aiMatrix4x4::Rotation(angle, axis, rot); 
        res *= rot; 



        aiVector3D scale; 
        aiQuaternion rotation; 
        aiVector3D translation; 
        res.Decompose(scale, rotation, translation); 

Répondre

1

Vous l'avez compris et appréciez votre aide. C'était une nuance d'Assimp. Apparemment, pour une raison étrange (bug?) Lit les rotations à l'envers, et donc vous devez faire ToEulerZYX, mais ensuite inverser l'utilisation de xyz en zyx.

    float3 keyValueOrig = quat.ToEulerZYX(); 
        float3 keyValue; 

        keyValue.z = RadToDeg(keyValueOrig.x); 
        keyValue.y = RadToDeg(keyValueOrig.y); 
        keyValue.x = RadToDeg(keyValueOrig.z); 
+0

Vous avez compris un moyen - je me demande toujours si cela a à voir avec la légèreté ou quoi, serait bon de savoir pour le compte rendu. – antont

1

Selon les documents par défaut ordre de rotation FBX Euler est en effet XYZ. La classe Quat du FBX SDK a une méthode pour convertir un quat en euler de cette façon: DecomposeSphericalXYZ en http://docs.autodesk.com/FBX/2014/ENU/FBX-SDK-Documentation/index.html?url=files/GUID-3E0DCCD0-5F9A-44D0-8D5E-423237D49DB6.htm,topicNumber=d30e9965

Donc, étant donné que votre ToEulerXYZ est correct, cela devrait fonctionner. Assurez-vous de ne pas mélanger les degrés et les radians.

+0

Dans notre projet, nous utilisons une lib mathgeo open source qui a comme ceci: 'float3x3 float3x3 :: FromEulerXYZ (x float, float y, z float)' https://github.com/juj/MathGeoLib /blob/master/src/Math/float3x3.cpp#L180. Est appelé pour Quats à partir de https://github.com/juj/MathGeoLib/blob/master/src/Math/Quat.cpp#L611. C'est un peu difficile à suivre car l'opération est divisée en plusieurs parties/en utilisant des blocs de construction plus petits. – antont

+0

Cela a fonctionné pour 45,0,45, mais cela ne fonctionne pas pour 30,45,60. C'est quaternion 0.022260016,0.43967974,0.36042345,0.82236314 et je reçois 3,51,44 (ce qui n'est pas égal dans le modélisateur). –

+0

J'ai essayé MathGeoLib, et il obtient {x = -24.597227 y = 47.663212 z = 58.334499} pour quaternion en utilisant ToEulerXYZ de 30,45,60, donc quelque chose semble très mauvais avec celui-là aussi. –