Transform System
SafiEngine represents spatial data with two transform components:
SafiTransform— local position, rotation, and scale.SafiGlobalTransform— world-space model matrix, written automatically by the engine's propagation system.
Local transform
safi_transform_identity() returns zero position, identity quaternion, and unit scale.
safi_transform_to_mat4() composes a TRS model matrix (T * R * S) from a local transform. Used internally by the propagation system.
Global transform
A world-space model matrix. Written every frame by an engine-owned propagation system on EcsPostUpdate. Renderers and physics read this instead of rebuilding a matrix from SafiTransform.
Opt-in: entities only get a world transform if they explicitly carry SafiGlobalTransform. Add it alongside SafiTransform:
Hierarchy propagation
The propagation system uses flecs' cascade traversal on EcsChildOf to visit entities parents-before-children in a single pass. For each entity:
- Root (no parent):
global.matrix = local TRS - Child:
global.matrix = parent.global.matrix * local TRS
Parent a child entity using flecs' built-in EcsChildOf relationship:
The child's SafiGlobalTransform.matrix will contain the parent's world pose composed with its local offset. Rotating the parent causes the child to orbit around it.
Phase ordering
The propagation system runs on EcsPreStore inside the render pipeline, after both user gameplay and physics have written to SafiTransform:
This ensures the renderer sees a fully-settled world: both user-driven and physics-driven transform changes are captured before the first draw call.
Registration
The propagation system is registered automatically by safi_ecs_create. Apps that bring their own world can call safi_transform_register(world) directly (requires stock components to be registered first).
No dirty flags or change-driven recomputation exists. The propagation system rewrites every SafiGlobalTransform every frame, which is fine for hundreds of entities. Lazy propagation is a future optimization.
Scene panel hierarchy
The debug UI's Scene panel renders entities as a collapsible tree. Parent entities (those with EcsChildOf children) show an arrow toggle to expand/collapse their subtree. Children appear indented under their parent.
See also
- Stock components
- ECS Overview
- Scheduler & Stages — pipeline ordering
- Render Overview