@lakuna/umath 1.3.8 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (163) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +2 -0
  3. package/dist/algorithms/approx.d.ts +9 -0
  4. package/dist/algorithms/approx.d.ts.map +1 -0
  5. package/dist/algorithms/approx.js +12 -0
  6. package/dist/algorithms/approx.js.map +1 -0
  7. package/dist/algorithms/approxRelative.d.ts +9 -0
  8. package/dist/algorithms/approxRelative.d.ts.map +1 -0
  9. package/dist/algorithms/approxRelative.js +12 -0
  10. package/dist/algorithms/approxRelative.js.map +1 -0
  11. package/dist/algorithms/combinations.d.ts +2 -1
  12. package/dist/algorithms/combinations.d.ts.map +1 -1
  13. package/dist/algorithms/combinations.js +2 -1
  14. package/dist/algorithms/combinations.js.map +1 -1
  15. package/dist/algorithms/degreesToRadians.d.ts +3 -2
  16. package/dist/algorithms/degreesToRadians.d.ts.map +1 -1
  17. package/dist/algorithms/degreesToRadians.js +5 -3
  18. package/dist/algorithms/degreesToRadians.js.map +1 -1
  19. package/dist/algorithms/factorial.d.ts +2 -1
  20. package/dist/algorithms/factorial.d.ts.map +1 -1
  21. package/dist/algorithms/factorial.js +2 -1
  22. package/dist/algorithms/factorial.js.map +1 -1
  23. package/dist/algorithms/fibonacci.d.ts +2 -1
  24. package/dist/algorithms/fibonacci.d.ts.map +1 -1
  25. package/dist/algorithms/fibonacci.js +6 -2
  26. package/dist/algorithms/fibonacci.js.map +1 -1
  27. package/dist/algorithms/greatestCommonDivisor.d.ts +4 -2
  28. package/dist/algorithms/greatestCommonDivisor.d.ts.map +1 -1
  29. package/dist/algorithms/greatestCommonDivisor.js +5 -2
  30. package/dist/algorithms/greatestCommonDivisor.js.map +1 -1
  31. package/dist/algorithms/hypergeometricPmf.d.ts +3 -2
  32. package/dist/algorithms/hypergeometricPmf.d.ts.map +1 -1
  33. package/dist/algorithms/hypergeometricPmf.js +3 -2
  34. package/dist/algorithms/hypergeometricPmf.js.map +1 -1
  35. package/dist/algorithms/isPrime.d.ts +2 -1
  36. package/dist/algorithms/isPrime.d.ts.map +1 -1
  37. package/dist/algorithms/isPrime.js +2 -1
  38. package/dist/algorithms/isPrime.js.map +1 -1
  39. package/dist/algorithms/permutations.d.ts +2 -1
  40. package/dist/algorithms/permutations.d.ts.map +1 -1
  41. package/dist/algorithms/permutations.js +2 -1
  42. package/dist/algorithms/permutations.js.map +1 -1
  43. package/dist/algorithms/primeFactorization.d.ts +2 -1
  44. package/dist/algorithms/primeFactorization.d.ts.map +1 -1
  45. package/dist/algorithms/primeFactorization.js +4 -4
  46. package/dist/algorithms/primeFactorization.js.map +1 -1
  47. package/dist/algorithms/radiansToDegrees.d.ts +3 -2
  48. package/dist/algorithms/radiansToDegrees.d.ts.map +1 -1
  49. package/dist/algorithms/radiansToDegrees.js +5 -3
  50. package/dist/algorithms/radiansToDegrees.js.map +1 -1
  51. package/dist/algorithms/summation.d.ts +2 -1
  52. package/dist/algorithms/summation.d.ts.map +1 -1
  53. package/dist/algorithms/summation.js +2 -1
  54. package/dist/algorithms/summation.js.map +1 -1
  55. package/dist/linalg/DualQuaternion.d.ts +102 -32
  56. package/dist/linalg/DualQuaternion.d.ts.map +1 -1
  57. package/dist/linalg/DualQuaternion.js +249 -275
  58. package/dist/linalg/DualQuaternion.js.map +1 -1
  59. package/dist/linalg/Matrix.d.ts +14 -10
  60. package/dist/linalg/Matrix.d.ts.map +1 -1
  61. package/dist/linalg/Matrix2.d.ts +74 -51
  62. package/dist/linalg/Matrix2.d.ts.map +1 -1
  63. package/dist/linalg/Matrix2.js +96 -169
  64. package/dist/linalg/Matrix2.js.map +1 -1
  65. package/dist/linalg/Matrix3.d.ts +122 -72
  66. package/dist/linalg/Matrix3.d.ts.map +1 -1
  67. package/dist/linalg/Matrix3.js +205 -358
  68. package/dist/linalg/Matrix3.js.map +1 -1
  69. package/dist/linalg/Matrix4.d.ts +267 -150
  70. package/dist/linalg/Matrix4.d.ts.map +1 -1
  71. package/dist/linalg/Matrix4.js +553 -864
  72. package/dist/linalg/Matrix4.js.map +1 -1
  73. package/dist/linalg/Quaternion.d.ts +252 -34
  74. package/dist/linalg/Quaternion.d.ts.map +1 -1
  75. package/dist/linalg/Quaternion.js +436 -166
  76. package/dist/linalg/Quaternion.js.map +1 -1
  77. package/dist/linalg/SlowMatrix.d.ts +10 -9
  78. package/dist/linalg/SlowMatrix.d.ts.map +1 -1
  79. package/dist/linalg/SlowMatrix.js +10 -9
  80. package/dist/linalg/SlowMatrix.js.map +1 -1
  81. package/dist/linalg/SlowSquareMatrix.d.ts +10 -9
  82. package/dist/linalg/SlowSquareMatrix.d.ts.map +1 -1
  83. package/dist/linalg/SlowSquareMatrix.js +10 -9
  84. package/dist/linalg/SlowSquareMatrix.js.map +1 -1
  85. package/dist/linalg/SquareMatrix.d.ts +6 -5
  86. package/dist/linalg/SquareMatrix.d.ts.map +1 -1
  87. package/dist/linalg/Vector.d.ts +8 -4
  88. package/dist/linalg/Vector.d.ts.map +1 -1
  89. package/dist/linalg/Vector2.d.ts +82 -31
  90. package/dist/linalg/Vector2.d.ts.map +1 -1
  91. package/dist/linalg/Vector2.js +112 -154
  92. package/dist/linalg/Vector2.js.map +1 -1
  93. package/dist/linalg/Vector3.d.ts +93 -41
  94. package/dist/linalg/Vector3.d.ts.map +1 -1
  95. package/dist/linalg/Vector3.js +171 -282
  96. package/dist/linalg/Vector3.js.map +1 -1
  97. package/dist/linalg/Vector4.d.ts +71 -21
  98. package/dist/linalg/Vector4.d.ts.map +1 -1
  99. package/dist/linalg/Vector4.js +121 -195
  100. package/dist/linalg/Vector4.js.map +1 -1
  101. package/dist/types/AxisAngle.d.ts +4 -1
  102. package/dist/types/AxisAngle.d.ts.map +1 -1
  103. package/dist/types/FieldOfView.d.ts +4 -1
  104. package/dist/types/FieldOfView.d.ts.map +1 -1
  105. package/dist/utility/BigNumber.d.ts +4 -1
  106. package/dist/utility/BigNumber.d.ts.map +1 -1
  107. package/dist/utility/BigNumber.js +4 -1
  108. package/dist/utility/BigNumber.js.map +1 -1
  109. package/dist/utility/MagnitudeError.d.ts +4 -1
  110. package/dist/utility/MagnitudeError.d.ts.map +1 -1
  111. package/dist/utility/MagnitudeError.js +4 -1
  112. package/dist/utility/MagnitudeError.js.map +1 -1
  113. package/dist/utility/MatrixSizeError.d.ts +4 -1
  114. package/dist/utility/MatrixSizeError.d.ts.map +1 -1
  115. package/dist/utility/MatrixSizeError.js +4 -1
  116. package/dist/utility/MatrixSizeError.js.map +1 -1
  117. package/dist/utility/PartialMatrixError.d.ts +4 -1
  118. package/dist/utility/PartialMatrixError.d.ts.map +1 -1
  119. package/dist/utility/PartialMatrixError.js +4 -1
  120. package/dist/utility/PartialMatrixError.js.map +1 -1
  121. package/dist/utility/SingularMatrixError.d.ts +2 -1
  122. package/dist/utility/SingularMatrixError.d.ts.map +1 -1
  123. package/dist/utility/SingularMatrixError.js +2 -1
  124. package/dist/utility/SingularMatrixError.js.map +1 -1
  125. package/dist/utility/epsilon.d.ts +4 -1
  126. package/dist/utility/epsilon.d.ts.map +1 -1
  127. package/dist/utility/epsilon.js +4 -1
  128. package/dist/utility/epsilon.js.map +1 -1
  129. package/package.json +14 -18
  130. package/src/algorithms/approx.ts +12 -0
  131. package/src/algorithms/approxRelative.ts +12 -0
  132. package/src/algorithms/combinations.ts +2 -1
  133. package/src/algorithms/degreesToRadians.ts +6 -3
  134. package/src/algorithms/factorial.ts +3 -1
  135. package/src/algorithms/fibonacci.ts +7 -2
  136. package/src/algorithms/greatestCommonDivisor.ts +9 -4
  137. package/src/algorithms/hypergeometricPmf.ts +3 -2
  138. package/src/algorithms/isPrime.ts +2 -1
  139. package/src/algorithms/permutations.ts +2 -1
  140. package/src/algorithms/primeFactorization.ts +5 -3
  141. package/src/algorithms/radiansToDegrees.ts +6 -3
  142. package/src/algorithms/summation.ts +2 -1
  143. package/src/linalg/DualQuaternion.ts +430 -292
  144. package/src/linalg/Matrix.ts +14 -10
  145. package/src/linalg/Matrix2.ts +143 -185
  146. package/src/linalg/Matrix3.ts +421 -385
  147. package/src/linalg/Matrix4.ts +1147 -952
  148. package/src/linalg/Quaternion.ts +706 -188
  149. package/src/linalg/SlowMatrix.ts +10 -9
  150. package/src/linalg/SlowSquareMatrix.ts +10 -9
  151. package/src/linalg/SquareMatrix.ts +6 -5
  152. package/src/linalg/Vector.ts +8 -4
  153. package/src/linalg/Vector2.ts +146 -173
  154. package/src/linalg/Vector3.ts +293 -326
  155. package/src/linalg/Vector4.ts +227 -215
  156. package/src/types/AxisAngle.ts +4 -1
  157. package/src/types/FieldOfView.ts +4 -1
  158. package/src/utility/BigNumber.ts +6 -3
  159. package/src/utility/MagnitudeError.ts +4 -1
  160. package/src/utility/MatrixSizeError.ts +4 -1
  161. package/src/utility/PartialMatrixError.ts +4 -1
  162. package/src/utility/SingularMatrixError.ts +2 -1
  163. package/src/utility/epsilon.ts +4 -1
@@ -1,16 +1,27 @@
1
- import Quaternion, { type QuaternionLike } from "./Quaternion.js";
2
- import Vector3, { type Vector3Like, createVector3Like } from "./Vector3.js";
1
+ import Quaternion, {
2
+ type QuaternionLike,
3
+ fromValues as quaternionFromValues
4
+ } from "./Quaternion.js";
5
+ import Vector3, {
6
+ type Vector3Like,
7
+ createVector3Like,
8
+ fromValues as vector3FromValues
9
+ } from "./Vector3.js";
3
10
  import type { DualQuaternionLike } from "./DualQuaternion.js";
4
11
  import type FieldOfView from "../types/FieldOfView.js";
5
12
  import MagnitudeError from "../utility/MagnitudeError.js";
6
13
  import type { MatrixLike } from "./Matrix.js";
7
14
  import SingularMatrixError from "../utility/SingularMatrixError.js";
8
15
  import type SquareMatrix from "./SquareMatrix.js";
16
+ import approx from "../algorithms/approx.js";
17
+ import approxRelative from "../algorithms/approxRelative.js";
18
+ import degreesToRadians from "../algorithms/degreesToRadians.js";
9
19
  import epsilon from "../utility/epsilon.js";
10
20
 
11
21
  /**
12
22
  * Numbers arranged into four columns and four rows.
13
- * @see [Matrix](https://en.wikipedia.org/wiki/Matrix_(mathematics))
23
+ * @see {@link https://en.wikipedia.org/wiki/Matrix_(mathematics) | Matrix}
24
+ * @public
14
25
  */
15
26
  export interface Matrix4Like extends MatrixLike {
16
27
  /** The value in the first column and first row. */
@@ -63,109 +74,159 @@ export interface Matrix4Like extends MatrixLike {
63
74
  }
64
75
 
65
76
  /**
66
- * Create a 4x4 matrix-like object.
67
- * @returns A 4x4 matrix-like object.
77
+ * Create a four-by-four matrix-like object.
78
+ * @returns A four-by-four matrix-like object.
79
+ * @public
68
80
  */
69
- export const createMatrix4Like = () => {
81
+ export const createMatrix4Like = (): Float32Array & Matrix4Like => {
70
82
  return new Float32Array(16) as Float32Array & Matrix4Like;
71
83
  };
72
84
 
73
85
  /**
74
- * Create a transformation matrix that represents a translation by the given vector.
86
+ * Create a four-by-four matrix with the given values.
87
+ * @param c0r0 - The value in the first column and first row.
88
+ * @param c0r1 - The value in the first column and second row.
89
+ * @param c0r2 - The value in the first column and third row.
90
+ * @param c0r3 - The value in the first column and fourth row.
91
+ * @param c1r0 - The value in the second column and first row.
92
+ * @param c1r1 - The value in the second column and second row.
93
+ * @param c1r2 - The value in the second column and third row.
94
+ * @param c1r3 - The value in the second column and fourth row.
95
+ * @param c2r0 - The value in the third column and first row.
96
+ * @param c2r1 - The value in the third column and second row.
97
+ * @param c2r2 - The value in the third column and third row.
98
+ * @param c2r3 - The value in the third column and fourth row.
99
+ * @param c3r0 - The value in the fourth column and first row.
100
+ * @param c3r1 - The value in the fourth column and second row.
101
+ * @param c3r2 - The value in the fourth column and third row.
102
+ * @param c3r3 - The value in the fourth column and fourth row.
103
+ * @param out - The matrix to store the result in.
104
+ * @returns The matrix.
105
+ * @public
106
+ */
107
+ export const fromValues = <T extends Matrix4Like>(
108
+ c0r0: number,
109
+ c0r1: number,
110
+ c0r2: number,
111
+ c0r3: number,
112
+ c1r0: number,
113
+ c1r1: number,
114
+ c1r2: number,
115
+ c1r3: number,
116
+ c2r0: number,
117
+ c2r1: number,
118
+ c2r2: number,
119
+ c2r3: number,
120
+ c3r0: number,
121
+ c3r1: number,
122
+ c3r2: number,
123
+ c3r3: number,
124
+ out: T
125
+ ): T => {
126
+ out[0] = c0r0;
127
+ out[1] = c0r1;
128
+ out[2] = c0r2;
129
+ out[3] = c0r3;
130
+ out[4] = c1r0;
131
+ out[5] = c1r1;
132
+ out[6] = c1r2;
133
+ out[7] = c1r3;
134
+ out[8] = c2r0;
135
+ out[9] = c2r1;
136
+ out[10] = c2r2;
137
+ out[11] = c2r3;
138
+ out[12] = c3r0;
139
+ out[13] = c3r1;
140
+ out[14] = c3r2;
141
+ out[15] = c3r3;
142
+ return out;
143
+ };
144
+
145
+ /**
146
+ * Create a transformation matrix that represents a translation by the given vector. Equivalent to (but faster than) `translate(identity(out), vector, out)`.
75
147
  * @param vector - The translation vector.
76
148
  * @param out - The matrix to store the result in.
77
149
  * @returns The transformation matrix.
78
- * @see [Transformation matrix](https://en.wikipedia.org/wiki/Transformation_matrix)
150
+ * @see {@link https://en.wikipedia.org/wiki/Transformation_matrix | Transformation matrix}
151
+ * @public
79
152
  */
80
153
  export const fromTranslation = <T extends Matrix4Like>(
81
154
  vector: Vector3Like,
82
155
  out: T
83
- ): T => {
84
- out[0] = 1;
85
- out[1] = 0;
86
- out[2] = 0;
87
- out[3] = 0;
88
- out[4] = 0;
89
- out[5] = 1;
90
- out[6] = 0;
91
- out[7] = 0;
92
- out[8] = 0;
93
- out[9] = 0;
94
- out[10] = 1;
95
- out[11] = 0;
96
- out[12] = vector[0];
97
- out[13] = vector[1];
98
- out[14] = vector[2];
99
- out[15] = 1;
100
- return out;
101
- };
156
+ ): T =>
157
+ fromValues(
158
+ 1,
159
+ 0,
160
+ 0,
161
+ 0,
162
+ 0,
163
+ 1,
164
+ 0,
165
+ 0,
166
+ 0,
167
+ 0,
168
+ 1,
169
+ 0,
170
+ vector[0],
171
+ vector[1],
172
+ vector[2],
173
+ 1,
174
+ out
175
+ );
102
176
 
103
177
  /**
104
- * Create a transformation matrix that represents a scaling by the given vector.
178
+ * Create a transformation matrix that represents a scaling by the given vector. This is equivalent to (but faster than) `scale(identity(out), vector, out)`.
105
179
  * @param vector - The scaling vector.
106
180
  * @param out - The matrix to store the result in.
107
181
  * @returns The transformation matrix.
108
- * @see [Transformation matrix](https://en.wikipedia.org/wiki/Transformation_matrix)
182
+ * @see {@link https://en.wikipedia.org/wiki/Transformation_matrix | Transformation matrix}
183
+ * @public
109
184
  */
110
185
  export const fromScaling = <T extends Matrix4Like>(
111
186
  vector: Vector3Like,
112
187
  out: T
113
- ): T => {
114
- out[0] = vector[0];
115
- out[1] = 0;
116
- out[2] = 0;
117
- out[3] = 0;
118
- out[4] = 0;
119
- out[5] = vector[1];
120
- out[6] = 0;
121
- out[7] = 0;
122
- out[8] = 0;
123
- out[9] = 0;
124
- out[10] = vector[2];
125
- out[11] = 0;
126
- out[12] = 0;
127
- out[13] = 0;
128
- out[14] = 0;
129
- out[15] = 1;
130
- return out;
131
- };
188
+ ): T =>
189
+ fromValues(
190
+ vector[0],
191
+ 0,
192
+ 0,
193
+ 0,
194
+ 0,
195
+ vector[1],
196
+ 0,
197
+ 0,
198
+ 0,
199
+ 0,
200
+ vector[2],
201
+ 0,
202
+ 0,
203
+ 0,
204
+ 0,
205
+ 1,
206
+ out
207
+ );
132
208
 
