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

google / vector_math.dart / 17181727464

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

push

github

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

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

18 existing lines in 8 files now uncovered.

4463 of 16714 relevant lines covered (26.7%)

1.18 hits per line

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

0.0
/lib/src/vector_math_64/opengl.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
/// Constructs a rotation matrix in [rotationMatrix].
8
///
9
/// Sets [rotationMatrix] to a rotation matrix built from
10
/// [forwardDirection] and [upDirection]. The right direction is
11
/// constructed to be orthogonal to [forwardDirection] and
12
/// [upDirection].
13
///
14
/// [forwardDirection] specifies the direction of the forward vector.
15
/// [upDirection] specifies the direction of the up vector.
16
///
17
/// Use case is to build the per-model rotation matrix from vectors
18
/// [forwardDirection] and [upDirection]. See sample code below for
19
/// a context.
20
///
21
///     class Model {
22
///       Vector3 _center = new Vector3.zero();        // per-model translation
23
///       Vector3 _scale = new Vector3(1.0, 1.0, 1.0); // per-model scaling
24
///       Matrix4 _rotation = new Matrix4.identity();  // per-model rotation
25
///       Matrix4 _MV = new Matrix4.identity();        // per-model model-view
26
///
27
///       void updateModelViewUniform(RenderingContext gl, UniformLocation u_MV,
28
///         Vector3 camPosition, camFocusPosition, camUpDirection) {
29
///
30
///         // V = View (inverse of camera)
31
///         // T = Translation
32
///         // R = Rotation
33
///         // S = Scaling
34
///         setViewMatrix(_MV, camPosition, camFocusPosition, camUpDirection); // MV = V
35
///         _MV.translate(_center); // MV = V*T
36
///         _MV.multiply(_rotation); // MV = V*T*R
37
///         // _rotation is updated with setRotationMatrix(_rotation, forward, up);
38
///         _MV.scale(_scale); // MV = V*T*R*S
39
///
40
///         gl.uniformMatrix4fv(u_MV, false, _MV.storage);
41
///       }
42
///     }
43
void setRotationMatrix(
×
44
  Matrix4 rotationMatrix,
45
  Vector3 forwardDirection,
46
  Vector3 upDirection,
47
) {
UNCOV
48
  setModelMatrix(rotationMatrix, forwardDirection, upDirection, 0.0, 0.0, 0.0);
×
49
}
50

51
/// Constructs an OpenGL model matrix in [modelMatrix].
52
/// Model transformation is the inverse of the view transformation.
53
/// Model transformation is also known as "camera" transformation.
54
/// Model matrix is commonly used to compute a object location/orientation into
55
/// the full model-view stack.
56
///
57
/// [forwardDirection] specifies the direction of the forward vector.
58
/// [upDirection] specifies the direction of the up vector.
59
/// [tx],[ty],[tz] specifies the position of the object.
NEW
60
void setModelMatrix(
×
61
  Matrix4 modelMatrix,
62
  Vector3 forwardDirection,
63
  Vector3 upDirection,
64
  double tx,
65
  double ty,
66
  double tz,
67
) {
UNCOV
68
  final right = forwardDirection.cross(upDirection)..normalize();
×
69
  final c1 = right;
70
  final c2 = upDirection;
71
  final c3 = -forwardDirection;
×
NEW
72
  modelMatrix.setValues(
×
NEW
73
    c1[0],
×
NEW
74
    c1[1],
×
NEW
75
    c1[2],
×
76
    0.0,
NEW
77
    c2[0],
×
NEW
78
    c2[1],
×
NEW
79
    c2[2],
×
80
    0.0,
NEW
81
    c3[0],
×
NEW
82
    c3[1],
×
NEW
83
    c3[2],
×
84
    0.0,
85
    tx,
86
    ty,
87
    tz,
88
    1.0,
89
  );
90
}
91

