I've been using Euler rotations for my animation for each joint an I am trying to understand how you would move away from Euler to Quaternions instead for animation since Euler can have issues.
Currently I am taking the rotations specified in degrees per angle for the joint and just multiplying the appropriate matrices from right to left to get the per frame per joint rotation for the animation.
Mat4 rotationMatrix = Mat4::RotateX(jointRot.x) * Mat4::RotateY(jointRot.y) * Mat4::RotateZ(jointRot.z);
To do the same rotation using Quaternions it would be the following?
This is what I am currently doing and my animation breaks, rotations seem incorrect
Quaternion RotX = Quaternion(jointRot.x, vec3(1.0f, 0.0f, 0.0f).unit());
Mat4 MatX = RotX.ToRotationMatrix();
Quaternion RotY = Quaternion(jointRot.y, vec3(0.0f, 1.0f, 0.0f));
Mat4 MatY = RotY.ToRotationMatrix();
Quaternion RotZ = Quaternion(jointRot.z, vec3(0.0f, 0.0f, 1.0f));
Mat4 MatZ = RotZ.ToRotationMatrix();
Mat4 rotationMatrix = MatX * MatY * MatZ;
// Quaternion
Quaternion::Quaternion(float angle, const vec3& v)
{
float angleRadians = angle * M_PI / 180;
float rotAngle = angleRadians / 2;
float cosAngle = std::cos(rotAngle);
float sinAngle = std::sin(rotAngle);
w = cosAngle;
x = v.x * sinAngle;
y = v.y * sinAngle;
z = v.z * sinAngle;
}
// To matrix function:
Mat4 Quaternion::ToRotationMatrix()
{
float x2 = x * x;
float y2 = y * y;
float z2 = z * z;
float xy = x * y;
float xz = x * z;
float yz = y * z;
float wx = w * x;
float wy = w * y;
float wz = w * z;
Mat4 ret;
ret.m[0][0] = 1.0f - 2.0f * (y2 + z2);
ret.m[1][0] = 2.0f * (xy - wz);
ret.m[2][0] = 2.0f * (xz + wy);
ret.m[3][0] = 0.0f;
ret.m[0][1] = 2.0f * (xy + wz);
ret.m[1][1] = 1.0f - 2.0f * (x2 + z2);
ret.m[2][1] = 2.0f * (yz + wx);
ret.m[3][1] = 0.0f;
ret.m[0][2] = 2.0f * (xz + wy);
ret.m[1][2] = 2.0f * (yz - wx);
ret.m[2][2] = 1.0f - 2.0f * (x2 + y2);
ret.m[3][2] = 0.0f;
ret.m[0][3] = 0.0f;
ret.m[1][3] = 0.0f;
ret.m[2][3] = 0.0f;
ret.m[3][3] = 1.0f;
return ret;
}