How to get the Quaternion Rotation from a Matrix4x4

Hello, I’m trying to create animations during run time. It’s going pretty good so far, I just have a few issues with retrieving a quaternion rotation from a matrix4x4. I was able to get the position and scale perfectly by using:

`
private Vector3 GetPosition(Matrix4x4 matrix)
{
    return matrix.GetColumn(3);
}
private Vector3 GetScale(Matrix4x4 matrix)
{
    return new Vector3(matrix.GetColumn(0).magnitude, matrix.GetColumn(1).magnitude, matrix.GetColumn(2).magnitude);
}
`

However, trying to figure out a feasible get rotation function that is exactly the same as unity engines importer for matrices, is another story. I have tried the following, which seem to partially work, but cause a little bit of jitter between key frames:

`
Both of these work to some extent, but do not produce the same results as unitys importer.  
  

private Quaternion GetRotation(Matrix4x4 matrix)
{
    return Quaternion.LookRotation(matrix.GetColumn(2), matrix.GetColumn(1));
}

and

public static Quaternion QuaternionFromMatrix(Matrix4x4 m)
{

    Quaternion q = new Quaternion();
    float absQ2 = Mathf.Pow(determinant(m), (1 / 3));
    q.w = Mathf.Sqrt(Mathf.Max(0, absQ2 + m[0, 0] + m[1, 1] + m[2, 2])) / 2;
    q.x = Mathf.Sqrt(Mathf.Max(0, 1 + m[0, 0] - m[1, 1] - m[2, 2])) / 2;
    q.y = Mathf.Sqrt(Mathf.Max(0, 1 - m[0, 0] + m[1, 1] - m[2, 2])) / 2;
    q.z = Mathf.Sqrt(Mathf.Max(0, 1 - m[0, 0] - m[1, 1] + m[2, 2])) / 2;
    q.x *= Mathf.Sign(q.x * (m[2, 1] - m[1, 2]));
    q.y *= Mathf.Sign(q.y * (m[0, 2] - m[2, 0]));
    q.z *= Mathf.Sign(q.z * (m[1, 0] - m[0, 1]));

    return q;
}

public static float determinant(Matrix4x4 m)
{
    float tmp;
    tmp =
    m.m03 * m.m12 * m.m21 * m.m30 - m.m02 * m.m13 * m.m21 * m.m30 - m.m03 * m.m11 * m.m22 * m.m30 + m.m01 * m.m13 * m.m22 * m.m30 +
    m.m02 * m.m11 * m.m23 * m.m30 - m.m01 * m.m12 * m.m23 * m.m30 - m.m03 * m.m12 * m.m20 * m.m31 + m.m02 * m.m13 * m.m20 * m.m31 +
    m.m03 * m.m10 * m.m22 * m.m31 - m.m00 * m.m13 * m.m22 * m.m31 - m.m02 * m.m10 * m.m23 * m.m31 + m.m00 * m.m12 * m.m23 * m.m31 +
    m.m03 * m.m11 * m.m20 * m.m32 - m.m01 * m.m13 * m.m20 * m.m32 - m.m03 * m.m10 * m.m21 * m.m32 + m.m00 * m.m13 * m.m21 * m.m32 +
    m.m01 * m.m10 * m.m23 * m.m32 - m.m00 * m.m11 * m.m23 * m.m32 - m.m02 * m.m11 * m.m20 * m.m33 + m.m01 * m.m12 * m.m20 * m.m33 +
    m.m02 * m.m10 * m.m21 * m.m33 - m.m00 * m.m12 * m.m21 * m.m33 - m.m01 * m.m10 * m.m22 * m.m33 + m.m00 * m.m11 * m.m22 * m.m33;
    return tmp;
}

`

To sum it up, I just need to figure out what unity does to get a quaternion rotation from a matrix4x4 on import of keyframes from fbx files.

Thanks so much,

~Matthew.

You can get the quaternion rotation from 4x4 rotation matrix using this formula

QuaternionW= √(1 + M00 + M11 + M22) /2

QuaternionX = (M21 - M12)/(QuaternionW * 4)

QuaternionY = (M02 - M20)/(QuaternionW * 4)

QuaternionZ = (M10 - M01)/(QuaternionW * 4)

for more refer here

http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/

It turns out that you have to use EnsureQuaternionContinuity() on the animation clips after creating them in memory, which will then perfectly convert all rotations to how unity does on import of fbx/dae/etc animation files.

Thanks!