92
/// Constructs an OpenGL view matrix in [viewMatrix].
93
/// View transformation is the inverse of the model transformation.
94
/// View matrix is commonly used to compute the camera location/orientation into
95
/// the full model-view stack.
96
///
97
/// [cameraPosition] specifies the position of the camera.
98
/// [cameraFocusPosition] specifies the position the camera is focused on.
99
/// [upDirection] specifies the direction of the up vector (usually, +Y).
NEW
100
void setViewMatrix(
×
101
  Matrix4 viewMatrix,
102
  Vector3 cameraPosition,
103
  Vector3 cameraFocusPosition,
104
  Vector3 upDirection,
105
) {
106
  final z = (cameraPosition - cameraFocusPosition)..normalize();
×
107
  final x = upDirection.cross(z)..normalize();
×
108
  final y = z.cross(x)..normalize();
×
109

110
  final rotatedEyeX = -x.dot(cameraPosition);
×
111
  final rotatedEyeY = -y.dot(cameraPosition);
×
112
  final rotatedEyeZ = -z.dot(cameraPosition);
×
113

NEW
114
  viewMatrix.setValues(
×
NEW
115
    x[0],
×
NEW
116
    y[0],
×
NEW
117
    z[0],
×
118
    0.0,
NEW
119
    x[1],
×
NEW
120
    y[1],
×
NEW
121
    z[1],
×
122
    0.0,
NEW
123
    x[2],
×
NEW
124
    y[2],
×
NEW
125
    z[2],
×
126
    0.0,
127
    rotatedEyeX,
128
    rotatedEyeY,
129
    rotatedEyeZ,
130
    1.0,
131
  );
132
}
133

134
/// Constructs a new OpenGL view matrix.
135
///
136
/// [cameraPosition] specifies the position of the camera.
137
/// [cameraFocusPosition] specifies the position the camera is focused on.
138
/// [upDirection] specifies the direction of the up vector (usually, +Y).
139
Matrix4 makeViewMatrix(
×
140
  Vector3 cameraPosition,
141
  Vector3 cameraFocusPosition,
142
  Vector3 upDirection,
143
) {
144
  final r = Matrix4.zero();
×
145
  setViewMatrix(r, cameraPosition, cameraFocusPosition, upDirection);
×
146
  return r;
147
}
148

149
/// Constructs an OpenGL perspective projection matrix in [perspectiveMatrix].
150
///
151
/// [fovYRadians] specifies the field of view angle, in radians, in the y
152
/// direction.
153
/// [aspectRatio] specifies the aspect ratio that determines the field of view
154
/// in the x direction. The aspect ratio of x (width) to y (height).
155
/// [zNear] specifies the distance from the viewer to the near plane
156
/// (always positive).
157
/// [zFar] specifies the distance from the viewer to the far plane
158
/// (always positive).
NEW
159
void setPerspectiveMatrix(
×
160
  Matrix4 perspectiveMatrix,
161
  double fovYRadians,
162
  double aspectRatio,
163
  double zNear,
164
  double zFar,
165
) {
166
  final height = math.tan(fovYRadians * 0.5);
×
167
  final width = height * aspectRatio;
×
168
  final near_minus_far = zNear - zFar;
×
169

170
  perspectiveMatrix
171
    ..setZero()
×
172
    ..setEntry(0, 0, 1.0 / width)
×
173
    ..setEntry(1, 1, 1.0 / height)
×
174
    ..setEntry(2, 2, (zFar + zNear) / near_minus_far)
×
175
    ..setEntry(3, 2, -1.0)
×
176
    ..setEntry(2, 3, (2.0 * zNear * zFar) / near_minus_far);
×
177
}
178

179
/// Constructs a new OpenGL perspective projection matrix.
180
///
181
/// [fovYRadians] specifies the field of view angle, in radians, in the y
182
/// direction.
183
/// [aspectRatio] specifies the aspect ratio that determines the field of view
184
/// in the x direction. The aspect ratio of x (width) to y (height).
185
/// [zNear] specifies the distance from the viewer to the near plane
186
/// (always positive).
187
/// [zFar] specifies the distance from the viewer to the far plane
188
/// (always positive).
189
Matrix4 makePerspectiveMatrix(
×
190
  double fovYRadians,
191
  double aspectRatio,
192
  double zNear,
193
  double zFar,
194
) {
195
  final r = Matrix4.zero();
×
196
  setPerspectiveMatrix(r, fovYRadians, aspectRatio, zNear, zFar);
×
197
  return r;
198
}
199