133
209
  /**
134
210
  * Reset a matrix to identity.
135
211
  * @param out - The matrix to store the result in.
136
212
  * @returns The matrix.
137
- * @see [Identity matrix](https://en.wikipedia.org/wiki/Identity_matrix)
213
+ * @see {@link https://en.wikipedia.org/wiki/Identity_matrix | Identity matrix}
214
+ * @public
138
215
  */
139
- export const identity = <T extends Matrix4Like>(out: T): T => {
140
- out[0] = 1;
141
- out[1] = 0;
142
- out[2] = 0;
143
- out[3] = 0;
144
- out[4] = 0;
145
- out[5] = 1;
146
- out[6] = 0;
147
- out[7] = 0;
148
- out[8] = 0;
149
- out[9] = 0;
150
- out[10] = 1;
151
- out[11] = 0;
152
- out[12] = 0;
153
- out[13] = 0;
154
- out[14] = 0;
155
- out[15] = 1;
156
- return out;
157
- };
216
+ export const identity = <T extends Matrix4Like>(out: T): T =>
217
+ fromValues(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, out);
158
218
 
159
219
  /**
160
- * Create a transformation matrix that represents a rotation by the given angle around the Z-axis.
161
- * @param r - The angle in radians.
220
+ * Create a transformation matrix that represents a rotation by the given angle around the given axis. This is equivalent to (but faster than) `rotate(identity(out), radians, axis, out)`.
221
+ * @param radians - The angle in radians.
162
222
  * @param axis - The axis to rotate around.
163
223
  * @param out - The matrix to store the result in.
164
224
  * @returns The transformation matrix.
165
- * @see [Rotation matrix](https://en.wikipedia.org/wiki/Rotation_matrix)
225
+ * @see {@link https://en.wikipedia.org/wiki/Rotation_matrix | Rotation matrix}
226
+ * @public
166
227
  */
