decompose method

(V3, Q, V3) decompose()

Implementation

(V3 translation, Q rotation, V3 scale) decompose() {
  late V3 translation;
  late Q rotation;
  late V3 scale;

  // Extract translation.
  translation = RaylibVector3Factories.createFactory(m12, m13, m14) as V3;

  // 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;
  V3 abc = RaylibVector3Factories.createFactory(a, b, c) as V3;
  V3 def = RaylibVector3Factories.createFactory(d, e, f) as V3;
  V3 ghi = RaylibVector3Factories.createFactory(g, h, i) as V3;

  V3 s = RaylibVector3Factories.createFactory(abc.length, def.length, ghi.length) as V3;
  if (det < 0) s = s.negate();
  scale = s;

  // Remove scale from the matrix if it is not close to zero
  M clone = this.clone();
  if (!RaylibFunctions.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 = RaylibQuaternionFactories.fromMatrix(clone) as Q;
  } else {
    // Set to identity if close to zero
    rotation = RaylibQuaternionFactories.identity() as Q;
  }

  return (translation, rotation, scale);
}