When organizing your world, you often want to arrange your 3D objects in a hierarchy. We have two transformation hierarchies in our engine:
The "outer" tree containing scenes:
TCastleViewport.Items
is a tree containing scenes. A scene is an instance of
TCastleScene
class,
which is probably the most important class in our engine.
It represents a 3D or 2D model.
You can group and transform the scenes using
TCastleTransform
.
The TCastleScene
is also a descendant of
TCastleTransform
,
so you can just transform a scene directly.
This is a very simple tree, that allows you to simply transform and group 3D objects.
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),
or hiding / showing the items (use the
TCastleTransform.Exists
property).
It is ultimately fast and can be done as often as you need.
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.
The "inner" tree inside every scene, containing X3D nodes:
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 TTransformNode
(see X3D grouping component). Everything you see
is expressed as a combination of X3D nodes — meshes, materials,
textures, shaders, lighting, animations, collisions...
Each single TCastleScene
has a tree of X3D nodes.
In the simplest cases (if you load scenes using
TCastleSceneCore.Load
)
you will create one TCastleScene
instance for each 3D model file you have.
But you're not limited to this approach, as you can split and merge
X3D graphs freely.
See an example code
examples/viewport_and_scenes/combine_multiple_x3d_into_one_scene
for how to load multiple 3D model files into a single X3D graph
(single TX3DRootNode
).
Properties of the X3D transformation hierarchy:
Changing the transformations in this tree is very fast and optimized, but may have a tiny cost at some point. Rebuilding this tree right now is poorly optimized (it may be improved 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 operations look only at flattened
TCastleScene.Shapes
mentioned below).
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: this tree is somewhat less dynamic. It is very optimized for some changes, like changing transformations of existing objects, but poorly optimized for an arbitrary rearranging at runtime. Rendering and processing is always lighting fast, regardless of the tree depth or complication.
A natural question is should you combine multiple loaded models into one TCastleScene (like examples/viewport_and_scenes/combine_multiple_x3d_into_one_scene example does)?
At the beginning, don't merge the scenes. It's more natural, and in 90% cases perfectly fast, to use one TCastleScene
for each one model file you load. This allows to trivially load the model using Scene.Load
and is really advised for most cases. See also the relevant section in the manual about optimization.
100, or even 1000, or TCastleScene
instances visible should not be a problem. You should consider merging them if you have 10 000 or more. It depends on your use-case (how complicated are the scenes, how heavy is their rendering and which optimizations matter most).
For completeness, we should also mention another transformation tree.
The X3D nodes hierarchy is automatically reflected as (a little flattened and simplified)
tree of shapes in the
TCastleSceneCore.Shapes
property.The visible nodes of this tree are X3D Shape
nodes
(TShapeNode
) linked
with geometry nodes inside
(TAbstractGeometryNode
).
This tree can be completely ignored by your code.
It is automatically created and managed inside the
TCastleScene
.
Sometimes you can use this tree to speedup some operations — instead of traversing
the tree in TCastleSceneCore.RootNode
,
it's sometimes enough to traverse simpler tree
TCastleSceneCore.Shapes
.