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

google / vector_math.dart / 17181727464

04 Aug 2025 07:19PM UTC coverage: 26.702% (+0.3%) from 26.388%
17181727464

push

github

web-flow
Bump min SDK to 3.7, update dependencies, reformat (#348)

496 of 1182 new or added lines in 55 files covered. (41.96%)

18 existing lines in 8 files now uncovered.

4463 of 16714 relevant lines covered (26.7%)

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

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

166
  /// Return index in storage for [row], [col] value.
167
  int index(int row, int col) => (col * 4) + row;
×
168

169
  /// Value at [row], [col].
170
  double entry(int row, int col) {
×
171
    assert((row >= 0) && (row < dimension));
×
172
    assert((col >= 0) && (col < dimension));
×
173

174
    return _m4storage[index(row, col)];
×
175
  }
176

177
  /// Set value at [row], [col] to be [v].
178
  void setEntry(int row, int col, double v) {
×
179
    assert((row >= 0) && (row < dimension));
×
180
    assert((col >= 0) && (col < dimension));
×
181

182
    _m4storage[index(row, col)] = v;
×
183
  }
184

185
  /// Constructs a new mat4.
186
  factory Matrix4(
×
187
    double arg0,
188
    double arg1,
189
    double arg2,
190
    double arg3,
191
    double arg4,
192
    double arg5,
193
    double arg6,
194
    double arg7,
195
    double arg8,
196
    double arg9,
197
    double arg10,
198
    double arg11,
199
    double arg12,
200
    double arg13,
201
    double arg14,
202
    double arg15,
203
  ) =>
NEW
204
      Matrix4.zero()..setValues(
×
205
        arg0,
206
        arg1,
207
        arg2,
208
        arg3,
209
        arg4,
210
        arg5,
211
        arg6,
212
        arg7,
213
        arg8,
214
        arg9,
215
        arg10,
216
        arg11,
217
        arg12,
218
        arg13,
219
        arg14,
220
        arg15,
221
      );
222

223
  /// New matrix from [values].
NEW
224
  factory Matrix4.fromList(List<double> values) =>
×
NEW
225
      Matrix4.zero()..setValues(
×
226
        values[0],
×
227
        values[1],
×
228
        values[2],
×
229
        values[3],
×
230
        values[4],
×
231
        values[5],
×
232
        values[6],
×
233
        values[7],
×
234
        values[8],
×
235
        values[9],
×
236
        values[10],
×
237
        values[11],
×
238
        values[12],
×
239
        values[13],
×
240
        values[14],
×
NEW
241
        values[15],
×
242
      );
243

244
  /// Zero matrix.
245
  Matrix4.zero() : _m4storage = Float64List(16);
×
246

247
  /// Identity matrix.
248
  factory Matrix4.identity() => Matrix4.zero()..setIdentity();
×
249

250
  /// Copies values from [other].
251
  factory Matrix4.copy(Matrix4 other) => Matrix4.zero()..setFrom(other);
×
252

253
  /// Constructs a matrix that is the inverse of [other].
254
  factory Matrix4.inverted(Matrix4 other) {
×
255
    final r = Matrix4.zero();
×
256
    final determinant = r.copyInverse(other);
×
257
    if (determinant == 0.0) {
×
258
      throw ArgumentError.value(other, 'other', 'Matrix cannot be inverted');
×
259
    }
260
    return r;
261
  }
262

263
  /// Constructs a new mat4 from columns.
264
  factory Matrix4.columns(
×
265
    Vector4 arg0,
266
    Vector4 arg1,
267
    Vector4 arg2,
268
    Vector4 arg3,
NEW
269
  ) => Matrix4.zero()..setColumns(arg0, arg1, arg2, arg3);
×
270

271
  /// Outer product of [u] and [v].
272
  factory Matrix4.outer(Vector4 u, Vector4 v) => Matrix4.zero()..setOuter(u, v);
×
273

274
  /// Rotation of [radians] around X.
NEW
275
  factory Matrix4.rotationX(double radians) =>
×
NEW
276
      Matrix4.zero()
×
NEW
277
        .._m4storage[15] = 1.0
×
NEW
278
        ..setRotationX(radians);
×
279

280
  /// Rotation of [radians] around Y.
NEW
281
  factory Matrix4.rotationY(double radians) =>
×
NEW
282
      Matrix4.zero()
×
NEW
283
        .._m4storage[15] = 1.0
×
NEW
284
        ..setRotationY(radians);
×
285

286
  /// Rotation of [radians] around Z.
NEW
287
  factory Matrix4.rotationZ(double radians) =>
×
NEW
288
      Matrix4.zero()
×
NEW
289
        .._m4storage[15] = 1.0
×
NEW
290
        ..setRotationZ(radians);
×
291

292
  /// Translation matrix.
NEW
293
  factory Matrix4.translation(Vector3 translation) =>
×
NEW
294
      Matrix4.zero()
×
NEW
295
        ..setIdentity()
×
NEW
296
        ..setTranslation(translation);
×
297

298
  /// Translation matrix.
299
  factory Matrix4.translationValues(double x, double y, double z) =>
×
300
      Matrix4.zero()
×
301
        ..setIdentity()
×
302
        ..setTranslationRaw(x, y, z);
×
303

304
  /// Scale matrix.
305
  factory Matrix4.diagonal3(Vector3 scale) {
×
306
    final m = Matrix4.zero();
×
307
    final mStorage = m._m4storage;
×
308
    final scaleStorage = scale._v3storage;
×
309
    mStorage[15] = 1.0;
×
310
    mStorage[10] = scaleStorage[2];
×
311
    mStorage[5] = scaleStorage[1];
×
312
    mStorage[0] = scaleStorage[0];
×
313
    return m;
314
  }
315

316
  /// Scale matrix.
317
  factory Matrix4.diagonal3Values(double x, double y, double z) =>
×
318
      Matrix4.zero()
×
319
        .._m4storage[15] = 1.0
×
320
        .._m4storage[10] = z
×
321
        .._m4storage[5] = y
×
322
        .._m4storage[0] = x;
×
323

324
  /// Skew matrix around X axis
325
  factory Matrix4.skewX(double alpha) {
×
326
    final m = Matrix4.identity();
×
327
    m._m4storage[4] = math.tan(alpha);
×
328
    return m;
329
  }
330

331
  /// Skew matrix around Y axis.
332
  factory Matrix4.skewY(double beta) {
×
333
    final m = Matrix4.identity();
×
334
    m._m4storage[1] = math.tan(beta);
×
335
    return m;
336
  }
337

338
  /// Skew matrix around X axis (alpha) and Y axis (beta).
339
  factory Matrix4.skew(double alpha, double beta) {
×
340
    final m = Matrix4.identity();
×
341
    m._m4storage[1] = math.tan(beta);
×
342
    m._m4storage[4] = math.tan(alpha);
×
343
    return m;
344
  }
345

346
  /// Constructs Matrix4 with given [Float64List] as [storage].
347
  Matrix4.fromFloat64List(this._m4storage);
×
348

349
  /// Constructs Matrix4 with a [storage] that views given [buffer] starting at
350
  /// [offset]. [offset] has to be multiple of [Float64List.bytesPerElement].
351
  Matrix4.fromBuffer(ByteBuffer buffer, int offset)
×
NEW
352
    : _m4storage = Float64List.view(buffer, offset, 16);
×
353

354
  /// Constructs Matrix4 from [translation], [rotation] and [scale].
355
  factory Matrix4.compose(
×
356
    Vector3 translation,
357
    Quaternion rotation,
358
    Vector3 scale,
359
  ) =>
360
      Matrix4.zero()
×
361
        ..setFromTranslationRotationScale(translation, rotation, scale);
×
362

363
  /// Sets the diagonal to [arg].
364
  void splatDiagonal(double arg) {
×
365
    _m4storage[0] = arg;
×
366
    _m4storage[5] = arg;
×
367
    _m4storage[10] = arg;
×
368
    _m4storage[15] = arg;
×
369
  }
370

371
  /// Sets the matrix with specified values.
372
  void setValues(
×
373
    double arg0,
374
    double arg1,
375
    double arg2,
376
    double arg3,
377
    double arg4,
378
    double arg5,
379
    double arg6,
380
    double arg7,
381
    double arg8,
382
    double arg9,
383
    double arg10,
384
    double arg11,
385
    double arg12,
386
    double arg13,
387
    double arg14,
388
    double arg15,
389
  ) {
390
    _m4storage[15] = arg15;
×
391
    _m4storage[14] = arg14;
×
392
    _m4storage[13] = arg13;
×
393
    _m4storage[12] = arg12;
×
394
    _m4storage[11] = arg11;
×
395
    _m4storage[10] = arg10;
×
396
    _m4storage[9] = arg9;
×
397
    _m4storage[8] = arg8;
×
398
    _m4storage[7] = arg7;
×
399
    _m4storage[6] = arg6;
×
400
    _m4storage[5] = arg5;
×
401
    _m4storage[4] = arg4;
×
402
    _m4storage[3] = arg3;
×
403
    _m4storage[2] = arg2;
×
404
    _m4storage[1] = arg1;
×
405
    _m4storage[0] = arg0;
×
406
  }
407

408
  /// Sets the entire matrix to the column values.
409
  void setColumns(Vector4 arg0, Vector4 arg1, Vector4 arg2, Vector4 arg3) {
×
410
    final arg0Storage = arg0._v4storage;
×
411
    final arg1Storage = arg1._v4storage;
×
412
    final arg2Storage = arg2._v4storage;
×
413
    final arg3Storage = arg3._v4storage;
×
414
    _m4storage[0] = arg0Storage[0];
×
415
    _m4storage[1] = arg0Storage[1];
×
416
    _m4storage[2] = arg0Storage[2];
×
417
    _m4storage[3] = arg0Storage[3];
×
418
    _m4storage[4] = arg1Storage[0];
×
419
    _m4storage[5] = arg1Storage[1];
×
420
    _m4storage[6] = arg1Storage[2];
×
421
    _m4storage[7] = arg1Storage[3];
×
422
    _m4storage[8] = arg2Storage[0];
×
423
    _m4storage[9] = arg2Storage[1];
×
424
    _m4storage[10] = arg2Storage[2];
×
425
    _m4storage[11] = arg2Storage[3];
×
426
    _m4storage[12] = arg3Storage[0];
×
427
    _m4storage[13] = arg3Storage[1];
×
428
    _m4storage[14] = arg3Storage[2];
×
429
    _m4storage[15] = arg3Storage[3];
×
430
  }
431

432
  /// Sets the entire matrix to the matrix in [arg].
433
  void setFrom(Matrix4 arg) {
×
434
    final argStorage = arg._m4storage;
×
435
    _m4storage[15] = argStorage[15];
×
436
    _m4storage[14] = argStorage[14];
×
437
    _m4storage[13] = argStorage[13];
×
438
    _m4storage[12] = argStorage[12];
×
439
    _m4storage[11] = argStorage[11];
×
440
    _m4storage[10] = argStorage[10];
×
441
    _m4storage[9] = argStorage[9];
×
442
    _m4storage[8] = argStorage[8];
×
443
    _m4storage[7] = argStorage[7];
×
444
    _m4storage[6] = argStorage[6];
×
445
    _m4storage[5] = argStorage[5];
×
446
    _m4storage[4] = argStorage[4];
×
447
    _m4storage[3] = argStorage[3];
×
448
    _m4storage[2] = argStorage[2];
×
449
    _m4storage[1] = argStorage[1];
×
450
    _m4storage[0] = argStorage[0];
×
451
  }
452

453
  /// Sets the matrix from translation [arg0] and rotation [arg1].
454
  void setFromTranslationRotation(Vector3 arg0, Quaternion arg1) {
×
455
    final arg1Storage = arg1._qStorage;
×
456
    final x = arg1Storage[0];
×
457
    final y = arg1Storage[1];
×
458
    final z = arg1Storage[2];
×
459
    final w = arg1Storage[3];
×
460
    final x2 = x + x;
×
461
    final y2 = y + y;
×
462
    final z2 = z + z;
×
463
    final xx = x * x2;
×
464
    final xy = x * y2;
×
465
    final xz = x * z2;
×
466
    final yy = y * y2;
×
467
    final yz = y * z2;
×
468
    final zz = z * z2;
×
469
    final wx = w * x2;
×
470
    final wy = w * y2;
×
471
    final wz = w * z2;
×
472

473
    final arg0Storage = arg0._v3storage;
×
474
    _m4storage[0] = 1.0 - (yy + zz);
×
475
    _m4storage[1] = xy + wz;
×
476
    _m4storage[2] = xz - wy;
×
477
    _m4storage[3] = 0.0;
×
478
    _m4storage[4] = xy - wz;
×
479
    _m4storage[5] = 1.0 - (xx + zz);
×
480
    _m4storage[6] = yz + wx;
×
481
    _m4storage[7] = 0.0;
×
482
    _m4storage[8] = xz + wy;
×
483
    _m4storage[9] = yz - wx;
×
484
    _m4storage[10] = 1.0 - (xx + yy);
×
485
    _m4storage[11] = 0.0;
×
486
    _m4storage[12] = arg0Storage[0];
×
487
    _m4storage[13] = arg0Storage[1];
×
488
    _m4storage[14] = arg0Storage[2];
×
489
    _m4storage[15] = 1.0;
×
490
  }
491

492
  /// Sets the matrix from [translation], [rotation] and [scale].
493
  void setFromTranslationRotationScale(
×
494
    Vector3 translation,
495
    Quaternion rotation,
496
    Vector3 scale,
497
  ) {
498
    setFromTranslationRotation(translation, rotation);
×
499
    scaleByVector3(scale);
×
500
  }
501

502
  /// Sets the upper 2x2 of the matrix to be [arg].
503
  void setUpper2x2(Matrix2 arg) {
×
504
    final argStorage = arg._m2storage;
×
505
    _m4storage[0] = argStorage[0];
×
506
    _m4storage[1] = argStorage[1];
×
507
    _m4storage[4] = argStorage[2];
×
508
    _m4storage[5] = argStorage[3];
×
509
  }
510

511
  /// Sets the diagonal of the matrix to be [arg].
512
  void setDiagonal(Vector4 arg) {
×
513
    final argStorage = arg._v4storage;
×
514
    _m4storage[0] = argStorage[0];
×
515
    _m4storage[5] = argStorage[1];
×
516
    _m4storage[10] = argStorage[2];
×
517
    _m4storage[15] = argStorage[3];
×
518
  }
519

520
  void setOuter(Vector4 u, Vector4 v) {
×
521
    final uStorage = u._v4storage;
×
522
    final vStorage = v._v4storage;
×
523
    _m4storage[0] = uStorage[0] * vStorage[0];
×
524
    _m4storage[1] = uStorage[0] * vStorage[1];
×
525
    _m4storage[2] = uStorage[0] * vStorage[2];
×
526
    _m4storage[3] = uStorage[0] * vStorage[3];
×
527
    _m4storage[4] = uStorage[1] * vStorage[0];
×
528
    _m4storage[5] = uStorage[1] * vStorage[1];
×
529
    _m4storage[6] = uStorage[1] * vStorage[2];
×
530
    _m4storage[7] = uStorage[1] * vStorage[3];
×
531
    _m4storage[8] = uStorage[2] * vStorage[0];
×
532
    _m4storage[9] = uStorage[2] * vStorage[1];
×
533
    _m4storage[10] = uStorage[2] * vStorage[2];
×
534
    _m4storage[11] = uStorage[2] * vStorage[3];
×
535
    _m4storage[12] = uStorage[3] * vStorage[0];
×
536
    _m4storage[13] = uStorage[3] * vStorage[1];
×
537
    _m4storage[14] = uStorage[3] * vStorage[2];
×
538
    _m4storage[15] = uStorage[3] * vStorage[3];
×
539
  }
540

541
  /// Returns a printable string
542
  @override
×
NEW
543
  String toString() =>
×
NEW
544
      '[0] ${getRow(0)}\n[1] ${getRow(1)}\n'
×
UNCOV
545
      '[2] ${getRow(2)}\n[3] ${getRow(3)}\n';
×
546

547
  /// Dimension of the matrix.
548
  int get dimension => 4;
×
549

550
  /// Access the element of the matrix at the index [i].
551
  double operator [](int i) => _m4storage[i];
×
552

553
  /// Set the element of the matrix at the index [i].
554
  void operator []=(int i, double v) {
×
555
    _m4storage[i] = v;
×
556
  }
557

558
  /// Check if two matrices are the same.
559
  @override
×
560
  bool operator ==(Object other) =>
561
      (other is Matrix4) &&
×
562
      (_m4storage[0] == other._m4storage[0]) &&
×
563
      (_m4storage[1] == other._m4storage[1]) &&
×
564
      (_m4storage[2] == other._m4storage[2]) &&
×
565
      (_m4storage[3] == other._m4storage[3]) &&
×
566
      (_m4storage[4] == other._m4storage[4]) &&
×
567
      (_m4storage[5] == other._m4storage[5]) &&
×
568
      (_m4storage[6] == other._m4storage[6]) &&
×
569
      (_m4storage[7] == other._m4storage[7]) &&
×
570
      (_m4storage[8] == other._m4storage[8]) &&
×
571
      (_m4storage[9] == other._m4storage[9]) &&
×
572
      (_m4storage[10] == other._m4storage[10]) &&
×
573
      (_m4storage[11] == other._m4storage[11]) &&
×
574
      (_m4storage[12] == other._m4storage[12]) &&
×
575
      (_m4storage[13] == other._m4storage[13]) &&
×
576
      (_m4storage[14] == other._m4storage[14]) &&
×
577
      (_m4storage[15] == other._m4storage[15]);
×
578

579
  @override
×
580
  int get hashCode => Object.hashAll(_m4storage);
×
581

582
  /// Returns row 0
583
  Vector4 get row0 => getRow(0);
×
584

585
  /// Returns row 1
586
  Vector4 get row1 => getRow(1);
×
587

588
  /// Returns row 2
589
  Vector4 get row2 => getRow(2);
×
590

591
  /// Returns row 3
592
  Vector4 get row3 => getRow(3);
×
593

594
  /// Sets row 0 to [arg]
595
  set row0(Vector4 arg) => setRow(0, arg);
×
596

597
  /// Sets row 1 to [arg]
598
  set row1(Vector4 arg) => setRow(1, arg);
×
599

600
  /// Sets row 2 to [arg]
601
  set row2(Vector4 arg) => setRow(2, arg);
×
602

603
  /// Sets row 3 to [arg]
604
  set row3(Vector4 arg) => setRow(3, arg);
×
605

606
  /// Assigns the [row] of the matrix [arg]
607
  void setRow(int row, Vector4 arg) {
×
608
    final argStorage = arg._v4storage;
×
609
    _m4storage[index(row, 0)] = argStorage[0];
×
610
    _m4storage[index(row, 1)] = argStorage[1];
×
611
    _m4storage[index(row, 2)] = argStorage[2];
×
612
    _m4storage[index(row, 3)] = argStorage[3];
×
613
  }
614

615
  /// Gets the [row] of the matrix
616
  Vector4 getRow(int row) {
×
617
    final r = Vector4.zero();
×
618
    final rStorage = r._v4storage;
×
619
    rStorage[0] = _m4storage[index(row, 0)];
×
620
    rStorage[1] = _m4storage[index(row, 1)];
×
621
    rStorage[2] = _m4storage[index(row, 2)];
×
622
    rStorage[3] = _m4storage[index(row, 3)];
×
623
    return r;
624
  }
625

626
  /// Assigns the [column] of the matrix [arg]
627
  void setColumn(int column, Vector4 arg) {
×
628
    final entry = column * 4;
×
629
    final argStorage = arg._v4storage;
×
630
    _m4storage[entry + 3] = argStorage[3];
×
631
    _m4storage[entry + 2] = argStorage[2];
×
632
    _m4storage[entry + 1] = argStorage[1];
×
633
    _m4storage[entry + 0] = argStorage[0];
×
634
  }
635

636
  /// Gets the [column] of the matrix
637
  Vector4 getColumn(int column) {
×
638
    final r = Vector4.zero();
×
639
    final rStorage = r._v4storage;
×
640
    final entry = column * 4;
×
641
    rStorage[3] = _m4storage[entry + 3];
×
642
    rStorage[2] = _m4storage[entry + 2];
×
643
    rStorage[1] = _m4storage[entry + 1];
×
644
    rStorage[0] = _m4storage[entry + 0];
×
645
    return r;
646
  }
647

648
  /// Clone matrix.
649
  Matrix4 clone() => Matrix4.copy(this);
×
650

651
  /// Copy into [arg].
652
  Matrix4 copyInto(Matrix4 arg) {
×
653
    final argStorage = arg._m4storage;
×
654
    argStorage[0] = _m4storage[0];
×
655
    argStorage[1] = _m4storage[1];
×
656
    argStorage[2] = _m4storage[2];
×
657
    argStorage[3] = _m4storage[3];
×
658
    argStorage[4] = _m4storage[4];
×
659
    argStorage[5] = _m4storage[5];
×
660
    argStorage[6] = _m4storage[6];
×
661
    argStorage[7] = _m4storage[7];
×
662
    argStorage[8] = _m4storage[8];
×
663
    argStorage[9] = _m4storage[9];
×
664
    argStorage[10] = _m4storage[10];
×
665
    argStorage[11] = _m4storage[11];
×
666
    argStorage[12] = _m4storage[12];
×
667
    argStorage[13] = _m4storage[13];
×
668
    argStorage[14] = _m4storage[14];
×
669
    argStorage[15] = _m4storage[15];
×
670
    return arg;
671
  }
672

673
  /// Returns new matrix -this
674
  Matrix4 operator -() => clone()..negate();
×
675

676
  /// Returns a new vector or matrix by multiplying this with [arg].
677
  ///
678
  /// [arg] should be a [double] (to scale), [Vector4] (to transform), [Vector3]
679
  /// (to transform), or [Matrix4] (to multiply).
680
  ///
681
  /// If you know the argument type in a call site, prefer [scaledByDouble],
682
  /// [transformed], [transformed3], or [multiplied] for performance.
683
  @pragma('wasm:prefer-inline')
×
684
  @pragma('vm:prefer-inline')
685
  @pragma('dart2js:prefer-inline')
686
  dynamic operator *(dynamic arg) {
687
    final Object result;
688
    if (arg is double) {
×
689
      result = scaledByDouble(arg, arg, arg, 1.0);
×
690
    } else if (arg is Vector4) {
×
691
      result = transformed(arg);
×
692
    } else if (arg is Vector3) {
×
693
      result = transformed3(arg);
×
694
    } else if (arg is Matrix4) {
×
695
      result = multiplied(arg);
×
696
    } else {
697
      throw ArgumentError(arg);
×
698
    }
699
    return result;
700
  }
701

702
  /// Returns new matrix after component wise this + [arg]
703
  Matrix4 operator +(Matrix4 arg) => clone()..add(arg);
×
704

705
  /// Returns new matrix after component wise this - [arg]
706
  Matrix4 operator -(Matrix4 arg) => clone()..sub(arg);
×
707

708
  /// Translate this matrix by a [Vector3], [Vector4], or x,y,z as [double]s.
709
  ///
710
  /// If you know the argument types in a call site, prefer [translateByDouble],
711
  /// [translateByVector3], or [translateByVector4] for performance.
712
  @pragma('wasm:prefer-inline')
×
713
  @pragma('vm:prefer-inline')
714
  @pragma('dart2js:prefer-inline')
715
  @Deprecated(
716
    'Use translateByVector3, translateByVector4, '
717
    'or translateByDouble instead',
718
  )
719
  void translate(dynamic x, [double y = 0.0, double z = 0.0]) {
720
    if (x is Vector3) {
×
721
      translateByVector3(x);
×
722
    } else if (x is Vector4) {
×
723
      translateByVector4(x);
×
724
    } else if (x is double) {
×
725
      translateByDouble(x, y, z, 1.0);
×
726
    } else {
727
      throw UnimplementedError();
×
728
    }
729
  }
730

731
  /// Translate this matrix by x, y, z, w.
732
  void translateByDouble(double tx, double ty, double tz, double tw) {
×
733
    final t1 =
NEW
734
        _m4storage[0] * tx +
×
735
        _m4storage[4] * ty +
×
736
        _m4storage[8] * tz +
×
737
        _m4storage[12] * tw;
×
738
    _m4storage[12] = t1;
×
739

740
    final t2 =
NEW
741
        _m4storage[1] * tx +
×
742
        _m4storage[5] * ty +
×
743
        _m4storage[9] * tz +
×
744
        _m4storage[13] * tw;
×
745
    _m4storage[13] = t2;
×
746

747
    final t3 =
NEW
748
        _m4storage[2] * tx +
×
749
        _m4storage[6] * ty +
×
750
        _m4storage[10] * tz +
×
751
        _m4storage[14] * tw;
×
752
    _m4storage[14] = t3;
×
753

754
    final t4 =
NEW
755
        _m4storage[3] * tx +
×
756
        _m4storage[7] * ty +
×
757
        _m4storage[11] * tz +
×
758
        _m4storage[15] * tw;
×
759
    _m4storage[15] = t4;
×
760
  }
761

762
  /// Translate this matrix by a [Vector3].
763
  @pragma('wasm:prefer-inline')
×
764
  @pragma('vm:prefer-inline')
765
  @pragma('dart2js:prefer-inline')
766
  void translateByVector3(Vector3 v3) =>
767
      translateByDouble(v3.x, v3.y, v3.z, 1.0);
×
768

769
  /// Translate this matrix by a [Vector4].
770
  @pragma('wasm:prefer-inline')
×
771
  @pragma('vm:prefer-inline')
772
  @pragma('dart2js:prefer-inline')
773
  void translateByVector4(Vector4 v4) =>
774
      translateByDouble(v4.x, v4.y, v4.z, v4.w);
×
775

776
  /// Multiply this by a translation from the left.
777
  ///
778
  /// The translation can be specified with a [Vector3], [Vector4], or x, y, z
779
  /// as [double]s.
780
  ///
781
  /// If you know the argument types in a call site, prefer
782
  /// [leftTranslateByDouble], [leftTranslateByVector3], or
783
  /// [leftTranslateByVector4] for performance.
784
  @pragma('wasm:prefer-inline')
×
785
  @pragma('vm:prefer-inline')
786
  @pragma('dart2js:prefer-inline')
787
  @Deprecated(
788
    'Use leftTranslateByVector3, leftTranslateByVector4, '
789
    'or leftTranslateByDouble instead',
790
  )
791
  void leftTranslate(dynamic x, [double y = 0.0, double z = 0.0]) {
792
    if (x is Vector3) {
×
793
      leftTranslateByVector3(x);
×
794
    } else if (x is Vector4) {
×
795
      leftTranslateByVector4(x);
×
796
    } else if (x is double) {
×
797
      leftTranslateByDouble(x, y, z, 1.0);
×
798
    } else {
799
      throw UnimplementedError();
×
800
    }
801
  }
802

803
  /// Multiply this by a translation from the left.
804
  void leftTranslateByDouble(double tx, double ty, double tz, double tw) {
×
805
    // Column 1
806
    final r1 = _m4storage[3];
×
807
    _m4storage[0] += tx * r1;
×
808
    _m4storage[1] += ty * r1;
×
809
    _m4storage[2] += tz * r1;
×
810
    _m4storage[3] = tw * r1;
×
811

812
    // Column 2
813
    final r2 = _m4storage[7];
×
814
    _m4storage[4] += tx * r2;
×
815
    _m4storage[5] += ty * r2;
×
816
    _m4storage[6] += tz * r2;
×
817
    _m4storage[7] = tw * r2;
×
818

819
    // Column 3
820
    final r3 = _m4storage[11];
×
821
    _m4storage[8] += tx * r3;
×
822
    _m4storage[9] += ty * r3;
×
823
    _m4storage[10] += tz * r3;
×
824
    _m4storage[11] = tw * r3;
×
825

826
    // Column 4
827
    final r4 = _m4storage[15];
×
828
    _m4storage[12] += tx * r4;
×
829
    _m4storage[13] += ty * r4;
×
830
    _m4storage[14] += tz * r4;
×
831
    _m4storage[15] = tw * r4;
×
832
  }
833

834
  /// Multiply this by a translation from the left.
835
  @pragma('wasm:prefer-inline')
×
836
  @pragma('vm:prefer-inline')
837
  @pragma('dart2js:prefer-inline')
838
  void leftTranslateByVector3(Vector3 v3) =>
839
      leftTranslateByDouble(v3.x, v3.y, v3.z, 1.0);
×
840

841
  /// Multiply this by a translation from the left.
842
  @pragma('wasm:prefer-inline')
×
843
  @pragma('vm:prefer-inline')
844
  @pragma('dart2js:prefer-inline')
845
  void leftTranslateByVector4(Vector4 v4) =>
846
      leftTranslateByDouble(v4.x, v4.y, v4.z, v4.w);
×
847

848
  /// Rotate this [angle] radians around [axis]
849
  void rotate(Vector3 axis, double angle) {
×
850
    final len = axis.length;
×
851
    final axisStorage = axis._v3storage;
×
852
    final x = axisStorage[0] / len;
×
853
    final y = axisStorage[1] / len;
×
854
    final z = axisStorage[2] / len;
×
855
    final c = math.cos(angle);
×
856
    final s = math.sin(angle);
×
857
    final C = 1.0 - c;
×
858
    final m11 = x * x * C + c;
×
859
    final m12 = x * y * C - z * s;
×
860
    final m13 = x * z * C + y * s;
×
861
    final m21 = y * x * C + z * s;
×
862
    final m22 = y * y * C + c;
×
863
    final m23 = y * z * C - x * s;
×
864
    final m31 = z * x * C - y * s;
×
865
    final m32 = z * y * C + x * s;
×
866
    final m33 = z * z * C + c;
×
867
    final t1 = _m4storage[0] * m11 + _m4storage[4] * m21 + _m4storage[8] * m31;
×
868
    final t2 = _m4storage[1] * m11 + _m4storage[5] * m21 + _m4storage[9] * m31;
×
869
    final t3 = _m4storage[2] * m11 + _m4storage[6] * m21 + _m4storage[10] * m31;
×
870
    final t4 = _m4storage[3] * m11 + _m4storage[7] * m21 + _m4storage[11] * m31;
×
871
    final t5 = _m4storage[0] * m12 + _m4storage[4] * m22 + _m4storage[8] * m32;
×
872
    final t6 = _m4storage[1] * m12 + _m4storage[5] * m22 + _m4storage[9] * m32;
×
873
    final t7 = _m4storage[2] * m12 + _m4storage[6] * m22 + _m4storage[10] * m32;
×
874
    final t8 = _m4storage[3] * m12 + _m4storage[7] * m22 + _m4storage[11] * m32;
×
875
    final t9 = _m4storage[0] * m13 + _m4storage[4] * m23 + _m4storage[8] * m33;
×
876
    final t10 = _m4storage[1] * m13 + _m4storage[5] * m23 + _m4storage[9] * m33;
×
877
    final t11 =
878
        _m4storage[2] * m13 + _m4storage[6] * m23 + _m4storage[10] * m33;
×
879
    final t12 =
880
        _m4storage[3] * m13 + _m4storage[7] * m23 + _m4storage[11] * m33;
×
881
    _m4storage[0] = t1;
×
882
    _m4storage[1] = t2;
×
883
    _m4storage[2] = t3;
×
884
    _m4storage[3] = t4;
×
885
    _m4storage[4] = t5;
×
886
    _m4storage[5] = t6;
×
887
    _m4storage[6] = t7;
×
888
    _m4storage[7] = t8;
×
889
    _m4storage[8] = t9;
×
890
    _m4storage[9] = t10;
×
891
    _m4storage[10] = t11;
×
892
    _m4storage[11] = t12;
×
893
  }
894

895
  /// Rotate this [angle] radians around X
896
  void rotateX(double angle) {
×
897
    final cosAngle = math.cos(angle);
×
898
    final sinAngle = math.sin(angle);
×
899
    final t1 = _m4storage[4] * cosAngle + _m4storage[8] * sinAngle;
×
900
    final t2 = _m4storage[5] * cosAngle + _m4storage[9] * sinAngle;
×
901
    final t3 = _m4storage[6] * cosAngle + _m4storage[10] * sinAngle;
×
902
    final t4 = _m4storage[7] * cosAngle + _m4storage[11] * sinAngle;
×
903
    final t5 = _m4storage[4] * -sinAngle + _m4storage[8] * cosAngle;
×
904
    final t6 = _m4storage[5] * -sinAngle + _m4storage[9] * cosAngle;
×
905
    final t7 = _m4storage[6] * -sinAngle + _m4storage[10] * cosAngle;
×
906
    final t8 = _m4storage[7] * -sinAngle + _m4storage[11] * cosAngle;
×
907
    _m4storage[4] = t1;
×
908
    _m4storage[5] = t2;
×
909
    _m4storage[6] = t3;
×
910
    _m4storage[7] = t4;
×
911
    _m4storage[8] = t5;
×
912
    _m4storage[9] = t6;
×
913
    _m4storage[10] = t7;
×
914
    _m4storage[11] = t8;
×
915
  }
916

917
  /// Rotate this matrix [angle] radians around Y
918
  void rotateY(double angle) {
×
919
    final cosAngle = math.cos(angle);
×
920
    final sinAngle = math.sin(angle);
×
921
    final t1 = _m4storage[0] * cosAngle + _m4storage[8] * -sinAngle;
×
922
    final t2 = _m4storage[1] * cosAngle + _m4storage[9] * -sinAngle;
×
923
    final t3 = _m4storage[2] * cosAngle + _m4storage[10] * -sinAngle;
×
924
    final t4 = _m4storage[3] * cosAngle + _m4storage[11] * -sinAngle;
×
925
    final t5 = _m4storage[0] * sinAngle + _m4storage[8] * cosAngle;
×
926
    final t6 = _m4storage[1] * sinAngle + _m4storage[9] * cosAngle;
×
927
    final t7 = _m4storage[2] * sinAngle + _m4storage[10] * cosAngle;
×
928
    final t8 = _m4storage[3] * sinAngle + _m4storage[11] * cosAngle;
×
929
    _m4storage[0] = t1;
×
930
    _m4storage[1] = t2;
×
931
    _m4storage[2] = t3;
×
932
    _m4storage[3] = t4;
×
933
    _m4storage[8] = t5;
×
934
    _m4storage[9] = t6;
×
935
    _m4storage[10] = t7;
×
936
    _m4storage[11] = t8;
×
937
  }
938

939
  /// Rotate this matrix [angle] radians around Z
940
  void rotateZ(double angle) {
×
941
    final cosAngle = math.cos(angle);
×
942
    final sinAngle = math.sin(angle);
×
943
    final t1 = _m4storage[0] * cosAngle + _m4storage[4] * sinAngle;
×
944
    final t2 = _m4storage[1] * cosAngle + _m4storage[5] * sinAngle;
×
945
    final t3 = _m4storage[2] * cosAngle + _m4storage[6] * sinAngle;
×
946
    final t4 = _m4storage[3] * cosAngle + _m4storage[7] * sinAngle;
×
947
    final t5 = _m4storage[0] * -sinAngle + _m4storage[4] * cosAngle;
×
948
    final t6 = _m4storage[1] * -sinAngle + _m4storage[5] * cosAngle;
×
949
    final t7 = _m4storage[2] * -sinAngle + _m4storage[6] * cosAngle;
×
950
    final t8 = _m4storage[3] * -sinAngle + _m4storage[7] * cosAngle;
×
951
    _m4storage[0] = t1;
×
952
    _m4storage[1] = t2;
×
953
    _m4storage[2] = t3;
×
954
    _m4storage[3] = t4;
×
955
    _m4storage[4] = t5;
×
956
    _m4storage[5] = t6;
×
957
    _m4storage[6] = t7;
×
958
    _m4storage[7] = t8;
×
959
  }
960

961
  /// Scale this matrix by a [Vector3], [Vector4], or x,y,z as [double]s.
962
  ///
963
  /// If you know the argument types in a call site, prefer [scaleByDouble],
964
  /// [scaleByVector3], or [scaleByVector4] for performance.
965
  @pragma('wasm:prefer-inline')
×
966
  @pragma('vm:prefer-inline')
967
  @pragma('dart2js:prefer-inline')
968
  @Deprecated('Use scaleByVector3, scaleByVector4, or scaleByDouble instead')
969
  void scale(dynamic x, [double? y, double? z]) {
970
    if (x is Vector3) {
×
971
      scaleByVector3(x);
×
972
    } else if (x is Vector4) {
×
973
      scaleByVector4(x);
×
974
    } else if (x is double) {
×
975
      scaleByDouble(x, y ?? x, z ?? x, 1.0);
×
976
    } else {
977
      throw UnimplementedError();
×
978
    }
979
  }
980

981
  /// Scale this matrix.
982
  void scaleByDouble(double sx, double sy, double sz, double sw) {
×
983
    _m4storage[0] *= sx;
×
984
    _m4storage[1] *= sx;
×
985
    _m4storage[2] *= sx;
×
986
    _m4storage[3] *= sx;
×
987
    _m4storage[4] *= sy;
×
988
    _m4storage[5] *= sy;
×
989
    _m4storage[6] *= sy;
×
990
    _m4storage[7] *= sy;
×
991
    _m4storage[8] *= sz;
×
992
    _m4storage[9] *= sz;
×
993
    _m4storage[10] *= sz;
×
994
    _m4storage[11] *= sz;
×
995
    _m4storage[12] *= sw;
×
996
    _m4storage[13] *= sw;
×
997
    _m4storage[14] *= sw;
×
998
    _m4storage[15] *= sw;
×
999
  }
1000

1001
  /// Scale this matrix.
1002
  @pragma('wasm:prefer-inline')
×
1003
  @pragma('vm:prefer-inline')
1004
  @pragma('dart2js:prefer-inline')
1005
  void scaleByVector3(Vector3 v3) => scaleByDouble(v3.x, v3.y, v3.z, 1.0);
×
1006

1007
  /// Scale this matrix.
1008
  @pragma('wasm:prefer-inline')
×
1009
  @pragma('vm:prefer-inline')
1010
  @pragma('dart2js:prefer-inline')
1011
  void scaleByVector4(Vector4 v4) => scaleByDouble(v4.x, v4.y, v4.z, v4.w);
×
1012

1013
  /// Create a copy of this scaled by a [Vector3], [Vector4] or [x],[y], and
1014
  /// [z].
1015
  @pragma('wasm:prefer-inline')
×
1016
  @pragma('vm:prefer-inline')
1017
  @pragma('dart2js:prefer-inline')
1018
  @Deprecated('Use scaledByVector3, scaledByVector4, or scaledByDouble instead')
1019
  Matrix4 scaled(dynamic x, [double? y, double? z]) => clone()..scale(x, y, z);
×
1020

1021
  /// Create a copy of this scaled by [x], [y], [z], and [t].
1022
  @pragma('wasm:prefer-inline')
×
1023
  @pragma('vm:prefer-inline')
1024
  @pragma('dart2js:prefer-inline')
1025
  Matrix4 scaledByDouble(double x, double y, double z, double t) =>
1026
      clone()..scaleByDouble(x, y, z, t);
×
1027

1028
  /// Create a copy of this scaled by a [Vector3].
1029
  @pragma('wasm:prefer-inline')
×
1030
  @pragma('vm:prefer-inline')
1031
  @pragma('dart2js:prefer-inline')
1032
  Matrix4 scaledByVector3(Vector3 v3) => clone()..scaleByVector3(v3);
×
1033

1034
  /// Create a copy of this scaled by a [Vector4].
1035
  @pragma('wasm:prefer-inline')
×
1036
  @pragma('vm:prefer-inline')
1037
  @pragma('dart2js:prefer-inline')
1038
  Matrix4 scaledByVector4(Vector4 v4) => clone()..scaleByVector4(v4);
×
1039

1040
  /// Zeros this.
1041
  void setZero() {
×
1042
    _m4storage[0] = 0.0;
×
1043
    _m4storage[1] = 0.0;
×
1044
    _m4storage[2] = 0.0;
×
1045
    _m4storage[3] = 0.0;
×
1046
    _m4storage[4] = 0.0;
×
1047
    _m4storage[5] = 0.0;
×
1048
    _m4storage[6] = 0.0;
×
1049
    _m4storage[7] = 0.0;
×
1050
    _m4storage[8] = 0.0;
×
1051
    _m4storage[9] = 0.0;
×
1052
    _m4storage[10] = 0.0;
×
1053
    _m4storage[11] = 0.0;
×
1054
    _m4storage[12] = 0.0;
×
1055
    _m4storage[13] = 0.0;
×
1056
    _m4storage[14] = 0.0;
×
1057
    _m4storage[15] = 0.0;
×
1058
  }
1059

1060
  /// Makes this into the identity matrix.
1061
  void setIdentity() {
×
1062
    _m4storage[0] = 1.0;
×
1063
    _m4storage[1] = 0.0;
×
1064
    _m4storage[2] = 0.0;
×
1065
    _m4storage[3] = 0.0;
×
1066
    _m4storage[4] = 0.0;
×
1067
    _m4storage[5] = 1.0;
×
1068
    _m4storage[6] = 0.0;
×
1069
    _m4storage[7] = 0.0;
×
1070
    _m4storage[8] = 0.0;
×
1071
    _m4storage[9] = 0.0;
×
1072
    _m4storage[10] = 1.0;
×
1073
    _m4storage[11] = 0.0;
×
1074
    _m4storage[12] = 0.0;
×
1075
    _m4storage[13] = 0.0;
×
1076
    _m4storage[14] = 0.0;
×
1077
    _m4storage[15] = 1.0;
×
1078
  }
1079

1080
  /// Returns the tranpose of this.
1081
  Matrix4 transposed() => clone()..transpose();
×
1082

1083
  void transpose() {
×
1084
    double temp;
1085
    temp = _m4storage[4];
×
1086
    _m4storage[4] = _m4storage[1];
×
1087
    _m4storage[1] = temp;
×
1088
    temp = _m4storage[8];
×
1089
    _m4storage[8] = _m4storage[2];
×
1090
    _m4storage[2] = temp;
×
1091
    temp = _m4storage[12];
×
1092
    _m4storage[12] = _m4storage[3];
×
1093
    _m4storage[3] = temp;
×
1094
    temp = _m4storage[9];
×
1095
    _m4storage[9] = _m4storage[6];
×
1096
    _m4storage[6] = temp;
×
1097
    temp = _m4storage[13];
×
1098
    _m4storage[13] = _m4storage[7];
×
1099
    _m4storage[7] = temp;
×
1100
    temp = _m4storage[14];
×
1101
    _m4storage[14] = _m4storage[11];
×
1102
    _m4storage[11] = temp;
×
1103
  }
1104

1105
  /// Returns the component wise absolute value of this.
1106
  Matrix4 absolute() {
×
1107
    final r = Matrix4.zero();
×
1108
    final rStorage = r._m4storage;
×
1109
    rStorage[0] = _m4storage[0].abs();
×
1110
    rStorage[1] = _m4storage[1].abs();
×
1111
    rStorage[2] = _m4storage[2].abs();
×
1112
    rStorage[3] = _m4storage[3].abs();
×
1113
    rStorage[4] = _m4storage[4].abs();
×
1114
    rStorage[5] = _m4storage[5].abs();
×
1115
    rStorage[6] = _m4storage[6].abs();
×
1116
    rStorage[7] = _m4storage[7].abs();
×
1117
    rStorage[8] = _m4storage[8].abs();
×
1118
    rStorage[9] = _m4storage[9].abs();
×
1119
    rStorage[10] = _m4storage[10].abs();
×
1120
    rStorage[11] = _m4storage[11].abs();
×
1121
    rStorage[12] = _m4storage[12].abs();
×
1122
    rStorage[13] = _m4storage[13].abs();
×
1123
    rStorage[14] = _m4storage[14].abs();
×
1124
    rStorage[15] = _m4storage[15].abs();
×
1125
    return r;
1126
  }
1127

1128
  /// Returns the determinant of this matrix.
1129
  double determinant() {
×
1130
    final det2_01_01 =
1131
        _m4storage[0] * _m4storage[5] - _m4storage[1] * _m4storage[4];
×
1132
    final det2_01_02 =
1133
        _m4storage[0] * _m4storage[6] - _m4storage[2] * _m4storage[4];
×
1134
    final det2_01_03 =
1135
        _m4storage[0] * _m4storage[7] - _m4storage[3] * _m4storage[4];
×
1136
    final det2_01_12 =
1137
        _m4storage[1] * _m4storage[6] - _m4storage[2] * _m4storage[5];
×
1138
    final det2_01_13 =
1139
        _m4storage[1] * _m4storage[7] - _m4storage[3] * _m4storage[5];
×
1140
    final det2_01_23 =
1141
        _m4storage[2] * _m4storage[7] - _m4storage[3] * _m4storage[6];
×
1142
    final det3_201_012 =
NEW
1143
        _m4storage[8] * det2_01_12 -
×
1144
        _m4storage[9] * det2_01_02 +
×
1145
        _m4storage[10] * det2_01_01;
×
1146
    final det3_201_013 =
NEW
1147
        _m4storage[8] * det2_01_13 -
×
1148
        _m4storage[9] * det2_01_03 +
×
1149
        _m4storage[11] * det2_01_01;
×
1150
    final det3_201_023 =
NEW
1151
        _m4storage[8] * det2_01_23 -
×
1152
        _m4storage[10] * det2_01_03 +
×
1153
        _m4storage[11] * det2_01_02;
×
1154
    final det3_201_123 =
NEW
1155
        _m4storage[9] * det2_01_23 -
×
1156
        _m4storage[10] * det2_01_13 +
×
1157
        _m4storage[11] * det2_01_12;
×
1158
    return -det3_201_123 * _m4storage[12] +
×
1159
        det3_201_023 * _m4storage[13] -
×
1160
        det3_201_013 * _m4storage[14] +
×
1161
        det3_201_012 * _m4storage[15];
×
1162
  }
1163

1164
  /// Returns the dot product of row [i] and [v].
1165
  double dotRow(int i, Vector4 v) {
×
1166
    final vStorage = v._v4storage;
×
1167
    return _m4storage[i] * vStorage[0] +
×
1168
        _m4storage[4 + i] * vStorage[1] +
×
1169
        _m4storage[8 + i] * vStorage[2] +
×
1170
        _m4storage[12 + i] * vStorage[3];
×
1171
  }
1172

1173
  /// Returns the dot product of column [j] and [v].
1174
  double dotColumn(int j, Vector4 v) {
×
1175
    final vStorage = v._v4storage;
×
1176
    return _m4storage[j * 4] * vStorage[0] +
×
1177
        _m4storage[j * 4 + 1] * vStorage[1] +
×
1178
        _m4storage[j * 4 + 2] * vStorage[2] +
×
1179
        _m4storage[j * 4 + 3] * vStorage[3];
×
1180
  }
1181

1182
  /// Returns the trace of the matrix. The trace of a matrix is the sum of the
1183
  /// diagonal entries.
1184
  double trace() {
×
1185
    var t = 0.0;
1186
    t += _m4storage[0];
×
1187
    t += _m4storage[5];
×
1188
    t += _m4storage[10];
×
1189
    t += _m4storage[15];
×
1190
    return t;
1191
  }
1192

1193
  /// Returns infinity norm of the matrix. Used for numerical analysis.
1194
  double infinityNorm() {
×
1195
    var norm = 0.0;
1196
    {
1197
      var row_norm = 0.0;
1198
      row_norm += _m4storage[0].abs();
×
1199
      row_norm += _m4storage[1].abs();
×
1200
      row_norm += _m4storage[2].abs();
×
1201
      row_norm += _m4storage[3].abs();
×
1202
      norm = row_norm > norm ? row_norm : norm;
×
1203
    }
1204
    {
1205
      var row_norm = 0.0;
1206
      row_norm += _m4storage[4].abs();
×
1207
      row_norm += _m4storage[5].abs();
×
1208
      row_norm += _m4storage[6].abs();
×
1209
      row_norm += _m4storage[7].abs();
×
1210
      norm = row_norm > norm ? row_norm : norm;
×
1211
    }
1212
    {
1213
      var row_norm = 0.0;
1214
      row_norm += _m4storage[8].abs();
×
1215
      row_norm += _m4storage[9].abs();
×
1216
      row_norm += _m4storage[10].abs();
×
1217
      row_norm += _m4storage[11].abs();
×
1218
      norm = row_norm > norm ? row_norm : norm;
×
1219
    }
1220
    {
1221
      var row_norm = 0.0;
1222
      row_norm += _m4storage[12].abs();
×
1223
      row_norm += _m4storage[13].abs();
×
1224
      row_norm += _m4storage[14].abs();
×
1225
      row_norm += _m4storage[15].abs();
×
1226
      norm = row_norm > norm ? row_norm : norm;
×
1227
    }
1228
    return norm;
1229
  }
1230

1231
  /// Returns relative error between this and [correct]
1232
  double relativeError(Matrix4 correct) {
×
1233
    final diff = correct - this;
×
1234
    final correct_norm = correct.infinityNorm();
×
1235
    final diff_norm = diff.infinityNorm();
×
1236
    return diff_norm / correct_norm;
×
1237
  }
1238

1239
  /// Returns absolute error between this and [correct]
1240
  double absoluteError(Matrix4 correct) {
×
1241
    final this_norm = infinityNorm();
×
1242
    final correct_norm = correct.infinityNorm();
×
1243
    final diff_norm = (this_norm - correct_norm).abs();
×
1244
    return diff_norm;
1245
  }
1246

1247
  /// Returns the translation vector from this homogeneous transformation
1248
  /// matrix.
1249
  Vector3 getTranslation() {
×
1250
    final z = _m4storage[14];
×
1251
    final y = _m4storage[13];
×
1252
    final x = _m4storage[12];
×
1253
    return Vector3(x, y, z);
×
1254
  }
1255

1256
  /// Sets the translation vector in this homogeneous transformation matrix.
1257
  void setTranslation(Vector3 t) {
×
1258
    final tStorage = t._v3storage;
×
1259
    final z = tStorage[2];
×
1260
    final y = tStorage[1];
×
1261
    final x = tStorage[0];
×
1262
    _m4storage[14] = z;
×
1263
    _m4storage[13] = y;
×
1264
    _m4storage[12] = x;
×
1265
  }
1266

1267
  /// Sets the translation vector in this homogeneous transformation matrix.
1268
  void setTranslationRaw(double x, double y, double z) {
×
1269
    _m4storage[14] = z;
×
1270
    _m4storage[13] = y;
×
1271
    _m4storage[12] = x;
×
1272
  }
1273

1274
  /// Returns the rotation matrix from this homogeneous transformation matrix.
1275
  Matrix3 getRotation() {
×
1276
    final r = Matrix3.zero();
×
1277
    copyRotation(r);
×
1278
    return r;
1279
  }
1280

1281
  /// Copies the rotation matrix from this homogeneous transformation matrix
1282
  /// into [rotation].
1283
  void copyRotation(Matrix3 rotation) {
×
1284
    final rStorage = rotation._m3storage;
×
1285
    rStorage[0] = _m4storage[0];
×
1286
    rStorage[1] = _m4storage[1];
×
1287
    rStorage[2] = _m4storage[2];
×
1288
    rStorage[3] = _m4storage[4];
×
1289
    rStorage[4] = _m4storage[5];
×
1290
    rStorage[5] = _m4storage[6];
×
1291
    rStorage[6] = _m4storage[8];
×
1292
    rStorage[7] = _m4storage[9];
×
1293
    rStorage[8] = _m4storage[10];
×
1294
  }
1295

1296
  /// Sets the rotation matrix in this homogeneous transformation matrix.
1297
  void setRotation(Matrix3 r) {
×
1298
    final rStorage = r._m3storage;
×
1299
    _m4storage[0] = rStorage[0];
×
1300
    _m4storage[1] = rStorage[1];
×
1301
    _m4storage[2] = rStorage[2];
×
1302
    _m4storage[4] = rStorage[3];
×
1303
    _m4storage[5] = rStorage[4];
×
1304
    _m4storage[6] = rStorage[5];
×
1305
    _m4storage[8] = rStorage[6];
×
1306
    _m4storage[9] = rStorage[7];
×
1307
    _m4storage[10] = rStorage[8];
×
1308
  }
1309

1310
  /// Returns the normal matrix from this homogeneous transformation matrix.
1311
  ///
1312
  /// The normal matrix is the transpose of the inverse of the top-left 3x3 part
1313
  /// of this 4x4 matrix.
1314
  Matrix3 getNormalMatrix() => Matrix3.identity()..copyNormalMatrix(this);
×
1315

1316
  /// Returns the max scale value of the 3 axes.
1317
  double getMaxScaleOnAxis() {
×
1318
    final scaleXSq =
NEW
1319
        _m4storage[0] * _m4storage[0] +
×
1320
        _m4storage[1] * _m4storage[1] +
×
1321
        _m4storage[2] * _m4storage[2];
×
1322
    final scaleYSq =
NEW
1323
        _m4storage[4] * _m4storage[4] +
×
1324
        _m4storage[5] * _m4storage[5] +
×
1325
        _m4storage[6] * _m4storage[6];
×
1326
    final scaleZSq =
NEW
1327
        _m4storage[8] * _m4storage[8] +
×
1328
        _m4storage[9] * _m4storage[9] +
×
1329
        _m4storage[10] * _m4storage[10];
×
1330
    return math.sqrt(math.max(scaleXSq, math.max(scaleYSq, scaleZSq)));
×
1331
  }
1332

1333
  /// Transposes just the upper 3x3 rotation matrix.
1334
  void transposeRotation() {
×
1335
    double temp;
1336
    temp = _m4storage[1];
×
1337
    _m4storage[1] = _m4storage[4];
×
1338
    _m4storage[4] = temp;
×
1339
    temp = _m4storage[2];
×
1340
    _m4storage[2] = _m4storage[8];
×
1341
    _m4storage[8] = temp;
×
1342
    temp = _m4storage[4];
×
1343
    _m4storage[4] = _m4storage[1];
×
1344
    _m4storage[1] = temp;
×
1345
    temp = _m4storage[6];
×
1346
    _m4storage[6] = _m4storage[9];
×
1347
    _m4storage[9] = temp;
×
1348
    temp = _m4storage[8];
×
1349
    _m4storage[8] = _m4storage[2];
×
1350
    _m4storage[2] = temp;
×
1351
    temp = _m4storage[9];
×
1352
    _m4storage[9] = _m4storage[6];
×
1353
    _m4storage[6] = temp;
×
1354
  }
1355

1356
  /// Invert this.
1357
  double invert() => copyInverse(this);
×
1358

1359
  /// Set this matrix to be the inverse of [arg]
1360
  double copyInverse(Matrix4 arg) {
×
1361
    final argStorage = arg._m4storage;
×
1362
    final a00 = argStorage[0];
×
1363
    final a01 = argStorage[1];
×
1364
    final a02 = argStorage[2];
×
1365
    final a03 = argStorage[3];
×
1366
    final a10 = argStorage[4];
×
1367
    final a11 = argStorage[5];
×
1368
    final a12 = argStorage[6];
×
1369
    final a13 = argStorage[7];
×
1370
    final a20 = argStorage[8];
×
1371
    final a21 = argStorage[9];
×
1372
    final a22 = argStorage[10];
×
1373
    final a23 = argStorage[11];
×
1374
    final a30 = argStorage[12];
×
1375
    final a31 = argStorage[13];
×
1376
    final a32 = argStorage[14];
×
1377
    final a33 = argStorage[15];
×
1378
    final b00 = a00 * a11 - a01 * a10;
×
1379
    final b01 = a00 * a12 - a02 * a10;
×
1380
    final b02 = a00 * a13 - a03 * a10;
×
1381
    final b03 = a01 * a12 - a02 * a11;
×
1382
    final b04 = a01 * a13 - a03 * a11;
×
1383
    final b05 = a02 * a13 - a03 * a12;
×
1384
    final b06 = a20 * a31 - a21 * a30;
×
1385
    final b07 = a20 * a32 - a22 * a30;
×
1386
    final b08 = a20 * a33 - a23 * a30;
×
1387
    final b09 = a21 * a32 - a22 * a31;
×
1388
    final b10 = a21 * a33 - a23 * a31;
×
1389
    final b11 = a22 * a33 - a23 * a32;
×
1390
    final det =
1391
        b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
×
1392
    if (det == 0.0) {
×
1393
      setFrom(arg);
×
1394
      return 0.0;
1395
    }
1396
    final invDet = 1.0 / det;
×
1397
    _m4storage[0] = (a11 * b11 - a12 * b10 + a13 * b09) * invDet;
×
1398
    _m4storage[1] = (-a01 * b11 + a02 * b10 - a03 * b09) * invDet;
×
1399
    _m4storage[2] = (a31 * b05 - a32 * b04 + a33 * b03) * invDet;
×
1400
    _m4storage[3] = (-a21 * b05 + a22 * b04 - a23 * b03) * invDet;
×
1401
    _m4storage[4] = (-a10 * b11 + a12 * b08 - a13 * b07) * invDet;
×
1402
    _m4storage[5] = (a00 * b11 - a02 * b08 + a03 * b07) * invDet;
×
1403
    _m4storage[6] = (-a30 * b05 + a32 * b02 - a33 * b01) * invDet;
×
1404
    _m4storage[7] = (a20 * b05 - a22 * b02 + a23 * b01) * invDet;
×
1405
    _m4storage[8] = (a10 * b10 - a11 * b08 + a13 * b06) * invDet;
×
1406
    _m4storage[9] = (-a00 * b10 + a01 * b08 - a03 * b06) * invDet;
×
1407
    _m4storage[10] = (a30 * b04 - a31 * b02 + a33 * b00) * invDet;
×
1408
    _m4storage[11] = (-a20 * b04 + a21 * b02 - a23 * b00) * invDet;
×
1409
    _m4storage[12] = (-a10 * b09 + a11 * b07 - a12 * b06) * invDet;
×
1410
    _m4storage[13] = (a00 * b09 - a01 * b07 + a02 * b06) * invDet;
×
1411
    _m4storage[14] = (-a30 * b03 + a31 * b01 - a32 * b00) * invDet;
×
1412
    _m4storage[15] = (a20 * b03 - a21 * b01 + a22 * b00) * invDet;
×
1413
    return det;
1414
  }
1415

1416
  double invertRotation() {
×
1417
    final det = determinant();
×
1418
    if (det == 0.0) {
×
1419
      return 0.0;
1420
    }
1421
    final invDet = 1.0 / det;
×
1422
    double ix;
1423
    double iy;
1424
    double iz;
1425
    double jx;
1426
    double jy;
1427
    double jz;
1428
    double kx;
1429
    double ky;
1430
    double kz;
1431
    ix =
NEW
1432
        invDet *
×
1433
        (_m4storage[5] * _m4storage[10] - _m4storage[6] * _m4storage[9]);
×
1434
    iy =
NEW
1435
        invDet *
×
1436
        (_m4storage[2] * _m4storage[9] - _m4storage[1] * _m4storage[10]);
×
1437
    iz =
NEW
1438
        invDet *
×
1439
        (_m4storage[1] * _m4storage[6] - _m4storage[2] * _m4storage[5]);
×
1440
    jx =
NEW
1441
        invDet *
×
1442
        (_m4storage[6] * _m4storage[8] - _m4storage[4] * _m4storage[10]);
×
1443
    jy =
NEW
1444
        invDet *
×
1445
        (_m4storage[0] * _m4storage[10] - _m4storage[2] * _m4storage[8]);
×
1446
    jz =
NEW
1447
        invDet *
×
1448
        (_m4storage[2] * _m4storage[4] - _m4storage[0] * _m4storage[6]);
×
1449
    kx =
NEW
1450
        invDet *
×
1451
        (_m4storage[4] * _m4storage[9] - _m4storage[5] * _m4storage[8]);
×
1452
    ky =
NEW
1453
        invDet *
×
1454
        (_m4storage[1] * _m4storage[8] - _m4storage[0] * _m4storage[9]);
×
1455
    kz =
NEW
1456
        invDet *
×
1457
        (_m4storage[0] * _m4storage[5] - _m4storage[1] * _m4storage[4]);
×
1458
    _m4storage[0] = ix;
×
1459
    _m4storage[1] = iy;
×
1460
    _m4storage[2] = iz;
×
1461
    _m4storage[4] = jx;
×
1462
    _m4storage[5] = jy;
×
1463
    _m4storage[6] = jz;
×
1464
    _m4storage[8] = kx;
×
1465
    _m4storage[9] = ky;
×
1466
    _m4storage[10] = kz;
×
1467
    return det;
1468
  }
1469

1470
  /// Sets the upper 3x3 to a rotation of [radians] around X
1471
  void setRotationX(double radians) {
×
1472
    final c = math.cos(radians);
×
1473
    final s = math.sin(radians);
×
1474
    _m4storage[0] = 1.0;
×
1475
    _m4storage[1] = 0.0;
×
1476
    _m4storage[2] = 0.0;
×
1477
    _m4storage[4] = 0.0;
×
1478
    _m4storage[5] = c;
×
1479
    _m4storage[6] = s;
×
1480
    _m4storage[8] = 0.0;
×
1481
    _m4storage[9] = -s;
×
1482
    _m4storage[10] = c;
×
1483
    _m4storage[3] = 0.0;
×
1484
    _m4storage[7] = 0.0;
×
1485
    _m4storage[11] = 0.0;
×
1486
  }
1487

1488
  /// Sets the upper 3x3 to a rotation of [radians] around Y
1489
  void setRotationY(double radians) {
×
1490
    final c = math.cos(radians);
×
1491
    final s = math.sin(radians);
×
1492
    _m4storage[0] = c;
×
1493
    _m4storage[1] = 0.0;
×
1494
    _m4storage[2] = -s;
×
1495
    _m4storage[4] = 0.0;
×
1496
    _m4storage[5] = 1.0;
×
1497
    _m4storage[6] = 0.0;
×
1498
    _m4storage[8] = s;
×
1499
    _m4storage[9] = 0.0;
×
1500
    _m4storage[10] = c;
×
1501
    _m4storage[3] = 0.0;
×
1502
    _m4storage[7] = 0.0;
×
1503
    _m4storage[11] = 0.0;
×
1504
  }
1505

1506
  /// Sets the upper 3x3 to a rotation of [radians] around Z
1507
  void setRotationZ(double radians) {
×
1508
    final c = math.cos(radians);
×
1509
    final s = math.sin(radians);
×
1510
    _m4storage[0] = c;
×
1511
    _m4storage[1] = s;
×
1512
    _m4storage[2] = 0.0;
×
1513
    _m4storage[4] = -s;
×
1514
    _m4storage[5] = c;
×
1515
    _m4storage[6] = 0.0;
×
1516
    _m4storage[8] = 0.0;
×
1517
    _m4storage[9] = 0.0;
×
1518
    _m4storage[10] = 1.0;
×
1519
    _m4storage[3] = 0.0;
×
1520
    _m4storage[7] = 0.0;
×
1521
    _m4storage[11] = 0.0;
×
1522
  }
1523

1524
  /// Converts into Adjugate matrix and scales by [scale]
1525
  void scaleAdjoint(double scale) {
×
1526
    // Adapted from code by Richard Carling.
1527
    final a1 = _m4storage[0];
×
1528
    final b1 = _m4storage[4];
×
1529
    final c1 = _m4storage[8];
×
1530
    final d1 = _m4storage[12];
×
1531
    final a2 = _m4storage[1];
×
1532
    final b2 = _m4storage[5];
×
1533
    final c2 = _m4storage[9];
×
1534
    final d2 = _m4storage[13];
×
1535
    final a3 = _m4storage[2];
×
1536
    final b3 = _m4storage[6];
×
1537
    final c3 = _m4storage[10];
×
1538
    final d3 = _m4storage[14];
×
1539
    final a4 = _m4storage[3];
×
1540
    final b4 = _m4storage[7];
×
1541
    final c4 = _m4storage[11];
×
1542
    final d4 = _m4storage[15];
×
NEW
1543
    _m4storage[0] =
×
NEW
1544
        (b2 * (c3 * d4 - c4 * d3) -
×
1545
            c2 * (b3 * d4 - b4 * d3) +
×
1546
            d2 * (b3 * c4 - b4 * c3)) *
×
1547
        scale;
NEW
1548
    _m4storage[1] =
×
NEW
1549
        -(a2 * (c3 * d4 - c4 * d3) -
×
1550
            c2 * (a3 * d4 - a4 * d3) +
×
1551
            d2 * (a3 * c4 - a4 * c3)) *
×
1552
        scale;
NEW
1553
    _m4storage[2] =
×
NEW
1554
        (a2 * (b3 * d4 - b4 * d3) -
×
1555
            b2 * (a3 * d4 - a4 * d3) +
×
1556
            d2 * (a3 * b4 - a4 * b3)) *
×
1557
        scale;
NEW
1558
    _m4storage[3] =
×
NEW
1559
        -(a2 * (b3 * c4 - b4 * c3) -
×
1560
            b2 * (a3 * c4 - a4 * c3) +
×
1561
            c2 * (a3 * b4 - a4 * b3)) *
×
1562
        scale;
NEW
1563
    _m4storage[4] =
×
NEW
1564
        -(b1 * (c3 * d4 - c4 * d3) -
×
1565
            c1 * (b3 * d4 - b4 * d3) +
×
1566
            d1 * (b3 * c4 - b4 * c3)) *
×
1567
        scale;
NEW
1568
    _m4storage[5] =
×
NEW
1569
        (a1 * (c3 * d4 - c4 * d3) -
×
1570
            c1 * (a3 * d4 - a4 * d3) +
×
1571
            d1 * (a3 * c4 - a4 * c3)) *
×
1572
        scale;
NEW
1573
    _m4storage[6] =
×
NEW
1574
        -(a1 * (b3 * d4 - b4 * d3) -
×
1575
            b1 * (a3 * d4 - a4 * d3) +
×
1576
            d1 * (a3 * b4 - a4 * b3)) *
×
1577
        scale;
NEW
1578
    _m4storage[7] =
×
NEW
1579
        (a1 * (b3 * c4 - b4 * c3) -
×
1580
            b1 * (a3 * c4 - a4 * c3) +
×
1581
            c1 * (a3 * b4 - a4 * b3)) *
×
1582
        scale;
NEW
1583
    _m4storage[8] =
×
NEW
1584
        (b1 * (c2 * d4 - c4 * d2) -
×
1585
            c1 * (b2 * d4 - b4 * d2) +
×
1586
            d1 * (b2 * c4 - b4 * c2)) *
×
1587
        scale;
NEW
1588
    _m4storage[9] =
×
NEW
1589
        -(a1 * (c2 * d4 - c4 * d2) -
×
1590
            c1 * (a2 * d4 - a4 * d2) +
×
1591
            d1 * (a2 * c4 - a4 * c2)) *
×
1592
        scale;
NEW
1593
    _m4storage[10] =
×
NEW
1594
        (a1 * (b2 * d4 - b4 * d2) -
×
1595
            b1 * (a2 * d4 - a4 * d2) +
×
1596
            d1 * (a2 * b4 - a4 * b2)) *
×
1597
        scale;
NEW
1598
    _m4storage[11] =
×
NEW
1599
        -(a1 * (b2 * c4 - b4 * c2) -
×
1600
            b1 * (a2 * c4 - a4 * c2) +
×
1601
            c1 * (a2 * b4 - a4 * b2)) *
×
1602
        scale;
NEW
1603
    _m4storage[12] =
×
NEW
1604
        -(b1 * (c2 * d3 - c3 * d2) -
×
1605
            c1 * (b2 * d3 - b3 * d2) +
×
1606
            d1 * (b2 * c3 - b3 * c2)) *
×
1607
        scale;
NEW
1608
    _m4storage[13] =
×
NEW
1609
        (a1 * (c2 * d3 - c3 * d2) -
×
1610
            c1 * (a2 * d3 - a3 * d2) +
×
1611
            d1 * (a2 * c3 - a3 * c2)) *
×
1612
        scale;
NEW
1613
    _m4storage[14] =
×
NEW
1614
        -(a1 * (b2 * d3 - b3 * d2) -
×
1615
            b1 * (a2 * d3 - a3 * d2) +
×
1616
            d1 * (a2 * b3 - a3 * b2)) *
×
1617
        scale;
NEW
1618
    _m4storage[15] =
×
NEW
1619
        (a1 * (b2 * c3 - b3 * c2) -
×
1620
            b1 * (a2 * c3 - a3 * c2) +
×
1621
            c1 * (a2 * b3 - a3 * b2)) *
×
1622
        scale;
1623
  }
1624

1625
  /// Rotates [arg] by the absolute rotation of this
1626
  /// Returns [arg].
1627
  /// Primarily used by AABB transformation code.
1628
  Vector3 absoluteRotate(Vector3 arg) {
×
1629
    final m00 = _m4storage[0].abs();
×
1630
    final m01 = _m4storage[4].abs();
×
1631
    final m02 = _m4storage[8].abs();
×
1632
    final m10 = _m4storage[1].abs();
×
1633
    final m11 = _m4storage[5].abs();
×
1634
    final m12 = _m4storage[9].abs();
×
1635
    final m20 = _m4storage[2].abs();
×
1636
    final m21 = _m4storage[6].abs();
×
1637
    final m22 = _m4storage[10].abs();
×
1638
    final argStorage = arg._v3storage;
×
1639
    final x = argStorage[0];
×
1640
    final y = argStorage[1];
×
1641
    final z = argStorage[2];
×
1642
    argStorage[0] = x * m00 + y * m01 + z * m02 + 0.0 * 0.0;
×
1643
    argStorage[1] = x * m10 + y * m11 + z * m12 + 0.0 * 0.0;
×
1644
    argStorage[2] = x * m20 + y * m21 + z * m22 + 0.0 * 0.0;
×
1645
    return arg;
1646
  }
1647

1648
  /// Adds [o] to this.
1649
  void add(Matrix4 o) {
×
1650
    final oStorage = o._m4storage;
×
1651
    _m4storage[0] = _m4storage[0] + oStorage[0];
×
1652
    _m4storage[1] = _m4storage[1] + oStorage[1];
×
1653
    _m4storage[2] = _m4storage[2] + oStorage[2];
×
1654
    _m4storage[3] = _m4storage[3] + oStorage[3];
×
1655
    _m4storage[4] = _m4storage[4] + oStorage[4];
×
1656
    _m4storage[5] = _m4storage[5] + oStorage[5];
×
1657
    _m4storage[6] = _m4storage[6] + oStorage[6];
×
1658
    _m4storage[7] = _m4storage[7] + oStorage[7];
×
1659
    _m4storage[8] = _m4storage[8] + oStorage[8];
×
1660
    _m4storage[9] = _m4storage[9] + oStorage[9];
×
1661
    _m4storage[10] = _m4storage[10] + oStorage[10];
×
1662
    _m4storage[11] = _m4storage[11] + oStorage[11];
×
1663
    _m4storage[12] = _m4storage[12] + oStorage[12];
×
1664
    _m4storage[13] = _m4storage[13] + oStorage[13];
×
1665
    _m4storage[14] = _m4storage[14] + oStorage[14];
×
1666
    _m4storage[15] = _m4storage[15] + oStorage[15];
×
1667
  }
1668

1669
  /// Subtracts [o] from this.
1670
  void sub(Matrix4 o) {
×
1671
    final oStorage = o._m4storage;
×
1672
    _m4storage[0] = _m4storage[0] - oStorage[0];
×
1673
    _m4storage[1] = _m4storage[1] - oStorage[1];
×
1674
    _m4storage[2] = _m4storage[2] - oStorage[2];
×
1675
    _m4storage[3] = _m4storage[3] - oStorage[3];
×
1676
    _m4storage[4] = _m4storage[4] - oStorage[4];
×
1677
    _m4storage[5] = _m4storage[5] - oStorage[5];
×
1678
    _m4storage[6] = _m4storage[6] - oStorage[6];
×
1679
    _m4storage[7] = _m4storage[7] - oStorage[7];
×
1680
    _m4storage[8] = _m4storage[8] - oStorage[8];
×
1681
    _m4storage[9] = _m4storage[9] - oStorage[9];
×
1682
    _m4storage[10] = _m4storage[10] - oStorage[10];
×
1683
    _m4storage[11] = _m4storage[11] - oStorage[11];
×
1684
    _m4storage[12] = _m4storage[12] - oStorage[12];
×
1685
    _m4storage[13] = _m4storage[13] - oStorage[13];
×
1686
    _m4storage[14] = _m4storage[14] - oStorage[14];
×
1687
    _m4storage[15] = _m4storage[15] - oStorage[15];
×
1688
  }
1689

1690
  /// Negate this.
1691
  void negate() {
×
1692
    _m4storage[0] = -_m4storage[0];
×
1693
    _m4storage[1] = -_m4storage[1];
×
1694
    _m4storage[2] = -_m4storage[2];
×
1695
    _m4storage[3] = -_m4storage[3];
×
1696
    _m4storage[4] = -_m4storage[4];
×
1697
    _m4storage[5] = -_m4storage[5];
×
1698
    _m4storage[6] = -_m4storage[6];
×
1699
    _m4storage[7] = -_m4storage[7];
×
1700
    _m4storage[8] = -_m4storage[8];
×
1701
    _m4storage[9] = -_m4storage[9];
×
1702
    _m4storage[10] = -_m4storage[10];
×
1703
    _m4storage[11] = -_m4storage[11];
×
1704
    _m4storage[12] = -_m4storage[12];
×
1705
    _m4storage[13] = -_m4storage[13];
×
1706
    _m4storage[14] = -_m4storage[14];
×
1707
    _m4storage[15] = -_m4storage[15];
×
1708
  }
1709

1710
  /// Multiply this by [arg].
1711
  void multiply(Matrix4 arg) {
×
1712
    final m00 = _m4storage[0];
×
1713
    final m01 = _m4storage[4];
×
1714
    final m02 = _m4storage[8];
×
1715
    final m03 = _m4storage[12];
×
1716
    final m10 = _m4storage[1];
×
1717
    final m11 = _m4storage[5];
×
1718
    final m12 = _m4storage[9];
×
1719
    final m13 = _m4storage[13];
×
1720
    final m20 = _m4storage[2];
×
1721
    final m21 = _m4storage[6];
×
1722
    final m22 = _m4storage[10];
×
1723
    final m23 = _m4storage[14];
×
1724
    final m30 = _m4storage[3];
×
1725
    final m31 = _m4storage[7];
×
1726
    final m32 = _m4storage[11];
×
1727
    final m33 = _m4storage[15];
×
1728
    final argStorage = arg._m4storage;
×
1729
    final n00 = argStorage[0];
×
1730
    final n01 = argStorage[4];
×
1731
    final n02 = argStorage[8];
×
1732
    final n03 = argStorage[12];
×
1733
    final n10 = argStorage[1];
×
1734
    final n11 = argStorage[5];
×
1735
    final n12 = argStorage[9];
×
1736
    final n13 = argStorage[13];
×
1737
    final n20 = argStorage[2];
×
1738
    final n21 = argStorage[6];
×
1739
    final n22 = argStorage[10];
×
1740
    final n23 = argStorage[14];
×
1741
    final n30 = argStorage[3];
×
1742
    final n31 = argStorage[7];
×
1743
    final n32 = argStorage[11];
×
1744
    final n33 = argStorage[15];
×
1745
    _m4storage[0] = (m00 * n00) + (m01 * n10) + (m02 * n20) + (m03 * n30);
×
1746
    _m4storage[4] = (m00 * n01) + (m01 * n11) + (m02 * n21) + (m03 * n31);
×
1747
    _m4storage[8] = (m00 * n02) + (m01 * n12) + (m02 * n22) + (m03 * n32);
×
1748
    _m4storage[12] = (m00 * n03) + (m01 * n13) + (m02 * n23) + (m03 * n33);
×
1749
    _m4storage[1] = (m10 * n00) + (m11 * n10) + (m12 * n20) + (m13 * n30);
×
1750
    _m4storage[5] = (m10 * n01) + (m11 * n11) + (m12 * n21) + (m13 * n31);
×
1751
    _m4storage[9] = (m10 * n02) + (m11 * n12) + (m12 * n22) + (m13 * n32);
×
1752
    _m4storage[13] = (m10 * n03) + (m11 * n13) + (m12 * n23) + (m13 * n33);
×
1753
    _m4storage[2] = (m20 * n00) + (m21 * n10) + (m22 * n20) + (m23 * n30);
×
1754
    _m4storage[6] = (m20 * n01) + (m21 * n11) + (m22 * n21) + (m23 * n31);
×
1755
    _m4storage[10] = (m20 * n02) + (m21 * n12) + (m22 * n22) + (m23 * n32);
×
1756
    _m4storage[14] = (m20 * n03) + (m21 * n13) + (m22 * n23) + (m23 * n33);
×
1757
    _m4storage[3] = (m30 * n00) + (m31 * n10) + (m32 * n20) + (m33 * n30);
×
1758
    _m4storage[7] = (m30 * n01) + (m31 * n11) + (m32 * n21) + (m33 * n31);
×
1759
    _m4storage[11] = (m30 * n02) + (m31 * n12) + (m32 * n22) + (m33 * n32);
×
1760
    _m4storage[15] = (m30 * n03) + (m31 * n13) + (m32 * n23) + (m33 * n33);
×
1761
  }
1762

1763
  /// Multiply a copy of this with [arg].
1764
  Matrix4 multiplied(Matrix4 arg) => clone()..multiply(arg);
×
1765

1766
  /// Multiply a transposed this with [arg].
1767
  void transposeMultiply(Matrix4 arg) {
×
1768
    final m00 = _m4storage[0];
×
1769
    final m01 = _m4storage[1];
×
1770
    final m02 = _m4storage[2];
×
1771
    final m03 = _m4storage[3];
×
1772
    final m10 = _m4storage[4];
×
1773
    final m11 = _m4storage[5];
×
1774
    final m12 = _m4storage[6];
×
1775
    final m13 = _m4storage[7];
×
1776
    final m20 = _m4storage[8];
×
1777
    final m21 = _m4storage[9];
×
1778
    final m22 = _m4storage[10];
×
1779
    final m23 = _m4storage[11];
×
1780
    final m30 = _m4storage[12];
×
1781
    final m31 = _m4storage[13];
×
1782
    final m32 = _m4storage[14];
×
1783
    final m33 = _m4storage[15];
×
1784
    final argStorage = arg._m4storage;
×
NEW
1785
    _m4storage[0] =
×
NEW
1786
        (m00 * argStorage[0]) +
×
1787
        (m01 * argStorage[1]) +
×
1788
        (m02 * argStorage[2]) +
×
1789
        (m03 * argStorage[3]);
×
NEW
1790
    _m4storage[4] =
×
NEW
1791
        (m00 * argStorage[4]) +
×
1792
        (m01 * argStorage[5]) +
×
1793
        (m02 * argStorage[6]) +
×
1794
        (m03 * argStorage[7]);
×
NEW
1795
    _m4storage[8] =
×
NEW
1796
        (m00 * argStorage[8]) +
×
1797
        (m01 * argStorage[9]) +
×
1798
        (m02 * argStorage[10]) +
×
1799
        (m03 * argStorage[11]);
×
NEW
1800
    _m4storage[12] =
×
NEW
1801
        (m00 * argStorage[12]) +
×
1802
        (m01 * argStorage[13]) +
×
1803
        (m02 * argStorage[14]) +
×
1804
        (m03 * argStorage[15]);
×
NEW
1805
    _m4storage[1] =
×
NEW
1806
        (m10 * argStorage[0]) +
×
1807
        (m11 * argStorage[1]) +
×
1808
        (m12 * argStorage[2]) +
×
1809
        (m13 * argStorage[3]);
×
NEW
1810
    _m4storage[5] =
×
NEW
1811
        (m10 * argStorage[4]) +
×
1812
        (m11 * argStorage[5]) +
×
1813
        (m12 * argStorage[6]) +
×
1814
        (m13 * argStorage[7]);
×
NEW
1815
    _m4storage[9] =
×
NEW
1816
        (m10 * argStorage[8]) +
×
1817
        (m11 * argStorage[9]) +
×
1818
        (m12 * argStorage[10]) +
×
1819
        (m13 * argStorage[11]);
×
NEW
1820
    _m4storage[13] =
×
NEW
1821
        (m10 * argStorage[12]) +
×
1822
        (m11 * argStorage[13]) +
×
1823
        (m12 * argStorage[14]) +
×
1824
        (m13 * argStorage[15]);
×
NEW
1825
    _m4storage[2] =
×
NEW
1826
        (m20 * argStorage[0]) +
×
1827
        (m21 * argStorage[1]) +
×
1828
        (m22 * argStorage[2]) +
×
1829
        (m23 * argStorage[3]);
×
NEW
1830
    _m4storage[6] =
×
NEW
1831
        (m20 * argStorage[4]) +
×
1832
        (m21 * argStorage[5]) +
×
1833
        (m22 * argStorage[6]) +
×
1834
        (m23 * argStorage[7]);
×
NEW
1835
    _m4storage[10] =
×
NEW
1836
        (m20 * argStorage[8]) +
×
1837
        (m21 * argStorage[9]) +
×
1838
        (m22 * argStorage[10]) +
×
1839
        (m23 * argStorage[11]);
×
NEW
1840
    _m4storage[14] =
×
NEW
1841
        (m20 * argStorage[12]) +
×
1842
        (m21 * argStorage[13]) +
×
1843
        (m22 * argStorage[14]) +
×
1844
        (m23 * argStorage[15]);
×
NEW
1845
    _m4storage[3] =
×
NEW
1846
        (m30 * argStorage[0]) +
×
1847
        (m31 * argStorage[1]) +
×
1848
        (m32 * argStorage[2]) +
×
1849
        (m33 * argStorage[3]);
×
NEW
1850
    _m4storage[7] =
×
NEW
1851
        (m30 * argStorage[4]) +
×
1852
        (m31 * argStorage[5]) +
×
1853
        (m32 * argStorage[6]) +
×
1854
        (m33 * argStorage[7]);
×
NEW
1855
    _m4storage[11] =
×
NEW
1856
        (m30 * argStorage[8]) +
×
1857
        (m31 * argStorage[9]) +
×
1858
        (m32 * argStorage[10]) +
×
1859
        (m33 * argStorage[11]);
×
NEW
1860
    _m4storage[15] =
×
NEW
1861
        (m30 * argStorage[12]) +
×
1862
        (m31 * argStorage[13]) +
×
1863
        (m32 * argStorage[14]) +
×
1864
        (m33 * argStorage[15]);
×
1865
  }
1866

1867
  /// Multiply this with a transposed [arg].
1868
  void multiplyTranspose(Matrix4 arg) {
×
1869
    final m00 = _m4storage[0];
×
1870
    final m01 = _m4storage[4];
×
1871
    final m02 = _m4storage[8];
×
1872
    final m03 = _m4storage[12];
×
1873
    final m10 = _m4storage[1];
×
1874
    final m11 = _m4storage[5];
×
1875
    final m12 = _m4storage[9];
×
1876
    final m13 = _m4storage[13];
×
1877
    final m20 = _m4storage[2];
×
1878
    final m21 = _m4storage[6];
×
1879
    final m22 = _m4storage[10];
×
1880
    final m23 = _m4storage[14];
×
1881
    final m30 = _m4storage[3];
×
1882
    final m31 = _m4storage[7];
×
1883
    final m32 = _m4storage[11];
×
1884
    final m33 = _m4storage[15];
×
1885
    final argStorage = arg._m4storage;
×
NEW
1886
    _m4storage[0] =
×
NEW
1887
        (m00 * argStorage[0]) +
×
1888
        (m01 * argStorage[4]) +
×
1889
        (m02 * argStorage[8]) +
×
1890
        (m03 * argStorage[12]);
×
NEW
1891
    _m4storage[4] =
×
NEW
1892
        (m00 * argStorage[1]) +
×
1893
        (m01 * argStorage[5]) +
×
1894
        (m02 * argStorage[9]) +
×
1895
        (m03 * argStorage[13]);
×
NEW
1896
    _m4storage[8] =
×
NEW
1897
        (m00 * argStorage[2]) +
×
1898
        (m01 * argStorage[6]) +
×
1899
        (m02 * argStorage[10]) +
×
1900
        (m03 * argStorage[14]);
×
NEW
1901
    _m4storage[12] =
×
NEW
1902
        (m00 * argStorage[3]) +
×
1903
        (m01 * argStorage[7]) +
×
1904
        (m02 * argStorage[11]) +
×
1905
        (m03 * argStorage[15]);
×
NEW
1906
    _m4storage[1] =
×
NEW
1907
        (m10 * argStorage[0]) +
×
1908
        (m11 * argStorage[4]) +
×
1909
        (m12 * argStorage[8]) +
×
1910
        (m13 * argStorage[12]);
×
NEW
1911
    _m4storage[5] =
×
NEW
1912
        (m10 * argStorage[1]) +
×
1913
        (m11 * argStorage[5]) +
×
1914
        (m12 * argStorage[9]) +
×
1915
        (m13 * argStorage[13]);
×
NEW
1916
    _m4storage[9] =
×
NEW
1917
        (m10 * argStorage[2]) +
×
1918
        (m11 * argStorage[6]) +
×
1919
        (m12 * argStorage[10]) +
×
1920
        (m13 * argStorage[14]);
×
NEW
1921
    _m4storage[13] =
×
NEW
1922
        (m10 * argStorage[3]) +
×
1923
        (m11 * argStorage[7]) +
×
1924
        (m12 * argStorage[11]) +
×
1925
        (m13 * argStorage[15]);
×
NEW
1926
    _m4storage[2] =
×
NEW
1927
        (m20 * argStorage[0]) +
×
1928
        (m21 * argStorage[4]) +
×
1929
        (m22 * argStorage[8]) +
×
1930
        (m23 * argStorage[12]);
×
NEW
1931
    _m4storage[6] =
×
NEW
1932
        (m20 * argStorage[1]) +
×
1933
        (m21 * argStorage[5]) +
×
1934
        (m22 * argStorage[9]) +
×
1935
        (m23 * argStorage[13]);
×
NEW
1936
    _m4storage[10] =
×
NEW
1937
        (m20 * argStorage[2]) +
×
1938
        (m21 * argStorage[6]) +
×
1939
        (m22 * argStorage[10]) +
×
1940
        (m23 * argStorage[14]);
×
NEW
1941
    _m4storage[14] =
×
NEW
1942
        (m20 * argStorage[3]) +
×
1943
        (m21 * argStorage[7]) +
×
1944
        (m22 * argStorage[11]) +
×
1945
        (m23 * argStorage[15]);
×
NEW
1946
    _m4storage[3] =
×
NEW
1947
        (m30 * argStorage[0]) +
×
1948
        (m31 * argStorage[4]) +
×
1949
        (m32 * argStorage[8]) +
×
1950
        (m33 * argStorage[12]);
×
NEW
1951
    _m4storage[7] =
×
NEW
1952
        (m30 * argStorage[1]) +
×
1953
        (m31 * argStorage[5]) +
×
1954
        (m32 * argStorage[9]) +
×
1955
        (m33 * argStorage[13]);
×
NEW
1956
    _m4storage[11] =
×
NEW
1957
        (m30 * argStorage[2]) +
×
1958
        (m31 * argStorage[6]) +
×
1959
        (m32 * argStorage[10]) +
×
1960
        (m33 * argStorage[14]);
×
NEW
1961
    _m4storage[15] =
×
NEW
1962
        (m30 * argStorage[3]) +
×
1963
        (m31 * argStorage[7]) +
×
1964
        (m32 * argStorage[11]) +
×
1965
        (m33 * argStorage[15]);
×
1966
  }
1967

1968
  /// Decomposes this into [translation], [rotation] and [scale] components.
1969
  void decompose(Vector3 translation, Quaternion rotation, Vector3 scale) {
×
1970
    final v = _decomposeV ??= Vector3.zero();
×
1971
    var sx = (v..setValues(_m4storage[0], _m4storage[1], _m4storage[2])).length;
×
1972
    final sy =
1973
        (v..setValues(_m4storage[4], _m4storage[5], _m4storage[6])).length;
×
1974
    final sz =
1975
        (v..setValues(_m4storage[8], _m4storage[9], _m4storage[10])).length;
×
1976

1977
    if (determinant() < 0) {
×
1978
      sx = -sx;
×
1979
    }
1980

1981
    translation._v3storage[0] = _m4storage[12];
×
1982
    translation._v3storage[1] = _m4storage[13];
×
1983
    translation._v3storage[2] = _m4storage[14];
×
1984

1985
    final invSX = 1.0 / sx;
×
1986
    final invSY = 1.0 / sy;
×
1987
    final invSZ = 1.0 / sz;
×
1988

1989
    final m = _decomposeM ??= Matrix4.zero();
×
1990
    m.setFrom(this);
×
1991
    m._m4storage[0] *= invSX;
×
1992
    m._m4storage[1] *= invSX;
×
1993
    m._m4storage[2] *= invSX;
×
1994
    m._m4storage[4] *= invSY;
×
1995
    m._m4storage[5] *= invSY;
×
1996
    m._m4storage[6] *= invSY;
×
1997
    m._m4storage[8] *= invSZ;
×
1998
    m._m4storage[9] *= invSZ;
×
1999
    m._m4storage[10] *= invSZ;
×
2000

2001
    final r = _decomposeR ??= Matrix3.zero();
×
2002
    m.copyRotation(r);
×
2003
    rotation.setFromRotation(r);
×
2004

2005
    scale._v3storage[0] = sx;
×
2006
    scale._v3storage[1] = sy;
×
2007
    scale._v3storage[2] = sz;
×
2008
  }
2009

2010
  static Vector3? _decomposeV;
2011
  static Matrix4? _decomposeM;
2012
  static Matrix3? _decomposeR;
2013

2014
  /// Rotate [arg] of type [Vector3] using the rotation defined by this.
2015
  Vector3 rotate3(Vector3 arg) {
×
2016
    final argStorage = arg._v3storage;
×
2017
    final x_ =
NEW
2018
        (_m4storage[0] * argStorage[0]) +
×
2019
        (_m4storage[4] * argStorage[1]) +
×
2020
        (_m4storage[8] * argStorage[2]);
×
2021
    final y_ =
NEW
2022
        (_m4storage[1] * argStorage[0]) +
×
2023
        (_m4storage[5] * argStorage[1]) +
×
2024
        (_m4storage[9] * argStorage[2]);
×
2025
    final z_ =
NEW
2026
        (_m4storage[2] * argStorage[0]) +
×
2027
        (_m4storage[6] * argStorage[1]) +
×
2028
        (_m4storage[10] * argStorage[2]);
×
2029
    argStorage[0] = x_;
×
2030
    argStorage[1] = y_;
×
2031
    argStorage[2] = z_;
×
2032
    return arg;
2033
  }
2034

2035
  /// Rotate a copy of [arg] of type [Vector3] using the rotation defined by
2036
  /// this. If a [out] parameter is supplied, the copy is stored in [out].
2037
  Vector3 rotated3(Vector3 arg, [Vector3? out]) {
×
2038
    if (out == null) {
2039
      out = Vector3.copy(arg);
×
2040
    } else {
2041
      out.setFrom(arg);
×
2042
    }
2043
    return rotate3(out);
×
2044
  }
2045

2046
  /// Transform [arg] of type [Vector3] using the transformation defined by
2047
  /// this.
2048
  Vector3 transform3(Vector3 arg) {
×
2049
    final argStorage = arg._v3storage;
×
2050
    final x_ =
NEW
2051
        (_m4storage[0] * argStorage[0]) +
×
2052
        (_m4storage[4] * argStorage[1]) +
×
2053
        (_m4storage[8] * argStorage[2]) +
×
2054
        _m4storage[12];
×
2055
    final y_ =
NEW
2056
        (_m4storage[1] * argStorage[0]) +
×
2057
        (_m4storage[5] * argStorage[1]) +
×
2058
        (_m4storage[9] * argStorage[2]) +
×
2059
        _m4storage[13];
×
2060
    final z_ =
NEW
2061
        (_m4storage[2] * argStorage[0]) +
×
2062
        (_m4storage[6] * argStorage[1]) +
×
2063
        (_m4storage[10] * argStorage[2]) +
×
2064
        _m4storage[14];
×
2065
    argStorage[0] = x_;
×
2066
    argStorage[1] = y_;
×
2067
    argStorage[2] = z_;
×
2068
    return arg;
2069
  }
2070

2071
  /// Transform a copy of [arg] of type [Vector3] using the transformation
2072
  /// defined by this. If a [out] parameter is supplied, the copy is stored in
2073
  /// [out].
2074
  Vector3 transformed3(Vector3 arg, [Vector3? out]) {
×
2075
    if (out == null) {
2076
      out = Vector3.copy(arg);
×
2077
    } else {
2078
      out.setFrom(arg);
×
2079
    }
2080
    return transform3(out);
×
2081
  }
2082

2083
  /// Transform [arg] of type [Vector4] using the transformation defined by
2084
  /// this.
2085
  Vector4 transform(Vector4 arg) {
×
2086
    final argStorage = arg._v4storage;
×
2087
    final x_ =
NEW
2088
        (_m4storage[0] * argStorage[0]) +
×
2089
        (_m4storage[4] * argStorage[1]) +
×
2090
        (_m4storage[8] * argStorage[2]) +
×
2091
        (_m4storage[12] * argStorage[3]);
×
2092
    final y_ =
NEW
2093
        (_m4storage[1] * argStorage[0]) +
×
2094
        (_m4storage[5] * argStorage[1]) +
×
2095
        (_m4storage[9] * argStorage[2]) +
×
2096
        (_m4storage[13] * argStorage[3]);
×
2097
    final z_ =
NEW
2098
        (_m4storage[2] * argStorage[0]) +
×
2099
        (_m4storage[6] * argStorage[1]) +
×
2100
        (_m4storage[10] * argStorage[2]) +
×
2101
        (_m4storage[14] * argStorage[3]);
×
2102
    final w_ =
NEW
2103
        (_m4storage[3] * argStorage[0]) +
×
2104
        (_m4storage[7] * argStorage[1]) +
×
2105
        (_m4storage[11] * argStorage[2]) +
×
2106
        (_m4storage[15] * argStorage[3]);
×
2107
    argStorage[0] = x_;
×
2108
    argStorage[1] = y_;
×
2109
    argStorage[2] = z_;
×
2110
    argStorage[3] = w_;
×
2111
    return arg;
2112
  }
2113

2114
  /// Transform [arg] of type [Vector3] using the perspective transformation
2115
  /// defined by this.
2116
  Vector3 perspectiveTransform(Vector3 arg) {
×
2117
    final argStorage = arg._v3storage;
×
2118
    final x_ =
NEW
2119
        (_m4storage[0] * argStorage[0]) +
×
2120
        (_m4storage[4] * argStorage[1]) +
×
2121
        (_m4storage[8] * argStorage[2]) +
×
2122
        _m4storage[12];
×
2123
    final y_ =
NEW
2124
        (_m4storage[1] * argStorage[0]) +
×
2125
        (_m4storage[5] * argStorage[1]) +
×
2126
        (_m4storage[9] * argStorage[2]) +
×
2127
        _m4storage[13];
×
2128
    final z_ =
NEW
2129
        (_m4storage[2] * argStorage[0]) +
×
2130
        (_m4storage[6] * argStorage[1]) +
×
2131
        (_m4storage[10] * argStorage[2]) +
×
2132
        _m4storage[14];
×
2133
    final w_ =
NEW
2134
        1.0 /
×
2135
        ((_m4storage[3] * argStorage[0]) +
×
2136
            (_m4storage[7] * argStorage[1]) +
×
2137
            (_m4storage[11] * argStorage[2]) +
×
2138
            _m4storage[15]);
×
2139
    argStorage[0] = x_ * w_;
×
2140
    argStorage[1] = y_ * w_;
×
2141
    argStorage[2] = z_ * w_;
×
2142
    return arg;
2143
  }
2144

2145
  /// Transform a copy of [arg] of type [Vector4] using the transformation
2146
  /// defined by this. If a [out] parameter is supplied, the copy is stored in
2147
  /// [out].
2148
  Vector4 transformed(Vector4 arg, [Vector4? out]) {
×
2149
    if (out == null) {
2150
      out = Vector4.copy(arg);
×
2151
    } else {
2152
      out.setFrom(arg);
×
2153
    }
2154
    return transform(out);
×
2155
  }
2156

2157
  /// Copies this into [array] starting at [offset].
2158
  void copyIntoArray(List<num> array, [int offset = 0]) {
×
2159
    final i = offset;
2160
    array[i + 15] = _m4storage[15];
×
2161
    array[i + 14] = _m4storage[14];
×
2162
    array[i + 13] = _m4storage[13];
×
2163
    array[i + 12] = _m4storage[12];
×
2164
    array[i + 11] = _m4storage[11];
×
2165
    array[i + 10] = _m4storage[10];
×
2166
    array[i + 9] = _m4storage[9];
×
2167
    array[i + 8] = _m4storage[8];
×
2168
    array[i + 7] = _m4storage[7];
×
2169
    array[i + 6] = _m4storage[6];
×
2170
    array[i + 5] = _m4storage[5];
×
2171
    array[i + 4] = _m4storage[4];
×
2172
    array[i + 3] = _m4storage[3];
×
2173
    array[i + 2] = _m4storage[2];
×
2174
    array[i + 1] = _m4storage[1];
×
2175
    array[i + 0] = _m4storage[0];
×
2176
  }
2177

2178
  /// Copies elements from [array] into this starting at [offset].
2179
  void copyFromArray(List<double> array, [int offset = 0]) {
×
2180
    final i = offset;
2181
    _m4storage[15] = array[i + 15];
×
2182
    _m4storage[14] = array[i + 14];
×
2183
    _m4storage[13] = array[i + 13];
×
2184
    _m4storage[12] = array[i + 12];
×
2185
    _m4storage[11] = array[i + 11];
×
2186
    _m4storage[10] = array[i + 10];
×
2187
    _m4storage[9] = array[i + 9];
×
2188
    _m4storage[8] = array[i + 8];
×
2189
    _m4storage[7] = array[i + 7];
×
2190
    _m4storage[6] = array[i + 6];
×
2191
    _m4storage[5] = array[i + 5];
×
2192
    _m4storage[4] = array[i + 4];
×
2193
    _m4storage[3] = array[i + 3];
×
2194
    _m4storage[2] = array[i + 2];
×
2195
    _m4storage[1] = array[i + 1];
×
2196
    _m4storage[0] = array[i + 0];
×
2197
  }
2198

2199
  /// Multiply this to each set of xyz values in [array] starting at [offset].
2200
  List<double> applyToVector3Array(List<double> array, [int offset = 0]) {
×
2201
    for (var i = 0, j = offset; i < array.length; i += 3, j += 3) {
×
2202
      final v = Vector3.array(array, j)..applyMatrix4(this);
×
2203
      array[j] = v.storage[0];
×
2204
      array[j + 1] = v.storage[1];
×
2205
      array[j + 2] = v.storage[2];
×
2206
    }
2207

2208
    return array;
2209
  }
2210

2211
  Vector3 get right {
×
2212
    final x = _m4storage[0];
×
2213
    final y = _m4storage[1];
×
2214
    final z = _m4storage[2];
×
2215
    return Vector3(x, y, z);
×
2216
  }
2217

2218
  Vector3 get up {
×
2219
    final x = _m4storage[4];
×
2220
    final y = _m4storage[5];
×
2221
    final z = _m4storage[6];
×
2222
    return Vector3(x, y, z);
×
2223
  }
2224

2225
  Vector3 get forward {
×
2226
    final x = _m4storage[8];
×
2227
    final y = _m4storage[9];
×
2228
    final z = _m4storage[10];
×
2229
    return Vector3(x, y, z);
×
2230
  }
2231

2232
  /// Is this the identity matrix?
2233
  bool isIdentity() =>
×
NEW
2234
      _m4storage[0] ==
×
2235
          1.0 // col 1
2236
          &&
2237
      _m4storage[1] == 0.0 &&
×
2238
      _m4storage[2] == 0.0 &&
×
2239
      _m4storage[3] == 0.0 &&
×
NEW
2240
      _m4storage[4] ==
×
2241
          0.0 // col 2
2242
          &&
2243
      _m4storage[5] == 1.0 &&
×
2244
      _m4storage[6] == 0.0 &&
×
2245
      _m4storage[7] == 0.0 &&
×
NEW
2246
      _m4storage[8] ==
×
2247
          0.0 // col 3
2248
          &&
2249
      _m4storage[9] == 0.0 &&
×
2250
      _m4storage[10] == 1.0 &&
×
2251
      _m4storage[11] == 0.0 &&
×
NEW
2252
      _m4storage[12] ==
×
2253
          0.0 // col 4
2254
          &&
2255
      _m4storage[13] == 0.0 &&
×
2256
      _m4storage[14] == 0.0 &&
×
2257
      _m4storage[15] == 1.0;
×
2258

2259
  /// Is this the zero matrix?
2260
  bool isZero() =>
×
NEW
2261
      _m4storage[0] ==
×
2262
          0.0 // col 1
2263
          &&
2264
      _m4storage[1] == 0.0 &&
×
2265
      _m4storage[2] == 0.0 &&
×
2266
      _m4storage[3] == 0.0 &&
×
NEW
2267
      _m4storage[4] ==
×
2268
          0.0 // col 2
2269
          &&
2270
      _m4storage[5] == 0.0 &&
×
2271
      _m4storage[6] == 0.0 &&
×
2272
      _m4storage[7] == 0.0 &&
×
NEW
2273
      _m4storage[8] ==
×
2274
          0.0 // col 3
2275
          &&
2276
      _m4storage[9] == 0.0 &&
×
2277
      _m4storage[10] == 0.0 &&
×
2278
      _m4storage[11] == 0.0 &&
×
NEW
2279
      _m4storage[12] ==
×
2280
          0.0 // col 4
2281
          &&
2282
      _m4storage[13] == 0.0 &&
×
2283
      _m4storage[14] == 0.0 &&
×
2284
      _m4storage[15] == 0.0;
×
2285
}
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