167
228
  export const fromRotation = <T extends Matrix4Like>(
168
- r: number,
229
+ radians: number,
169
230
  axis: Vector3Like,
170
231
  out: T
171
232
  ): T => {
@@ -173,7 +234,7 @@ export const fromRotation = <T extends Matrix4Like>(
173
234
  let y = axis[1];
174
235
  let z = axis[2];
175
236
 
176
- let len = Math.hypot(x, y, z);
237
+ let len = Math.sqrt(x * x + y * y + z * z);
177
238
  if (len === 0) {
178
239
  throw new MagnitudeError();
179
240
  }
@@ -183,128 +244,95 @@ export const fromRotation = <T extends Matrix4Like>(
183
244
  y *= len;
184
245
  z *= len;
185
246
 
186
- const s = Math.sin(r);
187
- const c = Math.cos(r);
247
+ const s = Math.sin(radians);
248
+ const c = Math.cos(radians);
188
249
  const t = 1 - c;
189
250
 
190
- out[0] = x * x * t + c;
191
- out[1] = y * x * t + z * s;
192
- out[2] = z * x * t - y * s;
193
- out[3] = 0;
194
- out[4] = x * y * t - z * s;
195
- out[5] = y * y * t + c;
196
- out[6] = z * y * t + x * s;
197
- out[7] = 0;
198
- out[8] = x * z * t + y * s;
199
- out[9] = y * z * t - x * s;
200
- out[10] = z * z * t + c;
201
- out[11] = 0;
202
- out[12] = 0;
203
- out[13] = 0;
204
- out[14] = 0;
205
- out[15] = 1;
206
- return out;
251
+ return fromValues(
252
+ x * x * t + c,
253
+ y * x * t + z * s,
254
+ z * x * t - y * s,
255
+ 0,
256
+ x * y * t - z * s,
257
+ y * y * t + c,
258
+ z * y * t + x * s,
259
+ 0,
260
+ x * z * t + y * s,
261
+ y * z * t - x * s,
262
+ z * z * t + c,
263
+ 0,
264
+ 0,
265
+ 0,
266
+ 0,
267
+ 1,
268
+ out
269
+ );
207
270
  };
208
271
 
209
272
  /**
210
- * Create a transformation matrix that represents a rotation by the given angle around the X-axis.
211
- * @param r - The angle in radians.
273
+ * Create a transformation matrix that represents a rotation by the given angle around the X-axis. This is equivalent to (but faster than) `rotateX(identity(out), radians, out)`.
274
+ * @param radians - The angle in radians.
212
275
  * @param out - The matrix to store the result in.
213
276
  * @returns The transformation matrix.
214
- * @see [Rotation matrix](https://en.wikipedia.org/wiki/Rotation_matrix)
277
+ * @see {@link https://en.wikipedia.org/wiki/Rotation_matrix | Rotation matrix}
278
+ * @public
215
279
  */
216
- export const fromXRotation = <T extends Matrix4Like>(r: number, out: T): T => {
217
- const s = Math.sin(r);
218
- const c = Math.cos(r);
280
+ export const fromXRotation = <T extends Matrix4Like>(
281
+ radians: number,
282
+ out: T
283
+ ): T => {
284
+ const s = Math.sin(radians);
285
+ const c = Math.cos(radians);
219
286
 
220
- out[0] = 1;
221
- out[1] = 0;
222
- out[2] = 0;
223
- out[3] = 0;
224
- out[4] = 0;
225
- out[5] = c;
226
- out[6] = s;
227
- out[7] = 0;
228
- out[8] = 0;
229
- out[9] = -s;
230
- out[10] = c;
231
- out[11] = 0;
232
- out[12] = 0;
233
- out[13] = 0;
234
- out[14] = 0;
235
- out[15] = 1;
236
- return out;
287
+ return fromValues(1, 0, 0, 0, 0, c, s, 0, 0, -s, c, 0, 0, 0, 0, 1, out);
237
288
  };
238
289
 
239
290
  /**
240
- * Create a transformation matrix that represents a rotation by the given angle around the Y-axis.
241
- * @param r - The angle in radians.
291
+ * Create a transformation matrix that represents a rotation by the given angle around the Y-axis. This is equivalent to (but faster than) `rotateY(identity(out), radians, out)`.
292
+ * @param radians - The angle in radians.
242
293
  * @param out - The matrix to store the result in.
243
294
  * @returns The transformation matrix.
244
- * @see [Rotation matrix](https://en.wikipedia.org/wiki/Rotation_matrix)
295
+ * @see {@link https://en.wikipedia.org/wiki/Rotation_matrix | Rotation matrix}
296
+ * @public
245
297
  */
246
- export const fromYRotation = <T extends Matrix4Like>(r: number, out: T): T => {
247
- const s = Math.sin(r);
248
- const c = Math.cos(r);
298
+ export const fromYRotation = <T extends Matrix4Like>(
299
+ radians: number,
300
+ out: T
301
+ ): T => {
302
+ const s = Math.sin(radians);
303
+ const c = Math.cos(radians);
249
304
 
250
- out[0] = c;
251
- out[1] = 0;
252
- out[2] = -s;
253
- out[3] = 0;
254
- out[4] = 0;
255
- out[5] = 1;
256
- out[6] = 0;
257
- out[7] = 0;
258
- out[8] = s;
259
- out[9] = 0;
260
- out[10] = c;
261
- out[11] = 0;
262
- out[12] = 0;
263
- out[13] = 0;
264
- out[14] = 0;
265
- out[15] = 1;
266
- return out;
305
+ return fromValues(c, 0, -s, 0, 0, 1, 0, 0, s, 0, c, 0, 0, 0, 0, 1, out);
267
306
  };
268
307
 
269
308
  /**
270
- * Create a transformation matrix that represents a rotation by the given angle around the Z-axis.
271
- * @param r - The angle in radians.
309
+ * Create a transformation matrix that represents a rotation by the given angle around the Z-axis. This is equivalent to (but faster than) `rotateZ(identity(out), radians, out)`.
310
+ * @param radians - The angle in radians.
272
311
  * @param out - The matrix to store the result in.
273
312
  * @returns The transformation matrix.
274
- * @see [Rotation matrix](https://en.wikipedia.org/wiki/Rotation_matrix)
313
+ * @see {@link https://en.wikipedia.org/wiki/Rotation_matrix | Rotation matrix}
314
+ * @public
275
315
  */
276
- export const fromZRotation = <T extends Matrix4Like>(r: number, out: T): T => {
277
- const s = Math.sin(r);
278
- const c = Math.cos(r);
316
+ export const fromZRotation = <T extends Matrix4Like>(
317
+ radians: number,
318
+ out: T
319
+ ): T => {
320
+ const s = Math.sin(radians);
321
+ const c = Math.cos(radians);
279
322
 
280
- out[0] = c;
281
- out[1] = s;
282
- out[2] = 0;
283
- out[3] = 0;
284
- out[4] = -s;
285
- out[5] = c;
286
- out[6] = 0;
287
- out[7] = 0;
288
- out[8] = 0;
289
- out[9] = 0;
290
- out[10] = 1;
291
- out[11] = 0;
292
- out[12] = 0;
293
- out[13] = 0;
294
- out[14] = 0;
295
- out[15] = 1;
296
- return out;
323
+ return fromValues(c, s, 0, 0, -s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, out);
297
324
  };
298
325
 
299
326
  /**
300
- * Create a transformation matrix from the given rotation and translation.
327
+ * Create a transformation matrix from the given rotation and translation. This is equivalent to (but faster than) `multiply(translate(identity(out), translation, out), fromQuaternion(rotation, createMatrix4Like()), out)`.
301
328
  * @param rotation - The rotation quaternion.
302
329
  * @param translation - The translation vector.
303
330
  * @param out - The matrix to store the result in.
304
331
  * @returns The transformation matrix.
305
- * @see [Quaternion](https://en.wikipedia.org/wiki/Quaternion)
306
- * @see [Rotation matrix](https://en.wikipedia.org/wiki/Rotation_matrix)
307
- * @see [Transformation matrix](https://en.wikipedia.org/wiki/Transformation_matrix)
332
+ * @see {@link https://en.wikipedia.org/wiki/Quaternion | Quaternion}
333
+ * @see {@link https://en.wikipedia.org/wiki/Rotation_matrix | Rotation matrix}
334
+ * @see {@link https://en.wikipedia.org/wiki/Transformation_matrix | Transformation matrix}
335
+ * @public
308
336
  */
309
337
  export const fromRotationTranslation = <T extends Matrix4Like>(
310
338
  rotation: QuaternionLike,
@@ -329,35 +357,38 @@ export const fromRotationTranslation = <T extends Matrix4Like>(
329
357
  const wy = w * y2;
330
358
  const wz = w * z2;
331
359
 
332
- out[0] = 1 - (yy + zz);
333
- out[1] = xy + wz;
334
- out[2] = xz - wy;
335
- out[3] = 0;
336
- out[4] = xy - wz;
337
- out[5] = 1 - (xx + zz);
338
- out[6] = yz + wx;
339
- out[7] = 0;
340
- out[8] = xz + wy;
341
- out[9] = yz - wx;
342
- out[10] = 1 - (xx + yy);
343
- out[11] = 0;
344
- out[12] = translation[0];
345
- out[13] = translation[1];
346
- out[14] = translation[2];
347
- out[15] = 1;
348
- return out;
360
+ return fromValues(
361
+ 1 - (yy + zz),
362
+ xy + wz,
363
+ xz - wy,
364
+ 0,
365
+ xy - wz,
366
+ 1 - (xx + zz),
367
+ yz + wx,
368
+ 0,
369
+ xz + wy,
370
+ yz - wx,
371
+ 1 - (xx + yy),
372
+ 0,
373
+ translation[0],
374
+ translation[1],
375
+ translation[2],
376
+ 1,
377
+ out
378
+ );
349
379
  };
350
380
 
351
381
  /**
352
- * Create a transformation matrix from the given rotation, translation, and scale.
382
+ * Create a transformation matrix from the given rotation, translation, and scale. This is equivalent to (but faster than) `scale(multiply(translate(identity(out), translation, out), fromQuaternion(rotation, createMatrix4Like()), out), scaling, out)`.
353
383
  * @param rotation - The rotation quaternion.
354
384
  * @param translation - The translation vector.
355
385
  * @param scaling - The scaling vector.
356
386
  * @param out - The matrix to store the result in.
357
387
  * @returns The transformation matrix.
358
- * @see [Quaternion](https://en.wikipedia.org/wiki/Quaternion)
359
- * @see [Rotation matrix](https://en.wikipedia.org/wiki/Rotation_matrix)
360
- * @see [Transformation matrix](https://en.wikipedia.org/wiki/Transformation_matrix)
388
+ * @see {@link https://en.wikipedia.org/wiki/Quaternion | Quaternion}
389
+ * @see {@link https://en.wikipedia.org/wiki/Rotation_matrix | Rotation matrix}
390
+ * @see {@link https://en.wikipedia.org/wiki/Transformation_matrix | Transformation matrix}
391
+ * @public
361
392
  */
362
393
  export const fromRotationTranslationScale = <T extends Matrix4Like>(
363
394
  rotation: QuaternionLike,
@@ -387,36 +418,39 @@ export const fromRotationTranslationScale = <T extends Matrix4Like>(
387
418
  const sy = scaling[1];
388
419
  const sz = scaling[2];
389
420
 
390
- out[0] = (1 - (yy + zz)) * sx;
391
- out[1] = (xy + wz) * sx;
392
- out[2] = (xz - wy) * sx;
393
- out[3] = 0;
394
- out[4] = (xy - wz) * sy;
395
- out[5] = (1 - (xx + zz)) * sy;
396
- out[6] = (yz + wx) * sy;
397
- out[7] = 0;
398
- out[8] = (xz + wy) * sz;
399
- out[9] = (yz - wx) * sz;
400
- out[10] = (1 - (xx + yy)) * sz;
401
- out[11] = 0;
402
- out[12] = translation[0];
403
- out[13] = translation[1];
404
- out[14] = translation[2];
405
- out[15] = 1;
406
- return out;
421
+ return fromValues(
422
+ (1 - (yy + zz)) * sx,
423
+ (xy + wz) * sx,
424
+ (xz - wy) * sx,
425
+ 0,
426
+ (xy - wz) * sy,
427
+ (1 - (xx + zz)) * sy,
428
+ (yz + wx) * sy,
429
+ 0,
430
+ (xz + wy) * sz,
431
+ (yz - wx) * sz,
432
+ (1 - (xx + yy)) * sz,
433
+ 0,
434
+ translation[0],
435
+ translation[1],
436
+ translation[2],
437
+ 1,
438
+ out
439
+ );
407
440
  };
408
441
 
409
442
  /**
410
- * Create a transformation matrix from the given rotation, translation, and scale around the given origin.
443
+ * Create a transformation matrix from the given rotation, translation, and scale around the given origin. This is equivalent to (but faster than) `translate(scale(multiply(translate(translate(identity(out), translation, out), origin, out), fromQuaternion(rotation, createMatrix4Like()), out), scaling, out), negate(origin), out)`.
411
444
  * @param rotation - The rotation quaternion.
412
445
  * @param translation - The translation vector.
413
446
  * @param scaling - The scaling vector.
414
447
  * @param origin - The origin vector.
415
448
  * @param out - The matrix to store the result in.
416
449
  * @returns The transformation matrix.
417
- * @see [Quaternion](https://en.wikipedia.org/wiki/Quaternion)
418
- * @see [Rotation matrix](https://en.wikipedia.org/wiki/Rotation_matrix)
419
- * @see [Transformation matrix](https://en.wikipedia.org/wiki/Transformation_matrix)
450
+ * @see {@link https://en.wikipedia.org/wiki/Quaternion | Quaternion}
451
+ * @see {@link https://en.wikipedia.org/wiki/Rotation_matrix | Rotation matrix}
452
+ * @see {@link https://en.wikipedia.org/wiki/Transformation_matrix | Transformation matrix}
453
+ * @public
420
454
  */
421
455
  export const fromRotationTranslationScaleOrigin = <T extends Matrix4Like>(
422
456
  rotation: QuaternionLike,
@@ -450,46 +484,102 @@ export const fromRotationTranslationScaleOrigin = <T extends Matrix4Like>(
450
484
  const oy = origin[1];
451
485
  const oz = origin[2];
452
486
 
453
- const out0 = (1 - (yy + zz)) * sx;
454
- const out1 = (xy + wz) * sx;
455
- const out2 = (xz - wy) * sx;
456
- const out4 = (xy - wz) * sy;
457
- const out5 = (1 - (xx + zz)) * sy;
458
- const out6 = (yz + wx) * sy;
459
- const out8 = (xz + wy) * sz;
460
- const out9 = (yz - wx) * sz;
461
- const out10 = (1 - (xx + yy)) * sz;
462
-
463
- out[0] = out0;
464
- out[1] = out1;
465
- out[2] = out2;
466
- out[3] = 0;
467
- out[4] = out4;
468
- out[5] = out5;
469
- out[6] = out6;
470
- out[7] = 0;
471
- out[8] = out8;
472
- out[9] = out9;
473
- out[10] = out10;
474
- out[11] = 0;
475
- out[12] = translation[0] + ox - (out0 * ox + out4 * oy + out8 * oz);
476
- out[13] = translation[1] + oy - (out1 * ox + out5 * oy + out9 * oz);
477
- out[14] = translation[2] + oz - (out2 * ox + out6 * oy + out10 * oz);
478
- out[15] = 1;
479
- return out;
487
+ const o0 = (1 - (yy + zz)) * sx;
488
+ const o1 = (xy + wz) * sx;
489
+ const o2 = (xz - wy) * sx;
490
+ const o4 = (xy - wz) * sy;
491
+ const o5 = (1 - (xx + zz)) * sy;
492
+ const o6 = (yz + wx) * sy;
493
+ const o8 = (xz + wy) * sz;
494
+ const o9 = (yz - wx) * sz;
495
+ const o10 = (1 - (xx + yy)) * sz;
496
+
497
+ return fromValues(
498
+ o0,
499
+ o1,
500
+ o2,
501
+ 0,
502
+ o4,
503
+ o5,
504
+ o6,
505
+ 0,
506
+ o8,
507
+ o9,
508
+ o10,
509
+ 0,
510
+ translation[0] + ox - (o0 * ox + o4 * oy + o8 * oz),
511
+ translation[1] + oy - (o1 * ox + o5 * oy + o9 * oz),
512
+ translation[2] + oz - (o2 * ox + o6 * oy + o10 * oz),
513
+ 1,
514
+ out
515
+ );
516
+ };
517
+
518
+ /**
519
+ * Create a transformation matrix from a quaternion.
520
+ * @param quaternion - The quaternion.
521
+ * @param out - The matrix to store the result in.
522
+ * @returns The transformation matrix.
523
+ * @see {@link https://en.wikipedia.org/wiki/Rotation_matrix | Rotation matrix}
524
+ * @see {@link https://en.wikipedia.org/wiki/Transformation_matrix | Transformation matrix}
525
+ * @public
526
+ */
527
+ export const fromQuaternion = <T extends Matrix4Like>(
528
+ quaternion: QuaternionLike,
529
+ out: T
530
+ ): T => {
531
+ const x = quaternion[0];
532
+ const y = quaternion[1];
533
+ const z = quaternion[2];
534
+ const w = quaternion[3];
535
+
536
+ const x2 = x + x;
537
+ const y2 = y + y;
538
+ const z2 = z + z;
539
+
540
+ const xx = x * x2;
541
+ const yx = y * x2;
542
+ const yy = y * y2;
543
+ const zx = z * x2;
544
+ const zy = z * y2;
545
+ const zz = z * z2;
546
+ const wx = w * x2;
547
+ const wy = w * y2;
548
+ const wz = w * z2;
549
+
550
+ return fromValues(
551
+ 1 - yy - zz,
552
+ yx + wz,
553
+ zx - wy,
554
+ 0,
555
+ yx - wz,
556
+ 1 - xx - zz,
557
+ zy + wx,
558
+ 0,
559
+ zx + wy,
560
+ zy - wx,
561
+ 1 - xx - yy,
562
+ 0,
563
+ 0,
564
+ 0,
565
+ 0,
566
+ 1,
567
+ out
568
+ );
480
569
  };
481
570
 
482
571
  // Used to store intermediary values in some functions.
483
- const intermediary = createVector3Like();
572
+ const iv3 = createVector3Like();
484
573
 
485
574
  /**
486
575
  * Create a transformation matrix from a dual quaternion.
487
576
  * @param quaternion - The dual quaternion.
488
577
  * @param out - The matrix to store the result in.
489
578
  * @returns The transformation matrix.
490
- * @see [Dual quaternion](https://en.wikipedia.org/wiki/Dual_quaternion)
491
- * @see [Rotation matrix](https://en.wikipedia.org/wiki/Rotation_matrix)
492
- * @see [Transformation matrix](https://en.wikipedia.org/wiki/Transformation_matrix)
579
+ * @see {@link https://en.wikipedia.org/wiki/Dual_quaternion | Dual quaternion}
580
+ * @see {@link https://en.wikipedia.org/wiki/Rotation_matrix | Rotation matrix}
581
+ * @see {@link https://en.wikipedia.org/wiki/Transformation_matrix | Transformation matrix}
582
+ * @public
493
583
  */
494
584
  export const fromDualQuaternion = <T extends Matrix4Like>(
495
585
  quaternion: DualQuaternionLike,
@@ -505,17 +595,23 @@ export const fromDualQuaternion = <T extends Matrix4Like>(
505
595
  const aw = quaternion[7];
506
596
 
507
597
  const magnitude = bx * bx + by * by + bz * bz + bw * bw;
508
- if (magnitude > 0) {
509
- intermediary[0] = ((ax * bw + aw * bx + ay * bz - az * by) * 2) / magnitude;
510
- intermediary[1] = ((ay * bw + aw * by + az * bx - ax * bz) * 2) / magnitude;
511
- intermediary[2] = ((az * bw + aw * bz + ax * by - ay * bx) * 2) / magnitude;
512
- } else {
513
- intermediary[0] = (ax * bw + aw * bx + ay * bz - az * by) * 2;
514
- intermediary[1] = (ay * bw + aw * by + az * bx - ax * bz) * 2;
515
- intermediary[2] = (az * bw + aw * bz + ax * by - ay * bx) * 2;
516
- }
517
-
518
- return fromRotationTranslation(quaternion, intermediary, out);
598
+ return fromRotationTranslation(
599
+ quaternion,
600
+ magnitude > 0
601
+ ? vector3FromValues(
602
+ ((ax * bw + aw * bx + ay * bz - az * by) * 2) / magnitude,
603
+ ((ay * bw + aw * by + az * bx - ax * bz) * 2) / magnitude,
604
+ ((az * bw + aw * bz + ax * by - ay * bx) * 2) / magnitude,
605
+ iv3
606
+ )
607
+ : vector3FromValues(
608
+ (ax * bw + aw * bx + ay * bz - az * by) * 2,
609
+ (ay * bw + aw * by + az * bx - ax * bz) * 2,
610
+ (az * bw + aw * bz + ax * by - ay * bx) * 2,
611
+ iv3
612
+ ),
613
+ out
614
+ );
519
615
  };
520
616
 
521
617
  /**
@@ -528,8 +624,9 @@ export const fromDualQuaternion = <T extends Matrix4Like>(
528
624
  * @param far - The far bound of the frustum.
529
625
  * @param out - The matrix to store the result in.
530
626
  * @returns The frustum matrix.
531
- * @see [Camera matrix](https://en.wikipedia.org/wiki/Camera_matrix)
532
- * @see [3D projection](https://en.wikipedia.org/wiki/3D_projection)
627
+ * @see {@link https://en.wikipedia.org/wiki/Camera_matrix | Camera matrix}
628
+ * @see {@link https://en.wikipedia.org/wiki/3D_projection | 3D projection}
629
+ * @public
533
630
  */
534
631
  export const frustum = <T extends Matrix4Like>(
535
632
  left: number,
@@ -542,7 +639,6 @@ export const frustum = <T extends Matrix4Like>(
542
639
  ): T => {
543
640
  const rl = 1 / (right - left);
544
641
  const tb = 1 / (top - bottom);
545
- const nf = 1 / (near - far);
546
642
 
547
643
  out[0] = near * 2 * rl;
548
644
  out[1] = 0;
@@ -554,25 +650,34 @@ export const frustum = <T extends Matrix4Like>(
554
650
  out[7] = 0;
555
651
  out[8] = (right + left) * rl;
556
652
  out[9] = (top + bottom) * tb;
557
- out[10] = (far + near) * nf;
558
653
  out[11] = -1;
559
654
  out[12] = 0;
560
655
  out[13] = 0;
561
- out[14] = far * near * 2 * nf;
562
656
  out[15] = 0;
657
+
658
+ if (far === Infinity) {
659
+ out[10] = -1;
660
+ out[14] = -2 * near;
661
+ return out;
662
+ }
663
+
664
+ const nf = 1 / (near - far);
665
+ out[10] = (far + near) * nf;
666
+ out[14] = 2 * far * near * nf;
563
667
  return out;
564
668
  };
565
669
 
566
670
  /**
567
- * Create a perspective projection matrix with the given bounds.
671
+ * Create a perspective projection matrix with the given bounds such that the near and far clip planes correspond to a normalized device coordinate Z range of `[-1, 1]` (OpenGL/WebGL).
568
672
  * @param fov - The vertical field of view in radians.
569
673
  * @param aspect - The aspect ratio (typically the width of the viewport divided by its height).
570
- * @param near - The near bound of the frustum.
674
+ * @param near - The near bound of the frustum. Must be strictly positive.
571
675
  * @param far - The far bound of the frustum.
572
676
  * @param out - The matrix to store the result in.
573
677
  * @returns The perspective projection matrix.
574
- * @see [Camera matrix](https://en.wikipedia.org/wiki/Camera_matrix)
575
- * @see [3D projection](https://en.wikipedia.org/wiki/3D_projection)
678
+ * @see {@link https://en.wikipedia.org/wiki/Camera_matrix | Camera matrix}
679
+ * @see {@link https://en.wikipedia.org/wiki/3D_projection | 3D projection}
680
+ * @public
576
681
  */
577
682
  export const perspective = <T extends Matrix4Like>(
578
683
  fov: number,
@@ -601,60 +706,112 @@ export const perspective = <T extends Matrix4Like>(
601
706
  if (far === Infinity) {
602
707
  out[10] = -1;
603
708
  out[14] = -2 * near;
604
- } else {
605
- const nf = 1 / (near - far);
606
- out[10] = (far + near) * nf;
607
- out[14] = 2 * far * near * nf;
709
+ return out;
608
710
  }
609
711
 
712
+ const nf = 1 / (near - far);
713
+ out[10] = (far + near) * nf;
714
+ out[14] = 2 * far * near * nf;
610
715
  return out;
611
716
  };
612
717
 
613
718
  /**
614
- * Create a perspective projection matrix from a field of view. Useful for generating projection matrices to be used with the WebXR API.
615
- * @param fov - The field of view.
616
- * @param near - The near bound of the frustum.
719
+ * Create a perspective projection matrix with the given bounds such that the near and far clip planes correspond to a normalized device coordinate Z range of `[0, 1]` (WebGPU/Vulkan/DirectX/Metal).
720
+ * @param fov - The vertical field of view in radians.
721
+ * @param aspect - The aspect ratio (typically the width of the viewport divided by its height).
722
+ * @param near - The near bound of the frustum. Must be strictly positive.
617
723
  * @param far - The far bound of the frustum.
618
724
  * @param out - The matrix to store the result in.
619
725
  * @returns The perspective projection matrix.
620
- * @see [WebXR API](https://developer.mozilla.org/en-US/docs/Web/API/WebXR_Device_API)
621
- * @see [Camera matrix](https://en.wikipedia.org/wiki/Camera_matrix)
622
- * @see [3D projection](https://en.wikipedia.org/wiki/3D_projection)
726
+ * @see {@link https://en.wikipedia.org/wiki/Camera_matrix | Camera matrix}
727
+ * @see {@link https://en.wikipedia.org/wiki/3D_projection | 3D projection}
728
+ * @public
623
729
  */
624
- export const perspectiveFromFieldOfView = <T extends Matrix4Like>(
625
- fov: FieldOfView,
730
+ export const perspectiveGpu = <T extends Matrix4Like>(
731
+ fov: number,
732
+ aspect: number,
626
733
  near: number,
627
734
  far: number,
628
735
  out: T
629
736
  ): T => {
630
- const upTan = Math.tan((fov.upDegrees * Math.PI) / 180);
631
- const downTan = Math.tan((fov.downDegrees * Math.PI) / 180);
632
- const leftTan = Math.tan((fov.leftDegrees * Math.PI) / 180);
633
- const rightTan = Math.tan((fov.rightDegrees * Math.PI) / 180);
634
- const xScale = 2 / (leftTan + rightTan);
635
- const yScale = 2 / (upTan + downTan);
737
+ const f = 1 / Math.tan(fov / 2);
636
738
 
637
- out[0] = xScale;
739
+ out[0] = f / aspect;
638
740
  out[1] = 0;
639
741
  out[2] = 0;
640
742
  out[3] = 0;
641
743
  out[4] = 0;
642
- out[5] = yScale;
744
+ out[5] = f;
643
745
  out[6] = 0;
644
746
  out[7] = 0;
645
- out[8] = -((leftTan - rightTan) * xScale * 0.5);
646
- out[9] = (upTan - downTan) * yScale * 0.5;
647
- out[10] = far / (near - far);
747
+ out[8] = 0;
748
+ out[9] = 0;
648
749
  out[11] = -1;
649
750
  out[12] = 0;
650
751
  out[13] = 0;
651
- out[14] = (far * near) / (near - far);
652
752
  out[15] = 0;
753
+
754
+ if (far === Infinity) {
755
+ out[10] = -1;
756
+ out[14] = -near;
757
+ return out;
758
+ }
759
+
760
+ const fnf = far * (1 / (near - far));
761
+ out[10] = fnf;
762
+ out[14] = near * fnf;
653
763
  return out;
654
764
  };
655
765
 
656
766
  /**
657
- * Generate an orthogonal projection matrix with the given bounds.
767
+ * Create a perspective projection matrix from a field of view. Useful for generating projection matrices to be used with the WebXR API.
768
+ * @param fov - The field of view.
769
+ * @param near - The near bound of the frustum.
770
+ * @param far - The far bound of the frustum.
771
+ * @param out - The matrix to store the result in.
772
+ * @returns The perspective projection matrix.
773
+ * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/WebXR_Device_API | WebXR API}
774
+ * @see {@link https://en.wikipedia.org/wiki/Camera_matrix | Camera matrix}
775
+ * @see {@link https://en.wikipedia.org/wiki/3D_projection | 3D projection}
776
+ * @public
777
+ */
778
+ export const perspectiveFromFieldOfView = <T extends Matrix4Like>(
779
+ fov: FieldOfView,
780
+ near: number,
781
+ far: number,
782
+ out: T
783
+ ): T => {
784
+ const upTan = Math.tan(degreesToRadians(fov.upDegrees));
785
+ const downTan = Math.tan(degreesToRadians(fov.downDegrees));
786
+ const leftTan = Math.tan(degreesToRadians(fov.leftDegrees));
787
+ const rightTan = Math.tan(degreesToRadians(fov.rightDegrees));
788
+ const xScale = 2 / (leftTan + rightTan);
789
+ const yScale = 2 / (upTan + downTan);
790
+ const nf = near - far;
791
+
792
+ return fromValues(
793
+ xScale,
794
+ 0,
795
+ 0,
796
+ 0,
797
+ 0,
798
+ yScale,
799
+ 0,
800
+ 0,
801
+ -(((leftTan - rightTan) * xScale) / 2),
802
+ ((upTan - downTan) * yScale) / 2,
803
+ far / nf,
804
+ -1,
805
+ 0,
806
+ 0,
807
+ (far * near) / nf,
808
+ 0,
809
+ out
810
+ );
811
+ };
812
+
813
+ /**
814
+ * Generate an orthogonal projection matrix with the given bounds such that the near and far clip planes correspond to a normalized device coordinate Z range of `[-1, 1]` (OpenGL/WebGL).
658
815
  * @param left - The left bound of the frustum.
659
816
  * @param right - The right bound of the frustum.
660
817
  * @param bottom - The bottom bound of the frustum.
@@ -663,8 +820,9 @@ export const perspectiveFromFieldOfView = <T extends Matrix4Like>(
663
820
  * @param far - The far bound of the frustum.
664
821
  * @param out - The matrix to store the result in.
665
822
  * @returns The frustum matrix.
666
- * @see [Camera matrix](https://en.wikipedia.org/wiki/Camera_matrix)
667
- * @see [3D projection](https://en.wikipedia.org/wiki/3D_projection)
823
+ * @see {@link https://en.wikipedia.org/wiki/Camera_matrix | Camera matrix}
824
+ * @see {@link https://en.wikipedia.org/wiki/3D_projection | 3D projection}
825
+ * @public
668
826
  */
669
827
  export const ortho = <T extends Matrix4Like>(
670
828
  left: number,
@@ -679,23 +837,73 @@ export const ortho = <T extends Matrix4Like>(
679
837
  const bt = 1 / (bottom - top);
680
838
  const nf = 1 / (near - far);
681
839
 
682
- out[0] = -2 * lr;
683
- out[1] = 0;
684
- out[2] = 0;
685
- out[3] = 0;
686
- out[4] = 0;
687
- out[5] = -2 * bt;
688
- out[6] = 0;
689
- out[7] = 0;
690
- out[8] = 0;
691
- out[9] = 0;
692
- out[10] = 2 * nf;
693
- out[11] = 0;
694
- out[12] = (left + right) * lr;
695
- out[13] = (top + bottom) * bt;
696
- out[14] = (far + near) * nf;
697
- out[15] = 1;
698
- return out;
840
+ return fromValues(
841
+ -2 * lr,
842
+ 0,
843
+ 0,
844
+ 0,
845
+ 0,
846
+ -2 * bt,
847
+ 0,
848
+ 0,
849
+ 0,
850
+ 0,
851
+ 2 * nf,
852
+ 0,
853
+ (left + right) * lr,
854
+ (top + bottom) * bt,
855
+ (far + near) * nf,
856
+ 1,
857
+ out
858
+ );
859
+ };
860
+
861
+ /**
862
+ * Generate an orthogonal projection matrix with the given bounds such that the near and far clip planes correspond to a normalized device coordinate Z range of `[0, 1]` (WebGPU/Vulkan/DirectX/Metal).
863
+ * @param left - The left bound of the frustum.
864
+ * @param right - The right bound of the frustum.
865
+ * @param bottom - The bottom bound of the frustum.
866
+ * @param top - The top bound of the frustum.
867
+ * @param near - The near bound of the frustum.
868
+ * @param far - The far bound of the frustum.
869
+ * @param out - The matrix to store the result in.
870
+ * @returns The frustum matrix.
871
+ * @see {@link https://en.wikipedia.org/wiki/Camera_matrix | Camera matrix}
872
+ * @see {@link https://en.wikipedia.org/wiki/3D_projection | 3D projection}
873
+ * @public
874
+ */
875
+ export const orthoGpu = <T extends Matrix4Like>(
876
+ left: number,
877
+ right: number,
878
+ bottom: number,
879
+ top: number,
880
+ near: number,
881
+ far: number,
882
+ out: T
883
+ ): T => {
884
+ const lr = 1 / (left - right);
885
+ const bt = 1 / (bottom - top);
886
+ const nf = 1 / (near - far);
887
+
888
+ return fromValues(
889
+ -2 * lr,
890
+ 0,
891
+ 0,
892
+ 0,
893
+ 0,
894
+ -2 * bt,
895
+ 0,
896
+ 0,
897
+ 0,
898
+ 0,
899
+ nf,
900
+ 0,
901
+ (left + right) * lr,
902
+ (top + bottom) * bt,
903
+ near * nf,
904
+ 1,
905
+ out
906
+ );
699
907
  };
700
908
 
701
909
  /**
@@ -705,7 +913,8 @@ export const ortho = <T extends Matrix4Like>(
705
913
  * @param up - The local up direction.
706
914
  * @param out - The matrix to store the result in.
707
915
  * @returns The look-at matrix.
708
- * @see [Transformation matrix](https://en.wikipedia.org/wiki/Transformation_matrix)
916
+ * @see {@link https://en.wikipedia.org/wiki/Transformation_matrix | Transformation matrix}
917
+ * @public
709
918
  */
710
919
  export const lookAt = <T extends Matrix4Like>(
711
920
  eye: Vector3Like,
@@ -725,18 +934,14 @@ export const lookAt = <T extends Matrix4Like>(
725
934
  const centery = center[1];
726
935
  const centerz = center[2];
727
936
 
728
- if (
729
- Math.abs(eyex - centerx) < epsilon &&
730
- Math.abs(eyey - centery) < epsilon &&
731
- Math.abs(eyez - centerz) < epsilon
732
- ) {
937
+ if (approx(eyex, centerx) && approx(eyey, centery) && approx(eyez, centerz)) {
733
938
  return identity(out);
734
939
  }
735
940
 
736
941
  let z0 = eyex - centerx;
737
942
  let z1 = eyey - centery;
738
943
  let z2 = eyez - centerz;
739
- let len = 1 / Math.hypot(z0, z1, z2);
944
+ let len = 1 / Math.sqrt(z0 * z0 + z1 * z1 + z2 * z2); // `Math.hypot` is slower.
740
945
  z0 *= len;
741
946
  z1 *= len;
742
947
  z2 *= len;
@@ -744,8 +949,8 @@ export const lookAt = <T extends Matrix4Like>(
744
949
  let x0 = upy * z2 - upz * z1;
745
950
  let x1 = upz * z0 - upx * z2;
746
951
  let x2 = upx * z1 - upy * z0;
747
- len = Math.hypot(x0, x1, x2);
748
- if (len > 0) {
952
+ len = Math.sqrt(x0 * x0 + x1 * x1 + x2 * x2);
953
+ if (len) {
749
954
  len = 1 / len;
750
955
  x0 *= len;
751
956
  x1 *= len;
@@ -759,8 +964,8 @@ export const lookAt = <T extends Matrix4Like>(
759
964
  let y0 = z1 * x2 - z2 * x1;
760
965
  let y1 = z2 * x0 - z0 * x2;
761
966
  let y2 = z0 * x1 - z1 * x0;
762
- len = Math.hypot(y0, y1, y2);
763
- if (len > 0) {
967
+ len = Math.sqrt(y0 * y0 + y1 * y1 + y2 * y2);
968
+ if (len) {
764
969
  len = 1 / len;
765
970
  y0 *= len;
766
971
  y1 *= len;
@@ -771,23 +976,25 @@ export const lookAt = <T extends Matrix4Like>(
771
976
  y2 = 0;
772
977
  }
773
978
 
774
- out[0] = x0;
775
- out[1] = y0;
776
- out[2] = z0;
777
- out[3] = 0;
778
- out[4] = x1;
779
- out[5] = y1;
780
- out[6] = z1;
781
- out[7] = 0;
782
- out[8] = x2;
783
- out[9] = y2;
784
- out[10] = z2;
785
- out[11] = 0;
786
- out[12] = -(x0 * eyex + x1 * eyey + x2 * eyez);
787
- out[13] = -(y0 * eyex + y1 * eyey + y2 * eyez);
788
- out[14] = -(z0 * eyex + z1 * eyey + z2 * eyez);
789
- out[15] = 1;
790
- return out;
979
+ return fromValues(
980
+ x0,
981
+ y0,
982
+ z0,
983
+ 0,
984
+ x1,
985
+ y1,
986
+ z1,
987
+ 0,
988
+ x2,
989
+ y2,
990
+ z2,
991
+ 0,
992
+ -(x0 * eyex + x1 * eyey + x2 * eyez),
993
+ -(y0 * eyex + y1 * eyey + y2 * eyez),
994
+ -(z0 * eyex + z1 * eyey + z2 * eyez),
995
+ 1,
996
+ out
997
+ );
791
998
  };
792
999
 
793
1000
  /**
@@ -797,7 +1004,8 @@ export const lookAt = <T extends Matrix4Like>(
797
1004
  * @param up - The local up direction.
798
1005
  * @param out - The matrix to store the result in.
799
1006
  * @returns The transformation matrix.
800
- * @see [Transformation matrix](https://en.wikipedia.org/wiki/Transformation_matrix)
1007
+ * @see {@link https://en.wikipedia.org/wiki/Transformation_matrix | Transformation matrix}
1008
+ * @public
801
1009
  */
802
1010
  export const targetTo = <T extends Matrix4Like>(
803
1011
  eye: Vector3Like,
@@ -809,241 +1017,144 @@ export const targetTo = <T extends Matrix4Like>(
809
1017
  const eyey = eye[1];
810
1018
  const eyez = eye[2];
811
1019
 
812
- const upx = up[0];
813
- const upy = up[1];
814
- const upz = up[2];
815
-
816
- let z0 = eyex - target[0];
817
- let z1 = eyey - target[1];
818
- let z2 = eyez - target[2];
819
- let len = z0 * z0 + z1 * z1 + z2 * z2;
820
- if (len > 0) {
821
- len = 1 / Math.sqrt(len);
822
- z0 *= len;
823
- z1 *= len;
824
- z2 *= len;
825
- }
826
-
827
- let x0 = upy * z2 - upz * z1;
828
- let x1 = upz * z0 - upx * z2;
829
- let x2 = upx * z1 - upy * z0;
830
- len = x0 * x0 + x1 * x1 + x2 * x2;
831
- if (len > 0) {
832
- len = 1 / Math.sqrt(len);
833
- x0 *= len;
834
- x1 *= len;
835
- x2 *= len;
836
- }
837
-
838
- out[0] = x0;
839
- out[1] = x1;
840
- out[2] = x2;
841
- out[3] = 0;
842
- out[4] = z1 * x2 - z2 * x1;
843
- out[5] = z2 * x0 - z0 * x2;
844
- out[6] = z0 * x1 - z1 * x0;
845
- out[7] = 0;
846
- out[8] = z0;
847
- out[9] = z1;
848
- out[10] = z2;
849
- out[11] = 0;
850
- out[12] = eyex;
851
- out[13] = eyey;
852
- out[14] = eyez;
853
- out[15] = 1;
854
- return out;
855
- };
856
-
857
- /**
858
- * Add two matrices.
859
- * @param a - The augend.
860
- * @param b - The addend.
861
- * @param out - The matrix to store the result in.
862
- * @returns The sum.
863
- * @see [Matrix addition](https://en.wikipedia.org/wiki/Matrix_addition)
864
- */
865
- export const add = <T extends Matrix4Like>(
866
- a: Matrix4Like,
867
- b: Matrix4Like,
868
- out: T
869
- ): T => {
870
- out[0] = a[0] + b[0];
871
- out[1] = a[1] + b[1];
872
- out[2] = a[2] + b[2];
873
- out[3] = a[3] + b[3];
874
- out[4] = a[4] + b[4];
875
- out[5] = a[5] + b[5];
876
- out[6] = a[6] + b[6];
877
- out[7] = a[7] + b[7];
878
- out[8] = a[8] + b[8];
879
- out[9] = a[9] + b[8];
880
- out[10] = a[10] + b[10];
881
- out[11] = a[11] + b[11];
882
- out[12] = a[12] + b[12];
883
- out[13] = a[13] + b[13];
884
- out[14] = a[14] + b[14];
885
- out[15] = a[15] + b[15];
886
- return out;
887
- };
888
-
889
- /**
890
- * Create a two-by-two matrix with the given values.
891
- * @param c0r0 - The value in the first column and first row.
892
- * @param c0r1 - The value in the first column and second row.
893
- * @param c0r2 - The value in the first column and third row.
894
- * @param c0r3 - The value in the first column and fourth row.
895
- * @param c1r0 - The value in the second column and first row.
896
- * @param c1r1 - The value in the second column and second row.
897
- * @param c1r2 - The value in the second column and third row.
898
- * @param c1r3 - The value in the second column and fourth row.
899
- * @param c2r0 - The value in the third column and first row.
900
- * @param c2r1 - The value in the third column and second row.
901
- * @param c2r2 - The value in the third column and third row.
902
- * @param c2r3 - The value in the third column and fourth row.
903
- * @param c3r0 - The value in the fourth column and first row.
904
- * @param c3r1 - The value in the fourth column and second row.
905
- * @param c3r2 - The value in the fourth column and third row.
906
- * @param c3r3 - The value in the fourth column and fourth row.
907
- * @param out - The matrix to store the result in.
908
- * @returns The matrix.
909
- */
910
- export const fromValues = <T extends Matrix4Like>(
911
- c0r0: number,
912
- c0r1: number,
913
- c0r2: number,
914
- c0r3: number,
915
- c1r0: number,
916
- c1r1: number,
917
- c1r2: number,
918
- c1r3: number,
919
- c2r0: number,
920
- c2r1: number,
921
- c2r2: number,
922
- c2r3: number,
923
- c3r0: number,
924
- c3r1: number,
925
- c3r2: number,
926
- c3r3: number,
927
- out: T
928
- ): T => {
929
- out[0] = c0r0;
930
- out[1] = c0r1;
931
- out[2] = c0r2;
932
- out[3] = c0r3;
933
- out[4] = c1r0;
934
- out[5] = c1r1;
935
- out[6] = c1r2;
936
- out[7] = c1r3;
937
- out[8] = c2r0;
938
- out[9] = c2r1;
939
- out[10] = c2r2;
940
- out[11] = c2r3;
941
- out[12] = c3r0;
942
- out[13] = c3r1;
943
- out[14] = c3r2;
944
- out[15] = c3r3;
945
- return out;
1020
+ const upx = up[0];
1021
+ const upy = up[1];
1022
+ const upz = up[2];
1023
+
1024
+ let z0 = eyex - target[0];
1025
+ let z1 = eyey - target[1];
1026
+ let z2 = eyez - target[2];
1027
+ let len = z0 * z0 + z1 * z1 + z2 * z2;
1028
+ if (len) {
1029
+ len = 1 / Math.sqrt(len);
1030
+ z0 *= len;
1031
+ z1 *= len;
1032
+ z2 *= len;
1033
+ }
1034
+
1035
+ let x0 = upy * z2 - upz * z1;
1036
+ let x1 = upz * z0 - upx * z2;
1037
+ let x2 = upx * z1 - upy * z0;
1038
+ len = x0 * x0 + x1 * x1 + x2 * x2;
1039
+ if (len) {
1040
+ len = 1 / Math.sqrt(len);
1041
+ x0 *= len;
1042
+ x1 *= len;
1043
+ x2 *= len;
1044
+ }
1045
+
1046
+ return fromValues(
1047
+ x0,
1048
+ x1,
1049
+ x2,
1050
+ 0,
1051
+ z1 * x2 - z2 * x1,
1052
+ z2 * x0 - z0 * x2,
1053
+ z0 * x1 - z1 * x0,
1054
+ 0,
1055
+ z0,
1056
+ z1,
1057
+ z2,
1058
+ 0,
1059
+ eyex,
1060
+ eyey,
1061
+ eyez,
1062
+ 1,
1063
+ out
1064
+ );
946
1065
  };
947
1066
 
1067
+ /**
1068
+ * Add two matrices.
1069
+ * @param a - The augend.
1070
+ * @param b - The addend.
1071
+ * @param out - The matrix to store the result in.
1072
+ * @returns The sum.
1073
+ * @see {@link https://en.wikipedia.org/wiki/Matrix_addition | Matrix addition}
1074
+ * @public
1075
+ */
1076
+ export const add = <T extends Matrix4Like>(
1077
+ a: Matrix4Like,
1078
+ b: Matrix4Like,
1079
+ out: T
1080
+ ): T =>
1081
+ fromValues(
1082
+ a[0] + b[0],
1083
+ a[1] + b[1],
1084
+ a[2] + b[2],
1085
+ a[3] + b[3],
1086
+ a[4] + b[4],
1087
+ a[5] + b[5],
1088
+ a[6] + b[6],
1089
+ a[7] + b[7],
1090
+ a[8] + b[8],
1091
+ a[9] + b[8],
1092
+ a[10] + b[10],
1093
+ a[11] + b[11],
1094
+ a[12] + b[12],
1095
+ a[13] + b[13],
1096
+ a[14] + b[14],
1097
+ a[15] + b[15],
1098
+ out
1099
+ );
1100
+
948
1101
  /**
949
1102
  * Determine whether or not two matrices are roughly equivalent.
950
1103
  * @param a - The first matrix.
951
1104
  * @param b - The second matrix.
952
1105
  * @returns Whether or not the matrices are equivalent.
1106
+ * @public
953
1107
  */
954
- export const equals = (a: Matrix4Like, b: Matrix4Like): boolean => {
955
- const a0 = a[0];
956
- const a1 = a[1];
957
- const a2 = a[2];
958
- const a3 = a[3];
959
- const a4 = a[4];
960
- const a5 = a[5];
961
- const a6 = a[6];
962
- const a7 = a[7];
963
- const a8 = a[8];
964
- const a9 = a[9];
965
- const a10 = a[10];
966
- const a11 = a[11];
967
- const a12 = a[12];
968
- const a13 = a[13];
969
- const a14 = a[14];
970
- const a15 = a[15];
971
-
972
- const b0 = b[0];
973
- const b1 = b[1];
974
- const b2 = b[2];
975
- const b3 = b[3];
976
- const b4 = b[4];
977
- const b5 = b[5];
978
- const b6 = b[6];
979
- const b7 = b[7];
980
- const b8 = b[8];
981
- const b9 = b[9];
982
- const b10 = b[10];
983
- const b11 = b[11];
984
- const b12 = b[12];
985
- const b13 = b[13];
986
- const b14 = b[14];
987
- const b15 = b[15];
988
-
989
- return (
990
- Math.abs(a0 - b0) <= epsilon * Math.max(1, Math.abs(a0), Math.abs(b0)) &&
991
- Math.abs(a1 - b1) <= epsilon * Math.max(1, Math.abs(a1), Math.abs(b1)) &&
992
- Math.abs(a2 - b2) <= epsilon * Math.max(1, Math.abs(a2), Math.abs(b2)) &&
993
- Math.abs(a3 - b3) <= epsilon * Math.max(1, Math.abs(a3), Math.abs(b3)) &&
994
- Math.abs(a4 - b4) <= epsilon * Math.max(1, Math.abs(a4), Math.abs(b4)) &&
995
- Math.abs(a5 - b5) <= epsilon * Math.max(1, Math.abs(a5), Math.abs(b5)) &&
996
- Math.abs(a6 - b6) <= epsilon * Math.max(1, Math.abs(a6), Math.abs(b6)) &&
997
- Math.abs(a7 - b7) <= epsilon * Math.max(1, Math.abs(a7), Math.abs(b7)) &&
998
- Math.abs(a8 - b8) <= epsilon * Math.max(1, Math.abs(a8), Math.abs(b8)) &&
999
- Math.abs(a9 - b9) <= epsilon * Math.max(1, Math.abs(a9), Math.abs(b9)) &&
1000
- Math.abs(a10 - b10) <=
1001
- epsilon * Math.max(1, Math.abs(a10), Math.abs(b10)) &&
1002
- Math.abs(a11 - b11) <=
1003
- epsilon * Math.max(1, Math.abs(a11), Math.abs(b11)) &&
1004
- Math.abs(a12 - b12) <=
1005
- epsilon * Math.max(1, Math.abs(a12), Math.abs(b12)) &&
1006
- Math.abs(a13 - b13) <=
1007
- epsilon * Math.max(1, Math.abs(a13), Math.abs(b13)) &&
1008
- Math.abs(a14 - b14) <=
1009
- epsilon * Math.max(1, Math.abs(a14), Math.abs(b14)) &&
1010
- Math.abs(a15 - b15) <= epsilon * Math.max(1, Math.abs(a15), Math.abs(b15))
1011
- );
1012
- };
1108
+ export const equals = (a: Matrix4Like, b: Matrix4Like): boolean =>
1109
+ approxRelative(a[0], b[0]) &&
1110
+ approxRelative(a[1], b[1]) &&
1111
+ approxRelative(a[2], b[2]) &&
1112
+ approxRelative(a[3], b[3]) &&
1113
+ approxRelative(a[4], b[4]) &&
1114
+ approxRelative(a[5], b[5]) &&
1115
+ approxRelative(a[6], b[6]) &&
1116
+ approxRelative(a[7], b[7]) &&
1117
+ approxRelative(a[8], b[8]) &&
1118
+ approxRelative(a[9], b[9]) &&
1119
+ approxRelative(a[10], b[10]) &&
1120
+ approxRelative(a[11], b[11]) &&
1121
+ approxRelative(a[12], b[12]) &&
1122
+ approxRelative(a[13], b[13]) &&
1123
+ approxRelative(a[14], b[14]) &&
1124
+ approxRelative(a[15], b[15]);
1013
1125
 
1014
1126
  /**
1015
1127
  * Determine whether or not two matrices are exactly equivalent.
1016
1128
  * @param a - The first matrix.
1017
1129
  * @param b - The second matrix.
1018
1130
  * @returns Whether the matrices are equivalent.
1131
+ * @public
1019
1132
  */
1020
- export const exactEquals = (a: Matrix4Like, b: Matrix4Like): boolean => {
1021
- return (
1022
- a[0] === b[0] &&
1023
- a[1] === b[1] &&
1024
- a[2] === b[2] &&
1025
- a[3] === b[3] &&
1026
- a[4] === b[4] &&
1027
- a[5] === b[5] &&
1028
- a[6] === b[6] &&
1029
- a[7] === b[7] &&
1030
- a[8] === b[8] &&
1031
- a[9] === b[9] &&
1032
- a[10] === b[10] &&
1033
- a[11] === b[11] &&
1034
- a[12] === b[12] &&
1035
- a[13] === b[13] &&
1036
- a[14] === b[14] &&
1037
- a[15] === b[15]
1038
- );
1039
- };
1133
+ export const exactEquals = (a: Matrix4Like, b: Matrix4Like): boolean =>
1134
+ a[0] === b[0] &&
1135
+ a[1] === b[1] &&
1136
+ a[2] === b[2] &&
1137
+ a[3] === b[3] &&
1138
+ a[4] === b[4] &&
1139
+ a[5] === b[5] &&
1140
+ a[6] === b[6] &&
1141
+ a[7] === b[7] &&
1142
+ a[8] === b[8] &&
1143
+ a[9] === b[9] &&
1144
+ a[10] === b[10] &&
1145
+ a[11] === b[11] &&
1146
+ a[12] === b[12] &&
1147
+ a[13] === b[13] &&
1148
+ a[14] === b[14] &&
1149
+ a[15] === b[15];
1040
1150
 
1041
1151
  /**
1042
1152
  * Calculate the adjugate of a matrix.
1043
1153
  * @param matrix - The matrix.
1044
1154
  * @param out - The matrix to store the result in.
1045
1155
  * @returns The adjugate of the matrix.
1046
- * @see [Adjugate matrix](https://en.wikipedia.org/wiki/Adjugate_matrix)
1156
+ * @see {@link https://en.wikipedia.org/wiki/Adjugate_matrix | Adjugate matrix}
1157
+ * @public
1047
1158
  */
1048
1159
  export const adjoint = <T extends Matrix4Like>(
1049
1160
  matrix: Matrix4Like,
@@ -1066,79 +1177,38 @@ export const adjoint = <T extends Matrix4Like>(
1066
1177
  const a32 = matrix[14];
1067
1178
  const a33 = matrix[15];
1068
1179
 
1069
- out[0] =
1070
- a11 * (a22 * a33 - a23 * a32) -
1071
- a21 * (a12 * a33 - a13 * a32) +
1072
- a31 * (a12 * a23 - a13 * a22);
1073
- out[1] = -(
1074
- a01 * (a22 * a33 - a23 * a32) -
1075
- a21 * (a02 * a33 - a03 * a32) +
1076
- a31 * (a02 * a23 - a03 * a22)
1077
- );
1078
- out[2] =
1079
- a01 * (a12 * a33 - a13 * a32) -
1080
- a11 * (a02 * a33 - a03 * a32) +
1081
- a31 * (a02 * a13 - a03 * a12);
1082
- out[3] = -(
1083
- a01 * (a12 * a23 - a13 * a22) -
1084
- a11 * (a02 * a23 - a03 * a22) +
1085
- a21 * (a02 * a13 - a03 * a12)
1086
- );
1087
- out[4] = -(
1088
- a10 * (a22 * a33 - a23 * a32) -
1089
- a20 * (a12 * a33 - a13 * a32) +
1090
- a30 * (a12 * a23 - a13 * a22)
1091
- );
1092
- out[5] =
1093
- a00 * (a22 * a33 - a23 * a32) -
1094
- a20 * (a02 * a33 - a03 * a32) +
1095
- a30 * (a02 * a23 - a03 * a22);
1096
- out[6] = -(
1097
- a00 * (a12 * a33 - a13 * a32) -
1098
- a10 * (a02 * a33 - a03 * a32) +
1099
- a30 * (a02 * a13 - a03 * a12)
1100
- );
1101
- out[7] =
1102
- a00 * (a12 * a23 - a13 * a22) -
1103
- a10 * (a02 * a23 - a03 * a22) +
1104
- a20 * (a02 * a13 - a03 * a12);
1105
- out[8] =
1106
- a10 * (a21 * a33 - a23 * a31) -
1107
- a20 * (a11 * a33 - a13 * a31) +
1108
- a30 * (a11 * a23 - a13 * a21);
1109
- out[9] = -(
1110
- a00 * (a21 * a33 - a23 * a31) -
1111
- a20 * (a01 * a33 - a03 * a31) +
1112
- a30 * (a01 * a23 - a03 * a21)
1113
- );
1114
- out[10] =
1115
- a00 * (a11 * a33 - a13 * a31) -
1116
- a10 * (a01 * a33 - a03 * a31) +
1117
- a30 * (a01 * a13 - a03 * a11);
1118
- out[11] = -(
1119
- a00 * (a11 * a23 - a13 * a21) -
1120
- a10 * (a01 * a23 - a03 * a21) +
1121
- a20 * (a01 * a13 - a03 * a11)
1122
- );
1123
- out[12] = -(
1124
- a10 * (a21 * a32 - a22 * a31) -
1125
- a20 * (a11 * a32 - a12 * a31) +
1126
- a30 * (a11 * a22 - a12 * a21)
1127
- );
1128
- out[13] =
1129
- a00 * (a21 * a32 - a22 * a31) -
1130
- a20 * (a01 * a32 - a02 * a31) +
1131
- a30 * (a01 * a22 - a02 * a21);
1132
- out[14] = -(
1133
- a00 * (a11 * a32 - a12 * a31) -
1134
- a10 * (a01 * a32 - a02 * a31) +
1135
- a30 * (a01 * a12 - a02 * a11)
1180
+ const b00 = a00 * a11 - a01 * a10;
1181
+ const b01 = a00 * a12 - a02 * a10;
1182
+ const b02 = a00 * a13 - a03 * a10;
1183
+ const b03 = a01 * a12 - a02 * a11;
1184
+ const b04 = a01 * a13 - a03 * a11;
1185
+ const b05 = a02 * a13 - a03 * a12;
1186
+ const b06 = a20 * a31 - a21 * a30;
1187
+ const b07 = a20 * a32 - a22 * a30;
1188
+ const b08 = a20 * a33 - a23 * a30;
1189
+ const b09 = a21 * a32 - a22 * a31;
1190
+ const b10 = a21 * a33 - a23 * a31;
1191
+ const b11 = a22 * a33 - a23 * a32;
1192
+
1193
+ return fromValues(
1194
+ a11 * b11 - a12 * b10 + a13 * b09,
1195
+ a02 * b10 - a01 * b11 - a03 * b09,
1196
+ a31 * b05 - a32 * b04 + a33 * b03,
1197
+ a22 * b04 - a21 * b05 - a23 * b03,
1198
+ a12 * b08 - a10 * b11 - a13 * b07,
1199
+ a00 * b11 - a02 * b08 + a03 * b07,
1200
+ a32 * b02 - a30 * b05 - a33 * b01,
1201
+ a20 * b05 - a22 * b02 + a23 * b01,
1202
+ a10 * b10 - a11 * b08 + a13 * b06,
1203
+ a01 * b08 - a00 * b10 - a03 * b06,
1204
+ a30 * b04 - a31 * b02 + a33 * b00,
1205
+ a21 * b02 - a20 * b04 - a23 * b00,
1206
+ a11 * b07 - a10 * b09 - a12 * b06,
1207
+ a00 * b09 - a01 * b07 + a02 * b06,
1208
+ a31 * b01 - a30 * b03 - a32 * b00,
1209
+ a20 * b03 - a21 * b01 + a22 * b00,
1210
+ out
1136
1211
  );
1137
- out[15] =
1138
- a00 * (a11 * a22 - a12 * a21) -
1139
- a10 * (a01 * a22 - a02 * a21) +
1140
- a20 * (a01 * a12 - a02 * a11);
1141
- return out;
1142
1212
  };
1143
1213
 
1144
1214
  /**
@@ -1146,35 +1216,10 @@ export const adjoint = <T extends Matrix4Like>(
1146
1216
  * @param matrix - The matrix to copy.
1147
1217
  * @param out - The matrix to store the result in.
1148
1218
  * @returns This matrix.
1219
+ * @public
1149
1220
  */
1150
- export const copy = <T extends Matrix4Like>(matrix: Matrix4Like, out: T): T => {
1151
- out[0] = matrix[0];
1152
- out[1] = matrix[1];
1153
- out[2] = matrix[2];
1154
- out[3] = matrix[3];
1155
- out[4] = matrix[4];
1156
- out[5] = matrix[5];
1157
- out[6] = matrix[6];
1158
- out[7] = matrix[7];
1159
- out[8] = matrix[8];
1160
- out[9] = matrix[9];
1161
- out[10] = matrix[10];
1162
- out[11] = matrix[11];
1163
- out[12] = matrix[12];
1164
- out[13] = matrix[13];
1165
- out[14] = matrix[14];
1166
- out[15] = matrix[15];
1167
- return out;
1168
- };
1169
-
1170
- /**
1171
- * Calculate the Frobenius norm of a matrix.
1172
- * @param matrix - The matrix.
1173
- * @returns The Frobenius norm.
1174
- * @see [Matrix norm](https://en.wikipedia.org/wiki/Matrix_norm)
1175
- */
1176
- export const frob = (matrix: Matrix4Like): number => {
1177
- return Math.hypot(
1221
+ export const copy = <T extends Matrix4Like>(matrix: Matrix4Like, out: T): T =>
1222
+ fromValues(
1178
1223
  matrix[0],
1179
1224
  matrix[1],
1180
1225
  matrix[2],
@@ -1190,17 +1235,64 @@ export const frob = (matrix: Matrix4Like): number => {
1190
1235
  matrix[12],
1191
1236
  matrix[13],
1192
1237
  matrix[14],
1193
- matrix[15]
1238
+ matrix[15],
1239
+ out
1240
+ );
1241
+
1242
+ /**
1243
+ * Calculate the Frobenius norm of a matrix.
1244
+ * @param matrix - The matrix.
1245
+ * @returns The Frobenius norm.
1246
+ * @see {@link https://en.wikipedia.org/wiki/Matrix_norm | Matrix norm}
1247
+ * @public
1248
+ */
1249
+ export const frob = (matrix: Matrix4Like): number => {
1250
+ const a00 = matrix[0];
1251
+ const a01 = matrix[1];
1252
+ const a02 = matrix[2];
1253
+ const a03 = matrix[3];
1254
+ const a10 = matrix[4];
1255
+ const a11 = matrix[5];
1256
+ const a12 = matrix[6];
1257
+ const a13 = matrix[7];
1258
+ const a20 = matrix[8];
1259
+ const a21 = matrix[9];
1260
+ const a22 = matrix[10];
1261
+ const a23 = matrix[11];
1262
+ const a30 = matrix[12];
1263
+ const a31 = matrix[13];
1264
+ const a32 = matrix[14];
1265
+ const a33 = matrix[15];
1266
+
1267
+ // `Math.hypot` is slower.
1268
+ return Math.sqrt(
1269
+ a00 * a00 +
1270
+ a01 * a01 +
1271
+ a02 * a02 +
1272
+ a03 * a03 +
1273
+ a10 * a10 +
1274
+ a11 * a11 +
1275
+ a12 * a12 +
1276
+ a13 * a13 +
1277
+ a20 * a20 +
1278
+ a21 * a21 +
1279
+ a22 * a22 +
1280
+ a23 * a23 +
1281
+ a30 * a30 +
1282
+ a31 * a31 +
1283
+ a32 * a32 +
1284
+ a33 * a33
1194
1285
  );
1195
1286
  };
1196
1287
 
1197
1288
  /**
1198
1289
  * Multiply two matrices.
1199
- * @param a - The multiplicand.
1200
- * @param b - The multiplier.
1290
+ * @param a - The multiplier.
1291
+ * @param b - The multiplicand.
1201
1292
  * @param out - The matrix to store the result in.
1202
1293
  * @returns The product.
1203
- * @see [Matrix multiplication](https://en.wikipedia.org/wiki/Matrix_multiplication)
1294
+ * @see {@link https://en.wikipedia.org/wiki/Matrix_multiplication | Matrix multiplication}
1295
+ * @public
1204
1296
  */
1205
1297
  export const multiply = <T extends Matrix4Like>(
1206
1298
  a: Matrix4Like,
@@ -1224,39 +1316,42 @@ export const multiply = <T extends Matrix4Like>(
1224
1316
  const a32 = a[14];
1225
1317
  const a33 = a[15];
1226
1318
 
1227
- let b0 = b[0];
1228
- let b1 = b[1];
1229
- let b2 = b[2];
1230
- let b3 = b[3];
1231
- out[0] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
1232
- out[1] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
1233
- out[2] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
1234
- out[3] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
1235
- b0 = b[4];
1236
- b1 = b[5];
1237
- b2 = b[6];
1238
- b3 = b[7];
1239
- out[4] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
1240
- out[5] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
1241
- out[6] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
1242
- out[7] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
1243
- b0 = b[8];
1244
- b1 = b[9];
1245
- b2 = b[10];
1246
- b3 = b[11];
1247
- out[8] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
1248
- out[9] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
1249
- out[10] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
1250
- out[11] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
1251
- b0 = b[12];
1252
- b1 = b[13];
1253
- b2 = b[14];
1254
- b3 = b[15];
1255
- out[12] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
1256
- out[13] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
1257
- out[14] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
1258
- out[15] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
1259
- return out;
1319
+ const b00 = b[0];
1320
+ const b01 = b[1];
1321
+ const b02 = b[2];
1322
+ const b03 = b[3];
1323
+ const b10 = b[4];
1324
+ const b11 = b[5];
1325
+ const b12 = b[6];
1326
+ const b13 = b[7];
1327
+ const b20 = b[8];
1328
+ const b21 = b[9];
1329
+ const b22 = b[10];
1330
+ const b23 = b[11];
1331
+ const b30 = b[12];
1332
+ const b31 = b[13];
1333
+ const b32 = b[14];
1334
+ const b33 = b[15];
1335
+
1336
+ return fromValues(
1337
+ b00 * a00 + b01 * a10 + b02 * a20 + b03 * a30,
1338
+ b00 * a01 + b01 * a11 + b02 * a21 + b03 * a31,
1339
+ b00 * a02 + b01 * a12 + b02 * a22 + b03 * a32,
1340
+ b00 * a03 + b01 * a13 + b02 * a23 + b03 * a33,
1341
+ b10 * a00 + b11 * a10 + b12 * a20 + b13 * a30,
1342
+ b10 * a01 + b11 * a11 + b12 * a21 + b13 * a31,
1343
+ b10 * a02 + b11 * a12 + b12 * a22 + b13 * a32,
1344
+ b10 * a03 + b11 * a13 + b12 * a23 + b13 * a33,
1345
+ b20 * a00 + b21 * a10 + b22 * a20 + b23 * a30,
1346
+ b20 * a01 + b21 * a11 + b22 * a21 + b23 * a31,
1347
+ b20 * a02 + b21 * a12 + b22 * a22 + b23 * a32,
1348
+ b20 * a03 + b21 * a13 + b22 * a23 + b23 * a33,
1349
+ b30 * a00 + b31 * a10 + b32 * a20 + b33 * a30,
1350
+ b30 * a01 + b31 * a11 + b32 * a21 + b33 * a31,
1351
+ b30 * a02 + b31 * a12 + b32 * a22 + b33 * a32,
1352
+ b30 * a03 + b31 * a13 + b32 * a23 + b33 * a33,
1353
+ out
1354
+ );
1260
1355
  };
1261
1356
 
1262
1357
  /**
@@ -1265,31 +1360,33 @@ export const multiply = <T extends Matrix4Like>(
1265
1360
  * @param scalar - The multiplier.
1266
1361
  * @param out - The matrix to store the result in.
1267
1362
  * @returns The product.
1268
- * @see [Matrix multiplication](https://en.wikipedia.org/wiki/Matrix_multiplication)
1363
+ * @see {@link https://en.wikipedia.org/wiki/Matrix_multiplication | Matrix multiplication}
1364
+ * @public
1269
1365
  */
1270
1366
  export const multiplyScalar = <T extends Matrix4Like>(
1271
1367
  matrix: Matrix4Like,
1272
1368
  scalar: number,
1273
1369
  out: T
1274
- ): T => {
1275
- out[0] = matrix[0] * scalar;
1276
- out[1] = matrix[1] * scalar;
1277
- out[2] = matrix[2] * scalar;
1278
- out[3] = matrix[3] * scalar;
1279
- out[4] = matrix[4] * scalar;
1280
- out[5] = matrix[5] * scalar;
1281
- out[6] = matrix[6] * scalar;
1282
- out[7] = matrix[7] * scalar;
1283
- out[8] = matrix[8] * scalar;
1284
- out[9] = matrix[9] * scalar;
1285
- out[10] = matrix[10] * scalar;
1286
- out[11] = matrix[11] * scalar;
1287
- out[12] = matrix[12] * scalar;
1288
- out[13] = matrix[13] * scalar;
1289
- out[14] = matrix[14] * scalar;
1290
- out[15] = matrix[15] * scalar;
1291
- return out;
1292
- };
1370
+ ): T =>
1371
+ fromValues(
1372
+ matrix[0] * scalar,
1373
+ matrix[1] * scalar,
1374
+ matrix[2] * scalar,
1375
+ matrix[3] * scalar,
1376
+ matrix[4] * scalar,
1377
+ matrix[5] * scalar,
1378
+ matrix[6] * scalar,
1379
+ matrix[7] * scalar,
1380
+ matrix[8] * scalar,
1381
+ matrix[9] * scalar,
1382
+ matrix[10] * scalar,
1383
+ matrix[11] * scalar,
1384
+ matrix[12] * scalar,
1385
+ matrix[13] * scalar,
1386
+ matrix[14] * scalar,
1387
+ matrix[15] * scalar,
1388
+ out
1389
+ );
1293
1390
 
1294
1391
  /**
1295
1392
  * Add a matrix to another after multiplying the other by a scalar.
@@ -1298,33 +1395,35 @@ export const multiplyScalar = <T extends Matrix4Like>(
1298
1395
  * @param scalar - The multiplier.
1299
1396
  * @param out - The matrix to store the result in.
1300
1397
  * @returns The sum.
1301
- * @see [Matrix addition](https://en.wikipedia.org/wiki/Matrix_addition)
1302
- * @see [Matrix multiplication](https://en.wikipedia.org/wiki/Matrix_multiplication)
1398
+ * @see {@link https://en.wikipedia.org/wiki/Matrix_addition | Matrix addition}
1399
+ * @see {@link https://en.wikipedia.org/wiki/Matrix_multiplication | Matrix multiplication}
1400
+ * @public
1303
1401
  */
1304
1402
  export const multiplyScalarAndAdd = <T extends Matrix4Like>(
1305
1403
  a: Matrix4Like,
1306
1404
  b: Matrix4Like,
1307
1405
  scalar: number,
1308
1406
  out: T
1309
- ): T => {
1310
- out[0] = a[0] + b[0] * scalar;
1311
- out[1] = a[1] + b[1] * scalar;
1312
- out[2] = a[2] + b[2] * scalar;
1313
- out[3] = a[3] + b[3] * scalar;
1314
- out[4] = a[4] + b[4] * scalar;
1315
- out[5] = a[5] + b[5] * scalar;
1316
- out[6] = a[6] + b[6] * scalar;
1317
- out[7] = a[7] + b[7] * scalar;
1318
- out[8] = a[8] + b[8] * scalar;
1319
- out[9] = a[9] + b[9] * scalar;
1320
- out[10] = a[10] + b[10] * scalar;
1321
- out[11] = a[11] + b[11] * scalar;
1322
- out[12] = a[12] + b[12] * scalar;
1323
- out[13] = a[13] + b[13] * scalar;
1324
- out[14] = a[14] + b[14] * scalar;
1325
- out[15] = a[15] + b[15] * scalar;
1326
- return out;
1327
- };
1407
+ ): T =>
1408
+ fromValues(
1409
+ a[0] + b[0] * scalar,
1410
+ a[1] + b[1] * scalar,
1411
+ a[2] + b[2] * scalar,
1412
+ a[3] + b[3] * scalar,
1413
+ a[4] + b[4] * scalar,
1414
+ a[5] + b[5] * scalar,
1415
+ a[6] + b[6] * scalar,
1416
+ a[7] + b[7] * scalar,
1417
+ a[8] + b[8] * scalar,
1418
+ a[9] + b[9] * scalar,
1419
+ a[10] + b[10] * scalar,
1420
+ a[11] + b[11] * scalar,
1421
+ a[12] + b[12] * scalar,
1422
+ a[13] + b[13] * scalar,
1423
+ a[14] + b[14] * scalar,
1424
+ a[15] + b[15] * scalar,
1425
+ out
1426
+ );
1328
1427
 
1329
1428
  /**
1330
1429
  * Subtract two matrices.
@@ -1332,38 +1431,41 @@ export const multiplyScalarAndAdd = <T extends Matrix4Like>(
1332
1431
  * @param b - The subtrahend.
1333
1432
  * @param out - The matrix to store the result in.
1334
1433
  * @returns The difference.
1335
- * @see [Matrix addition](https://en.wikipedia.org/wiki/Matrix_addition)
1434
+ * @see {@link https://en.wikipedia.org/wiki/Matrix_addition | Matrix addition}
1435
+ * @public
1336
1436
  */
1337
1437
  export const subtract = <T extends Matrix4Like>(
1338
1438
  a: Matrix4Like,
1339
1439
  b: Matrix4Like,
1340
1440
  out: T
1341
- ): T => {
1342
- out[0] = a[0] - b[0];
1343
- out[1] = a[1] - b[1];
1344
- out[2] = a[2] - b[2];
1345
- out[3] = a[3] - b[3];
1346
- out[4] = a[4] - b[4];
1347
- out[5] = a[5] - b[5];
1348
- out[6] = a[6] - b[6];
1349
- out[7] = a[7] - b[7];
1350
- out[8] = a[8] - b[8];
1351
- out[9] = a[9] - b[8];
1352
- out[10] = a[10] - b[10];
1353
- out[11] = a[11] - b[11];
1354
- out[12] = a[12] - b[12];
1355
- out[13] = a[13] - b[13];
1356
- out[14] = a[14] - b[14];
1357
- out[15] = a[15] - b[15];
1358
- return out;
1359
- };
1441
+ ): T =>
1442
+ fromValues(
1443
+ a[0] - b[0],
1444
+ a[1] - b[1],
1445
+ a[2] - b[2],
1446
+ a[3] - b[3],
1447
+ a[4] - b[4],
1448
+ a[5] - b[5],
1449
+ a[6] - b[6],
1450
+ a[7] - b[7],
1451
+ a[8] - b[8],
1452
+ a[9] - b[8],
1453
+ a[10] - b[10],
1454
+ a[11] - b[11],
1455
+ a[12] - b[12],
1456
+ a[13] - b[13],
1457
+ a[14] - b[14],
1458
+ a[15] - b[15],
1459
+ out
1460
+ );
1360
1461
 
1361
1462
  /**
1362
1463
  * Transpose a matrix.
1363
1464
  * @param matrix - The matrix.
1364
1465
  * @param out - The matrix to store the result in.
1365
1466
  * @returns The transpose.
1366
- * @see [Transpose](https://en.wikipedia.org/wiki/Transpose)
1467
+ * @see {@link https://en.wikipedia.org/wiki/Transpose | Transpose}
1468
+ * @public
1367
1469
  */
1368
1470
  export const transpose = <T extends Matrix4Like>(
1369
1471
  matrix: Matrix4Like,
@@ -1388,66 +1490,64 @@ export const transpose = <T extends Matrix4Like>(
1388
1490
  out[12] = a03;
1389
1491
  out[13] = a13;
1390
1492
  out[14] = a23;
1391
- } else {
1392
- out[0] = matrix[0];
1393
- out[1] = matrix[4];
1394
- out[2] = matrix[8];
1395
- out[3] = matrix[12];
1396
- out[4] = matrix[1];
1397
- out[5] = matrix[5];
1398
- out[6] = matrix[9];
1399
- out[7] = matrix[13];
1400
- out[8] = matrix[2];
1401
- out[9] = matrix[6];
1402
- out[10] = matrix[10];
1403
- out[11] = matrix[14];
1404
- out[12] = matrix[3];
1405
- out[13] = matrix[7];
1406
- out[14] = matrix[11];
1407
- out[15] = matrix[15];
1493
+ return out;
1408
1494
  }
1409
1495
 
1410
- return out;
1496
+ return fromValues(
1497
+ matrix[0],
1498
+ matrix[4],
1499
+ matrix[8],
1500
+ matrix[12],
1501
+ matrix[1],
1502
+ matrix[5],
1503
+ matrix[9],
1504
+ matrix[13],
1505
+ matrix[2],
1506
+ matrix[6],
1507
+ matrix[10],
1508
+ matrix[14],
1509
+ matrix[3],
1510
+ matrix[7],
1511
+ matrix[11],
1512
+ matrix[15],
1513
+ out
1514
+ );
1411
1515
  };
1412
1516
 
1413
1517
  /**
1414
1518
  * Calculate the determinant of a matrix.
1415
1519
  * @param matrix - The matrix.
1416
1520
  * @returns The determinant.
1417
- * @see [Determinant](https://en.wikipedia.org/wiki/Determinant)
1521
+ * @see {@link https://en.wikipedia.org/wiki/Determinant | Determinant}
1522
+ * @public
1418
1523
  */
1419
1524
  export const determinant = (matrix: Matrix4Like): number => {
1420
1525
  const a00 = matrix[0];
1421
1526
  const a01 = matrix[1];
1422
1527
  const a02 = matrix[2];
1423
- const a03 = matrix[3];
1424
1528
  const a10 = matrix[4];
1425
1529
  const a11 = matrix[5];
1426
1530
  const a12 = matrix[6];
1427
- const a13 = matrix[7];
1428
1531
  const a20 = matrix[8];
1429
1532
  const a21 = matrix[9];
1430
1533
  const a22 = matrix[10];
1431
- const a23 = matrix[11];
1432
1534
  const a30 = matrix[12];
1433
1535
  const a31 = matrix[13];
1434
1536
  const a32 = matrix[14];
1435
- const a33 = matrix[15];
1436
1537
 
1437
- const b00 = a00 * a11 - a01 * a10;
1438
- const b01 = a00 * a12 - a02 * a10;
1439
- const b02 = a00 * a13 - a03 * a10;
1440
- const b03 = a01 * a12 - a02 * a11;
1441
- const b04 = a01 * a13 - a03 * a11;
1442
- const b05 = a02 * a13 - a03 * a12;
1443
- const b06 = a20 * a31 - a21 * a30;
1444
- const b07 = a20 * a32 - a22 * a30;
1445
- const b08 = a20 * a33 - a23 * a30;
1446
- const b09 = a21 * a32 - a22 * a31;
1447
- const b10 = a21 * a33 - a23 * a31;
1448
- const b11 = a22 * a33 - a23 * a32;
1538
+ const b0 = a00 * a11 - a01 * a10;
1539
+ const b1 = a00 * a12 - a02 * a10;
1540
+ const b2 = a01 * a12 - a02 * a11;
1541
+ const b3 = a20 * a31 - a21 * a30;
1542
+ const b4 = a20 * a32 - a22 * a30;
1543
+ const b5 = a21 * a32 - a22 * a31;
1449
1544
 
1450
- return b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
1545
+ return (
1546
+ matrix[7] * (a00 * b5 - a01 * b4 + a02 * b3) -
1547
+ matrix[3] * (a10 * b5 - a11 * b4 + a12 * b3) +
1548
+ matrix[15] * (a20 * b2 - a21 * b1 + a22 * b0) -
1549
+ matrix[11] * (a30 * b2 - a31 * b1 + a32 * b0)
1550
+ );
1451
1551
  };
1452
1552
 
1453
1553
  /**
@@ -1455,7 +1555,8 @@ export const determinant = (matrix: Matrix4Like): number => {
1455
1555
  * @param matrix - The matrix.
1456
1556
  * @param out - The matrix to store the result in.
1457
1557
  * @returns The inverted matrix.
1458
- * @see [Invertible matrix](https://en.wikipedia.org/wiki/Invertible_matrix)
1558
+ * @see {@link https://en.wikipedia.org/wiki/Invertible_matrix | Invertible matrix}
1559
+ * @public
1459
1560
  */
1460
1561
  export const invert = <T extends Matrix4Like>(
1461
1562
  matrix: Matrix4Like,
@@ -1498,23 +1599,25 @@ export const invert = <T extends Matrix4Like>(
1498
1599
  }
1499
1600
  det = 1 / det;
1500
1601
 
1501
- out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det;
1502
- out[1] = (a02 * b10 - a01 * b11 - a03 * b09) * det;
1503
- out[2] = (a31 * b05 - a32 * b04 + a33 * b03) * det;
1504
- out[3] = (a22 * b04 - a21 * b05 - a23 * b03) * det;
1505
- out[4] = (a12 * b08 - a10 * b11 - a13 * b07) * det;
1506
- out[5] = (a00 * b11 - a02 * b08 + a03 * b07) * det;
1507
- out[6] = (a32 * b02 - a30 * b05 - a33 * b01) * det;
1508
- out[7] = (a20 * b05 - a22 * b02 + a23 * b01) * det;
1509
- out[8] = (a10 * b10 - a11 * b08 + a13 * b06) * det;
1510
- out[9] = (a01 * b08 - a00 * b10 - a03 * b06) * det;
1511
- out[10] = (a30 * b04 - a31 * b02 + a33 * b00) * det;
1512
- out[11] = (a21 * b02 - a20 * b04 - a23 * b00) * det;
1513
- out[12] = (a11 * b07 - a10 * b09 - a12 * b06) * det;
1514
- out[13] = (a00 * b09 - a01 * b07 + a02 * b06) * det;
1515
- out[14] = (a31 * b01 - a30 * b03 - a32 * b00) * det;
1516
- out[15] = (a20 * b03 - a21 * b01 + a22 * b00) * det;
1517
- return out;
1602
+ return fromValues(
1603
+ (a11 * b11 - a12 * b10 + a13 * b09) * det,
1604
+ (a02 * b10 - a01 * b11 - a03 * b09) * det,
1605
+ (a31 * b05 - a32 * b04 + a33 * b03) * det,
1606
+ (a22 * b04 - a21 * b05 - a23 * b03) * det,
1607
+ (a12 * b08 - a10 * b11 - a13 * b07) * det,
1608
+ (a00 * b11 - a02 * b08 + a03 * b07) * det,
1609
+ (a32 * b02 - a30 * b05 - a33 * b01) * det,
1610
+ (a20 * b05 - a22 * b02 + a23 * b01) * det,
1611
+ (a10 * b10 - a11 * b08 + a13 * b06) * det,
1612
+ (a01 * b08 - a00 * b10 - a03 * b06) * det,
1613
+ (a30 * b04 - a31 * b02 + a33 * b00) * det,
1614
+ (a21 * b02 - a20 * b04 - a23 * b00) * det,
1615
+ (a11 * b07 - a10 * b09 - a12 * b06) * det,
1616
+ (a00 * b09 - a01 * b07 + a02 * b06) * det,
1617
+ (a31 * b01 - a30 * b03 - a32 * b00) * det,
1618
+ (a20 * b03 - a21 * b01 + a22 * b00) * det,
1619
+ out
1620
+ );
1518
1621
  };
1519
1622
 
1520
1623
  /**
@@ -1523,7 +1626,8 @@ export const invert = <T extends Matrix4Like>(
1523
1626
  * @param vector - The scaling vector.
1524
1627
  * @param out - The matrix to store the result in.
1525
1628
  * @returns The scaled matrix.
1526
- * @see [Transformation matrix](https://en.wikipedia.org/wiki/Transformation_matrix)
1629
+ * @see {@link https://en.wikipedia.org/wiki/Transformation_matrix | Transformation matrix}
1630
+ * @public
1527
1631
  */
1528
1632
  export const scale = <T extends Matrix4Like>(
1529
1633
  matrix: Matrix4Like,
@@ -1534,23 +1638,25 @@ export const scale = <T extends Matrix4Like>(
1534
1638
  const y = vector[1];
1535
1639
  const z = vector[2];
1536
1640
 
1537
- out[0] = matrix[0] * x;
1538
- out[1] = matrix[1] * x;
1539
- out[2] = matrix[2] * x;
1540
- out[3] = matrix[3] * x;
1541
- out[4] = matrix[4] * y;
1542
- out[5] = matrix[5] * y;
1543
- out[6] = matrix[6] * y;
1544
- out[7] = matrix[7] * y;
1545
- out[8] = matrix[8] * z;
1546
- out[9] = matrix[9] * z;
1547
- out[10] = matrix[10] * z;
1548
- out[11] = matrix[11] * z;
1549
- out[12] = matrix[12];
1550
- out[13] = matrix[13];
1551
- out[14] = matrix[14];
1552
- out[15] = matrix[15];
1553
- return out;
1641
+ return fromValues(
1642
+ matrix[0] * x,
1643
+ matrix[1] * x,
1644
+ matrix[2] * x,
1645
+ matrix[3] * x,
1646
+ matrix[4] * y,
1647
+ matrix[5] * y,
1648
+ matrix[6] * y,
1649
+ matrix[7] * y,
1650
+ matrix[8] * z,
1651
+ matrix[9] * z,
1652
+ matrix[10] * z,
1653
+ matrix[11] * z,
1654
+ matrix[12],
1655
+ matrix[13],
1656
+ matrix[14],
1657
+ matrix[15],
1658
+ out
1659
+ );
1554
1660
  };
1555
1661
 
1556
1662
  /**
@@ -1559,7 +1665,8 @@ export const scale = <T extends Matrix4Like>(
1559
1665
  * @param vector - The translation vector.
1560
1666
  * @param out - The matrix to store the result in.
1561
1667
  * @returns The translated matrix.
1562
- * @see [Transformation matrix](https://en.wikipedia.org/wiki/Transformation_matrix)
1668
+ * @see {@link https://en.wikipedia.org/wiki/Transformation_matrix | Transformation matrix}
1669
+ * @public
1563
1670
  */
1564
1671
  export const translate = <T extends Matrix4Like>(
1565
1672
  matrix: Matrix4Like,
@@ -1575,39 +1682,41 @@ export const translate = <T extends Matrix4Like>(
1575
1682
  out[13] = matrix[1] * x + matrix[5] * y + matrix[9] * z + matrix[13];
1576
1683
  out[14] = matrix[2] * x + matrix[6] * y + matrix[10] * z + matrix[14];
1577
1684
  out[15] = matrix[3] * x + matrix[7] * y + matrix[11] * z + matrix[15];
1578
- } else {
1579
- const a00 = matrix[0];
1580
- const a01 = matrix[1];
1581
- const a02 = matrix[2];
1582
- const a03 = matrix[3];
1583
- const a10 = matrix[4];
1584
- const a11 = matrix[5];
1585
- const a12 = matrix[6];
1586
- const a13 = matrix[7];
1587
- const a20 = matrix[8];
1588
- const a21 = matrix[9];
1589
- const a22 = matrix[10];
1590
- const a23 = matrix[11];
1591
-
1592
- out[0] = a00;
1593
- out[1] = a01;
1594
- out[2] = a02;
1595
- out[3] = a03;
1596
- out[4] = a10;
1597
- out[5] = a11;
1598
- out[6] = a12;
1599
- out[7] = a13;
1600
- out[8] = a20;
1601
- out[9] = a21;
1602
- out[10] = a22;
1603
- out[11] = a23;
1604
- out[12] = a00 * x + a10 * y + a20 * z + matrix[12];
1605
- out[13] = a01 * x + a11 * y + a21 * z + matrix[13];
1606
- out[14] = a02 * x + a12 * y + a22 * z + matrix[14];
1607
- out[15] = a03 * x + a13 * y + a23 * z + matrix[15];
1685
+ return out;
1608
1686
  }
1609
1687
 
1610
- return out;
1688
+ const a00 = matrix[0];
1689
+ const a01 = matrix[1];
1690
+ const a02 = matrix[2];
1691
+ const a03 = matrix[3];
1692
+ const a10 = matrix[4];
1693
+ const a11 = matrix[5];
1694
+ const a12 = matrix[6];
1695
+ const a13 = matrix[7];
1696
+ const a20 = matrix[8];
1697
+ const a21 = matrix[9];
1698
+ const a22 = matrix[10];
1699
+ const a23 = matrix[11];
1700
+
1701
+ return fromValues(
1702
+ a00,
1703
+ a01,
1704
+ a02,
1705
+ a03,
1706
+ a10,
1707
+ a11,
1708
+ a12,
1709
+ a13,
1710
+ a20,
1711
+ a21,
1712
+ a22,
1713
+ a23,
1714
+ a00 * x + a10 * y + a20 * z + matrix[12],
1715
+ a01 * x + a11 * y + a21 * z + matrix[13],
1716
+ a02 * x + a12 * y + a22 * z + matrix[14],
1717
+ a03 * x + a13 * y + a23 * z + matrix[15],
1718
+ out
1719
+ );
1611
1720
  };
1612
1721
 
1613
1722
  /**
@@ -1617,7 +1726,8 @@ export const translate = <T extends Matrix4Like>(
1617
1726
  * @param axis - The axis.
1618
1727
  * @param out - The matrix to store the result in.
1619
1728
  * @returns The rotated matrix.
1620
- * @see [Rotation matrix](https://en.wikipedia.org/wiki/Rotation_matrix)
1729
+ * @see {@link https://en.wikipedia.org/wiki/Rotation_matrix | Rotation matrix}
1730
+ * @public
1621
1731
  */
1622
1732
  export const rotate = <T extends Matrix4Like>(
1623
1733
  matrix: Matrix4Like,
@@ -1629,7 +1739,7 @@ export const rotate = <T extends Matrix4Like>(
1629
1739
  let y = axis[1];
1630
1740
  let z = axis[2];
1631
1741
 
1632
- let len = Math.hypot(x, y, z);
1742
+ let len = Math.sqrt(x * x + y * y + z * z); // `Math.hypot` is slower.
1633
1743
  if (len < epsilon) {
1634
1744
  return out;
1635
1745
  }
@@ -1643,6 +1753,14 @@ export const rotate = <T extends Matrix4Like>(
1643
1753
  const c = Math.cos(radians);
1644
1754
  const t = 1 - c;
1645
1755
 
1756
+ const xs = x * s;
1757
+ const ys = y * s;
1758
+ const zs = z * s;
1759
+
1760
+ const xt = x * t;
1761
+ const yt = y * t;
1762
+ const zt = z * t;
1763
+
1646
1764
  const a00 = matrix[0];
1647
1765
  const a01 = matrix[1];
1648
1766
  const a02 = matrix[2];
@@ -1656,15 +1774,15 @@ export const rotate = <T extends Matrix4Like>(
1656
1774
  const a22 = matrix[10];
1657
1775
  const a23 = matrix[11];
1658
1776
 
1659
- const b00 = x * x * t + c;
1660
- const b01 = y * x * t + z * s;
1661
- const b02 = z * x * t - y * s;
1662
- const b10 = x * y * t - z * s;
1663
- const b11 = y * y * t + c;
1664
- const b12 = z * y * t + x * s;
1665
- const b20 = x * z * t + y * s;
1666
- const b21 = y * z * t - x * s;
1667
- const b22 = z * z * t + c;
1777
+ const b00 = x * xt + c;
1778
+ const b01 = y * xt + zs;
1779
+ const b02 = z * xt - ys;
1780
+ const b10 = x * yt - zs;
1781
+ const b11 = y * yt + c;
1782
+ const b12 = z * yt + xs;
1783
+ const b20 = x * zt + ys;
1784
+ const b21 = y * zt - xs;
1785
+ const b22 = z * zt + c;
1668
1786
 
1669
1787
  out[0] = a00 * b00 + a10 * b01 + a20 * b02;
1670
1788
  out[1] = a01 * b00 + a11 * b01 + a21 * b02;
@@ -1678,12 +1796,14 @@ export const rotate = <T extends Matrix4Like>(
1678
1796
  out[9] = a01 * b20 + a11 * b21 + a21 * b22;
1679
1797
  out[10] = a02 * b20 + a12 * b21 + a22 * b22;
1680
1798
  out[11] = a03 * b20 + a13 * b21 + a23 * b22;
1799
+
1681
1800
  if (out !== matrix) {
1682
1801
  out[12] = matrix[12];
1683
1802
  out[13] = matrix[13];
1684
1803
  out[14] = matrix[14];
1685
1804
  out[15] = matrix[15];
1686
1805
  }
1806
+
1687
1807
  return out;
1688
1808
  };
1689
1809
 
@@ -1693,7 +1813,8 @@ export const rotate = <T extends Matrix4Like>(
1693
1813
  * @param r - The angle in radians.
1694
1814
  * @param out - The matrix to store the result in.
1695
1815
  * @returns The rotated matrix.
1696
- * @see [Rotation matrix](https://en.wikipedia.org/wiki/Rotation_matrix)
1816
+ * @see {@link https://en.wikipedia.org/wiki/Rotation_matrix | Rotation matrix}
1817
+ * @public
1697
1818
  */
1698
1819
  export const rotateX = <T extends Matrix4Like>(
1699
1820
  matrix: Matrix4Like,
@@ -1740,7 +1861,8 @@ export const rotateX = <T extends Matrix4Like>(
1740
1861
  * @param r - The angle in radians.
1741
1862
  * @param out - The matrix to store the result in.
1742
1863
  * @returns The rotated matrix.
1743
- * @see [Rotation matrix](https://en.wikipedia.org/wiki/Rotation_matrix)
1864
+ * @see {@link https://en.wikipedia.org/wiki/Rotation_matrix | Rotation matrix}
1865
+ * @public
1744
1866
  */
1745
1867
  export const rotateY = <T extends Matrix4Like>(
1746
1868
  matrix: Matrix4Like,
@@ -1787,7 +1909,8 @@ export const rotateY = <T extends Matrix4Like>(
1787
1909
  * @param r - The angle in radians.
1788
1910
  * @param out - The matrix to store the result in.
1789
1911
  * @returns The rotated matrix.
1790
- * @see [Rotation matrix](https://en.wikipedia.org/wiki/Rotation_matrix)
1912
+ * @see {@link https://en.wikipedia.org/wiki/Rotation_matrix | Rotation matrix}
1913
+ * @public
1791
1914
  */
1792
1915
  export const rotateZ = <T extends Matrix4Like>(
1793
1916
  matrix: Matrix4Like,
@@ -1833,17 +1956,13 @@ export const rotateZ = <T extends Matrix4Like>(
1833
1956
  * @param matrix - The matrix.
1834
1957
  * @param out - The vector to store the result in.
1835
1958
  * @returns The translation vector.
1836
- * @see [Transformation matrix](https://en.wikipedia.org/wiki/Transformation_matrix)
1959
+ * @see {@link https://en.wikipedia.org/wiki/Transformation_matrix | Transformation matrix}
1960
+ * @public
1837
1961
  */
1838
1962
  export const getTranslation = <T extends Vector3Like>(
1839
1963
  matrix: Matrix4Like,
1840
1964
  out: T
1841
- ): T => {
1842
- out[0] = matrix[12];
1843
- out[1] = matrix[13];
1844
- out[2] = matrix[14];
1845
- return out;
1846
- };
1965
+ ): T => vector3FromValues(matrix[12], matrix[13], matrix[14], out);
1847
1966
 
1848
1967
  /**
1849
1968
  * Set the translation vector component of a transformation matrix.
@@ -1851,7 +1970,8 @@ export const getTranslation = <T extends Vector3Like>(
1851
1970
  * @param translation - The translation vector.
1852
1971
  * @param out - The matrix to store the result in.
1853
1972
  * @returns The transformation matrix.
1854
- * @see [Transformation matrix](https://en.wikipedia.org/wiki/Transformation_matrix)
1973
+ * @see {@link https://en.wikipedia.org/wiki/Transformation_matrix | Transformation matrix}
1974
+ * @public
1855
1975
  */
1856
1976
  export const setTranslation = <T extends Matrix4Like>(
1857
1977
  matrix: Matrix4Like,
@@ -1885,7 +2005,8 @@ export const setTranslation = <T extends Matrix4Like>(
1885
2005
  * @param matrix - The matrix.
1886
2006
  * @param out - The vector to store the result in.
1887
2007
  * @returns The scaling vector.
1888
- * @see [Transformation matrix](https://en.wikipedia.org/wiki/Transformation_matrix)
2008
+ * @see {@link https://en.wikipedia.org/wiki/Transformation_matrix | Transformation matrix}
2009
+ * @public
1889
2010
  */
1890
2011
  export const getScaling = <T extends Vector3Like>(
1891
2012
  matrix: Matrix4Like,
@@ -1901,10 +2022,13 @@ export const getScaling = <T extends Vector3Like>(
1901
2022
  const m32 = matrix[9];
1902
2023
  const m33 = matrix[10];
1903
2024
 
1904
- out[0] = Math.hypot(m11, m12, m13);
1905
- out[1] = Math.hypot(m21, m22, m23);
1906
- out[2] = Math.hypot(m31, m32, m33);
1907
- return out;
2025
+ // `Math.hypot` is slower.
2026
+ return vector3FromValues(
2027
+ Math.sqrt(m11 * m11 + m12 * m12 + m13 * m13),
2028
+ Math.sqrt(m21 * m21 + m22 * m22 + m23 * m23),
2029
+ Math.sqrt(m31 * m31 + m32 * m32 + m33 * m33),
2030
+ out
2031
+ );
1908
2032
  };
1909
2033
 
1910
2034
  /**
@@ -1912,17 +2036,18 @@ export const getScaling = <T extends Vector3Like>(
1912
2036
  * @param matrix - The matrix.
1913
2037
  * @param out - The quaternion to store the result in.
1914
2038
  * @returns The rotation.
1915
- * @see [Rotation matrix](https://en.wikipedia.org/wiki/Rotation_matrix)
2039
+ * @see {@link https://en.wikipedia.org/wiki/Rotation_matrix | Rotation matrix}
2040
+ * @public
1916
2041
  */
1917
2042
  export const getRotation = <T extends QuaternionLike>(
1918
2043
  matrix: Matrix4Like,
1919
2044
  out: T
1920
2045
  ): T => {
1921
- const scaling = getScaling(matrix, createVector3Like());
2046
+ getScaling(matrix, iv3);
1922
2047
 
1923
- const is1 = 1 / scaling[0];
1924
- const is2 = 1 / scaling[1];
1925
- const is3 = 1 / scaling[2];
2048
+ const is1 = 1 / iv3[0];
2049
+ const is2 = 1 / iv3[1];
2050
+ const is3 = 1 / iv3[2];
1926
2051
 
1927
2052
  const sm11 = matrix[0] * is1;
1928
2053
  const sm12 = matrix[1] * is2;
@@ -1938,42 +2063,51 @@ export const getRotation = <T extends QuaternionLike>(
1938
2063
 
1939
2064
  if (trace > 0) {
1940
2065
  const s = Math.sqrt(trace + 1) * 2;
1941
- out[0] = (sm23 - sm32) / s;
1942
- out[1] = (sm31 - sm13) / s;
1943
- out[2] = (sm12 - sm21) / s;
1944
- out[3] = 0.25 * s;
1945
- return out;
2066
+ return quaternionFromValues(
2067
+ (sm23 - sm32) / s,
2068
+ (sm31 - sm13) / s,
2069
+ (sm12 - sm21) / s,
2070
+ 0.25 * s,
2071
+ out
2072
+ );
1946
2073
  }
1947
2074
 
1948
2075
  if (sm11 > sm22 && sm11 > sm33) {
1949
2076
  const s = Math.sqrt(1 + sm11 - sm22 - sm33) * 2;
1950
- out[0] = 0.25 * s;
1951
- out[1] = (sm12 + sm21) / s;
1952
- out[2] = (sm31 + sm13) / s;
1953
- out[3] = (sm23 - sm32) / s;
1954
- return out;
2077
+ return quaternionFromValues(
2078
+ 0.25 * s,
2079
+ (sm12 + sm21) / s,
2080
+ (sm31 + sm13) / s,
2081
+ (sm23 - sm32) / s,
2082
+ out
2083
+ );
1955
2084
  }
1956
2085
 
1957
2086
  if (sm22 > sm33) {
1958
2087
  const s = Math.sqrt(1 + sm22 - sm11 - sm33) * 2;
1959
- out[0] = (sm12 + sm21) / s;
1960
- out[1] = 0.25 * s;
1961
- out[2] = (sm23 + sm32) / s;
1962
- out[3] = (sm31 - sm13) / s;
1963
- return out;
2088
+ return quaternionFromValues(
2089
+ (sm12 + sm21) / s,
2090
+ 0.25 * s,
2091
+ (sm23 + sm32) / s,
2092
+ (sm31 - sm13) / s,
2093
+ out
2094
+ );
1964
2095
  }
1965
2096
 
1966
2097
  const s = Math.sqrt(1 + sm33 - sm11 - sm22) * 2;
1967
- out[0] = (sm31 + sm13) / s;
1968
- out[1] = (sm23 + sm32) / s;
1969
- out[2] = 0.25 * s;
1970
- out[3] = (sm12 - sm21) / s;
1971
- return out;
2098
+ return quaternionFromValues(
2099
+ (sm31 + sm13) / s,
2100
+ (sm23 + sm32) / s,
2101
+ 0.25 * s,
2102
+ (sm12 - sm21) / s,
2103
+ out
2104
+ );
1972
2105
  };
1973
2106
 
1974
2107
  /**
1975
2108
  * A four-by-four matrix.
1976
- * @see [Matrix](https://en.wikipedia.org/wiki/Matrix_(mathematics))
2109
+ * @see {@link https://en.wikipedia.org/wiki/Matrix_(mathematics) | Matrix}
2110
+ * @public
1977
2111
  */
1978
2112
  export default class Matrix4
1979
2113
  extends Float32Array
@@ -1984,7 +2118,7 @@ export default class Matrix4
1984
2118
  * @param vector - The translation vector.
1985
2119
  * @param out - The matrix to store the result in.
1986
2120
  * @returns The transformation matrix.
1987
- * @see [Transformation matrix](https://en.wikipedia.org/wiki/Transformation_matrix)
2121
+ * @see {@link https://en.wikipedia.org/wiki/Transformation_matrix | Transformation matrix}
1988
2122
  */
1989
2123
  public static fromTranslation<T extends Matrix4Like = Matrix4>(
1990
2124
  vector: Vector3Like,
@@ -1998,7 +2132,7 @@ export default class Matrix4
1998
2132
  * @param vector - The scaling vector.
1999
2133
  * @param out - The matrix to store the result in.
2000
2134
  * @returns The transformation matrix.
2001
- * @see [Transformation matrix](https://en.wikipedia.org/wiki/Transformation_matrix)
2135
+ * @see {@link https://en.wikipedia.org/wiki/Transformation_matrix | Transformation matrix}
2002
2136
  */
2003
2137
  public static fromScaling<T extends Matrix4Like = Matrix4>(
2004
2138
  vector: Vector3Like,
@@ -2013,7 +2147,7 @@ export default class Matrix4
2013
2147
  * @param axis - The axis to rotate around.
2014
2148
  * @param out - The matrix to store the result in.
2015
2149
  * @returns The transformation matrix.
2016
- * @see [Rotation matrix](https://en.wikipedia.org/wiki/Rotation_matrix)
2150
+ * @see {@link https://en.wikipedia.org/wiki/Rotation_matrix | Rotation matrix}
2017
2151
  */
2018
2152
  public static fromRotation<T extends Matrix4Like = Matrix4>(
2019
2153
  r: number,
@@ -2028,7 +2162,7 @@ export default class Matrix4
2028
2162
  * @param r - The angle in radians.
2029
2163
  * @param out - The matrix to store the result in.
2030
2164
  * @returns The transformation matrix.
2031
- * @see [Rotation matrix](https://en.wikipedia.org/wiki/Rotation_matrix)
2165
+ * @see {@link https://en.wikipedia.org/wiki/Rotation_matrix | Rotation matrix}
2032
2166
  */
2033
2167
  public static fromXRotation<T extends Matrix4Like = Matrix4>(
2034
2168
  r: number,
@@ -2042,7 +2176,7 @@ export default class Matrix4
2042
2176
  * @param r - The angle in radians.
2043
2177
  * @param out - The matrix to store the result in.
2044
2178
  * @returns The transformation matrix.
2045
- * @see [Rotation matrix](https://en.wikipedia.org/wiki/Rotation_matrix)
2179
+ * @see {@link https://en.wikipedia.org/wiki/Rotation_matrix | Rotation matrix}
2046
2180
  */
2047
2181
  public static fromYRotation<T extends Matrix4Like = Matrix4>(
2048
2182
  r: number,
@@ -2056,7 +2190,7 @@ export default class Matrix4
2056
2190
  * @param r - The angle in radians.
2057
2191
  * @param out - The matrix to store the result in.
2058
2192
  * @returns The transformation matrix.
2059
- * @see [Rotation matrix](https://en.wikipedia.org/wiki/Rotation_matrix)
2193
+ * @see {@link https://en.wikipedia.org/wiki/Rotation_matrix | Rotation matrix}
2060
2194
  */
2061
2195
  public static fromZRotation<T extends Matrix4Like = Matrix4>(
2062
2196
  r: number,
@@ -2071,8 +2205,8 @@ export default class Matrix4
2071
2205
  * @param translation - The translation vector.
2072
2206
  * @param out - The matrix to store the result in.
2073
2207
  * @returns The transformation matrix.
2074
- * @see [Rotation matrix](https://en.wikipedia.org/wiki/Rotation_matrix)
2075
- * @see [Transformation matrix](https://en.wikipedia.org/wiki/Transformation_matrix)
2208
+ * @see {@link https://en.wikipedia.org/wiki/Rotation_matrix | Rotation matrix}
2209
+ * @see {@link https://en.wikipedia.org/wiki/Transformation_matrix | Transformation matrix}
2076
2210
  */
2077
2211
  public static fromRotationTranslation<T extends Matrix4Like = Matrix4>(
2078
2212
  rotation: QuaternionLike,
@@ -2089,8 +2223,8 @@ export default class Matrix4
2089
2223
  * @param scaling - The scaling vector.
2090
2224
  * @param out - The matrix to store the result in.
2091
2225
  * @returns The transformation matrix.
2092
- * @see [Rotation matrix](https://en.wikipedia.org/wiki/Rotation_matrix)
2093
- * @see [Transformation matrix](https://en.wikipedia.org/wiki/Transformation_matrix)
2226
+ * @see {@link https://en.wikipedia.org/wiki/Rotation_matrix | Rotation matrix}
2227
+ * @see {@link https://en.wikipedia.org/wiki/Transformation_matrix | Transformation matrix}
2094
2228
  */
2095
2229
  public static fromRotationTranslationScale<T extends Matrix4Like = Matrix4>(
2096
2230
  rotation: QuaternionLike,
@@ -2109,8 +2243,8 @@ export default class Matrix4
2109
2243
  * @param origin - The origin vector.
2110
2244
  * @param out - The matrix to store the result in.
2111
2245
  * @returns The transformation matrix.
2112
- * @see [Rotation matrix](https://en.wikipedia.org/wiki/Rotation_matrix)
2113
- * @see [Transformation matrix](https://en.wikipedia.org/wiki/Transformation_matrix)
2246
+ * @see {@link https://en.wikipedia.org/wiki/Rotation_matrix | Rotation matrix}
2247
+ * @see {@link https://en.wikipedia.org/wiki/Transformation_matrix | Transformation matrix}
2114
2248
  */
2115
2249
  public static fromRotationTranslationScaleOrigin<
2116
2250
  T extends Matrix4Like = Matrix4
@@ -2135,9 +2269,9 @@ export default class Matrix4
2135
2269
  * @param quaternion - The dual quaternion.
2136
2270
  * @param out - The matrix to store the result in.
2137
2271
  * @returns The transformation matrix.
2138
- * @see [Dual quaternion](https://en.wikipedia.org/wiki/Dual_quaternion)
2139
- * @see [Rotation matrix](https://en.wikipedia.org/wiki/Rotation_matrix)
2140
- * @see [Transformation matrix](https://en.wikipedia.org/wiki/Transformation_matrix)
2272
+ * @see {@link https://en.wikipedia.org/wiki/Dual_quaternion | Dual quaternion}
2273
+ * @see {@link https://en.wikipedia.org/wiki/Rotation_matrix | Rotation matrix}
2274
+ * @see {@link https://en.wikipedia.org/wiki/Transformation_matrix | Transformation matrix}
2141
2275
  */
2142
2276
  public static fromDualQuaternion<T extends Matrix4Like = Matrix4>(
2143
2277
  quaternion: DualQuaternionLike,
@@ -2146,6 +2280,21 @@ export default class Matrix4
2146
2280
  return fromDualQuaternion(quaternion, out);
2147
2281
  }
2148
2282
 
2283
+ /**
2284
+ * Create a transformation matrix from a quaternion.
2285
+ * @param quaternion - The quaternion.
2286
+ * @param out - The matrix to store the result in.
2287
+ * @returns The transformation matrix.
2288
+ * @see {@link https://en.wikipedia.org/wiki/Rotation_matrix | Rotation matrix}
2289
+ * @see {@link https://en.wikipedia.org/wiki/Transformation_matrix | Transformation matrix}
2290
+ */
2291
+ public static fromQuaternion<T extends Matrix4Like = Matrix4>(
2292
+ quaternion: QuaternionLike,
2293
+ out: T = new Matrix4() as Matrix4 & T
2294
+ ): T {
2295
+ return fromQuaternion(quaternion, out);
2296
+ }
2297
+
2149
2298
  /**
2150
2299
  * Generate a frustum matrix with the given bounds.
2151
2300
  * @param left - The left bound of the frustum.
@@ -2156,8 +2305,8 @@ export default class Matrix4
2156
2305
  * @param far - The far bound of the frustum.
2157
2306
  * @param out - The matrix to store the result in.
2158
2307
  * @returns The frustum matrix.
2159
- * @see [Camera matrix](https://en.wikipedia.org/wiki/Camera_matrix)
2160
- * @see [3D projection](https://en.wikipedia.org/wiki/3D_projection)
2308
+ * @see {@link https://en.wikipedia.org/wiki/Camera_matrix | Camera matrix}
2309
+ * @see {@link https://en.wikipedia.org/wiki/3D_projection | 3D projection}
2161
2310
  */
2162
2311
  public static frustum<T extends Matrix4Like = Matrix4>(
2163
2312
  left: number,
@@ -2172,15 +2321,15 @@ export default class Matrix4
2172
2321
  }
2173
2322
 
2174
2323
  /**
2175
- * Create a perspective projection matrix with the given bounds.
2324
+ * Create a perspective projection matrix with the given bounds such that the near and far clip planes correspond to a normalized device coordinate Z range of `[-1, 1]` (OpenGL/WebGL).
2176
2325
  * @param fov - The vertical field of view in radians.
2177
2326
  * @param aspect - The aspect ratio (typically the width of the viewport divided by its height).
2178
2327
  * @param near - The near bound of the frustum.
2179
2328
  * @param far - The far bound of the frustum.
2180
2329
  * @param out - The matrix to store the result in.
2181
2330
  * @returns The perspective projection matrix.
2182
- * @see [Camera matrix](https://en.wikipedia.org/wiki/Camera_matrix)
2183
- * @see [3D projection](https://en.wikipedia.org/wiki/3D_projection)
2331
+ * @see {@link https://en.wikipedia.org/wiki/Camera_matrix | Camera matrix}
2332
+ * @see {@link https://en.wikipedia.org/wiki/3D_projection | 3D projection}
2184
2333
  */
2185
2334
  public static perspective<T extends Matrix4Like = Matrix4>(
2186
2335
  fov: number,
@@ -2192,6 +2341,27 @@ export default class Matrix4
2192
2341
  return perspective(fov, aspect, near, far, out);
2193
2342
  }
2194
2343
 
2344
+ /**
2345
+ * Create a perspective projection matrix with the given bounds such that the near and far clip planes correspond to a normalized device coordinate Z range of `[0, 1]` (WebGPU/Vulkan/DirectX/Metal).
2346
+ * @param fov - The vertical field of view in radians.
2347
+ * @param aspect - The aspect ratio (typically the width of the viewport divided by its height).
2348
+ * @param near - The near bound of the frustum.
2349
+ * @param far - The far bound of the frustum.
2350
+ * @param out - The matrix to store the result in.
2351
+ * @returns The perspective projection matrix.
2352
+ * @see {@link https://en.wikipedia.org/wiki/Camera_matrix | Camera matrix}
2353
+ * @see {@link https://en.wikipedia.org/wiki/3D_projection | 3D projection}
2354
+ */
2355
+ public static perspectiveGpu<T extends Matrix4Like = Matrix4>(
2356
+ fov: number,
2357
+ aspect: number,
2358
+ near: number,
2359
+ far: number,
2360
+ out: T = new Matrix4() as Matrix4 & T
2361
+ ): T {
2362
+ return perspectiveGpu(fov, aspect, near, far, out);
2363
+ }
2364
+
2195
2365
  /**
2196
2366
  * Create a perspective projection matrix from a field of view. Useful for generating projection matrices to be used with the WebXR API.
2197
2367
  * @param fov - The field of view.
@@ -2199,9 +2369,9 @@ export default class Matrix4
2199
2369
  * @param far - The far bound of the frustum.
2200
2370
  * @param out - The matrix to store the result in.
2201
2371
  * @returns The perspective projection matrix.
2202
- * @see [Camera matrix](https://en.wikipedia.org/wiki/Camera_matrix)
2203
- * @see [3D projection](https://en.wikipedia.org/wiki/3D_projection)
2204
- * @see [WebXR API](https://developer.mozilla.org/en-US/docs/Web/API/WebXR_Device_API)
2372
+ * @see {@link https://en.wikipedia.org/wiki/Camera_matrix | Camera matrix}
2373
+ * @see {@link https://en.wikipedia.org/wiki/3D_projection | 3D projection}
2374
+ * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/WebXR_Device_API | WebXR API}
2205
2375
  */
2206
2376
  public static perspectiveFromFieldOfView<T extends Matrix4Like = Matrix4>(
2207
2377
  fov: FieldOfView,
@@ -2213,7 +2383,7 @@ export default class Matrix4
2213
2383
  }
2214
2384
 
2215
2385
  /**
2216
- * Generate an orthogonal projection matrix with the given bounds.
2386
+ * Generate an orthogonal projection matrix with the given bounds such that the near and far clip planes correspond to a normalized device coordinate Z range of `[-1, 1]` (OpenGL/WebGL).
2217
2387
  * @param left - The left bound of the frustum.
2218
2388
  * @param right - The right bound of the frustum.
2219
2389
  * @param bottom - The bottom bound of the frustum.
@@ -2222,8 +2392,8 @@ export default class Matrix4
2222
2392
  * @param far - The far bound of the frustum.
2223
2393
  * @param out - The matrix to store the result in.
2224
2394
  * @returns The frustum matrix.
2225
- * @see [Camera matrix](https://en.wikipedia.org/wiki/Camera_matrix)
2226
- * @see [3D projection](https://en.wikipedia.org/wiki/3D_projection)
2395
+ * @see {@link https://en.wikipedia.org/wiki/Camera_matrix | Camera matrix}
2396
+ * @see {@link https://en.wikipedia.org/wiki/3D_projection | 3D projection}
2227
2397
  */
2228
2398
  public static ortho<T extends Matrix4Like = Matrix4>(
2229
2399
  left: number,
@@ -2237,6 +2407,31 @@ export default class Matrix4
2237
2407
  return ortho(left, right, bottom, top, near, far, out);
2238
2408
  }
2239
2409
 
2410
+ /**
2411
+ * Generate an orthogonal projection matrix with the given bounds such that the near and far clip planes correspond to a normalized device coordinate Z range of `[0, 1]` (WebGPU/Vulkan/DirectX/Metal).
2412
+ * @param left - The left bound of the frustum.
2413
+ * @param right - The right bound of the frustum.
2414
+ * @param bottom - The bottom bound of the frustum.
2415
+ * @param top - The top bound of the frustum.
2416
+ * @param near - The near bound of the frustum.
2417
+ * @param far - The far bound of the frustum.
2418
+ * @param out - The matrix to store the result in.
2419
+ * @returns The frustum matrix.
2420
+ * @see {@link https://en.wikipedia.org/wiki/Camera_matrix | Camera matrix}
2421
+ * @see {@link https://en.wikipedia.org/wiki/3D_projection | 3D projection}
2422
+ */
2423
+ public static orthoGpu<T extends Matrix4Like = Matrix4>(
2424
+ left: number,
2425
+ right: number,
2426
+ bottom: number,
2427
+ top: number,
2428
+ near: number,
2429
+ far: number,
2430
+ out: T = new Matrix4() as Matrix4 & T
2431
+ ): T {
2432
+ return orthoGpu(left, right, bottom, top, near, far, out);
2433
+ }
2434
+
2240
2435
  /**
2241
2436
  * Generate a look-at matrix. If you want a matrix that actually makes an object look at another object, use `targetTo` instead.
2242
2437
  * @param eye - The position of the viewer.
@@ -2244,7 +2439,7 @@ export default class Matrix4
2244
2439
  * @param up - The local up direction.
2245
2440
  * @param out - The matrix to store the result in.
2246
2441
  * @returns The look-at matrix.
2247
- * @see [Transformation matrix](https://en.wikipedia.org/wiki/Transformation_matrix)
2442
+ * @see {@link https://en.wikipedia.org/wiki/Transformation_matrix | Transformation matrix}
2248
2443
  */
2249
2444
  public static lookAt<T extends Matrix4Like = Matrix4>(
2250
2445
  eye: Vector3Like,
@@ -2262,7 +2457,7 @@ export default class Matrix4
2262
2457
  * @param up - The local up direction.
2263
2458
  * @param out - The matrix to store the result in.
2264
2459
  * @returns The transformation matrix.
2265
- * @see [Transformation matrix](https://en.wikipedia.org/wiki/Transformation_matrix)
2460
+ * @see {@link https://en.wikipedia.org/wiki/Transformation_matrix | Transformation matrix}
2266
2461
  */
2267
2462
  public static targetTo<T extends Matrix4Like = Matrix4>(
2268
2463
  eye: Vector3Like,
@@ -2336,7 +2531,7 @@ export default class Matrix4
2336
2531
 
2337
2532
  /**
2338
2533
  * Create a four-by-four identity matrix.
2339
- * @see [Identity matrix](https://en.wikipedia.org/wiki/Identity_matrix)
2534
+ * @see {@link https://en.wikipedia.org/wiki/Identity_matrix | Identity matrix}
2340
2535
  */
2341
2536
  public constructor() {
2342
2537
  super(16);
@@ -2427,7 +2622,7 @@ export default class Matrix4
2427
2622
  * @param matrix - The other matrix.
2428
2623
  * @param out - The matrix to store the result in.
2429
2624
  * @returns The sum of the matrices.
2430
- * @see [Matrix addition](https://en.wikipedia.org/wiki/Matrix_addition)
2625
+ * @see {@link https://en.wikipedia.org/wiki/Matrix_addition | Matrix addition}
2431
2626
  */
2432
2627
  public add<T extends Matrix4Like = Matrix4>(
2433
2628
  matrix: Matrix4Like,
@@ -2440,7 +2635,7 @@ export default class Matrix4
2440
2635
  * Calculate the adjugate of this matrix.
2441
2636
  * @param out - The matrix to store the result in.
2442
2637
  * @returns The adjugate of this matrix.
2443
- * @see [Adjugate matrix](https://en.wikipedia.org/wiki/Adjugate_matrix)
2638
+ * @see {@link https://en.wikipedia.org/wiki/Adjugate_matrix | Adjugate matrix}
2444
2639
  */
2445
2640
  public adjoint<T extends Matrix4Like = Matrix4>(
2446
2641
  out: T = new Matrix4() as Matrix4 & T
@@ -2470,7 +2665,7 @@ export default class Matrix4
2470
2665
 
2471
2666
  /**
2472
2667
  * Get the Frobenius norm of this matrix.
2473
- * @see [Matrix norm](https://en.wikipedia.org/wiki/Matrix_norm)
2668
+ * @see {@link https://en.wikipedia.org/wiki/Matrix_norm | Matrix norm}
2474
2669
  */
2475
2670
  public get frob(): number {
2476
2671
  return frob(this);
@@ -2481,7 +2676,7 @@ export default class Matrix4
2481
2676
  * @param matrix - The other matrix.
2482
2677
  * @param out - The matrix to store the result in.
2483
2678
  * @returns The product of the matrices.
2484
- * @see [Matrix multiplication](https://en.wikipedia.org/wiki/Matrix_multiplication)
2679
+ * @see {@link https://en.wikipedia.org/wiki/Matrix_multiplication | Matrix multiplication}
2485
2680
  */
2486
2681
  public multiply<T extends Matrix4Like = Matrix4>(
2487
2682
  matrix: Matrix4Like,
@@ -2495,7 +2690,7 @@ export default class Matrix4
2495
2690
  * @param scalar - The scalar value.
2496
2691
  * @param out - The matrix to store the result in.
2497
2692
  * @returns The product of the matrix and the scalar value.
2498
- * @see [Matrix multiplication](https://en.wikipedia.org/wiki/Matrix_multiplication)
2693
+ * @see {@link https://en.wikipedia.org/wiki/Matrix_multiplication | Matrix multiplication}
2499
2694
  */
2500
2695
  public multiplyScalar<T extends Matrix4Like = Matrix4>(
2501
2696
  scalar: number,
@@ -2510,8 +2705,8 @@ export default class Matrix4
2510
2705
  * @param scalar - The scalar.
2511
2706
  * @param out - The matrix to store the result in.
2512
2707
  * @returns The sum.
2513
- * @see [Matrix addition](https://en.wikipedia.org/wiki/Matrix_addition)
2514
- * @see [Matrix multiplication](https://en.wikipedia.org/wiki/Matrix_multiplication)
2708
+ * @see {@link https://en.wikipedia.org/wiki/Matrix_addition | Matrix addition}
2709
+ * @see {@link https://en.wikipedia.org/wiki/Matrix_multiplication | Matrix multiplication}
2515
2710
  */
2516
2711
  public multiplyScalarAndAdd<T extends Matrix4Like = Matrix4>(
2517
2712
  matrix: Matrix4Like,
@@ -2526,7 +2721,7 @@ export default class Matrix4
2526
2721
  * @param matrix - The other matrix.
2527
2722
  * @param out - The matrix to store the result in.
2528
2723
  * @returns The difference between the matrices.
2529
- * @see [Matrix addition](https://en.wikipedia.org/wiki/Matrix_addition)
2724
+ * @see {@link https://en.wikipedia.org/wiki/Matrix_addition | Matrix addition}
2530
2725
  */
2531
2726
  public subtract<T extends Matrix4Like = Matrix4>(
2532
2727
  matrix: Matrix4Like,
@@ -2539,7 +2734,7 @@ export default class Matrix4
2539
2734
  * Transpose this matrix.
2540
2735
  * @param out - The matrix to store the result in.
2541
2736
  * @returns The transpose of this matrix.
2542
- * @see [Transpose](https://en.wikipedia.org/wiki/Transpose)
2737
+ * @see {@link https://en.wikipedia.org/wiki/Transpose | Transpose}
2543
2738
  */
2544
2739
  public transpose<T extends Matrix4Like = Matrix4>(
2545
2740
  out: T = new Matrix4() as Matrix4 & T
@@ -2549,7 +2744,7 @@ export default class Matrix4
2549
2744
 
2550
2745
  /**
2551
2746
  * Get the determinant of this matrix.
2552
- * @see [Determinant](https://en.wikipedia.org/wiki/Determinant)
2747
+ * @see {@link https://en.wikipedia.org/wiki/Determinant | Determinant}
2553
2748
  */
2554
2749
  public get determinant(): number {
2555
2750
  return determinant(this);
@@ -2558,7 +2753,7 @@ export default class Matrix4
2558
2753
  /**
2559
2754
  * Reset this matrix to identity.
2560
2755
  * @returns This matrix.
2561
- * @see [Identity matrix](https://en.wikipedia.org/wiki/Identity_matrix)
2756
+ * @see {@link https://en.wikipedia.org/wiki/Identity_matrix | Identity matrix}
2562
2757
  */
2563
2758
  public identity(): this {
2564
2759
  return identity(this);
@@ -2568,7 +2763,7 @@ export default class Matrix4
2568
2763
  * Invert this matrix.
2569
2764
  * @param out - The matrix to store the result in.
2570
2765
  * @returns The inverted matrix.
2571
- * @see [Invertible matrix](https://en.wikipedia.org/wiki/Invertible_matrix)
2766
+ * @see {@link https://en.wikipedia.org/wiki/Invertible_matrix | Invertible matrix}
2572
2767
  */
2573
2768
  public invert<T extends Matrix4Like = Matrix4>(
2574
2769
  out: T = new Matrix4() as Matrix4 & T
@@ -2581,7 +2776,7 @@ export default class Matrix4
2581
2776
  * @param vector - The scaling vector.
2582
2777
  * @param out - The matrix to store the result in.
2583
2778
  * @returns The scaled matrix.
2584
- * @see [Transformation matrix](https://en.wikipedia.org/wiki/Transformation_matrix)
2779
+ * @see {@link https://en.wikipedia.org/wiki/Transformation_matrix | Transformation matrix}
2585
2780
  */
2586
2781
  public scale<T extends Matrix4Like = Matrix4>(
2587
2782
  vector: Vector3Like,
@@ -2595,7 +2790,7 @@ export default class Matrix4
2595
2790
  * @param vector - The translation vector.
2596
2791
  * @param out - The matrix to store the result in.
2597
2792
  * @returns The translated matrix.
2598
- * @see [Transformation matrix](https://en.wikipedia.org/wiki/Transformation_matrix)
2793
+ * @see {@link https://en.wikipedia.org/wiki/Transformation_matrix | Transformation matrix}
2599
2794
  */
2600
2795
  public translate<T extends Matrix4Like = Matrix4>(
2601
2796
  vector: Vector3Like,
@@ -2610,7 +2805,7 @@ export default class Matrix4
2610
2805
  * @param axis - The axis.
2611
2806
  * @param out - The matrix to store the result in.
2612
2807
  * @returns The rotated matrix.
2613
- * @see [Rotation matrix](https://en.wikipedia.org/wiki/Rotation_matrix)
2808
+ * @see {@link https://en.wikipedia.org/wiki/Rotation_matrix | Rotation matrix}
2614
2809
  */
2615
2810
  public rotate<T extends Matrix4Like = Matrix4>(
2616
2811
  r: number,
@@ -2625,7 +2820,7 @@ export default class Matrix4
2625
2820
  * @param r - The angle in radians.
2626
2821
  * @param out - The matrix to store the result in.
2627
2822
  * @returns The rotated matrix.
2628
- * @see [Rotation matrix](https://en.wikipedia.org/wiki/Rotation_matrix)
2823
+ * @see {@link https://en.wikipedia.org/wiki/Rotation_matrix | Rotation matrix}
2629
2824
  */
2630
2825
  public rotateX<T extends Matrix4Like = Matrix4>(
2631
2826
  r: number,
@@ -2639,7 +2834,7 @@ export default class Matrix4
2639
2834
  * @param r - The angle in radians.
2640
2835
  * @param out - The matrix to store the result in.
2641
2836
  * @returns The rotated matrix.
2642
- * @see [Rotation matrix](https://en.wikipedia.org/wiki/Rotation_matrix)
2837
+ * @see {@link https://en.wikipedia.org/wiki/Rotation_matrix | Rotation matrix}
2643
2838
  */
2644
2839
  public rotateY<T extends Matrix4Like = Matrix4>(
2645
2840
  r: number,
@@ -2653,7 +2848,7 @@ export default class Matrix4
2653
2848
  * @param r - The angle in radians.
2654
2849
  * @param out - The matrix to store the result in.
2655
2850
  * @returns The rotated matrix.
2656
- * @see [Rotation matrix](https://en.wikipedia.org/wiki/Rotation_matrix)
2851
+ * @see {@link https://en.wikipedia.org/wiki/Rotation_matrix | Rotation matrix}
2657
2852
  */
2658
2853
  public rotateZ<T extends Matrix4Like = Matrix4>(
2659
2854
  r: number,
@@ -2666,7 +2861,7 @@ export default class Matrix4
2666
2861
  * Get the translation vector component of this transformation matrix.
2667
2862
  * @param out - The vector to store the result in.
2668
2863
  * @returns The translation.
2669
- * @see [Transformation matrix](https://en.wikipedia.org/wiki/Transformation_matrix)
2864
+ * @see {@link https://en.wikipedia.org/wiki/Transformation_matrix | Transformation matrix}
2670
2865
  */
2671
2866
  public getTranslation<T extends Vector3Like = Vector3>(
2672
2867
  out: T = new Vector3() as Vector3 & T
@@ -2679,7 +2874,7 @@ export default class Matrix4
2679
2874
  * @param translation - The translation vector.
2680
2875
  * @param out - The matrix to store the result in.
2681
2876
  * @returns The transformation matrix.
2682
- * @see [Transformation matrix](https://en.wikipedia.org/wiki/Transformation_matrix)
2877
+ * @see {@link https://en.wikipedia.org/wiki/Transformation_matrix | Transformation matrix}
2683
2878
  */
2684
2879
  public setTranslation<T extends Matrix4Like = Matrix4>(
2685
2880
  translation: Vector3Like,
@@ -2692,7 +2887,7 @@ export default class Matrix4
2692
2887
  * Get the scaling vector component of this transformation matrix.
2693
2888
  * @param out - The vector to store the result in.
2694
2889
  * @returns The scaling.
2695
- * @see [Transformation matrix](https://en.wikipedia.org/wiki/Transformation_matrix)
2890
+ * @see {@link https://en.wikipedia.org/wiki/Transformation_matrix | Transformation matrix}
2696
2891
  */
2697
2892
  public getScaling<T extends Vector3Like = Vector3>(
2698
2893
  out: T = new Vector3() as Vector3 & T
@@ -2704,7 +2899,7 @@ export default class Matrix4
2704
2899
  * Get the scaling vector component of this transformation matrix.
2705
2900
  * @param out - The quaternion to store the result in.
2706
2901
  * @returns The rotation.
2707
- * @see [Rotation matrix](https://en.wikipedia.org/wiki/Rotation_matrix)
2902
+ * @see {@link https://en.wikipedia.org/wiki/Rotation_matrix | Rotation matrix}
2708
2903
  */
2709
2904
  public getRotation<T extends QuaternionLike = Quaternion>(
2710
2905
  out: T = new Quaternion() as Quaternion & T