Skip to main content

Super Basic Transforms

Quick examples working with transforms in C++.

The FTransform Struct

A transform in Unreal is defined by the FTransform:

using FTransform = UE::Math::TTransform<double>;	

Where TTransform is:

template<typename T>
struct alignas( TAlignOfTransform<T>::Value ) TTransform
{
/** Rotation of this transformation, as a quaternion */
TPersistentVectorRegisterType<T> Rotation;
/** Translation of this transformation, as a vector */
TPersistentVectorRegisterType<T> Translation;
/** 3D scale (always applied in local space) as a vector */
TPersistentVectorRegisterType<T> Scale3D;
}

The "alignas" specifier tells the compiler to allocate an FTransform on a memory boundary. So for TTransform<double> the memory is aligned on an 8 byte boundary (because a double is 8 bytes or 64 bits). This improves performance.

The TPersistentVectorRegisterType<T> type resolves to VectorRegister4Double which is both aligned, and supports AVX (Advanced Vector Extensions) for increased performance on platforms which support AVX.

Relative Positions and Transforms

Assuming we have two objects Parent and Child in a parent-child relationship, for example an actor and an actor component. Parent has a world transform (an FTransform), and Child has a relative position to Parent (an FVector).

We can make relative transform from the relative position:

FTransform ChildRelativeTransform = FTransform( FQuat::Identity, RelativePosition, FVector::OneVector );

We can calculate the world transform of the child by multiplying the relative transform of the child by the world transform of the parent:

FTransform ChildWorldTransform = ChildRelativeTransform * ParentWorldTransform;

If the child has a rotation and a position, we can make a transform from these two values and then multiply it by the parent transform to get the world transform:

FQuat ChildRotation( FVector::ZAxisVector, FMath::DegreesToRadians( 90.0 ) );
FVector ChildRelativePosition( 100, 0, 0 );

FTransform ChildRelativeTransform( ChildRotation, ChildRelativePosition );

FTransform ChildWorldTransform = ChildRelativeTransform * ParentWorldTransform;

We can go the other way. If we have the ChildWorldTransform and the ParentWorldTransform, we can calculate the relative transform of the child to the parent:

FTransform ChildRelativeTransform = ChildWorldTransform.GetRelativeTransform(ParentWorldTransform);

To get just the relative position (as opposed to the full transform), if we have the ChildWorldTransform and the ParentWorldTransform, we can calculate the relative position of the child to the parent:

FVector ChildRelativePosition 
= ParentWorldTransform.InverseTransformPosition(ChildWorldTransform.GetLocation);