Chapter 2. Scene Manager

The best way to use our engine is through the scene manager. Scene manager knows everything about your 3D world, everything that is needed to perform collision detection, rendering and other useful operations. By default, scene manager is also a viewport, that allows you to actually see the 3D world.

2.1. Scene manager, and basic example of using our engine

Figure 2.1. Three 3D objects are rendered here: precalculated dinosaur animation, scripted (could be interactive) fountain animation, and static tower.

Three 3D objects are rendered here: precalculated dinosaur animation, scripted (could be interactive) fountain animation, and static tower.

In the simplest case, you just create TCastleWindow instance which gives you a ready-to-use scene manager inside the TCastleWindow.SceneManager property.

Example code below uses scene manager to trivially make a full 3D model viewer. This correctly handles collisions, renders in an optimal manner (frustum culling etc.), handles animations and interactive behavior and generally takes care of everything.

var
  Window: TCastleWindow;
  Scene: TCastleScene;
begin
  Scene := TCastleScene.Create(Application
    { Owner that will free the Scene });
  Scene.Load('models/boxes.x3dv');
  Scene.Spatial := [ssRendering, ssDynamicCollisions];
  Scene.ProcessEvents := true;

  Window := TCastleWindow.Create(Application);
  Window.SceneManager.Items.Add(Scene);
  Window.SceneManager.MainScene := Scene;

  Window.OpenAndRun;
end.

The source code of this program is in examples/3d_rendering_processing/view_3d_model_basic.lpr in engine sources. You can compile it and see that it actually works. There's also more extensive demo of scene manager in the examples/3d_rendering_processing/scene_manager_demos.lpr, and demo of other engine stuff in examples/3d_rendering_processing/view_3d_model_advanced.lpr.

This looks nice and relatively straightforward, right? You create 3D object (Scene), and a window to display the 3D world (Window). It's obvious how to add a second 3D object: just create Scene2, and add it to Window.SceneManager.Items.

The Lazarus component equivalent to TCastleWindow is called TCastleControl. It works the same, but you can drop it on a Lazarus form.

A 3D object is anything descending from a base class T3D. All 3D objects in our engine are derived from the T3D class. The most important non-abstract 3D objects are TCastleScene (3D model, possibly interactive VRML / X3D) and TCastlePrecalculatedAnimation (non-interactive animation). There are also some helper 3D objects (T3DList - list of other 3D objects, and T3DTranslated - translated other 3D object). And the real beauty is that you can easily derive your own T3D descendants, just override a couple methods and you get 3D objects that can be visible, can collide etc. in 3D world.

Any T3D descendant may be added to the scene manager Items. In every 3D program you have an instance of scene manager (TCastleSceneManager class, or your customized descendant of it), and you add your 3D objects to the scene manager. Scene manager keeps the whole knowledge about your 3D world, as a tree of T3D objects. Scene manager should also be present on the Controls list of the window, to receive all the necessary events from your window, and pass them to all interested 3D objects. If you use TCastleWindow, suggested in the example above, then scene manager is already created and added to the Controls list for you. Scene manager also connects your camera, and defines your viewport where 3D world is rendered through this camera.