# World Space Getters

So far, we've only represented a transform in world space as a matrix. How can we retrieve the world space position / rotation / scale of a transform? We can retrieve world position and rotatin, we can't retrieve world scale. Unity calls this global scale, lossyScale.

## Getting Global Rotation

To get the world rotation of a transform, recursivley multiply the rotation of the transform with it's parents. The code below does this, it uses an iterator instead of recursion.

```Quaternion GetGlobalRotation(Transform t) {
Transform iterator = t.parent

while (iterator != NULL) {
rotation = iterator.rotation * t.rotation;
iterator = iterator.parent
}

return rotation;
}```

## Getting Global Position

The easy way to get the world position of a transform would be to take the last row of the world matrix of the transform. However, we can save a few multiplications by calculating this value without any matrix operations. We need to take the position of the transform and apply it's parents transform to it in the same order as multiplying matrices would:

• scale first
• rotate next
• translate last:
```Vector GetGlobalPosition(Transform t) {
Vector worldPos = t.position; // Copy, not reference

Transform iter = t.Parent
while (iter != null) {
// First apply parent scale
worldPos = worldPos * iter.scale // Vec3 * Vec3
// Next apply parent rotation
worldPos = worldPos * iter.rotation; // Quat * Vec3
// Finally apply parent translation
worldPos += iter.position; // Vec3 + Vec3

iter = iter.parent
}

return worldPos;
}```

## Getting Global (lossy) Scale

The rotation and scale of a parent transform affects the scale of it's child transforms, this can introduce skewing if a parent has a non-uniform scale. Because of this, retrieving the global scale of a transform is difficult. The first step in doing so is to find a 3x3 Matrix that holds both the rotation and scale of the transform. To find this matrix, convert the scale and rotation of the transform into matrices, combine them and recirsivley multiply with the parent transforms rotation and scale matrix.

```Matrix3 GetGlobalRotationAndScale(Transform t) {
Matrix3 scaleMat = Matrix3(
t.scale.x, 0, 0,
0, t.scale.y, 0,
0, 0, t.scale.z
);
Matrix3 rotationMat = ToMatrix(t.rotation);

Matrix3 worldRS = rotationMat * scaleMat;

// Recursivley concatenate with parent
if (t.parent != NULL) {
Matrix3 parentRS = GetGlobalRotationAndScale(t.parent);
worldRS = parentRS * worldRS;
}

// Return scale rotation
return worldRS
}```

Now that we know the global rotation and scale of the transform, we can remove the rotation component, leaving us with just the scale and skew matrix. To do this, find just the global rotation of the transform, invert that quaternion and turn it into a matrix. This new matrix is the inverse global rotation matrix of the transform. Multiply it with the scale and rotation matrix to remove the rotation component. The main diagonal of the resulting scale and skew matrix is the global lossy scale of the transform.

```Vector3 GetGlobalLossyScale(Transform t) {
// Find inverse global rotation (rotation only) of transform
Quaternion rotation = GetGlobalRotation(t);
Matrix3 invRotation = ToMatrix(Inverse(rotation));

// Find global rotation and scale of transform
Matrix3 scaleAndRotation = GetGlobalRotationAndScale(t);

// Remove global rotation from rotation & scale
Matrix3 scaleAndSkew = invRotation * scaleAndRotation; // Mat3 * Mat3

// Return the main doagonal of the scale & skew matrix
return Vector3(scaleAndSkew[0], scaleAndSkew[4], scaleAndSkew[8]);
}```

This method of retrieving global scale is covered in more detail in GPU Pro 5, Managing Transformations in Hierarchy by Bartosz Chodorowski and Wojciech Sterna