decompose function

List<double> decompose(
  1. List<double> outR,
  2. List<double> outT,
  3. List<double> outS,
  4. List<double> mat,
)

Decomposes a transformation matrix into its rotation, translation and scale components. Returns only the rotation component @param {quat} out_r Quaternion to receive the rotation component @param {vec3} out_t Vector to receive the translation vector @param {vec3} out_s Vector to receive the scaling factor @param {ReadonlyMat4} mat Matrix to be decomposed (input) @returns {quat} out_r

Implementation

List<double> decompose(List<double> outR, List<double> outT, List<double> outS, List<double> mat) {
  outT[0] = mat[12];
  outT[1] = mat[13];
  outT[2] = mat[14];

  final m11 = mat[0];
  final m12 = mat[1];
  final m13 = mat[2];
  final m21 = mat[4];
  final m22 = mat[5];
  final m23 = mat[6];
  final m31 = mat[8];
  final m32 = mat[9];
  final m33 = mat[10];

  outS[0] = hypot([m11, m12, m13]);
  outS[1] = hypot([m21, m22, m23]);
  outS[2] = hypot([m31, m32, m33]);

  final is1 = 1 / outS[0];
  final is2 = 1 / outS[1];
  final is3 = 1 / outS[2];

  final sm11 = m11 * is1;
  final sm12 = m12 * is2;
  final sm13 = m13 * is3;
  final sm21 = m21 * is1;
  final sm22 = m22 * is2;
  final sm23 = m23 * is3;
  final sm31 = m31 * is1;
  final sm32 = m32 * is2;
  final sm33 = m33 * is3;

  final trace = sm11 + sm22 + sm33;
  double S = 0;

  if (trace > 0) {
    S = math.sqrt(trace + 1.0) * 2;
    outR[3] = 0.25 * S;
    outR[0] = (sm23 - sm32) / S;
    outR[1] = (sm31 - sm13) / S;
    outR[2] = (sm12 - sm21) / S;
  } else if (sm11 > sm22 && sm11 > sm33) {
    S = math.sqrt(1.0 + sm11 - sm22 - sm33) * 2;
    outR[3] = (sm23 - sm32) / S;
    outR[0] = 0.25 * S;
    outR[1] = (sm12 + sm21) / S;
    outR[2] = (sm31 + sm13) / S;
  } else if (sm22 > sm33) {
    S = math.sqrt(1.0 + sm22 - sm11 - sm33) * 2;
    outR[3] = (sm31 - sm13) / S;
    outR[0] = (sm12 + sm21) / S;
    outR[1] = 0.25 * S;
    outR[2] = (sm23 + sm32) / S;
  } else {
    S = math.sqrt(1.0 + sm33 - sm11 - sm22) * 2;
    outR[3] = (sm12 - sm21) / S;
    outR[0] = (sm31 + sm13) / S;
    outR[1] = (sm23 + sm32) / S;
    outR[2] = 0.25 * S;
  }

  return outR;
}