24. Transformation hierarchy

When organizing your 3D world, you often want to arrange your 3D objects in a hierarchy. We have two transformation hierarchies in our engine:

  1. TCastleSceneManager.Items contains a hierarchy of 3D objects. It can transform 3D objects by containers like T3DTransform and T3DOrient. Existing management of creatures (TCreature) and items on level (TItemOnWorld) and player (TPlayer) already uses these transforming containers to move creatures, player etc. Loading a level by TGameSceneManager.LoadLevel initializes the whole tree for you, but you can also do it by hand.

    The visible leaves of this tree are TCastleScene instances (although you can also implement your own visible 3D objects).

    Properties of this transformation hierarchy:

    • Changing this tree dynamically has absolutely zero cost. This includes changing transformations of items (moving, rotating, scaling them), or completely rearranging the tree (adding, removing items). It is fast and can be done often.

    • Downside: do not make this tree too deep and complicated. This tree needs to be traversed each time you render or check collisions with the 3D world. Although we successfully use it with hundreds of transformations, but be careful — at some point the processing time will become noticeable.

    • Summary: absolutely dynamic tree, but don't make it too deep and complicated.

  2. Inside TCastleScene there is a transformation hierarchy of X3D nodes, starting in TCastleSceneCore.RootNode. Loading the scene by TCastleSceneCore.Load automatically builds a tree of X3D nodes based on 3D model contents. You can also build (or process) the X3D nodes tree by code. There are various grouping and transforming nodes, most notably Transform (see X3D grouping component).

    See example code castle_game_engine/examples/3d_rendering_processing/combine_multiple_x3d_into_one.lpr for how to load multiple 3D model files into a single X3D graph (single TX3DRootNode).

    This hierarchy is also automatically reflected as (a little flattened a simplified) TCastleSceneCore.Shapes tree.

    The visible nodes of this tree are X3D Shape nodes (TShapeNode) with geometry nodes inside (TAbstractGeometryNode).

    Properties of this transformation hierarchy:

    • Changing the transformations in this tree is still very fast and optimized, but may have a tiny cost at some point. Rebuilding this tree right now is poorly optimized (it may improve in the future, but there's a limit to how much it can be done).
    • Upside: you can go wild with the transformation level here, the actual rendering and many other read-only operations look only at flatter TCastleScene.Shapes.

    • 3D collisions, and the "frustum culling" rendering optimization, use a tree (like an octree) to minimize the number of calculations. This is very efficient if you have a lot of 3D shapes.

    • Summary: somewhat less dynamic (very optimized for some specific changes, like changing transformations of existing objects, but poorly optimized for general rearranging at runtime). Rendering and processing is always lighting fast, regardless of the tree depth or complication.