Index

Scene Graph

Like many engines, Trial includes a "scene graph" – a tree of nodes in which the objects that are drawn or are interactable are organised. Each node is a scene-node with a container pointer to its parent node. Nodes that can contain other child nodes are containers. Nodes that can be named are called entitys. If an entity is named, it is uniquely identified by its name within the scene it is contained in. An entity can be obtained via its name with the node function.

Graph Operations

Operating on the graph is rather simple: enter is used to introduce a node into a container, and leave is used to remove it again. When a node is entered, it is also registered on the graph's root scene. Similarly, when it is left, the node and any children it might have are first deregistered. When the name of an entity is changed via setf, the object is also first deregistered and then re-registered after the name change.

Each container must be a sequence and as such can be iterated over as one, using either for:for or sequences:dosequence. All other standard sequence operations are naturally required to be supported as well.

You can also clear a container fully, though note that this will not recursively clear if the container contained other containers. When a container is finalized, all of its children are also finalized and the container is cleared, though as with all finalization you should not rely on any particular state after finalization.

Finally, you can check whether a node is within a container with contained-p, and retrieve the container it is in (if any) with the container function. To retrieve the root scene, simply use the scene function.

Reacting to Scene Changes

When a node in the scene graph is added or removed, you can react to that change at the immediate child level via methods on enter and leave. Any enter and leave operation will also bubble upwards (to the root) of the tree via register and deregister calls correspondingly, so you can react to changes lower down in the tree via methods on those functions.

Note that all of those functions are called synchronously, so performing expensive operations in them will also make scene tree changes expensive as well. However, it also allows you to perform consistency checks and error out, should an insertion or removal be considered invalid.

In order to react to changes elsewhere in the scene graph, you can add an event handler for the register and deregister events. Note that these will be asynchronous and will only be handled after the change has already been performed.

Entity Mixins

By themselves nodes don't actually do anything. Often you'd like the nodes to carry some properties such as a location, orientation, etc. To this end, Trial offers a number of mixin classes:

Note that if you use multiple of these mixins that the order in which you specify them in the superclass list matters, as it determines the order in which their transformations apply to the model-matrix via apply-transforms.

Container Types

While you can create your own container types when necessary, Trial already provides a number of containers that should fit almost every need out there.

Defining your own container types is simple – all you need to do is subclass container, and implement clear, enter, leave, and the necessary sequence methods (most notably sequences:make-sequence-iterator).