I have an orientation expressed with a quaternion and an angular velocity expressed as either a quaternion or a number (radians per second around the original orientation).
For update of orientation , you require to multiply current orientation by delta rotation. This is comparable expensive operation with axis angle conversion.
Common way to represent angular velocity is "exponential map", the 3d vector parallel with rotation axis and magnitude of rotation velocity (radians per second). The conversion to delta rotation quaternion looks like
Quaternion deltaRotation(const Vector3& em, double deltaTime)
{
Vector3 ha = em * deltaTime * 0.5; // vector of half angle
double l = ha.norm(); // magnitude
if (l > 0) {
ha *= sin(l) / l;
return Quaternion(cos(l), ha.x(), ha.y(), ha.z());
} else {
return Quaternion(1.0, ha.x(), ha.y(), ha.z());
}
}
If your deltaTime is small and rotation speed is small, you can use approximation by 1st Taylor series multiplier. But you should normalize result quaternion to avoid numerical instability more often.
Quaternion deltaRotationAppx1(const Vector3& em, double deltaTime)
{
Vector3 ha = em * deltaTime * 0.5; // vector of half angle
return Quaternion(1.0, ha.x(), ha.y(), ha.z());
}