# Shoemake's Code

The code presented in the last section works, but it's mostly a black box. Lets explore what the `decomp_affine`

function does on a high level. We only ever use the `t`

, `q`

and `k`

fields of the `AffineParts`

structure. Let's take a look at the source of `decomp_affine`

and see how these componetns are filled in.

void decomp_affine(HMatrix A, AffineParts *parts) { HMatrix Q, S, U; Quat p; float det; parts->t = Qt_(A[X][W], A[Y][W], A[Z][W], 0); det = polar_decomp(A, Q, S); if (det<0.f) { mat_copy(Q,=,-Q,3); parts->f = -1; } else { parts->f = 1; } parts->q = Qt_FromMatrix(Q); parts->k = spect_decomp(S, U); parts->u = Qt_FromMatrix(U); p = snuggle(parts->u, &parts->k); parts->u = Qt_Mul(parts->u, p); }

The `t`

field is super simple, it just copies the fields of the matrix that hold the translation data.

The `q`

field is obtained by calling the `polar_decomp`

function, which performs a polar decomposition. This function takes a `Matrix`

**M** as it's input argument and fills out two output arguments **Q** and **S**, the *rotation* (with potential flip data) and *scale* (with potential skew data) matrices respectivley. Finally, the function returns the **determinent** of the rotation matrix.

At this point, the rotation matrix **Q** might actually be a flip. If the determinant was less than `0`

, **Q** contains flip information and needs to be negated. **Q** now holds the final rotation matrix, it can be converted to a quaternion and stored in `q`

.

The **S** matrix contains both scaling and skew data. This skew data is removed using the `spect_decomp`

function, which breaks the matrix down into eigen vectors and eigen values. This function takes the **S** matrix containing scale and skew data as it's input argument and fills out a single output argument, **U** which is the "stretch" matrix. The function returns a `Vector`

which holds the scale data (eigen values)for the transform on each axis.

The resulting `k`

and `u`

values are non-unique, there are 24 potential values for these. The snuggle function modifies the value of `k`

and returns a quaternion that needs to multiply `u`

in order to make sure these values are correct when interpolated. We don't actually care about the `u`

component. After `k`

is corrected, we have everything we need.