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