compose3DMatrix static method

Matrix4 compose3DMatrix(
  1. dynamic translate,
  2. dynamic scale,
  3. dynamic skew,
  4. dynamic perspective,
  5. List<double> quaternion,
)

Implementation

static Matrix4 compose3DMatrix(translate, scale, skew, perspective, List<double> quaternion) {
  List<List<double>> matrix = [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]];

  // apply perspective
  for (var i = 0; i < 4; i++) {
    matrix[i][3] = perspective[i];
  }

  // apply translation
  for (var i = 0; i < 3; i++) {
    for (var j = 0; j < 3; j++) {
      matrix[3][i] += translate[j] * matrix[j][i];
    }
  }

  // apply rotation
  var x = quaternion[0];
  var y = quaternion[1];
  var z = quaternion[2];
  var w = quaternion[3];

  List<List<double>> rotationMatrix = [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]];

  // Construct a composite rotation matrix from the quaternion values
  // rotationMatrix is a identity 4x4 matrix initially
  rotationMatrix[0][0] = 1 - 2 * (y * y + z * z);
  rotationMatrix[0][1] = 2 * (x * y - z * w);
  rotationMatrix[0][2] = 2 * (x * z + y * w);
  rotationMatrix[1][0] = 2 * (x * y + z * w);
  rotationMatrix[1][1] = 1 - 2 * (x * x + z * z);
  rotationMatrix[1][2] = 2 * (y * z - x * w);
  rotationMatrix[2][0] = 2 * (x * z - y * w);
  rotationMatrix[2][1] = 2 * (y * z + x * w);
  rotationMatrix[2][2] = 1 - 2 * (x * x + y * y);

  matrix = _multiply(matrix, rotationMatrix);

  // apply skew
  // temp is a identity 4x4 matrix initially
  List<List<double>> temp = [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]];
  if (skew[2] != 0) {
    temp[2][1] = skew[2];
    matrix = _multiply(matrix, temp);
  }

  if (skew[1] != 0) {
    temp[2][1] = 0;
    temp[2][0] = skew[0];
    matrix = _multiply(matrix, temp);
  }

  if (skew[0] != 0) {
    temp[2][0] = 0;
    temp[1][0] = skew[0];
    matrix = _multiply(matrix, temp);
  }

  // apply scale
  for (var i = 0; i < 3; i++) {
    for (var j = 0; j < 3; j++) {
      matrix[i][j] *= scale[i];
    }
  }

  return Matrix4.columns(
    Vector4.array(matrix[0]),
    Vector4.array(matrix[1]),
    Vector4.array(matrix[2]),
    Vector4.array(matrix[3])
  );
}