200
/// Constructs an OpenGL infinite projection matrix in [infiniteMatrix].
201
/// [fovYRadians] specifies the field of view angle, in radians, in the y
202
/// direction.
203
/// [aspectRatio] specifies the aspect ratio that determines the field of view
204
/// in the x direction. The aspect ratio of x (width) to y (height).
205
/// [zNear] specifies the distance from the viewer to the near plane
206
/// (always positive).
NEW
207
void setInfiniteMatrix(
×
208
  Matrix4 infiniteMatrix,
209
  double fovYRadians,
210
  double aspectRatio,
211
  double zNear,
212
) {
213
  final height = math.tan(fovYRadians * 0.5);
×
214
  final width = height * aspectRatio;
×
215

216
  infiniteMatrix
217
    ..setZero()
×
218
    ..setEntry(0, 0, 1.0 / width)
×
219
    ..setEntry(1, 1, 1.0 / height)
×
220
    ..setEntry(2, 2, -1.0)
×
221
    ..setEntry(3, 2, -1.0)
×
222
    ..setEntry(2, 3, -2.0 * zNear);
×
223
}
224

225
/// Constructs a new OpenGL infinite projection matrix.
226
///
227
/// [fovYRadians] specifies the field of view angle, in radians, in the y
228
/// direction.
229
/// [aspectRatio] specifies the aspect ratio that determines the field of view
230
/// in the x direction. The aspect ratio of x (width) to y (height).
231
/// [zNear] specifies the distance from the viewer to the near plane
232
/// (always positive).
233
Matrix4 makeInfiniteMatrix(
×
234
  double fovYRadians,
235
  double aspectRatio,
236
  double zNear,
237
) {
238
  final r = Matrix4.zero();
×
239
  setInfiniteMatrix(r, fovYRadians, aspectRatio, zNear);
×
240
  return r;
241
}
242

243
/// Constructs an OpenGL perspective projection matrix in [perspectiveMatrix].
244
///
245
/// [left], [right] specify the coordinates for the left and right vertical
246
/// clipping planes.
247
/// [bottom], [top] specify the coordinates for the bottom and top horizontal
248
/// clipping planes.
249
/// [near], [far] specify the coordinates to the near and far depth clipping
250
/// planes.
NEW
251
void setFrustumMatrix(
×
252
  Matrix4 perspectiveMatrix,
253
  double left,
254
  double right,
255
  double bottom,
256
  double top,
257
  double near,
258
  double far,
259
) {
260
  final two_near = 2.0 * near;
×
261
  final right_minus_left = right - left;
×
262
  final top_minus_bottom = top - bottom;
×
263
  final far_minus_near = far - near;
×
264
  perspectiveMatrix
265
    ..setZero()
×
266
    ..setEntry(0, 0, two_near / right_minus_left)
×
267
    ..setEntry(1, 1, two_near / top_minus_bottom)
×
268
    ..setEntry(0, 2, (right + left) / right_minus_left)
×
269
    ..setEntry(1, 2, (top + bottom) / top_minus_bottom)
×
270
    ..setEntry(2, 2, -(far + near) / far_minus_near)
×
271
    ..setEntry(3, 2, -1.0)
×
272
    ..setEntry(2, 3, -(two_near * far) / far_minus_near);
×
273
}
274

275
/// Constructs a new OpenGL perspective projection matrix.
276
///
277
/// [left], [right] specify the coordinates for the left and right vertical
278
/// clipping planes.
279
/// [bottom], [top] specify the coordinates for the bottom and top horizontal
280
/// clipping planes.
281
/// [near], [far] specify the coordinates to the near and far depth clipping
282
/// planes.
NEW
283
Matrix4 makeFrustumMatrix(
×
284
  double left,
285
  double right,
286
  double bottom,
287
  double top,
288
  double near,
289
  double far,
290
) {
291
  final view = Matrix4.zero();
×
292
  setFrustumMatrix(view, left, right, bottom, top, near, far);
×
293
  return view;
294
}
295

