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);
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);