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

google / vector_math.dart / 14950460281

01 May 2025 03:57PM UTC coverage: 26.388% (+0.02%) from 26.372%
14950460281

push

github

web-flow
Improve performance of functions with dynamic arguments (#345)

* Deprecated functions with dynamic arguments
* Bump version, update changelog

54 of 164 new or added lines in 8 files covered. (32.93%)

5 existing lines in 2 files now uncovered.

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

71.73
/lib/src/vector_math/matrix3.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.dart';
6

7
/// 3D Matrix.
8
/// Values are stored in column major order.
9
class Matrix3 {
10
  final Float32List _m3storage;
11

12
  /// The components of the matrix.
13
  Float32List get storage => _m3storage;
6✔
14

15
  /// Solve [A] * [x] = [b].
16
  static void solve2(Matrix3 A, Vector2 x, Vector2 b) {
1✔
17
    final a11 = A.entry(0, 0);
1✔
18
    final a12 = A.entry(0, 1);
1✔
19
    final a21 = A.entry(1, 0);
1✔
20
    final a22 = A.entry(1, 1);
1✔
21
    final bx = b.x - A.storage[6];
4✔
22
    final by = b.y - A.storage[7];
4✔
23
    var det = a11 * a22 - a12 * a21;
3✔
24

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

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

34
  /// Solve [A] * [x] = [b].
35
  static void solve(Matrix3 A, Vector3 x, Vector3 b) {
1✔
36
    final A0x = A.entry(0, 0);
1✔
37
    final A0y = A.entry(1, 0);
1✔
38
    final A0z = A.entry(2, 0);
1✔
39
    final A1x = A.entry(0, 1);
1✔
40
    final A1y = A.entry(1, 1);
1✔
41
    final A1z = A.entry(2, 1);
1✔
42
    final A2x = A.entry(0, 2);
1✔
43
    final A2y = A.entry(1, 2);
1✔
44
    final A2z = A.entry(2, 2);
1✔
45
    double rx, ry, rz;
46
    double det;
47

48
    // Column1 cross Column 2
49
    rx = A1y * A2z - A1z * A2y;
3✔
50
    ry = A1z * A2x - A1x * A2z;
3✔
51
    rz = A1x * A2y - A1y * A2x;
3✔
52

53
    // A.getColumn(0).dot(x)
54
    det = A0x * rx + A0y * ry + A0z * rz;
5✔
55
    if (det != 0.0) {
1✔
56
      det = 1.0 / det;
1✔
57
    }
58

59
    // b dot [Column1 cross Column 2]
60
    final x_ = det * (b.x * rx + b.y * ry + b.z * rz);
9✔
61

62
    // Column2 cross b
63
    rx = -(A2y * b.z - A2z * b.y);
6✔
64
    ry = -(A2z * b.x - A2x * b.z);
6✔
65
    rz = -(A2x * b.y - A2y * b.x);
6✔
66
    // Column0 dot -[Column2 cross b (Column3)]
67
    final y_ = det * (A0x * rx + A0y * ry + A0z * rz);
6✔
68

69
    // b cross Column 1
70
    rx = -(b.y * A1z - b.z * A1y);
6✔
71
    ry = -(b.z * A1x - b.x * A1z);
6✔
72
    rz = -(b.x * A1y - b.y * A1x);
6✔
73
    // Column0 dot -[b cross Column 1]
74
    final z_ = det * (A0x * rx + A0y * ry + A0z * rz);
6✔
75

76
    x
77
      ..x = x_
1✔
78
      ..y = y_
1✔
79
      ..z = z_;
1✔
80
  }
81

82
  /// Return index in storage for [row], [col] value.
83
  int index(int row, int col) => (col * 3) + row;
12✔
84

85
  /// Value at [row], [col].
86
  double entry(int row, int col) {
2✔
87
    assert((row >= 0) && (row < dimension));
8✔
88
    assert((col >= 0) && (col < dimension));
8✔
89

90
    return _m3storage[index(row, col)];
6✔
91
  }
92

93
  /// Set value at [row], [col] to be [v].
94
  void setEntry(int row, int col, double v) {
2✔
95
    assert((row >= 0) && (row < dimension));
8✔
96
    assert((col >= 0) && (col < dimension));
8✔
97

98
    _m3storage[index(row, col)] = v;
6✔
99
  }
100

101
  /// New matrix with specified values.
102
  factory Matrix3(double arg0, double arg1, double arg2, double arg3,
2✔
103
          double arg4, double arg5, double arg6, double arg7, double arg8) =>
104
      Matrix3.zero()
2✔
105
        ..setValues(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
2✔
106

107
  /// New matrix from [values].
108
  factory Matrix3.fromList(List<double> values) => Matrix3.zero()
2✔
109
    ..setValues(values[0], values[1], values[2], values[3], values[4],
6✔
110
        values[5], values[6], values[7], values[8]);
4✔
111

112
  /// Constructs a new [Matrix3] filled with zeros.
113
  Matrix3.zero() : _m3storage = Float32List(9);
12✔
114

115
  /// Identity matrix.
116
  factory Matrix3.identity() => Matrix3.zero()..setIdentity();
3✔
117

118
  /// Copes values from [other].
119
  factory Matrix3.copy(Matrix3 other) => Matrix3.zero()..setFrom(other);
9✔
120

121
  /// Constructs a new mat3 from columns.
122
  factory Matrix3.columns(Vector3 arg0, Vector3 arg1, Vector3 arg2) =>
1✔
123
      Matrix3.zero()..setColumns(arg0, arg1, arg2);
2✔
124

125
  /// Outer product of [u] and [v].
126
  factory Matrix3.outer(Vector3 u, Vector3 v) => Matrix3.zero()..setOuter(u, v);
×
127

128
  /// Rotation of [radians] around X axis.
129
  factory Matrix3.rotationX(double radians) =>
4✔
130
      Matrix3.zero()..setRotationX(radians);
8✔
131

132
  /// Rotation of [radians] around Y axis.
133
  factory Matrix3.rotationY(double radians) =>
3✔
134
      Matrix3.zero()..setRotationY(radians);
6✔
135

136
  /// Rotation of [radians] around Z axis.
137
  factory Matrix3.rotationZ(double radians) =>
5✔
138
      Matrix3.zero()..setRotationZ(radians);
10✔
139

140
  /// Sets the matrix with specified values.
141
  void setValues(double arg0, double arg1, double arg2, double arg3,
2✔
142
      double arg4, double arg5, double arg6, double arg7, double arg8) {
143
    _m3storage[8] = arg8;
4✔
144
    _m3storage[7] = arg7;
4✔
145
    _m3storage[6] = arg6;
4✔
146
    _m3storage[5] = arg5;
4✔
147
    _m3storage[4] = arg4;
4✔
148
    _m3storage[3] = arg3;
4✔
149
    _m3storage[2] = arg2;
4✔
150
    _m3storage[1] = arg1;
4✔
151
    _m3storage[0] = arg0;
4✔
152
  }
153

154
  /// Sets the entire matrix to the column values.
155
  void setColumns(Vector3 arg0, Vector3 arg1, Vector3 arg2) {
1✔
156
    final arg0Storage = arg0._v3storage;
1✔
157
    final arg1Storage = arg1._v3storage;
1✔
158
    final arg2Storage = arg2._v3storage;
1✔
159
    _m3storage[0] = arg0Storage[0];
3✔
160
    _m3storage[1] = arg0Storage[1];
3✔
161
    _m3storage[2] = arg0Storage[2];
3✔
162
    _m3storage[3] = arg1Storage[0];
3✔
163
    _m3storage[4] = arg1Storage[1];
3✔
164
    _m3storage[5] = arg1Storage[2];
3✔
165
    _m3storage[6] = arg2Storage[0];
3✔
166
    _m3storage[7] = arg2Storage[1];
3✔
167
    _m3storage[8] = arg2Storage[2];
3✔
168
  }
169

170
  /// Sets the entire matrix to the matrix in [arg].
171
  void setFrom(Matrix3 arg) {
3✔
172
    final argStorage = arg._m3storage;
3✔
173
    _m3storage[8] = argStorage[8];
9✔
174
    _m3storage[7] = argStorage[7];
9✔
175
    _m3storage[6] = argStorage[6];
9✔
176
    _m3storage[5] = argStorage[5];
9✔
177
    _m3storage[4] = argStorage[4];
9✔
178
    _m3storage[3] = argStorage[3];
9✔
179
    _m3storage[2] = argStorage[2];
9✔
180
    _m3storage[1] = argStorage[1];
9✔
181
    _m3storage[0] = argStorage[0];
9✔
182
  }
183

184
  /// Set this to the outer product of [u] and [v].
185
  void setOuter(Vector3 u, Vector3 v) {
×
186
    final uStorage = u._v3storage;
×
187
    final vStorage = v._v3storage;
×
188
    _m3storage[0] = uStorage[0] * vStorage[0];
×
189
    _m3storage[1] = uStorage[0] * vStorage[1];
×
190
    _m3storage[2] = uStorage[0] * vStorage[2];
×
191
    _m3storage[3] = uStorage[1] * vStorage[0];
×
192
    _m3storage[4] = uStorage[1] * vStorage[1];
×
193
    _m3storage[5] = uStorage[1] * vStorage[2];
×
194
    _m3storage[6] = uStorage[2] * vStorage[0];
×
195
    _m3storage[7] = uStorage[2] * vStorage[1];
×
196
    _m3storage[8] = uStorage[2] * vStorage[2];
×
197
  }
198

199
  /// Set the diagonal of the matrix.
200
  void splatDiagonal(double arg) {
×
201
    _m3storage[0] = arg;
×
202
    _m3storage[4] = arg;
×
203
    _m3storage[8] = arg;
×
204
  }
205

206
  /// Set the diagonal of the matrix.
207
  void setDiagonal(Vector3 arg) {
×
208
    _m3storage[0] = arg.storage[0];
×
209
    _m3storage[4] = arg.storage[1];
×
210
    _m3storage[8] = arg.storage[2];
×
211
  }
212

213
  /// Sets the upper 2x2 of the matrix to be [arg].
214
  void setUpper2x2(Matrix2 arg) {
×
215
    final argStorage = arg._m2storage;
×
216
    _m3storage[0] = argStorage[0];
×
217
    _m3storage[1] = argStorage[1];
×
218
    _m3storage[3] = argStorage[2];
×
219
    _m3storage[4] = argStorage[3];
×
220
  }
221

222
  /// Returns a printable string
223
  @override
2✔
224
  String toString() => '[0] ${getRow(0)}\n[1] ${getRow(1)}\n[2] ${getRow(2)}\n';
8✔
225

226
  /// Dimension of the matrix.
227
  int get dimension => 3;
2✔
228

229
  /// Access the element of the matrix at the index [i].
230
  double operator [](int i) => _m3storage[i];
×
231

232
  /// Set the element of the matrix at the index [i].
233
  void operator []=(int i, double v) {
1✔
234
    _m3storage[i] = v;
2✔
235
  }
236

237
  /// Check if two matrices are the same.
238
  @override
1✔
239
  bool operator ==(Object other) =>
240
      (other is Matrix3) &&
1✔
241
      (_m3storage[0] == other._m3storage[0]) &&
5✔
242
      (_m3storage[1] == other._m3storage[1]) &&
5✔
243
      (_m3storage[2] == other._m3storage[2]) &&
5✔
244
      (_m3storage[3] == other._m3storage[3]) &&
5✔
245
      (_m3storage[4] == other._m3storage[4]) &&
5✔
246
      (_m3storage[5] == other._m3storage[5]) &&
5✔
247
      (_m3storage[6] == other._m3storage[6]) &&
5✔
248
      (_m3storage[7] == other._m3storage[7]) &&
5✔
249
      (_m3storage[8] == other._m3storage[8]);
5✔
250

251
  @override
1✔
252
  int get hashCode => Object.hashAll(_m3storage);
2✔
253

254
  /// Returns row 0
255
  Vector3 get row0 => getRow(0);
×
256

257
  /// Returns row 1
258
  Vector3 get row1 => getRow(1);
×
259

260
  /// Returns row 2
261
  Vector3 get row2 => getRow(2);
×
262

263
  /// Sets row 0 to [arg]
264
  set row0(Vector3 arg) => setRow(0, arg);
×
265

266
  /// Sets row 1 to [arg]
267
  set row1(Vector3 arg) => setRow(1, arg);
×
268

269
  /// Sets row 2 to [arg]
270
  set row2(Vector3 arg) => setRow(2, arg);
×
271

272
  /// Assigns the [row] of to [arg].
273
  void setRow(int row, Vector3 arg) {
×
274
    final argStorage = arg._v3storage;
×
275
    _m3storage[index(row, 0)] = argStorage[0];
×
276
    _m3storage[index(row, 1)] = argStorage[1];
×
277
    _m3storage[index(row, 2)] = argStorage[2];
×
278
  }
279

280
  /// Gets the [row] of the matrix
281
  Vector3 getRow(int row) {
2✔
282
    final r = Vector3.zero();
2✔
283
    final rStorage = r._v3storage;
2✔
284
    rStorage[0] = _m3storage[index(row, 0)];
8✔
285
    rStorage[1] = _m3storage[index(row, 1)];
8✔
286
    rStorage[2] = _m3storage[index(row, 2)];
8✔
287
    return r;
288
  }
289

290
  /// Assigns the [column] of the matrix [arg]
291
  void setColumn(int column, Vector3 arg) {
×
292
    final argStorage = arg._v3storage;
×
293
    final entry = column * 3;
×
294
    _m3storage[entry + 2] = argStorage[2];
×
295
    _m3storage[entry + 1] = argStorage[1];
×
296
    _m3storage[entry + 0] = argStorage[0];
×
297
  }
298

299
  /// Gets the [column] of the matrix
300
  Vector3 getColumn(int column) {
×
301
    final r = Vector3.zero();
×
302
    final rStorage = r._v3storage;
×
303
    final entry = column * 3;
×
304
    rStorage[2] = _m3storage[entry + 2];
×
305
    rStorage[1] = _m3storage[entry + 1];
×
306
    rStorage[0] = _m3storage[entry + 0];
×
307
    return r;
308
  }
309

310
  /// Clone of this.
311
  Matrix3 clone() => Matrix3.copy(this);
6✔
312

313
  /// Copy this into [arg].
314
  Matrix3 copyInto(Matrix3 arg) {
×
315
    final argStorage = arg._m3storage;
×
316
    argStorage[0] = _m3storage[0];
×
317
    argStorage[1] = _m3storage[1];
×
318
    argStorage[2] = _m3storage[2];
×
319
    argStorage[3] = _m3storage[3];
×
320
    argStorage[4] = _m3storage[4];
×
321
    argStorage[5] = _m3storage[5];
×
322
    argStorage[6] = _m3storage[6];
×
323
    argStorage[7] = _m3storage[7];
×
324
    argStorage[8] = _m3storage[8];
×
325
    return arg;
326
  }
327

328
  /// Returns a new vector or matrix by multiplying this with [arg].
329
  @pragma('wasm:prefer-inline')
2✔
330
  @pragma('vm:prefer-inline')
331
  @pragma('dart2js:prefer-inline')
332
  dynamic operator *(dynamic arg) {
333
    final Object result;
334
    if (arg is double) {
2✔
NEW
335
      result = scaled(arg);
×
336
    } else if (arg is Vector3) {
2✔
337
      result = transformed(arg);
1✔
338
    } else if (arg is Matrix3) {
2✔
339
      result = multiplied(arg);
2✔
340
    } else {
NEW
341
      throw ArgumentError(arg);
×
342
    }
343
    return result;
344
  }
345

346
  /// Returns new matrix after component wise this + [arg]
347
  Matrix3 operator +(Matrix3 arg) => clone()..add(arg);
×
348

349
  /// Returns new matrix after component wise this - [arg]
350
  Matrix3 operator -(Matrix3 arg) => clone()..sub(arg);
6✔
351

352
  /// Returns new matrix -this
353
  Matrix3 operator -() => clone()..negate();
×
354

355
  /// Zeros this.
356
  void setZero() {
×
357
    _m3storage[0] = 0.0;
×
358
    _m3storage[1] = 0.0;
×
359
    _m3storage[2] = 0.0;
×
360
    _m3storage[3] = 0.0;
×
361
    _m3storage[4] = 0.0;
×
362
    _m3storage[5] = 0.0;
×
363
    _m3storage[6] = 0.0;
×
364
    _m3storage[7] = 0.0;
×
365
    _m3storage[8] = 0.0;
×
366
  }
367

368
  /// Makes this into the identity matrix.
369
  void setIdentity() {
1✔
370
    _m3storage[0] = 1.0;
2✔
371
    _m3storage[1] = 0.0;
2✔
372
    _m3storage[2] = 0.0;
2✔
373
    _m3storage[3] = 0.0;
2✔
374
    _m3storage[4] = 1.0;
2✔
375
    _m3storage[5] = 0.0;
2✔
376
    _m3storage[6] = 0.0;
2✔
377
    _m3storage[7] = 0.0;
2✔
378
    _m3storage[8] = 1.0;
2✔
379
  }
380

381
  /// Returns the tranpose of this.
382
  Matrix3 transposed() => clone()..transpose();
3✔
383

384
  /// Transpose this.
385
  void transpose() {
1✔
386
    double temp;
387
    temp = _m3storage[3];
2✔
388
    _m3storage[3] = _m3storage[1];
4✔
389
    _m3storage[1] = temp;
2✔
390
    temp = _m3storage[6];
2✔
391
    _m3storage[6] = _m3storage[2];
4✔
392
    _m3storage[2] = temp;
2✔
393
    temp = _m3storage[7];
2✔
394
    _m3storage[7] = _m3storage[5];
4✔
395
    _m3storage[5] = temp;
2✔
396
  }
397

398
  /// Returns the component wise absolute value of this.
399
  Matrix3 absolute() {
×
400
    final r = Matrix3.zero();
×
401
    final rStorage = r._m3storage;
×
402
    rStorage[0] = _m3storage[0].abs();
×
403
    rStorage[1] = _m3storage[1].abs();
×
404
    rStorage[2] = _m3storage[2].abs();
×
405
    rStorage[3] = _m3storage[3].abs();
×
406
    rStorage[4] = _m3storage[4].abs();
×
407
    rStorage[5] = _m3storage[5].abs();
×
408
    rStorage[6] = _m3storage[6].abs();
×
409
    rStorage[7] = _m3storage[7].abs();
×
410
    rStorage[8] = _m3storage[8].abs();
×
411
    return r;
412
  }
413

414
  /// Returns the determinant of this matrix.
415
  double determinant() {
2✔
416
    final x = _m3storage[0] *
6✔
417
        ((_m3storage[4] * _m3storage[8]) - (_m3storage[5] * _m3storage[7]));
22✔
418
    final y = _m3storage[1] *
6✔
419
        ((_m3storage[3] * _m3storage[8]) - (_m3storage[5] * _m3storage[6]));
22✔
420
    final z = _m3storage[2] *
6✔
421
        ((_m3storage[3] * _m3storage[7]) - (_m3storage[4] * _m3storage[6]));
22✔
422
    return x - y + z;
4✔
423
  }
424

425
  /// Returns the dot product of row [i] and [v].
426
  double dotRow(int i, Vector3 v) {
1✔
427
    final vStorage = v._v3storage;
1✔
428
    return _m3storage[i] * vStorage[0] +
5✔
429
        _m3storage[3 + i] * vStorage[1] +
6✔
430
        _m3storage[6 + i] * vStorage[2];
5✔
431
  }
432

433
  /// Returns the dot product of column [j] and [v].
434
  double dotColumn(int j, Vector3 v) {
1✔
435
    final vStorage = v._v3storage;
1✔
436
    return _m3storage[j * 3] * vStorage[0] +
6✔
437
        _m3storage[j * 3 + 1] * vStorage[1] +
7✔
438
        _m3storage[j * 3 + 2] * vStorage[2];
6✔
439
  }
440

441
  /// Returns the trace of the matrix. The trace of a matrix is the sum of
442
  /// the diagonal entries.
443
  double trace() {
2✔
444
    var t = 0.0;
445
    t += _m3storage[0];
6✔
446
    t += _m3storage[4];
6✔
447
    t += _m3storage[8];
6✔
448
    return t;
449
  }
450

451
  /// Returns infinity norm of the matrix. Used for numerical analysis.
452
  double infinityNorm() {
2✔
453
    var norm = 0.0;
454
    {
455
      var row_norm = 0.0;
456
      row_norm += _m3storage[0].abs();
8✔
457
      row_norm += _m3storage[1].abs();
8✔
458
      row_norm += _m3storage[2].abs();
8✔
459
      norm = row_norm > norm ? row_norm : norm;
2✔
460
    }
461
    {
462
      var row_norm = 0.0;
463
      row_norm += _m3storage[3].abs();
8✔
464
      row_norm += _m3storage[4].abs();
8✔
465
      row_norm += _m3storage[5].abs();
8✔
466
      norm = row_norm > norm ? row_norm : norm;
2✔
467
    }
468
    {
469
      var row_norm = 0.0;
470
      row_norm += _m3storage[6].abs();
8✔
471
      row_norm += _m3storage[7].abs();
8✔
472
      row_norm += _m3storage[8].abs();
8✔
473
      norm = row_norm > norm ? row_norm : norm;
2✔
474
    }
475
    return norm;
476
  }
477

478
  /// Returns relative error between this and [correct]
479
  double relativeError(Matrix3 correct) {
2✔
480
    final diff = correct - this;
2✔
481
    final correct_norm = correct.infinityNorm();
2✔
482
    final diff_norm = diff.infinityNorm();
2✔
483
    return diff_norm / correct_norm;
2✔
484
  }
485

486
  /// Returns absolute error between this and [correct]
487
  double absoluteError(Matrix3 correct) {
×
488
    final this_norm = infinityNorm();
×
489
    final correct_norm = correct.infinityNorm();
×
490
    final diff_norm = (this_norm - correct_norm).abs();
×
491
    return diff_norm;
492
  }
493

494
  /// Invert the matrix. Returns the determinant.
495
  double invert() => copyInverse(this);
2✔
496

497
  /// Set this matrix to be the inverse of [arg]
498
  double copyInverse(Matrix3 arg) {
2✔
499
    final det = arg.determinant();
2✔
500
    if (det == 0.0) {
2✔
501
      setFrom(arg);
×
502
      return 0.0;
503
    }
504
    final invDet = 1.0 / det;
2✔
505
    final argStorage = arg._m3storage;
2✔
506
    final ix = invDet *
2✔
507
        (argStorage[4] * argStorage[8] - argStorage[5] * argStorage[7]);
14✔
508
    final iy = invDet *
2✔
509
        (argStorage[2] * argStorage[7] - argStorage[1] * argStorage[8]);
14✔
510
    final iz = invDet *
2✔
511
        (argStorage[1] * argStorage[5] - argStorage[2] * argStorage[4]);
14✔
512
    final jx = invDet *
2✔
513
        (argStorage[5] * argStorage[6] - argStorage[3] * argStorage[8]);
14✔
514
    final jy = invDet *
2✔
515
        (argStorage[0] * argStorage[8] - argStorage[2] * argStorage[6]);
14✔
516
    final jz = invDet *
2✔
517
        (argStorage[2] * argStorage[3] - argStorage[0] * argStorage[5]);
14✔
518
    final kx = invDet *
2✔
519
        (argStorage[3] * argStorage[7] - argStorage[4] * argStorage[6]);
14✔
520
    final ky = invDet *
2✔
521
        (argStorage[1] * argStorage[6] - argStorage[0] * argStorage[7]);
14✔
522
    final kz = invDet *
2✔
523
        (argStorage[0] * argStorage[4] - argStorage[1] * argStorage[3]);
14✔
524
    _m3storage[0] = ix;
4✔
525
    _m3storage[1] = iy;
4✔
526
    _m3storage[2] = iz;
4✔
527
    _m3storage[3] = jx;
4✔
528
    _m3storage[4] = jy;
4✔
529
    _m3storage[5] = jz;
4✔
530
    _m3storage[6] = kx;
4✔
531
    _m3storage[7] = ky;
4✔
532
    _m3storage[8] = kz;
4✔
533
    return det;
534
  }
535

536
  /// Set this matrix to be the normal matrix of [arg].
537
  void copyNormalMatrix(Matrix4 arg) {
×
538
    copyInverse(arg.getRotation());
×
539
    transpose();
×
540
  }
541

542
  /// Turns the matrix into a rotation of [radians] around X
543
  void setRotationX(double radians) {
4✔
544
    final c = math.cos(radians);
4✔
545
    final s = math.sin(radians);
4✔
546
    _m3storage[0] = 1.0;
8✔
547
    _m3storage[1] = 0.0;
8✔
548
    _m3storage[2] = 0.0;
8✔
549
    _m3storage[3] = 0.0;
8✔
550
    _m3storage[4] = c;
8✔
551
    _m3storage[5] = s;
8✔
552
    _m3storage[6] = 0.0;
8✔
553
    _m3storage[7] = -s;
12✔
554
    _m3storage[8] = c;
8✔
555
  }
556

557
  /// Turns the matrix into a rotation of [radians] around Y
558
  void setRotationY(double radians) {
3✔
559
    final c = math.cos(radians);
3✔
560
    final s = math.sin(radians);
3✔
561
    _m3storage[0] = c;
6✔
562
    _m3storage[1] = 0.0;
6✔
563
    _m3storage[2] = -s;
9✔
564
    _m3storage[3] = 0.0;
6✔
565
    _m3storage[4] = 1.0;
6✔
566
    _m3storage[5] = 0.0;
6✔
567
    _m3storage[6] = s;
6✔
568
    _m3storage[7] = 0.0;
6✔
569
    _m3storage[8] = c;
6✔
570
  }
571

572
  /// Turns the matrix into a rotation of [radians] around Z
573
  void setRotationZ(double radians) {
5✔
574
    final c = math.cos(radians);
5✔
575
    final s = math.sin(radians);
5✔
576
    _m3storage[0] = c;
10✔
577
    _m3storage[1] = s;
10✔
578
    _m3storage[2] = 0.0;
10✔
579
    _m3storage[3] = -s;
15✔
580
    _m3storage[4] = c;
10✔
581
    _m3storage[5] = 0.0;
10✔
582
    _m3storage[6] = 0.0;
10✔
583
    _m3storage[7] = 0.0;
10✔
584
    _m3storage[8] = 1.0;
10✔
585
  }
586

587
  /// Converts into Adjugate matrix and scales by [scale]
588
  void scaleAdjoint(double scale) {
1✔
589
    final m00 = _m3storage[0];
2✔
590
    final m01 = _m3storage[3];
2✔
591
    final m02 = _m3storage[6];
2✔
592
    final m10 = _m3storage[1];
2✔
593
    final m11 = _m3storage[4];
2✔
594
    final m12 = _m3storage[7];
2✔
595
    final m20 = _m3storage[2];
2✔
596
    final m21 = _m3storage[5];
2✔
597
    final m22 = _m3storage[8];
2✔
598
    _m3storage[0] = (m11 * m22 - m12 * m21) * scale;
6✔
599
    _m3storage[1] = (m12 * m20 - m10 * m22) * scale;
6✔
600
    _m3storage[2] = (m10 * m21 - m11 * m20) * scale;
6✔
601
    _m3storage[3] = (m02 * m21 - m01 * m22) * scale;
6✔
602
    _m3storage[4] = (m00 * m22 - m02 * m20) * scale;
6✔
603
    _m3storage[5] = (m01 * m20 - m00 * m21) * scale;
6✔
604
    _m3storage[6] = (m01 * m12 - m02 * m11) * scale;
6✔
605
    _m3storage[7] = (m02 * m10 - m00 * m12) * scale;
6✔
606
    _m3storage[8] = (m00 * m11 - m01 * m10) * scale;
6✔
607
  }
608

609
  /// Rotates [arg] by the absolute rotation of this
610
  /// Returns [arg].
611
  /// Primarily used by AABB transformation code.
612
  Vector3 absoluteRotate(Vector3 arg) {
×
613
    final m00 = _m3storage[0].abs();
×
614
    final m01 = _m3storage[3].abs();
×
615
    final m02 = _m3storage[6].abs();
×
616
    final m10 = _m3storage[1].abs();
×
617
    final m11 = _m3storage[4].abs();
×
618
    final m12 = _m3storage[7].abs();
×
619
    final m20 = _m3storage[2].abs();
×
620
    final m21 = _m3storage[5].abs();
×
621
    final m22 = _m3storage[8].abs();
×
622
    final argStorage = arg._v3storage;
×
623
    final x = argStorage[0];
×
624
    final y = argStorage[1];
×
625
    final z = argStorage[2];
×
626
    argStorage[0] = x * m00 + y * m01 + z * m02;
×
627
    argStorage[1] = x * m10 + y * m11 + z * m12;
×
628
    argStorage[2] = x * m20 + y * m21 + z * m22;
×
629
    return arg;
630
  }
631

632
  /// Rotates [arg] by the absolute rotation of this
633
  /// Returns [arg].
634
  /// Primarily used by AABB transformation code.
635
  Vector2 absoluteRotate2(Vector2 arg) {
2✔
636
    final m00 = _m3storage[0].abs();
6✔
637
    final m01 = _m3storage[3].abs();
6✔
638
    final m10 = _m3storage[1].abs();
6✔
639
    final m11 = _m3storage[4].abs();
6✔
640
    final argStorage = arg._v2storage;
2✔
641
    final x = argStorage[0];
2✔
642
    final y = argStorage[1];
2✔
643
    argStorage[0] = x * m00 + y * m01;
8✔
644
    argStorage[1] = x * m10 + y * m11;
8✔
645
    return arg;
646
  }
647

648
  /// Transforms [arg] with this.
649
  Vector2 transform2(Vector2 arg) {
3✔
650
    final argStorage = arg._v2storage;
3✔
651
    final x_ = (_m3storage[0] * argStorage[0]) +
15✔
652
        (_m3storage[3] * argStorage[1]) +
15✔
653
        _m3storage[6];
6✔
654
    final y_ = (_m3storage[1] * argStorage[0]) +
15✔
655
        (_m3storage[4] * argStorage[1]) +
15✔
656
        _m3storage[7];
6✔
657
    argStorage[0] = x_;
3✔
658
    argStorage[1] = y_;
3✔
659
    return arg;
660
  }
661

662
  /// Scales this by [scale].
663
  void scale(double scale) {
1✔
664
    _m3storage[0] = _m3storage[0] * scale;
5✔
665
    _m3storage[1] = _m3storage[1] * scale;
5✔
666
    _m3storage[2] = _m3storage[2] * scale;
5✔
667
    _m3storage[3] = _m3storage[3] * scale;
5✔
668
    _m3storage[4] = _m3storage[4] * scale;
5✔
669
    _m3storage[5] = _m3storage[5] * scale;
5✔
670
    _m3storage[6] = _m3storage[6] * scale;
5✔
671
    _m3storage[7] = _m3storage[7] * scale;
5✔
672
    _m3storage[8] = _m3storage[8] * scale;
5✔
673
  }
674

675
  /// Create a copy of this and scale it by [scale].
676
  Matrix3 scaled(double scale) => clone()..scale(scale);
3✔
677

678
  /// Add [o] to this.
679
  void add(Matrix3 o) {
×
680
    final oStorage = o._m3storage;
×
681
    _m3storage[0] = _m3storage[0] + oStorage[0];
×
682
    _m3storage[1] = _m3storage[1] + oStorage[1];
×
683
    _m3storage[2] = _m3storage[2] + oStorage[2];
×
684
    _m3storage[3] = _m3storage[3] + oStorage[3];
×
685
    _m3storage[4] = _m3storage[4] + oStorage[4];
×
686
    _m3storage[5] = _m3storage[5] + oStorage[5];
×
687
    _m3storage[6] = _m3storage[6] + oStorage[6];
×
688
    _m3storage[7] = _m3storage[7] + oStorage[7];
×
689
    _m3storage[8] = _m3storage[8] + oStorage[8];
×
690
  }
691

692
  /// Subtract [o] from this.
693
  void sub(Matrix3 o) {
2✔
694
    final oStorage = o._m3storage;
2✔
695
    _m3storage[0] = _m3storage[0] - oStorage[0];
12✔
696
    _m3storage[1] = _m3storage[1] - oStorage[1];
12✔
697
    _m3storage[2] = _m3storage[2] - oStorage[2];
12✔
698
    _m3storage[3] = _m3storage[3] - oStorage[3];
12✔
699
    _m3storage[4] = _m3storage[4] - oStorage[4];
12✔
700
    _m3storage[5] = _m3storage[5] - oStorage[5];
12✔
701
    _m3storage[6] = _m3storage[6] - oStorage[6];
12✔
702
    _m3storage[7] = _m3storage[7] - oStorage[7];
12✔
703
    _m3storage[8] = _m3storage[8] - oStorage[8];
12✔
704
  }
705

706
  /// Negate this.
707
  void negate() {
×
708
    _m3storage[0] = -_m3storage[0];
×
709
    _m3storage[1] = -_m3storage[1];
×
710
    _m3storage[2] = -_m3storage[2];
×
711
    _m3storage[3] = -_m3storage[3];
×
712
    _m3storage[4] = -_m3storage[4];
×
713
    _m3storage[5] = -_m3storage[5];
×
714
    _m3storage[6] = -_m3storage[6];
×
715
    _m3storage[7] = -_m3storage[7];
×
716
    _m3storage[8] = -_m3storage[8];
×
717
  }
718

719
  /// Multiply this by [arg].
720
  void multiply(Matrix3 arg) {
3✔
721
    final m00 = _m3storage[0];
6✔
722
    final m01 = _m3storage[3];
6✔
723
    final m02 = _m3storage[6];
6✔
724
    final m10 = _m3storage[1];
6✔
725
    final m11 = _m3storage[4];
6✔
726
    final m12 = _m3storage[7];
6✔
727
    final m20 = _m3storage[2];
6✔
728
    final m21 = _m3storage[5];
6✔
729
    final m22 = _m3storage[8];
6✔
730
    final argStorage = arg._m3storage;
3✔
731
    final n00 = argStorage[0];
3✔
732
    final n01 = argStorage[3];
3✔
733
    final n02 = argStorage[6];
3✔
734
    final n10 = argStorage[1];
3✔
735
    final n11 = argStorage[4];
3✔
736
    final n12 = argStorage[7];
3✔
737
    final n20 = argStorage[2];
3✔
738
    final n21 = argStorage[5];
3✔
739
    final n22 = argStorage[8];
3✔
740
    _m3storage[0] = (m00 * n00) + (m01 * n10) + (m02 * n20);
21✔
741
    _m3storage[3] = (m00 * n01) + (m01 * n11) + (m02 * n21);
21✔
742
    _m3storage[6] = (m00 * n02) + (m01 * n12) + (m02 * n22);
21✔
743
    _m3storage[1] = (m10 * n00) + (m11 * n10) + (m12 * n20);
21✔
744
    _m3storage[4] = (m10 * n01) + (m11 * n11) + (m12 * n21);
21✔
745
    _m3storage[7] = (m10 * n02) + (m11 * n12) + (m12 * n22);
21✔
746
    _m3storage[2] = (m20 * n00) + (m21 * n10) + (m22 * n20);
21✔
747
    _m3storage[5] = (m20 * n01) + (m21 * n11) + (m22 * n21);
21✔
748
    _m3storage[8] = (m20 * n02) + (m21 * n12) + (m22 * n22);
21✔
749
  }
750

751
  /// Create a copy of this and multiply it by [arg].
752
  Matrix3 multiplied(Matrix3 arg) => clone()..multiply(arg);
6✔
753

754
  void transposeMultiply(Matrix3 arg) {
1✔
755
    final m00 = _m3storage[0];
2✔
756
    final m01 = _m3storage[1];
2✔
757
    final m02 = _m3storage[2];
2✔
758
    final m10 = _m3storage[3];
2✔
759
    final m11 = _m3storage[4];
2✔
760
    final m12 = _m3storage[5];
2✔
761
    final m20 = _m3storage[6];
2✔
762
    final m21 = _m3storage[7];
2✔
763
    final m22 = _m3storage[8];
2✔
764
    final argStorage = arg._m3storage;
1✔
765
    _m3storage[0] =
2✔
766
        (m00 * argStorage[0]) + (m01 * argStorage[1]) + (m02 * argStorage[2]);
8✔
767
    _m3storage[3] =
2✔
768
        (m00 * argStorage[3]) + (m01 * argStorage[4]) + (m02 * argStorage[5]);
8✔
769
    _m3storage[6] =
2✔
770
        (m00 * argStorage[6]) + (m01 * argStorage[7]) + (m02 * argStorage[8]);
8✔
771
    _m3storage[1] =
2✔
772
        (m10 * argStorage[0]) + (m11 * argStorage[1]) + (m12 * argStorage[2]);
8✔
773
    _m3storage[4] =
2✔
774
        (m10 * argStorage[3]) + (m11 * argStorage[4]) + (m12 * argStorage[5]);
8✔
775
    _m3storage[7] =
2✔
776
        (m10 * argStorage[6]) + (m11 * argStorage[7]) + (m12 * argStorage[8]);
8✔
777
    _m3storage[2] =
2✔
778
        (m20 * argStorage[0]) + (m21 * argStorage[1]) + (m22 * argStorage[2]);
8✔
779
    _m3storage[5] =
2✔
780
        (m20 * argStorage[3]) + (m21 * argStorage[4]) + (m22 * argStorage[5]);
8✔
781
    _m3storage[8] =
2✔
782
        (m20 * argStorage[6]) + (m21 * argStorage[7]) + (m22 * argStorage[8]);
8✔
783
  }
784

785
  void multiplyTranspose(Matrix3 arg) {
1✔
786
    final m00 = _m3storage[0];
2✔
787
    final m01 = _m3storage[3];
2✔
788
    final m02 = _m3storage[6];
2✔
789
    final m10 = _m3storage[1];
2✔
790
    final m11 = _m3storage[4];
2✔
791
    final m12 = _m3storage[7];
2✔
792
    final m20 = _m3storage[2];
2✔
793
    final m21 = _m3storage[5];
2✔
794
    final m22 = _m3storage[8];
2✔
795
    final argStorage = arg._m3storage;
1✔
796
    _m3storage[0] =
2✔
797
        (m00 * argStorage[0]) + (m01 * argStorage[3]) + (m02 * argStorage[6]);
8✔
798
    _m3storage[3] =
2✔
799
        (m00 * argStorage[1]) + (m01 * argStorage[4]) + (m02 * argStorage[7]);
8✔
800
    _m3storage[6] =
2✔
801
        (m00 * argStorage[2]) + (m01 * argStorage[5]) + (m02 * argStorage[8]);
8✔
802
    _m3storage[1] =
2✔
803
        (m10 * argStorage[0]) + (m11 * argStorage[3]) + (m12 * argStorage[6]);
8✔
804
    _m3storage[4] =
2✔
805
        (m10 * argStorage[1]) + (m11 * argStorage[4]) + (m12 * argStorage[7]);
8✔
806
    _m3storage[7] =
2✔
807
        (m10 * argStorage[2]) + (m11 * argStorage[5]) + (m12 * argStorage[8]);
8✔
808
    _m3storage[2] =
2✔
809
        (m20 * argStorage[0]) + (m21 * argStorage[3]) + (m22 * argStorage[6]);
8✔
810
    _m3storage[5] =
2✔
811
        (m20 * argStorage[1]) + (m21 * argStorage[4]) + (m22 * argStorage[7]);
8✔
812
    _m3storage[8] =
2✔
813
        (m20 * argStorage[2]) + (m21 * argStorage[5]) + (m22 * argStorage[8]);
8✔
814
  }
815

816
  /// Transform [arg] of type [Vector3] using the transformation defined by
817
  /// this.
818
  Vector3 transform(Vector3 arg) {
3✔
819
    final argStorage = arg._v3storage;
3✔
820
    final x_ = (_m3storage[0] * argStorage[0]) +
15✔
821
        (_m3storage[3] * argStorage[1]) +
15✔
822
        (_m3storage[6] * argStorage[2]);
12✔
823
    final y_ = (_m3storage[1] * argStorage[0]) +
15✔
824
        (_m3storage[4] * argStorage[1]) +
15✔
825
        (_m3storage[7] * argStorage[2]);
12✔
826
    final z_ = (_m3storage[2] * argStorage[0]) +
15✔
827
        (_m3storage[5] * argStorage[1]) +
15✔
828
        (_m3storage[8] * argStorage[2]);
12✔
829
    arg
830
      ..x = x_
3✔
831
      ..y = y_
3✔
832
      ..z = z_;
3✔
833
    return arg;
834
  }
835

836
  /// Transform a copy of [arg] of type [Vector3] using the transformation
837
  /// defined by this. If a [out] parameter is supplied, the copy is stored in
838
  /// [out].
839
  Vector3 transformed(Vector3 arg, [Vector3? out]) {
2✔
840
    if (out == null) {
841
      out = Vector3.copy(arg);
2✔
842
    } else {
843
      out.setFrom(arg);
×
844
    }
845
    return transform(out);
2✔
846
  }
847

848
  /// Copies this into [array] starting at [offset].
849
  void copyIntoArray(List<num> array, [int offset = 0]) {
×
850
    final i = offset;
851
    array[i + 8] = _m3storage[8];
×
852
    array[i + 7] = _m3storage[7];
×
853
    array[i + 6] = _m3storage[6];
×
854
    array[i + 5] = _m3storage[5];
×
855
    array[i + 4] = _m3storage[4];
×
856
    array[i + 3] = _m3storage[3];
×
857
    array[i + 2] = _m3storage[2];
×
858
    array[i + 1] = _m3storage[1];
×
859
    array[i + 0] = _m3storage[0];
×
860
  }
861

862
  /// Copies elements from [array] into this starting at [offset].
863
  void copyFromArray(List<double> array, [int offset = 0]) {
×
864
    final i = offset;
865
    _m3storage[8] = array[i + 8];
×
866
    _m3storage[7] = array[i + 7];
×
867
    _m3storage[6] = array[i + 6];
×
868
    _m3storage[5] = array[i + 5];
×
869
    _m3storage[4] = array[i + 4];
×
870
    _m3storage[3] = array[i + 3];
×
871
    _m3storage[2] = array[i + 2];
×
872
    _m3storage[1] = array[i + 1];
×
873
    _m3storage[0] = array[i + 0];
×
874
  }
875

876
  /// Multiply this to each set of xyz values in [array] starting at [offset].
877
  List<double> applyToVector3Array(List<double> array, [int offset = 0]) {
×
878
    for (var i = 0, j = offset; i < array.length; i += 3, j += 3) {
×
879
      final v = Vector3.array(array, j)..applyMatrix3(this);
×
880
      array[j] = v.storage[0];
×
881
      array[j + 1] = v.storage[1];
×
882
      array[j + 2] = v.storage[2];
×
883
    }
884

885
    return array;
886
  }
887

888
  Vector3 get right {
×
889
    final x = _m3storage[0];
×
890
    final y = _m3storage[1];
×
891
    final z = _m3storage[2];
×
892
    return Vector3(x, y, z);
×
893
  }
894

895
  Vector3 get up {
×
896
    final x = _m3storage[3];
×
897
    final y = _m3storage[4];
×
898
    final z = _m3storage[5];
×
899
    return Vector3(x, y, z);
×
900
  }
901

902
  Vector3 get forward {
×
903
    final x = _m3storage[6];
×
904
    final y = _m3storage[7];
×
905
    final z = _m3storage[8];
×
906
    return Vector3(x, y, z);
×
907
  }
908

909
  /// Is this the identity matrix?
910
  bool isIdentity() =>
1✔
911
      _m3storage[0] == 1.0 // col 1
3✔
912
      &&
913
      _m3storage[1] == 0.0 &&
3✔
914
      _m3storage[2] == 0.0 &&
3✔
915
      _m3storage[3] == 0.0 // col 2
3✔
916
      &&
917
      _m3storage[4] == 1.0 &&
3✔
918
      _m3storage[5] == 0.0 &&
3✔
919
      _m3storage[6] == 0.0 // col 3
3✔
920
      &&
921
      _m3storage[7] == 0.0 &&
3✔
922
      _m3storage[8] == 1.0;
3✔
923

924
  /// Is this the zero matrix?
925
  bool isZero() =>
1✔
926
      _m3storage[0] == 0.0 // col 1
3✔
927
      &&
928
      _m3storage[1] == 0.0 &&
3✔
929
      _m3storage[2] == 0.0 &&
3✔
930
      _m3storage[3] == 0.0 // col 2
3✔
931
      &&
932
      _m3storage[4] == 0.0 &&
3✔
933
      _m3storage[5] == 0.0 &&
3✔
934
      _m3storage[6] == 0.0 // col 3
3✔
935
      &&
936
      _m3storage[7] == 0.0 &&
3✔
937
      _m3storage[8] == 0.0;
3✔
938
}
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