296
/// Constructs an OpenGL orthographic projection matrix in [orthographicMatrix].
297
///
298
/// [left], [right] specify the coordinates for the left and right vertical
299
/// clipping planes.
300
/// [bottom], [top] specify the coordinates for the bottom and top horizontal
301
/// clipping planes.
302
/// [near], [far] specify the coordinates to the near and far depth clipping
303
/// planes.
NEW
304
void setOrthographicMatrix(
×
305
  Matrix4 orthographicMatrix,
306
  double left,
307
  double right,
308
  double bottom,
309
  double top,
310
  double near,
311
  double far,
312
) {
313
  final rml = right - left;
×
314
  final rpl = right + left;
×
315
  final tmb = top - bottom;
×
316
  final tpb = top + bottom;
×
317
  final fmn = far - near;
×
318
  final fpn = far + near;
×
319
  orthographicMatrix
320
    ..setZero()
×
321
    ..setEntry(0, 0, 2.0 / rml)
×
322
    ..setEntry(1, 1, 2.0 / tmb)
×
323
    ..setEntry(2, 2, -2.0 / fmn)
×
324
    ..setEntry(0, 3, -rpl / rml)
×
325
    ..setEntry(1, 3, -tpb / tmb)
×
326
    ..setEntry(2, 3, -fpn / fmn)
×
327
    ..setEntry(3, 3, 1.0);
×
328
}
329

330
/// Constructs a new OpenGL orthographic projection matrix.
331
///
332
/// [left], [right] specify the coordinates for the left and right vertical
333
/// clipping planes.
334
/// [bottom], [top] specify the coordinates for the bottom and top horizontal
335
/// clipping planes.
336
/// [near], [far] specify the coordinates to the near and far depth clipping
337
/// planes.
NEW
338
Matrix4 makeOrthographicMatrix(
×
339
  double left,
340
  double right,
341
  double bottom,
342
  double top,
343
  double near,
344
  double far,
345
) {
346
  final r = Matrix4.zero();
×
347
  setOrthographicMatrix(r, left, right, bottom, top, near, far);
×
348
  return r;
349
}
350

351
/// Returns a transformation matrix that transforms points onto
352
/// the plane specified with [planeNormal] and [planePoint].
353
Matrix4 makePlaneProjection(Vector3 planeNormal, Vector3 planePoint) {
×
NEW
354
  final v = Vector4(
×
NEW
355
    planeNormal.storage[0],
×
NEW
356
    planeNormal.storage[1],
×
NEW
357
    planeNormal.storage[2],
×
358
    0.0,
359
  );
360
  final outer = Matrix4.outer(v, v);
×
361
  var r = Matrix4.zero();
×
362
  r = r - outer;
×
363
  final scaledNormal = planeNormal.scaled(dot3(planePoint, planeNormal));
×
NEW
364
  final T = Vector4(
×
NEW
365
    scaledNormal.storage[0],
×
NEW
366
    scaledNormal.storage[1],
×
NEW
367
    scaledNormal.storage[2],
×
368
    1.0,
369
  );
UNCOV
370
  r.setColumn(3, T);
×
371
  return r;
372
}
373

374
/// Returns a transformation matrix that transforms points by reflecting
375
/// them through the plane specified with [planeNormal] and [planePoint].
376
Matrix4 makePlaneReflection(Vector3 planeNormal, Vector3 planePoint) {
×
NEW
377
  final v = Vector4(
×
NEW
378
    planeNormal.storage[0],
×
NEW
379
    planeNormal.storage[1],
×
NEW
380
    planeNormal.storage[2],
×
381
    0.0,
382
  );
383
  final outer = Matrix4.outer(v, v)..scaleByDouble(2.0, 2.0, 2.0, 1.0);
×
384
  var r = Matrix4.zero();
×
385
  r = r - outer;
×
386
  final scale = 2.0 * planePoint.dot(planeNormal);
×
387
  final scaledNormal = planeNormal.scaled(scale);
×
NEW
388
  final T = Vector4(
×
NEW
389
    scaledNormal.storage[0],
×
NEW
390
    scaledNormal.storage[1],
×
NEW
391
    scaledNormal.storage[2],
×
392
    1.0,
393
  );
UNCOV
394
  r.setColumn(3, T);
×
395
  return r;
396
}
397

