X3D is an open standard that defines:
A set of nodes that describe 3D and 2D content, like shapes (meshes, boxes, spheres), materials, lights, cameras, animations, interactions, shaders, sounds, cube maps (mirrors)…
These nodes are the important building block of our Castle Game Engine. You can load and display them using TCastleScene
.
In our engine, in addition to the standard X3D nodes, we also define a few extension nodes. E.g. we add nodes to make shader effects, screen (post-processing) effects, shadows and more.
A file format to load and save these nodes in files.
There are multiple encodings of X3D nodes, we support the two most common: XML encoding and classic encoding. Both these encodings are just text files — you don’t need any special software to edit them, any text editor will do just fine.
Various 3D modeling applications can export to it. Unfortunately, current Blender exporter to X3D lacks a lot of important features (animations, PBR materials, any textures, metadata…) so we don’t recommend using it.
As a file format, we recommend using glTF instead.
In our engine, the first point is the most important: X3D nodes are the core building block of everything. That is, everything you see loaded into TCastleScene
is a graph of X3D nodes. All 3D and 2D model formats are loaded into a graph of X3D nodes. You have Pascal API available to manipulate these nodes, to create and modify them at runtime.
See our demo models for example X3D models.
You can load and display any X3D model using:
Our Castle Model Viewer.
Any other Castle Game Engine tool. The engine even features a ready "3D Model Viewer" project template and we encourage you to use it to create your own custom viewer.
A number of other X3D viewers and tools are available (including free and open-source). To name a few:
The X3D specifications are your ultimate resource to learn X3D. You will most likely want to browse X3D Architecture and base components specification, which describes the available X3D nodes.
X3D nodes are the scene graph of our engine. Once you load a 3D or 2D model into TCastleScene
(whether it was in X3D format or anything else, like glTF), you have a graph of X3D nodes. The root of this graph is available as TCastleSceneCore.RootNode
.
Every X3D node corresponds to a Pascal class with appropriate fields, and you can freely create and modify X3D nodes at runtime.
For example, consider an X3D node Box. This node in X3D has fields:
size
(the X3D type is SFVec3f
)
solid
(the X3D type is SFBool
).
In Pascal, this node corresponds to the class TBoxNode
, with properties
You can create and edit instances of TBoxNode
and use TCastleScene
to render them.
See for example:
You can also pre-process the loaded scene (e.g. change the texture), by changing the X3D nodes graph (see this forum post for details).
The X3D nodes have a reference-counting mechanism. The node (TX3DNode
or any descendant) is freed when the reference count of it changes from non-zero to zero.
So in the usual case, if you set the node as a value of some property of the other node, then you no longer need to think about releasing this node — it will be released along with the parent. For example:
var
Geometry: TBoxNode;
Shape: TShapeNode;
Root: TX3DRootNode;
begin
Geometry := TBoxNode.Create;
Shape := TShapeNode.Create;
Shape.Geometry := Geometry;
{ Now you no longer need to worry about freeing Geometry.
It will be freed along with Shape.
Note that there's a shortcut for above 3 lines:
Geometry := TBoxNode.CreateWithShape(Shape);
}
Root := TX3DRootNode.Create;
Root.AddChildren(Shape);
{ Now you no longer need to worry about freeing Shape.
It will be freed along with Root. }
// to be continued ...
Moreover, when you load nodes into TCastleScene
using Scene.Load(MyNodes, true)
— the 2nd parameter equal true
means that Scene
takes ownership of the whole nodes tree. So the whole TX3DRootNode
instance will be freed along with Scene
.
So we can continue the example above:
Scene := TCastleScene.Create(Application);
Scene.Load(Root, true);
{ Now you no longer need to worry about freeing Root.
It will be freed along with Scene. }
And Scene
is a regular Pascal TComponent
, with usual component ownership. In the above example, it is owned by the Application
singleton. In larger application, when using views, it will often be owned by TCastleView.FreeAtStop
. And you can always free the scene explicitly too, like FreeAndNil(Scene);
.
Notes:
If a node is not referenced from anywhere, you are responsible for freeing it manually as usual. For example, if we would not load Root
into Scene
(if we remove the line Scene.Load(Root, true)
from above example) then at some point you should call FreeAndNil(Root);
.
If for some reason you do not want the node to be automatically freed, you can use TX3DNode.KeepExistingBegin
and TX3DNode.KeepExistingEnd
.
To improve this documentation just edit this page and create a pull request to cge-www repository.