In this tutorial, you have learned the following:

Coordinate systems (spaces) are defined by 3 basis axes and a position.

The transformation from one 3D space to another can be defined by a 4x4 matrix, which is constructed from the 3 basis axes and the position.

Model space is the coordinate system that a particular model occupies, relative to camera space. Other models can have model spaces that depend on the model space of other models.

Scale, translation, and rotation transformations have specific matrix forms.

Transformations can be composed via matrix multiplication. All transformations for a model can be folded into a single matrix, which a vertex shader can execute at a fixed rate. Therefore, complex transforms are no slower to execute (for the graphics chip) than simple ones.

The order that successive transforms are applied in matters. Matrix multiplication is not commutative, and neither is object transformation.

Successive transformations can be used to build hierarchies of objects, each dependent on the accumulated transformations of lower ones. This is done using a matrix stack.

Try doing these things with the given programs.

In the Translation tutorial, we had two objects that rotated around a specific point. This was achieved by computing the offset for the rotated position on the CPU, not through the use of a rotation transformation. Change this code to use rotation transformations instead. Make sure that the orientation of the objects do not change as they are being rotated around; this will require applying more than one rotation transformation.

Reverse the order of rotations on the wrist in the Hierarchy tutorial. Note how this affects the ability to adjust the wrist.

Reimplement the Hierarchy tutorial, instead using a more generic data structure. Have each node be a struct/class that can be attached to an arbitrary node. The scene will simply be the root node. The individual angle values should be stored in the node object. The node should have a render function that will render this node, given the matrix stack. It would render itself, then recursively render its children. The node would also have a way to define the size (in world-space) and origin point of the rectangle to be drawn.

Given the generalized Hierarchy code, remove the matrix stack. Use matrix objects created on the C++ stack instead. The node render function would take a const& to a matrix rather than a matrix stack reference.