Scene graph
A Scene renders a tree of Nodes. Each node has a transform, may carry a mesh, may hold child nodes, and may run behavior through attached components. Child transforms compose with their parent, so moving or rotating a node moves its whole subtree.
Nodes and transforms
Section titled “Nodes and transforms”A Node holds a localTransform, a Matrix4 relative to its parent. Add a node to the scene with scene.add, which attaches it under the scene’s root node.
final node = Node(mesh: myMesh) ..localTransform = vm.Matrix4.translation(vm.Vector3(2, 0, 0));scene.add(node);A node’s world transform is its parent’s world transform times its own local transform. The render loop recomputes this each frame, so animating a transform is just assigning a new localTransform.
Building a hierarchy
Section titled “Building a hierarchy”Add children to any node with node.add. The child’s transform is then relative to the parent.
final orbit = Node(); // a pivot at the originfinal planet = Node(mesh: planetMesh) ..localTransform = vm.Matrix4.translation(vm.Vector3(5, 0, 0));orbit.add(planet);scene.add(orbit);Rotating orbit now sweeps planet around the origin, because the planet’s position is expressed in the pivot’s rotating space. Nest another pivot under the planet and its children orbit the planet in turn, which is exactly how the demo’s moon works.
Components
Section titled “Components”A Component is behavior bound to a node. Override update, which the engine calls every frame with the elapsed seconds, and read or write node to affect the owner. The demo spins each pivot with a small component.
class Spin extends Component { Spin(this.radiansPerSecond);
final double radiansPerSecond;
@override void update(double deltaSeconds) { node.localTransform = node.localTransform * vm.Matrix4.rotationY(radiansPerSecond * deltaSeconds); }}
final pivot = Node()..addComponent(Spin(0.5));Meshes are attached the same way. Node(mesh: ...) is a convenience that adds a mesh-drawing component for you, so a node can carry rendering, custom behavior, and other components together.
Finding nodes
Section titled “Finding nodes”The scene’s root is scene.root, an ordinary Node you can traverse. Nodes carry an optional name, and getComponents<T>() returns the attached components of a type, which is how you reach a node’s mesh, light, or your own components after building the tree.