1

I am trying to figure out how to convert Collada (from Assimp) Quaternions for animation rotation, back into Euler rotations for FBX. I am sure it is a simple algorithm, I just can't find the right one...all the ones I try are wrong, that are usually called ToEulerXYZ. Perhaps it's because these rotations are X, then Y, then Z, instead of simultaneous? Someone in the know can probably help easily.

Here are my test samples - I input euler angles, and then export collada and get the equivalent quaternion. I'd like to do the opposite (and from quaternion, get euler). Note, that I am aware won't always get same value, but just need values that yield same rotation.

Sample values: 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

If this helps, Assimp is generating the quaternion this way (under Assimp license):

                    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);
Mary Ellen Bench
  • 589
  • 1
  • 8
  • 28

2 Answers2

1

According to the docs the default FBX Euler rotation order is indeed XYZ. The FBX SDK's Quat class has a method to convert a quat to euler in that way: DecomposeSphericalXYZ in http://docs.autodesk.com/FBX/2014/ENU/FBX-SDK-Documentation/index.html?url=files/GUID-3E0DCCD0-5F9A-44D0-8D5E-423237D49DB6.htm,topicNumber=d30e9965

So given that your ToEulerXYZ is correct it should work. Make sure you're not mixing degrees and radians..

antont
  • 2,676
  • 1
  • 19
  • 21
  • In our project we use an open source mathgeo lib that has it like this: `float3x3 float3x3::FromEulerXYZ(float x, float y, float z)` https://github.com/juj/MathGeoLib/blob/master/src/Math/float3x3.cpp#L180 . Is called for Quats from https://github.com/juj/MathGeoLib/blob/master/src/Math/Quat.cpp#L611 . Is a bit hard to track there due to the whole op being split to many parts / using smaller building blocks. – antont May 11 '14 at 01:07
  • This worked for 45,0,45, but it doesn't work for 30,45,60. That's quaternion 0.022260016,0.43967974,0.36042345,0.82236314 and I get 3,51,44 (which is not equal in modeller). – Mary Ellen Bench May 11 '14 at 01:08
  • I have tried MathGeoLib, and it gets {x=-24.597227 y=47.663212 z=58.334499} for quaternion using ToEulerXYZ from 30,45,60, so something seems very wrong with that one too. – Mary Ellen Bench May 11 '14 at 01:10
  • Another lib we use is three.js where Euler has setFromQuaternion at http://github.com/mrdoob/three.js/blob/master/src/math/Euler.js#L227 – antont May 11 '14 at 01:13
  • I think you have radians in your sample whereas MathGeoLib gives degrees. It still does not match though: math.degrees(0.43967974) => 25.191793439409363 – antont May 11 '14 at 01:16
  • I get the same value in that second link you showed (mrdoob), {x=-24.597229 y=47.663212 z=58.334499 ...}, so I suspect this is not equivalent to whatever FBX uses? For quaternion 0.022260016,0.43967974,0.36042345,0.82236314, which should be 30,45,60 angles from FBX. – Mary Ellen Bench May 11 '14 at 01:19
  • Besides degrees vs. radians only difference I can imagine anymore is coordsys handedness - FBX is right handed according to http://stackoverflow.com/questions/14484887/loading-fbx-model-into-directx-application – antont May 11 '14 at 01:27
1

Figured it out, and appreciate your help antont. It was a nuance of Assimp. Apparently it for some odd reason (bug?) reads rotations in backwards, and so you have to do ToEulerZYX, but then reverse use of xyz to zyx.

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

                    keyValue.z = RadToDeg(keyValueOrig.x);
                    keyValue.y = RadToDeg(keyValueOrig.y);
                    keyValue.x = RadToDeg(keyValueOrig.z);
Mary Ellen Bench
  • 589
  • 1
  • 8
  • 28
  • Great you figured out a way - I still wonder whether that has to do with handedness or what, would be nice to know for the record. – antont May 11 '14 at 17:34