@woosh/meep-engine 2.134.3 → 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 +1 -1
- package/src/core/geom/vec3/v3_rigid_align_paired_unit_vectors.d.ts +23 -0
- package/src/core/geom/vec3/v3_rigid_align_paired_unit_vectors.d.ts.map +1 -0
- package/src/core/geom/vec3/v3_rigid_align_paired_unit_vectors.js +96 -0
- package/src/core/graph/eigen/matrix_top_eigenvector_power_iteration.d.ts +20 -0
- package/src/core/graph/eigen/matrix_top_eigenvector_power_iteration.d.ts.map +1 -0
- package/src/core/graph/eigen/matrix_top_eigenvector_power_iteration.js +110 -0
- package/src/engine/animation/curve/AnimationCurve.d.ts +10 -2
- package/src/engine/animation/curve/AnimationCurve.d.ts.map +1 -1
- package/src/engine/animation/curve/AnimationCurve.js +16 -12
- package/src/engine/animation/curve/view/prototype.js +1 -1
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.
|
|
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
|
+
}
|
|
@@ -136,12 +136,15 @@ export class AnimationCurve implements Iterable<Keyframe> {
|
|
|
136
136
|
*/
|
|
137
137
|
alignTangents(index: number): void;
|
|
138
138
|
/**
|
|
139
|
-
*
|
|
139
|
+
* @deprecated
|
|
140
140
|
* @param {number} index Index of keyframe to be affected
|
|
141
141
|
* @param {number} weight How much smoothing to apply, 1 will be fully smoothed out and 0 will have no effect at all. Value between 0 and 1
|
|
142
142
|
*/
|
|
143
143
|
smoothTangents(index: number, weight: number): void;
|
|
144
|
-
|
|
144
|
+
/**
|
|
145
|
+
* Smooth out the curve
|
|
146
|
+
*/
|
|
147
|
+
alignAllTangents(): void;
|
|
145
148
|
/**
|
|
146
149
|
* The copy is deep
|
|
147
150
|
* @param {AnimationCurve} other
|
|
@@ -175,6 +178,11 @@ export class AnimationCurve implements Iterable<Keyframe> {
|
|
|
175
178
|
* @type {boolean}
|
|
176
179
|
*/
|
|
177
180
|
readonly isAnimationCurve: boolean;
|
|
181
|
+
/**
|
|
182
|
+
* Smooths out the curve.
|
|
183
|
+
* Alias to {@link alignAllTangents}.
|
|
184
|
+
*/
|
|
185
|
+
smooth: () => void;
|
|
178
186
|
/**
|
|
179
187
|
* @deprecated use `getKeyIndexLow` instead
|
|
180
188
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AnimationCurve.d.ts","sourceRoot":"","sources":["../../../../../src/engine/animation/curve/AnimationCurve.js"],"names":[],"mappings":"
|
|
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"}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { assert } from "../../../core/assert.js";
|
|
2
2
|
import { computeHashArray } from "../../../core/collection/array/computeHashArray.js";
|
|
3
3
|
import { isArrayEqual } from "../../../core/collection/array/isArrayEqual.js";
|
|
4
|
-
import { lerp } from "../../../core/math/lerp.js";
|
|
5
4
|
import { invokeObjectClone } from "../../../core/model/object/invokeObjectClone.js";
|
|
6
5
|
import { invokeObjectHash } from "../../../core/model/object/invokeObjectHash.js";
|
|
7
6
|
import { invokeObjectToJSON } from "../../../core/model/object/invokeObjectToJSON.js";
|
|
@@ -337,25 +336,24 @@ export class AnimationCurve {
|
|
|
337
336
|
}
|
|
338
337
|
|
|
339
338
|
/**
|
|
340
|
-
*
|
|
339
|
+
* @deprecated
|
|
341
340
|
* @param {number} index Index of keyframe to be affected
|
|
342
341
|
* @param {number} weight How much smoothing to apply, 1 will be fully smoothed out and 0 will have no effect at all. Value between 0 and 1
|
|
343
342
|
*/
|
|
344
343
|
smoothTangents(index, weight) {
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
const key = keys[index];
|
|
348
|
-
|
|
349
|
-
const average = lerp(key.inTangent, key.outTangent, 0.5);
|
|
350
|
-
|
|
351
|
-
key.inTangent = lerp(key.inTangent, average, weight);
|
|
352
|
-
key.outTangent = lerp(key.outTangent, average, weight);
|
|
344
|
+
throw new Error('Deprecated, use alignTagents() instead');
|
|
353
345
|
}
|
|
354
346
|
|
|
355
|
-
|
|
347
|
+
/**
|
|
348
|
+
* Smooth out the curve
|
|
349
|
+
*/
|
|
350
|
+
alignAllTangents() {
|
|
356
351
|
const n = this.length;
|
|
352
|
+
|
|
353
|
+
// TODO add support for looping curves
|
|
354
|
+
|
|
357
355
|
for (let i = 0; i < n; i++) {
|
|
358
|
-
this.
|
|
356
|
+
this.alignTangents(i);
|
|
359
357
|
}
|
|
360
358
|
}
|
|
361
359
|
|
|
@@ -513,6 +511,12 @@ export class AnimationCurve {
|
|
|
513
511
|
AnimationCurve.prototype.isAnimationCurve = true;
|
|
514
512
|
|
|
515
513
|
|
|
514
|
+
/**
|
|
515
|
+
* Smooths out the curve.
|
|
516
|
+
* Alias to {@link alignAllTangents}.
|
|
517
|
+
*/
|
|
518
|
+
AnimationCurve.prototype.smooth = AnimationCurve.prototype.alignAllTangents;
|
|
519
|
+
|
|
516
520
|
/**
|
|
517
521
|
* @deprecated use `getKeyIndexLow` instead
|
|
518
522
|
*/
|