We will now load a 3D model from file using the
and display it.
Note that a 3D model doesn't have to be static. It can include animated stuff, interactions, 3D sounds, scripts, and more. Our scene graph based on X3D is really quite powerful.
A sample 3D model may be found inside the engine examples,
My advice is to copy now the whole directory
data from there into your
own project directory (so you have files like
data is special, it cooperates with the default
behavior of our ApplicationData function.
And if you want to make your own 3D model, go ahead — generally use any 3D modeler and export to any 3D format we can handle, preferably X3D. See our guide to creating game data for more information about preparing 3D data.
If you use Lazarus form with
To load a 3D model, double click to create an event
TForm1 class, and put there the following code:
// also add to your uses clauses these units: CastleSceneCore, CastleScene; procedure TForm1.FormCreate(Sender: TObject); var Scene: TCastleScene; begin Scene := TCastleScene.Create(Application); Scene.Load('car.x3d'); Scene.Spatial := [ssRendering, ssDynamicCollisions]; Scene.ProcessEvents := true; CastleControl1.SceneManager.Items.Add(Scene); CastleControl1.SceneManager.MainScene := Scene; end;
If you use TCastleWindow: To load a 3D model, change your program code to this:
uses CastleWindow, CastleSceneCore, CastleScene; var Window: TCastleWindow; Scene: TCastleScene; begin Window := TCastleWindow.Create(Application); Window.Open; Scene := TCastleScene.Create(Application); Scene.Load('car.x3d'); Scene.Spatial := [ssRendering, ssDynamicCollisions]; Scene.ProcessEvents := true; Window.SceneManager.Items.Add(Scene); Window.SceneManager.MainScene := Scene; Application.Run; end.
At the beginning we create a new instance of
TCastleScene, and load
it's contents from a file.
Scene.Spatial determines what spatial
structures (octrees for now) are created, the value
ssDynamicCollisions] is the most flexible one (it allows to speed up
the rendering by frustum culling, detect collisions between player and
level, and it adapts to a dynamic level that may have some animated
Scene.ProcessEvents activates animating VRML/X3D models (you
can remove it if you know that your level is, and always will be, static).
The level is added to the scene manager. The level is also set as the MainScene of scene manager, this means that some central settings (like initial camera position, initial headlight status and such) can be obtained from this scene.
To control the initial camera view, one option is to use the SceneManager.RequiredCamera.SetView method. This takes three vectors — position, look direction and look up vector. Simply add the CastleVectors unit to your uses clause, and call this:
Window.SceneManager.RequiredCamera.SetView( Vector3Single(-7.83, 6.15, -7.55), Vector3Single( 0.47, -0.30, 0.82), Vector3Single( 0.16, 0.95, 0.25) );
Note: setting camera to the hardcoded values in code, like above, is not usually the best choice. We did it just to show you how to control the camera by code.
A better choice would be to place an
Viewpoint node inside the
car.x3d file to
define the initial camera view. We could have generated this
Viewpoint using the
"Console -> Print Current Camera (Viewpoint)",
or by setting the camera in Blender before exporting this X3D file.
In fact, I used view3dscene to find out the correct numbers to put in the code above.
Note that you have a lot of options to control the camera. You can assign a specific camera descendant to SceneManager.Camera. If you don't, the camera instance is automatically created when you use SceneManager.RequiredCamera, SceneManager.WalkCamera, SceneManager.ExamineCamera or anything that underneath requires a camera (e.g. rendering requires a camera). You can change the navigation type by setting SceneManager.NavigationType. You can change the SceneManager.Camera.Input to disable some default camera key and mouse operations.
You can also control it from X3D by using the
Scene manager contains the whole knowledge about your game 3D world.
It is essential to add all your 3D stuff to a scene manager.
An instance of scene manager (class
is already created and available in the
By default TCastleSceneManager also acts as a viewport filling the whole window. So the whole window shows
your 3D world. In more complex scenarios you can have
many smaller viewports inside your window using TCastleViewport.
You can also turn off scene manager from being a viewport
(setting TCastleSceneManager.DefaultViewport to
false), and then scene manager is really
only something that keeps track of 3D world, and nothing more.
For examples of using viewports, see:
In more advanced
scenarios you may need to create and manage scene manager yourself.
There are special classes available (
TCastleWindowCustom) that allow you to use your own scene manager
instance (or maybe zero, or maybe more than one scene manager instance,
maybe a custom scene manager class...).
An important strength of our engine is that you can express a lot of stuff inside your data, that is inside VRML/X3D models. So many features of our engine (shaders, screen effects, mirrors and many many more) don't have any special Object Pascal examples, because they are simply not needed. For simple uses, you just define what you need inside VRML/X3D file (of course, for advanced usage you can do a lot more with Object Pascal code, and you can always build/modify VRML/X3D graph by Object Pascal code). So be sure to grab our demo VRML/X3D models and try opening them with any engine example program (like the one you just created, or even our view3dscene) — you will find that everything just works, not requiring a single line of Object Pascal code.
Our model viewer view3dscene allows to test your models before loading them to your games.