For simplification, I

*only*need to worry about the local Euler rotations of the object—the scale, pivots, pre-rotate, post-rotate, etc., are all “identity” and do not contribute to the result for my test work.

That means I only have to take an X-rotation matrix, Y-rotation matrix, and Z-rotation matrix and combine them in that order (because I am using row-major matrices whereas they are using column-major matrices).

When I actually construct these 3 matrices and combine them in that order, it works fine. Code for the way I construct them (only upper 3×3 shown):

MatrixRotationX( _tType _tAngle ) { LSREAL fS; LSREAL fC; CMathLib::SinCos( static_cast<LSREAL>(_tAngle), fS, fC ); _11 = 1.0; _12 = 0.0; _13 = 0.0; _21 = 0.0; _22 = fC; _23 = fS; _31 = 0.0; _32 = -fS; _33 = fC; }

MatrixRotationY( _tType _tAngle ) { LSREAL fS; LSREAL fC; CMathLib::SinCos( static_cast<LSREAL>(_tAngle), fS, fC ); _11 = fC; _12 = 0.0; _13 = -fS; _21 = 0.0; _22 = 1.0; _23 = 0.0; _31 = fS; _32 = 0.0; _33 = fC; }

MatrixRotationZ( _tType _tAngle ) { LSREAL fS; LSREAL fC; CMathLib::SinCos( static_cast<LSREAL>(_tAngle), fS, fC ); _11 = fC; _12 = fS; _13 = 0.0; _21 = -fS; _22 = fC; _23 = 0.0; _31 = 0.0; _32 = 0.0; _33 = 1.0; }According to this, this is a left-handed system that has been transposed for my row-major matrices (theirs are column-major). My assignments are grouped by rows, and my row [_11, _12, _13] matches their first column except that the sign of the sine’s are reversed, making it left-handed (I guess?).

In any case, if I use these to manually combine the XYZ Euler rotations from the FBX data the result is correct.

But I don’t want to construct 3 matrices and multiply them together when I know there is a way to get the result directly.

So I checked here to get some direct conversions.

My code for their Tait-Bryan XYZ set follows (exactly the same but transposed into row-major):

MatrixRotationXYZ( _tType _tX, _tType _tY, _tType _tZ ) { LSREAL fS1, fC1; CMathLib::SinCos( static_cast<LSREAL>(_tX), fS1, fC1 ); LSREAL fS2, fC2; CMathLib::SinCos( static_cast<LSREAL>(_tY), fS2, fC2 ); LSREAL fS3, fC3; CMathLib::SinCos( static_cast<LSREAL>(_tZ), fS3, fC3 ); _11 = fC2 * fC3; _12 = fC1 * fS3 + fC3 * fS1 * fS2; _13 = fS1 * fS3 - fC1 * fC3 * fS2; _21 = -fC2 * fS3; _22 = fC1 * fC3 - fS1 * fS2 * fS3; _23 = fC3 * fS1 + fC1 * fS2 * fS3; _31 = fS2; _32 = -fC2 * fS1; _33 = fC1 * fC2; }Obviously, this is not going to work, as it is right-handed and transposing is not enough.

How do I make this left-handed? I need at least this one, but best would be a table of all combinations (YZX, XZY, ZYX, etc., as on Wikipedia).

Thank you,

L. Spiro