zuka those are homogenous transformation matrices. They are a great way for calculating rotation, translation and even scaling and perspective. The great thing about them is, you can multiply them to apply multiple transformations at once. You cant do that with normal cartesian transformation matrices.
With those matrices I want to calculate where to draw the object so it is allways in front of the camera at a fixed position relative to the camera.
So I would like to take the origin of the global (world) co-ordinate system, translate it by a vector (distCamX, distCamY, distCamZ). Thats what the matrix T_d does when you map a point P with it. In the picture I accidently switched the names of T_c and T_d :p d for dist, c for camera...
T_d * P. If you try this, you will see that a point/vector P has one coordinate too little. You have to make it a "homogenous" coordinate first. You do that by adding a 1 as the 4. coordinate. (0,0,0) becomes (0,0,0,1). Now you can multiply the the matrix T_c and the point P.
When you do this with the point (0,0,0) resp (0,0,0,1) you get to the point (distCamX, distCamY, distCamZ, 1).
I hope they dont mind me hotlinking:
To get back the original cartesian coordinate/point you simply divide by the 4. coordinate wich is 1 in this case (it is most of the time).
So far this is like with cartesian transformations (even more work). But the homogenous transformations come handy when you want to do multiple transformations.
So after translating the origin (0,0,0) to (distCamX, distCamY, distCamZ) I want to rotate around the x and y axis of the camera. I can do this with homogenous rotation matrices.
This matrix rotates around the x axis by A degrees.
| 1 0 0 0 |
Rx(A) = | 0 cos A -sin A 0 |
| 0 sin A cos A 0 |
| 0 0 0 1 |
y axis:
| cos A 0 sin A 0 |
Ry(A) = | 0 1 0 0 |
| -sin A 0 cos A 0 |
| 0 0 0 1 |
z axis:
| cos A -sin A 0 0 |
Rz(A) = | sin A cos A 0 0 |
| 0 0 1 0 |
| 0 0 0 1 |
I only need x and y. Thats what R_x and R_y are for.
One can do those steps in one because the matrices can be multiplied.
So if you multiply the matrices T_d, R_x and R_y, take the resulting matrix and multiply a vector with it. The vector is translated and rotated around x and y axis at once.
Since I want all this to happen at the current camera positon I do another translation with T_c. So I get the resulting transformation matrix by doing:
T_c*T_d*R_x*R_y
Why T_c at first? Because the order matters. (Matrix multiplication is not commutative)
It makes a difference whether I multiply a transformation from the left or from the right side.
From left: the transformation is done relative to the world co-ordinate system (WcS) axes. Those are fix. They never move nore rotate.
From right: the transformation is done relative to the new (formerly rotatet or moved/translated object co-ordinate system (or camera co-ordinate sytem in my case (OCS/CCS))
I find it easy to start a transformation with the identity Matrix I. Which does nothing
| 1 0 0 0 |
I = | 0 1 0 0 |
| 0 0 1 0 |
| 0 0 0 1 |
Try to multiply a homogenous vector with it. Nothing happens.
Now multiply the first transformation matrix. Since nothing happened yet it doesnt matter whether you multiply it to the right or to the left. But I find it easier to multiply it to the left, because the WCS is the only co-ordinate system (CS) in the beginning (or at least the wCS and the OCS/CCS are the same).
So because I want to translate to (distCamX, distCamY, distCamZ) I multiply
| 1 0 0 distCamX |
T_d = | 0 1 0 distCamY |
| 0 0 1 distCamZ |
| 0 0 0 1 |
from the left: T_d * I
Now I want to rotate around the x axis of the camera (which is the object). So I multiply from the right.
T_d * I * R_x
Same for rotation around y. Now this time is the first time it would actually make a difference whether I multiplied from the left or right. Because after rotating with R_x around the x axis of the object you have to different CS. One for the world (WCS) and one for the object/camera (OCS/CCS). After rotating around the x axis, the two x axes still point in the same direction, but the y and z axis doesnt. So if I want to rotate around the y axis of the object/camera (which I do) I have to multiply from the right.
T_d * I * R_x * Ry
Last step is to bring everything to where the camera is with T_c
| 1 0 0 dbCameraPositionX() |
T_d = | 0 1 0 dbCameraPositionY() |
| 0 0 1 dbCameraPositionZ() |
| 0 0 0 1 |
Since the camera position is given in world co-ordinates I have to translate along the axes of the WCS. Hence I have to multiply from the left:
T_c * T_d * I * R_x * Ry
There are other orders of multiplication that should lead to the same result.
If I multiply (0,0,0,1) with the resulting matrix I _should_ get to a position that lies at (distCamX, distCamY, distCamZ) in front of the camera.
But since I dont you shouldnt take my word for it
And if anyone spots an error in this... that would be great!