decompose method

(Vector3D, QuaternionD, Vector3D) decompose()

Implementation

(Vector3D translation, QuaternionD rotation, Vector3D scale) decompose() {
  late Vector3D translation;
  late QuaternionD rotation;
  late Vector3D scale;

  // Extract translation.
  translation = .vec3(m12, m13, m14);

  // Extract upper-left for determinant computation
  final a = m0;
  final b = m4;
  final c = m8;
  final d = m1;
  final e = m5;
  final f = m9;
  final g = m2;
  final h = m6;
  final i = m10;
  final A = e*i - f*h;
  final B = f*g - d*i;
  final C = d*h - e*g;

  // Extract scale
  final det = a*A + b*B + c*C;
  Vector3D abc = .vec3(a, b, c);
  Vector3D def = .vec3(d, e, f);
  Vector3D ghi = .vec3(g, h, i);

  Vector3D s = .vec3(abc.length, def.length, ghi.length);
  if (det < 0) s = s.negate();
  scale = s;

  // Remove scale from the matrix if it is not close to zero
  MatrixD clone = this.clone();
  if (!Raylib.instance.FloatEquals(det, 0)) {
    clone.m0 /= s.x;
    clone.m4 /= s.x;
    clone.m8 /= s.x;
    clone.m1 /= s.y;
    clone.m5 /= s.y;
    clone.m9 /= s.y;
    clone.m2 /= s.z;
    clone.m6 /= s.z;
    clone.m10 /= s.z;

    // Extract rotation
    rotation = .qFromMatrix(clone);
  } else {
    // Set to identity if close to zero
    rotation = .qIdentity();
  }

  return (translation, rotation, scale);
}