setFromRotationMatrix method

Euler setFromRotationMatrix(
  1. Matrix4 m, [
  2. RotationOrders? order,
  3. bool? update
])

m - a Matrix4 of which the upper 3x3 of matrix is a pure rotation matrix (i.e. unscaled).

order - (optional) a string representing the order that the rotations are applied.

Sets the angles of this euler transform from a pure rotation matrix based on the orientation specified by order.

Implementation

Euler setFromRotationMatrix(Matrix4 m, [RotationOrders? order, bool? update]) {
  //final clamp = MathUtils.clamp;

  // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)

  final te = m.storage;
  double m11 = te[0], m12 = te[4], m13 = te[8];
  double m21 = te[1], m22 = te[5], m23 = te[9];
  double m31 = te[2], m32 = te[6], m33 = te[10];

  order = order ?? _order;

  switch (order) {
    case RotationOrders.xyz:
      _y = math.asin(MathUtils.clamp(m13, -1, 1));

      if (m13.abs() < 0.9999999) {
        _x = math.atan2(-m23, m33);
        _z = math.atan2(-m12, m11);
      } else {
        _x = math.atan2(m32, m22);
        _z = 0;
      }

      break;

    case RotationOrders.yxz:
      _x = math.asin(-MathUtils.clamp(m23, -1, 1));

      if (m23.abs() < 0.9999999) {
        _y = math.atan2(m13, m33);
        _z = math.atan2(m21, m22);
      } else {
        _y = math.atan2(-m31, m11);
        _z = 0;
      }

      break;

    case RotationOrders.zxy:
      _x = math.asin(MathUtils.clamp(m32, -1, 1));

      if (m32.abs() < 0.9999999) {
        _y = math.atan2(-m31, m33);
        _z = math.atan2(-m12, m22);
      } else {
        _y = 0;
        _z = math.atan2(m21, m11);
      }

      break;

    case RotationOrders.zyx:
      _y = math.asin(-MathUtils.clamp(m31, -1, 1));

      if (m31.abs() < 0.9999999) {
        _x = math.atan2(m32, m33);
        _z = math.atan2(m21, m11);
      } else {
        _x = 0;
        _z = math.atan2(-m12, m22);
      }

      break;

    case RotationOrders.yzx:
      _z = math.asin(MathUtils.clamp(m21, -1, 1));

      if (m21.abs() < 0.9999999) {
        _x = math.atan2(-m23, m22);
        _y = math.atan2(-m31, m11);
      } else {
        _x = 0;
        _y = math.atan2(m13, m33);
      }

      break;

    case RotationOrders.xzy:
      _z = math.asin(-MathUtils.clamp(m12, -1, 1));

      if (m12.abs() < 0.9999999) {
        _x = math.atan2(m32, m22);
        _y = math.atan2(m13, m11);
      } else {
        _x = math.atan2(-m23, m33);
        _y = 0;
      }
      break;
  }

  _order = order;

  if (update != false) onChangeCallback();

  return this;
}