I'm having trouble figuring out the proper conversions from Euler angles to Quaternions. The Eulers come from BVH files, which use a right-handed coordinate system (Y is up, Z is forward) and can have any rotation order specified. The Quaternions are in Unity, which is left-handed (Y is up, Z is back).
I'm composing the Quaternions from three AngleAxis
rotations, but messing up the order somewhere. So far I can't find understandable and generalized information for doing these types of conversions.
public enum AxisOrder
{
XYZ, XZY, YXZ, YZX, ZXY, ZYX, None
}
public Quaternion EulerToQuat(Vector3 eulerAngles, AxisOrder rotationOrder)
{
// I've tried various combinations of axis angles here, but would
// like to understand what's wrong rather than brute-force
// every combination
var xRot = Quaternion.AngleAxis(eulerAngles.x, Vector3.left);
var yRot = Quaternion.AngleAxis(eulerAngles.y, Vector3.down);
var zRot = Quaternion.AngleAxis(eulerAngles.z, Vector3.back);
switch (rotationOrder)
{
case AxisOrder.XYZ: return (xRot * yRot) * zRot;
case AxisOrder.XZY: return (xRot * zRot) * yRot;
case AxisOrder.YXZ: return (yRot * xRot) * zRot;
case AxisOrder.YZX: return (yRot * zRot) * xRot;
case AxisOrder.ZXY: return (zRot * xRot) * yRot;
case AxisOrder.ZYX: return (zRot * yRot) * xRot;
}
return Quaternion.identity;
}
...and converting translation data like so (I believe this is working):
public static Vector3 BvhToUnityTranslation(float xPos, float yPos, float zPos)
{
return new Vector3(xPos, yPos, -zPos);
}
If anyone can help me better understand how to conceptualize coordinate system conversions, and where I'm going wrong, I'd greatly appreciate it.