@lakuna/umath 1.3.9 → 1.4.2
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.
- package/README.md +1 -1
- package/dist/algorithms/approx.d.ts +9 -0
- package/dist/algorithms/approx.d.ts.map +1 -0
- package/dist/algorithms/approx.js +12 -0
- package/dist/algorithms/approx.js.map +1 -0
- package/dist/algorithms/approxRelative.d.ts +9 -0
- package/dist/algorithms/approxRelative.d.ts.map +1 -0
- package/dist/algorithms/approxRelative.js +12 -0
- package/dist/algorithms/approxRelative.js.map +1 -0
- package/dist/algorithms/combinations.d.ts +2 -1
- package/dist/algorithms/combinations.d.ts.map +1 -1
- package/dist/algorithms/combinations.js +2 -1
- package/dist/algorithms/combinations.js.map +1 -1
- package/dist/algorithms/degreesToRadians.d.ts +3 -2
- package/dist/algorithms/degreesToRadians.d.ts.map +1 -1
- package/dist/algorithms/degreesToRadians.js +5 -3
- package/dist/algorithms/degreesToRadians.js.map +1 -1
- package/dist/algorithms/factorial.d.ts +2 -1
- package/dist/algorithms/factorial.d.ts.map +1 -1
- package/dist/algorithms/factorial.js +2 -1
- package/dist/algorithms/factorial.js.map +1 -1
- package/dist/algorithms/fibonacci.d.ts +2 -1
- package/dist/algorithms/fibonacci.d.ts.map +1 -1
- package/dist/algorithms/fibonacci.js +6 -2
- package/dist/algorithms/fibonacci.js.map +1 -1
- package/dist/algorithms/greatestCommonDivisor.d.ts +4 -2
- package/dist/algorithms/greatestCommonDivisor.d.ts.map +1 -1
- package/dist/algorithms/greatestCommonDivisor.js +5 -2
- package/dist/algorithms/greatestCommonDivisor.js.map +1 -1
- package/dist/algorithms/hypergeometricPmf.d.ts +3 -2
- package/dist/algorithms/hypergeometricPmf.d.ts.map +1 -1
- package/dist/algorithms/hypergeometricPmf.js +3 -2
- package/dist/algorithms/hypergeometricPmf.js.map +1 -1
- package/dist/algorithms/isPrime.d.ts +2 -1
- package/dist/algorithms/isPrime.d.ts.map +1 -1
- package/dist/algorithms/isPrime.js +2 -1
- package/dist/algorithms/isPrime.js.map +1 -1
- package/dist/algorithms/permutations.d.ts +2 -1
- package/dist/algorithms/permutations.d.ts.map +1 -1
- package/dist/algorithms/permutations.js +2 -1
- package/dist/algorithms/permutations.js.map +1 -1
- package/dist/algorithms/primeFactorization.d.ts +2 -1
- package/dist/algorithms/primeFactorization.d.ts.map +1 -1
- package/dist/algorithms/primeFactorization.js +2 -1
- package/dist/algorithms/primeFactorization.js.map +1 -1
- package/dist/algorithms/radiansToDegrees.d.ts +3 -2
- package/dist/algorithms/radiansToDegrees.d.ts.map +1 -1
- package/dist/algorithms/radiansToDegrees.js +5 -3
- package/dist/algorithms/radiansToDegrees.js.map +1 -1
- package/dist/algorithms/summation.d.ts +2 -1
- package/dist/algorithms/summation.d.ts.map +1 -1
- package/dist/algorithms/summation.js +2 -1
- package/dist/algorithms/summation.js.map +1 -1
- package/dist/linalg/DualQuaternion.d.ts +102 -32
- package/dist/linalg/DualQuaternion.d.ts.map +1 -1
- package/dist/linalg/DualQuaternion.js +243 -272
- package/dist/linalg/DualQuaternion.js.map +1 -1
- package/dist/linalg/Matrix.d.ts +14 -10
- package/dist/linalg/Matrix.d.ts.map +1 -1
- package/dist/linalg/Matrix2.d.ts +74 -51
- package/dist/linalg/Matrix2.d.ts.map +1 -1
- package/dist/linalg/Matrix2.js +95 -171
- package/dist/linalg/Matrix2.js.map +1 -1
- package/dist/linalg/Matrix3.d.ts +122 -72
- package/dist/linalg/Matrix3.d.ts.map +1 -1
- package/dist/linalg/Matrix3.js +186 -355
- package/dist/linalg/Matrix3.js.map +1 -1
- package/dist/linalg/Matrix4.d.ts +266 -149
- package/dist/linalg/Matrix4.d.ts.map +1 -1
- package/dist/linalg/Matrix4.js +512 -852
- package/dist/linalg/Matrix4.js.map +1 -1
- package/dist/linalg/Quaternion.d.ts +252 -34
- package/dist/linalg/Quaternion.d.ts.map +1 -1
- package/dist/linalg/Quaternion.js +436 -166
- package/dist/linalg/Quaternion.js.map +1 -1
- package/dist/linalg/SlowMatrix.d.ts +10 -9
- package/dist/linalg/SlowMatrix.d.ts.map +1 -1
- package/dist/linalg/SlowMatrix.js +10 -9
- package/dist/linalg/SlowMatrix.js.map +1 -1
- package/dist/linalg/SlowSquareMatrix.d.ts +10 -9
- package/dist/linalg/SlowSquareMatrix.d.ts.map +1 -1
- package/dist/linalg/SlowSquareMatrix.js +10 -9
- package/dist/linalg/SlowSquareMatrix.js.map +1 -1
- package/dist/linalg/SquareMatrix.d.ts +6 -5
- package/dist/linalg/SquareMatrix.d.ts.map +1 -1
- package/dist/linalg/Vector.d.ts +8 -4
- package/dist/linalg/Vector.d.ts.map +1 -1
- package/dist/linalg/Vector2.d.ts +82 -31
- package/dist/linalg/Vector2.d.ts.map +1 -1
- package/dist/linalg/Vector2.js +112 -154
- package/dist/linalg/Vector2.js.map +1 -1
- package/dist/linalg/Vector3.d.ts +93 -41
- package/dist/linalg/Vector3.d.ts.map +1 -1
- package/dist/linalg/Vector3.js +171 -282
- package/dist/linalg/Vector3.js.map +1 -1
- package/dist/linalg/Vector4.d.ts +71 -21
- package/dist/linalg/Vector4.d.ts.map +1 -1
- package/dist/linalg/Vector4.js +121 -195
- package/dist/linalg/Vector4.js.map +1 -1
- package/dist/types/AxisAngle.d.ts +4 -1
- package/dist/types/AxisAngle.d.ts.map +1 -1
- package/dist/types/FieldOfView.d.ts +4 -1
- package/dist/types/FieldOfView.d.ts.map +1 -1
- package/dist/utility/BigNumber.d.ts +4 -1
- package/dist/utility/BigNumber.d.ts.map +1 -1
- package/dist/utility/BigNumber.js +4 -1
- package/dist/utility/BigNumber.js.map +1 -1
- package/dist/utility/MagnitudeError.d.ts +4 -1
- package/dist/utility/MagnitudeError.d.ts.map +1 -1
- package/dist/utility/MagnitudeError.js +4 -1
- package/dist/utility/MagnitudeError.js.map +1 -1
- package/dist/utility/MatrixSizeError.d.ts +4 -1
- package/dist/utility/MatrixSizeError.d.ts.map +1 -1
- package/dist/utility/MatrixSizeError.js +4 -1
- package/dist/utility/MatrixSizeError.js.map +1 -1
- package/dist/utility/PartialMatrixError.d.ts +4 -1
- package/dist/utility/PartialMatrixError.d.ts.map +1 -1
- package/dist/utility/PartialMatrixError.js +4 -1
- package/dist/utility/PartialMatrixError.js.map +1 -1
- package/dist/utility/SingularMatrixError.d.ts +2 -1
- package/dist/utility/SingularMatrixError.d.ts.map +1 -1
- package/dist/utility/SingularMatrixError.js +2 -1
- package/dist/utility/SingularMatrixError.js.map +1 -1
- package/dist/utility/epsilon.d.ts +4 -1
- package/dist/utility/epsilon.d.ts.map +1 -1
- package/dist/utility/epsilon.js +4 -1
- package/dist/utility/epsilon.js.map +1 -1
- package/package.json +11 -11
- package/src/algorithms/approx.ts +12 -0
- package/src/algorithms/approxRelative.ts +12 -0
- package/src/algorithms/combinations.ts +2 -1
- package/src/algorithms/degreesToRadians.ts +6 -3
- package/src/algorithms/factorial.ts +3 -1
- package/src/algorithms/fibonacci.ts +7 -2
- package/src/algorithms/greatestCommonDivisor.ts +9 -4
- package/src/algorithms/hypergeometricPmf.ts +3 -2
- package/src/algorithms/isPrime.ts +2 -1
- package/src/algorithms/permutations.ts +2 -1
- package/src/algorithms/primeFactorization.ts +2 -1
- package/src/algorithms/radiansToDegrees.ts +6 -3
- package/src/algorithms/summation.ts +2 -1
- package/src/linalg/DualQuaternion.ts +424 -289
- package/src/linalg/Matrix.ts +14 -10
- package/src/linalg/Matrix2.ts +141 -188
- package/src/linalg/Matrix3.ts +400 -375
- package/src/linalg/Matrix4.ts +1083 -905
- package/src/linalg/Quaternion.ts +706 -188
- package/src/linalg/SlowMatrix.ts +10 -9
- package/src/linalg/SlowSquareMatrix.ts +10 -9
- package/src/linalg/SquareMatrix.ts +6 -5
- package/src/linalg/Vector.ts +8 -4
- package/src/linalg/Vector2.ts +146 -173
- package/src/linalg/Vector3.ts +293 -326
- package/src/linalg/Vector4.ts +227 -215
- package/src/types/AxisAngle.ts +4 -1
- package/src/types/FieldOfView.ts +4 -1
- package/src/utility/BigNumber.ts +6 -3
- package/src/utility/MagnitudeError.ts +4 -1
- package/src/utility/MatrixSizeError.ts +4 -1
- package/src/utility/PartialMatrixError.ts +4 -1
- package/src/utility/SingularMatrixError.ts +2 -1
- package/src/utility/epsilon.ts +4 -1
|
@@ -1,25 +1,127 @@
|
|
|
1
|
-
import { createMatrix3Like } from "./Matrix3.js";
|
|
2
|
-
import {
|
|
1
|
+
import { createMatrix3Like, fromValues as matrix3FromValues } from "./Matrix3.js";
|
|
2
|
+
import Vector3, { createVector3Like, cross as vector3Cross, dot as vector3Dot, fromValues as vector3FromValues, getMagnitude as vector3GetMagnitude, normalize as vector3Normalize } from "./Vector3.js";
|
|
3
|
+
import { add as vector4Add, copy as vector4Copy, dot as vector4Dot, exactEquals as vector4ExactEquals, fromValues as vector4FromValues, getMagnitude as vector4GetMagnitude, getSquaredMagnitude as vector4GetSquaredMagnitude, lerp as vector4Lerp, normalize as vector4Normalize, scale as vector4Scale } from "./Vector4.js";
|
|
3
4
|
import epsilon from "../utility/epsilon.js";
|
|
5
|
+
import radiansToDegrees from "../algorithms/radiansToDegrees.js";
|
|
4
6
|
/**
|
|
5
7
|
* Create a quaternion-like object.
|
|
6
8
|
* @returns A quaternion-like object.
|
|
9
|
+
* @public
|
|
7
10
|
*/
|
|
8
11
|
export const createQuaternionLike = () => {
|
|
9
12
|
return new Float32Array(4);
|
|
10
13
|
};
|
|
14
|
+
/**
|
|
15
|
+
* Create a quaternion with the given values.
|
|
16
|
+
* @param x - The first component.
|
|
17
|
+
* @param y - The second component.
|
|
18
|
+
* @param z - The third component.
|
|
19
|
+
* @param w - The fourth component.
|
|
20
|
+
* @param out - The quaternion to store the result in.
|
|
21
|
+
* @returns A new quaternion.
|
|
22
|
+
* @public
|
|
23
|
+
*/
|
|
24
|
+
export const fromValues = vector4FromValues;
|
|
25
|
+
/**
|
|
26
|
+
* Add two quaternions.
|
|
27
|
+
* @param a - The first quaternion
|
|
28
|
+
* @param b - The second quaternion.
|
|
29
|
+
* @param out - The quaternion to store the result in.
|
|
30
|
+
* @returns The sum of the quaternions.
|
|
31
|
+
* @public
|
|
32
|
+
*/
|
|
33
|
+
export const add = vector4Add;
|
|
34
|
+
/**
|
|
35
|
+
* Copy the values from one quaternion to another.
|
|
36
|
+
* @param quaternion - The quaternion to copy.
|
|
37
|
+
* @param out - The quaternion to store the result in.
|
|
38
|
+
* @returns The copy.
|
|
39
|
+
* @public
|
|
40
|
+
*/
|
|
41
|
+
export const copy = vector4Copy;
|
|
42
|
+
/**
|
|
43
|
+
* Calculate the dot product of two quaternions.
|
|
44
|
+
* @param a - The first quaternion
|
|
45
|
+
* @param b - The second quaternion.
|
|
46
|
+
* @returns The dot product.
|
|
47
|
+
* @public
|
|
48
|
+
*/
|
|
49
|
+
export const dot = vector4Dot;
|
|
50
|
+
/**
|
|
51
|
+
* Determine whether or not two unit quaternions point in roughly the same direction.
|
|
52
|
+
* @param a - The first unit quaternion.
|
|
53
|
+
* @param b - The second unit quaternion.
|
|
54
|
+
* @returns Whether or not the unit quaternions point in the same direction.
|
|
55
|
+
* @public
|
|
56
|
+
*/
|
|
57
|
+
export const equals = (a, b) => Math.abs(dot(a, b)) >= 1 - epsilon;
|
|
58
|
+
/**
|
|
59
|
+
* Determine whether or not two quaternions are exactly equivalent.
|
|
60
|
+
* @param a - The first quaternion.
|
|
61
|
+
* @param b - The second quaternion.
|
|
62
|
+
* @returns Whether or not the quaternions are equivalent.
|
|
63
|
+
* @public
|
|
64
|
+
*/
|
|
65
|
+
export const exactEquals = vector4ExactEquals;
|
|
66
|
+
/**
|
|
67
|
+
* Calculate the magnitude (length) of a quaternion.
|
|
68
|
+
* @param quaternion - The quaternion.
|
|
69
|
+
* @returns The magnitude.
|
|
70
|
+
* @public
|
|
71
|
+
*/
|
|
72
|
+
export const getMagnitude = vector4GetMagnitude;
|
|
73
|
+
/**
|
|
74
|
+
* Calculate the squared magnitude (length) of a quaternion.
|
|
75
|
+
* @param quaternion - The quaternion.
|
|
76
|
+
* @returns The squared magnitude.
|
|
77
|
+
* @public
|
|
78
|
+
*/
|
|
79
|
+
export const getSquaredMagnitude = vector4GetSquaredMagnitude;
|
|
80
|
+
/**
|
|
81
|
+
* Perform a linear interpolation between two quaternions.
|
|
82
|
+
* @param a - The first quaternion.
|
|
83
|
+
* @param b - The second quaternion.
|
|
84
|
+
* @param t - The interpolation amount (in `[0,1]`).
|
|
85
|
+
* @param out - The quaternion to store the result in.
|
|
86
|
+
* @returns The interpolated quaternion.
|
|
87
|
+
* @see {@link https://en.wikipedia.org/wiki/Linear_interpolation | Linear interpolation}
|
|
88
|
+
* @public
|
|
89
|
+
*/
|
|
90
|
+
export const lerp = vector4Lerp;
|
|
91
|
+
/**
|
|
92
|
+
* Normalize a quaternion.
|
|
93
|
+
* @param quaternion - The quaternion.
|
|
94
|
+
* @param out - The quaternion to store the result in.
|
|
95
|
+
* @returns The normalized quaternion.
|
|
96
|
+
* @public
|
|
97
|
+
*/
|
|
98
|
+
export const normalize = vector4Normalize;
|
|
99
|
+
/**
|
|
100
|
+
* Scale a quaternion by a scalar.
|
|
101
|
+
* @param quaternion - The multiplier.
|
|
102
|
+
* @param scalar - The multiplicand.
|
|
103
|
+
* @param out - The quaternion to store the result in.
|
|
104
|
+
* @returns The product.
|
|
105
|
+
* @public
|
|
106
|
+
*/
|
|
107
|
+
export const scale = vector4Scale;
|
|
11
108
|
/**
|
|
12
109
|
* Create a quaternion from a three-by-three rotation matrix.
|
|
13
110
|
* @param matrix - The matrix.
|
|
14
111
|
* @param out - The quaternion to store the result in.
|
|
15
|
-
* @returns The quaternion.
|
|
16
|
-
* @see
|
|
112
|
+
* @returns The quaternion (not normalized).
|
|
113
|
+
* @see {@link https://en.wikipedia.org/wiki/Rotation_matrix | Rotation matrix}
|
|
114
|
+
* @see Ken Shoemake. Quaternion calculus and fast animation. SIGGRAPH Course Notes, 10:101-121, 1987.
|
|
115
|
+
* @public
|
|
17
116
|
*/
|
|
18
117
|
export const fromMatrix3 = (matrix, out) => {
|
|
19
|
-
const
|
|
118
|
+
const m0 = matrix[0];
|
|
119
|
+
const m4 = matrix[4];
|
|
120
|
+
const m8 = matrix[8];
|
|
121
|
+
const fTrace = m0 + m4 + m8;
|
|
20
122
|
if (fTrace > 0) {
|
|
21
123
|
let fRoot = Math.sqrt(fTrace + 1);
|
|
22
|
-
out[3] =
|
|
124
|
+
out[3] = fRoot / 2;
|
|
23
125
|
fRoot = 0.5 / fRoot;
|
|
24
126
|
out[0] = (matrix[5] - matrix[7]) * fRoot;
|
|
25
127
|
out[1] = (matrix[6] - matrix[2]) * fRoot;
|
|
@@ -27,10 +129,10 @@ export const fromMatrix3 = (matrix, out) => {
|
|
|
27
129
|
return out;
|
|
28
130
|
}
|
|
29
131
|
let i = 0;
|
|
30
|
-
if (
|
|
132
|
+
if (m4 > m0) {
|
|
31
133
|
i = 1;
|
|
32
134
|
}
|
|
33
|
-
if (
|
|
135
|
+
if (m8 > matrix[(i * 3 + i)]) {
|
|
34
136
|
i = 2;
|
|
35
137
|
}
|
|
36
138
|
const j = ((i + 1) % 3);
|
|
@@ -39,7 +141,7 @@ export const fromMatrix3 = (matrix, out) => {
|
|
|
39
141
|
matrix[(j * 3 + j)] -
|
|
40
142
|
matrix[(k * 3 + k)] +
|
|
41
143
|
1);
|
|
42
|
-
out[i] =
|
|
144
|
+
out[i] = fRoot / 2;
|
|
43
145
|
fRoot = 0.5 / fRoot;
|
|
44
146
|
out[3] =
|
|
45
147
|
(matrix[(j * 3 + k)] - matrix[(k * 3 + j)]) *
|
|
@@ -52,79 +154,237 @@ export const fromMatrix3 = (matrix, out) => {
|
|
|
52
154
|
fRoot;
|
|
53
155
|
return out;
|
|
54
156
|
};
|
|
157
|
+
const ratio = Math.PI / 360;
|
|
55
158
|
/**
|
|
56
|
-
* Create a quaternion from equivalent
|
|
57
|
-
* @param x - The X angle.
|
|
58
|
-
* @param y - The Y angle.
|
|
59
|
-
* @param z - The Z angle.
|
|
159
|
+
* Create a quaternion from equivalent x-y'-z" (intrinsic) Tait-Bryan angles.
|
|
160
|
+
* @param x - The X angle in degrees.
|
|
161
|
+
* @param y - The Y angle in degrees.
|
|
162
|
+
* @param z - The Z angle in degrees.
|
|
60
163
|
* @param out - The quaternion to store the result in.
|
|
61
164
|
* @returns The quaternion.
|
|
62
|
-
* @see
|
|
165
|
+
* @see {@link https://en.wikipedia.org/wiki/Euler_angles | Euler angles}
|
|
166
|
+
* @public
|
|
63
167
|
*/
|
|
64
|
-
export const
|
|
65
|
-
const
|
|
66
|
-
const
|
|
67
|
-
const
|
|
68
|
-
const z2 = z * r;
|
|
168
|
+
export const fromEulerXyz = (x, y, z, out) => {
|
|
169
|
+
const x2 = x * ratio;
|
|
170
|
+
const y2 = y * ratio;
|
|
171
|
+
const z2 = z * ratio;
|
|
69
172
|
const sx = Math.sin(x2);
|
|
70
173
|
const cx = Math.cos(x2);
|
|
71
174
|
const sy = Math.sin(y2);
|
|
72
175
|
const cy = Math.cos(y2);
|
|
73
176
|
const sz = Math.sin(z2);
|
|
74
177
|
const cz = Math.cos(z2);
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
return out;
|
|
178
|
+
const sxcy = sx * cy;
|
|
179
|
+
const cxsy = cx * sy;
|
|
180
|
+
const cxcy = cx * cy;
|
|
181
|
+
const sxsy = sx * sy;
|
|
182
|
+
return fromValues(sxcy * cz - cxsy * sz, cxsy * cz + sxcy * sz, cxcy * sz - sxsy * cz, cxcy * cz + sxsy * sz, out);
|
|
183
|
+
};
|
|
184
|
+
/**
|
|
185
|
+
* Create a quaternion from equivalent x-z'-y" (intrinsic) Tait-Bryan angles.
|
|
186
|
+
* @param x - The X angle in degrees.
|
|
187
|
+
* @param z - The Z angle in degrees.
|
|
188
|
+
* @param y - The Y angle in degrees.
|
|
189
|
+
* @param out - The quaternion to store the result in.
|
|
190
|
+
* @returns The quaternion.
|
|
191
|
+
* @see {@link https://en.wikipedia.org/wiki/Euler_angles | Euler angles}
|
|
192
|
+
* @public
|
|
193
|
+
*/
|
|
194
|
+
export const fromEulerXzy = (x, z, y, out) => {
|
|
195
|
+
const x2 = x * ratio;
|
|
196
|
+
const y2 = y * ratio;
|
|
197
|
+
const z2 = z * ratio;
|
|
198
|
+
const sx = Math.sin(x2);
|
|
199
|
+
const cx = Math.cos(x2);
|
|
200
|
+
const sy = Math.sin(y2);
|
|
201
|
+
const cy = Math.cos(y2);
|
|
202
|
+
const sz = Math.sin(z2);
|
|
203
|
+
const cz = Math.cos(z2);
|
|
204
|
+
const sxcy = sx * cy;
|
|
205
|
+
const cxsy = cx * sy;
|
|
206
|
+
const cxcy = cx * cy;
|
|
207
|
+
const sxsy = sx * sy;
|
|
208
|
+
return fromValues(sxcy * cz - cxsy * sz, cxsy * cz - sxcy * sz, cxcy * sz + sxsy * cz, cxcy * cz + sxsy * sz, out);
|
|
209
|
+
};
|
|
210
|
+
/**
|
|
211
|
+
* Create a quaternion from equivalent y-x'-z" (intrinsic) Tait-Bryan angles.
|
|
212
|
+
* @param y - The Y angle in degrees.
|
|
213
|
+
* @param x - The X angle in degrees.
|
|
214
|
+
* @param z - The Z angle in degrees.
|
|
215
|
+
* @param out - The quaternion to store the result in.
|
|
216
|
+
* @returns The quaternion.
|
|
217
|
+
* @see {@link https://en.wikipedia.org/wiki/Euler_angles | Euler angles}
|
|
218
|
+
* @public
|
|
219
|
+
*/
|
|
220
|
+
export const fromEulerYxz = (y, x, z, out) => {
|
|
221
|
+
const x2 = x * ratio;
|
|
222
|
+
const y2 = y * ratio;
|
|
223
|
+
const z2 = z * ratio;
|
|
224
|
+
const sx = Math.sin(x2);
|
|
225
|
+
const cx = Math.cos(x2);
|
|
226
|
+
const sy = Math.sin(y2);
|
|
227
|
+
const cy = Math.cos(y2);
|
|
228
|
+
const sz = Math.sin(z2);
|
|
229
|
+
const cz = Math.cos(z2);
|
|
230
|
+
const sxcy = sx * cy;
|
|
231
|
+
const cxsy = cx * sy;
|
|
232
|
+
const cxcy = cx * cy;
|
|
233
|
+
const sxsy = sx * sy;
|
|
234
|
+
return fromValues(sxcy * cz + cxsy * sz, cxsy * cz - sxcy * sz, cxcy * sz - sxsy * cz, cxcy * cz + sxsy * sz, out);
|
|
235
|
+
};
|
|
236
|
+
/**
|
|
237
|
+
* Create a quaternion from equivalent y-z'-x" (intrinsic) Tait-Bryan angles.
|
|
238
|
+
* @param y - The Y angle in degrees.
|
|
239
|
+
* @param z - The Z angle in degrees.
|
|
240
|
+
* @param x - The X angle in degrees.
|
|
241
|
+
* @param out - The quaternion to store the result in.
|
|
242
|
+
* @returns The quaternion.
|
|
243
|
+
* @see {@link https://en.wikipedia.org/wiki/Euler_angles | Euler angles}
|
|
244
|
+
* @public
|
|
245
|
+
*/
|
|
246
|
+
export const fromEulerYzx = (y, z, x, out) => {
|
|
247
|
+
const x2 = x * ratio;
|
|
248
|
+
const y2 = y * ratio;
|
|
249
|
+
const z2 = z * ratio;
|
|
250
|
+
const sx = Math.sin(x2);
|
|
251
|
+
const cx = Math.cos(x2);
|
|
252
|
+
const sy = Math.sin(y2);
|
|
253
|
+
const cy = Math.cos(y2);
|
|
254
|
+
const sz = Math.sin(z2);
|
|
255
|
+
const cz = Math.cos(z2);
|
|
256
|
+
const sxcy = sx * cy;
|
|
257
|
+
const cxsy = cx * sy;
|
|
258
|
+
const cxcy = cx * cy;
|
|
259
|
+
const sxsy = sx * sy;
|
|
260
|
+
return fromValues(sxcy * cz + cxsy * sz, cxsy * cz + sxcy * sz, cxcy * sz - sxsy * cz, cxcy * cz - sxsy * sz, out);
|
|
261
|
+
};
|
|
262
|
+
/**
|
|
263
|
+
* Create a quaternion from equivalent z-x'-y" (intrinsic) Tait-Bryan angles.
|
|
264
|
+
* @param z - The Z angle in degrees.
|
|
265
|
+
* @param x - The X angle in degrees.
|
|
266
|
+
* @param y - The Y angle in degrees.
|
|
267
|
+
* @param out - The quaternion to store the result in.
|
|
268
|
+
* @returns The quaternion.
|
|
269
|
+
* @see {@link https://en.wikipedia.org/wiki/Euler_angles | Euler angles}
|
|
270
|
+
* @public
|
|
271
|
+
*/
|
|
272
|
+
export const fromEulerZxy = (z, x, y, out) => {
|
|
273
|
+
const x2 = x * ratio;
|
|
274
|
+
const y2 = y * ratio;
|
|
275
|
+
const z2 = z * ratio;
|
|
276
|
+
const sx = Math.sin(x2);
|
|
277
|
+
const cx = Math.cos(x2);
|
|
278
|
+
const sy = Math.sin(y2);
|
|
279
|
+
const cy = Math.cos(y2);
|
|
280
|
+
const sz = Math.sin(z2);
|
|
281
|
+
const cz = Math.cos(z2);
|
|
282
|
+
const sxcy = sx * cy;
|
|
283
|
+
const cxsy = cx * sy;
|
|
284
|
+
const cxcy = cx * cy;
|
|
285
|
+
const sxsy = sx * sy;
|
|
286
|
+
return fromValues(sxcy * cz - cxsy * sz, cxsy * cz + sxcy * sz, cxcy * sz + sxsy * cz, cxcy * cz - sxsy * sz, out);
|
|
287
|
+
};
|
|
288
|
+
/**
|
|
289
|
+
* Create a quaternion from equivalent z-y'-x" (intrinsic) Tait-Bryan angles.
|
|
290
|
+
* @param z - The Z angle (yaw) in degrees.
|
|
291
|
+
* @param y - The Y angle (pitch) in degrees.
|
|
292
|
+
* @param x - The X angle (roll) in degrees.
|
|
293
|
+
* @param out - The quaternion to store the result in.
|
|
294
|
+
* @returns The quaternion.
|
|
295
|
+
* @see {@link https://en.wikipedia.org/wiki/Euler_angles | Euler angles}
|
|
296
|
+
* @public
|
|
297
|
+
*/
|
|
298
|
+
export const fromEulerZyx = (z, y, x, out) => {
|
|
299
|
+
const x2 = x * ratio;
|
|
300
|
+
const y2 = y * ratio;
|
|
301
|
+
const z2 = z * ratio;
|
|
302
|
+
const sx = Math.sin(x2);
|
|
303
|
+
const cx = Math.cos(x2);
|
|
304
|
+
const sy = Math.sin(y2);
|
|
305
|
+
const cy = Math.cos(y2);
|
|
306
|
+
const sz = Math.sin(z2);
|
|
307
|
+
const cz = Math.cos(z2);
|
|
308
|
+
const sxcy = sx * cy;
|
|
309
|
+
const cxsy = cx * sy;
|
|
310
|
+
const cxcy = cx * cy;
|
|
311
|
+
const sxsy = sx * sy;
|
|
312
|
+
return fromValues(sxcy * cz - cxsy * sz, cxsy * cz + sxcy * sz, cxcy * sz - sxsy * cz, cxcy * cz + sxsy * sz, out);
|
|
80
313
|
};
|
|
81
|
-
// Stores intermediary values for some functions.
|
|
82
|
-
const intermediary = createMatrix3Like();
|
|
83
314
|
/**
|
|
84
|
-
* Create a quaternion
|
|
85
|
-
* @param
|
|
86
|
-
* @param
|
|
87
|
-
* @param
|
|
315
|
+
* Create a quaternion from equivalent z-y'-x" (intrinsic) Tait-Bryan angles.
|
|
316
|
+
* @param z - The Z angle (roll) in degrees.
|
|
317
|
+
* @param y - The Y angle (pitch) in degrees.
|
|
318
|
+
* @param x - The X angle (yaw) in degrees.
|
|
88
319
|
* @param out - The quaternion to store the result in.
|
|
89
320
|
* @returns The quaternion.
|
|
321
|
+
* @see {@link https://en.wikipedia.org/wiki/Euler_angles | Euler angles}
|
|
322
|
+
* @public
|
|
90
323
|
*/
|
|
91
|
-
export const
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
324
|
+
export const fromEuler = fromEulerZyx;
|
|
325
|
+
// Used in `toEuler`.
|
|
326
|
+
const halfEpsilon = 0.5 - epsilon;
|
|
327
|
+
const doubleRatio = 360 / Math.PI;
|
|
328
|
+
/**
|
|
329
|
+
* Convert a quaternion to equivalent z-y'-x" (intrinsic) Tait-Bryan angles.
|
|
330
|
+
* @param quaternion - The quaternion.
|
|
331
|
+
* @param out - The vector in which to store the Tait-Bryan angles.
|
|
332
|
+
* @returns The Tait-Bryan angles in degrees in roll (z), pitch (y'), yaw (x") order.
|
|
333
|
+
* @public
|
|
334
|
+
*/
|
|
335
|
+
export const toEuler = (quaternion, out) => {
|
|
336
|
+
const x = quaternion[0];
|
|
337
|
+
const y = quaternion[1];
|
|
338
|
+
const z = quaternion[2];
|
|
339
|
+
const w = quaternion[3];
|
|
340
|
+
const y2 = y * y;
|
|
341
|
+
const z2 = z * z;
|
|
342
|
+
const w2 = w * w;
|
|
343
|
+
const test = x * w - y * z;
|
|
344
|
+
const heu = halfEpsilon * (x * x + y2 + z2 + w2);
|
|
345
|
+
if (test > heu) {
|
|
346
|
+
return vector3FromValues(90, Math.atan2(y, x) * doubleRatio, 0, out);
|
|
347
|
+
}
|
|
348
|
+
if (test < -heu) {
|
|
349
|
+
return vector3FromValues(-90, Math.atan2(y, x) * doubleRatio, 0, out);
|
|
350
|
+
}
|
|
351
|
+
return vector3FromValues(radiansToDegrees(Math.asin(2 * (x * z - w * y))), radiansToDegrees(Math.atan2(2 * (x * w + y * z), 1 - 2 * (z2 + w2))), radiansToDegrees(Math.atan2(2 * (x * y + z * w), 1 - 2 * (y2 + z2))), out);
|
|
102
352
|
};
|
|
353
|
+
// Stores intermediary values for some functions.
|
|
354
|
+
const im3 = createMatrix3Like();
|
|
355
|
+
/**
|
|
356
|
+
* Create a quaternion with values corresponding to the given orthonormal set of unit vectors.
|
|
357
|
+
* @param view - The unit vector representing the viewing direction.
|
|
358
|
+
* @param right - The unit vector representing the local "right" direction.
|
|
359
|
+
* @param up - The unit vector representing the local "up" direction.
|
|
360
|
+
* @param out - The quaternion to store the result in.
|
|
361
|
+
* @returns The quaternion.
|
|
362
|
+
* @public
|
|
363
|
+
*/
|
|
364
|
+
export const fromAxes = (view, right, up, out) => normalize(fromMatrix3(matrix3FromValues(right[0], up[0], -view[0], right[1], up[1], -view[1], right[2], up[2], -view[2], im3), out), out);
|
|
103
365
|
/**
|
|
104
366
|
* Set a quaternion to the identity.
|
|
105
367
|
* @param out - The quaternion to store the result in.
|
|
106
368
|
* @returns This quaternion.
|
|
369
|
+
* @public
|
|
107
370
|
*/
|
|
108
|
-
export const identity = (out) =>
|
|
109
|
-
out[0] = 0;
|
|
110
|
-
out[1] = 0;
|
|
111
|
-
out[2] = 0;
|
|
112
|
-
out[3] = 1;
|
|
113
|
-
return out;
|
|
114
|
-
};
|
|
371
|
+
export const identity = (out) => fromValues(0, 0, 0, 1, out);
|
|
115
372
|
/**
|
|
116
373
|
* Calculate the axis and angle that represent a quaternion.
|
|
117
374
|
* @param quaternion - The quaternion.
|
|
118
375
|
* @param out - The axis and angle to store the result in.
|
|
119
376
|
* @returns The axis and angle.
|
|
377
|
+
* @public
|
|
120
378
|
*/
|
|
121
379
|
export const getAxisAngle = (quaternion, out) => {
|
|
122
380
|
const r = Math.acos(quaternion[3]) * 2;
|
|
123
381
|
const s = Math.sin(r / 2);
|
|
124
|
-
|
|
125
|
-
s
|
|
126
|
-
|
|
127
|
-
|
|
382
|
+
if (s > epsilon) {
|
|
383
|
+
vector3FromValues(quaternion[0] / s, quaternion[1] / s, quaternion[2] / s, out.axis);
|
|
384
|
+
}
|
|
385
|
+
else {
|
|
386
|
+
vector3FromValues(1, 0, 0, out.axis);
|
|
387
|
+
}
|
|
128
388
|
out.angle = r;
|
|
129
389
|
return out;
|
|
130
390
|
};
|
|
@@ -133,21 +393,19 @@ export const getAxisAngle = (quaternion, out) => {
|
|
|
133
393
|
* @param axisAngle - The axis and angle.
|
|
134
394
|
* @param out - The quaternion to store the result in.
|
|
135
395
|
* @returns The quaternion.
|
|
396
|
+
* @public
|
|
136
397
|
*/
|
|
137
|
-
export const setAxisAngle = (
|
|
138
|
-
const r =
|
|
398
|
+
export const setAxisAngle = ({ angle, axis }, out) => {
|
|
399
|
+
const r = angle / 2;
|
|
139
400
|
const s = Math.sin(r);
|
|
140
|
-
|
|
141
|
-
out[1] = s * axisAngle.axis[1];
|
|
142
|
-
out[2] = s * axisAngle.axis[2];
|
|
143
|
-
out[3] = Math.cos(r);
|
|
144
|
-
return out;
|
|
401
|
+
return fromValues(axis[0] * s, axis[1] * s, axis[2] * s, Math.cos(r), out);
|
|
145
402
|
};
|
|
146
403
|
/**
|
|
147
404
|
* Get the angular distance between two unit quaternions.
|
|
148
405
|
* @param a - The first unit quaternion.
|
|
149
406
|
* @param b - The second unit quaternion.
|
|
150
407
|
* @returns The angular distance in radians.
|
|
408
|
+
* @public
|
|
151
409
|
*/
|
|
152
410
|
export const getAngle = (a, b) => {
|
|
153
411
|
const dp = dot(a, b);
|
|
@@ -159,6 +417,7 @@ export const getAngle = (a, b) => {
|
|
|
159
417
|
* @param b - The multiplicand.
|
|
160
418
|
* @param out - The quaternion to store the result in.
|
|
161
419
|
* @returns The product.
|
|
420
|
+
* @public
|
|
162
421
|
*/
|
|
163
422
|
export const multiply = (a, b, out) => {
|
|
164
423
|
const ax = a[0];
|
|
@@ -169,11 +428,7 @@ export const multiply = (a, b, out) => {
|
|
|
169
428
|
const by = b[1];
|
|
170
429
|
const bz = b[2];
|
|
171
430
|
const bw = b[3];
|
|
172
|
-
|
|
173
|
-
out[1] = ay * bw + aw * by + az * bx - ax * bz;
|
|
174
|
-
out[2] = az * bw + aw * bz + ax * by - ay * bx;
|
|
175
|
-
out[3] = aw * bw - ax * bx - ay * by - az * bz;
|
|
176
|
-
return out;
|
|
431
|
+
return fromValues(ax * bw + aw * bx + ay * bz - az * by, ay * bw + aw * by + az * bx - ax * bz, az * bw + aw * bz + ax * by - ay * bx, aw * bw - ax * bx - ay * by - az * bz, out);
|
|
177
432
|
};
|
|
178
433
|
/**
|
|
179
434
|
* Rotate a quaternion by the given angle around the X-axis.
|
|
@@ -181,20 +436,17 @@ export const multiply = (a, b, out) => {
|
|
|
181
436
|
* @param radians - The angle in radians.
|
|
182
437
|
* @param out - The quaternion to store the result in.
|
|
183
438
|
* @returns The rotated quaternion.
|
|
439
|
+
* @public
|
|
184
440
|
*/
|
|
185
441
|
export const rotateX = (quaternion, radians, out) => {
|
|
186
|
-
const r = radians * 0.5;
|
|
187
442
|
const ax = quaternion[0];
|
|
188
443
|
const ay = quaternion[1];
|
|
189
444
|
const az = quaternion[2];
|
|
190
445
|
const aw = quaternion[3];
|
|
191
|
-
const
|
|
192
|
-
const
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
out[2] = az * bw - ay * bx;
|
|
196
|
-
out[3] = aw * bw - ax * bx;
|
|
197
|
-
return out;
|
|
446
|
+
const r = radians / 2;
|
|
447
|
+
const s = Math.sin(r);
|
|
448
|
+
const c = Math.cos(r);
|
|
449
|
+
return fromValues(ax * c + aw * s, ay * c + az * s, az * c - ay * s, aw * c - ax * s, out);
|
|
198
450
|
};
|
|
199
451
|
/**
|
|
200
452
|
* Rotate a quaternion by the given angle around the Y-axis.
|
|
@@ -202,20 +454,17 @@ export const rotateX = (quaternion, radians, out) => {
|
|
|
202
454
|
* @param radians - The angle in radians.
|
|
203
455
|
* @param out - The quaternion to store the result in.
|
|
204
456
|
* @returns The rotated quaternion.
|
|
457
|
+
* @public
|
|
205
458
|
*/
|
|
206
459
|
export const rotateY = (quaternion, radians, out) => {
|
|
207
|
-
const r = radians * 0.5;
|
|
208
460
|
const ax = quaternion[0];
|
|
209
461
|
const ay = quaternion[1];
|
|
210
462
|
const az = quaternion[2];
|
|
211
463
|
const aw = quaternion[3];
|
|
212
|
-
const
|
|
213
|
-
const
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
out[2] = az * bw + ax * by;
|
|
217
|
-
out[3] = aw * bw - ay * by;
|
|
218
|
-
return out;
|
|
464
|
+
const r = radians / 2;
|
|
465
|
+
const s = Math.sin(r);
|
|
466
|
+
const c = Math.cos(r);
|
|
467
|
+
return fromValues(ax * c - az * s, ay * c + aw * s, az * c + ax * s, aw * c - ay * s, out);
|
|
219
468
|
};
|
|
220
469
|
/**
|
|
221
470
|
* Rotate a quaternion by the given angle around the Z-axis.
|
|
@@ -223,86 +472,79 @@ export const rotateY = (quaternion, radians, out) => {
|
|
|
223
472
|
* @param radians - The angle in radians.
|
|
224
473
|
* @param out - The quaternion to store the result in.
|
|
225
474
|
* @returns The rotated quaternion.
|
|
475
|
+
* @public
|
|
226
476
|
*/
|
|
227
477
|
export const rotateZ = (quaternion, radians, out) => {
|
|
228
|
-
const r = radians * 0.5;
|
|
229
478
|
const ax = quaternion[0];
|
|
230
479
|
const ay = quaternion[1];
|
|
231
480
|
const az = quaternion[2];
|
|
232
481
|
const aw = quaternion[3];
|
|
233
|
-
const
|
|
234
|
-
const
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
out[2] = az * bw + aw * bz;
|
|
238
|
-
out[3] = aw * bw - az * bz;
|
|
239
|
-
return out;
|
|
482
|
+
const r = radians / 2;
|
|
483
|
+
const s = Math.sin(r);
|
|
484
|
+
const c = Math.cos(r);
|
|
485
|
+
return fromValues(ax * c + ay * s, ay * c - ax * s, az * c + aw * s, aw * c - az * s, out);
|
|
240
486
|
};
|
|
241
487
|
/**
|
|
242
488
|
* Calculate the fourth component of a unit quaternion from the first three, ignoring the existing fourth component.
|
|
243
|
-
* @param quaternion - The quaternion.
|
|
489
|
+
* @param quaternion - The unit quaternion.
|
|
244
490
|
* @param out - The quaternion to store the result in.
|
|
245
491
|
* @returns The quaternion.
|
|
492
|
+
* @public
|
|
246
493
|
*/
|
|
247
494
|
export const calculateW = (quaternion, out) => {
|
|
248
495
|
const x = quaternion[0];
|
|
249
496
|
const y = quaternion[1];
|
|
250
497
|
const z = quaternion[2];
|
|
251
|
-
out
|
|
252
|
-
|
|
253
|
-
|
|
498
|
+
if (quaternion !== out) {
|
|
499
|
+
out[0] = x;
|
|
500
|
+
out[1] = y;
|
|
501
|
+
out[2] = z;
|
|
502
|
+
}
|
|
254
503
|
out[3] = Math.sqrt(Math.abs(1 - x * x - y * y - z * z));
|
|
255
504
|
return out;
|
|
256
505
|
};
|
|
257
506
|
/**
|
|
258
507
|
* Calculate the exponential of a unit quaternion.
|
|
259
|
-
* @param quaternion - The quaternion.
|
|
508
|
+
* @param quaternion - The unit quaternion.
|
|
260
509
|
* @param out - The quaternion to store the result in.
|
|
261
510
|
* @returns The exponential.
|
|
511
|
+
* @public
|
|
262
512
|
*/
|
|
263
513
|
export const exp = (quaternion, out) => {
|
|
264
514
|
const x = quaternion[0];
|
|
265
515
|
const y = quaternion[1];
|
|
266
516
|
const z = quaternion[2];
|
|
267
|
-
const
|
|
268
|
-
const
|
|
269
|
-
const et = Math.exp(w);
|
|
517
|
+
const r = Math.sqrt(x * x + y * y + z * z); // `Math.hypot` is slower.
|
|
518
|
+
const et = Math.exp(quaternion[3]);
|
|
270
519
|
const s = r > 0 ? (et * Math.sin(r)) / r : 0;
|
|
271
|
-
|
|
272
|
-
out[1] = y * s;
|
|
273
|
-
out[2] = z * s;
|
|
274
|
-
out[3] = et * Math.cos(r);
|
|
275
|
-
return out;
|
|
520
|
+
return fromValues(x * s, y * s, z * s, et * Math.cos(r), out);
|
|
276
521
|
};
|
|
277
522
|
/**
|
|
278
523
|
* Calculate the natural logarithm of a unit quaternion.
|
|
279
|
-
* @param quaternion - The quaternion.
|
|
524
|
+
* @param quaternion - The unit quaternion.
|
|
280
525
|
* @param out - The quaternion to store the result in.
|
|
281
526
|
* @returns The natural logarithm.
|
|
527
|
+
* @public
|
|
282
528
|
*/
|
|
283
529
|
export const ln = (quaternion, out) => {
|
|
284
530
|
const x = quaternion[0];
|
|
285
531
|
const y = quaternion[1];
|
|
286
532
|
const z = quaternion[2];
|
|
287
533
|
const w = quaternion[3];
|
|
288
|
-
const
|
|
534
|
+
const xyz2 = x * x + y * y + z * z;
|
|
535
|
+
const r = Math.sqrt(xyz2); // `Math.hypot` is slower.
|
|
289
536
|
const t = r > 0 ? Math.atan2(r, w) / r : 0;
|
|
290
|
-
|
|
291
|
-
out[1] = y * t;
|
|
292
|
-
out[2] = z * t;
|
|
293
|
-
out[3] = 0.5 * Math.log(x * x + y * y + z * z + w * w);
|
|
294
|
-
return out;
|
|
537
|
+
return fromValues(x * t, y * t, z * t, Math.log(xyz2 + w * w) / 2, out);
|
|
295
538
|
};
|
|
296
539
|
/**
|
|
297
|
-
* Calculate a power of a unit quaternion.
|
|
298
|
-
* @param quaternion - The quaternion.
|
|
540
|
+
* Calculate a scalar power of a unit quaternion.
|
|
541
|
+
* @param quaternion - The unit quaternion.
|
|
299
542
|
* @param scalar - The amount to scale the quaternion by.
|
|
300
543
|
* @param out - The quaternion to store the result in.
|
|
301
|
-
* @returns The power.
|
|
544
|
+
* @returns The scalar power.
|
|
545
|
+
* @public
|
|
302
546
|
*/
|
|
303
|
-
export const pow = (quaternion, scalar, out) =>
|
|
304
|
-
return exp(scale(ln(quaternion, out), scalar, out), out);
|
|
305
|
-
};
|
|
547
|
+
export const pow = (quaternion, scalar, out) => exp(scale(ln(quaternion, out), scalar, out), out);
|
|
306
548
|
/**
|
|
307
549
|
* Perform a spherical linear interpolation between two quaternions.
|
|
308
550
|
* @param a - The first quaternion.
|
|
@@ -310,7 +552,8 @@ export const pow = (quaternion, scalar, out) => {
|
|
|
310
552
|
* @param t - The interpolation amount in `[0,1]`.
|
|
311
553
|
* @param out - The quaternion to store the result in.
|
|
312
554
|
* @returns The interpolated quaternion.
|
|
313
|
-
* @see
|
|
555
|
+
* @see {@link https://en.wikipedia.org/wiki/Slerp | Slerp}
|
|
556
|
+
* @public
|
|
314
557
|
*/
|
|
315
558
|
export const slerp = (a, b, t, out) => {
|
|
316
559
|
const ax = a[0];
|
|
@@ -344,34 +587,29 @@ export const slerp = (a, b, t, out) => {
|
|
|
344
587
|
scale0 = 1 - t;
|
|
345
588
|
scale1 = t;
|
|
346
589
|
}
|
|
347
|
-
|
|
348
|
-
out[1] = scale0 * ay + scale1 * by;
|
|
349
|
-
out[2] = scale0 * az + scale1 * bz;
|
|
350
|
-
out[3] = scale0 * aw + scale1 * bw;
|
|
351
|
-
return out;
|
|
590
|
+
return fromValues(ax * scale0 + bx * scale1, ay * scale0 + by * scale1, az * scale0 + bz * scale1, aw * scale0 + bw * scale1, out);
|
|
352
591
|
};
|
|
592
|
+
const pi2 = Math.PI * 2;
|
|
353
593
|
/**
|
|
354
594
|
* Set a quaternion to a random unit quaternion.
|
|
355
595
|
* @param out - The quaternion to store the result in.
|
|
356
596
|
* @returns The quaternion.
|
|
597
|
+
* @public
|
|
357
598
|
*/
|
|
358
599
|
export const random = (out) => {
|
|
359
|
-
const
|
|
360
|
-
const
|
|
361
|
-
const
|
|
362
|
-
const
|
|
363
|
-
const
|
|
364
|
-
|
|
365
|
-
out[1] = sqrt1MinusU1 * Math.cos(2 * Math.PI * u2);
|
|
366
|
-
out[2] = sqrtU1 * Math.sin(2 * Math.PI * u3);
|
|
367
|
-
out[3] = sqrtU1 * Math.cos(2 * Math.PI * u3);
|
|
368
|
-
return out;
|
|
600
|
+
const rand = Math.random();
|
|
601
|
+
const sqInvRand = Math.sqrt(1 - rand);
|
|
602
|
+
const sqRand = Math.sqrt(rand);
|
|
603
|
+
const pi2u2 = pi2 * Math.random();
|
|
604
|
+
const pi2u3 = pi2 * Math.random();
|
|
605
|
+
return fromValues(sqInvRand * Math.sin(pi2u2), sqInvRand * Math.cos(pi2u2), sqRand * Math.sin(pi2u3), sqRand * Math.cos(pi2u3), out);
|
|
369
606
|
};
|
|
370
607
|
/**
|
|
371
608
|
* Calculate the inverse of a quaternion. If the quaternion is normalized, the conjugate is the same but faster to calculate.
|
|
372
609
|
* @param quaternion - The quaternion.
|
|
373
610
|
* @param out - The quaternion to store the result in.
|
|
374
611
|
* @returns The inverse.
|
|
612
|
+
* @public
|
|
375
613
|
*/
|
|
376
614
|
export const invert = (quaternion, out) => {
|
|
377
615
|
const a0 = quaternion[0];
|
|
@@ -380,32 +618,18 @@ export const invert = (quaternion, out) => {
|
|
|
380
618
|
const a3 = quaternion[3];
|
|
381
619
|
const aDotA = a0 * a0 + a1 * a1 + a2 * a2 + a3 * a3;
|
|
382
620
|
const invDot = aDotA ? 1 / aDotA : 0;
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
out[2] = 0;
|
|
387
|
-
out[3] = 0;
|
|
388
|
-
return out;
|
|
389
|
-
}
|
|
390
|
-
out[0] = -a0 * invDot;
|
|
391
|
-
out[1] = -a1 * invDot;
|
|
392
|
-
out[2] = -a2 * invDot;
|
|
393
|
-
out[3] = a3 * invDot;
|
|
394
|
-
return out;
|
|
621
|
+
return aDotA === 0 ?
|
|
622
|
+
fromValues(0, 0, 0, 0, out)
|
|
623
|
+
: fromValues(-a0 * invDot, -a1 * invDot, -a2 * invDot, a3 * invDot, out);
|
|
395
624
|
};
|
|
396
625
|
/**
|
|
397
626
|
* Calculate the conjugate of a quaternion. If the quaternion is normalized, this is the same as the inverse but faster to calculate.
|
|
398
627
|
* @param quaternion - The quaternion.
|
|
399
628
|
* @param out - The quaternion to store the result in.
|
|
400
629
|
* @returns The conjugate.
|
|
630
|
+
* @public
|
|
401
631
|
*/
|
|
402
|
-
export const conjugate = (quaternion, out) =>
|
|
403
|
-
out[0] = -quaternion[0];
|
|
404
|
-
out[1] = -quaternion[1];
|
|
405
|
-
out[2] = -quaternion[2];
|
|
406
|
-
out[3] = quaternion[3];
|
|
407
|
-
return out;
|
|
408
|
-
};
|
|
632
|
+
export const conjugate = (quaternion, out) => fromValues(-quaternion[0], -quaternion[1], -quaternion[2], quaternion[3], out);
|
|
409
633
|
// Used to store intermediate values for some functions.
|
|
410
634
|
const controlPointOne = createQuaternionLike();
|
|
411
635
|
const controlPointTwo = createQuaternionLike();
|
|
@@ -418,16 +642,44 @@ const controlPointTwo = createQuaternionLike();
|
|
|
418
642
|
* @param t - The interpolation amount in `[0,1]`.
|
|
419
643
|
* @param out - The quaternion to store the result in.
|
|
420
644
|
* @returns The interpolated value.
|
|
421
|
-
* @see
|
|
645
|
+
* @see {@link https://en.wikipedia.org/wiki/Slerp | Slerp}
|
|
646
|
+
* @public
|
|
647
|
+
*/
|
|
648
|
+
export const sqlerp = (a, b, c, d, t, out) => slerp(slerp(a, d, t, controlPointOne), slerp(b, c, t, controlPointTwo), 2 * t * (1 - t), out);
|
|
649
|
+
// The unit three-dimensional vector that represents the X-axis.
|
|
650
|
+
const xAxis = vector3FromValues(1, 0, 0, createVector3Like());
|
|
651
|
+
// The unit three-dimensional vector that represents the Y-axis.
|
|
652
|
+
const yAxis = vector3FromValues(0, 1, 0, createVector3Like());
|
|
653
|
+
// Used to store intermediary values for some functions.
|
|
654
|
+
const iv3 = createVector3Like();
|
|
655
|
+
/**
|
|
656
|
+
* Create a unit quaternion that represents the shortest rotation from one unit vector to another.
|
|
657
|
+
* @param a - The first unit vector.
|
|
658
|
+
* @param b - The second unit vector.
|
|
659
|
+
* @param out - The quaternion to store the result in.
|
|
660
|
+
* @returns The unit quaternion.
|
|
661
|
+
* @public
|
|
422
662
|
*/
|
|
423
|
-
export const
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
663
|
+
export const fromRotationTo = (a, b, out) => {
|
|
664
|
+
const dp = vector3Dot(a, b);
|
|
665
|
+
if (dp < epsilon - 1) {
|
|
666
|
+
vector3Cross(xAxis, a, iv3);
|
|
667
|
+
if (vector3GetMagnitude(iv3) < epsilon) {
|
|
668
|
+
vector3Cross(yAxis, a, iv3);
|
|
669
|
+
}
|
|
670
|
+
vector3Normalize(iv3, iv3);
|
|
671
|
+
return setAxisAngle({ angle: Math.PI, axis: iv3 }, out);
|
|
672
|
+
}
|
|
673
|
+
if (dp > 1 - epsilon) {
|
|
674
|
+
return fromValues(0, 0, 0, 1, out);
|
|
675
|
+
}
|
|
676
|
+
vector3Cross(a, b, iv3);
|
|
677
|
+
return normalize(fromValues(iv3[0], iv3[1], iv3[2], 1 + dp, out), out);
|
|
427
678
|
};
|
|
428
679
|
/**
|
|
429
680
|
* A complex number that is commonly used to describe rotations.
|
|
430
|
-
* @see
|
|
681
|
+
* @see {@link https://en.wikipedia.org/wiki/Quaternion | Quaternion}
|
|
682
|
+
* @public
|
|
431
683
|
*/
|
|
432
684
|
export default class Quaternion extends Float32Array {
|
|
433
685
|
/**
|
|
@@ -435,22 +687,22 @@ export default class Quaternion extends Float32Array {
|
|
|
435
687
|
* @param matrix - The matrix.
|
|
436
688
|
* @param out - The quaternion to store the result in.
|
|
437
689
|
* @returns The quaternion.
|
|
438
|
-
* @see
|
|
690
|
+
* @see {@link https://en.wikipedia.org/wiki/Rotation_matrix | Rotation matrix}
|
|
439
691
|
*/
|
|
440
692
|
static fromMatrix3(matrix, out = new Quaternion()) {
|
|
441
693
|
return fromMatrix3(matrix, out);
|
|
442
694
|
}
|
|
443
695
|
/**
|
|
444
|
-
* Create a quaternion from equivalent
|
|
445
|
-
* @param
|
|
446
|
-
* @param y - The y angle.
|
|
447
|
-
* @param
|
|
696
|
+
* Create a quaternion from equivalent z-y'-x" (intrinsic) Tait-Bryan angles.
|
|
697
|
+
* @param z - The z (roll) angle.
|
|
698
|
+
* @param y - The y (pitch) angle.
|
|
699
|
+
* @param x - The x (yaw) angle.
|
|
448
700
|
* @param out - The quaternion to store the result in.
|
|
449
701
|
* @returns The quaternion.
|
|
450
|
-
* @see
|
|
702
|
+
* @see {@link https://en.wikipedia.org/wiki/Euler_angles | Euler angles}
|
|
451
703
|
*/
|
|
452
|
-
static fromEuler(
|
|
453
|
-
return fromEuler(
|
|
704
|
+
static fromEuler(z, y, x, out = new Quaternion()) {
|
|
705
|
+
return fromEuler(z, y, x, out);
|
|
454
706
|
}
|
|
455
707
|
/**
|
|
456
708
|
* Create a quaternion with the given values.
|
|
@@ -475,9 +727,19 @@ export default class Quaternion extends Float32Array {
|
|
|
475
727
|
static fromAxes(view, right, up, out = new Quaternion()) {
|
|
476
728
|
return fromAxes(view, right, up, out);
|
|
477
729
|
}
|
|
730
|
+
/**
|
|
731
|
+
* Create a unit quaternion that represents the shortest rotation from one unit vector to another.
|
|
732
|
+
* @param a - The first unit vector.
|
|
733
|
+
* @param b - The second unit vector.
|
|
734
|
+
* @param out - The quaternion to store the result in.
|
|
735
|
+
* @returns The unit quaternion.
|
|
736
|
+
*/
|
|
737
|
+
static fromRotationTo(a, b, out = new Quaternion()) {
|
|
738
|
+
return fromRotationTo(a, b, out);
|
|
739
|
+
}
|
|
478
740
|
/**
|
|
479
741
|
* Create an identity quaternion.
|
|
480
|
-
* @see
|
|
742
|
+
* @see {@link https://en.wikipedia.org/wiki/Quaternion | Quaternion}
|
|
481
743
|
*/
|
|
482
744
|
constructor() {
|
|
483
745
|
super(4);
|
|
@@ -597,7 +859,7 @@ export default class Quaternion extends Float32Array {
|
|
|
597
859
|
* @param t - The interpolation amount in `[0,1]`.
|
|
598
860
|
* @param out - The quaternion to store the result in.
|
|
599
861
|
* @returns The interpolated quaternion.
|
|
600
|
-
* @see
|
|
862
|
+
* @see {@link https://en.wikipedia.org/wiki/Slerp | Slerp}
|
|
601
863
|
*/
|
|
602
864
|
slerp(quaternion, t, out = new Quaternion()) {
|
|
603
865
|
return slerp(this, quaternion, t, out);
|
|
@@ -717,10 +979,18 @@ export default class Quaternion extends Float32Array {
|
|
|
717
979
|
* @param t - The interpolation amount in `[0,1]`.
|
|
718
980
|
* @param out - The quaternion to store the result in.
|
|
719
981
|
* @returns The interpolated value.
|
|
720
|
-
* @see
|
|
982
|
+
* @see {@link https://en.wikipedia.org/wiki/Slerp | Slerp}
|
|
721
983
|
*/
|
|
722
984
|
sqlerp(a, b, quaternion, t, out = new Quaternion()) {
|
|
723
985
|
return sqlerp(this, a, b, quaternion, t, out);
|
|
724
986
|
}
|
|
987
|
+
/**
|
|
988
|
+
* Convert this quaternion to equivalent z-y'-x" (intrinsic) Tait-Bryan angles.
|
|
989
|
+
* @param out - The vector in which to store the Tait-Bryan angles.
|
|
990
|
+
* @returns The Tait-Bryan angles in degrees in roll (z), pitch (y'), yaw (x") order.
|
|
991
|
+
*/
|
|
992
|
+
toEuler(out = new Vector3()) {
|
|
993
|
+
return toEuler(this, out);
|
|
994
|
+
}
|
|
725
995
|
}
|
|
726
996
|
//# sourceMappingURL=Quaternion.js.map
|