TransformManager is used to add transform components to entities, giving them position and orientation in 3D space with hierarchical parent-child relationships.
Overview
A Transform component provides an entity with a local transform relative to its parent. The TransformManager automatically computes world-space transforms by composing local transforms through the hierarchy.
Basic Usage
#include <filament/Engine.h>
#include <filament/TransformManager.h>
#include <utils/EntityManager.h>
using namespace filament;
Engine* engine = Engine::create();
auto& tcm = engine->getTransformManager();
utils::Entity object = utils::EntityManager::get().create();
// Create the transform component
tcm.create(object);
// Set its transform
auto instance = tcm.getInstance(object);
tcm.setTransform(instance, mat4f::translation({0, 0, -1}));
// Destroy when done
tcm.destroy(object);
create
Creates a transform component and associates it with an entity.
void create(utils::Entity entity,
Instance parent = {},
const math::mat4f& localTransform = {});
Parameters:
entity - Entity to associate the transform component with
parent - Instance of the parent transform, or empty Instance for root
localTransform - Initial local transform relative to parent
If a component already exists on the entity, it is destroyed first.
Example with parent-child hierarchy:
auto& tcm = engine->getTransformManager();
utils::Entity parent = utils::EntityManager::get().create();
utils::Entity child = utils::EntityManager::get().create();
// Create parent at world origin
tcm.create(parent);
auto parentInstance = tcm.getInstance(parent);
// Create child with parent, offset by (1, 0, 0)
tcm.create(child, parentInstance, mat4f::translation({1, 0, 0}));
destroy
Destroys the transform component from an entity. Children are orphaned.
void destroy(utils::Entity e) noexcept;
When a transform is destroyed, its children become orphaned - their local transform becomes their world transform. Ensure child transforms are handled before destroying a parent.
setParent
Re-parents an entity to a new parent.
void setParent(Instance i, Instance newParent) noexcept;
Re-parenting an entity to one of its descendants will cause undefined behavior. Always verify parent-child relationships before re-parenting.
getParent
Returns the parent entity, or a null entity if the transform is a root.
utils::Entity getParent(Instance i) const noexcept;
getChildCount
Returns the number of children for a transform.
size_t getChildCount(Instance i) const noexcept;
getChildren
Retrieves children entities into an array.
size_t getChildren(Instance i,
utils::Entity* children,
size_t count) const noexcept;
Example:
auto instance = tcm.getInstance(parentEntity);
size_t childCount = tcm.getChildCount(instance);
std::vector<utils::Entity> children(childCount);
tcm.getChildren(instance, children.data(), childCount);
Iterating Children
Use iterators to traverse children:
children_iterator getChildrenBegin(Instance parent) const noexcept;
children_iterator getChildrenEnd(Instance parent) const noexcept;
Example:
auto& tcm = engine->getTransformManager();
auto parentInstance = tcm.getInstance(parentEntity);
for (auto it = tcm.getChildrenBegin(parentInstance);
it != tcm.getChildrenEnd(parentInstance); ++it) {
auto childInstance = *it;
// Process child transform
}
Sets the local transform of a component.
void setTransform(Instance ci, const math::mat4f& localTransform) noexcept;
void setTransform(Instance ci, const math::mat4& localTransform) noexcept;
The mat4 overload maintains translation at double precision when accurate translation mode is enabled.
This operation can be slow if the transform hierarchy is deep. For bulk updates, use transform transactions.
Example from animation sample:
auto& tcm = engine->getTransformManager();
tcm.setTransform(tcm.getInstance(renderable),
filament::math::mat4f::rotation(now, filament::math::float3{0, 0, 1}));
Returns the local transform (relative to parent).
const math::mat4f& getTransform(Instance ci) const noexcept;
math::mat4 getTransformAccurate(Instance ci) const noexcept;
Returns the world transform (relative to root).
const math::mat4f& getWorldTransform(Instance ci) const noexcept;
math::mat4 getWorldTransformAccurate(Instance ci) const noexcept;
The world transform is the composition of the local transform with all parent transforms up to the root.
For efficient bulk updates of transforms in deep hierarchies:
Opens a transaction for batch transform updates.
void openLocalTransformTransaction() noexcept;
During a transaction:
setTransform() runs in constant time
getWorldTransform() may return invalid values until the transaction is committed
Commits the transaction and updates world transforms.
void commitLocalTransformTransaction() noexcept;
Failure to commit the transaction will cause rendering problems. The system never automatically closes transactions.
Example with transaction:
auto& tcm = engine->getTransformManager();
// Open transaction for bulk updates
tcm.openLocalTransformTransaction();
// Update many transforms efficiently
for (size_t i = 0; i < entities.size(); ++i) {
auto instance = tcm.getInstance(entities[i]);
tcm.setTransform(instance, transforms[i]);
}
// Commit to update world transforms
tcm.commitLocalTransformTransaction();
Accurate Translation Mode
For scenarios requiring high precision (large worlds, astronomical distances):
setAccurateTranslationsEnabled
Enables double precision for translation components.
void setAccurateTranslationsEnabled(bool enable) noexcept;
When enabled:
- Translation components are maintained at double precision
- Use the
mat4 overloads of setTransform() to provide double precision input
- Use
getTransformAccurate() and getWorldTransformAccurate() to retrieve full precision
isAccurateTranslationsEnabled
Returns whether accurate translation mode is active.
bool isAccurateTranslationsEnabled() const noexcept;
Component Management
hasComponent
Checks if an entity has a transform component.
bool hasComponent(utils::Entity e) const noexcept;
getInstance
Gets an Instance handle for the entity’s transform component.
Instance getInstance(utils::Entity e) const noexcept;
Returns an invalid instance if the entity has no transform component. Use Instance::isValid() to check.
getEntity
Retrieves the entity from a component instance.
utils::Entity getEntity(Instance i) const noexcept;
getComponentCount
Returns the total number of transform components.
size_t getComponentCount() const noexcept;
empty
Returns true if the manager has no components.
bool empty() const noexcept;