@buley/hexgrid-3d 3.2.3 → 3.3.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.
- package/dist/algorithms/AdvancedStatistics.d.ts +2 -2
- package/dist/algorithms/AdvancedStatistics.d.ts.map +1 -1
- package/dist/algorithms/AdvancedStatistics.js +2 -2
- package/dist/algorithms/BayesianStatistics.d.ts +6 -0
- package/dist/algorithms/BayesianStatistics.d.ts.map +1 -1
- package/dist/algorithms/BayesianStatistics.js +54 -0
- package/dist/algorithms/FlowField.d.ts +11 -0
- package/dist/algorithms/FlowField.d.ts.map +1 -1
- package/dist/algorithms/FlowField.js +13 -0
- package/dist/algorithms/FluidSimulation.d.ts +21 -3
- package/dist/algorithms/FluidSimulation.d.ts.map +1 -1
- package/dist/algorithms/FluidSimulation.js +40 -0
- package/dist/algorithms/GraphAlgorithms.d.ts +1 -1
- package/dist/algorithms/GraphAlgorithms.d.ts.map +1 -1
- package/dist/algorithms/GraphAlgorithms.js +87 -15
- package/dist/algorithms/OutlierDetection.d.ts +4 -0
- package/dist/algorithms/OutlierDetection.d.ts.map +1 -1
- package/dist/algorithms/OutlierDetection.js +15 -3
- package/dist/algorithms/ParticleSystem.d.ts +46 -3
- package/dist/algorithms/ParticleSystem.d.ts.map +1 -1
- package/dist/algorithms/ParticleSystem.js +118 -15
- package/dist/components/HexGrid.d.ts +32 -2
- package/dist/components/HexGrid.d.ts.map +1 -1
- package/dist/components/HexGrid.js +5456 -25
- package/dist/components/debug/PoolStatsOverlay.d.ts +6 -0
- package/dist/components/debug/PoolStatsOverlay.d.ts.map +1 -0
- package/dist/components/debug/PoolStatsOverlay.js +18 -0
- package/dist/components/index.d.ts +3 -2
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +1 -1
- package/dist/lib/html-utils.d.ts +2 -0
- package/dist/lib/html-utils.d.ts.map +1 -0
- package/dist/lib/html-utils.js +7 -0
- package/dist/lib/logger.d.ts +20 -0
- package/dist/lib/logger.d.ts.map +1 -0
- package/dist/lib/logger.js +9 -0
- package/dist/lib/narration.d.ts +5 -0
- package/dist/lib/narration.d.ts.map +1 -1
- package/dist/lib/narration.js +19 -0
- package/dist/lib/stats-tracker.d.ts +2 -0
- package/dist/lib/stats-tracker.d.ts.map +1 -1
- package/dist/lib/stats-tracker.js +13 -0
- package/dist/lib/theme-colors.d.ts +9 -0
- package/dist/lib/theme-colors.d.ts.map +1 -1
- package/dist/lib/theme-colors.js +18 -1
- package/dist/math/Matrix4.d.ts +179 -2
- package/dist/math/Matrix4.d.ts.map +1 -1
- package/dist/math/Matrix4.js +528 -8
- package/dist/math/Quaternion.d.ts +69 -0
- package/dist/math/Quaternion.d.ts.map +1 -1
- package/dist/math/Quaternion.js +439 -0
- package/dist/math/SpatialIndex.d.ts +32 -13
- package/dist/math/SpatialIndex.d.ts.map +1 -1
- package/dist/math/SpatialIndex.js +239 -33
- package/package.json +4 -2
package/dist/math/Matrix4.js
CHANGED
|
@@ -1,19 +1,539 @@
|
|
|
1
1
|
import { Vector3 } from './Vector3';
|
|
2
|
+
/**
|
|
3
|
+
* 4x4 matrix using column-major storage (OpenGL convention).
|
|
4
|
+
*
|
|
5
|
+
* Memory layout (16-element array):
|
|
6
|
+
* | e[0] e[4] e[8] e[12] |
|
|
7
|
+
* | e[1] e[5] e[9] e[13] |
|
|
8
|
+
* | e[2] e[6] e[10] e[14] |
|
|
9
|
+
* | e[3] e[7] e[11] e[15] |
|
|
10
|
+
*/
|
|
2
11
|
export class Matrix4 {
|
|
3
12
|
constructor(elements) {
|
|
4
|
-
|
|
13
|
+
if (elements) {
|
|
14
|
+
this.elements = elements.slice();
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
this.elements = [
|
|
18
|
+
1, 0, 0, 0,
|
|
19
|
+
0, 1, 0, 0,
|
|
20
|
+
0, 0, 1, 0,
|
|
21
|
+
0, 0, 0, 1,
|
|
22
|
+
];
|
|
23
|
+
}
|
|
5
24
|
}
|
|
25
|
+
// ---------------------------------------------------------------------------
|
|
26
|
+
// Static factory methods
|
|
27
|
+
// ---------------------------------------------------------------------------
|
|
6
28
|
static identity() {
|
|
7
|
-
return new Matrix4([
|
|
29
|
+
return new Matrix4([
|
|
30
|
+
1, 0, 0, 0,
|
|
31
|
+
0, 1, 0, 0,
|
|
32
|
+
0, 0, 1, 0,
|
|
33
|
+
0, 0, 0, 1,
|
|
34
|
+
]);
|
|
35
|
+
}
|
|
36
|
+
static zero() {
|
|
37
|
+
return new Matrix4([
|
|
38
|
+
0, 0, 0, 0,
|
|
39
|
+
0, 0, 0, 0,
|
|
40
|
+
0, 0, 0, 0,
|
|
41
|
+
0, 0, 0, 0,
|
|
42
|
+
]);
|
|
8
43
|
}
|
|
9
44
|
static translation(x, y, z) {
|
|
10
|
-
return new Matrix4([
|
|
45
|
+
return new Matrix4([
|
|
46
|
+
1, 0, 0, 0,
|
|
47
|
+
0, 1, 0, 0,
|
|
48
|
+
0, 0, 1, 0,
|
|
49
|
+
x, y, z, 1,
|
|
50
|
+
]);
|
|
51
|
+
}
|
|
52
|
+
static translationFromVector(v) {
|
|
53
|
+
return Matrix4.translation(v.x, v.y, v.z);
|
|
54
|
+
}
|
|
55
|
+
static scale(x, y, z) {
|
|
56
|
+
return new Matrix4([
|
|
57
|
+
x, 0, 0, 0,
|
|
58
|
+
0, y, 0, 0,
|
|
59
|
+
0, 0, z, 0,
|
|
60
|
+
0, 0, 0, 1,
|
|
61
|
+
]);
|
|
62
|
+
}
|
|
63
|
+
static uniformScale(s) {
|
|
64
|
+
return Matrix4.scale(s, s, s);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Rotation around the X axis.
|
|
68
|
+
* Column-major: [5]=cos, [6]=sin, [9]=-sin, [10]=cos
|
|
69
|
+
*/
|
|
70
|
+
static rotationX(angle) {
|
|
71
|
+
const c = Math.cos(angle);
|
|
72
|
+
const s = Math.sin(angle);
|
|
73
|
+
return new Matrix4([
|
|
74
|
+
1, 0, 0, 0,
|
|
75
|
+
0, c, s, 0,
|
|
76
|
+
0, -s, c, 0,
|
|
77
|
+
0, 0, 0, 1,
|
|
78
|
+
]);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Rotation around the Y axis.
|
|
82
|
+
* Column-major: [0]=cos, [2]=-sin, [8]=sin, [10]=cos
|
|
83
|
+
*/
|
|
84
|
+
static rotationY(angle) {
|
|
85
|
+
const c = Math.cos(angle);
|
|
86
|
+
const s = Math.sin(angle);
|
|
87
|
+
return new Matrix4([
|
|
88
|
+
c, 0, -s, 0,
|
|
89
|
+
0, 1, 0, 0,
|
|
90
|
+
s, 0, c, 0,
|
|
91
|
+
0, 0, 0, 1,
|
|
92
|
+
]);
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Rotation around the Z axis.
|
|
96
|
+
* Column-major: [0]=cos, [1]=sin, [4]=-sin, [5]=cos
|
|
97
|
+
*/
|
|
98
|
+
static rotationZ(angle) {
|
|
99
|
+
const c = Math.cos(angle);
|
|
100
|
+
const s = Math.sin(angle);
|
|
101
|
+
return new Matrix4([
|
|
102
|
+
c, s, 0, 0,
|
|
103
|
+
-s, c, 0, 0,
|
|
104
|
+
0, 0, 1, 0,
|
|
105
|
+
0, 0, 0, 1,
|
|
106
|
+
]);
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Rotation around an arbitrary axis using Rodrigues' rotation formula.
|
|
110
|
+
*/
|
|
111
|
+
static rotationAxis(axis, angle) {
|
|
112
|
+
const a = axis.normalize();
|
|
113
|
+
const c = Math.cos(angle);
|
|
114
|
+
const s = Math.sin(angle);
|
|
115
|
+
const t = 1 - c;
|
|
116
|
+
const x = a.x;
|
|
117
|
+
const y = a.y;
|
|
118
|
+
const z = a.z;
|
|
119
|
+
return new Matrix4([
|
|
120
|
+
t * x * x + c, t * x * y + s * z, t * x * z - s * y, 0,
|
|
121
|
+
t * x * y - s * z, t * y * y + c, t * y * z + s * x, 0,
|
|
122
|
+
t * x * z + s * y, t * y * z - s * x, t * z * z + c, 0,
|
|
123
|
+
0, 0, 0, 1,
|
|
124
|
+
]);
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Compose rotation from Euler angles: R = Rx * Ry * Rz
|
|
128
|
+
*/
|
|
129
|
+
static rotationEuler(x, y, z) {
|
|
130
|
+
return Matrix4.rotationX(x).multiply(Matrix4.rotationY(y)).multiply(Matrix4.rotationZ(z));
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Perspective projection matrix.
|
|
134
|
+
* elements[11] = -1, elements[15] = 0
|
|
135
|
+
*/
|
|
136
|
+
static perspective(fov, aspect, near, far) {
|
|
137
|
+
const f = 1.0 / Math.tan(fov / 2);
|
|
138
|
+
const rangeInv = 1.0 / (near - far);
|
|
139
|
+
return new Matrix4([
|
|
140
|
+
f / aspect, 0, 0, 0,
|
|
141
|
+
0, f, 0, 0,
|
|
142
|
+
0, 0, (near + far) * rangeInv, -1,
|
|
143
|
+
0, 0, 2 * near * far * rangeInv, 0,
|
|
144
|
+
]);
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Orthographic projection matrix.
|
|
148
|
+
* elements[15] = 1
|
|
149
|
+
*/
|
|
150
|
+
static orthographic(left, right, bottom, top, near, far) {
|
|
151
|
+
const lr = 1 / (left - right);
|
|
152
|
+
const bt = 1 / (bottom - top);
|
|
153
|
+
const nf = 1 / (near - far);
|
|
154
|
+
return new Matrix4([
|
|
155
|
+
-2 * lr, 0, 0, 0,
|
|
156
|
+
0, -2 * bt, 0, 0,
|
|
157
|
+
0, 0, 2 * nf, 0,
|
|
158
|
+
(left + right) * lr, (top + bottom) * bt, (far + near) * nf, 1,
|
|
159
|
+
]);
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Look-at view matrix.
|
|
163
|
+
* elements[15] = 1
|
|
164
|
+
*/
|
|
165
|
+
static lookAt(eye, target, up) {
|
|
166
|
+
const zAxis = eye.subtract(target).normalize(); // forward (camera looks down -z)
|
|
167
|
+
const xAxis = up.cross(zAxis).normalize(); // right
|
|
168
|
+
const yAxis = zAxis.cross(xAxis); // recalculated up
|
|
169
|
+
return new Matrix4([
|
|
170
|
+
xAxis.x, yAxis.x, zAxis.x, 0,
|
|
171
|
+
xAxis.y, yAxis.y, zAxis.y, 0,
|
|
172
|
+
xAxis.z, yAxis.z, zAxis.z, 0,
|
|
173
|
+
-xAxis.dot(eye), -yAxis.dot(eye), -zAxis.dot(eye), 1,
|
|
174
|
+
]);
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Compose a TRS (Translation * Rotation * Scale) matrix.
|
|
178
|
+
* elements[12]=t.x, elements[0]=s.x*R[0], etc.
|
|
179
|
+
*/
|
|
180
|
+
static compose(translation, rotation, scale) {
|
|
181
|
+
const r = rotation.elements;
|
|
182
|
+
const sx = scale.x;
|
|
183
|
+
const sy = scale.y;
|
|
184
|
+
const sz = scale.z;
|
|
185
|
+
return new Matrix4([
|
|
186
|
+
r[0] * sx, r[1] * sx, r[2] * sx, 0,
|
|
187
|
+
r[4] * sy, r[5] * sy, r[6] * sy, 0,
|
|
188
|
+
r[8] * sz, r[9] * sz, r[10] * sz, 0,
|
|
189
|
+
translation.x, translation.y, translation.z, 1,
|
|
190
|
+
]);
|
|
191
|
+
}
|
|
192
|
+
// ---------------------------------------------------------------------------
|
|
193
|
+
// Instance methods
|
|
194
|
+
// ---------------------------------------------------------------------------
|
|
195
|
+
clone() {
|
|
196
|
+
return new Matrix4(this.elements.slice());
|
|
197
|
+
}
|
|
198
|
+
copy(other) {
|
|
199
|
+
for (let i = 0; i < 16; i++) {
|
|
200
|
+
this.elements[i] = other.elements[i];
|
|
201
|
+
}
|
|
202
|
+
return this;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Column-major matrix multiplication: this * other.
|
|
206
|
+
*
|
|
207
|
+
* Result column j = this * column j of other.
|
|
208
|
+
*/
|
|
209
|
+
multiply(other) {
|
|
210
|
+
const a = this.elements;
|
|
211
|
+
const b = other.elements;
|
|
212
|
+
const out = new Array(16);
|
|
213
|
+
for (let col = 0; col < 4; col++) {
|
|
214
|
+
for (let row = 0; row < 4; row++) {
|
|
215
|
+
out[col * 4 + row] =
|
|
216
|
+
a[row] * b[col * 4] +
|
|
217
|
+
a[4 + row] * b[col * 4 + 1] +
|
|
218
|
+
a[8 + row] * b[col * 4 + 2] +
|
|
219
|
+
a[12 + row] * b[col * 4 + 3];
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
return new Matrix4(out);
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Premultiply: other * this
|
|
226
|
+
*/
|
|
227
|
+
premultiply(other) {
|
|
228
|
+
return other.multiply(this);
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Transform a point (applies full matrix including translation).
|
|
232
|
+
* Column-major: x = e[0]*vx + e[4]*vy + e[8]*vz + e[12]
|
|
233
|
+
*/
|
|
234
|
+
transformPoint(v) {
|
|
235
|
+
const e = this.elements;
|
|
236
|
+
return new Vector3(e[0] * v.x + e[4] * v.y + e[8] * v.z + e[12], e[1] * v.x + e[5] * v.y + e[9] * v.z + e[13], e[2] * v.x + e[6] * v.y + e[10] * v.z + e[14]);
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Transform a direction vector (no translation applied).
|
|
240
|
+
*/
|
|
241
|
+
transformDirection(v) {
|
|
242
|
+
const e = this.elements;
|
|
243
|
+
return new Vector3(e[0] * v.x + e[4] * v.y + e[8] * v.z, e[1] * v.x + e[5] * v.y + e[9] * v.z, e[2] * v.x + e[6] * v.y + e[10] * v.z);
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Transform a normal vector by the inverse transpose of the upper-left 3x3.
|
|
247
|
+
* Result is normalized.
|
|
248
|
+
*/
|
|
249
|
+
transformNormal(v) {
|
|
250
|
+
const inv = this.inverse();
|
|
251
|
+
if (!inv) {
|
|
252
|
+
return v.clone();
|
|
253
|
+
}
|
|
254
|
+
// Multiply by the transpose of the inverse: use rows of inv instead of columns
|
|
255
|
+
const e = inv.elements;
|
|
256
|
+
const result = new Vector3(e[0] * v.x + e[1] * v.y + e[2] * v.z, e[4] * v.x + e[5] * v.y + e[6] * v.z, e[8] * v.x + e[9] * v.y + e[10] * v.z);
|
|
257
|
+
return result.normalize();
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Transform an array of points.
|
|
261
|
+
*/
|
|
262
|
+
transformPoints(points) {
|
|
263
|
+
return points.map((p) => this.transformPoint(p));
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* 4x4 determinant computed via cofactor expansion.
|
|
267
|
+
*/
|
|
268
|
+
determinant() {
|
|
269
|
+
const e = this.elements;
|
|
270
|
+
const a00 = e[0], a01 = e[4], a02 = e[8], a03 = e[12];
|
|
271
|
+
const a10 = e[1], a11 = e[5], a12 = e[9], a13 = e[13];
|
|
272
|
+
const a20 = e[2], a21 = e[6], a22 = e[10], a23 = e[14];
|
|
273
|
+
const a30 = e[3], a31 = e[7], a32 = e[11], a33 = e[15];
|
|
274
|
+
const b00 = a00 * a11 - a01 * a10;
|
|
275
|
+
const b01 = a00 * a12 - a02 * a10;
|
|
276
|
+
const b02 = a00 * a13 - a03 * a10;
|
|
277
|
+
const b03 = a01 * a12 - a02 * a11;
|
|
278
|
+
const b04 = a01 * a13 - a03 * a11;
|
|
279
|
+
const b05 = a02 * a13 - a03 * a12;
|
|
280
|
+
const b06 = a20 * a31 - a21 * a30;
|
|
281
|
+
const b07 = a20 * a32 - a22 * a30;
|
|
282
|
+
const b08 = a20 * a33 - a23 * a30;
|
|
283
|
+
const b09 = a21 * a32 - a22 * a31;
|
|
284
|
+
const b10 = a21 * a33 - a23 * a31;
|
|
285
|
+
const b11 = a22 * a33 - a23 * a32;
|
|
286
|
+
return b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Compute the inverse. Returns null if the matrix is singular (determinant ~ 0).
|
|
290
|
+
*/
|
|
291
|
+
inverse() {
|
|
292
|
+
const e = this.elements;
|
|
293
|
+
const a00 = e[0], a01 = e[4], a02 = e[8], a03 = e[12];
|
|
294
|
+
const a10 = e[1], a11 = e[5], a12 = e[9], a13 = e[13];
|
|
295
|
+
const a20 = e[2], a21 = e[6], a22 = e[10], a23 = e[14];
|
|
296
|
+
const a30 = e[3], a31 = e[7], a32 = e[11], a33 = e[15];
|
|
297
|
+
const b00 = a00 * a11 - a01 * a10;
|
|
298
|
+
const b01 = a00 * a12 - a02 * a10;
|
|
299
|
+
const b02 = a00 * a13 - a03 * a10;
|
|
300
|
+
const b03 = a01 * a12 - a02 * a11;
|
|
301
|
+
const b04 = a01 * a13 - a03 * a11;
|
|
302
|
+
const b05 = a02 * a13 - a03 * a12;
|
|
303
|
+
const b06 = a20 * a31 - a21 * a30;
|
|
304
|
+
const b07 = a20 * a32 - a22 * a30;
|
|
305
|
+
const b08 = a20 * a33 - a23 * a30;
|
|
306
|
+
const b09 = a21 * a32 - a22 * a31;
|
|
307
|
+
const b10 = a21 * a33 - a23 * a31;
|
|
308
|
+
const b11 = a22 * a33 - a23 * a32;
|
|
309
|
+
const det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
|
|
310
|
+
if (Math.abs(det) < 1e-10) {
|
|
311
|
+
return null;
|
|
312
|
+
}
|
|
313
|
+
const invDet = 1.0 / det;
|
|
314
|
+
return new Matrix4([
|
|
315
|
+
(a11 * b11 - a12 * b10 + a13 * b09) * invDet,
|
|
316
|
+
(-a10 * b11 + a12 * b08 - a13 * b07) * invDet,
|
|
317
|
+
(a10 * b10 - a11 * b08 + a13 * b06) * invDet,
|
|
318
|
+
(-a10 * b09 + a11 * b07 - a12 * b06) * invDet,
|
|
319
|
+
(-a01 * b11 + a02 * b10 - a03 * b09) * invDet,
|
|
320
|
+
(a00 * b11 - a02 * b08 + a03 * b07) * invDet,
|
|
321
|
+
(-a00 * b10 + a01 * b08 - a03 * b06) * invDet,
|
|
322
|
+
(a00 * b09 - a01 * b07 + a02 * b06) * invDet,
|
|
323
|
+
(a31 * b05 - a32 * b04 + a33 * b03) * invDet,
|
|
324
|
+
(-a30 * b05 + a32 * b02 - a33 * b01) * invDet,
|
|
325
|
+
(a30 * b04 - a31 * b02 + a33 * b00) * invDet,
|
|
326
|
+
(-a30 * b03 + a31 * b01 - a32 * b00) * invDet,
|
|
327
|
+
(-a21 * b05 + a22 * b04 - a23 * b03) * invDet,
|
|
328
|
+
(a20 * b05 - a22 * b02 + a23 * b01) * invDet,
|
|
329
|
+
(-a20 * b04 + a21 * b02 - a23 * b00) * invDet,
|
|
330
|
+
(a20 * b03 - a21 * b01 + a22 * b00) * invDet,
|
|
331
|
+
]);
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Transpose this matrix (swap rows and columns).
|
|
335
|
+
*/
|
|
336
|
+
transpose() {
|
|
337
|
+
const e = this.elements;
|
|
338
|
+
return new Matrix4([
|
|
339
|
+
e[0], e[4], e[8], e[12],
|
|
340
|
+
e[1], e[5], e[9], e[13],
|
|
341
|
+
e[2], e[6], e[10], e[14],
|
|
342
|
+
e[3], e[7], e[11], e[15],
|
|
343
|
+
]);
|
|
344
|
+
}
|
|
345
|
+
/**
|
|
346
|
+
* Extract the translation component.
|
|
347
|
+
*/
|
|
348
|
+
getTranslation() {
|
|
349
|
+
return new Vector3(this.elements[12], this.elements[13], this.elements[14]);
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* Extract the scale by computing the length of each column.
|
|
353
|
+
*/
|
|
354
|
+
getScale() {
|
|
355
|
+
const e = this.elements;
|
|
356
|
+
const sx = Math.sqrt(e[0] * e[0] + e[1] * e[1] + e[2] * e[2]);
|
|
357
|
+
const sy = Math.sqrt(e[4] * e[4] + e[5] * e[5] + e[6] * e[6]);
|
|
358
|
+
const sz = Math.sqrt(e[8] * e[8] + e[9] * e[9] + e[10] * e[10]);
|
|
359
|
+
return new Vector3(sx, sy, sz);
|
|
360
|
+
}
|
|
361
|
+
/**
|
|
362
|
+
* Extract the rotation matrix (scale removed, translation zeroed).
|
|
363
|
+
*/
|
|
364
|
+
getRotationMatrix() {
|
|
365
|
+
const e = this.elements;
|
|
366
|
+
const scale = this.getScale();
|
|
367
|
+
const invSx = scale.x !== 0 ? 1 / scale.x : 0;
|
|
368
|
+
const invSy = scale.y !== 0 ? 1 / scale.y : 0;
|
|
369
|
+
const invSz = scale.z !== 0 ? 1 / scale.z : 0;
|
|
370
|
+
return new Matrix4([
|
|
371
|
+
e[0] * invSx, e[1] * invSx, e[2] * invSx, 0,
|
|
372
|
+
e[4] * invSy, e[5] * invSy, e[6] * invSy, 0,
|
|
373
|
+
e[8] * invSz, e[9] * invSz, e[10] * invSz, 0,
|
|
374
|
+
0, 0, 0, 1,
|
|
375
|
+
]);
|
|
376
|
+
}
|
|
377
|
+
/**
|
|
378
|
+
* Decompose into translation, scale, and rotation components.
|
|
379
|
+
*/
|
|
380
|
+
decompose() {
|
|
381
|
+
return {
|
|
382
|
+
translation: this.getTranslation(),
|
|
383
|
+
scale: this.getScale(),
|
|
384
|
+
rotation: this.getRotationMatrix(),
|
|
385
|
+
};
|
|
386
|
+
}
|
|
387
|
+
/**
|
|
388
|
+
* Element-wise linear interpolation between this and other.
|
|
389
|
+
*/
|
|
390
|
+
lerp(other, t) {
|
|
391
|
+
const a = this.elements;
|
|
392
|
+
const b = other.elements;
|
|
393
|
+
const out = new Array(16);
|
|
394
|
+
for (let i = 0; i < 16; i++) {
|
|
395
|
+
out[i] = a[i] + (b[i] - a[i]) * t;
|
|
396
|
+
}
|
|
397
|
+
return new Matrix4(out);
|
|
398
|
+
}
|
|
399
|
+
/**
|
|
400
|
+
* Element-wise equality check with optional epsilon.
|
|
401
|
+
*/
|
|
402
|
+
equals(other, epsilon = Number.EPSILON) {
|
|
403
|
+
for (let i = 0; i < 16; i++) {
|
|
404
|
+
if (Math.abs(this.elements[i] - other.elements[i]) >= epsilon) {
|
|
405
|
+
return false;
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
return true;
|
|
409
|
+
}
|
|
410
|
+
/**
|
|
411
|
+
* Return a copy of the elements array.
|
|
412
|
+
*/
|
|
413
|
+
toArray() {
|
|
414
|
+
return this.elements.slice();
|
|
415
|
+
}
|
|
416
|
+
/**
|
|
417
|
+
* String representation with 4 decimal places.
|
|
418
|
+
*/
|
|
419
|
+
toString() {
|
|
420
|
+
const formatted = this.elements.map((v) => v.toFixed(4));
|
|
421
|
+
return `Matrix4([${formatted.join(', ')}])`;
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
/**
|
|
425
|
+
* 3x3 matrix using row-major storage.
|
|
426
|
+
*
|
|
427
|
+
* Layout:
|
|
428
|
+
* | e[0] e[1] e[2] |
|
|
429
|
+
* | e[3] e[4] e[5] |
|
|
430
|
+
* | e[6] e[7] e[8] |
|
|
431
|
+
*/
|
|
432
|
+
export class Matrix3 {
|
|
433
|
+
constructor(elements) {
|
|
434
|
+
if (elements) {
|
|
435
|
+
this.elements = elements.slice();
|
|
436
|
+
}
|
|
437
|
+
else {
|
|
438
|
+
this.elements = [
|
|
439
|
+
1, 0, 0,
|
|
440
|
+
0, 1, 0,
|
|
441
|
+
0, 0, 1,
|
|
442
|
+
];
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
static identity() {
|
|
446
|
+
return new Matrix3([
|
|
447
|
+
1, 0, 0,
|
|
448
|
+
0, 1, 0,
|
|
449
|
+
0, 0, 1,
|
|
450
|
+
]);
|
|
451
|
+
}
|
|
452
|
+
/**
|
|
453
|
+
* Extract the upper-left 3x3 from a column-major Matrix4 into a row-major Matrix3.
|
|
454
|
+
*
|
|
455
|
+
* Mapping:
|
|
456
|
+
* m3[0]=m4[0], m3[1]=m4[4], m3[2]=m4[8]
|
|
457
|
+
* m3[3]=m4[1], m3[4]=m4[5], m3[5]=m4[9]
|
|
458
|
+
* m3[6]=m4[2], m3[7]=m4[6], m3[8]=m4[10]
|
|
459
|
+
*/
|
|
460
|
+
static fromMatrix4(m4) {
|
|
461
|
+
const e = m4.elements;
|
|
462
|
+
return new Matrix3([
|
|
463
|
+
e[0], e[4], e[8],
|
|
464
|
+
e[1], e[5], e[9],
|
|
465
|
+
e[2], e[6], e[10],
|
|
466
|
+
]);
|
|
467
|
+
}
|
|
468
|
+
clone() {
|
|
469
|
+
return new Matrix3(this.elements.slice());
|
|
470
|
+
}
|
|
471
|
+
/**
|
|
472
|
+
* Row-major 3x3 multiplication: this * other.
|
|
473
|
+
*/
|
|
474
|
+
multiply(other) {
|
|
475
|
+
const a = this.elements;
|
|
476
|
+
const b = other.elements;
|
|
477
|
+
return new Matrix3([
|
|
478
|
+
a[0] * b[0] + a[1] * b[3] + a[2] * b[6],
|
|
479
|
+
a[0] * b[1] + a[1] * b[4] + a[2] * b[7],
|
|
480
|
+
a[0] * b[2] + a[1] * b[5] + a[2] * b[8],
|
|
481
|
+
a[3] * b[0] + a[4] * b[3] + a[5] * b[6],
|
|
482
|
+
a[3] * b[1] + a[4] * b[4] + a[5] * b[7],
|
|
483
|
+
a[3] * b[2] + a[4] * b[5] + a[5] * b[8],
|
|
484
|
+
a[6] * b[0] + a[7] * b[3] + a[8] * b[6],
|
|
485
|
+
a[6] * b[1] + a[7] * b[4] + a[8] * b[7],
|
|
486
|
+
a[6] * b[2] + a[7] * b[5] + a[8] * b[8],
|
|
487
|
+
]);
|
|
488
|
+
}
|
|
489
|
+
/**
|
|
490
|
+
* Transform a Vector3 using row-major convention:
|
|
491
|
+
* x = e[0]*vx + e[1]*vy + e[2]*vz
|
|
492
|
+
*/
|
|
493
|
+
transformVector(v) {
|
|
494
|
+
const e = this.elements;
|
|
495
|
+
return new Vector3(e[0] * v.x + e[1] * v.y + e[2] * v.z, e[3] * v.x + e[4] * v.y + e[5] * v.z, e[6] * v.x + e[7] * v.y + e[8] * v.z);
|
|
496
|
+
}
|
|
497
|
+
/**
|
|
498
|
+
* 3x3 determinant.
|
|
499
|
+
*/
|
|
500
|
+
determinant() {
|
|
501
|
+
const e = this.elements;
|
|
502
|
+
return (e[0] * (e[4] * e[8] - e[5] * e[7]) -
|
|
503
|
+
e[1] * (e[3] * e[8] - e[5] * e[6]) +
|
|
504
|
+
e[2] * (e[3] * e[7] - e[4] * e[6]));
|
|
505
|
+
}
|
|
506
|
+
/**
|
|
507
|
+
* Compute the inverse. Returns null if the matrix is singular.
|
|
508
|
+
*/
|
|
509
|
+
inverse() {
|
|
510
|
+
const e = this.elements;
|
|
511
|
+
const det = this.determinant();
|
|
512
|
+
if (Math.abs(det) < 1e-10) {
|
|
513
|
+
return null;
|
|
514
|
+
}
|
|
515
|
+
const invDet = 1.0 / det;
|
|
516
|
+
return new Matrix3([
|
|
517
|
+
(e[4] * e[8] - e[5] * e[7]) * invDet,
|
|
518
|
+
(e[2] * e[7] - e[1] * e[8]) * invDet,
|
|
519
|
+
(e[1] * e[5] - e[2] * e[4]) * invDet,
|
|
520
|
+
(e[5] * e[6] - e[3] * e[8]) * invDet,
|
|
521
|
+
(e[0] * e[8] - e[2] * e[6]) * invDet,
|
|
522
|
+
(e[2] * e[3] - e[0] * e[5]) * invDet,
|
|
523
|
+
(e[3] * e[7] - e[4] * e[6]) * invDet,
|
|
524
|
+
(e[1] * e[6] - e[0] * e[7]) * invDet,
|
|
525
|
+
(e[0] * e[4] - e[1] * e[3]) * invDet,
|
|
526
|
+
]);
|
|
11
527
|
}
|
|
12
|
-
|
|
528
|
+
/**
|
|
529
|
+
* Transpose the 3x3 matrix.
|
|
530
|
+
*/
|
|
531
|
+
transpose() {
|
|
13
532
|
const e = this.elements;
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
533
|
+
return new Matrix3([
|
|
534
|
+
e[0], e[3], e[6],
|
|
535
|
+
e[1], e[4], e[7],
|
|
536
|
+
e[2], e[5], e[8],
|
|
537
|
+
]);
|
|
18
538
|
}
|
|
19
539
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Vector3 } from './Vector3';
|
|
2
|
+
import { Matrix4, Matrix3 } from './Matrix4';
|
|
2
3
|
export declare class Quaternion {
|
|
3
4
|
x: number;
|
|
4
5
|
y: number;
|
|
@@ -6,6 +7,74 @@ export declare class Quaternion {
|
|
|
6
7
|
w: number;
|
|
7
8
|
constructor(x?: number, y?: number, z?: number, w?: number);
|
|
8
9
|
static identity(): Quaternion;
|
|
10
|
+
static fromAxisAngle(axis: Vector3, angle: number): Quaternion;
|
|
11
|
+
static fromEuler(x: number, y: number, z: number): Quaternion;
|
|
12
|
+
static fromEulerDegrees(x: number, y: number, z: number): Quaternion;
|
|
13
|
+
static fromToRotation(from: Vector3, to: Vector3): Quaternion;
|
|
14
|
+
static fromMatrix(m: Matrix4): Quaternion;
|
|
15
|
+
static random(): Quaternion;
|
|
16
|
+
static lookRotation(forward: Vector3, up?: Vector3): Quaternion;
|
|
17
|
+
static exp(v: Vector3): Quaternion;
|
|
18
|
+
static squad(a: Quaternion, b: Quaternion, c: Quaternion, d: Quaternion, t: number): Quaternion;
|
|
19
|
+
clone(): Quaternion;
|
|
20
|
+
set(x: number, y: number, z: number, w: number): this;
|
|
21
|
+
copy(other: Quaternion): this;
|
|
22
|
+
multiply(other: Quaternion): Quaternion;
|
|
23
|
+
premultiply(other: Quaternion): Quaternion;
|
|
24
|
+
add(other: Quaternion): Quaternion;
|
|
25
|
+
scale(s: number): Quaternion;
|
|
26
|
+
dot(other: Quaternion): number;
|
|
27
|
+
magnitude(): number;
|
|
28
|
+
magnitudeSquared(): number;
|
|
29
|
+
normalize(): Quaternion;
|
|
30
|
+
normalizeInPlace(): this;
|
|
31
|
+
conjugate(): Quaternion;
|
|
32
|
+
inverse(): Quaternion;
|
|
33
|
+
slerp(other: Quaternion, t: number): Quaternion;
|
|
34
|
+
lerp(other: Quaternion, t: number): Quaternion;
|
|
35
|
+
nlerp(other: Quaternion, t: number): Quaternion;
|
|
9
36
|
rotateVector(vector: Vector3): Vector3;
|
|
37
|
+
getAngle(): number;
|
|
38
|
+
getAxis(): Vector3;
|
|
39
|
+
toAxisAngle(): {
|
|
40
|
+
axis: Vector3;
|
|
41
|
+
angle: number;
|
|
42
|
+
};
|
|
43
|
+
toEuler(): {
|
|
44
|
+
x: number;
|
|
45
|
+
y: number;
|
|
46
|
+
z: number;
|
|
47
|
+
};
|
|
48
|
+
toEulerDegrees(): {
|
|
49
|
+
x: number;
|
|
50
|
+
y: number;
|
|
51
|
+
z: number;
|
|
52
|
+
};
|
|
53
|
+
toMatrix4(): Matrix4;
|
|
54
|
+
toMatrix3(): Matrix3;
|
|
55
|
+
angleTo(other: Quaternion): number;
|
|
56
|
+
equals(other: Quaternion, epsilon?: number): boolean;
|
|
57
|
+
isIdentity(epsilon?: number): boolean;
|
|
58
|
+
log(): Vector3;
|
|
59
|
+
pow(t: number): Quaternion;
|
|
60
|
+
toArray(): [number, number, number, number];
|
|
61
|
+
toString(): string;
|
|
62
|
+
}
|
|
63
|
+
export declare class DualQuaternion {
|
|
64
|
+
real: Quaternion;
|
|
65
|
+
dual: Quaternion;
|
|
66
|
+
constructor(real: Quaternion, dual: Quaternion);
|
|
67
|
+
static fromRotationTranslation(rotation: Quaternion, translation: Vector3): DualQuaternion;
|
|
68
|
+
clone(): DualQuaternion;
|
|
69
|
+
multiply(other: DualQuaternion): DualQuaternion;
|
|
70
|
+
conjugate(): DualQuaternion;
|
|
71
|
+
normalize(): DualQuaternion;
|
|
72
|
+
transformPoint(p: Vector3): Vector3;
|
|
73
|
+
toRotationTranslation(): {
|
|
74
|
+
rotation: Quaternion;
|
|
75
|
+
translation: Vector3;
|
|
76
|
+
};
|
|
77
|
+
sclerp(other: DualQuaternion, t: number): DualQuaternion;
|
|
78
|
+
pow(t: number): DualQuaternion;
|
|
10
79
|
}
|
|
11
80
|
//# sourceMappingURL=Quaternion.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Quaternion.d.ts","sourceRoot":"","sources":["../../src/math/Quaternion.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"Quaternion.d.ts","sourceRoot":"","sources":["../../src/math/Quaternion.ts"],"names":[],"mappings":"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"}
|