@woosh/meep-engine 2.134.4 → 2.134.5

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/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "description": "Pure JavaScript game engine. Fully featured and production ready.",
6
6
  "type": "module",
7
7
  "author": "Alexander Goldring",
8
- "version": "2.134.4",
8
+ "version": "2.134.5",
9
9
  "main": "build/meep.module.js",
10
10
  "module": "build/meep.module.js",
11
11
  "exports": {
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Closed-form solution for the rotation that best aligns two sets of unit
3
+ * vectors, via Horn (1987) "Closed-form solution of absolute orientation using
4
+ * unit quaternions".
5
+ *
6
+ * Given paired unit vectors {a_i} and {b_i}, finds the unit quaternion q such
7
+ * that rotating each b_i by q minimizes Σ |a_i − R(q)·b_i|².
8
+ *
9
+ * The matrix N is built so that the eigenvector of its largest eigenvalue
10
+ * IS the optimal rotation quaternion (in scalar-last form, matching meep's
11
+ * `Quaternion`).
12
+ *
13
+ * Inputs are unit vectors so no centroid subtraction is needed — the rotation
14
+ * is recovered from the cross-correlations alone.
15
+ *
16
+ * @param {Float32Array|number[]} a_xyz Source vectors — Length: count*3, unit length per triple
17
+ * @param {Float32Array|number[]} b_xyz Target vectors — Length: count*3, unit length per triple
18
+ * @param {number} count
19
+ * @param {Float32Array|number[]} out_quaternion Length 4 (x, y, z, w)
20
+ * @returns {number} The maximum eigenvalue ≈ Σ a_i · R·b_i. For a perfect alignment this equals `count`.
21
+ */
22
+ export function v3_rigid_align_paired_unit_vectors(a_xyz: Float32Array | number[], b_xyz: Float32Array | number[], count: number, out_quaternion: Float32Array | number[]): number;
23
+ //# sourceMappingURL=v3_rigid_align_paired_unit_vectors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"v3_rigid_align_paired_unit_vectors.d.ts","sourceRoot":"","sources":["../../../../../src/core/geom/vec3/v3_rigid_align_paired_unit_vectors.js"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,0DANW,YAAY,GAAC,MAAM,EAAE,SACrB,YAAY,GAAC,MAAM,EAAE,SACrB,MAAM,kBACN,YAAY,GAAC,MAAM,EAAE,GACnB,MAAM,CAsElB"}
@@ -0,0 +1,96 @@
1
+ import { BinaryDataType } from "../../binary/type/BinaryDataType.js";
2
+ import { matrix_top_eigenvector_power_iteration } from "../../graph/eigen/matrix_top_eigenvector_power_iteration.js";
3
+ import { SquareMatrix } from "../../math/matrix/SquareMatrix.js"
4
+
5
+ const scratch_horn_n = new SquareMatrix(4, BinaryDataType.Float64);
6
+
7
+ /**
8
+ * Closed-form solution for the rotation that best aligns two sets of unit
9
+ * vectors, via Horn (1987) "Closed-form solution of absolute orientation using
10
+ * unit quaternions".
11
+ *
12
+ * Given paired unit vectors {a_i} and {b_i}, finds the unit quaternion q such
13
+ * that rotating each b_i by q minimizes Σ |a_i − R(q)·b_i|².
14
+ *
15
+ * The matrix N is built so that the eigenvector of its largest eigenvalue
16
+ * IS the optimal rotation quaternion (in scalar-last form, matching meep's
17
+ * `Quaternion`).
18
+ *
19
+ * Inputs are unit vectors so no centroid subtraction is needed — the rotation
20
+ * is recovered from the cross-correlations alone.
21
+ *
22
+ * @param {Float32Array|number[]} a_xyz Source vectors — Length: count*3, unit length per triple
23
+ * @param {Float32Array|number[]} b_xyz Target vectors — Length: count*3, unit length per triple
24
+ * @param {number} count
25
+ * @param {Float32Array|number[]} out_quaternion Length 4 (x, y, z, w)
26
+ * @returns {number} The maximum eigenvalue ≈ Σ a_i · R·b_i. For a perfect alignment this equals `count`.
27
+ */
28
+ export function v3_rigid_align_paired_unit_vectors(a_xyz, b_xyz, count, out_quaternion) {
29
+
30
+ // Cross-correlation matrix S_ij = Σ b_i_component * a_j_component
31
+ // Note: S is built as Σ b ⊗ aᵀ (Horn 1987 convention) — the rotation
32
+ // recovered will take b onto a.
33
+ let Sxx = 0, Sxy = 0, Sxz = 0;
34
+ let Syx = 0, Syy = 0, Syz = 0;
35
+ let Szx = 0, Szy = 0, Szz = 0;
36
+
37
+ for (let i = 0; i < count; i++) {
38
+ const i3 = i * 3;
39
+ const ax = a_xyz[i3], ay = a_xyz[i3 + 1], az = a_xyz[i3 + 2];
40
+ const bx = b_xyz[i3], by = b_xyz[i3 + 1], bz = b_xyz[i3 + 2];
41
+
42
+ Sxx += bx * ax;
43
+ Sxy += bx * ay;
44
+ Sxz += bx * az;
45
+ Syx += by * ax;
46
+ Syy += by * ay;
47
+ Syz += by * az;
48
+ Szx += bz * ax;
49
+ Szy += bz * ay;
50
+ Szz += bz * az;
51
+ }
52
+
53
+ // Horn's 4x4 symmetric matrix N (scalar-last quaternion ordering: x, y, z, w).
54
+ //
55
+ // From the paper, ordered for scalar-FIRST quaternion (w, x, y, z):
56
+ // N00 = Sxx + Syy + Szz N01 = Syz - Szy N02 = Szx - Sxz N03 = Sxy - Syx
57
+ // N11 = Sxx - Syy - Szz N12 = Sxy + Syx N13 = Szx + Sxz
58
+ // N22 = -Sxx + Syy - Szz N23 = Syz + Szy
59
+ // N33 = -Sxx - Syy + Szz
60
+ //
61
+ // We rebind to (x, y, z, w):
62
+ // row/col 0 = x, 1 = y, 2 = z, 3 = w
63
+ // i.e. swap original index 0 with 3 and shift others down.
64
+ const Nxx = Sxx - Syy - Szz;
65
+ const Nyy = -Sxx + Syy - Szz;
66
+ const Nzz = -Sxx - Syy + Szz;
67
+ const Nww = Sxx + Syy + Szz;
68
+ const Nxy = Sxy + Syx;
69
+ const Nxz = Szx + Sxz;
70
+ const Nxw = Syz - Szy;
71
+ const Nyz = Syz + Szy;
72
+ const Nyw = Szx - Sxz;
73
+ const Nzw = Sxy - Syx;
74
+
75
+ const N = scratch_horn_n;
76
+ const d = N.data;
77
+ // SquareMatrix is column-major: d[col * 4 + row]
78
+ d[0] = Nxx;
79
+ d[5] = Nyy;
80
+ d[10] = Nzz;
81
+ d[15] = Nww;
82
+ d[1] = Nxy;
83
+ d[4] = Nxy;
84
+ d[2] = Nxz;
85
+ d[8] = Nxz;
86
+ d[3] = Nxw;
87
+ d[12] = Nxw;
88
+ d[6] = Nyz;
89
+ d[9] = Nyz;
90
+ d[7] = Nyw;
91
+ d[13] = Nyw;
92
+ d[11] = Nzw;
93
+ d[14] = Nzw;
94
+
95
+ return matrix_top_eigenvector_power_iteration(N, out_quaternion);
96
+ }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Find the eigenvector corresponding to the largest-magnitude eigenvalue of a
3
+ * symmetric square matrix using power iteration.
4
+ *
5
+ * Designed for small symmetric matrices where the dominant eigenvalue is
6
+ * well-separated from the rest (Horn's quaternion method on a 4x4, PCA on a
7
+ * 3x3 covariance, etc.). Unsuitable when the top two eigenvalues have nearly
8
+ * equal magnitude — convergence stalls in that regime.
9
+ *
10
+ * NOTE: intended to live in @woosh/meep-engine under core/graph/eigen/. Kept
11
+ * local for now.
12
+ *
13
+ * @param {SquareMatrix} matrix Symmetric, column-major as per SquareMatrix
14
+ * @param {number[]|Float32Array|Float64Array} out Eigenvector is written here, length >= matrix.size
15
+ * @param {number} [max_iterations=64]
16
+ * @param {number} [tolerance=1e-8] Convergence stops when ||v_next - v|| < tolerance
17
+ * @returns {number} The Rayleigh quotient (estimated eigenvalue)
18
+ */
19
+ export function matrix_top_eigenvector_power_iteration(matrix: SquareMatrix, out: number[] | Float32Array | Float64Array, max_iterations?: number, tolerance?: number): number;
20
+ //# sourceMappingURL=matrix_top_eigenvector_power_iteration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"matrix_top_eigenvector_power_iteration.d.ts","sourceRoot":"","sources":["../../../../../src/core/graph/eigen/matrix_top_eigenvector_power_iteration.js"],"names":[],"mappings":"AASA;;;;;;;;;;;;;;;;;GAiBG;AACH,kFALW,MAAM,EAAE,GAAC,YAAY,GAAC,YAAY,mBAClC,MAAM,cACN,MAAM,GACJ,MAAM,CAoFlB"}
@@ -0,0 +1,110 @@
1
+ import { assert } from "@woosh/meep-engine/src/core/assert.js";
2
+
3
+ let scratch_next = new Float64Array(16);
4
+
5
+ function ensure_scratch(n) {
6
+ if (scratch_next.length < n) scratch_next = new Float64Array(n);
7
+ return scratch_next;
8
+ }
9
+
10
+ /**
11
+ * Find the eigenvector corresponding to the largest-magnitude eigenvalue of a
12
+ * symmetric square matrix using power iteration.
13
+ *
14
+ * Designed for small symmetric matrices where the dominant eigenvalue is
15
+ * well-separated from the rest (Horn's quaternion method on a 4x4, PCA on a
16
+ * 3x3 covariance, etc.). Unsuitable when the top two eigenvalues have nearly
17
+ * equal magnitude — convergence stalls in that regime.
18
+ *
19
+ * NOTE: intended to live in @woosh/meep-engine under core/graph/eigen/. Kept
20
+ * local for now.
21
+ *
22
+ * @param {SquareMatrix} matrix Symmetric, column-major as per SquareMatrix
23
+ * @param {number[]|Float32Array|Float64Array} out Eigenvector is written here, length >= matrix.size
24
+ * @param {number} [max_iterations=64]
25
+ * @param {number} [tolerance=1e-8] Convergence stops when ||v_next - v|| < tolerance
26
+ * @returns {number} The Rayleigh quotient (estimated eigenvalue)
27
+ */
28
+ export function matrix_top_eigenvector_power_iteration(
29
+ matrix,
30
+ out,
31
+ max_iterations = 64,
32
+ tolerance = 1e-8
33
+ ) {
34
+ assert.defined(matrix, "matrix");
35
+ assert.defined(out, "out");
36
+
37
+ const n = matrix.size;
38
+ const data = matrix.data;
39
+
40
+ // Deterministic asymmetric initial vector. A uniform init (e.g. 1/√n in
41
+ // every slot) can be orthogonal to the dominant eigenvector when the matrix
42
+ // has block structure, stalling iteration on a sub-dominant eigenvalue.
43
+ // Irrational-component cosines avoid this for any reasonable n.
44
+ let init_norm_sq = 0;
45
+ for (let i = 0; i < n; i++) {
46
+ const v = Math.cos(i * 1.7 + 0.3);
47
+ out[i] = v;
48
+ init_norm_sq += v * v;
49
+ }
50
+ const init_inv = 1 / Math.sqrt(init_norm_sq);
51
+ for (let i = 0; i < n; i++) out[i] *= init_inv;
52
+
53
+ const next = ensure_scratch(n);
54
+ let eigenvalue = 0;
55
+
56
+ for (let iter = 0; iter < max_iterations; iter++) {
57
+ // next = matrix * out
58
+ // Column-major: data[col * n + row] is element at (row, col)
59
+ for (let row = 0; row < n; row++) {
60
+ let sum = 0;
61
+ for (let col = 0; col < n; col++) {
62
+ sum += data[col * n + row] * out[col];
63
+ }
64
+ next[row] = sum;
65
+ }
66
+
67
+ // Rayleigh quotient = out . next (since out is unit length and matrix is symmetric)
68
+ let rayleigh = 0;
69
+ for (let i = 0; i < n; i++) {
70
+ rayleigh += out[i] * next[i];
71
+ }
72
+
73
+ // Normalize next
74
+ let length_sqr = 0;
75
+ for (let i = 0; i < n; i++) {
76
+ length_sqr += next[i] * next[i];
77
+ }
78
+
79
+ if (length_sqr === 0) {
80
+ // Degenerate input — bail out, leave `out` as-is
81
+ return 0;
82
+ }
83
+
84
+ const inv_length = 1 / Math.sqrt(length_sqr);
85
+
86
+ // Sign-align next with out so we can measure convergence by raw difference.
87
+ // (Power iteration has a sign ambiguity per step when eigenvalue is negative.)
88
+ let dot = 0;
89
+ for (let i = 0; i < n; i++) {
90
+ dot += next[i] * out[i];
91
+ }
92
+ const sign = dot < 0 ? -inv_length : inv_length;
93
+
94
+ let delta_sqr = 0;
95
+ for (let i = 0; i < n; i++) {
96
+ const v = next[i] * sign;
97
+ const d = v - out[i];
98
+ delta_sqr += d * d;
99
+ out[i] = v;
100
+ }
101
+
102
+ eigenvalue = rayleigh;
103
+
104
+ if (delta_sqr < tolerance * tolerance) {
105
+ break;
106
+ }
107
+ }
108
+
109
+ return eigenvalue;
110
+ }
@@ -178,6 +178,11 @@ export class AnimationCurve implements Iterable<Keyframe> {
178
178
  * @type {boolean}
179
179
  */
180
180
  readonly isAnimationCurve: boolean;
181
+ /**
182
+ * Smooths out the curve.
183
+ * Alias to {@link alignAllTangents}.
184
+ */
185
+ smooth: () => void;
181
186
  /**
182
187
  * @deprecated use `getKeyIndexLow` instead
183
188
  */
@@ -1 +1 @@
1
- {"version":3,"file":"AnimationCurve.d.ts","sourceRoot":"","sources":["../../../../../src/engine/animation/curve/AnimationCurve.js"],"names":[],"mappings":"AASA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,gDANwB,QAAQ;IAqZ5B;;;;OAIG;IACH,kBAHW,QAAQ,EAAE,GACR,cAAc,CAQ1B;IAED;;;;;;;;;OASG;IACH,6BANW,MAAM,eACN,MAAM,YACN,MAAM,aACN,MAAM,GACL,cAAc,CAUzB;IAED;;;;;;OAMG;IACH,4BALW,MAAM,YACN,MAAM,UACN,MAAM,GACL,cAAc,CAOzB;IAED;;;;;;;OAOG;IACH,0BANW,MAAM,eACN,MAAM,YACN,MAAM,aACN,MAAM,GACL,cAAc,CAezB;IAldD;;;;;OAKG;IACH,eAFU,QAAQ,EAAE,CAEV;IAEV;;;;;OAKG;IACH,SAHW,QAAQ,GACN,MAAM,CAuClB;IAED;;;OAGG;IACH,cAFW,QAAQ,EAAE,QAUpB;IAED;;;;OAIG;IACH,YAHW,QAAQ,GACN,OAAO,CAYnB;IAED;;OAEG;IACH,cAEC;IAGD;;;OAGG;IACH,WAFY,OAAO,CAIlB;IAED;;;OAGG;IACH,qBAEC;IAED;;;;OAIG;IACH,yBAUC;IAED;;;;OAIG;IACH,uBAUC;IAED;;;;OAIG;IACH,uBAcC;IAED;;;;;;OAMG;IACH,qBAHW,MAAM,GACJ,MAAM,CAmDlB;IAED;;;;OAIG;IACH,eAHW,MAAM,GACL,MAAM,CAoCjB;IAED;;;;OAIG;IACH,qBAFW,MAAM,QAmChB;IAED;;;;OAIG;IACH,sBAHW,MAAM,UACN,MAAM,QAIhB;IAED;;OAEG;IACH,yBAQC;IAGD;;;OAGG;IACH,YAFW,cAAc,QAIxB;IAED;;;OAGG;IACH,SAFY,cAAc,CAQzB;IAED;;;;OAIG;IACH,cAHW,cAAc,GACb,OAAO,CAIlB;IAED;;;OAGG;IACH,QAFY,MAAM,CAIjB;IAED;;MAIC;IAED;;aAkBC;IAoFL;;;;OAIG;IACH,2BAFU,OAAO,CAEwB;IAGzC;;OAEG;IACH,0BA1Te,MAAM,KACJ,MAAM,CAyTmB;IA7FtC,wDAQC;CAuEJ;yBA/ewB,eAAe"}
1
+ {"version":3,"file":"AnimationCurve.d.ts","sourceRoot":"","sources":["../../../../../src/engine/animation/curve/AnimationCurve.js"],"names":[],"mappings":"AASA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,gDANwB,QAAQ;IAqZ5B;;;;OAIG;IACH,kBAHW,QAAQ,EAAE,GACR,cAAc,CAQ1B;IAED;;;;;;;;;OASG;IACH,6BANW,MAAM,eACN,MAAM,YACN,MAAM,aACN,MAAM,GACL,cAAc,CAUzB;IAED;;;;;;OAMG;IACH,4BALW,MAAM,YACN,MAAM,UACN,MAAM,GACL,cAAc,CAOzB;IAED;;;;;;;OAOG;IACH,0BANW,MAAM,eACN,MAAM,YACN,MAAM,aACN,MAAM,GACL,cAAc,CAezB;IAldD;;;;;OAKG;IACH,eAFU,QAAQ,EAAE,CAEV;IAEV;;;;;OAKG;IACH,SAHW,QAAQ,GACN,MAAM,CAuClB;IAED;;;OAGG;IACH,cAFW,QAAQ,EAAE,QAUpB;IAED;;;;OAIG;IACH,YAHW,QAAQ,GACN,OAAO,CAYnB;IAED;;OAEG;IACH,cAEC;IAGD;;;OAGG;IACH,WAFY,OAAO,CAIlB;IAED;;;OAGG;IACH,qBAEC;IAED;;;;OAIG;IACH,yBAUC;IAED;;;;OAIG;IACH,uBAUC;IAED;;;;OAIG;IACH,uBAcC;IAED;;;;;;OAMG;IACH,qBAHW,MAAM,GACJ,MAAM,CAmDlB;IAED;;;;OAIG;IACH,eAHW,MAAM,GACL,MAAM,CAoCjB;IAED;;;;OAIG;IACH,qBAFW,MAAM,QAmChB;IAED;;;;OAIG;IACH,sBAHW,MAAM,UACN,MAAM,QAIhB;IAED;;OAEG;IACH,yBAQC;IAGD;;;OAGG;IACH,YAFW,cAAc,QAIxB;IAED;;;OAGG;IACH,SAFY,cAAc,CAQzB;IAED;;;;OAIG;IACH,cAHW,cAAc,GACb,OAAO,CAIlB;IAED;;;OAGG;IACH,QAFY,MAAM,CAIjB;IAED;;MAIC;IAED;;aAkBC;IAoFL;;;;OAIG;IACH,2BAFU,OAAO,CAEwB;IAGzC;;;OAGG;IACH,mBAA+B;IAE/B;;OAEG;IACH,0BAhUe,MAAM,KACJ,MAAM,CA+TmB;IAnGtC,wDAQC;CAuEJ;yBA/ewB,eAAe"}
@@ -511,6 +511,12 @@ export class AnimationCurve {
511
511
  AnimationCurve.prototype.isAnimationCurve = true;
512
512
 
513
513
 
514
+ /**
515
+ * Smooths out the curve.
516
+ * Alias to {@link alignAllTangents}.
517
+ */
518
+ AnimationCurve.prototype.smooth = AnimationCurve.prototype.alignAllTangents;
519
+
514
520
  /**
515
521
  * @deprecated use `getKeyIndexLow` instead
516
522
  */