matrices and nesting hierarchy with game objects

Let's say we have some game objects and they are nested to form a tree:

- A
- B
- C
- D


If each of those have a matrix for the scale, rotation and translation, is it then easier that they inherit the properties from the parent as well or not?

If I do make them inherit from the parent then:

+ If I wan't to test if a point is inside C then I can get the inverse matrix and do a test. No need to worry about the matrices of A and B.

+ I can draw C directly for example without the need of applying the matrix of A and B.

If I don't make them inherit:

+ rotating C is more easy for example, cause there is no need to subtract from the parent to get correct values.

+ translating one specific entity is more easy cause there is no need to update the children.

- Testing if a point is inside for example is harder, cause all the matrices up to the root of the be applied.

What is more common / recommended? I'm guessing it makes more sense that children don't inherit from the parent but just start with a identity matrix instead. If someone knows how blender is doing this then please tell me.

1 Answer

Inheritance of transformation is the main reason we like to use transformation hierarchies in game scenes.

If I want to move a car, it's convenient that I can simply move the body/root of the car, and it will bring its doors, wheels, passengers, and contents along for the ride. If I rotate the forearm bone of an animated skeleton, it should not leave the tips of the finger bones behind!

So the source of truth for an object's transformation is its local position, orientation, and scale relative to its parent's coordinate system. If I transform the parent without changing these local variables to compensate, the object should get carried along with the parent's transformation by default.

To keep this fast for the cases where we do want an object's world transformation — the combined/net effect of its local transformation and all the local transformations of its parent, grandparent, great^n grandparent chain — we cache this matrix as a separate variable.

When I change an object's local transformation inputs — its position/orientation/scale relative to its parent — I can construct a local transformation matrix and multiply it by the parent's world matrix to get a new world matrix for the child. Note that we didn't have to walk up the whole parent tree here, since the parent's world matrix already bakes-in the effect of the grandparents, if any. Then we roll that new world matrix down to our object's children.

If you tend to do a lot of random writes to local transformations, and relatively few reads (like just to build the matrices for rendering once per frame), you can use a dirty flag to quickly mark the world matrix out of date, then update it only on-demand, so a bunch of back-to-back transform changes only incur a single combined update cost.