Specialized components
Physics and spatial systems
Transform system
17 min
overview the transform system is a fundamental component of the ir engine that manages the spatial properties of entities in the 3d environment it handles the position, rotation, and scale of objects, as well as their hierarchical relationships this system is essential for determining where objects appear in the virtual world and how they relate spatially to one another transformcomponent the core data structure of the transform system is the transformcomponent this component stores the spatial information for an entity and is defined with the following key properties property type description position vector3 the (x, y, z) coordinates of the entity in 3d space rotation quaternion the orientation of the entity, stored as a quaternion scale vector3 the size of the entity along each axis matrix matrix4 the local transformation matrix derived from position, rotation, and scale matrixworld matrix4 the final world transformation matrix, accounting for parent transformations // simplified from src/transform/components/transformcomponent ts import { s } from '@ir engine/ecs/src/schemas/jsonschemas'; import { t } from ' / /schema/schemafunctions'; export const transformcomponent = definecomponent({ name 'transformcomponent', schema s object({ position t vec3(), rotation t quaternion(), scale t vec3(), matrix t mat4(), matrixworld t mat4() }), // additional component configuration }); using the transform component adding a transform to an entity to position an entity in 3d space, a transformcomponent is added to it import { createentity, setcomponent } from '@ir engine/ecs'; import { transformcomponent } from ' /transform/components/transformcomponent'; const entity = createentity(); // add a transformcomponent with specific position values setcomponent(entity, transformcomponent, { position { x 5, y 2, z 3 } // rotation and scale will use default values }); modifying transform properties transform properties can be modified directly through the component import { getcomponent } from '@ir engine/ecs'; // get the transform component of an entity const transform = getcomponent(entity, transformcomponent); // update position transform position x = 10; transform position y += 2; // update rotation (quaternion) transform rotation setfromaxisangle(new vector3(0, 1, 0), math pi/2); // update scale transform scale set(2, 1, 1); // twice as wide on the x axis when these properties are modified, the transform system automatically marks the component as "dirty," indicating that its matrices need to be recalculated transform system operation the transform system performs several key operations during each frame of execution 1\ dirty state management the system first identifies which transform components need to be updated components whose position, rotation, or scale have changed components whose parent's transform has changed components that have been newly added to entities // conceptual from src/transform/systems/transformsystem ts function identifydirtytransforms() { for (const entity of entitieswithtransform) { const isdirty = checkselfdirty(entity) || checkparentdirty(entity) || checkcomputedtransformdirty(entity); if (isdirty) { dirtyentities add(entity); } } } 2\ local matrix calculation for each dirty transform, the system calculates the local transformation matrix from the position, rotation, and scale values // simplified from src/transform/components/transformcomponent ts function composematrix(entity) { const transform = getcomponent(entity, transformcomponent); // create a 4x4 matrix from position, rotation, and scale transform matrix compose( transform position, transform rotation, transform scale ); } 3\ world matrix calculation the system then calculates the world matrix, which accounts for parent child relationships // simplified from src/transform/components/transformcomponent ts export const transformcomponent = definecomponent({ // computetransformmatrix (entity entity) => { const transform = getcomponent(entity, transformcomponent); // update local matrix composematrix(entity); // update world matrix based on parent (if any) const parententity = getoptionalcomponent(entity, entitytreecomponent)? parententity; if (parententity) { const parenttransform = getoptionalcomponent(parententity, transformcomponent); if (parenttransform) { // worldmatrix = parent worldmatrix localmatrix transform matrixworld multiplymatrices( parenttransform matrixworld, transform matrix ); } else { transform matrixworld copy(transform matrix); } } else { transform matrixworld copy(transform matrix); } } // }); 4\ dirty state cleanup after all transforms have been updated, the system resets the dirty flags for the next frame // conceptual from src/transform/systems/transformsystem ts function cleanupdirtyflags() { transformcomponent dirty fill(0); // reset all dirty flags } transform hierarchy the transform system supports hierarchical relationships between entities, allowing child objects to inherit transformations from their parents parent child relationships when an entity is a child of another entity, its final world position, rotation, and scale are influenced by its parent's transform // create parent and child entities const parententity = createentity(); const childentity = createentity(); // set up parent child relationship setcomponent(childentity, entitytreecomponent, { parententity parententity }); // position parent at (10, 0, 0) setcomponent(parententity, transformcomponent, { position { x 10, y 0, z 0 } }); // position child at (0, 5, 0) relative to parent setcomponent(childentity, transformcomponent, { position { x 0, y 5, z 0 } }); // child's world position will be (10, 5, 0) matrix propagation the transform system automatically propagates changes through the hierarchy when a parent's transform changes, all its children are marked as dirty the system processes entities in hierarchical order, ensuring parents are updated before their children each child's world matrix is calculated by multiplying its local matrix by its parent's world matrix execution flow the following sequence diagram illustrates the transform system's execution flow when an entity's position is changed sequencediagram participant usercode participant tc as transformcomponent participant tds as transformdirtyupdatesystem participant ts as transformsystem participant tdcleanups as transformdirtycleanupsystem usercode >>tc entity position x = 10 note right of tc component marked as 'dirty' note over tds, tdcleanups engine game loop tick tds >>tc query for dirty transforms tc >>tds list of dirty entities ts >>tc for each dirty entity updatematrix(entity) note right of tc computetransformmatrix(entity) \<br/>1 composematrix() (prs → local matrix)\<br/>2 local matrix parent's world matrix → world matrix tdcleanups >>tc reset all dirty flags integration with other systems the transform system provides essential spatial information to several other engine systems rendering system uses world matrices to position and orient visual elements physics system uses and updates transforms based on physical simulation input system may modify transforms in response to user input animation system updates transforms over time to create movement performance considerations the transform system is optimized for performance in several ways dirty flagging only recalculates matrices when necessary hierarchical processing updates entities in the correct order to minimize redundant calculations batch processing processes transforms in batches for better cache utilization matrix reuse avoids creating new matrix objects during calculations next steps with an understanding of how entities are positioned and oriented in 3d space, the next chapter explores the rendering system, which uses this spatial information to visualize objects on screen next rendering system docid 9tweoypzmllk2luw1ohxc