Can someone explain what FRotationMatrix is?

Hi, I’m basically trying to understand the default third person movement in C++. This is part the Function that moves forward/backwards:


const FRotator Rotation = Controller->GetControlRotation(); 
const FRotator YawRotation(0, Rotation.Yaw, 0); 

I guess I understand this first part. It creates a rotator, gets the rotation, but we only “take” the Yaw, this way, we know which way is “forward”.


//get forward vector
const FVector fwd = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X);
AddMovementInput(fwd, amount);

Now here’s what I don’t understand, how does it get the FVector from a FRotator. What does exactly this do:


 FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X);

Thanks for your help and sorry if the question is very stupid, I’m new to this :smiley:

Hello,

I think your question is wrong. I will give an explanation, hopefully you can ask the right question.

Rotation matrix is for rotation, not “translation”.

If you have a 3D object in 3D world, you can move long each of x, y, and z axis. This is “translation” motion. You can move from any point (x1, y1, z1) to another (x2, y2, z2).

Now, for the same 3D object, you can rotate an object around each of x, y, and z axis. Go toimages.google.com and search for “pitch roll yaw” for good explanation.
Rotating around x is called Roll (Think of how an airplane Goes from this – to this / when it wants to turn)
Rotating around the y axis is called Pitch. (Imagine an airplane wants to dive down. It points downward)
Rotating around z axis is called Yaw (like you rotate a screw driver for example).

Now, imagine you have an airplane toy, and you are in a room with a TV. You hold the airplane in the air. How do you tell another person how this airplane is “oriented”, or where it is pointing to, if the room has nothing but a TV?

You do something like this:

  • Point the airplane towards the TV with wings parallel to the floor (Decide a frame of reference)
  • Take call this position of the airplane: INITIAL POSITION
  • Rotate the airplane from its INITIAL POSITION around its body or its x-axis. (This is Pitch). Memorize this position. Call it APRoll for (AirPlaneRoll) for example.
  • Rotate the airplane from its INITIAL POSITION to the right of TV by 45 degrees, around the Z axis (This is Yaw). Memorize this position. Call it APYaw.
  • Rotate the airplane from its INITIAL POSITION up from the floor by 30 degrees, around the Y axis. (This is Pitch). Memorize this position. Call it APPitch

Now, to tell another person the orientation, you can send them the numbers (APRoll, APYaw, APPitch). This is possible because we defined a “Reference Frame” and “Rotation Operation” which rotates an object from its initial position.

So far so good. Now assume you have a picture somewhere on the wall. You make the airplane point towards that picture. Previously, we described the rotation along X, Y, and Z which everybody agrees to.
You want to describe a rotation with respect to the vector pointing from the airplane to the picture. Call this line AirplanePicture vector.

You can do that, and everybody will understand what you mean, as long as you can describe AirplanePicture line in terms of X,Y, Z. For example, the AirplanePicture = (2, 3, 4).

If you do that and tell me your rotation, I’ll point my airplane to that direction as initial condition, instead of pointing it to the TV, and then I apply rotation.

There is still 1 problem.
When you say (2, 3, 4), what does 2 mean? 2 cm? 2 m? Maybe you counted how many tiles? Maybe we shouldn’t care!
So, you can define a unit vector (vector of length 1, where 1 is the length of whichever unit you choose). Then you can tell me that vector. Now I have a bigger or smaller room, I won’t be affected because the vector is “normalized”, of length 1.

So, this code below gets the rotation of Controller around Z axis.



const FRotator Rotation = Controller->GetControlRotation(); 
const FRotator YawRotation(0, Rotation.Yaw, 0)

Now this code below


//get forward vector
const FVector fwd = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X);
AddMovementInput(fwd, amount);

It seems to me that based on your rotation with respect to z axis, you are adjusting the speed of your movement. Remember, code is logic, not physics. I’ll try to explain better.

  • This code gets the rotation, Yaw (around Z axis, or around the Character Body, basically if you are standingf acing the TV, and you rotate left or right of the TV).
  • Then it “GetsUnitAxis(EAxis::X)”. Remember how discussion about how airplane looks at the picture? This is a bit similar. You are saying something like: "I am looking to the left. Take the unit vector of where I am pointing at. How much of that is in the X-direction? (Dot Product). Apply that to my speed.
  • Then, if you rotate 90 degrees, you should not be able to move at all, because you are pointing perpendicular to the X direction.

So, this code ties the forward movement speed of the character to its orientation.

I hope this helps.

21 Likes

Take the red pill :wink:

2 Likes

I know it is a very late reply, but I think I kind of get what the OP is asking. If you come from mathematical background just like me, the interface of FRotationMatrix feels rather off. I meant, it is basically a transformation matrix, what does GetUnitAxis has to do with it? Because transformation matrix, in its plain form, has nothing to do with axis! What I am expecting is to multiply this Matrix with a point or another vector, but what I get is this weird GetUnitAxis function call!

After diving in into the engine code, I think I finally get it.
The FRotationMatrix consist of three component, the yaw transformation matrix (yMat), the pitch transformation matrix (pMat), and of course roll transformation matrix (rMat).

It then calculates the combined transformation matrix.
CombinedMat = yMatpMatrMat (basically it does the transformations in order)

Now consider that X axis is represented by a unit length vector (1.0, 0, 0), what GetUnitAxis(EAxis::X) do is basically applying the rotation transformation into that unit length Vector pointing to the X axis, which produces where the vector pointing to after it gets rotated (which is why you get FVector).

And that’s about it.

4 Likes

Great Explanation!

I think in the last part, “GetsUnitAxis(EAxis::X)”, it doesnt really get the X component of the direction we are pointing at, instead it takes the unit vector along X and applies the yaw rotation to that unit vector and returns an FVector.

I guess they destruct RotationMatrix components to handle each component by different input (as u suggested). As I understand, GetUnitAxis() returns normalized vector (Length=1) from the RotationMatrix. So, I think, the anonymous_user_be4a1715’s breakdown is correct.
(Sorry for the late comment - I’m trying to figure that math, after having lost most of my math-skills… it’s hard :slight_smile:, but your comment was helpful, tnx )