# 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.