• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

google / vector_math.dart / 12224890780

08 Dec 2024 08:11PM UTC coverage: 26.372%. Remained the same
12224890780

Pull #337

github

web-flow
Merge 1b1108c78 into 433fb6c82
Pull Request #337: Partial fix for benchmarks.

4325 of 16400 relevant lines covered (26.37%)

1.2 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/lib/src/vector_math_64/matrix4.dart
1
// Copyright (c) 2015, Google Inc. Please see the AUTHORS file for details.
2
// All rights reserved. Use of this source code is governed by a BSD-style
3
// license that can be found in the LICENSE file.
4

5
part of '../../vector_math_64.dart';
6

7
/// 4D Matrix.
8
/// Values are stored in column major order.
9
class Matrix4 {
10
  final Float64List _m4storage;
11

12
  /// The components of the matrix.
13
  Float64List get storage => _m4storage;
×
14

15
  /// Solve [A] * [x] = [b].
16
  static void solve2(Matrix4 A, Vector2 x, Vector2 b) {
×
17
    final a11 = A.entry(0, 0);
×
18
    final a12 = A.entry(0, 1);
×
19
    final a21 = A.entry(1, 0);
×
20
    final a22 = A.entry(1, 1);
×
21
    final bx = b.x - A._m4storage[8];
×
22
    final by = b.y - A._m4storage[9];
×
23
    var det = a11 * a22 - a12 * a21;
×
24

25
    if (det != 0.0) {
×
26
      det = 1.0 / det;
×
27
    }
28

29
    x
30
      ..x = det * (a22 * bx - a12 * by)
×
31
      ..y = det * (a11 * by - a21 * bx);
×
32
  }
33

34
  /// Solve [A] * [x] = [b].
35
  static void solve3(Matrix4 A, Vector3 x, Vector3 b) {
×
36
    final A0x = A.entry(0, 0);
×
37
    final A0y = A.entry(1, 0);
×
38
    final A0z = A.entry(2, 0);
×
39
    final A1x = A.entry(0, 1);
×
40
    final A1y = A.entry(1, 1);
×
41
    final A1z = A.entry(2, 1);
×
42
    final A2x = A.entry(0, 2);
×
43
    final A2y = A.entry(1, 2);
×
44
    final A2z = A.entry(2, 2);
×
45
    final bx = b.x - A._m4storage[12];
×
46
    final by = b.y - A._m4storage[13];
×
47
    final bz = b.z - A._m4storage[14];
×
48
    double rx, ry, rz;
49
    double det;
50

51
    // Column1 cross Column 2
52
    rx = A1y * A2z - A1z * A2y;
×
53
    ry = A1z * A2x - A1x * A2z;
×
54
    rz = A1x * A2y - A1y * A2x;
×
55

56
    // A.getColumn(0).dot(x)
57
    det = A0x * rx + A0y * ry + A0z * rz;
×
58
    if (det != 0.0) {
×
59
      det = 1.0 / det;
×
60
    }
61

62
    // b dot [Column1 cross Column 2]
63
    final x_ = det * (bx * rx + by * ry + bz * rz);
×
64

65
    // Column2 cross b
66
    rx = -(A2y * bz - A2z * by);
×
67
    ry = -(A2z * bx - A2x * bz);
×
68
    rz = -(A2x * by - A2y * bx);
×
69
    // Column0 dot -[Column2 cross b (Column3)]
70
    final y_ = det * (A0x * rx + A0y * ry + A0z * rz);
×
71

72
    // b cross Column 1
73
    rx = -(by * A1z - bz * A1y);
×
74
    ry = -(bz * A1x - bx * A1z);
×
75
    rz = -(bx * A1y - by * A1x);
×
76
    // Column0 dot -[b cross Column 1]
77
    final z_ = det * (A0x * rx + A0y * ry + A0z * rz);
×
78

79
    x
80
      ..x = x_
×
81
      ..y = y_
×
82
      ..z = z_;
×
83
  }
84

85
  /// Solve [A] * [x] = [b].
86
  static void solve(Matrix4 A, Vector4 x, Vector4 b) {
×
87
    final a00 = A._m4storage[0];
×
88
    final a01 = A._m4storage[1];
×
89
    final a02 = A._m4storage[2];
×
90
    final a03 = A._m4storage[3];
×
91
    final a10 = A._m4storage[4];
×
92
    final a11 = A._m4storage[5];
×
93
    final a12 = A._m4storage[6];
×
94
    final a13 = A._m4storage[7];
×
95
    final a20 = A._m4storage[8];
×
96
    final a21 = A._m4storage[9];
×
97
    final a22 = A._m4storage[10];
×
98
    final a23 = A._m4storage[11];
×
99
    final a30 = A._m4storage[12];
×
100
    final a31 = A._m4storage[13];
×
101
    final a32 = A._m4storage[14];
×
102
    final a33 = A._m4storage[15];
×
103
    final b00 = a00 * a11 - a01 * a10;
×
104
    final b01 = a00 * a12 - a02 * a10;
×
105
    final b02 = a00 * a13 - a03 * a10;
×
106
    final b03 = a01 * a12 - a02 * a11;
×
107
    final b04 = a01 * a13 - a03 * a11;
×
108
    final b05 = a02 * a13 - a03 * a12;
×
109
    final b06 = a20 * a31 - a21 * a30;
×
110
    final b07 = a20 * a32 - a22 * a30;
×
111
    final b08 = a20 * a33 - a23 * a30;
×
112
    final b09 = a21 * a32 - a22 * a31;
×
113
    final b10 = a21 * a33 - a23 * a31;
×
114
    final b11 = a22 * a33 - a23 * a32;
×
115

116
    final bX = b.storage[0];
×
117
    final bY = b.storage[1];
×
118
    final bZ = b.storage[2];
×
119
    final bW = b.storage[3];
×
120

121
    var det =
122
        b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
×
123

124
    if (det != 0.0) {
×
125
      det = 1.0 / det;
×
126
    }
127

128
    x
129
      ..x = det *
×
130
          ((a11 * b11 - a12 * b10 + a13 * b09) * bX -
×
131
              (a10 * b11 - a12 * b08 + a13 * b07) * bY +
×
132
              (a10 * b10 - a11 * b08 + a13 * b06) * bZ -
×
133
              (a10 * b09 - a11 * b07 + a12 * b06) * bW)
×
134
      ..y = det *
×
135
          -((a01 * b11 - a02 * b10 + a03 * b09) * bX -
×
136
              (a00 * b11 - a02 * b08 + a03 * b07) * bY +
×
137
              (a00 * b10 - a01 * b08 + a03 * b06) * bZ -
×
138
              (a00 * b09 - a01 * b07 + a02 * b06) * bW)
×
139
      ..z = det *
×
140
          ((a31 * b05 - a32 * b04 + a33 * b03) * bX -
×
141
              (a30 * b05 - a32 * b02 + a33 * b01) * bY +
×
142
              (a30 * b04 - a31 * b02 + a33 * b00) * bZ -
×
143
              (a30 * b03 - a31 * b01 + a32 * b00) * bW)
×
144
      ..w = det *
×
145
          -((a21 * b05 - a22 * b04 + a23 * b03) * bX -
×
146
              (a20 * b05 - a22 * b02 + a23 * b01) * bY +
×
147
              (a20 * b04 - a21 * b02 + a23 * b00) * bZ -
×
148
              (a20 * b03 - a21 * b01 + a22 * b00) * bW);
×
149
  }
150

151
  /// Returns a matrix that is the inverse of [other] if [other] is invertible,
152
  /// otherwise `null`.
153
  static Matrix4? tryInvert(Matrix4 other) {
×
154
    final r = Matrix4.zero();
×
155
    final determinant = r.copyInverse(other);
×
156
    if (determinant == 0.0) {
×
157
      return null;
158
    }
159
    return r;
160
  }
161

162
  /// Return index in storage for [row], [col] value.
163
  int index(int row, int col) => (col * 4) + row;
×
164

165
  /// Value at [row], [col].
166
  double entry(int row, int col) {
×
167
    assert((row >= 0) && (row < dimension));
×
168
    assert((col >= 0) && (col < dimension));
×
169

170
    return _m4storage[index(row, col)];
×
171
  }
172

173
  /// Set value at [row], [col] to be [v].
174
  void setEntry(int row, int col, double v) {
×
175
    assert((row >= 0) && (row < dimension));
×
176
    assert((col >= 0) && (col < dimension));
×
177

178
    _m4storage[index(row, col)] = v;
×
179
  }
180

181
  /// Constructs a new mat4.
182
  factory Matrix4(
×
183
          double arg0,
184
          double arg1,
185
          double arg2,
186
          double arg3,
187
          double arg4,
188
          double arg5,
189
          double arg6,
190
          double arg7,
191
          double arg8,
192
          double arg9,
193
          double arg10,
194
          double arg11,
195
          double arg12,
196
          double arg13,
197
          double arg14,
198
          double arg15) =>
199
      Matrix4.zero()
×
200
        ..setValues(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9,
×
201
            arg10, arg11, arg12, arg13, arg14, arg15);
202

203
  /// New matrix from [values].
204
  factory Matrix4.fromList(List<double> values) => Matrix4.zero()
×
205
    ..setValues(
×
206
        values[0],
×
207
        values[1],
×
208
        values[2],
×
209
        values[3],
×
210
        values[4],
×
211
        values[5],
×
212
        values[6],
×
213
        values[7],
×
214
        values[8],
×
215
        values[9],
×
216
        values[10],
×
217
        values[11],
×
218
        values[12],
×
219
        values[13],
×
220
        values[14],
×
221
        values[15]);
×
222

223
  /// Zero matrix.
224
  Matrix4.zero() : _m4storage = Float64List(16);
×
225

226
  /// Identity matrix.
227
  factory Matrix4.identity() => Matrix4.zero()..setIdentity();
×
228

229
  /// Copies values from [other].
230
  factory Matrix4.copy(Matrix4 other) => Matrix4.zero()..setFrom(other);
×
231

232
  /// Constructs a matrix that is the inverse of [other].
233
  factory Matrix4.inverted(Matrix4 other) {
×
234
    final r = Matrix4.zero();
×
235
    final determinant = r.copyInverse(other);
×
236
    if (determinant == 0.0) {
×
237
      throw ArgumentError.value(other, 'other', 'Matrix cannot be inverted');
×
238
    }
239
    return r;
240
  }
241

242
  /// Constructs a new mat4 from columns.
243
  factory Matrix4.columns(
×
244
          Vector4 arg0, Vector4 arg1, Vector4 arg2, Vector4 arg3) =>
245
      Matrix4.zero()..setColumns(arg0, arg1, arg2, arg3);
×
246

247
  /// Outer product of [u] and [v].
248
  factory Matrix4.outer(Vector4 u, Vector4 v) => Matrix4.zero()..setOuter(u, v);
×
249

250
  /// Rotation of [radians] around X.
251
  factory Matrix4.rotationX(double radians) => Matrix4.zero()
×
252
    .._m4storage[15] = 1.0
×
253
    ..setRotationX(radians);
×
254

255
  /// Rotation of [radians] around Y.
256
  factory Matrix4.rotationY(double radians) => Matrix4.zero()
×
257
    .._m4storage[15] = 1.0
×
258
    ..setRotationY(radians);
×
259

260
  /// Rotation of [radians] around Z.
261
  factory Matrix4.rotationZ(double radians) => Matrix4.zero()
×
262
    .._m4storage[15] = 1.0
×
263
    ..setRotationZ(radians);
×
264

265
  /// Translation matrix.
266
  factory Matrix4.translation(Vector3 translation) => Matrix4.zero()
×
267
    ..setIdentity()
×
268
    ..setTranslation(translation);
×
269

270
  /// Translation matrix.
271
  factory Matrix4.translationValues(double x, double y, double z) =>
×
272
      Matrix4.zero()
×
273
        ..setIdentity()
×
274
        ..setTranslationRaw(x, y, z);
×
275

276
  /// Scale matrix.
277
  factory Matrix4.diagonal3(Vector3 scale) {
×
278
    final m = Matrix4.zero();
×
279
    final mStorage = m._m4storage;
×
280
    final scaleStorage = scale._v3storage;
×
281
    mStorage[15] = 1.0;
×
282
    mStorage[10] = scaleStorage[2];
×
283
    mStorage[5] = scaleStorage[1];
×
284
    mStorage[0] = scaleStorage[0];
×
285
    return m;
286
  }
287

288
  /// Scale matrix.
289
  factory Matrix4.diagonal3Values(double x, double y, double z) =>
×
290
      Matrix4.zero()
×
291
        .._m4storage[15] = 1.0
×
292
        .._m4storage[10] = z
×
293
        .._m4storage[5] = y
×
294
        .._m4storage[0] = x;
×
295

296
  /// Skew matrix around X axis
297
  factory Matrix4.skewX(double alpha) {
×
298
    final m = Matrix4.identity();
×
299
    m._m4storage[4] = math.tan(alpha);
×
300
    return m;
301
  }
302

303
  /// Skew matrix around Y axis.
304
  factory Matrix4.skewY(double beta) {
×
305
    final m = Matrix4.identity();
×
306
    m._m4storage[1] = math.tan(beta);
×
307
    return m;
308
  }
309

310
  /// Skew matrix around X axis (alpha) and Y axis (beta).
311
  factory Matrix4.skew(double alpha, double beta) {
×
312
    final m = Matrix4.identity();
×
313
    m._m4storage[1] = math.tan(beta);
×
314
    m._m4storage[4] = math.tan(alpha);
×
315
    return m;
316
  }
317

318
  /// Constructs Matrix4 with given [Float64List] as [storage].
319
  Matrix4.fromFloat64List(this._m4storage);
×
320

321
  /// Constructs Matrix4 with a [storage] that views given [buffer] starting at
322
  /// [offset]. [offset] has to be multiple of [Float64List.bytesPerElement].
323
  Matrix4.fromBuffer(ByteBuffer buffer, int offset)
×
324
      : _m4storage = Float64List.view(buffer, offset, 16);
×
325

326
  /// Constructs Matrix4 from [translation], [rotation] and [scale].
327
  factory Matrix4.compose(
×
328
          Vector3 translation, Quaternion rotation, Vector3 scale) =>
329
      Matrix4.zero()
×
330
        ..setFromTranslationRotationScale(translation, rotation, scale);
×
331

332
  /// Sets the diagonal to [arg].
333
  void splatDiagonal(double arg) {
×
334
    _m4storage[0] = arg;
×
335
    _m4storage[5] = arg;
×
336
    _m4storage[10] = arg;
×
337
    _m4storage[15] = arg;
×
338
  }
339

340
  /// Sets the matrix with specified values.
341
  void setValues(
×
342
      double arg0,
343
      double arg1,
344
      double arg2,
345
      double arg3,
346
      double arg4,
347
      double arg5,
348
      double arg6,
349
      double arg7,
350
      double arg8,
351
      double arg9,
352
      double arg10,
353
      double arg11,
354
      double arg12,
355
      double arg13,
356
      double arg14,
357
      double arg15) {
358
    _m4storage[15] = arg15;
×
359
    _m4storage[14] = arg14;
×
360
    _m4storage[13] = arg13;
×
361
    _m4storage[12] = arg12;
×
362
    _m4storage[11] = arg11;
×
363
    _m4storage[10] = arg10;
×
364
    _m4storage[9] = arg9;
×
365
    _m4storage[8] = arg8;
×
366
    _m4storage[7] = arg7;
×
367
    _m4storage[6] = arg6;
×
368
    _m4storage[5] = arg5;
×
369
    _m4storage[4] = arg4;
×
370
    _m4storage[3] = arg3;
×
371
    _m4storage[2] = arg2;
×
372
    _m4storage[1] = arg1;
×
373
    _m4storage[0] = arg0;
×
374
  }
375

376
  /// Sets the entire matrix to the column values.
377
  void setColumns(Vector4 arg0, Vector4 arg1, Vector4 arg2, Vector4 arg3) {
×
378
    final arg0Storage = arg0._v4storage;
×
379
    final arg1Storage = arg1._v4storage;
×
380
    final arg2Storage = arg2._v4storage;
×
381
    final arg3Storage = arg3._v4storage;
×
382
    _m4storage[0] = arg0Storage[0];
×
383
    _m4storage[1] = arg0Storage[1];
×
384
    _m4storage[2] = arg0Storage[2];
×
385
    _m4storage[3] = arg0Storage[3];
×
386
    _m4storage[4] = arg1Storage[0];
×
387
    _m4storage[5] = arg1Storage[1];
×
388
    _m4storage[6] = arg1Storage[2];
×
389
    _m4storage[7] = arg1Storage[3];
×
390
    _m4storage[8] = arg2Storage[0];
×
391
    _m4storage[9] = arg2Storage[1];
×
392
    _m4storage[10] = arg2Storage[2];
×
393
    _m4storage[11] = arg2Storage[3];
×
394
    _m4storage[12] = arg3Storage[0];
×
395
    _m4storage[13] = arg3Storage[1];
×
396
    _m4storage[14] = arg3Storage[2];
×
397
    _m4storage[15] = arg3Storage[3];
×
398
  }
399

400
  /// Sets the entire matrix to the matrix in [arg].
401
  void setFrom(Matrix4 arg) {
×
402
    final argStorage = arg._m4storage;
×
403
    _m4storage[15] = argStorage[15];
×
404
    _m4storage[14] = argStorage[14];
×
405
    _m4storage[13] = argStorage[13];
×
406
    _m4storage[12] = argStorage[12];
×
407
    _m4storage[11] = argStorage[11];
×
408
    _m4storage[10] = argStorage[10];
×
409
    _m4storage[9] = argStorage[9];
×
410
    _m4storage[8] = argStorage[8];
×
411
    _m4storage[7] = argStorage[7];
×
412
    _m4storage[6] = argStorage[6];
×
413
    _m4storage[5] = argStorage[5];
×
414
    _m4storage[4] = argStorage[4];
×
415
    _m4storage[3] = argStorage[3];
×
416
    _m4storage[2] = argStorage[2];
×
417
    _m4storage[1] = argStorage[1];
×
418
    _m4storage[0] = argStorage[0];
×
419
  }
420

421
  /// Sets the matrix from translation [arg0] and rotation [arg1].
422
  void setFromTranslationRotation(Vector3 arg0, Quaternion arg1) {
×
423
    final arg1Storage = arg1._qStorage;
×
424
    final x = arg1Storage[0];
×
425
    final y = arg1Storage[1];
×
426
    final z = arg1Storage[2];
×
427
    final w = arg1Storage[3];
×
428
    final x2 = x + x;
×
429
    final y2 = y + y;
×
430
    final z2 = z + z;
×
431
    final xx = x * x2;
×
432
    final xy = x * y2;
×
433
    final xz = x * z2;
×
434
    final yy = y * y2;
×
435
    final yz = y * z2;
×
436
    final zz = z * z2;
×
437
    final wx = w * x2;
×
438
    final wy = w * y2;
×
439
    final wz = w * z2;
×
440

441
    final arg0Storage = arg0._v3storage;
×
442
    _m4storage[0] = 1.0 - (yy + zz);
×
443
    _m4storage[1] = xy + wz;
×
444
    _m4storage[2] = xz - wy;
×
445
    _m4storage[3] = 0.0;
×
446
    _m4storage[4] = xy - wz;
×
447
    _m4storage[5] = 1.0 - (xx + zz);
×
448
    _m4storage[6] = yz + wx;
×
449
    _m4storage[7] = 0.0;
×
450
    _m4storage[8] = xz + wy;
×
451
    _m4storage[9] = yz - wx;
×
452
    _m4storage[10] = 1.0 - (xx + yy);
×
453
    _m4storage[11] = 0.0;
×
454
    _m4storage[12] = arg0Storage[0];
×
455
    _m4storage[13] = arg0Storage[1];
×
456
    _m4storage[14] = arg0Storage[2];
×
457
    _m4storage[15] = 1.0;
×
458
  }
459

460
  /// Sets the matrix from [translation], [rotation] and [scale].
461
  void setFromTranslationRotationScale(
×
462
      Vector3 translation, Quaternion rotation, Vector3 scale) {
463
    setFromTranslationRotation(translation, rotation);
×
464
    this.scale(scale);
×
465
  }
466

467
  /// Sets the upper 2x2 of the matrix to be [arg].
468
  void setUpper2x2(Matrix2 arg) {
×
469
    final argStorage = arg._m2storage;
×
470
    _m4storage[0] = argStorage[0];
×
471
    _m4storage[1] = argStorage[1];
×
472
    _m4storage[4] = argStorage[2];
×
473
    _m4storage[5] = argStorage[3];
×
474
  }
475

476
  /// Sets the diagonal of the matrix to be [arg].
477
  void setDiagonal(Vector4 arg) {
×
478
    final argStorage = arg._v4storage;
×
479
    _m4storage[0] = argStorage[0];
×
480
    _m4storage[5] = argStorage[1];
×
481
    _m4storage[10] = argStorage[2];
×
482
    _m4storage[15] = argStorage[3];
×
483
  }
484

485
  void setOuter(Vector4 u, Vector4 v) {
×
486
    final uStorage = u._v4storage;
×
487
    final vStorage = v._v4storage;
×
488
    _m4storage[0] = uStorage[0] * vStorage[0];
×
489
    _m4storage[1] = uStorage[0] * vStorage[1];
×
490
    _m4storage[2] = uStorage[0] * vStorage[2];
×
491
    _m4storage[3] = uStorage[0] * vStorage[3];
×
492
    _m4storage[4] = uStorage[1] * vStorage[0];
×
493
    _m4storage[5] = uStorage[1] * vStorage[1];
×
494
    _m4storage[6] = uStorage[1] * vStorage[2];
×
495
    _m4storage[7] = uStorage[1] * vStorage[3];
×
496
    _m4storage[8] = uStorage[2] * vStorage[0];
×
497
    _m4storage[9] = uStorage[2] * vStorage[1];
×
498
    _m4storage[10] = uStorage[2] * vStorage[2];
×
499
    _m4storage[11] = uStorage[2] * vStorage[3];
×
500
    _m4storage[12] = uStorage[3] * vStorage[0];
×
501
    _m4storage[13] = uStorage[3] * vStorage[1];
×
502
    _m4storage[14] = uStorage[3] * vStorage[2];
×
503
    _m4storage[15] = uStorage[3] * vStorage[3];
×
504
  }
505

506
  /// Returns a printable string
507
  @override
×
508
  String toString() => '[0] ${getRow(0)}\n[1] ${getRow(1)}\n'
×
509
      '[2] ${getRow(2)}\n[3] ${getRow(3)}\n';
×
510

511
  /// Dimension of the matrix.
512
  int get dimension => 4;
×
513

514
  /// Access the element of the matrix at the index [i].
515
  double operator [](int i) => _m4storage[i];
×
516

517
  /// Set the element of the matrix at the index [i].
518
  void operator []=(int i, double v) {
×
519
    _m4storage[i] = v;
×
520
  }
521

522
  /// Check if two matrices are the same.
523
  @override
×
524
  bool operator ==(Object other) =>
525
      (other is Matrix4) &&
×
526
      (_m4storage[0] == other._m4storage[0]) &&
×
527
      (_m4storage[1] == other._m4storage[1]) &&
×
528
      (_m4storage[2] == other._m4storage[2]) &&
×
529
      (_m4storage[3] == other._m4storage[3]) &&
×
530
      (_m4storage[4] == other._m4storage[4]) &&
×
531
      (_m4storage[5] == other._m4storage[5]) &&
×
532
      (_m4storage[6] == other._m4storage[6]) &&
×
533
      (_m4storage[7] == other._m4storage[7]) &&
×
534
      (_m4storage[8] == other._m4storage[8]) &&
×
535
      (_m4storage[9] == other._m4storage[9]) &&
×
536
      (_m4storage[10] == other._m4storage[10]) &&
×
537
      (_m4storage[11] == other._m4storage[11]) &&
×
538
      (_m4storage[12] == other._m4storage[12]) &&
×
539
      (_m4storage[13] == other._m4storage[13]) &&
×
540
      (_m4storage[14] == other._m4storage[14]) &&
×
541
      (_m4storage[15] == other._m4storage[15]);
×
542

543
  @override
×
544
  int get hashCode => Object.hashAll(_m4storage);
×
545

546
  /// Returns row 0
547
  Vector4 get row0 => getRow(0);
×
548

549
  /// Returns row 1
550
  Vector4 get row1 => getRow(1);
×
551

552
  /// Returns row 2
553
  Vector4 get row2 => getRow(2);
×
554

555
  /// Returns row 3
556
  Vector4 get row3 => getRow(3);
×
557

558
  /// Sets row 0 to [arg]
559
  set row0(Vector4 arg) => setRow(0, arg);
×
560

561
  /// Sets row 1 to [arg]
562
  set row1(Vector4 arg) => setRow(1, arg);
×
563

564
  /// Sets row 2 to [arg]
565
  set row2(Vector4 arg) => setRow(2, arg);
×
566

567
  /// Sets row 3 to [arg]
568
  set row3(Vector4 arg) => setRow(3, arg);
×
569

570
  /// Assigns the [row] of the matrix [arg]
571
  void setRow(int row, Vector4 arg) {
×
572
    final argStorage = arg._v4storage;
×
573
    _m4storage[index(row, 0)] = argStorage[0];
×
574
    _m4storage[index(row, 1)] = argStorage[1];
×
575
    _m4storage[index(row, 2)] = argStorage[2];
×
576
    _m4storage[index(row, 3)] = argStorage[3];
×
577
  }
578

579
  /// Gets the [row] of the matrix
580
  Vector4 getRow(int row) {
×
581
    final r = Vector4.zero();
×
582
    final rStorage = r._v4storage;
×
583
    rStorage[0] = _m4storage[index(row, 0)];
×
584
    rStorage[1] = _m4storage[index(row, 1)];
×
585
    rStorage[2] = _m4storage[index(row, 2)];
×
586
    rStorage[3] = _m4storage[index(row, 3)];
×
587
    return r;
588
  }
589

590
  /// Assigns the [column] of the matrix [arg]
591
  void setColumn(int column, Vector4 arg) {
×
592
    final entry = column * 4;
×
593
    final argStorage = arg._v4storage;
×
594
    _m4storage[entry + 3] = argStorage[3];
×
595
    _m4storage[entry + 2] = argStorage[2];
×
596
    _m4storage[entry + 1] = argStorage[1];
×
597
    _m4storage[entry + 0] = argStorage[0];
×
598
  }
599

600
  /// Gets the [column] of the matrix
601
  Vector4 getColumn(int column) {
×
602
    final r = Vector4.zero();
×
603
    final rStorage = r._v4storage;
×
604
    final entry = column * 4;
×
605
    rStorage[3] = _m4storage[entry + 3];
×
606
    rStorage[2] = _m4storage[entry + 2];
×
607
    rStorage[1] = _m4storage[entry + 1];
×
608
    rStorage[0] = _m4storage[entry + 0];
×
609
    return r;
610
  }
611

612
  /// Clone matrix.
613
  Matrix4 clone() => Matrix4.copy(this);
×
614

615
  /// Copy into [arg].
616
  Matrix4 copyInto(Matrix4 arg) {
×
617
    final argStorage = arg._m4storage;
×
618
    argStorage[0] = _m4storage[0];
×
619
    argStorage[1] = _m4storage[1];
×
620
    argStorage[2] = _m4storage[2];
×
621
    argStorage[3] = _m4storage[3];
×
622
    argStorage[4] = _m4storage[4];
×
623
    argStorage[5] = _m4storage[5];
×
624
    argStorage[6] = _m4storage[6];
×
625
    argStorage[7] = _m4storage[7];
×
626
    argStorage[8] = _m4storage[8];
×
627
    argStorage[9] = _m4storage[9];
×
628
    argStorage[10] = _m4storage[10];
×
629
    argStorage[11] = _m4storage[11];
×
630
    argStorage[12] = _m4storage[12];
×
631
    argStorage[13] = _m4storage[13];
×
632
    argStorage[14] = _m4storage[14];
×
633
    argStorage[15] = _m4storage[15];
×
634
    return arg;
635
  }
636

637
  /// Returns new matrix -this
638
  Matrix4 operator -() => clone()..negate();
×
639

640
  /// Returns a new vector or matrix by multiplying this with [arg].
641
  dynamic operator *(dynamic arg) {
×
642
    if (arg is double) {
×
643
      return scaled(arg);
×
644
    }
645
    if (arg is Vector4) {
×
646
      return transformed(arg);
×
647
    }
648
    if (arg is Vector3) {
×
649
      return transformed3(arg);
×
650
    }
651
    if (arg is Matrix4) {
×
652
      return multiplied(arg);
×
653
    }
654
    throw ArgumentError(arg);
×
655
  }
656

657
  /// Returns new matrix after component wise this + [arg]
658
  Matrix4 operator +(Matrix4 arg) => clone()..add(arg);
×
659

660
  /// Returns new matrix after component wise this - [arg]
661
  Matrix4 operator -(Matrix4 arg) => clone()..sub(arg);
×
662

663
  /// Translate this matrix by a [Vector3], [Vector4], or x,y,z
664
  void translate(dynamic x, [double y = 0.0, double z = 0.0]) {
×
665
    double tx;
666
    double ty;
667
    double tz;
668
    final tw = x is Vector4 ? x.w : 1.0;
×
669
    if (x is Vector3) {
×
670
      tx = x.x;
×
671
      ty = x.y;
×
672
      tz = x.z;
×
673
    } else if (x is Vector4) {
×
674
      tx = x.x;
×
675
      ty = x.y;
×
676
      tz = x.z;
×
677
    } else if (x is double) {
×
678
      tx = x;
679
      ty = y;
680
      tz = z;
681
    } else {
682
      throw UnimplementedError();
×
683
    }
684
    final t1 = _m4storage[0] * tx +
×
685
        _m4storage[4] * ty +
×
686
        _m4storage[8] * tz +
×
687
        _m4storage[12] * tw;
×
688
    final t2 = _m4storage[1] * tx +
×
689
        _m4storage[5] * ty +
×
690
        _m4storage[9] * tz +
×
691
        _m4storage[13] * tw;
×
692
    final t3 = _m4storage[2] * tx +
×
693
        _m4storage[6] * ty +
×
694
        _m4storage[10] * tz +
×
695
        _m4storage[14] * tw;
×
696
    final t4 = _m4storage[3] * tx +
×
697
        _m4storage[7] * ty +
×
698
        _m4storage[11] * tz +
×
699
        _m4storage[15] * tw;
×
700
    _m4storage[12] = t1;
×
701
    _m4storage[13] = t2;
×
702
    _m4storage[14] = t3;
×
703
    _m4storage[15] = t4;
×
704
  }
705

706
  /// Multiply this by a translation from the left.
707
  /// The translation can be specified with a  [Vector3], [Vector4], or x, y, z.
708
  void leftTranslate(dynamic x, [double y = 0.0, double z = 0.0]) {
×
709
    double tx;
710
    double ty;
711
    double tz;
712
    final tw = x is Vector4 ? x.w : 1.0;
×
713
    if (x is Vector3) {
×
714
      tx = x.x;
×
715
      ty = x.y;
×
716
      tz = x.z;
×
717
    } else if (x is Vector4) {
×
718
      tx = x.x;
×
719
      ty = x.y;
×
720
      tz = x.z;
×
721
    } else if (x is double) {
×
722
      tx = x;
723
      ty = y;
724
      tz = z;
725
    } else {
726
      throw UnimplementedError();
×
727
    }
728

729
    // Column 1
730
    _m4storage[0] += tx * _m4storage[3];
×
731
    _m4storage[1] += ty * _m4storage[3];
×
732
    _m4storage[2] += tz * _m4storage[3];
×
733
    _m4storage[3] = tw * _m4storage[3];
×
734

735
    // Column 2
736
    _m4storage[4] += tx * _m4storage[7];
×
737
    _m4storage[5] += ty * _m4storage[7];
×
738
    _m4storage[6] += tz * _m4storage[7];
×
739
    _m4storage[7] = tw * _m4storage[7];
×
740

741
    // Column 3
742
    _m4storage[8] += tx * _m4storage[11];
×
743
    _m4storage[9] += ty * _m4storage[11];
×
744
    _m4storage[10] += tz * _m4storage[11];
×
745
    _m4storage[11] = tw * _m4storage[11];
×
746

747
    // Column 4
748
    _m4storage[12] += tx * _m4storage[15];
×
749
    _m4storage[13] += ty * _m4storage[15];
×
750
    _m4storage[14] += tz * _m4storage[15];
×
751
    _m4storage[15] = tw * _m4storage[15];
×
752
  }
753

754
  /// Rotate this [angle] radians around [axis]
755
  void rotate(Vector3 axis, double angle) {
×
756
    final len = axis.length;
×
757
    final axisStorage = axis._v3storage;
×
758
    final x = axisStorage[0] / len;
×
759
    final y = axisStorage[1] / len;
×
760
    final z = axisStorage[2] / len;
×
761
    final c = math.cos(angle);
×
762
    final s = math.sin(angle);
×
763
    final C = 1.0 - c;
×
764
    final m11 = x * x * C + c;
×
765
    final m12 = x * y * C - z * s;
×
766
    final m13 = x * z * C + y * s;
×
767
    final m21 = y * x * C + z * s;
×
768
    final m22 = y * y * C + c;
×
769
    final m23 = y * z * C - x * s;
×
770
    final m31 = z * x * C - y * s;
×
771
    final m32 = z * y * C + x * s;
×
772
    final m33 = z * z * C + c;
×
773
    final t1 = _m4storage[0] * m11 + _m4storage[4] * m21 + _m4storage[8] * m31;
×
774
    final t2 = _m4storage[1] * m11 + _m4storage[5] * m21 + _m4storage[9] * m31;
×
775
    final t3 = _m4storage[2] * m11 + _m4storage[6] * m21 + _m4storage[10] * m31;
×
776
    final t4 = _m4storage[3] * m11 + _m4storage[7] * m21 + _m4storage[11] * m31;
×
777
    final t5 = _m4storage[0] * m12 + _m4storage[4] * m22 + _m4storage[8] * m32;
×
778
    final t6 = _m4storage[1] * m12 + _m4storage[5] * m22 + _m4storage[9] * m32;
×
779
    final t7 = _m4storage[2] * m12 + _m4storage[6] * m22 + _m4storage[10] * m32;
×
780
    final t8 = _m4storage[3] * m12 + _m4storage[7] * m22 + _m4storage[11] * m32;
×
781
    final t9 = _m4storage[0] * m13 + _m4storage[4] * m23 + _m4storage[8] * m33;
×
782
    final t10 = _m4storage[1] * m13 + _m4storage[5] * m23 + _m4storage[9] * m33;
×
783
    final t11 =
784
        _m4storage[2] * m13 + _m4storage[6] * m23 + _m4storage[10] * m33;
×
785
    final t12 =
786
        _m4storage[3] * m13 + _m4storage[7] * m23 + _m4storage[11] * m33;
×
787
    _m4storage[0] = t1;
×
788
    _m4storage[1] = t2;
×
789
    _m4storage[2] = t3;
×
790
    _m4storage[3] = t4;
×
791
    _m4storage[4] = t5;
×
792
    _m4storage[5] = t6;
×
793
    _m4storage[6] = t7;
×
794
    _m4storage[7] = t8;
×
795
    _m4storage[8] = t9;
×
796
    _m4storage[9] = t10;
×
797
    _m4storage[10] = t11;
×
798
    _m4storage[11] = t12;
×
799
  }
800

801
  /// Rotate this [angle] radians around X
802
  void rotateX(double angle) {
×
803
    final cosAngle = math.cos(angle);
×
804
    final sinAngle = math.sin(angle);
×
805
    final t1 = _m4storage[4] * cosAngle + _m4storage[8] * sinAngle;
×
806
    final t2 = _m4storage[5] * cosAngle + _m4storage[9] * sinAngle;
×
807
    final t3 = _m4storage[6] * cosAngle + _m4storage[10] * sinAngle;
×
808
    final t4 = _m4storage[7] * cosAngle + _m4storage[11] * sinAngle;
×
809
    final t5 = _m4storage[4] * -sinAngle + _m4storage[8] * cosAngle;
×
810
    final t6 = _m4storage[5] * -sinAngle + _m4storage[9] * cosAngle;
×
811
    final t7 = _m4storage[6] * -sinAngle + _m4storage[10] * cosAngle;
×
812
    final t8 = _m4storage[7] * -sinAngle + _m4storage[11] * cosAngle;
×
813
    _m4storage[4] = t1;
×
814
    _m4storage[5] = t2;
×
815
    _m4storage[6] = t3;
×
816
    _m4storage[7] = t4;
×
817
    _m4storage[8] = t5;
×
818
    _m4storage[9] = t6;
×
819
    _m4storage[10] = t7;
×
820
    _m4storage[11] = t8;
×
821
  }
822

823
  /// Rotate this matrix [angle] radians around Y
824
  void rotateY(double angle) {
×
825
    final cosAngle = math.cos(angle);
×
826
    final sinAngle = math.sin(angle);
×
827
    final t1 = _m4storage[0] * cosAngle + _m4storage[8] * -sinAngle;
×
828
    final t2 = _m4storage[1] * cosAngle + _m4storage[9] * -sinAngle;
×
829
    final t3 = _m4storage[2] * cosAngle + _m4storage[10] * -sinAngle;
×
830
    final t4 = _m4storage[3] * cosAngle + _m4storage[11] * -sinAngle;
×
831
    final t5 = _m4storage[0] * sinAngle + _m4storage[8] * cosAngle;
×
832
    final t6 = _m4storage[1] * sinAngle + _m4storage[9] * cosAngle;
×
833
    final t7 = _m4storage[2] * sinAngle + _m4storage[10] * cosAngle;
×
834
    final t8 = _m4storage[3] * sinAngle + _m4storage[11] * cosAngle;
×
835
    _m4storage[0] = t1;
×
836
    _m4storage[1] = t2;
×
837
    _m4storage[2] = t3;
×
838
    _m4storage[3] = t4;
×
839
    _m4storage[8] = t5;
×
840
    _m4storage[9] = t6;
×
841
    _m4storage[10] = t7;
×
842
    _m4storage[11] = t8;
×
843
  }
844

845
  /// Rotate this matrix [angle] radians around Z
846
  void rotateZ(double angle) {
×
847
    final cosAngle = math.cos(angle);
×
848
    final sinAngle = math.sin(angle);
×
849
    final t1 = _m4storage[0] * cosAngle + _m4storage[4] * sinAngle;
×
850
    final t2 = _m4storage[1] * cosAngle + _m4storage[5] * sinAngle;
×
851
    final t3 = _m4storage[2] * cosAngle + _m4storage[6] * sinAngle;
×
852
    final t4 = _m4storage[3] * cosAngle + _m4storage[7] * sinAngle;
×
853
    final t5 = _m4storage[0] * -sinAngle + _m4storage[4] * cosAngle;
×
854
    final t6 = _m4storage[1] * -sinAngle + _m4storage[5] * cosAngle;
×
855
    final t7 = _m4storage[2] * -sinAngle + _m4storage[6] * cosAngle;
×
856
    final t8 = _m4storage[3] * -sinAngle + _m4storage[7] * cosAngle;
×
857
    _m4storage[0] = t1;
×
858
    _m4storage[1] = t2;
×
859
    _m4storage[2] = t3;
×
860
    _m4storage[3] = t4;
×
861
    _m4storage[4] = t5;
×
862
    _m4storage[5] = t6;
×
863
    _m4storage[6] = t7;
×
864
    _m4storage[7] = t8;
×
865
  }
866

867
  /// Scale this matrix by a [Vector3], [Vector4], or x,y,z
868
  void scale(dynamic x, [double? y, double? z]) {
×
869
    double sx;
870
    double sy;
871
    double sz;
872
    final sw = x is Vector4 ? x.w : 1.0;
×
873
    if (x is Vector3) {
×
874
      sx = x.x;
×
875
      sy = x.y;
×
876
      sz = x.z;
×
877
    } else if (x is Vector4) {
×
878
      sx = x.x;
×
879
      sy = x.y;
×
880
      sz = x.z;
×
881
    } else if (x is double) {
×
882
      sx = x;
883
      sy = y ?? x;
884
      sz = z ?? x;
885
    } else {
886
      throw UnimplementedError();
×
887
    }
888
    _m4storage[0] *= sx;
×
889
    _m4storage[1] *= sx;
×
890
    _m4storage[2] *= sx;
×
891
    _m4storage[3] *= sx;
×
892
    _m4storage[4] *= sy;
×
893
    _m4storage[5] *= sy;
×
894
    _m4storage[6] *= sy;
×
895
    _m4storage[7] *= sy;
×
896
    _m4storage[8] *= sz;
×
897
    _m4storage[9] *= sz;
×
898
    _m4storage[10] *= sz;
×
899
    _m4storage[11] *= sz;
×
900
    _m4storage[12] *= sw;
×
901
    _m4storage[13] *= sw;
×
902
    _m4storage[14] *= sw;
×
903
    _m4storage[15] *= sw;
×
904
  }
905

906
  /// Create a copy of this scaled by a [Vector3], [Vector4] or [x],[y], and
907
  /// [z].
908
  Matrix4 scaled(dynamic x, [double? y, double? z]) => clone()..scale(x, y, z);
×
909

910
  /// Zeros this.
911
  void setZero() {
×
912
    _m4storage[0] = 0.0;
×
913
    _m4storage[1] = 0.0;
×
914
    _m4storage[2] = 0.0;
×
915
    _m4storage[3] = 0.0;
×
916
    _m4storage[4] = 0.0;
×
917
    _m4storage[5] = 0.0;
×
918
    _m4storage[6] = 0.0;
×
919
    _m4storage[7] = 0.0;
×
920
    _m4storage[8] = 0.0;
×
921
    _m4storage[9] = 0.0;
×
922
    _m4storage[10] = 0.0;
×
923
    _m4storage[11] = 0.0;
×
924
    _m4storage[12] = 0.0;
×
925
    _m4storage[13] = 0.0;
×
926
    _m4storage[14] = 0.0;
×
927
    _m4storage[15] = 0.0;
×
928
  }
929

930
  /// Makes this into the identity matrix.
931
  void setIdentity() {
×
932
    _m4storage[0] = 1.0;
×
933
    _m4storage[1] = 0.0;
×
934
    _m4storage[2] = 0.0;
×
935
    _m4storage[3] = 0.0;
×
936
    _m4storage[4] = 0.0;
×
937
    _m4storage[5] = 1.0;
×
938
    _m4storage[6] = 0.0;
×
939
    _m4storage[7] = 0.0;
×
940
    _m4storage[8] = 0.0;
×
941
    _m4storage[9] = 0.0;
×
942
    _m4storage[10] = 1.0;
×
943
    _m4storage[11] = 0.0;
×
944
    _m4storage[12] = 0.0;
×
945
    _m4storage[13] = 0.0;
×
946
    _m4storage[14] = 0.0;
×
947
    _m4storage[15] = 1.0;
×
948
  }
949

950
  /// Returns the tranpose of this.
951
  Matrix4 transposed() => clone()..transpose();
×
952

953
  void transpose() {
×
954
    double temp;
955
    temp = _m4storage[4];
×
956
    _m4storage[4] = _m4storage[1];
×
957
    _m4storage[1] = temp;
×
958
    temp = _m4storage[8];
×
959
    _m4storage[8] = _m4storage[2];
×
960
    _m4storage[2] = temp;
×
961
    temp = _m4storage[12];
×
962
    _m4storage[12] = _m4storage[3];
×
963
    _m4storage[3] = temp;
×
964
    temp = _m4storage[9];
×
965
    _m4storage[9] = _m4storage[6];
×
966
    _m4storage[6] = temp;
×
967
    temp = _m4storage[13];
×
968
    _m4storage[13] = _m4storage[7];
×
969
    _m4storage[7] = temp;
×
970
    temp = _m4storage[14];
×
971
    _m4storage[14] = _m4storage[11];
×
972
    _m4storage[11] = temp;
×
973
  }
974

975
  /// Returns the component wise absolute value of this.
976
  Matrix4 absolute() {
×
977
    final r = Matrix4.zero();
×
978
    final rStorage = r._m4storage;
×
979
    rStorage[0] = _m4storage[0].abs();
×
980
    rStorage[1] = _m4storage[1].abs();
×
981
    rStorage[2] = _m4storage[2].abs();
×
982
    rStorage[3] = _m4storage[3].abs();
×
983
    rStorage[4] = _m4storage[4].abs();
×
984
    rStorage[5] = _m4storage[5].abs();
×
985
    rStorage[6] = _m4storage[6].abs();
×
986
    rStorage[7] = _m4storage[7].abs();
×
987
    rStorage[8] = _m4storage[8].abs();
×
988
    rStorage[9] = _m4storage[9].abs();
×
989
    rStorage[10] = _m4storage[10].abs();
×
990
    rStorage[11] = _m4storage[11].abs();
×
991
    rStorage[12] = _m4storage[12].abs();
×
992
    rStorage[13] = _m4storage[13].abs();
×
993
    rStorage[14] = _m4storage[14].abs();
×
994
    rStorage[15] = _m4storage[15].abs();
×
995
    return r;
996
  }
997

998
  /// Returns the determinant of this matrix.
999
  double determinant() {
×
1000
    final det2_01_01 =
1001
        _m4storage[0] * _m4storage[5] - _m4storage[1] * _m4storage[4];
×
1002
    final det2_01_02 =
1003
        _m4storage[0] * _m4storage[6] - _m4storage[2] * _m4storage[4];
×
1004
    final det2_01_03 =
1005
        _m4storage[0] * _m4storage[7] - _m4storage[3] * _m4storage[4];
×
1006
    final det2_01_12 =
1007
        _m4storage[1] * _m4storage[6] - _m4storage[2] * _m4storage[5];
×
1008
    final det2_01_13 =
1009
        _m4storage[1] * _m4storage[7] - _m4storage[3] * _m4storage[5];
×
1010
    final det2_01_23 =
1011
        _m4storage[2] * _m4storage[7] - _m4storage[3] * _m4storage[6];
×
1012
    final det3_201_012 = _m4storage[8] * det2_01_12 -
×
1013
        _m4storage[9] * det2_01_02 +
×
1014
        _m4storage[10] * det2_01_01;
×
1015
    final det3_201_013 = _m4storage[8] * det2_01_13 -
×
1016
        _m4storage[9] * det2_01_03 +
×
1017
        _m4storage[11] * det2_01_01;
×
1018
    final det3_201_023 = _m4storage[8] * det2_01_23 -
×
1019
        _m4storage[10] * det2_01_03 +
×
1020
        _m4storage[11] * det2_01_02;
×
1021
    final det3_201_123 = _m4storage[9] * det2_01_23 -
×
1022
        _m4storage[10] * det2_01_13 +
×
1023
        _m4storage[11] * det2_01_12;
×
1024
    return -det3_201_123 * _m4storage[12] +
×
1025
        det3_201_023 * _m4storage[13] -
×
1026
        det3_201_013 * _m4storage[14] +
×
1027
        det3_201_012 * _m4storage[15];
×
1028
  }
1029

1030
  /// Returns the dot product of row [i] and [v].
1031
  double dotRow(int i, Vector4 v) {
×
1032
    final vStorage = v._v4storage;
×
1033
    return _m4storage[i] * vStorage[0] +
×
1034
        _m4storage[4 + i] * vStorage[1] +
×
1035
        _m4storage[8 + i] * vStorage[2] +
×
1036
        _m4storage[12 + i] * vStorage[3];
×
1037
  }
1038

1039
  /// Returns the dot product of column [j] and [v].
1040
  double dotColumn(int j, Vector4 v) {
×
1041
    final vStorage = v._v4storage;
×
1042
    return _m4storage[j * 4] * vStorage[0] +
×
1043
        _m4storage[j * 4 + 1] * vStorage[1] +
×
1044
        _m4storage[j * 4 + 2] * vStorage[2] +
×
1045
        _m4storage[j * 4 + 3] * vStorage[3];
×
1046
  }
1047

1048
  /// Returns the trace of the matrix. The trace of a matrix is the sum of the
1049
  /// diagonal entries.
1050
  double trace() {
×
1051
    var t = 0.0;
1052
    t += _m4storage[0];
×
1053
    t += _m4storage[5];
×
1054
    t += _m4storage[10];
×
1055
    t += _m4storage[15];
×
1056
    return t;
1057
  }
1058

1059
  /// Returns infinity norm of the matrix. Used for numerical analysis.
1060
  double infinityNorm() {
×
1061
    var norm = 0.0;
1062
    {
1063
      var row_norm = 0.0;
1064
      row_norm += _m4storage[0].abs();
×
1065
      row_norm += _m4storage[1].abs();
×
1066
      row_norm += _m4storage[2].abs();
×
1067
      row_norm += _m4storage[3].abs();
×
1068
      norm = row_norm > norm ? row_norm : norm;
×
1069
    }
1070
    {
1071
      var row_norm = 0.0;
1072
      row_norm += _m4storage[4].abs();
×
1073
      row_norm += _m4storage[5].abs();
×
1074
      row_norm += _m4storage[6].abs();
×
1075
      row_norm += _m4storage[7].abs();
×
1076
      norm = row_norm > norm ? row_norm : norm;
×
1077
    }
1078
    {
1079
      var row_norm = 0.0;
1080
      row_norm += _m4storage[8].abs();
×
1081
      row_norm += _m4storage[9].abs();
×
1082
      row_norm += _m4storage[10].abs();
×
1083
      row_norm += _m4storage[11].abs();
×
1084
      norm = row_norm > norm ? row_norm : norm;
×
1085
    }
1086
    {
1087
      var row_norm = 0.0;
1088
      row_norm += _m4storage[12].abs();
×
1089
      row_norm += _m4storage[13].abs();
×
1090
      row_norm += _m4storage[14].abs();
×
1091
      row_norm += _m4storage[15].abs();
×
1092
      norm = row_norm > norm ? row_norm : norm;
×
1093
    }
1094
    return norm;
1095
  }
1096

1097
  /// Returns relative error between this and [correct]
1098
  double relativeError(Matrix4 correct) {
×
1099
    final diff = correct - this;
×
1100
    final correct_norm = correct.infinityNorm();
×
1101
    final diff_norm = diff.infinityNorm();
×
1102
    return diff_norm / correct_norm;
×
1103
  }
1104

1105
  /// Returns absolute error between this and [correct]
1106
  double absoluteError(Matrix4 correct) {
×
1107
    final this_norm = infinityNorm();
×
1108
    final correct_norm = correct.infinityNorm();
×
1109
    final diff_norm = (this_norm - correct_norm).abs();
×
1110
    return diff_norm;
1111
  }
1112

1113
  /// Returns the translation vector from this homogeneous transformation
1114
  /// matrix.
1115
  Vector3 getTranslation() {
×
1116
    final z = _m4storage[14];
×
1117
    final y = _m4storage[13];
×
1118
    final x = _m4storage[12];
×
1119
    return Vector3(x, y, z);
×
1120
  }
1121

1122
  /// Sets the translation vector in this homogeneous transformation matrix.
1123
  void setTranslation(Vector3 t) {
×
1124
    final tStorage = t._v3storage;
×
1125
    final z = tStorage[2];
×
1126
    final y = tStorage[1];
×
1127
    final x = tStorage[0];
×
1128
    _m4storage[14] = z;
×
1129
    _m4storage[13] = y;
×
1130
    _m4storage[12] = x;
×
1131
  }
1132

1133
  /// Sets the translation vector in this homogeneous transformation matrix.
1134
  void setTranslationRaw(double x, double y, double z) {
×
1135
    _m4storage[14] = z;
×
1136
    _m4storage[13] = y;
×
1137
    _m4storage[12] = x;
×
1138
  }
1139

1140
  /// Returns the rotation matrix from this homogeneous transformation matrix.
1141
  Matrix3 getRotation() {
×
1142
    final r = Matrix3.zero();
×
1143
    copyRotation(r);
×
1144
    return r;
1145
  }
1146

1147
  /// Copies the rotation matrix from this homogeneous transformation matrix
1148
  /// into [rotation].
1149
  void copyRotation(Matrix3 rotation) {
×
1150
    final rStorage = rotation._m3storage;
×
1151
    rStorage[0] = _m4storage[0];
×
1152
    rStorage[1] = _m4storage[1];
×
1153
    rStorage[2] = _m4storage[2];
×
1154
    rStorage[3] = _m4storage[4];
×
1155
    rStorage[4] = _m4storage[5];
×
1156
    rStorage[5] = _m4storage[6];
×
1157
    rStorage[6] = _m4storage[8];
×
1158
    rStorage[7] = _m4storage[9];
×
1159
    rStorage[8] = _m4storage[10];
×
1160
  }
1161

1162
  /// Sets the rotation matrix in this homogeneous transformation matrix.
1163
  void setRotation(Matrix3 r) {
×
1164
    final rStorage = r._m3storage;
×
1165
    _m4storage[0] = rStorage[0];
×
1166
    _m4storage[1] = rStorage[1];
×
1167
    _m4storage[2] = rStorage[2];
×
1168
    _m4storage[4] = rStorage[3];
×
1169
    _m4storage[5] = rStorage[4];
×
1170
    _m4storage[6] = rStorage[5];
×
1171
    _m4storage[8] = rStorage[6];
×
1172
    _m4storage[9] = rStorage[7];
×
1173
    _m4storage[10] = rStorage[8];
×
1174
  }
1175

1176
  /// Returns the normal matrix from this homogeneous transformation matrix.
1177
  ///
1178
  /// The normal matrix is the transpose of the inverse of the top-left 3x3 part
1179
  /// of this 4x4 matrix.
1180
  Matrix3 getNormalMatrix() => Matrix3.identity()..copyNormalMatrix(this);
×
1181

1182
  /// Returns the max scale value of the 3 axes.
1183
  double getMaxScaleOnAxis() {
×
1184
    final scaleXSq = _m4storage[0] * _m4storage[0] +
×
1185
        _m4storage[1] * _m4storage[1] +
×
1186
        _m4storage[2] * _m4storage[2];
×
1187
    final scaleYSq = _m4storage[4] * _m4storage[4] +
×
1188
        _m4storage[5] * _m4storage[5] +
×
1189
        _m4storage[6] * _m4storage[6];
×
1190
    final scaleZSq = _m4storage[8] * _m4storage[8] +
×
1191
        _m4storage[9] * _m4storage[9] +
×
1192
        _m4storage[10] * _m4storage[10];
×
1193
    return math.sqrt(math.max(scaleXSq, math.max(scaleYSq, scaleZSq)));
×
1194
  }
1195

1196
  /// Transposes just the upper 3x3 rotation matrix.
1197
  void transposeRotation() {
×
1198
    double temp;
1199
    temp = _m4storage[1];
×
1200
    _m4storage[1] = _m4storage[4];
×
1201
    _m4storage[4] = temp;
×
1202
    temp = _m4storage[2];
×
1203
    _m4storage[2] = _m4storage[8];
×
1204
    _m4storage[8] = temp;
×
1205
    temp = _m4storage[4];
×
1206
    _m4storage[4] = _m4storage[1];
×
1207
    _m4storage[1] = temp;
×
1208
    temp = _m4storage[6];
×
1209
    _m4storage[6] = _m4storage[9];
×
1210
    _m4storage[9] = temp;
×
1211
    temp = _m4storage[8];
×
1212
    _m4storage[8] = _m4storage[2];
×
1213
    _m4storage[2] = temp;
×
1214
    temp = _m4storage[9];
×
1215
    _m4storage[9] = _m4storage[6];
×
1216
    _m4storage[6] = temp;
×
1217
  }
1218

1219
  /// Invert this.
1220
  double invert() => copyInverse(this);
×
1221

1222
  /// Set this matrix to be the inverse of [arg]
1223
  double copyInverse(Matrix4 arg) {
×
1224
    final argStorage = arg._m4storage;
×
1225
    final a00 = argStorage[0];
×
1226
    final a01 = argStorage[1];
×
1227
    final a02 = argStorage[2];
×
1228
    final a03 = argStorage[3];
×
1229
    final a10 = argStorage[4];
×
1230
    final a11 = argStorage[5];
×
1231
    final a12 = argStorage[6];
×
1232
    final a13 = argStorage[7];
×
1233
    final a20 = argStorage[8];
×
1234
    final a21 = argStorage[9];
×
1235
    final a22 = argStorage[10];
×
1236
    final a23 = argStorage[11];
×
1237
    final a30 = argStorage[12];
×
1238
    final a31 = argStorage[13];
×
1239
    final a32 = argStorage[14];
×
1240
    final a33 = argStorage[15];
×
1241
    final b00 = a00 * a11 - a01 * a10;
×
1242
    final b01 = a00 * a12 - a02 * a10;
×
1243
    final b02 = a00 * a13 - a03 * a10;
×
1244
    final b03 = a01 * a12 - a02 * a11;
×
1245
    final b04 = a01 * a13 - a03 * a11;
×
1246
    final b05 = a02 * a13 - a03 * a12;
×
1247
    final b06 = a20 * a31 - a21 * a30;
×
1248
    final b07 = a20 * a32 - a22 * a30;
×
1249
    final b08 = a20 * a33 - a23 * a30;
×
1250
    final b09 = a21 * a32 - a22 * a31;
×
1251
    final b10 = a21 * a33 - a23 * a31;
×
1252
    final b11 = a22 * a33 - a23 * a32;
×
1253
    final det =
1254
        b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
×
1255
    if (det == 0.0) {
×
1256
      setFrom(arg);
×
1257
      return 0.0;
1258
    }
1259
    final invDet = 1.0 / det;
×
1260
    _m4storage[0] = (a11 * b11 - a12 * b10 + a13 * b09) * invDet;
×
1261
    _m4storage[1] = (-a01 * b11 + a02 * b10 - a03 * b09) * invDet;
×
1262
    _m4storage[2] = (a31 * b05 - a32 * b04 + a33 * b03) * invDet;
×
1263
    _m4storage[3] = (-a21 * b05 + a22 * b04 - a23 * b03) * invDet;
×
1264
    _m4storage[4] = (-a10 * b11 + a12 * b08 - a13 * b07) * invDet;
×
1265
    _m4storage[5] = (a00 * b11 - a02 * b08 + a03 * b07) * invDet;
×
1266
    _m4storage[6] = (-a30 * b05 + a32 * b02 - a33 * b01) * invDet;
×
1267
    _m4storage[7] = (a20 * b05 - a22 * b02 + a23 * b01) * invDet;
×
1268
    _m4storage[8] = (a10 * b10 - a11 * b08 + a13 * b06) * invDet;
×
1269
    _m4storage[9] = (-a00 * b10 + a01 * b08 - a03 * b06) * invDet;
×
1270
    _m4storage[10] = (a30 * b04 - a31 * b02 + a33 * b00) * invDet;
×
1271
    _m4storage[11] = (-a20 * b04 + a21 * b02 - a23 * b00) * invDet;
×
1272
    _m4storage[12] = (-a10 * b09 + a11 * b07 - a12 * b06) * invDet;
×
1273
    _m4storage[13] = (a00 * b09 - a01 * b07 + a02 * b06) * invDet;
×
1274
    _m4storage[14] = (-a30 * b03 + a31 * b01 - a32 * b00) * invDet;
×
1275
    _m4storage[15] = (a20 * b03 - a21 * b01 + a22 * b00) * invDet;
×
1276
    return det;
1277
  }
1278

1279
  double invertRotation() {
×
1280
    final det = determinant();
×
1281
    if (det == 0.0) {
×
1282
      return 0.0;
1283
    }
1284
    final invDet = 1.0 / det;
×
1285
    double ix;
1286
    double iy;
1287
    double iz;
1288
    double jx;
1289
    double jy;
1290
    double jz;
1291
    double kx;
1292
    double ky;
1293
    double kz;
1294
    ix = invDet *
×
1295
        (_m4storage[5] * _m4storage[10] - _m4storage[6] * _m4storage[9]);
×
1296
    iy = invDet *
×
1297
        (_m4storage[2] * _m4storage[9] - _m4storage[1] * _m4storage[10]);
×
1298
    iz = invDet *
×
1299
        (_m4storage[1] * _m4storage[6] - _m4storage[2] * _m4storage[5]);
×
1300
    jx = invDet *
×
1301
        (_m4storage[6] * _m4storage[8] - _m4storage[4] * _m4storage[10]);
×
1302
    jy = invDet *
×
1303
        (_m4storage[0] * _m4storage[10] - _m4storage[2] * _m4storage[8]);
×
1304
    jz = invDet *
×
1305
        (_m4storage[2] * _m4storage[4] - _m4storage[0] * _m4storage[6]);
×
1306
    kx = invDet *
×
1307
        (_m4storage[4] * _m4storage[9] - _m4storage[5] * _m4storage[8]);
×
1308
    ky = invDet *
×
1309
        (_m4storage[1] * _m4storage[8] - _m4storage[0] * _m4storage[9]);
×
1310
    kz = invDet *
×
1311
        (_m4storage[0] * _m4storage[5] - _m4storage[1] * _m4storage[4]);
×
1312
    _m4storage[0] = ix;
×
1313
    _m4storage[1] = iy;
×
1314
    _m4storage[2] = iz;
×
1315
    _m4storage[4] = jx;
×
1316
    _m4storage[5] = jy;
×
1317
    _m4storage[6] = jz;
×
1318
    _m4storage[8] = kx;
×
1319
    _m4storage[9] = ky;
×
1320
    _m4storage[10] = kz;
×
1321
    return det;
1322
  }
1323

1324
  /// Sets the upper 3x3 to a rotation of [radians] around X
1325
  void setRotationX(double radians) {
×
1326
    final c = math.cos(radians);
×
1327
    final s = math.sin(radians);
×
1328
    _m4storage[0] = 1.0;
×
1329
    _m4storage[1] = 0.0;
×
1330
    _m4storage[2] = 0.0;
×
1331
    _m4storage[4] = 0.0;
×
1332
    _m4storage[5] = c;
×
1333
    _m4storage[6] = s;
×
1334
    _m4storage[8] = 0.0;
×
1335
    _m4storage[9] = -s;
×
1336
    _m4storage[10] = c;
×
1337
    _m4storage[3] = 0.0;
×
1338
    _m4storage[7] = 0.0;
×
1339
    _m4storage[11] = 0.0;
×
1340
  }
1341

1342
  /// Sets the upper 3x3 to a rotation of [radians] around Y
1343
  void setRotationY(double radians) {
×
1344
    final c = math.cos(radians);
×
1345
    final s = math.sin(radians);
×
1346
    _m4storage[0] = c;
×
1347
    _m4storage[1] = 0.0;
×
1348
    _m4storage[2] = -s;
×
1349
    _m4storage[4] = 0.0;
×
1350
    _m4storage[5] = 1.0;
×
1351
    _m4storage[6] = 0.0;
×
1352
    _m4storage[8] = s;
×
1353
    _m4storage[9] = 0.0;
×
1354
    _m4storage[10] = c;
×
1355
    _m4storage[3] = 0.0;
×
1356
    _m4storage[7] = 0.0;
×
1357
    _m4storage[11] = 0.0;
×
1358
  }
1359

1360
  /// Sets the upper 3x3 to a rotation of [radians] around Z
1361
  void setRotationZ(double radians) {
×
1362
    final c = math.cos(radians);
×
1363
    final s = math.sin(radians);
×
1364
    _m4storage[0] = c;
×
1365
    _m4storage[1] = s;
×
1366
    _m4storage[2] = 0.0;
×
1367
    _m4storage[4] = -s;
×
1368
    _m4storage[5] = c;
×
1369
    _m4storage[6] = 0.0;
×
1370
    _m4storage[8] = 0.0;
×
1371
    _m4storage[9] = 0.0;
×
1372
    _m4storage[10] = 1.0;
×
1373
    _m4storage[3] = 0.0;
×
1374
    _m4storage[7] = 0.0;
×
1375
    _m4storage[11] = 0.0;
×
1376
  }
1377

1378
  /// Converts into Adjugate matrix and scales by [scale]
1379
  void scaleAdjoint(double scale) {
×
1380
    // Adapted from code by Richard Carling.
1381
    final a1 = _m4storage[0];
×
1382
    final b1 = _m4storage[4];
×
1383
    final c1 = _m4storage[8];
×
1384
    final d1 = _m4storage[12];
×
1385
    final a2 = _m4storage[1];
×
1386
    final b2 = _m4storage[5];
×
1387
    final c2 = _m4storage[9];
×
1388
    final d2 = _m4storage[13];
×
1389
    final a3 = _m4storage[2];
×
1390
    final b3 = _m4storage[6];
×
1391
    final c3 = _m4storage[10];
×
1392
    final d3 = _m4storage[14];
×
1393
    final a4 = _m4storage[3];
×
1394
    final b4 = _m4storage[7];
×
1395
    final c4 = _m4storage[11];
×
1396
    final d4 = _m4storage[15];
×
1397
    _m4storage[0] = (b2 * (c3 * d4 - c4 * d3) -
×
1398
            c2 * (b3 * d4 - b4 * d3) +
×
1399
            d2 * (b3 * c4 - b4 * c3)) *
×
1400
        scale;
1401
    _m4storage[1] = -(a2 * (c3 * d4 - c4 * d3) -
×
1402
            c2 * (a3 * d4 - a4 * d3) +
×
1403
            d2 * (a3 * c4 - a4 * c3)) *
×
1404
        scale;
1405
    _m4storage[2] = (a2 * (b3 * d4 - b4 * d3) -
×
1406
            b2 * (a3 * d4 - a4 * d3) +
×
1407
            d2 * (a3 * b4 - a4 * b3)) *
×
1408
        scale;
1409
    _m4storage[3] = -(a2 * (b3 * c4 - b4 * c3) -
×
1410
            b2 * (a3 * c4 - a4 * c3) +
×
1411
            c2 * (a3 * b4 - a4 * b3)) *
×
1412
        scale;
1413
    _m4storage[4] = -(b1 * (c3 * d4 - c4 * d3) -
×
1414
            c1 * (b3 * d4 - b4 * d3) +
×
1415
            d1 * (b3 * c4 - b4 * c3)) *
×
1416
        scale;
1417
    _m4storage[5] = (a1 * (c3 * d4 - c4 * d3) -
×
1418
            c1 * (a3 * d4 - a4 * d3) +
×
1419
            d1 * (a3 * c4 - a4 * c3)) *
×
1420
        scale;
1421
    _m4storage[6] = -(a1 * (b3 * d4 - b4 * d3) -
×
1422
            b1 * (a3 * d4 - a4 * d3) +
×
1423
            d1 * (a3 * b4 - a4 * b3)) *
×
1424
        scale;
1425
    _m4storage[7] = (a1 * (b3 * c4 - b4 * c3) -
×
1426
            b1 * (a3 * c4 - a4 * c3) +
×
1427
            c1 * (a3 * b4 - a4 * b3)) *
×
1428
        scale;
1429
    _m4storage[8] = (b1 * (c2 * d4 - c4 * d2) -
×
1430
            c1 * (b2 * d4 - b4 * d2) +
×
1431
            d1 * (b2 * c4 - b4 * c2)) *
×
1432
        scale;
1433
    _m4storage[9] = -(a1 * (c2 * d4 - c4 * d2) -
×
1434
            c1 * (a2 * d4 - a4 * d2) +
×
1435
            d1 * (a2 * c4 - a4 * c2)) *
×
1436
        scale;
1437
    _m4storage[10] = (a1 * (b2 * d4 - b4 * d2) -
×
1438
            b1 * (a2 * d4 - a4 * d2) +
×
1439
            d1 * (a2 * b4 - a4 * b2)) *
×
1440
        scale;
1441
    _m4storage[11] = -(a1 * (b2 * c4 - b4 * c2) -
×
1442
            b1 * (a2 * c4 - a4 * c2) +
×
1443
            c1 * (a2 * b4 - a4 * b2)) *
×
1444
        scale;
1445
    _m4storage[12] = -(b1 * (c2 * d3 - c3 * d2) -
×
1446
            c1 * (b2 * d3 - b3 * d2) +
×
1447
            d1 * (b2 * c3 - b3 * c2)) *
×
1448
        scale;
1449
    _m4storage[13] = (a1 * (c2 * d3 - c3 * d2) -
×
1450
            c1 * (a2 * d3 - a3 * d2) +
×
1451
            d1 * (a2 * c3 - a3 * c2)) *
×
1452
        scale;
1453
    _m4storage[14] = -(a1 * (b2 * d3 - b3 * d2) -
×
1454
            b1 * (a2 * d3 - a3 * d2) +
×
1455
            d1 * (a2 * b3 - a3 * b2)) *
×
1456
        scale;
1457
    _m4storage[15] = (a1 * (b2 * c3 - b3 * c2) -
×
1458
            b1 * (a2 * c3 - a3 * c2) +
×
1459
            c1 * (a2 * b3 - a3 * b2)) *
×
1460
        scale;
1461
  }
1462

1463
  /// Rotates [arg] by the absolute rotation of this
1464
  /// Returns [arg].
1465
  /// Primarily used by AABB transformation code.
1466
  Vector3 absoluteRotate(Vector3 arg) {
×
1467
    final m00 = _m4storage[0].abs();
×
1468
    final m01 = _m4storage[4].abs();
×
1469
    final m02 = _m4storage[8].abs();
×
1470
    final m10 = _m4storage[1].abs();
×
1471
    final m11 = _m4storage[5].abs();
×
1472
    final m12 = _m4storage[9].abs();
×
1473
    final m20 = _m4storage[2].abs();
×
1474
    final m21 = _m4storage[6].abs();
×
1475
    final m22 = _m4storage[10].abs();
×
1476
    final argStorage = arg._v3storage;
×
1477
    final x = argStorage[0];
×
1478
    final y = argStorage[1];
×
1479
    final z = argStorage[2];
×
1480
    argStorage[0] = x * m00 + y * m01 + z * m02 + 0.0 * 0.0;
×
1481
    argStorage[1] = x * m10 + y * m11 + z * m12 + 0.0 * 0.0;
×
1482
    argStorage[2] = x * m20 + y * m21 + z * m22 + 0.0 * 0.0;
×
1483
    return arg;
1484
  }
1485

1486
  /// Adds [o] to this.
1487
  void add(Matrix4 o) {
×
1488
    final oStorage = o._m4storage;
×
1489
    _m4storage[0] = _m4storage[0] + oStorage[0];
×
1490
    _m4storage[1] = _m4storage[1] + oStorage[1];
×
1491
    _m4storage[2] = _m4storage[2] + oStorage[2];
×
1492
    _m4storage[3] = _m4storage[3] + oStorage[3];
×
1493
    _m4storage[4] = _m4storage[4] + oStorage[4];
×
1494
    _m4storage[5] = _m4storage[5] + oStorage[5];
×
1495
    _m4storage[6] = _m4storage[6] + oStorage[6];
×
1496
    _m4storage[7] = _m4storage[7] + oStorage[7];
×
1497
    _m4storage[8] = _m4storage[8] + oStorage[8];
×
1498
    _m4storage[9] = _m4storage[9] + oStorage[9];
×
1499
    _m4storage[10] = _m4storage[10] + oStorage[10];
×
1500
    _m4storage[11] = _m4storage[11] + oStorage[11];
×
1501
    _m4storage[12] = _m4storage[12] + oStorage[12];
×
1502
    _m4storage[13] = _m4storage[13] + oStorage[13];
×
1503
    _m4storage[14] = _m4storage[14] + oStorage[14];
×
1504
    _m4storage[15] = _m4storage[15] + oStorage[15];
×
1505
  }
1506

1507
  /// Subtracts [o] from this.
1508
  void sub(Matrix4 o) {
×
1509
    final oStorage = o._m4storage;
×
1510
    _m4storage[0] = _m4storage[0] - oStorage[0];
×
1511
    _m4storage[1] = _m4storage[1] - oStorage[1];
×
1512
    _m4storage[2] = _m4storage[2] - oStorage[2];
×
1513
    _m4storage[3] = _m4storage[3] - oStorage[3];
×
1514
    _m4storage[4] = _m4storage[4] - oStorage[4];
×
1515
    _m4storage[5] = _m4storage[5] - oStorage[5];
×
1516
    _m4storage[6] = _m4storage[6] - oStorage[6];
×
1517
    _m4storage[7] = _m4storage[7] - oStorage[7];
×
1518
    _m4storage[8] = _m4storage[8] - oStorage[8];
×
1519
    _m4storage[9] = _m4storage[9] - oStorage[9];
×
1520
    _m4storage[10] = _m4storage[10] - oStorage[10];
×
1521
    _m4storage[11] = _m4storage[11] - oStorage[11];
×
1522
    _m4storage[12] = _m4storage[12] - oStorage[12];
×
1523
    _m4storage[13] = _m4storage[13] - oStorage[13];
×
1524
    _m4storage[14] = _m4storage[14] - oStorage[14];
×
1525
    _m4storage[15] = _m4storage[15] - oStorage[15];
×
1526
  }
1527

1528
  /// Negate this.
1529
  void negate() {
×
1530
    _m4storage[0] = -_m4storage[0];
×
1531
    _m4storage[1] = -_m4storage[1];
×
1532
    _m4storage[2] = -_m4storage[2];
×
1533
    _m4storage[3] = -_m4storage[3];
×
1534
    _m4storage[4] = -_m4storage[4];
×
1535
    _m4storage[5] = -_m4storage[5];
×
1536
    _m4storage[6] = -_m4storage[6];
×
1537
    _m4storage[7] = -_m4storage[7];
×
1538
    _m4storage[8] = -_m4storage[8];
×
1539
    _m4storage[9] = -_m4storage[9];
×
1540
    _m4storage[10] = -_m4storage[10];
×
1541
    _m4storage[11] = -_m4storage[11];
×
1542
    _m4storage[12] = -_m4storage[12];
×
1543
    _m4storage[13] = -_m4storage[13];
×
1544
    _m4storage[14] = -_m4storage[14];
×
1545
    _m4storage[15] = -_m4storage[15];
×
1546
  }
1547

1548
  /// Multiply this by [arg].
1549
  void multiply(Matrix4 arg) {
×
1550
    final m00 = _m4storage[0];
×
1551
    final m01 = _m4storage[4];
×
1552
    final m02 = _m4storage[8];
×
1553
    final m03 = _m4storage[12];
×
1554
    final m10 = _m4storage[1];
×
1555
    final m11 = _m4storage[5];
×
1556
    final m12 = _m4storage[9];
×
1557
    final m13 = _m4storage[13];
×
1558
    final m20 = _m4storage[2];
×
1559
    final m21 = _m4storage[6];
×
1560
    final m22 = _m4storage[10];
×
1561
    final m23 = _m4storage[14];
×
1562
    final m30 = _m4storage[3];
×
1563
    final m31 = _m4storage[7];
×
1564
    final m32 = _m4storage[11];
×
1565
    final m33 = _m4storage[15];
×
1566
    final argStorage = arg._m4storage;
×
1567
    final n00 = argStorage[0];
×
1568
    final n01 = argStorage[4];
×
1569
    final n02 = argStorage[8];
×
1570
    final n03 = argStorage[12];
×
1571
    final n10 = argStorage[1];
×
1572
    final n11 = argStorage[5];
×
1573
    final n12 = argStorage[9];
×
1574
    final n13 = argStorage[13];
×
1575
    final n20 = argStorage[2];
×
1576
    final n21 = argStorage[6];
×
1577
    final n22 = argStorage[10];
×
1578
    final n23 = argStorage[14];
×
1579
    final n30 = argStorage[3];
×
1580
    final n31 = argStorage[7];
×
1581
    final n32 = argStorage[11];
×
1582
    final n33 = argStorage[15];
×
1583
    _m4storage[0] = (m00 * n00) + (m01 * n10) + (m02 * n20) + (m03 * n30);
×
1584
    _m4storage[4] = (m00 * n01) + (m01 * n11) + (m02 * n21) + (m03 * n31);
×
1585
    _m4storage[8] = (m00 * n02) + (m01 * n12) + (m02 * n22) + (m03 * n32);
×
1586
    _m4storage[12] = (m00 * n03) + (m01 * n13) + (m02 * n23) + (m03 * n33);
×
1587
    _m4storage[1] = (m10 * n00) + (m11 * n10) + (m12 * n20) + (m13 * n30);
×
1588
    _m4storage[5] = (m10 * n01) + (m11 * n11) + (m12 * n21) + (m13 * n31);
×
1589
    _m4storage[9] = (m10 * n02) + (m11 * n12) + (m12 * n22) + (m13 * n32);
×
1590
    _m4storage[13] = (m10 * n03) + (m11 * n13) + (m12 * n23) + (m13 * n33);
×
1591
    _m4storage[2] = (m20 * n00) + (m21 * n10) + (m22 * n20) + (m23 * n30);
×
1592
    _m4storage[6] = (m20 * n01) + (m21 * n11) + (m22 * n21) + (m23 * n31);
×
1593
    _m4storage[10] = (m20 * n02) + (m21 * n12) + (m22 * n22) + (m23 * n32);
×
1594
    _m4storage[14] = (m20 * n03) + (m21 * n13) + (m22 * n23) + (m23 * n33);
×
1595
    _m4storage[3] = (m30 * n00) + (m31 * n10) + (m32 * n20) + (m33 * n30);
×
1596
    _m4storage[7] = (m30 * n01) + (m31 * n11) + (m32 * n21) + (m33 * n31);
×
1597
    _m4storage[11] = (m30 * n02) + (m31 * n12) + (m32 * n22) + (m33 * n32);
×
1598
    _m4storage[15] = (m30 * n03) + (m31 * n13) + (m32 * n23) + (m33 * n33);
×
1599
  }
1600

1601
  /// Multiply a copy of this with [arg].
1602
  Matrix4 multiplied(Matrix4 arg) => clone()..multiply(arg);
×
1603

1604
  /// Multiply a transposed this with [arg].
1605
  void transposeMultiply(Matrix4 arg) {
×
1606
    final m00 = _m4storage[0];
×
1607
    final m01 = _m4storage[1];
×
1608
    final m02 = _m4storage[2];
×
1609
    final m03 = _m4storage[3];
×
1610
    final m10 = _m4storage[4];
×
1611
    final m11 = _m4storage[5];
×
1612
    final m12 = _m4storage[6];
×
1613
    final m13 = _m4storage[7];
×
1614
    final m20 = _m4storage[8];
×
1615
    final m21 = _m4storage[9];
×
1616
    final m22 = _m4storage[10];
×
1617
    final m23 = _m4storage[11];
×
1618
    final m30 = _m4storage[12];
×
1619
    final m31 = _m4storage[13];
×
1620
    final m32 = _m4storage[14];
×
1621
    final m33 = _m4storage[15];
×
1622
    final argStorage = arg._m4storage;
×
1623
    _m4storage[0] = (m00 * argStorage[0]) +
×
1624
        (m01 * argStorage[1]) +
×
1625
        (m02 * argStorage[2]) +
×
1626
        (m03 * argStorage[3]);
×
1627
    _m4storage[4] = (m00 * argStorage[4]) +
×
1628
        (m01 * argStorage[5]) +
×
1629
        (m02 * argStorage[6]) +
×
1630
        (m03 * argStorage[7]);
×
1631
    _m4storage[8] = (m00 * argStorage[8]) +
×
1632
        (m01 * argStorage[9]) +
×
1633
        (m02 * argStorage[10]) +
×
1634
        (m03 * argStorage[11]);
×
1635
    _m4storage[12] = (m00 * argStorage[12]) +
×
1636
        (m01 * argStorage[13]) +
×
1637
        (m02 * argStorage[14]) +
×
1638
        (m03 * argStorage[15]);
×
1639
    _m4storage[1] = (m10 * argStorage[0]) +
×
1640
        (m11 * argStorage[1]) +
×
1641
        (m12 * argStorage[2]) +
×
1642
        (m13 * argStorage[3]);
×
1643
    _m4storage[5] = (m10 * argStorage[4]) +
×
1644
        (m11 * argStorage[5]) +
×
1645
        (m12 * argStorage[6]) +
×
1646
        (m13 * argStorage[7]);
×
1647
    _m4storage[9] = (m10 * argStorage[8]) +
×
1648
        (m11 * argStorage[9]) +
×
1649
        (m12 * argStorage[10]) +
×
1650
        (m13 * argStorage[11]);
×
1651
    _m4storage[13] = (m10 * argStorage[12]) +
×
1652
        (m11 * argStorage[13]) +
×
1653
        (m12 * argStorage[14]) +
×
1654
        (m13 * argStorage[15]);
×
1655
    _m4storage[2] = (m20 * argStorage[0]) +
×
1656
        (m21 * argStorage[1]) +
×
1657
        (m22 * argStorage[2]) +
×
1658
        (m23 * argStorage[3]);
×
1659
    _m4storage[6] = (m20 * argStorage[4]) +
×
1660
        (m21 * argStorage[5]) +
×
1661
        (m22 * argStorage[6]) +
×
1662
        (m23 * argStorage[7]);
×
1663
    _m4storage[10] = (m20 * argStorage[8]) +
×
1664
        (m21 * argStorage[9]) +
×
1665
        (m22 * argStorage[10]) +
×
1666
        (m23 * argStorage[11]);
×
1667
    _m4storage[14] = (m20 * argStorage[12]) +
×
1668
        (m21 * argStorage[13]) +
×
1669
        (m22 * argStorage[14]) +
×
1670
        (m23 * argStorage[15]);
×
1671
    _m4storage[3] = (m30 * argStorage[0]) +
×
1672
        (m31 * argStorage[1]) +
×
1673
        (m32 * argStorage[2]) +
×
1674
        (m33 * argStorage[3]);
×
1675
    _m4storage[7] = (m30 * argStorage[4]) +
×
1676
        (m31 * argStorage[5]) +
×
1677
        (m32 * argStorage[6]) +
×
1678
        (m33 * argStorage[7]);
×
1679
    _m4storage[11] = (m30 * argStorage[8]) +
×
1680
        (m31 * argStorage[9]) +
×
1681
        (m32 * argStorage[10]) +
×
1682
        (m33 * argStorage[11]);
×
1683
    _m4storage[15] = (m30 * argStorage[12]) +
×
1684
        (m31 * argStorage[13]) +
×
1685
        (m32 * argStorage[14]) +
×
1686
        (m33 * argStorage[15]);
×
1687
  }
1688

1689
  /// Multiply this with a transposed [arg].
1690
  void multiplyTranspose(Matrix4 arg) {
×
1691
    final m00 = _m4storage[0];
×
1692
    final m01 = _m4storage[4];
×
1693
    final m02 = _m4storage[8];
×
1694
    final m03 = _m4storage[12];
×
1695
    final m10 = _m4storage[1];
×
1696
    final m11 = _m4storage[5];
×
1697
    final m12 = _m4storage[9];
×
1698
    final m13 = _m4storage[13];
×
1699
    final m20 = _m4storage[2];
×
1700
    final m21 = _m4storage[6];
×
1701
    final m22 = _m4storage[10];
×
1702
    final m23 = _m4storage[14];
×
1703
    final m30 = _m4storage[3];
×
1704
    final m31 = _m4storage[7];
×
1705
    final m32 = _m4storage[11];
×
1706
    final m33 = _m4storage[15];
×
1707
    final argStorage = arg._m4storage;
×
1708
    _m4storage[0] = (m00 * argStorage[0]) +
×
1709
        (m01 * argStorage[4]) +
×
1710
        (m02 * argStorage[8]) +
×
1711
        (m03 * argStorage[12]);
×
1712
    _m4storage[4] = (m00 * argStorage[1]) +
×
1713
        (m01 * argStorage[5]) +
×
1714
        (m02 * argStorage[9]) +
×
1715
        (m03 * argStorage[13]);
×
1716
    _m4storage[8] = (m00 * argStorage[2]) +
×
1717
        (m01 * argStorage[6]) +
×
1718
        (m02 * argStorage[10]) +
×
1719
        (m03 * argStorage[14]);
×
1720
    _m4storage[12] = (m00 * argStorage[3]) +
×
1721
        (m01 * argStorage[7]) +
×
1722
        (m02 * argStorage[11]) +
×
1723
        (m03 * argStorage[15]);
×
1724
    _m4storage[1] = (m10 * argStorage[0]) +
×
1725
        (m11 * argStorage[4]) +
×
1726
        (m12 * argStorage[8]) +
×
1727
        (m13 * argStorage[12]);
×
1728
    _m4storage[5] = (m10 * argStorage[1]) +
×
1729
        (m11 * argStorage[5]) +
×
1730
        (m12 * argStorage[9]) +
×
1731
        (m13 * argStorage[13]);
×
1732
    _m4storage[9] = (m10 * argStorage[2]) +
×
1733
        (m11 * argStorage[6]) +
×
1734
        (m12 * argStorage[10]) +
×
1735
        (m13 * argStorage[14]);
×
1736
    _m4storage[13] = (m10 * argStorage[3]) +
×
1737
        (m11 * argStorage[7]) +
×
1738
        (m12 * argStorage[11]) +
×
1739
        (m13 * argStorage[15]);
×
1740
    _m4storage[2] = (m20 * argStorage[0]) +
×
1741
        (m21 * argStorage[4]) +
×
1742
        (m22 * argStorage[8]) +
×
1743
        (m23 * argStorage[12]);
×
1744
    _m4storage[6] = (m20 * argStorage[1]) +
×
1745
        (m21 * argStorage[5]) +
×
1746
        (m22 * argStorage[9]) +
×
1747
        (m23 * argStorage[13]);
×
1748
    _m4storage[10] = (m20 * argStorage[2]) +
×
1749
        (m21 * argStorage[6]) +
×
1750
        (m22 * argStorage[10]) +
×
1751
        (m23 * argStorage[14]);
×
1752
    _m4storage[14] = (m20 * argStorage[3]) +
×
1753
        (m21 * argStorage[7]) +
×
1754
        (m22 * argStorage[11]) +
×
1755
        (m23 * argStorage[15]);
×
1756
    _m4storage[3] = (m30 * argStorage[0]) +
×
1757
        (m31 * argStorage[4]) +
×
1758
        (m32 * argStorage[8]) +
×
1759
        (m33 * argStorage[12]);
×
1760
    _m4storage[7] = (m30 * argStorage[1]) +
×
1761
        (m31 * argStorage[5]) +
×
1762
        (m32 * argStorage[9]) +
×
1763
        (m33 * argStorage[13]);
×
1764
    _m4storage[11] = (m30 * argStorage[2]) +
×
1765
        (m31 * argStorage[6]) +
×
1766
        (m32 * argStorage[10]) +
×
1767
        (m33 * argStorage[14]);
×
1768
    _m4storage[15] = (m30 * argStorage[3]) +
×
1769
        (m31 * argStorage[7]) +
×
1770
        (m32 * argStorage[11]) +
×
1771
        (m33 * argStorage[15]);
×
1772
  }
1773

1774
  /// Decomposes this into [translation], [rotation] and [scale] components.
1775
  void decompose(Vector3 translation, Quaternion rotation, Vector3 scale) {
×
1776
    final v = _decomposeV ??= Vector3.zero();
×
1777
    var sx = (v..setValues(_m4storage[0], _m4storage[1], _m4storage[2])).length;
×
1778
    final sy =
1779
        (v..setValues(_m4storage[4], _m4storage[5], _m4storage[6])).length;
×
1780
    final sz =
1781
        (v..setValues(_m4storage[8], _m4storage[9], _m4storage[10])).length;
×
1782

1783
    if (determinant() < 0) {
×
1784
      sx = -sx;
×
1785
    }
1786

1787
    translation._v3storage[0] = _m4storage[12];
×
1788
    translation._v3storage[1] = _m4storage[13];
×
1789
    translation._v3storage[2] = _m4storage[14];
×
1790

1791
    final invSX = 1.0 / sx;
×
1792
    final invSY = 1.0 / sy;
×
1793
    final invSZ = 1.0 / sz;
×
1794

1795
    final m = _decomposeM ??= Matrix4.zero();
×
1796
    m.setFrom(this);
×
1797
    m._m4storage[0] *= invSX;
×
1798
    m._m4storage[1] *= invSX;
×
1799
    m._m4storage[2] *= invSX;
×
1800
    m._m4storage[4] *= invSY;
×
1801
    m._m4storage[5] *= invSY;
×
1802
    m._m4storage[6] *= invSY;
×
1803
    m._m4storage[8] *= invSZ;
×
1804
    m._m4storage[9] *= invSZ;
×
1805
    m._m4storage[10] *= invSZ;
×
1806

1807
    final r = _decomposeR ??= Matrix3.zero();
×
1808
    m.copyRotation(r);
×
1809
    rotation.setFromRotation(r);
×
1810

1811
    scale._v3storage[0] = sx;
×
1812
    scale._v3storage[1] = sy;
×
1813
    scale._v3storage[2] = sz;
×
1814
  }
1815

1816
  static Vector3? _decomposeV;
1817
  static Matrix4? _decomposeM;
1818
  static Matrix3? _decomposeR;
1819

1820
  /// Rotate [arg] of type [Vector3] using the rotation defined by this.
1821
  Vector3 rotate3(Vector3 arg) {
×
1822
    final argStorage = arg._v3storage;
×
1823
    final x_ = (_m4storage[0] * argStorage[0]) +
×
1824
        (_m4storage[4] * argStorage[1]) +
×
1825
        (_m4storage[8] * argStorage[2]);
×
1826
    final y_ = (_m4storage[1] * argStorage[0]) +
×
1827
        (_m4storage[5] * argStorage[1]) +
×
1828
        (_m4storage[9] * argStorage[2]);
×
1829
    final z_ = (_m4storage[2] * argStorage[0]) +
×
1830
        (_m4storage[6] * argStorage[1]) +
×
1831
        (_m4storage[10] * argStorage[2]);
×
1832
    argStorage[0] = x_;
×
1833
    argStorage[1] = y_;
×
1834
    argStorage[2] = z_;
×
1835
    return arg;
1836
  }
1837

1838
  /// Rotate a copy of [arg] of type [Vector3] using the rotation defined by
1839
  /// this. If a [out] parameter is supplied, the copy is stored in [out].
1840
  Vector3 rotated3(Vector3 arg, [Vector3? out]) {
×
1841
    if (out == null) {
1842
      out = Vector3.copy(arg);
×
1843
    } else {
1844
      out.setFrom(arg);
×
1845
    }
1846
    return rotate3(out);
×
1847
  }
1848

1849
  /// Transform [arg] of type [Vector3] using the transformation defined by
1850
  /// this.
1851
  Vector3 transform3(Vector3 arg) {
×
1852
    final argStorage = arg._v3storage;
×
1853
    final x_ = (_m4storage[0] * argStorage[0]) +
×
1854
        (_m4storage[4] * argStorage[1]) +
×
1855
        (_m4storage[8] * argStorage[2]) +
×
1856
        _m4storage[12];
×
1857
    final y_ = (_m4storage[1] * argStorage[0]) +
×
1858
        (_m4storage[5] * argStorage[1]) +
×
1859
        (_m4storage[9] * argStorage[2]) +
×
1860
        _m4storage[13];
×
1861
    final z_ = (_m4storage[2] * argStorage[0]) +
×
1862
        (_m4storage[6] * argStorage[1]) +
×
1863
        (_m4storage[10] * argStorage[2]) +
×
1864
        _m4storage[14];
×
1865
    argStorage[0] = x_;
×
1866
    argStorage[1] = y_;
×
1867
    argStorage[2] = z_;
×
1868
    return arg;
1869
  }
1870

1871
  /// Transform a copy of [arg] of type [Vector3] using the transformation
1872
  /// defined by this. If a [out] parameter is supplied, the copy is stored in
1873
  /// [out].
1874
  Vector3 transformed3(Vector3 arg, [Vector3? out]) {
×
1875
    if (out == null) {
1876
      out = Vector3.copy(arg);
×
1877
    } else {
1878
      out.setFrom(arg);
×
1879
    }
1880
    return transform3(out);
×
1881
  }
1882

1883
  /// Transform [arg] of type [Vector4] using the transformation defined by
1884
  /// this.
1885
  Vector4 transform(Vector4 arg) {
×
1886
    final argStorage = arg._v4storage;
×
1887
    final x_ = (_m4storage[0] * argStorage[0]) +
×
1888
        (_m4storage[4] * argStorage[1]) +
×
1889
        (_m4storage[8] * argStorage[2]) +
×
1890
        (_m4storage[12] * argStorage[3]);
×
1891
    final y_ = (_m4storage[1] * argStorage[0]) +
×
1892
        (_m4storage[5] * argStorage[1]) +
×
1893
        (_m4storage[9] * argStorage[2]) +
×
1894
        (_m4storage[13] * argStorage[3]);
×
1895
    final z_ = (_m4storage[2] * argStorage[0]) +
×
1896
        (_m4storage[6] * argStorage[1]) +
×
1897
        (_m4storage[10] * argStorage[2]) +
×
1898
        (_m4storage[14] * argStorage[3]);
×
1899
    final w_ = (_m4storage[3] * argStorage[0]) +
×
1900
        (_m4storage[7] * argStorage[1]) +
×
1901
        (_m4storage[11] * argStorage[2]) +
×
1902
        (_m4storage[15] * argStorage[3]);
×
1903
    argStorage[0] = x_;
×
1904
    argStorage[1] = y_;
×
1905
    argStorage[2] = z_;
×
1906
    argStorage[3] = w_;
×
1907
    return arg;
1908
  }
1909

1910
  /// Transform [arg] of type [Vector3] using the perspective transformation
1911
  /// defined by this.
1912
  Vector3 perspectiveTransform(Vector3 arg) {
×
1913
    final argStorage = arg._v3storage;
×
1914
    final x_ = (_m4storage[0] * argStorage[0]) +
×
1915
        (_m4storage[4] * argStorage[1]) +
×
1916
        (_m4storage[8] * argStorage[2]) +
×
1917
        _m4storage[12];
×
1918
    final y_ = (_m4storage[1] * argStorage[0]) +
×
1919
        (_m4storage[5] * argStorage[1]) +
×
1920
        (_m4storage[9] * argStorage[2]) +
×
1921
        _m4storage[13];
×
1922
    final z_ = (_m4storage[2] * argStorage[0]) +
×
1923
        (_m4storage[6] * argStorage[1]) +
×
1924
        (_m4storage[10] * argStorage[2]) +
×
1925
        _m4storage[14];
×
1926
    final w_ = 1.0 /
×
1927
        ((_m4storage[3] * argStorage[0]) +
×
1928
            (_m4storage[7] * argStorage[1]) +
×
1929
            (_m4storage[11] * argStorage[2]) +
×
1930
            _m4storage[15]);
×
1931
    argStorage[0] = x_ * w_;
×
1932
    argStorage[1] = y_ * w_;
×
1933
    argStorage[2] = z_ * w_;
×
1934
    return arg;
1935
  }
1936

1937
  /// Transform a copy of [arg] of type [Vector4] using the transformation
1938
  /// defined by this. If a [out] parameter is supplied, the copy is stored in
1939
  /// [out].
1940
  Vector4 transformed(Vector4 arg, [Vector4? out]) {
×
1941
    if (out == null) {
1942
      out = Vector4.copy(arg);
×
1943
    } else {
1944
      out.setFrom(arg);
×
1945
    }
1946
    return transform(out);
×
1947
  }
1948

1949
  /// Copies this into [array] starting at [offset].
1950
  void copyIntoArray(List<num> array, [int offset = 0]) {
×
1951
    final i = offset;
1952
    array[i + 15] = _m4storage[15];
×
1953
    array[i + 14] = _m4storage[14];
×
1954
    array[i + 13] = _m4storage[13];
×
1955
    array[i + 12] = _m4storage[12];
×
1956
    array[i + 11] = _m4storage[11];
×
1957
    array[i + 10] = _m4storage[10];
×
1958
    array[i + 9] = _m4storage[9];
×
1959
    array[i + 8] = _m4storage[8];
×
1960
    array[i + 7] = _m4storage[7];
×
1961
    array[i + 6] = _m4storage[6];
×
1962
    array[i + 5] = _m4storage[5];
×
1963
    array[i + 4] = _m4storage[4];
×
1964
    array[i + 3] = _m4storage[3];
×
1965
    array[i + 2] = _m4storage[2];
×
1966
    array[i + 1] = _m4storage[1];
×
1967
    array[i + 0] = _m4storage[0];
×
1968
  }
1969

1970
  /// Copies elements from [array] into this starting at [offset].
1971
  void copyFromArray(List<double> array, [int offset = 0]) {
×
1972
    final i = offset;
1973
    _m4storage[15] = array[i + 15];
×
1974
    _m4storage[14] = array[i + 14];
×
1975
    _m4storage[13] = array[i + 13];
×
1976
    _m4storage[12] = array[i + 12];
×
1977
    _m4storage[11] = array[i + 11];
×
1978
    _m4storage[10] = array[i + 10];
×
1979
    _m4storage[9] = array[i + 9];
×
1980
    _m4storage[8] = array[i + 8];
×
1981
    _m4storage[7] = array[i + 7];
×
1982
    _m4storage[6] = array[i + 6];
×
1983
    _m4storage[5] = array[i + 5];
×
1984
    _m4storage[4] = array[i + 4];
×
1985
    _m4storage[3] = array[i + 3];
×
1986
    _m4storage[2] = array[i + 2];
×
1987
    _m4storage[1] = array[i + 1];
×
1988
    _m4storage[0] = array[i + 0];
×
1989
  }
1990

1991
  /// Multiply this to each set of xyz values in [array] starting at [offset].
1992
  List<double> applyToVector3Array(List<double> array, [int offset = 0]) {
×
1993
    for (var i = 0, j = offset; i < array.length; i += 3, j += 3) {
×
1994
      final v = Vector3.array(array, j)..applyMatrix4(this);
×
1995
      array[j] = v.storage[0];
×
1996
      array[j + 1] = v.storage[1];
×
1997
      array[j + 2] = v.storage[2];
×
1998
    }
1999

2000
    return array;
2001
  }
2002

2003
  Vector3 get right {
×
2004
    final x = _m4storage[0];
×
2005
    final y = _m4storage[1];
×
2006
    final z = _m4storage[2];
×
2007
    return Vector3(x, y, z);
×
2008
  }
2009

2010
  Vector3 get up {
×
2011
    final x = _m4storage[4];
×
2012
    final y = _m4storage[5];
×
2013
    final z = _m4storage[6];
×
2014
    return Vector3(x, y, z);
×
2015
  }
2016

2017
  Vector3 get forward {
×
2018
    final x = _m4storage[8];
×
2019
    final y = _m4storage[9];
×
2020
    final z = _m4storage[10];
×
2021
    return Vector3(x, y, z);
×
2022
  }
2023

2024
  /// Is this the identity matrix?
2025
  bool isIdentity() =>
×
2026
      _m4storage[0] == 1.0 // col 1
×
2027
      &&
2028
      _m4storage[1] == 0.0 &&
×
2029
      _m4storage[2] == 0.0 &&
×
2030
      _m4storage[3] == 0.0 &&
×
2031
      _m4storage[4] == 0.0 // col 2
×
2032
      &&
2033
      _m4storage[5] == 1.0 &&
×
2034
      _m4storage[6] == 0.0 &&
×
2035
      _m4storage[7] == 0.0 &&
×
2036
      _m4storage[8] == 0.0 // col 3
×
2037
      &&
2038
      _m4storage[9] == 0.0 &&
×
2039
      _m4storage[10] == 1.0 &&
×
2040
      _m4storage[11] == 0.0 &&
×
2041
      _m4storage[12] == 0.0 // col 4
×
2042
      &&
2043
      _m4storage[13] == 0.0 &&
×
2044
      _m4storage[14] == 0.0 &&
×
2045
      _m4storage[15] == 1.0;
×
2046

2047
  /// Is this the zero matrix?
2048
  bool isZero() =>
×
2049
      _m4storage[0] == 0.0 // col 1
×
2050
      &&
2051
      _m4storage[1] == 0.0 &&
×
2052
      _m4storage[2] == 0.0 &&
×
2053
      _m4storage[3] == 0.0 &&
×
2054
      _m4storage[4] == 0.0 // col 2
×
2055
      &&
2056
      _m4storage[5] == 0.0 &&
×
2057
      _m4storage[6] == 0.0 &&
×
2058
      _m4storage[7] == 0.0 &&
×
2059
      _m4storage[8] == 0.0 // col 3
×
2060
      &&
2061
      _m4storage[9] == 0.0 &&
×
2062
      _m4storage[10] == 0.0 &&
×
2063
      _m4storage[11] == 0.0 &&
×
2064
      _m4storage[12] == 0.0 // col 4
×
2065
      &&
2066
      _m4storage[13] == 0.0 &&
×
2067
      _m4storage[14] == 0.0 &&
×
2068
      _m4storage[15] == 0.0;
×
2069
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc