blob: 724a06195c50cc8a30de44965847948491b05e8d [file] [log] [blame]
// Copyright (c) 2015, Google Inc. Please see the AUTHORS file for details.
// All rights reserved. Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
part of vector_math_operations;
// ignore: avoid_classes_with_only_static_members
/// Static methods operating on 4x4 matrices packed column major into a
/// Float32List.
class Matrix44Operations {
/// Compute the determinant of the 4x4 [matrix] starting at [offset].
static double determinant(Float32List matrix, int offset) {
final m0 = matrix[0 + offset];
final m1 = matrix[1 + offset];
final m2 = matrix[2 + offset];
final m3 = matrix[3 + offset];
final m4 = matrix[4 + offset];
final m5 = matrix[5 + offset];
final m6 = matrix[6 + offset];
final m7 = matrix[7 + offset];
final det2_01_01 = m0 * m5 - m1 * m4;
final det2_01_02 = m0 * m6 - m2 * m4;
final det2_01_03 = m0 * m7 - m3 * m4;
final det2_01_12 = m1 * m6 - m2 * m5;
final det2_01_13 = m1 * m7 - m3 * m5;
final det2_01_23 = m2 * m7 - m3 * m6;
final m8 = matrix[8 + offset];
final m9 = matrix[9 + offset];
final m10 = matrix[10 + offset];
final m11 = matrix[11 + offset];
final det3_201_012 = m8 * det2_01_12 - m9 * det2_01_02 + m10 * det2_01_01;
final det3_201_013 = m8 * det2_01_13 - m9 * det2_01_03 + m11 * det2_01_01;
final det3_201_023 = m8 * det2_01_23 - m10 * det2_01_03 + m11 * det2_01_02;
final det3_201_123 = m9 * det2_01_23 - m10 * det2_01_13 + m11 * det2_01_12;
final m12 = matrix[12 + offset];
final m13 = matrix[13 + offset];
final m14 = matrix[14 + offset];
final m15 = matrix[15 + offset];
return -det3_201_123 * m12 +
det3_201_023 * m13 -
det3_201_013 * m14 +
det3_201_012 * m15;
}
/// Compute the determinant of the upper 3x3 of the 4x4 [matrix] starting at
/// [offset].
static double determinant33(Float32List matrix, int offset) {
final m0 = matrix[0 + offset];
final m1 = matrix[1 + offset];
final m2 = matrix[2 + offset];
final m4 = matrix[4 + offset];
final m5 = matrix[5 + offset];
final m6 = matrix[6 + offset];
final m8 = matrix[8 + offset];
final m9 = matrix[9 + offset];
final m10 = matrix[10 + offset];
final x = m0 * ((m5 * m10) - (m6 * m8));
final y = m1 * ((m4 * m10) - (m6 * m8));
final z = m2 * ((m4 * m9) - (m5 * m8));
return x - y + z;
}
/// Compute the inverse of the 4x4 [matrix] starting at [offset].
static double inverse(Float32List matrix, int offset) {
final a00 = matrix[0];
final a01 = matrix[1];
final a02 = matrix[2];
final a03 = matrix[3];
final a10 = matrix[4];
final a11 = matrix[5];
final a12 = matrix[6];
final a13 = matrix[7];
final a20 = matrix[8];
final a21 = matrix[9];
final a22 = matrix[10];
final a23 = matrix[11];
final a30 = matrix[12];
final a31 = matrix[13];
final a32 = matrix[14];
final a33 = matrix[15];
final b00 = a00 * a11 - a01 * a10;
final b01 = a00 * a12 - a02 * a10;
final b02 = a00 * a13 - a03 * a10;
final b03 = a01 * a12 - a02 * a11;
final b04 = a01 * a13 - a03 * a11;
final b05 = a02 * a13 - a03 * a12;
final b06 = a20 * a31 - a21 * a30;
final b07 = a20 * a32 - a22 * a30;
final b08 = a20 * a33 - a23 * a30;
final b09 = a21 * a32 - a22 * a31;
final b10 = a21 * a33 - a23 * a31;
final b11 = a22 * a33 - a23 * a32;
final det =
b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
if (det == 0.0) {
return det;
}
final invDet = 1.0 / det;
matrix[0] = (a11 * b11 - a12 * b10 + a13 * b09) * invDet;
matrix[1] = (-a01 * b11 + a02 * b10 - a03 * b09) * invDet;
matrix[2] = (a31 * b05 - a32 * b04 + a33 * b03) * invDet;
matrix[3] = (-a21 * b05 + a22 * b04 - a23 * b03) * invDet;
matrix[4] = (-a10 * b11 + a12 * b08 - a13 * b07) * invDet;
matrix[5] = (a00 * b11 - a02 * b08 + a03 * b07) * invDet;
matrix[6] = (-a30 * b05 + a32 * b02 - a33 * b01) * invDet;
matrix[7] = (a20 * b05 - a22 * b02 + a23 * b01) * invDet;
matrix[8] = (a10 * b10 - a11 * b08 + a13 * b06) * invDet;
matrix[9] = (-a00 * b10 + a01 * b08 - a03 * b06) * invDet;
matrix[10] = (a30 * b04 - a31 * b02 + a33 * b00) * invDet;
matrix[11] = (-a20 * b04 + a21 * b02 - a23 * b00) * invDet;
matrix[12] = (-a10 * b09 + a11 * b07 - a12 * b06) * invDet;
matrix[13] = (a00 * b09 - a01 * b07 + a02 * b06) * invDet;
matrix[14] = (-a30 * b03 + a31 * b01 - a32 * b00) * invDet;
matrix[15] = (a20 * b03 - a21 * b01 + a22 * b00) * invDet;
return det;
}
/// Compute the inverse of the upper 3x3 of the 4x4 [matrix] starting
/// at [offset].
static double inverse33(Float32List matrix, int offset) =>
throw UnimplementedError();
/// [out] = [a] * [b]; Starting at [outOffset], [aOffset], and [bOffset].
static void multiply(Float32List out, int outOffset, Float32List a,
int aOffset, Float32List b, int bOffset) {
final a00 = a[aOffset++];
final a01 = a[aOffset++];
final a02 = a[aOffset++];
final a03 = a[aOffset++];
final a10 = a[aOffset++];
final a11 = a[aOffset++];
final a12 = a[aOffset++];
final a13 = a[aOffset++];
final a20 = a[aOffset++];
final a21 = a[aOffset++];
final a22 = a[aOffset++];
final a23 = a[aOffset++];
final a30 = a[aOffset++];
final a31 = a[aOffset++];
final a32 = a[aOffset++];
final a33 = a[aOffset++];
var b0 = b[bOffset++];
var b1 = b[bOffset++];
var b2 = b[bOffset++];
var b3 = b[bOffset++];
out[outOffset++] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
out[outOffset++] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
out[outOffset++] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
out[outOffset++] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
b0 = b[bOffset++];
b1 = b[bOffset++];
b2 = b[bOffset++];
b3 = b[bOffset++];
out[outOffset++] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
out[outOffset++] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
out[outOffset++] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
out[outOffset++] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
b0 = b[bOffset++];
b1 = b[bOffset++];
b2 = b[bOffset++];
b3 = b[bOffset++];
out[outOffset++] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
out[outOffset++] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
out[outOffset++] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
out[outOffset++] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
b0 = b[bOffset++];
b1 = b[bOffset++];
b2 = b[bOffset++];
b3 = b[bOffset++];
out[outOffset++] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
out[outOffset++] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
out[outOffset++] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
out[outOffset++] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
}
/// Perform a 4x4 transformation matrix inverse. Assumes the upper
/// 3x3 is orthonormal (i.e. does not contain any scale).
static void orthoInverse(Float32List matrix, int offset) {}
/// Normalize the upper 3x3 of the 4x4 [matrix] starting at [offset].
static void normalize33(Float32List matrix, int offset) {}
/// Transform the 4D [vector] starting at [vectorOffset] by the 4x4 [matrix]
/// starting at [matrixOffset]. Store result in [out] starting at [outOffset].
static void transform4(Float32List out, int outOffset, Float32List matrix,
int matrixOffset, Float32List vector, int vectorOffset) {
final x = vector[vectorOffset++];
final y = vector[vectorOffset++];
final z = vector[vectorOffset++];
final w = vector[vectorOffset++];
final m0 = matrix[matrixOffset];
final m4 = matrix[4 + matrixOffset];
final m8 = matrix[8 + matrixOffset];
final m12 = matrix[12 + matrixOffset];
out[outOffset++] = m0 * x + m4 * y + m8 * z + m12 * w;
final m1 = matrix[1 + matrixOffset];
final m5 = matrix[5 + matrixOffset];
final m9 = matrix[9 + matrixOffset];
final m13 = matrix[13 + matrixOffset];
out[outOffset++] = m1 * x + m5 * y + m9 * z + m13 * w;
final m2 = matrix[2 + matrixOffset];
final m6 = matrix[6 + matrixOffset];
final m10 = matrix[10 + matrixOffset];
final m14 = matrix[14 + matrixOffset];
out[outOffset++] = m2 * x + m6 * y + m10 * z + m14 * w;
final m3 = matrix[3 + matrixOffset];
final m7 = matrix[7 + matrixOffset];
final m11 = matrix[11 + matrixOffset];
final m15 = matrix[15 + matrixOffset];
out[outOffset++] = m3 * x + m7 * y + m11 * z + m15 * w;
}
/// Transform the 3D [vector] starting at [vectorOffset] by the 4x4 [matrix]
/// starting at [matrixOffset]. Store result in [out] starting at [outOffset].
static void transform3(Float32List out, int outOffset, Float32List matrix,
int matrixOffset, Float32List vector, int vectorOffset) {}
/// Transpose the 4x4 [matrix] starting at [offset].
static void transpose(Float32List matrix, int offset) {}
/// Transpose the upper 3x3 of the 4x4 [matrix] starting at [offset].
static void transpose33(Float32List matrix, int offset) {}
static void zero(Float32List matrix, int offset) {
matrix[offset++] = 0.0;
matrix[offset++] = 0.0;
matrix[offset++] = 0.0;
matrix[offset++] = 0.0;
matrix[offset++] = 0.0;
matrix[offset++] = 0.0;
matrix[offset++] = 0.0;
matrix[offset++] = 0.0;
matrix[offset++] = 0.0;
matrix[offset++] = 0.0;
matrix[offset++] = 0.0;
matrix[offset++] = 0.0;
matrix[offset++] = 0.0;
matrix[offset++] = 0.0;
matrix[offset++] = 0.0;
matrix[offset++] = 0.0;
}
}
// ignore: avoid_classes_with_only_static_members
/// Static methods operating on 4x4 matrices packed column major into a
/// Float32x4List.
class Matrix44SIMDOperations {
/// [out] = [A] * [B]; Starting at [outOffset], [aOffset], and [bOffset].
static void multiply(Float32x4List out, int outOffset, Float32x4List A,
int aOffset, Float32x4List B, int bOffset) {
final a0 = A[aOffset++];
final a1 = A[aOffset++];
final a2 = A[aOffset++];
final a3 = A[aOffset++];
final b0 = B[bOffset++];
out[outOffset++] = b0.shuffle(Float32x4.xxxx) * a0 +
b0.shuffle(Float32x4.yyyy) * a1 +
b0.shuffle(Float32x4.zzzz) * a2 +
b0.shuffle(Float32x4.wwww) * a3;
final b1 = B[bOffset++];
out[outOffset++] = b1.shuffle(Float32x4.xxxx) * a0 +
b1.shuffle(Float32x4.yyyy) * a1 +
b1.shuffle(Float32x4.zzzz) * a2 +
b1.shuffle(Float32x4.wwww) * a3;
final b2 = B[bOffset++];
out[outOffset++] = b2.shuffle(Float32x4.xxxx) * a0 +
b2.shuffle(Float32x4.yyyy) * a1 +
b2.shuffle(Float32x4.zzzz) * a2 +
b2.shuffle(Float32x4.wwww) * a3;
final b3 = B[bOffset++];
out[outOffset++] = b3.shuffle(Float32x4.xxxx) * a0 +
b3.shuffle(Float32x4.yyyy) * a1 +
b3.shuffle(Float32x4.zzzz) * a2 +
b3.shuffle(Float32x4.wwww) * a3;
}
/// Transform the 4D [vector] starting at [vectorOffset] by the 4x4 [matrix]
/// starting at [matrixOffset]. Store result in [out] starting at [outOffset].
static void transform4(Float32x4List out, int outOffset, Float32x4List matrix,
int matrixOffset, Float32x4List vector, int vectorOffset) {
final v = vector[vectorOffset];
final xxxx = v.shuffle(Float32x4.xxxx);
var z = Float32x4.zero();
z += xxxx * matrix[0 + matrixOffset];
final yyyy = v.shuffle(Float32x4.yyyy);
z += yyyy * matrix[1 + matrixOffset];
final zzzz = v.shuffle(Float32x4.zzzz);
z += zzzz * matrix[2 + matrixOffset];
z += matrix[3 + matrixOffset];
out[0 + outOffset] = z;
}
static void zero(Float32x4List matrix, int offset) {
final z = Float32x4.zero();
matrix[offset++] = z;
matrix[offset++] = z;
matrix[offset++] = z;
matrix[offset++] = z;
}
}