invert method

Matrix4 invert()

Implementation

Matrix4 invert() {
  // based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm
  final te = storage;
  final double n11 = te[0],
      n21 = te[1],
      n31 = te[2],
      n41 = te[3],
      n12 = te[4],
      n22 = te[5],
      n32 = te[6],
      n42 = te[7],
      n13 = te[8],
      n23 = te[9],
      n33 = te[10],
      n43 = te[11],
      n14 = te[12],
      n24 = te[13],
      n34 = te[14],
      n44 = te[15],
      t11 = n23 * n34 * n42 -
          n24 * n33 * n42 +
          n24 * n32 * n43 -
          n22 * n34 * n43 -
          n23 * n32 * n44 +
          n22 * n33 * n44,
      t12 = n14 * n33 * n42 -
          n13 * n34 * n42 -
          n14 * n32 * n43 +
          n12 * n34 * n43 +
          n13 * n32 * n44 -
          n12 * n33 * n44,
      t13 = n13 * n24 * n42 -
          n14 * n23 * n42 +
          n14 * n22 * n43 -
          n12 * n24 * n43 -
          n13 * n22 * n44 +
          n12 * n23 * n44,
      t14 = n14 * n23 * n32 -
          n13 * n24 * n32 -
          n14 * n22 * n33 +
          n12 * n24 * n33 +
          n13 * n22 * n34 -
          n12 * n23 * n34;

  final det = n11 * t11 + n21 * t12 + n31 * t13 + n41 * t14;

  if (det == 0) return setValues(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);

  final detInv = 1 / det;

  te[0] = t11 * detInv;
  te[1] = (n24 * n33 * n41 -
          n23 * n34 * n41 -
          n24 * n31 * n43 +
          n21 * n34 * n43 +
          n23 * n31 * n44 -
          n21 * n33 * n44) *
      detInv;
  te[2] = (n22 * n34 * n41 -
          n24 * n32 * n41 +
          n24 * n31 * n42 -
          n21 * n34 * n42 -
          n22 * n31 * n44 +
          n21 * n32 * n44) *
      detInv;
  te[3] = (n23 * n32 * n41 -
          n22 * n33 * n41 -
          n23 * n31 * n42 +
          n21 * n33 * n42 +
          n22 * n31 * n43 -
          n21 * n32 * n43) *
      detInv;

  te[4] = t12 * detInv;
  te[5] = (n13 * n34 * n41 -
          n14 * n33 * n41 +
          n14 * n31 * n43 -
          n11 * n34 * n43 -
          n13 * n31 * n44 +
          n11 * n33 * n44) *
      detInv;
  te[6] = (n14 * n32 * n41 -
          n12 * n34 * n41 -
          n14 * n31 * n42 +
          n11 * n34 * n42 +
          n12 * n31 * n44 -
          n11 * n32 * n44) *
      detInv;
  te[7] = (n12 * n33 * n41 -
          n13 * n32 * n41 +
          n13 * n31 * n42 -
          n11 * n33 * n42 -
          n12 * n31 * n43 +
          n11 * n32 * n43) *
      detInv;

  te[8] = t13 * detInv;
  te[9] = (n14 * n23 * n41 -
          n13 * n24 * n41 -
          n14 * n21 * n43 +
          n11 * n24 * n43 +
          n13 * n21 * n44 -
          n11 * n23 * n44) *
      detInv;
  te[10] = (n12 * n24 * n41 -
          n14 * n22 * n41 +
          n14 * n21 * n42 -
          n11 * n24 * n42 -
          n12 * n21 * n44 +
          n11 * n22 * n44) *
      detInv;
  te[11] = (n13 * n22 * n41 -
          n12 * n23 * n41 -
          n13 * n21 * n42 +
          n11 * n23 * n42 +
          n12 * n21 * n43 -
          n11 * n22 * n43) *
      detInv;

  te[12] = t14 * detInv;
  te[13] = (n13 * n24 * n31 -
          n14 * n23 * n31 +
          n14 * n21 * n33 -
          n11 * n24 * n33 -
          n13 * n21 * n34 +
          n11 * n23 * n34) *
      detInv;
  te[14] = (n14 * n22 * n31 -
          n12 * n24 * n31 -
          n14 * n21 * n32 +
          n11 * n24 * n32 +
          n12 * n21 * n34 -
          n11 * n22 * n34) *
      detInv;
  te[15] = (n12 * n23 * n31 -
          n13 * n22 * n31 +
          n13 * n21 * n32 -
          n11 * n23 * n32 -
          n12 * n21 * n33 +
          n11 * n22 * n33) *
      detInv;

  return this;
}