398
/// On success, Sets [pickWorld] to be the world space position of
399
/// the screen space [pickX], [pickY], and [pickZ].
400
///
401
/// The viewport is specified by ([viewportX], [viewportWidth]) and
402
/// ([viewportY], [viewportHeight]).
403
///
404
/// [cameraMatrix] includes both the projection and view transforms.
405
///
406
/// [pickZ] is typically either 0.0 (near plane) or 1.0 (far plane).
407
///
408
/// Returns false on error, for example, the mouse is not in the viewport
409
bool unproject(
×
410
  Matrix4 cameraMatrix,
411
  num viewportX,
412
  num viewportWidth,
413
  num viewportY,
414
  num viewportHeight,
415
  num pickX,
416
  num pickY,
417
  num pickZ,
418
  Vector3 pickWorld,
419
) {
420
  viewportX = viewportX.toDouble();
×
421
  viewportWidth = viewportWidth.toDouble();
×
422
  viewportY = viewportY.toDouble();
×
423
  viewportHeight = viewportHeight.toDouble();
×
424
  pickX = pickX.toDouble();
×
425
  pickY = pickY.toDouble();
×
426
  pickX = pickX - viewportX;
×
427
  pickY = pickY - viewportY;
×
428
  pickX = (2.0 * pickX / viewportWidth) - 1.0;
×
429
  pickY = (2.0 * pickY / viewportHeight) - 1.0;
×
430
  pickZ = (2.0 * pickZ) - 1.0;
×
431

432
  // Check if pick point is inside unit cube
433
  if (pickX < -1.0 ||
×
434
      pickY < -1.0 ||
×
435
      pickX > 1.0 ||
×
436
      pickY > 1.0 ||
×
437
      pickZ < -1.0 ||
×
438
      pickZ > 1.0) {
×
439
    return false;
440
  }
441

442
  // Copy camera matrix.
443
  final invertedCameraMatrix = Matrix4.copy(cameraMatrix);
×
444
  // Invert the camera matrix.
445
  invertedCameraMatrix.invert();
×
446
  // Determine intersection point.
447
  final v = Vector4(pickX.toDouble(), pickY.toDouble(), pickZ.toDouble(), 1.0);
×
448
  invertedCameraMatrix.transform(v);
×
449
  if (v.w == 0.0) {
×
450
    return false;
451
  }
452
  final invW = 1.0 / v.w;
×
453
  pickWorld
454
    ..x = v.x * invW
×
455
    ..y = v.y * invW
×
456
    ..z = v.z * invW;
×
457

458
  return true;
459
}
460

461
/// On success, [rayNear] and [rayFar] are the points where
462
/// the screen space [pickX], [pickY] intersect with the near and far
463
/// planes respectively.
464
///
465
/// The viewport is specified by ([viewportX], [viewportWidth]) and
466
/// ([viewportY], [viewportHeight]).
467
///
468
/// [cameraMatrix] includes both the projection and view transforms.
469
///
470
/// Returns false on error, for example, the mouse is not in the viewport.
471
bool pickRay(
×
472
  Matrix4 cameraMatrix,
473
  num viewportX,
474
  num viewportWidth,
475
  num viewportY,
476
  num viewportHeight,
477
  num pickX,
478
  num pickY,
479
  Vector3 rayNear,
480
  Vector3 rayFar,
481
) {
482
  bool r;
483

NEW
484
  r = unproject(
×
485
    cameraMatrix,
486
    viewportX,
487
    viewportWidth,
488
    viewportY,
489
    viewportHeight,
490
    pickX,
NEW
491
    viewportHeight - pickY,
×
492
    0.0,
493
    rayNear,
494
  );
495
  if (!r) {
496
    return false;
497
  }
498

NEW
499
  return unproject(
×
500
    cameraMatrix,
501
    viewportX,
502
    viewportWidth,
503
    viewportY,
504
    viewportHeight,
505
    pickX,
NEW
506
    viewportHeight - pickY,
×
507
    1.0,
508
    rayFar,
509
  );
510
}
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