Phone: 905 409-1589
RSS LinkedIn Twitter Twitter

Transformations in 3D Space, the myths and facts:

I decided to write this help file to try and clear up the myths and facts about how transformations and particularly rotations work in 3D space. I remember drilling a programmer at Discreet about the way that rotations worked and how there must be an easy solution to the problem. After spending about an hour on the phone with him and a few Asprin I soon realized I had allot to learn about how transforms work in 3D, if you are reading this, you might too. Think of this doc as Transforms for Dummies, as I will not go into great mathematical mumbo jumbo to explain it but instead try to lay it out for the typical artist that is trying to understand it.

You should be very careful the way that you view the values of an object as some methods like the transform type in can be misleading. This is because you can change the context in which you view the transform but only one way is actually recorded. The track view/ Dope sheet/ Curve Editor is the only one that you can be sure of because this is what is being calculated by the program.


Lets start with scale because it is the only one that works the way that we would first assume. Scale is calculated in what is known as local space of an object. This means that if you scale an object along any one of the three axis with the object in any orientation in 3D space only that one axis will get a value change in the function curves. This makes it very easy to understand if you are animating the scale of an object even if it is in a hierarchy with other objects that are animated. Of course scaling objects in a hierarchy have another set of problems and we will try to get back to that later as it relies on having more knowledge of how transforms work in general.


The position of objects are the next easiest to understand once you get past the fact that they are not calculated in local space of an object like the scale is. To help illustrate how this works we will work with a couple of objects. First create a box and place it at [100,0,0] in the view port. Open the Dope Sheet Editor and take a look at the values that are recorded for the position. You should see that X is at 100, Y is at 0 and Z is at 0.

The objects position is being calculated as an offset from the center of world space. This makes perfect sense so far. Next create a sphere and align it to the position of the box, pivot to pivot, so that they are both at [100,0,0]. Using the link tool, link the box to the sphere so that the sphere is the parent object of the box. Now select the box and view the values of the position in the Dope Sheet again. Notice that the position value has changed to [0,0,0].

At first this appears to be wrong, however the position of objects are not calculated as an offset from the center of world space but as an offset from the center of their parent object. When we first created the box it had no parent object so the world is used as the parent. Once the box is linked to the sphere the sphere becomes parent and the position of the box is recalculated to [0,0,0]. We can use the term, parent space here to describe how the position of the box is calculated. What can get confusing is if you open the Transform Type-In dialog and view the value of the position. The dialog gives you the value in world coordinates, or in world space. This is misleading because it is not the value that is recorded during animation.

To further test this select the sphere and use the Transform Type-In to rotate it 45 degrees on the world Z axis. Change the Reference Coordinate System to local and move the box along any one of it's local axes. Notice that only the value for that axis will change in the Dope Sheet.

Because the boxes rotation is aligned to the sphere moving the box in local will give the results that you would expect. What you should really be doing is moving the box in Parent space. To test this rotate the box -45 in the Z axis, change the Reference Coordinate System to parent and move the box along any one of the axis. Only the value for that axis will change in the Dope Sheet.


Here is where is starts to get a bit more complicated. Let me dispel a myth first, there is no such thing as a local rotation in any piece of 3D software. 3DS Max 4 added a rotation controller called Local Euler XYZ, this was really a bit deceiving as all it really did was reverse the order of the calculation of the axes and there was nothing local about it. Rotations are calculated the same way that positions are, as an offset from the parent object. This can make it difficult to visualize in numbers and function curves. Lets get into how rotations are calculated using the default Euler XYZ controller to start with.

Euler XYZ controllers:
The Euler controller is the most common method for working with rotations. I will write Euler values in this format, [x,y,z]. Animators like Euler rotations because they display functions curves that represent the three axes of rotation and allows for easy editing of them. The problem is that they don't always represent what we want to see. The default Euler controller works by adding up X then Y then Z to calculate the final rotation (x + y + z = rotation). Once again this is based on the parent objects orientation. To help illustrate it create a Box in the top view port and align it's position to [0,0,0] world space using the Transform Type-In dialog. Change the Reference Coordinate System to parent, this will be the same as world since we don't have a parent object. Open the Dope Sheet editor and watch the values of the rotations as we change them. First rotate the box in the X axis 45 degrees, the Dope Sheet will read [45,0,0]. Rotate the box 45 degrees in the Y axis and the Dope Sheet will read [45,45,0]. Finally rotate the Z axis 45 degrees so that we have [45,45,45]. So far every thing looks very simple, we have rotations being calculated in parent space and the numbers are what we would expect. Here is where it gets tricky and a little hard to understand when you are animating. Lets go back and rotate the X axis another 45 degrees, you might think that we would end up with [90,45,45] but we don't, the final value looks something like [75.3,8.4,59.6]. Because the axis order is XYZ any time the X or Y axis are changed the others have to recalculate to solve the final rotation. If you rotate the Z axis you see that only the Z value changes, this is because it is the last in the order and it doesn't affect the value of the others. The best way to see what is actually happening is to set the Reference Coordinate System to Gimbal and then do these steps. Start the boxes orientation at [0,0,0] and rotate in Y, 90° and notice how the X axis aligns to the Z axis. If you wanted to rotate the Box 90° in the X axis using the Gimbal mode it is the same as rotating the z axis.

This is why animated rotations will often not in-between between keys the way that you might like. If you were animating in any of the other coordinate spaces you would be able to rotate the object around the X axis without rotating the z axis. The problem is that any other coordinate space is just for visual purposes so the gimbal rotation has to try and find a solution that will give you the result that you want. To test this lets animate the box. Reset the rotation of the box to [0,0,0]. Set the Reference Coordinate System to world. Turn on Auto Key and move the time slider to frame 10. Rotation the box 90° in the Y axis. Move the time slider to frame 20 and animate the box 90° in the X axis. To make sure that the functions curves are not overshooting the animation on the box, select all the keys in the track bar then open the Mini Curve Editor and set the tangents to linear. Move the time slider between frame 0 and 20 now. Notice that the animation from frame 0 to 10 is what you would expect but from 10 to 20 the box doesn't rotate only around the X axis. To see why set the Reference Coordinate System to Gimbal and move the time slider between frames 0 and 20 again. To solve the rotation the Z axis had to rotate 90° and the X and Y axis had to rotate -90°. This is what is causing the unwanted rotation between frame 10 and 20. How do you change this behavior? You can't really you just need to know that it is there and learn to work around it. There are a few tricks that can make it more understandable while animating but I will cover those later.