Euler Rotations and Matrix Questions


I would love to clarify some things in Unreal. I am no expert on rotation matrices but I foresee the cacophony of quaternion mentions, I know they are better/easier for representing rotations. Those things aside, I want to understand what is going on here.

I was looking at the code in FRotationTranslationMatrix::FRotationTranslationMatrix and can’t identify which order of rotational operations this matrix is supposed to represent"
const float SR = FMath::Sin(Rot.Roll * PI / 180.f);
const float SP = FMath::Sin(Rot.Pitch * PI / 180.f);
const float SY = FMath::Sin(Rot.Yaw * PI / 180.f);
const float CR = FMath::Cos(Rot.Roll * PI / 180.f);
const float CP = FMath::Cos(Rot.Pitch * PI / 180.f);
const float CY = FMath::Cos(Rot.Yaw * PI / 180.f);

M[0][0]	= CP * CY;
M[0][1]	= CP * SY;
M[0][2]	= SP;

M[1][0]	= SR * SP * CY - CR * SY;
M[1][1]	= SR * SP * SY + CR * CY;
M[1][2]	= - SR * CP;

M[2][0]	= -( CR * SP * CY + SR * SY );
M[2][1]	= CY * SR - CR * SP * SY;
M[2][2]	= CR * CP;


I removed the translation and am just focusing on the rotational 3x3 portion of the matrix. The pattern of signs doesn’t match any of the typical ones I’ve seen. I’d like to know the order of operations here (pitch then roll then yaw? or something else). I’d also like to make sure I understand what those mean in Unreal space:

Yaw is rotation about Z-Axis (Up)?
Pitch is rotation about Y-Axis (Right)?
Roll is rotation about X-Axis (Forward)?

Left-handed coordinate system?

Thanks in advance!
PS: I hope there is no issue posting code, I figured this was generic enough and anyone who’s done graphic programming has seen at least one form of this.

Yes, that’s correct!

Regarding the rotation matrix creation. There seems to be an inconsistency in how Unreal creates it and standard convention. I’m assuming it was intentional, but it doesn’t make sense to me…

In order to generate the rotation matrix the code above shows, the basic rotations used are:


Multiplied out and illustrating above code result (although transposed?)

Which do not match the standard:


Notice the sign of sines change for the rotation about Z. The usual pattern of signs for sine is upper-right/lower-left/upper-right or the transpose of that, however the code seems to use upper-right/lower-left/lower-left. After playing around in the editor I noticed that although the typical rotation direction (positive angle yields clockwise rotation about the axis when looking along the axis from the origin) apply for Pitch and Roll, it does not apply to the Z/Yaw rotations. I can’t imagine this is a bug, but I am curious why it was done this way. I doesn’t seem logical, why not keep it consistent and make all rotations clockwise along their axis? I am guessing that is the reason for the sign swap for the Z rotation sines and why I didn’t recognize the original code, but I am not 100% sure.

So to add to the previous understanding:

Yaw is rotation about Z-Axis (Up), positive rotation goes counterclockwise when looking along positive Z axis from origin?
Pitch is rotation about Y-Axis (Right), positive rotation goes clockwise when looking along positive Y axis from origin?
Roll is rotation about X-Axis (Forward), positive rotation goes clockwise when looking along positive X axis from origin?

Let me know if I have made some foolish mistake, just trying to make sense of things.