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

google / vector_math.dart / 16243452457

16 May 2025 09:33PM UTC coverage: 26.388%. Remained the same
16243452457

push

github

web-flow
Remove prefer-inline for non-trivial Matrix functions (#347)

* Prepare release

4335 of 16428 relevant lines covered (26.39%)

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
    scaleByVector3(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
  ///
642
  /// [arg] should be a [double] (to scale), [Vector4] (to transform), [Vector3]
643
  /// (to transform), or [Matrix4] (to multiply).
644
  ///
645
  /// If you know the argument type in a call site, prefer [scaledByDouble],
646
  /// [transformed], [transformed3], or [multiplied] for performance.
647
  @pragma('wasm:prefer-inline')
×
648
  @pragma('vm:prefer-inline')
649
  @pragma('dart2js:prefer-inline')
650
  dynamic operator *(dynamic arg) {
651
    final Object result;
652
    if (arg is double) {
×
653
      result = scaledByDouble(arg, arg, arg, 1.0);
×
654
    } else if (arg is Vector4) {
×
655
      result = transformed(arg);
×
656
    } else if (arg is Vector3) {
×
657
      result = transformed3(arg);
×
658
    } else if (arg is Matrix4) {
×
659
      result = multiplied(arg);
×
660
    } else {
661
      throw ArgumentError(arg);
×
662
    }
663
    return result;
664
  }
665

666
  /// Returns new matrix after component wise this + [arg]
667
  Matrix4 operator +(Matrix4 arg) => clone()..add(arg);
×
668

669
  /// Returns new matrix after component wise this - [arg]
670
  Matrix4 operator -(Matrix4 arg) => clone()..sub(arg);
×
671

672
  /// Translate this matrix by a [Vector3], [Vector4], or x,y,z as [double]s.
673
  ///
674
  /// If you know the argument types in a call site, prefer [translateByDouble],
675
  /// [translateByVector3], or [translateByVector4] for performance.
676
  @pragma('wasm:prefer-inline')
×
677
  @pragma('vm:prefer-inline')
678
  @pragma('dart2js:prefer-inline')
679
  @Deprecated('Use translateByVector3, translateByVector4, '
680
      'or translateByDouble instead')
681
  void translate(dynamic x, [double y = 0.0, double z = 0.0]) {
682
    if (x is Vector3) {
×
683
      translateByVector3(x);
×
684
    } else if (x is Vector4) {
×
685
      translateByVector4(x);
×
686
    } else if (x is double) {
×
687
      translateByDouble(x, y, z, 1.0);
×
688
    } else {
689
      throw UnimplementedError();
×
690
    }
691
  }
692

693
  /// Translate this matrix by x, y, z, w.
694
  void translateByDouble(double tx, double ty, double tz, double tw) {
×
695
    final t1 = _m4storage[0] * tx +
×
696
        _m4storage[4] * ty +
×
697
        _m4storage[8] * tz +
×
698
        _m4storage[12] * tw;
×
699
    _m4storage[12] = t1;
×
700

701
    final t2 = _m4storage[1] * tx +
×
702
        _m4storage[5] * ty +
×
703
        _m4storage[9] * tz +
×
704
        _m4storage[13] * tw;
×
705
    _m4storage[13] = t2;
×
706

707
    final t3 = _m4storage[2] * tx +
×
708
        _m4storage[6] * ty +
×
709
        _m4storage[10] * tz +
×
710
        _m4storage[14] * tw;
×
711
    _m4storage[14] = t3;
×
712

713
    final t4 = _m4storage[3] * tx +
×
714
        _m4storage[7] * ty +
×
715
        _m4storage[11] * tz +
×
716
        _m4storage[15] * tw;
×
717
    _m4storage[15] = t4;
×
718
  }
719

720
  /// Translate this matrix by a [Vector3].
721
  @pragma('wasm:prefer-inline')
×
722
  @pragma('vm:prefer-inline')
723
  @pragma('dart2js:prefer-inline')
724
  void translateByVector3(Vector3 v3) =>
725
      translateByDouble(v3.x, v3.y, v3.z, 1.0);
×
726

727
  /// Translate this matrix by a [Vector4].
728
  @pragma('wasm:prefer-inline')
×
729
  @pragma('vm:prefer-inline')
730
  @pragma('dart2js:prefer-inline')
731
  void translateByVector4(Vector4 v4) =>
732
      translateByDouble(v4.x, v4.y, v4.z, v4.w);
×
733

734
  /// Multiply this by a translation from the left.
735
  ///
736
  /// The translation can be specified with a [Vector3], [Vector4], or x, y, z
737
  /// as [double]s.
738
  ///
739
  /// If you know the argument types in a call site, prefer
740
  /// [leftTranslateByDouble], [leftTranslateByVector3], or
741
  /// [leftTranslateByVector4] for performance.
742
  @pragma('wasm:prefer-inline')
×
743
  @pragma('vm:prefer-inline')
744
  @pragma('dart2js:prefer-inline')
745
  @Deprecated('Use leftTranslateByVector3, leftTranslateByVector4, '
746
      'or leftTranslateByDouble instead')
747
  void leftTranslate(dynamic x, [double y = 0.0, double z = 0.0]) {
748
    if (x is Vector3) {
×
749
      leftTranslateByVector3(x);
×
750
    } else if (x is Vector4) {
×
751
      leftTranslateByVector4(x);
×
752
    } else if (x is double) {
×
753
      leftTranslateByDouble(x, y, z, 1.0);
×
754
    } else {
755
      throw UnimplementedError();
×
756
    }
757
  }
758

759
  /// Multiply this by a translation from the left.
760
  void leftTranslateByDouble(double tx, double ty, double tz, double tw) {
×
761
    // Column 1
762
    final r1 = _m4storage[3];
×
763
    _m4storage[0] += tx * r1;
×
764
    _m4storage[1] += ty * r1;
×
765
    _m4storage[2] += tz * r1;
×
766
    _m4storage[3] = tw * r1;
×
767

768
    // Column 2
769
    final r2 = _m4storage[7];
×
770
    _m4storage[4] += tx * r2;
×
771
    _m4storage[5] += ty * r2;
×
772
    _m4storage[6] += tz * r2;
×
773
    _m4storage[7] = tw * r2;
×
774

775
    // Column 3
776
    final r3 = _m4storage[11];
×
777
    _m4storage[8] += tx * r3;
×
778
    _m4storage[9] += ty * r3;
×
779
    _m4storage[10] += tz * r3;
×
780
    _m4storage[11] = tw * r3;
×
781

782
    // Column 4
783
    final r4 = _m4storage[15];
×
784
    _m4storage[12] += tx * r4;
×
785
    _m4storage[13] += ty * r4;
×
786
    _m4storage[14] += tz * r4;
×
787
    _m4storage[15] = tw * r4;
×
788
  }
789

790
  /// Multiply this by a translation from the left.
791
  @pragma('wasm:prefer-inline')
×
792
  @pragma('vm:prefer-inline')
793
  @pragma('dart2js:prefer-inline')
794
  void leftTranslateByVector3(Vector3 v3) =>
795
      leftTranslateByDouble(v3.x, v3.y, v3.z, 1.0);
×
796

797
  /// Multiply this by a translation from the left.
798
  @pragma('wasm:prefer-inline')
×
799
  @pragma('vm:prefer-inline')
800
  @pragma('dart2js:prefer-inline')
801
  void leftTranslateByVector4(Vector4 v4) =>
802
      leftTranslateByDouble(v4.x, v4.y, v4.z, v4.w);
×
803

804
  /// Rotate this [angle] radians around [axis]
805
  void rotate(Vector3 axis, double angle) {
×
806
    final len = axis.length;
×
807
    final axisStorage = axis._v3storage;
×
808
    final x = axisStorage[0] / len;
×
809
    final y = axisStorage[1] / len;
×
810
    final z = axisStorage[2] / len;
×
811
    final c = math.cos(angle);
×
812
    final s = math.sin(angle);
×
813
    final C = 1.0 - c;
×
814
    final m11 = x * x * C + c;
×
815
    final m12 = x * y * C - z * s;
×
816
    final m13 = x * z * C + y * s;
×
817
    final m21 = y * x * C + z * s;
×
818
    final m22 = y * y * C + c;
×
819
    final m23 = y * z * C - x * s;
×
820
    final m31 = z * x * C - y * s;
×
821
    final m32 = z * y * C + x * s;
×
822
    final m33 = z * z * C + c;
×
823
    final t1 = _m4storage[0] * m11 + _m4storage[4] * m21 + _m4storage[8] * m31;
×
824
    final t2 = _m4storage[1] * m11 + _m4storage[5] * m21 + _m4storage[9] * m31;
×
825
    final t3 = _m4storage[2] * m11 + _m4storage[6] * m21 + _m4storage[10] * m31;
×
826
    final t4 = _m4storage[3] * m11 + _m4storage[7] * m21 + _m4storage[11] * m31;
×
827
    final t5 = _m4storage[0] * m12 + _m4storage[4] * m22 + _m4storage[8] * m32;
×
828
    final t6 = _m4storage[1] * m12 + _m4storage[5] * m22 + _m4storage[9] * m32;
×
829
    final t7 = _m4storage[2] * m12 + _m4storage[6] * m22 + _m4storage[10] * m32;
×
830
    final t8 = _m4storage[3] * m12 + _m4storage[7] * m22 + _m4storage[11] * m32;
×
831
    final t9 = _m4storage[0] * m13 + _m4storage[4] * m23 + _m4storage[8] * m33;
×
832
    final t10 = _m4storage[1] * m13 + _m4storage[5] * m23 + _m4storage[9] * m33;
×
833
    final t11 =
834
        _m4storage[2] * m13 + _m4storage[6] * m23 + _m4storage[10] * m33;
×
835
    final t12 =
836
        _m4storage[3] * m13 + _m4storage[7] * m23 + _m4storage[11] * m33;
×
837
    _m4storage[0] = t1;
×
838
    _m4storage[1] = t2;
×
839
    _m4storage[2] = t3;
×
840
    _m4storage[3] = t4;
×
841
    _m4storage[4] = t5;
×
842
    _m4storage[5] = t6;
×
843
    _m4storage[6] = t7;
×
844
    _m4storage[7] = t8;
×
845
    _m4storage[8] = t9;
×
846
    _m4storage[9] = t10;
×
847
    _m4storage[10] = t11;
×
848
    _m4storage[11] = t12;
×
849
  }
850

851
  /// Rotate this [angle] radians around X
852
  void rotateX(double angle) {
×
853
    final cosAngle = math.cos(angle);
×
854
    final sinAngle = math.sin(angle);
×
855
    final t1 = _m4storage[4] * cosAngle + _m4storage[8] * sinAngle;
×
856
    final t2 = _m4storage[5] * cosAngle + _m4storage[9] * sinAngle;
×
857
    final t3 = _m4storage[6] * cosAngle + _m4storage[10] * sinAngle;
×
858
    final t4 = _m4storage[7] * cosAngle + _m4storage[11] * sinAngle;
×
859
    final t5 = _m4storage[4] * -sinAngle + _m4storage[8] * cosAngle;
×
860
    final t6 = _m4storage[5] * -sinAngle + _m4storage[9] * cosAngle;
×
861
    final t7 = _m4storage[6] * -sinAngle + _m4storage[10] * cosAngle;
×
862
    final t8 = _m4storage[7] * -sinAngle + _m4storage[11] * cosAngle;
×
863
    _m4storage[4] = t1;
×
864
    _m4storage[5] = t2;
×
865
    _m4storage[6] = t3;
×
866
    _m4storage[7] = t4;
×
867
    _m4storage[8] = t5;
×
868
    _m4storage[9] = t6;
×
869
    _m4storage[10] = t7;
×
870
    _m4storage[11] = t8;
×
871
  }
872

873
  /// Rotate this matrix [angle] radians around Y
874
  void rotateY(double angle) {
×
875
    final cosAngle = math.cos(angle);
×
876
    final sinAngle = math.sin(angle);
×
877
    final t1 = _m4storage[0] * cosAngle + _m4storage[8] * -sinAngle;
×
878
    final t2 = _m4storage[1] * cosAngle + _m4storage[9] * -sinAngle;
×
879
    final t3 = _m4storage[2] * cosAngle + _m4storage[10] * -sinAngle;
×
880
    final t4 = _m4storage[3] * cosAngle + _m4storage[11] * -sinAngle;
×
881
    final t5 = _m4storage[0] * sinAngle + _m4storage[8] * cosAngle;
×
882
    final t6 = _m4storage[1] * sinAngle + _m4storage[9] * cosAngle;
×
883
    final t7 = _m4storage[2] * sinAngle + _m4storage[10] * cosAngle;
×
884
    final t8 = _m4storage[3] * sinAngle + _m4storage[11] * cosAngle;
×
885
    _m4storage[0] = t1;
×
886
    _m4storage[1] = t2;
×
887
    _m4storage[2] = t3;
×
888
    _m4storage[3] = t4;
×
889
    _m4storage[8] = t5;
×
890
    _m4storage[9] = t6;
×
891
    _m4storage[10] = t7;
×
892
    _m4storage[11] = t8;
×
893
  }
894

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

917
  /// Scale this matrix by a [Vector3], [Vector4], or x,y,z as [double]s.
918
  ///
919
  /// If you know the argument types in a call site, prefer [scaleByDouble],
920
  /// [scaleByVector3], or [scaleByVector4] for performance.
921
  @pragma('wasm:prefer-inline')
×
922
  @pragma('vm:prefer-inline')
923
  @pragma('dart2js:prefer-inline')
924
  @Deprecated('Use scaleByVector3, scaleByVector4, or scaleByDouble instead')
925
  void scale(dynamic x, [double? y, double? z]) {
926
    if (x is Vector3) {
×
927
      scaleByVector3(x);
×
928
    } else if (x is Vector4) {
×
929
      scaleByVector4(x);
×
930
    } else if (x is double) {
×
931
      scaleByDouble(x, y ?? x, z ?? x, 1.0);
×
932
    } else {
933
      throw UnimplementedError();
×
934
    }
935
  }
936

937
  /// Scale this matrix.
938
  void scaleByDouble(double sx, double sy, double sz, double sw) {
×
939
    _m4storage[0] *= sx;
×
940
    _m4storage[1] *= sx;
×
941
    _m4storage[2] *= sx;
×
942
    _m4storage[3] *= sx;
×
943
    _m4storage[4] *= sy;
×
944
    _m4storage[5] *= sy;
×
945
    _m4storage[6] *= sy;
×
946
    _m4storage[7] *= sy;
×
947
    _m4storage[8] *= sz;
×
948
    _m4storage[9] *= sz;
×
949
    _m4storage[10] *= sz;
×
950
    _m4storage[11] *= sz;
×
951
    _m4storage[12] *= sw;
×
952
    _m4storage[13] *= sw;
×
953
    _m4storage[14] *= sw;
×
954
    _m4storage[15] *= sw;
×
955
  }
956

957
  /// Scale this matrix.
958
  @pragma('wasm:prefer-inline')
×
959
  @pragma('vm:prefer-inline')
960
  @pragma('dart2js:prefer-inline')
961
  void scaleByVector3(Vector3 v3) => scaleByDouble(v3.x, v3.y, v3.z, 1.0);
×
962

963
  /// Scale this matrix.
964
  @pragma('wasm:prefer-inline')
×
965
  @pragma('vm:prefer-inline')
966
  @pragma('dart2js:prefer-inline')
967
  void scaleByVector4(Vector4 v4) => scaleByDouble(v4.x, v4.y, v4.z, v4.w);
×
968

969
  /// Create a copy of this scaled by a [Vector3], [Vector4] or [x],[y], and
970
  /// [z].
971
  @pragma('wasm:prefer-inline')
×
972
  @pragma('vm:prefer-inline')
973
  @pragma('dart2js:prefer-inline')
974
  @Deprecated('Use scaledByVector3, scaledByVector4, or scaledByDouble instead')
975
  Matrix4 scaled(dynamic x, [double? y, double? z]) => clone()..scale(x, y, z);
×
976

977
  /// Create a copy of this scaled by [x], [y], [z], and [t].
978
  @pragma('wasm:prefer-inline')
×
979
  @pragma('vm:prefer-inline')
980
  @pragma('dart2js:prefer-inline')
981
  Matrix4 scaledByDouble(double x, double y, double z, double t) =>
982
      clone()..scaleByDouble(x, y, z, t);
×
983

984
  /// Create a copy of this scaled by a [Vector3].
985
  @pragma('wasm:prefer-inline')
×
986
  @pragma('vm:prefer-inline')
987
  @pragma('dart2js:prefer-inline')
988
  Matrix4 scaledByVector3(Vector3 v3) => clone()..scaleByVector3(v3);
×
989

990
  /// Create a copy of this scaled by a [Vector4].
991
  @pragma('wasm:prefer-inline')
×
992
  @pragma('vm:prefer-inline')
993
  @pragma('dart2js:prefer-inline')
994
  Matrix4 scaledByVector4(Vector4 v4) => clone()..scaleByVector4(v4);
×
995

996
  /// Zeros this.
997
  void setZero() {
×
998
    _m4storage[0] = 0.0;
×
999
    _m4storage[1] = 0.0;
×
1000
    _m4storage[2] = 0.0;
×
1001
    _m4storage[3] = 0.0;
×
1002
    _m4storage[4] = 0.0;
×
1003
    _m4storage[5] = 0.0;
×
1004
    _m4storage[6] = 0.0;
×
1005
    _m4storage[7] = 0.0;
×
1006
    _m4storage[8] = 0.0;
×
1007
    _m4storage[9] = 0.0;
×
1008
    _m4storage[10] = 0.0;
×
1009
    _m4storage[11] = 0.0;
×
1010
    _m4storage[12] = 0.0;
×
1011
    _m4storage[13] = 0.0;
×
1012
    _m4storage[14] = 0.0;
×
1013
    _m4storage[15] = 0.0;
×
1014
  }
1015

1016
  /// Makes this into the identity matrix.
1017
  void setIdentity() {
×
1018
    _m4storage[0] = 1.0;
×
1019
    _m4storage[1] = 0.0;
×
1020
    _m4storage[2] = 0.0;
×
1021
    _m4storage[3] = 0.0;
×
1022
    _m4storage[4] = 0.0;
×
1023
    _m4storage[5] = 1.0;
×
1024
    _m4storage[6] = 0.0;
×
1025
    _m4storage[7] = 0.0;
×
1026
    _m4storage[8] = 0.0;
×
1027
    _m4storage[9] = 0.0;
×
1028
    _m4storage[10] = 1.0;
×
1029
    _m4storage[11] = 0.0;
×
1030
    _m4storage[12] = 0.0;
×
1031
    _m4storage[13] = 0.0;
×
1032
    _m4storage[14] = 0.0;
×
1033
    _m4storage[15] = 1.0;
×
1034
  }
1035

1036
  /// Returns the tranpose of this.
1037
  Matrix4 transposed() => clone()..transpose();
×
1038

1039
  void transpose() {
×
1040
    double temp;
1041
    temp = _m4storage[4];
×
1042
    _m4storage[4] = _m4storage[1];
×
1043
    _m4storage[1] = temp;
×
1044
    temp = _m4storage[8];
×
1045
    _m4storage[8] = _m4storage[2];
×
1046
    _m4storage[2] = temp;
×
1047
    temp = _m4storage[12];
×
1048
    _m4storage[12] = _m4storage[3];
×
1049
    _m4storage[3] = temp;
×
1050
    temp = _m4storage[9];
×
1051
    _m4storage[9] = _m4storage[6];
×
1052
    _m4storage[6] = temp;
×
1053
    temp = _m4storage[13];
×
1054
    _m4storage[13] = _m4storage[7];
×
1055
    _m4storage[7] = temp;
×
1056
    temp = _m4storage[14];
×
1057
    _m4storage[14] = _m4storage[11];
×
1058
    _m4storage[11] = temp;
×
1059
  }
1060

1061
  /// Returns the component wise absolute value of this.
1062
  Matrix4 absolute() {
×
1063
    final r = Matrix4.zero();
×
1064
    final rStorage = r._m4storage;
×
1065
    rStorage[0] = _m4storage[0].abs();
×
1066
    rStorage[1] = _m4storage[1].abs();
×
1067
    rStorage[2] = _m4storage[2].abs();
×
1068
    rStorage[3] = _m4storage[3].abs();
×
1069
    rStorage[4] = _m4storage[4].abs();
×
1070
    rStorage[5] = _m4storage[5].abs();
×
1071
    rStorage[6] = _m4storage[6].abs();
×
1072
    rStorage[7] = _m4storage[7].abs();
×
1073
    rStorage[8] = _m4storage[8].abs();
×
1074
    rStorage[9] = _m4storage[9].abs();
×
1075
    rStorage[10] = _m4storage[10].abs();
×
1076
    rStorage[11] = _m4storage[11].abs();
×
1077
    rStorage[12] = _m4storage[12].abs();
×
1078
    rStorage[13] = _m4storage[13].abs();
×
1079
    rStorage[14] = _m4storage[14].abs();
×
1080
    rStorage[15] = _m4storage[15].abs();
×
1081
    return r;
1082
  }
1083

1084
  /// Returns the determinant of this matrix.
1085
  double determinant() {
×
1086
    final det2_01_01 =
1087
        _m4storage[0] * _m4storage[5] - _m4storage[1] * _m4storage[4];
×
1088
    final det2_01_02 =
1089
        _m4storage[0] * _m4storage[6] - _m4storage[2] * _m4storage[4];
×
1090
    final det2_01_03 =
1091
        _m4storage[0] * _m4storage[7] - _m4storage[3] * _m4storage[4];
×
1092
    final det2_01_12 =
1093
        _m4storage[1] * _m4storage[6] - _m4storage[2] * _m4storage[5];
×
1094
    final det2_01_13 =
1095
        _m4storage[1] * _m4storage[7] - _m4storage[3] * _m4storage[5];
×
1096
    final det2_01_23 =
1097
        _m4storage[2] * _m4storage[7] - _m4storage[3] * _m4storage[6];
×
1098
    final det3_201_012 = _m4storage[8] * det2_01_12 -
×
1099
        _m4storage[9] * det2_01_02 +
×
1100
        _m4storage[10] * det2_01_01;
×
1101
    final det3_201_013 = _m4storage[8] * det2_01_13 -
×
1102
        _m4storage[9] * det2_01_03 +
×
1103
        _m4storage[11] * det2_01_01;
×
1104
    final det3_201_023 = _m4storage[8] * det2_01_23 -
×
1105
        _m4storage[10] * det2_01_03 +
×
1106
        _m4storage[11] * det2_01_02;
×
1107
    final det3_201_123 = _m4storage[9] * det2_01_23 -
×
1108
        _m4storage[10] * det2_01_13 +
×
1109
        _m4storage[11] * det2_01_12;
×
1110
    return -det3_201_123 * _m4storage[12] +
×
1111
        det3_201_023 * _m4storage[13] -
×
1112
        det3_201_013 * _m4storage[14] +
×
1113
        det3_201_012 * _m4storage[15];
×
1114
  }
1115

1116
  /// Returns the dot product of row [i] and [v].
1117
  double dotRow(int i, Vector4 v) {
×
1118
    final vStorage = v._v4storage;
×
1119
    return _m4storage[i] * vStorage[0] +
×
1120
        _m4storage[4 + i] * vStorage[1] +
×
1121
        _m4storage[8 + i] * vStorage[2] +
×
1122
        _m4storage[12 + i] * vStorage[3];
×
1123
  }
1124

1125
  /// Returns the dot product of column [j] and [v].
1126
  double dotColumn(int j, Vector4 v) {
×
1127
    final vStorage = v._v4storage;
×
1128
    return _m4storage[j * 4] * vStorage[0] +
×
1129
        _m4storage[j * 4 + 1] * vStorage[1] +
×
1130
        _m4storage[j * 4 + 2] * vStorage[2] +
×
1131
        _m4storage[j * 4 + 3] * vStorage[3];
×
1132
  }
1133

1134
  /// Returns the trace of the matrix. The trace of a matrix is the sum of the
1135
  /// diagonal entries.
1136
  double trace() {
×
1137
    var t = 0.0;
1138
    t += _m4storage[0];
×
1139
    t += _m4storage[5];
×
1140
    t += _m4storage[10];
×
1141
    t += _m4storage[15];
×
1142
    return t;
1143
  }
1144

1145
  /// Returns infinity norm of the matrix. Used for numerical analysis.
1146
  double infinityNorm() {
×
1147
    var norm = 0.0;
1148
    {
1149
      var row_norm = 0.0;
1150
      row_norm += _m4storage[0].abs();
×
1151
      row_norm += _m4storage[1].abs();
×
1152
      row_norm += _m4storage[2].abs();
×
1153
      row_norm += _m4storage[3].abs();
×
1154
      norm = row_norm > norm ? row_norm : norm;
×
1155
    }
1156
    {
1157
      var row_norm = 0.0;
1158
      row_norm += _m4storage[4].abs();
×
1159
      row_norm += _m4storage[5].abs();
×
1160
      row_norm += _m4storage[6].abs();
×
1161
      row_norm += _m4storage[7].abs();
×
1162
      norm = row_norm > norm ? row_norm : norm;
×
1163
    }
1164
    {
1165
      var row_norm = 0.0;
1166
      row_norm += _m4storage[8].abs();
×
1167
      row_norm += _m4storage[9].abs();
×
1168
      row_norm += _m4storage[10].abs();
×
1169
      row_norm += _m4storage[11].abs();
×
1170
      norm = row_norm > norm ? row_norm : norm;
×
1171
    }
1172
    {
1173
      var row_norm = 0.0;
1174
      row_norm += _m4storage[12].abs();
×
1175
      row_norm += _m4storage[13].abs();
×
1176
      row_norm += _m4storage[14].abs();
×
1177
      row_norm += _m4storage[15].abs();
×
1178
      norm = row_norm > norm ? row_norm : norm;
×
1179
    }
1180
    return norm;
1181
  }
1182

1183
  /// Returns relative error between this and [correct]
1184
  double relativeError(Matrix4 correct) {
×
1185
    final diff = correct - this;
×
1186
    final correct_norm = correct.infinityNorm();
×
1187
    final diff_norm = diff.infinityNorm();
×
1188
    return diff_norm / correct_norm;
×
1189
  }
1190

1191
  /// Returns absolute error between this and [correct]
1192
  double absoluteError(Matrix4 correct) {
×
1193
    final this_norm = infinityNorm();
×
1194
    final correct_norm = correct.infinityNorm();
×
1195
    final diff_norm = (this_norm - correct_norm).abs();
×
1196
    return diff_norm;
1197
  }
1198

1199
  /// Returns the translation vector from this homogeneous transformation
1200
  /// matrix.
1201
  Vector3 getTranslation() {
×
1202
    final z = _m4storage[14];
×
1203
    final y = _m4storage[13];
×
1204
    final x = _m4storage[12];
×
1205
    return Vector3(x, y, z);
×
1206
  }
1207

1208
  /// Sets the translation vector in this homogeneous transformation matrix.
1209
  void setTranslation(Vector3 t) {
×
1210
    final tStorage = t._v3storage;
×
1211
    final z = tStorage[2];
×
1212
    final y = tStorage[1];
×
1213
    final x = tStorage[0];
×
1214
    _m4storage[14] = z;
×
1215
    _m4storage[13] = y;
×
1216
    _m4storage[12] = x;
×
1217
  }
1218

1219
  /// Sets the translation vector in this homogeneous transformation matrix.
1220
  void setTranslationRaw(double x, double y, double z) {
×
1221
    _m4storage[14] = z;
×
1222
    _m4storage[13] = y;
×
1223
    _m4storage[12] = x;
×
1224
  }
1225

1226
  /// Returns the rotation matrix from this homogeneous transformation matrix.
1227
  Matrix3 getRotation() {
×
1228
    final r = Matrix3.zero();
×
1229
    copyRotation(r);
×
1230
    return r;
1231
  }
1232

1233
  /// Copies the rotation matrix from this homogeneous transformation matrix
1234
  /// into [rotation].
1235
  void copyRotation(Matrix3 rotation) {
×
1236
    final rStorage = rotation._m3storage;
×
1237
    rStorage[0] = _m4storage[0];
×
1238
    rStorage[1] = _m4storage[1];
×
1239
    rStorage[2] = _m4storage[2];
×
1240
    rStorage[3] = _m4storage[4];
×
1241
    rStorage[4] = _m4storage[5];
×
1242
    rStorage[5] = _m4storage[6];
×
1243
    rStorage[6] = _m4storage[8];
×
1244
    rStorage[7] = _m4storage[9];
×
1245
    rStorage[8] = _m4storage[10];
×
1246
  }
1247

1248
  /// Sets the rotation matrix in this homogeneous transformation matrix.
1249
  void setRotation(Matrix3 r) {
×
1250
    final rStorage = r._m3storage;
×
1251
    _m4storage[0] = rStorage[0];
×
1252
    _m4storage[1] = rStorage[1];
×
1253
    _m4storage[2] = rStorage[2];
×
1254
    _m4storage[4] = rStorage[3];
×
1255
    _m4storage[5] = rStorage[4];
×
1256
    _m4storage[6] = rStorage[5];
×
1257
    _m4storage[8] = rStorage[6];
×
1258
    _m4storage[9] = rStorage[7];
×
1259
    _m4storage[10] = rStorage[8];
×
1260
  }
1261

1262
  /// Returns the normal matrix from this homogeneous transformation matrix.
1263
  ///
1264
  /// The normal matrix is the transpose of the inverse of the top-left 3x3 part
1265
  /// of this 4x4 matrix.
1266
  Matrix3 getNormalMatrix() => Matrix3.identity()..copyNormalMatrix(this);
×
1267

1268
  /// Returns the max scale value of the 3 axes.
1269
  double getMaxScaleOnAxis() {
×
1270
    final scaleXSq = _m4storage[0] * _m4storage[0] +
×
1271
        _m4storage[1] * _m4storage[1] +
×
1272
        _m4storage[2] * _m4storage[2];
×
1273
    final scaleYSq = _m4storage[4] * _m4storage[4] +
×
1274
        _m4storage[5] * _m4storage[5] +
×
1275
        _m4storage[6] * _m4storage[6];
×
1276
    final scaleZSq = _m4storage[8] * _m4storage[8] +
×
1277
        _m4storage[9] * _m4storage[9] +
×
1278
        _m4storage[10] * _m4storage[10];
×
1279
    return math.sqrt(math.max(scaleXSq, math.max(scaleYSq, scaleZSq)));
×
1280
  }
1281

1282
  /// Transposes just the upper 3x3 rotation matrix.
1283
  void transposeRotation() {
×
1284
    double temp;
1285
    temp = _m4storage[1];
×
1286
    _m4storage[1] = _m4storage[4];
×
1287
    _m4storage[4] = temp;
×
1288
    temp = _m4storage[2];
×
1289
    _m4storage[2] = _m4storage[8];
×
1290
    _m4storage[8] = temp;
×
1291
    temp = _m4storage[4];
×
1292
    _m4storage[4] = _m4storage[1];
×
1293
    _m4storage[1] = temp;
×
1294
    temp = _m4storage[6];
×
1295
    _m4storage[6] = _m4storage[9];
×
1296
    _m4storage[9] = temp;
×
1297
    temp = _m4storage[8];
×
1298
    _m4storage[8] = _m4storage[2];
×
1299
    _m4storage[2] = temp;
×
1300
    temp = _m4storage[9];
×
1301
    _m4storage[9] = _m4storage[6];
×
1302
    _m4storage[6] = temp;
×
1303
  }
1304

1305
  /// Invert this.
1306
  double invert() => copyInverse(this);
×
1307

1308
  /// Set this matrix to be the inverse of [arg]
1309
  double copyInverse(Matrix4 arg) {
×
1310
    final argStorage = arg._m4storage;
×
1311
    final a00 = argStorage[0];
×
1312
    final a01 = argStorage[1];
×
1313
    final a02 = argStorage[2];
×
1314
    final a03 = argStorage[3];
×
1315
    final a10 = argStorage[4];
×
1316
    final a11 = argStorage[5];
×
1317
    final a12 = argStorage[6];
×
1318
    final a13 = argStorage[7];
×
1319
    final a20 = argStorage[8];
×
1320
    final a21 = argStorage[9];
×
1321
    final a22 = argStorage[10];
×
1322
    final a23 = argStorage[11];
×
1323
    final a30 = argStorage[12];
×
1324
    final a31 = argStorage[13];
×
1325
    final a32 = argStorage[14];
×
1326
    final a33 = argStorage[15];
×
1327
    final b00 = a00 * a11 - a01 * a10;
×
1328
    final b01 = a00 * a12 - a02 * a10;
×
1329
    final b02 = a00 * a13 - a03 * a10;
×
1330
    final b03 = a01 * a12 - a02 * a11;
×
1331
    final b04 = a01 * a13 - a03 * a11;
×
1332
    final b05 = a02 * a13 - a03 * a12;
×
1333
    final b06 = a20 * a31 - a21 * a30;
×
1334
    final b07 = a20 * a32 - a22 * a30;
×
1335
    final b08 = a20 * a33 - a23 * a30;
×
1336
    final b09 = a21 * a32 - a22 * a31;
×
1337
    final b10 = a21 * a33 - a23 * a31;
×
1338
    final b11 = a22 * a33 - a23 * a32;
×
1339
    final det =
1340
        b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
×
1341
    if (det == 0.0) {
×
1342
      setFrom(arg);
×
1343
      return 0.0;
1344
    }
1345
    final invDet = 1.0 / det;
×
1346
    _m4storage[0] = (a11 * b11 - a12 * b10 + a13 * b09) * invDet;
×
1347
    _m4storage[1] = (-a01 * b11 + a02 * b10 - a03 * b09) * invDet;
×
1348
    _m4storage[2] = (a31 * b05 - a32 * b04 + a33 * b03) * invDet;
×
1349
    _m4storage[3] = (-a21 * b05 + a22 * b04 - a23 * b03) * invDet;
×
1350
    _m4storage[4] = (-a10 * b11 + a12 * b08 - a13 * b07) * invDet;
×
1351
    _m4storage[5] = (a00 * b11 - a02 * b08 + a03 * b07) * invDet;
×
1352
    _m4storage[6] = (-a30 * b05 + a32 * b02 - a33 * b01) * invDet;
×
1353
    _m4storage[7] = (a20 * b05 - a22 * b02 + a23 * b01) * invDet;
×
1354
    _m4storage[8] = (a10 * b10 - a11 * b08 + a13 * b06) * invDet;
×
1355
    _m4storage[9] = (-a00 * b10 + a01 * b08 - a03 * b06) * invDet;
×
1356
    _m4storage[10] = (a30 * b04 - a31 * b02 + a33 * b00) * invDet;
×
1357
    _m4storage[11] = (-a20 * b04 + a21 * b02 - a23 * b00) * invDet;
×
1358
    _m4storage[12] = (-a10 * b09 + a11 * b07 - a12 * b06) * invDet;
×
1359
    _m4storage[13] = (a00 * b09 - a01 * b07 + a02 * b06) * invDet;
×
1360
    _m4storage[14] = (-a30 * b03 + a31 * b01 - a32 * b00) * invDet;
×
1361
    _m4storage[15] = (a20 * b03 - a21 * b01 + a22 * b00) * invDet;
×
1362
    return det;
1363
  }
1364

1365
  double invertRotation() {
×
1366
    final det = determinant();
×
1367
    if (det == 0.0) {
×
1368
      return 0.0;
1369
    }
1370
    final invDet = 1.0 / det;
×
1371
    double ix;
1372
    double iy;
1373
    double iz;
1374
    double jx;
1375
    double jy;
1376
    double jz;
1377
    double kx;
1378
    double ky;
1379
    double kz;
1380
    ix = invDet *
×
1381
        (_m4storage[5] * _m4storage[10] - _m4storage[6] * _m4storage[9]);
×
1382
    iy = invDet *
×
1383
        (_m4storage[2] * _m4storage[9] - _m4storage[1] * _m4storage[10]);
×
1384
    iz = invDet *
×
1385
        (_m4storage[1] * _m4storage[6] - _m4storage[2] * _m4storage[5]);
×
1386
    jx = invDet *
×
1387
        (_m4storage[6] * _m4storage[8] - _m4storage[4] * _m4storage[10]);
×
1388
    jy = invDet *
×
1389
        (_m4storage[0] * _m4storage[10] - _m4storage[2] * _m4storage[8]);
×
1390
    jz = invDet *
×
1391
        (_m4storage[2] * _m4storage[4] - _m4storage[0] * _m4storage[6]);
×
1392
    kx = invDet *
×
1393
        (_m4storage[4] * _m4storage[9] - _m4storage[5] * _m4storage[8]);
×
1394
    ky = invDet *
×
1395
        (_m4storage[1] * _m4storage[8] - _m4storage[0] * _m4storage[9]);
×
1396
    kz = invDet *
×
1397
        (_m4storage[0] * _m4storage[5] - _m4storage[1] * _m4storage[4]);
×
1398
    _m4storage[0] = ix;
×
1399
    _m4storage[1] = iy;
×
1400
    _m4storage[2] = iz;
×
1401
    _m4storage[4] = jx;
×
1402
    _m4storage[5] = jy;
×
1403
    _m4storage[6] = jz;
×
1404
    _m4storage[8] = kx;
×
1405
    _m4storage[9] = ky;
×
1406
    _m4storage[10] = kz;
×
1407
    return det;
1408
  }
1409

1410
  /// Sets the upper 3x3 to a rotation of [radians] around X
1411
  void setRotationX(double radians) {
×
1412
    final c = math.cos(radians);
×
1413
    final s = math.sin(radians);
×
1414
    _m4storage[0] = 1.0;
×
1415
    _m4storage[1] = 0.0;
×
1416
    _m4storage[2] = 0.0;
×
1417
    _m4storage[4] = 0.0;
×
1418
    _m4storage[5] = c;
×
1419
    _m4storage[6] = s;
×
1420
    _m4storage[8] = 0.0;
×
1421
    _m4storage[9] = -s;
×
1422
    _m4storage[10] = c;
×
1423
    _m4storage[3] = 0.0;
×
1424
    _m4storage[7] = 0.0;
×
1425
    _m4storage[11] = 0.0;
×
1426
  }
1427

1428
  /// Sets the upper 3x3 to a rotation of [radians] around Y
1429
  void setRotationY(double radians) {
×
1430
    final c = math.cos(radians);
×
1431
    final s = math.sin(radians);
×
1432
    _m4storage[0] = c;
×
1433
    _m4storage[1] = 0.0;
×
1434
    _m4storage[2] = -s;
×
1435
    _m4storage[4] = 0.0;
×
1436
    _m4storage[5] = 1.0;
×
1437
    _m4storage[6] = 0.0;
×
1438
    _m4storage[8] = s;
×
1439
    _m4storage[9] = 0.0;
×
1440
    _m4storage[10] = c;
×
1441
    _m4storage[3] = 0.0;
×
1442
    _m4storage[7] = 0.0;
×
1443
    _m4storage[11] = 0.0;
×
1444
  }
1445

1446
  /// Sets the upper 3x3 to a rotation of [radians] around Z
1447
  void setRotationZ(double radians) {
×
1448
    final c = math.cos(radians);
×
1449
    final s = math.sin(radians);
×
1450
    _m4storage[0] = c;
×
1451
    _m4storage[1] = s;
×
1452
    _m4storage[2] = 0.0;
×
1453
    _m4storage[4] = -s;
×
1454
    _m4storage[5] = c;
×
1455
    _m4storage[6] = 0.0;
×
1456
    _m4storage[8] = 0.0;
×
1457
    _m4storage[9] = 0.0;
×
1458
    _m4storage[10] = 1.0;
×
1459
    _m4storage[3] = 0.0;
×
1460
    _m4storage[7] = 0.0;
×
1461
    _m4storage[11] = 0.0;
×
1462
  }
1463

1464
  /// Converts into Adjugate matrix and scales by [scale]
1465
  void scaleAdjoint(double scale) {
×
1466
    // Adapted from code by Richard Carling.
1467
    final a1 = _m4storage[0];
×
1468
    final b1 = _m4storage[4];
×
1469
    final c1 = _m4storage[8];
×
1470
    final d1 = _m4storage[12];
×
1471
    final a2 = _m4storage[1];
×
1472
    final b2 = _m4storage[5];
×
1473
    final c2 = _m4storage[9];
×
1474
    final d2 = _m4storage[13];
×
1475
    final a3 = _m4storage[2];
×
1476
    final b3 = _m4storage[6];
×
1477
    final c3 = _m4storage[10];
×
1478
    final d3 = _m4storage[14];
×
1479
    final a4 = _m4storage[3];
×
1480
    final b4 = _m4storage[7];
×
1481
    final c4 = _m4storage[11];
×
1482
    final d4 = _m4storage[15];
×
1483
    _m4storage[0] = (b2 * (c3 * d4 - c4 * d3) -
×
1484
            c2 * (b3 * d4 - b4 * d3) +
×
1485
            d2 * (b3 * c4 - b4 * c3)) *
×
1486
        scale;
1487
    _m4storage[1] = -(a2 * (c3 * d4 - c4 * d3) -
×
1488
            c2 * (a3 * d4 - a4 * d3) +
×
1489
            d2 * (a3 * c4 - a4 * c3)) *
×
1490
        scale;
1491
    _m4storage[2] = (a2 * (b3 * d4 - b4 * d3) -
×
1492
            b2 * (a3 * d4 - a4 * d3) +
×
1493
            d2 * (a3 * b4 - a4 * b3)) *
×
1494
        scale;
1495
    _m4storage[3] = -(a2 * (b3 * c4 - b4 * c3) -
×
1496
            b2 * (a3 * c4 - a4 * c3) +
×
1497
            c2 * (a3 * b4 - a4 * b3)) *
×
1498
        scale;
1499
    _m4storage[4] = -(b1 * (c3 * d4 - c4 * d3) -
×
1500
            c1 * (b3 * d4 - b4 * d3) +
×
1501
            d1 * (b3 * c4 - b4 * c3)) *
×
1502
        scale;
1503
    _m4storage[5] = (a1 * (c3 * d4 - c4 * d3) -
×
1504
            c1 * (a3 * d4 - a4 * d3) +
×
1505
            d1 * (a3 * c4 - a4 * c3)) *
×
1506
        scale;
1507
    _m4storage[6] = -(a1 * (b3 * d4 - b4 * d3) -
×
1508
            b1 * (a3 * d4 - a4 * d3) +
×
1509
            d1 * (a3 * b4 - a4 * b3)) *
×
1510
        scale;
1511
    _m4storage[7] = (a1 * (b3 * c4 - b4 * c3) -
×
1512
            b1 * (a3 * c4 - a4 * c3) +
×
1513
            c1 * (a3 * b4 - a4 * b3)) *
×
1514
        scale;
1515
    _m4storage[8] = (b1 * (c2 * d4 - c4 * d2) -
×
1516
            c1 * (b2 * d4 - b4 * d2) +
×
1517
            d1 * (b2 * c4 - b4 * c2)) *
×
1518
        scale;
1519
    _m4storage[9] = -(a1 * (c2 * d4 - c4 * d2) -
×
1520
            c1 * (a2 * d4 - a4 * d2) +
×
1521
            d1 * (a2 * c4 - a4 * c2)) *
×
1522
        scale;
1523
    _m4storage[10] = (a1 * (b2 * d4 - b4 * d2) -
×
1524
            b1 * (a2 * d4 - a4 * d2) +
×
1525
            d1 * (a2 * b4 - a4 * b2)) *
×
1526
        scale;
1527
    _m4storage[11] = -(a1 * (b2 * c4 - b4 * c2) -
×
1528
            b1 * (a2 * c4 - a4 * c2) +
×
1529
            c1 * (a2 * b4 - a4 * b2)) *
×
1530
        scale;
1531
    _m4storage[12] = -(b1 * (c2 * d3 - c3 * d2) -
×
1532
            c1 * (b2 * d3 - b3 * d2) +
×
1533
            d1 * (b2 * c3 - b3 * c2)) *
×
1534
        scale;
1535
    _m4storage[13] = (a1 * (c2 * d3 - c3 * d2) -
×
1536
            c1 * (a2 * d3 - a3 * d2) +
×
1537
            d1 * (a2 * c3 - a3 * c2)) *
×
1538
        scale;
1539
    _m4storage[14] = -(a1 * (b2 * d3 - b3 * d2) -
×
1540
            b1 * (a2 * d3 - a3 * d2) +
×
1541
            d1 * (a2 * b3 - a3 * b2)) *
×
1542
        scale;
1543
    _m4storage[15] = (a1 * (b2 * c3 - b3 * c2) -
×
1544
            b1 * (a2 * c3 - a3 * c2) +
×
1545
            c1 * (a2 * b3 - a3 * b2)) *
×
1546
        scale;
1547
  }
1548

1549
  /// Rotates [arg] by the absolute rotation of this
1550
  /// Returns [arg].
1551
  /// Primarily used by AABB transformation code.
1552
  Vector3 absoluteRotate(Vector3 arg) {
×
1553
    final m00 = _m4storage[0].abs();
×
1554
    final m01 = _m4storage[4].abs();
×
1555
    final m02 = _m4storage[8].abs();
×
1556
    final m10 = _m4storage[1].abs();
×
1557
    final m11 = _m4storage[5].abs();
×
1558
    final m12 = _m4storage[9].abs();
×
1559
    final m20 = _m4storage[2].abs();
×
1560
    final m21 = _m4storage[6].abs();
×
1561
    final m22 = _m4storage[10].abs();
×
1562
    final argStorage = arg._v3storage;
×
1563
    final x = argStorage[0];
×
1564
    final y = argStorage[1];
×
1565
    final z = argStorage[2];
×
1566
    argStorage[0] = x * m00 + y * m01 + z * m02 + 0.0 * 0.0;
×
1567
    argStorage[1] = x * m10 + y * m11 + z * m12 + 0.0 * 0.0;
×
1568
    argStorage[2] = x * m20 + y * m21 + z * m22 + 0.0 * 0.0;
×
1569
    return arg;
1570
  }
1571

1572
  /// Adds [o] to this.
1573
  void add(Matrix4 o) {
×
1574
    final oStorage = o._m4storage;
×
1575
    _m4storage[0] = _m4storage[0] + oStorage[0];
×
1576
    _m4storage[1] = _m4storage[1] + oStorage[1];
×
1577
    _m4storage[2] = _m4storage[2] + oStorage[2];
×
1578
    _m4storage[3] = _m4storage[3] + oStorage[3];
×
1579
    _m4storage[4] = _m4storage[4] + oStorage[4];
×
1580
    _m4storage[5] = _m4storage[5] + oStorage[5];
×
1581
    _m4storage[6] = _m4storage[6] + oStorage[6];
×
1582
    _m4storage[7] = _m4storage[7] + oStorage[7];
×
1583
    _m4storage[8] = _m4storage[8] + oStorage[8];
×
1584
    _m4storage[9] = _m4storage[9] + oStorage[9];
×
1585
    _m4storage[10] = _m4storage[10] + oStorage[10];
×
1586
    _m4storage[11] = _m4storage[11] + oStorage[11];
×
1587
    _m4storage[12] = _m4storage[12] + oStorage[12];
×
1588
    _m4storage[13] = _m4storage[13] + oStorage[13];
×
1589
    _m4storage[14] = _m4storage[14] + oStorage[14];
×
1590
    _m4storage[15] = _m4storage[15] + oStorage[15];
×
1591
  }
1592

1593
  /// Subtracts [o] from this.
1594
  void sub(Matrix4 o) {
×
1595
    final oStorage = o._m4storage;
×
1596
    _m4storage[0] = _m4storage[0] - oStorage[0];
×
1597
    _m4storage[1] = _m4storage[1] - oStorage[1];
×
1598
    _m4storage[2] = _m4storage[2] - oStorage[2];
×
1599
    _m4storage[3] = _m4storage[3] - oStorage[3];
×
1600
    _m4storage[4] = _m4storage[4] - oStorage[4];
×
1601
    _m4storage[5] = _m4storage[5] - oStorage[5];
×
1602
    _m4storage[6] = _m4storage[6] - oStorage[6];
×
1603
    _m4storage[7] = _m4storage[7] - oStorage[7];
×
1604
    _m4storage[8] = _m4storage[8] - oStorage[8];
×
1605
    _m4storage[9] = _m4storage[9] - oStorage[9];
×
1606
    _m4storage[10] = _m4storage[10] - oStorage[10];
×
1607
    _m4storage[11] = _m4storage[11] - oStorage[11];
×
1608
    _m4storage[12] = _m4storage[12] - oStorage[12];
×
1609
    _m4storage[13] = _m4storage[13] - oStorage[13];
×
1610
    _m4storage[14] = _m4storage[14] - oStorage[14];
×
1611
    _m4storage[15] = _m4storage[15] - oStorage[15];
×
1612
  }
1613

1614
  /// Negate this.
1615
  void negate() {
×
1616
    _m4storage[0] = -_m4storage[0];
×
1617
    _m4storage[1] = -_m4storage[1];
×
1618
    _m4storage[2] = -_m4storage[2];
×
1619
    _m4storage[3] = -_m4storage[3];
×
1620
    _m4storage[4] = -_m4storage[4];
×
1621
    _m4storage[5] = -_m4storage[5];
×
1622
    _m4storage[6] = -_m4storage[6];
×
1623
    _m4storage[7] = -_m4storage[7];
×
1624
    _m4storage[8] = -_m4storage[8];
×
1625
    _m4storage[9] = -_m4storage[9];
×
1626
    _m4storage[10] = -_m4storage[10];
×
1627
    _m4storage[11] = -_m4storage[11];
×
1628
    _m4storage[12] = -_m4storage[12];
×
1629
    _m4storage[13] = -_m4storage[13];
×
1630
    _m4storage[14] = -_m4storage[14];
×
1631
    _m4storage[15] = -_m4storage[15];
×
1632
  }
1633

1634
  /// Multiply this by [arg].
1635
  void multiply(Matrix4 arg) {
×
1636
    final m00 = _m4storage[0];
×
1637
    final m01 = _m4storage[4];
×
1638
    final m02 = _m4storage[8];
×
1639
    final m03 = _m4storage[12];
×
1640
    final m10 = _m4storage[1];
×
1641
    final m11 = _m4storage[5];
×
1642
    final m12 = _m4storage[9];
×
1643
    final m13 = _m4storage[13];
×
1644
    final m20 = _m4storage[2];
×
1645
    final m21 = _m4storage[6];
×
1646
    final m22 = _m4storage[10];
×
1647
    final m23 = _m4storage[14];
×
1648
    final m30 = _m4storage[3];
×
1649
    final m31 = _m4storage[7];
×
1650
    final m32 = _m4storage[11];
×
1651
    final m33 = _m4storage[15];
×
1652
    final argStorage = arg._m4storage;
×
1653
    final n00 = argStorage[0];
×
1654
    final n01 = argStorage[4];
×
1655
    final n02 = argStorage[8];
×
1656
    final n03 = argStorage[12];
×
1657
    final n10 = argStorage[1];
×
1658
    final n11 = argStorage[5];
×
1659
    final n12 = argStorage[9];
×
1660
    final n13 = argStorage[13];
×
1661
    final n20 = argStorage[2];
×
1662
    final n21 = argStorage[6];
×
1663
    final n22 = argStorage[10];
×
1664
    final n23 = argStorage[14];
×
1665
    final n30 = argStorage[3];
×
1666
    final n31 = argStorage[7];
×
1667
    final n32 = argStorage[11];
×
1668
    final n33 = argStorage[15];
×
1669
    _m4storage[0] = (m00 * n00) + (m01 * n10) + (m02 * n20) + (m03 * n30);
×
1670
    _m4storage[4] = (m00 * n01) + (m01 * n11) + (m02 * n21) + (m03 * n31);
×
1671
    _m4storage[8] = (m00 * n02) + (m01 * n12) + (m02 * n22) + (m03 * n32);
×
1672
    _m4storage[12] = (m00 * n03) + (m01 * n13) + (m02 * n23) + (m03 * n33);
×
1673
    _m4storage[1] = (m10 * n00) + (m11 * n10) + (m12 * n20) + (m13 * n30);
×
1674
    _m4storage[5] = (m10 * n01) + (m11 * n11) + (m12 * n21) + (m13 * n31);
×
1675
    _m4storage[9] = (m10 * n02) + (m11 * n12) + (m12 * n22) + (m13 * n32);
×
1676
    _m4storage[13] = (m10 * n03) + (m11 * n13) + (m12 * n23) + (m13 * n33);
×
1677
    _m4storage[2] = (m20 * n00) + (m21 * n10) + (m22 * n20) + (m23 * n30);
×
1678
    _m4storage[6] = (m20 * n01) + (m21 * n11) + (m22 * n21) + (m23 * n31);
×
1679
    _m4storage[10] = (m20 * n02) + (m21 * n12) + (m22 * n22) + (m23 * n32);
×
1680
    _m4storage[14] = (m20 * n03) + (m21 * n13) + (m22 * n23) + (m23 * n33);
×
1681
    _m4storage[3] = (m30 * n00) + (m31 * n10) + (m32 * n20) + (m33 * n30);
×
1682
    _m4storage[7] = (m30 * n01) + (m31 * n11) + (m32 * n21) + (m33 * n31);
×
1683
    _m4storage[11] = (m30 * n02) + (m31 * n12) + (m32 * n22) + (m33 * n32);
×
1684
    _m4storage[15] = (m30 * n03) + (m31 * n13) + (m32 * n23) + (m33 * n33);
×
1685
  }
1686

1687
  /// Multiply a copy of this with [arg].
1688
  Matrix4 multiplied(Matrix4 arg) => clone()..multiply(arg);
×
1689

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

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

1860
  /// Decomposes this into [translation], [rotation] and [scale] components.
1861
  void decompose(Vector3 translation, Quaternion rotation, Vector3 scale) {
×
1862
    final v = _decomposeV ??= Vector3.zero();
×
1863
    var sx = (v..setValues(_m4storage[0], _m4storage[1], _m4storage[2])).length;
×
1864
    final sy =
1865
        (v..setValues(_m4storage[4], _m4storage[5], _m4storage[6])).length;
×
1866
    final sz =
1867
        (v..setValues(_m4storage[8], _m4storage[9], _m4storage[10])).length;
×
1868

1869
    if (determinant() < 0) {
×
1870
      sx = -sx;
×
1871
    }
1872

1873
    translation._v3storage[0] = _m4storage[12];
×
1874
    translation._v3storage[1] = _m4storage[13];
×
1875
    translation._v3storage[2] = _m4storage[14];
×
1876

1877
    final invSX = 1.0 / sx;
×
1878
    final invSY = 1.0 / sy;
×
1879
    final invSZ = 1.0 / sz;
×
1880

1881
    final m = _decomposeM ??= Matrix4.zero();
×
1882
    m.setFrom(this);
×
1883
    m._m4storage[0] *= invSX;
×
1884
    m._m4storage[1] *= invSX;
×
1885
    m._m4storage[2] *= invSX;
×
1886
    m._m4storage[4] *= invSY;
×
1887
    m._m4storage[5] *= invSY;
×
1888
    m._m4storage[6] *= invSY;
×
1889
    m._m4storage[8] *= invSZ;
×
1890
    m._m4storage[9] *= invSZ;
×
1891
    m._m4storage[10] *= invSZ;
×
1892

1893
    final r = _decomposeR ??= Matrix3.zero();
×
1894
    m.copyRotation(r);
×
1895
    rotation.setFromRotation(r);
×
1896

1897
    scale._v3storage[0] = sx;
×
1898
    scale._v3storage[1] = sy;
×
1899
    scale._v3storage[2] = sz;
×
1900
  }
1901

1902
  static Vector3? _decomposeV;
1903
  static Matrix4? _decomposeM;
1904
  static Matrix3? _decomposeR;
1905

1906
  /// Rotate [arg] of type [Vector3] using the rotation defined by this.
1907
  Vector3 rotate3(Vector3 arg) {
×
1908
    final argStorage = arg._v3storage;
×
1909
    final x_ = (_m4storage[0] * argStorage[0]) +
×
1910
        (_m4storage[4] * argStorage[1]) +
×
1911
        (_m4storage[8] * argStorage[2]);
×
1912
    final y_ = (_m4storage[1] * argStorage[0]) +
×
1913
        (_m4storage[5] * argStorage[1]) +
×
1914
        (_m4storage[9] * argStorage[2]);
×
1915
    final z_ = (_m4storage[2] * argStorage[0]) +
×
1916
        (_m4storage[6] * argStorage[1]) +
×
1917
        (_m4storage[10] * argStorage[2]);
×
1918
    argStorage[0] = x_;
×
1919
    argStorage[1] = y_;
×
1920
    argStorage[2] = z_;
×
1921
    return arg;
1922
  }
1923

1924
  /// Rotate a copy of [arg] of type [Vector3] using the rotation defined by
1925
  /// this. If a [out] parameter is supplied, the copy is stored in [out].
1926
  Vector3 rotated3(Vector3 arg, [Vector3? out]) {
×
1927
    if (out == null) {
1928
      out = Vector3.copy(arg);
×
1929
    } else {
1930
      out.setFrom(arg);
×
1931
    }
1932
    return rotate3(out);
×
1933
  }
1934

1935
  /// Transform [arg] of type [Vector3] using the transformation defined by
1936
  /// this.
1937
  Vector3 transform3(Vector3 arg) {
×
1938
    final argStorage = arg._v3storage;
×
1939
    final x_ = (_m4storage[0] * argStorage[0]) +
×
1940
        (_m4storage[4] * argStorage[1]) +
×
1941
        (_m4storage[8] * argStorage[2]) +
×
1942
        _m4storage[12];
×
1943
    final y_ = (_m4storage[1] * argStorage[0]) +
×
1944
        (_m4storage[5] * argStorage[1]) +
×
1945
        (_m4storage[9] * argStorage[2]) +
×
1946
        _m4storage[13];
×
1947
    final z_ = (_m4storage[2] * argStorage[0]) +
×
1948
        (_m4storage[6] * argStorage[1]) +
×
1949
        (_m4storage[10] * argStorage[2]) +
×
1950
        _m4storage[14];
×
1951
    argStorage[0] = x_;
×
1952
    argStorage[1] = y_;
×
1953
    argStorage[2] = z_;
×
1954
    return arg;
1955
  }
1956

1957
  /// Transform a copy of [arg] of type [Vector3] using the transformation
1958
  /// defined by this. If a [out] parameter is supplied, the copy is stored in
1959
  /// [out].
1960
  Vector3 transformed3(Vector3 arg, [Vector3? out]) {
×
1961
    if (out == null) {
1962
      out = Vector3.copy(arg);
×
1963
    } else {
1964
      out.setFrom(arg);
×
1965
    }
1966
    return transform3(out);
×
1967
  }
1968

1969
  /// Transform [arg] of type [Vector4] using the transformation defined by
1970
  /// this.
1971
  Vector4 transform(Vector4 arg) {
×
1972
    final argStorage = arg._v4storage;
×
1973
    final x_ = (_m4storage[0] * argStorage[0]) +
×
1974
        (_m4storage[4] * argStorage[1]) +
×
1975
        (_m4storage[8] * argStorage[2]) +
×
1976
        (_m4storage[12] * argStorage[3]);
×
1977
    final y_ = (_m4storage[1] * argStorage[0]) +
×
1978
        (_m4storage[5] * argStorage[1]) +
×
1979
        (_m4storage[9] * argStorage[2]) +
×
1980
        (_m4storage[13] * argStorage[3]);
×
1981
    final z_ = (_m4storage[2] * argStorage[0]) +
×
1982
        (_m4storage[6] * argStorage[1]) +
×
1983
        (_m4storage[10] * argStorage[2]) +
×
1984
        (_m4storage[14] * argStorage[3]);
×
1985
    final w_ = (_m4storage[3] * argStorage[0]) +
×
1986
        (_m4storage[7] * argStorage[1]) +
×
1987
        (_m4storage[11] * argStorage[2]) +
×
1988
        (_m4storage[15] * argStorage[3]);
×
1989
    argStorage[0] = x_;
×
1990
    argStorage[1] = y_;
×
1991
    argStorage[2] = z_;
×
1992
    argStorage[3] = w_;
×
1993
    return arg;
1994
  }
1995

1996
  /// Transform [arg] of type [Vector3] using the perspective transformation
1997
  /// defined by this.
1998
  Vector3 perspectiveTransform(Vector3 arg) {
×
1999
    final argStorage = arg._v3storage;
×
2000
    final x_ = (_m4storage[0] * argStorage[0]) +
×
2001
        (_m4storage[4] * argStorage[1]) +
×
2002
        (_m4storage[8] * argStorage[2]) +
×
2003
        _m4storage[12];
×
2004
    final y_ = (_m4storage[1] * argStorage[0]) +
×
2005
        (_m4storage[5] * argStorage[1]) +
×
2006
        (_m4storage[9] * argStorage[2]) +
×
2007
        _m4storage[13];
×
2008
    final z_ = (_m4storage[2] * argStorage[0]) +
×
2009
        (_m4storage[6] * argStorage[1]) +
×
2010
        (_m4storage[10] * argStorage[2]) +
×
2011
        _m4storage[14];
×
2012
    final w_ = 1.0 /
×
2013
        ((_m4storage[3] * argStorage[0]) +
×
2014
            (_m4storage[7] * argStorage[1]) +
×
2015
            (_m4storage[11] * argStorage[2]) +
×
2016
            _m4storage[15]);
×
2017
    argStorage[0] = x_ * w_;
×
2018
    argStorage[1] = y_ * w_;
×
2019
    argStorage[2] = z_ * w_;
×
2020
    return arg;
2021
  }
2022

2023
  /// Transform a copy of [arg] of type [Vector4] using the transformation
2024
  /// defined by this. If a [out] parameter is supplied, the copy is stored in
2025
  /// [out].
2026
  Vector4 transformed(Vector4 arg, [Vector4? out]) {
×
2027
    if (out == null) {
2028
      out = Vector4.copy(arg);
×
2029
    } else {
2030
      out.setFrom(arg);
×
2031
    }
2032
    return transform(out);
×
2033
  }
2034

2035
  /// Copies this into [array] starting at [offset].
2036
  void copyIntoArray(List<num> array, [int offset = 0]) {
×
2037
    final i = offset;
2038
    array[i + 15] = _m4storage[15];
×
2039
    array[i + 14] = _m4storage[14];
×
2040
    array[i + 13] = _m4storage[13];
×
2041
    array[i + 12] = _m4storage[12];
×
2042
    array[i + 11] = _m4storage[11];
×
2043
    array[i + 10] = _m4storage[10];
×
2044
    array[i + 9] = _m4storage[9];
×
2045
    array[i + 8] = _m4storage[8];
×
2046
    array[i + 7] = _m4storage[7];
×
2047
    array[i + 6] = _m4storage[6];
×
2048
    array[i + 5] = _m4storage[5];
×
2049
    array[i + 4] = _m4storage[4];
×
2050
    array[i + 3] = _m4storage[3];
×
2051
    array[i + 2] = _m4storage[2];
×
2052
    array[i + 1] = _m4storage[1];
×
2053
    array[i + 0] = _m4storage[0];
×
2054
  }
2055

2056
  /// Copies elements from [array] into this starting at [offset].
2057
  void copyFromArray(List<double> array, [int offset = 0]) {
×
2058
    final i = offset;
2059
    _m4storage[15] = array[i + 15];
×
2060
    _m4storage[14] = array[i + 14];
×
2061
    _m4storage[13] = array[i + 13];
×
2062
    _m4storage[12] = array[i + 12];
×
2063
    _m4storage[11] = array[i + 11];
×
2064
    _m4storage[10] = array[i + 10];
×
2065
    _m4storage[9] = array[i + 9];
×
2066
    _m4storage[8] = array[i + 8];
×
2067
    _m4storage[7] = array[i + 7];
×
2068
    _m4storage[6] = array[i + 6];
×
2069
    _m4storage[5] = array[i + 5];
×
2070
    _m4storage[4] = array[i + 4];
×
2071
    _m4storage[3] = array[i + 3];
×
2072
    _m4storage[2] = array[i + 2];
×
2073
    _m4storage[1] = array[i + 1];
×
2074
    _m4storage[0] = array[i + 0];
×
2075
  }
2076

2077
  /// Multiply this to each set of xyz values in [array] starting at [offset].
2078
  List<double> applyToVector3Array(List<double> array, [int offset = 0]) {
×
2079
    for (var i = 0, j = offset; i < array.length; i += 3, j += 3) {
×
2080
      final v = Vector3.array(array, j)..applyMatrix4(this);
×
2081
      array[j] = v.storage[0];
×
2082
      array[j + 1] = v.storage[1];
×
2083
      array[j + 2] = v.storage[2];
×
2084
    }
2085

2086
    return array;
2087
  }
2088

2089
  Vector3 get right {
×
2090
    final x = _m4storage[0];
×
2091
    final y = _m4storage[1];
×
2092
    final z = _m4storage[2];
×
2093
    return Vector3(x, y, z);
×
2094
  }
2095

2096
  Vector3 get up {
×
2097
    final x = _m4storage[4];
×
2098
    final y = _m4storage[5];
×
2099
    final z = _m4storage[6];
×
2100
    return Vector3(x, y, z);
×
2101
  }
2102

2103
  Vector3 get forward {
×
2104
    final x = _m4storage[8];
×
2105
    final y = _m4storage[9];
×
2106
    final z = _m4storage[10];
×
2107
    return Vector3(x, y, z);
×
2108
  }
2109

2110
  /// Is this the identity matrix?
2111
  bool isIdentity() =>
×
2112
      _m4storage[0] == 1.0 // col 1
×
2113
      &&
2114
      _m4storage[1] == 0.0 &&
×
2115
      _m4storage[2] == 0.0 &&
×
2116
      _m4storage[3] == 0.0 &&
×
2117
      _m4storage[4] == 0.0 // col 2
×
2118
      &&
2119
      _m4storage[5] == 1.0 &&
×
2120
      _m4storage[6] == 0.0 &&
×
2121
      _m4storage[7] == 0.0 &&
×
2122
      _m4storage[8] == 0.0 // col 3
×
2123
      &&
2124
      _m4storage[9] == 0.0 &&
×
2125
      _m4storage[10] == 1.0 &&
×
2126
      _m4storage[11] == 0.0 &&
×
2127
      _m4storage[12] == 0.0 // col 4
×
2128
      &&
2129
      _m4storage[13] == 0.0 &&
×
2130
      _m4storage[14] == 0.0 &&
×
2131
      _m4storage[15] == 1.0;
×
2132

2133
  /// Is this the zero matrix?
2134
  bool isZero() =>
×
2135
      _m4storage[0] == 0.0 // col 1
×
2136
      &&
2137
      _m4storage[1] == 0.0 &&
×
2138
      _m4storage[2] == 0.0 &&
×
2139
      _m4storage[3] == 0.0 &&
×
2140
      _m4storage[4] == 0.0 // col 2
×
2141
      &&
2142
      _m4storage[5] == 0.0 &&
×
2143
      _m4storage[6] == 0.0 &&
×
2144
      _m4storage[7] == 0.0 &&
×
2145
      _m4storage[8] == 0.0 // col 3
×
2146
      &&
2147
      _m4storage[9] == 0.0 &&
×
2148
      _m4storage[10] == 0.0 &&
×
2149
      _m4storage[11] == 0.0 &&
×
2150
      _m4storage[12] == 0.0 // col 4
×
2151
      &&
2152
      _m4storage[13] == 0.0 &&
×
2153
      _m4storage[14] == 0.0 &&
×
2154
      _m4storage[15] == 0.0;
×
2155
}
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