@woosh/meep-engine 2.131.17 → 2.131.19
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/editor/ecs/component/editors/geom/QuaternionEditor.js +3 -3
- package/editor/tools/TransformTool.js +14 -3
- package/package.json +1 -1
- package/src/core/geom/Quaternion.d.ts +52 -19
- package/src/core/geom/Quaternion.d.ts.map +1 -1
- package/src/core/geom/Quaternion.js +77 -27
- package/src/core/geom/Vector3.d.ts +3 -0
- package/src/core/geom/Vector3.d.ts.map +1 -1
- package/src/core/geom/Vector3.js +16 -6
- package/src/core/math/spline/spline3_hermite.d.ts +1 -1
- package/src/core/math/spline/spline3_hermite.js +1 -1
- package/src/core/math/spline/spline3_hermite_bounds.d.ts +1 -1
- package/src/core/math/spline/spline3_hermite_bounds.js +2 -2
- package/src/core/math/spline/spline3_hermite_derivative.d.ts +8 -6
- package/src/core/math/spline/spline3_hermite_derivative.d.ts.map +1 -1
- package/src/core/math/spline/spline3_hermite_derivative.js +10 -7
- package/src/core/math/spline/spline3_hermite_integral.d.ts +14 -0
- package/src/core/math/spline/spline3_hermite_integral.d.ts.map +1 -0
- package/src/core/math/spline/spline3_hermite_integral.js +35 -0
- package/src/core/math/spline/spline3_hermite_subdivide.d.ts +1 -1
- package/src/core/math/spline/spline3_hermite_subdivide.js +1 -1
- package/src/core/model/node-graph/NodeGraph.d.ts +1 -0
- package/src/core/model/node-graph/NodeGraph.d.ts.map +1 -1
- package/src/core/model/node-graph/NodeGraph.js +4 -0
- package/src/engine/animation/curve/animation_curve_fit.d.ts +17 -0
- package/src/engine/animation/curve/animation_curve_fit.d.ts.map +1 -0
- package/src/engine/animation/curve/animation_curve_fit.js +195 -0
- package/src/engine/animation/curve/animation_curve_optimize.d.ts.map +1 -1
- package/src/engine/animation/curve/animation_curve_optimize.js +65 -21
- package/src/engine/animation/curve/animation_curve_subdivide.d.ts +4 -2
- package/src/engine/animation/curve/animation_curve_subdivide.d.ts.map +1 -1
- package/src/engine/animation/curve/animation_curve_subdivide.js +4 -2
- package/src/engine/ecs/transform/Transform.d.ts +9 -6
- package/src/engine/ecs/transform/Transform.d.ts.map +1 -1
- package/src/engine/ecs/transform/Transform.js +15 -8
- package/src/engine/graphics/ecs/camera/topdown/ComputeCameraFacingVector.js +1 -1
- package/src/engine/graphics/ecs/camera/topdown/TopDownCameraControllerSystem.js +1 -1
- package/src/engine/graphics/ecs/mesh-v2/aggregate/prototypeSGMesh.js +1 -1
- package/src/engine/graphics/render/forward_plus/plugin/ptototypeFPPlugin.js +1 -1
- package/src/generation/markers/transform/MarkerNodeTransformerYRotateByFilter.d.ts.map +1 -1
- package/src/generation/markers/transform/MarkerNodeTransformerYRotateByFilter.js +3 -3
- package/src/generation/markers/transform/MarkerNodeTransformerYRotateByFilterGradient.d.ts.map +1 -1
- package/src/generation/markers/transform/MarkerNodeTransformerYRotateByFilterGradient.js +5 -6
- package/src/view/View.d.ts +3 -3
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Calculates the integral (area under the curve) of a cubic hermite spline from 0 to t.
|
|
3
|
+
*
|
|
4
|
+
* @param {number} t normalized interpolation position in interval [0,1]
|
|
5
|
+
* @param {number} p0 first value
|
|
6
|
+
* @param {number} p1 second value
|
|
7
|
+
* @param {number} m0 first tangent
|
|
8
|
+
* @param {number} m1 second tangent
|
|
9
|
+
* @returns {number} The definite integral from 0 to t
|
|
10
|
+
*
|
|
11
|
+
* @see spline3_hermite_derivative
|
|
12
|
+
*/
|
|
13
|
+
export function spline3_hermite_integral(t, p0, p1, m0, m1) {
|
|
14
|
+
const t2 = t * t;
|
|
15
|
+
const t3 = t2 * t;
|
|
16
|
+
const t4 = t3 * t;
|
|
17
|
+
|
|
18
|
+
// Integral of (2t^3 - 3t^2 + 1)
|
|
19
|
+
// Result: 0.5t^4 - t^3 + t
|
|
20
|
+
const int_p0 = 0.5 * t4 - t3 + t;
|
|
21
|
+
|
|
22
|
+
// Integral of (t^3 - 2t^2 + t)
|
|
23
|
+
// Result: 0.25t^4 - (2/3)t^3 + 0.5t^2
|
|
24
|
+
const int_m0 = 0.25 * t4 - (2.0 / 3.0) * t3 + 0.5 * t2;
|
|
25
|
+
|
|
26
|
+
// Integral of (t^3 - t^2)
|
|
27
|
+
// Result: 0.25t^4 - (1/3)t^3
|
|
28
|
+
const int_m1 = 0.25 * t4 - (1.0 / 3.0) * t3;
|
|
29
|
+
|
|
30
|
+
// Integral of (3t^2 - 2t^3)
|
|
31
|
+
// Result: t^3 - 0.5t^4
|
|
32
|
+
const int_p1 = t3 - 0.5 * t4;
|
|
33
|
+
|
|
34
|
+
return int_p0 * p0 + int_m0 * m0 + int_m1 * m1 + int_p1 * p1;
|
|
35
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Subdivides a
|
|
2
|
+
* Subdivides a Hermite curve into two hermite curves.
|
|
3
3
|
* The result is written in form [a_p0, a_p1, a_m0, a_m1, b_p0, b_p1, b_m0, b_m1], note the stride and offset.
|
|
4
4
|
* @param {number[]} output where to write the result
|
|
5
5
|
* @param {number} output_offset where to start writing
|
|
@@ -3,7 +3,7 @@ import { spline3_hermite } from "./spline3_hermite.js";
|
|
|
3
3
|
import { spline3_hermite_derivative } from "./spline3_hermite_derivative.js";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
* Subdivides a
|
|
6
|
+
* Subdivides a Hermite curve into two hermite curves.
|
|
7
7
|
* The result is written in form [a_p0, a_p1, a_m0, a_m1, b_p0, b_p1, b_m0, b_m1], note the stride and offset.
|
|
8
8
|
* @param {number[]} output where to write the result
|
|
9
9
|
* @param {number} output_offset where to start writing
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NodeGraph.d.ts","sourceRoot":"","sources":["../../../../../src/core/model/node-graph/NodeGraph.js"],"names":[],"mappings":"AASA;;;;;;;;GAQG;AACH;IAEI;;;;OAIG;IACH,uBAAmB;IAEnB;;;;;OAKG;IACH,6BAAyB;IAEzB;;;;;OAKG;IACH,4BAA0B;IAE1B;;;;;OAKG;IACH,kCAAgC;IAQhC;;;;;OAKG;IACH,+BAEC;IAED;;OAEG;IACH;QACI;;;WAGG;;QAGH;;;WAGG;;QAGH;;;WAGG;;QAGH;;;WAGG;;MAEL;IAEF;;OAEG;IACH,cAQC;IAED;;;OAGG;IACH,YAFW,SAAS,QAYnB;IAED;;;OAGG;IACH,SAFa,SAAS,CAQrB;IAED;;;;;;OAMG;IACH,aAHW,SAAS,GACP;QAAC,WAAW,EAAC,UAAU,EAAE,CAAC;QAAC,KAAK,EAAC,YAAY,EAAE,CAAA;KAAC,CAe5D;IAED;;;;;;;;OAQG;IACH,sCAJW,YAAY,EAAE,GAEZ;QAAC,WAAW,EAAC,UAAU,EAAE,CAAC;QAAC,KAAK,EAAC,YAAY,EAAE,CAAA;KAAC,CAmF5D;IAED;;;;OAIG;IACH,8BAHoB,YAAY,+BAK/B;IAED;;;;OAIG;IACH,oCAHoB,UAAU,+BAK7B;IAED;;;;OAIG;IACH,YAFY,YAAY,EAAE,CAIzB;IAED;;;;OAIG;IACH,kBAFY,UAAU,EAAE,CAIvB;IAED;;;;OAIG;IACH,cAHW,YAAY,GACV,OAAO,CAgBnB;IAED;;;;OAIG;IACH,qDAFa,YAAY,EAAE,CAsB1B;IAED;;;;OAIG;IACH,0DAFa,YAAY,EAAE,CAqB1B;IAED;;;;OAIG;IACH,YAHW,MAAM,GACJ,YAAY,GAAC,SAAS,CAkBlC;IAED;;;;;OAKG;IACH,gBAJW,MAAM,GACJ,YAAY,CAWxB;IAED;;;;OAIG;IACH,kBAHW,MAAM,GACJ,UAAU,GAAC,SAAS,CAgBhC;IAED;;;;;OAKG;IACH,+BAJW,MAAM,WACN,MAAM,GACJ,4BAA0B,SAAS,CAY/C;IAED;;;;OAIG;IACH,mCAFa,MAAM,CAclB;IAED;;;OAGG;IACH,cAFW,YAAY,QAkBtB;IAED;;;;OAIG;IACH,eAHW,MAAM,GACJ,OAAO,CA8BnB;IAED;;;;;;;;OAQG;IACH,uCANW,MAAM,cACN,MAAM,cACN,MAAM,cACN,MAAM,GACJ,MAAM,CAqClB;IAED;;;;;;;;OAQG;IACH,6BAPW,MAAM,cACN,MAAM,cACN,MAAM,cACN,MAAM,GACJ,MAAM,CAuDlB;IAED;;;;OAIG;IACH,qBAHW,MAAM,GACJ,OAAO,CAyBnB;IAED;;;;;OAKG;IACH,iCAJW,MAAM,UACN,MAAM,EAAE,GACN,MAAM,CAyBlB;IAGL;;;;;;;;OAQG;IACH,sBAFU,OAAO,CAEc;;CAX9B;
|
|
1
|
+
{"version":3,"file":"NodeGraph.d.ts","sourceRoot":"","sources":["../../../../../src/core/model/node-graph/NodeGraph.js"],"names":[],"mappings":"AASA;;;;;;;;GAQG;AACH;IAEI;;;;OAIG;IACH,uBAAmB;IAEnB;;;;;OAKG;IACH,6BAAyB;IAEzB;;;;;OAKG;IACH,4BAA0B;IAE1B;;;;;OAKG;IACH,kCAAgC;IAQhC;;;;;OAKG;IACH,+BAEC;IAED;;OAEG;IACH;QACI;;;WAGG;;QAGH;;;WAGG;;QAGH;;;WAGG;;QAGH;;;WAGG;;MAEL;IAEF;;OAEG;IACH,cAQC;IAED;;;OAGG;IACH,YAFW,SAAS,QAYnB;IAED;;;OAGG;IACH,SAFa,SAAS,CAQrB;IAED;;;;;;OAMG;IACH,aAHW,SAAS,GACP;QAAC,WAAW,EAAC,UAAU,EAAE,CAAC;QAAC,KAAK,EAAC,YAAY,EAAE,CAAA;KAAC,CAe5D;IAED;;;;;;;;OAQG;IACH,sCAJW,YAAY,EAAE,GAEZ;QAAC,WAAW,EAAC,UAAU,EAAE,CAAC;QAAC,KAAK,EAAC,YAAY,EAAE,CAAA;KAAC,CAmF5D;IAED;;;;OAIG;IACH,8BAHoB,YAAY,+BAK/B;IAED;;;;OAIG;IACH,oCAHoB,UAAU,+BAK7B;IAED;;;;OAIG;IACH,YAFY,YAAY,EAAE,CAIzB;IAED;;;;OAIG;IACH,kBAFY,UAAU,EAAE,CAIvB;IAED;;;;OAIG;IACH,cAHW,YAAY,GACV,OAAO,CAgBnB;IAED;;;;OAIG;IACH,qDAFa,YAAY,EAAE,CAsB1B;IAED;;;;OAIG;IACH,0DAFa,YAAY,EAAE,CAqB1B;IAED;;;;OAIG;IACH,YAHW,MAAM,GACJ,YAAY,GAAC,SAAS,CAkBlC;IAED;;;;;OAKG;IACH,gBAJW,MAAM,GACJ,YAAY,CAWxB;IAED;;;;OAIG;IACH,kBAHW,MAAM,GACJ,UAAU,GAAC,SAAS,CAgBhC;IAED;;;;;OAKG;IACH,+BAJW,MAAM,WACN,MAAM,GACJ,4BAA0B,SAAS,CAY/C;IAED;;;;OAIG;IACH,mCAFa,MAAM,CAclB;IAED;;;OAGG;IACH,cAFW,YAAY,QAkBtB;IAED;;;;OAIG;IACH,eAHW,MAAM,GACJ,OAAO,CA8BnB;IAED;;;;;;;;OAQG;IACH,uCANW,MAAM,cACN,MAAM,cACN,MAAM,cACN,MAAM,GACJ,MAAM,CAqClB;IAED;;;;;;;;OAQG;IACH,6BAPW,MAAM,cACN,MAAM,cACN,MAAM,cACN,MAAM,GACJ,MAAM,CAuDlB;IAED;;;;OAIG;IACH,qBAHW,MAAM,GACJ,OAAO,CAyBnB;IAED;;;;;OAKG;IACH,iCAJW,MAAM,UACN,MAAM,EAAE,GACN,MAAM,CAyBlB;IAED,mBAEC;IAGL;;;;;;;;OAQG;IACH,sBAFU,OAAO,CAEc;;CAX9B;6BA1qB4B,wBAAwB;2BAD1B,iBAAiB"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fits a smooth {@link AnimationCurve} to a set of discrete 2D points using adaptive Cubic Hermite Spline fitting.
|
|
3
|
+
*
|
|
4
|
+
* This utility performs data reduction (lossy compression) on dense time-series data.
|
|
5
|
+
* It recursively subdivides the dataset, inserting {@link Keyframe}s only where the interpolated curve deviates from the original points by more than `maxError`.
|
|
6
|
+
*
|
|
7
|
+
* Tangents are automatically estimated based on the slope of the input data (Catmull-Rom style), ensuring smooth transitions between keyframes.
|
|
8
|
+
*
|
|
9
|
+
* @param {number[]} points flat array of coordinates [x0, y0, x1, y1, ... xn, yn]
|
|
10
|
+
* @param {number} [input_offset] flat offset into the input array where to start reading data
|
|
11
|
+
* @param {number} [input_count] number of points to fit, counted in points i.e., pairs of (x,y) values
|
|
12
|
+
* @param {number} [maxError] Maximum allowed deviation. Higher values produce fewer keys (more compression), lower values preserve more detail.
|
|
13
|
+
* @returns {AnimationCurve}
|
|
14
|
+
*/
|
|
15
|
+
export function animation_curve_fit(points: number[], input_offset?: number, input_count?: number, maxError?: number): AnimationCurve;
|
|
16
|
+
import { AnimationCurve } from "./AnimationCurve.js";
|
|
17
|
+
//# sourceMappingURL=animation_curve_fit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"animation_curve_fit.d.ts","sourceRoot":"","sources":["../../../../../src/engine/animation/curve/animation_curve_fit.js"],"names":[],"mappings":"AAkEA;;;;;;;;;;;;;GAaG;AACH,4CANW,MAAM,EAAE,iBACR,MAAM,gBACN,MAAM,aACN,MAAM,GACJ,cAAc,CAoH1B;+BA/L8B,qBAAqB"}
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import { assert } from "../../../core/assert.js";
|
|
2
|
+
import { spline3_hermite } from "../../../core/math/spline/spline3_hermite.js";
|
|
3
|
+
import { number_compare_ascending } from "../../../core/primitives/numbers/number_compare_ascending.js";
|
|
4
|
+
import { AnimationCurve } from "./AnimationCurve.js";
|
|
5
|
+
import { Keyframe } from "./Keyframe.js";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Calculates a Catmull-Rom style tangent (slope) for a point in the dataset.
|
|
9
|
+
* @param {number[]} points
|
|
10
|
+
* @param {number} points_offset
|
|
11
|
+
* @param {number} points_count
|
|
12
|
+
* @param {number} index
|
|
13
|
+
*/
|
|
14
|
+
function calculateTangent(
|
|
15
|
+
points,
|
|
16
|
+
points_offset,
|
|
17
|
+
points_count,
|
|
18
|
+
index
|
|
19
|
+
) {
|
|
20
|
+
|
|
21
|
+
const current = points_offset + index * 2;
|
|
22
|
+
|
|
23
|
+
// Handle boundaries: Linear slope to neighbor
|
|
24
|
+
if (index === 0) {
|
|
25
|
+
const next = points_offset + 2;
|
|
26
|
+
|
|
27
|
+
const dt = points[next] - points[current];
|
|
28
|
+
|
|
29
|
+
if (dt === 0) {
|
|
30
|
+
return 0;
|
|
31
|
+
} else {
|
|
32
|
+
return (points[next + 1] - points[current + 1]) / dt;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
}
|
|
36
|
+
if (index === points_count - 1) {
|
|
37
|
+
const prev = points_offset + (points_count - 2) * 2;
|
|
38
|
+
|
|
39
|
+
const dt = points[current] - points[prev];
|
|
40
|
+
|
|
41
|
+
if (dt === 0) {
|
|
42
|
+
return 0;
|
|
43
|
+
} else {
|
|
44
|
+
return (points[current + 1] - points[prev + 1]) / dt;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Handle internal points: Average slope between prev and next (Finite Difference)
|
|
50
|
+
const next = points_offset + (index + 1) * 2;
|
|
51
|
+
const prev = points_offset + (index - 1) * 2;
|
|
52
|
+
|
|
53
|
+
// A simpler approach is the slope between prev and next directly:
|
|
54
|
+
// return (next.value - prev.value) / (next.time - prev.time);
|
|
55
|
+
|
|
56
|
+
// However, weighted average often looks better for non-uniform time steps:
|
|
57
|
+
const dt0 = points[current] - points[prev];
|
|
58
|
+
const slope0 = dt0 === 0 ? 0 : (points[current + 1] - points[prev + 1]) / dt0;
|
|
59
|
+
|
|
60
|
+
const dt1 = points[next] - points[current];
|
|
61
|
+
const slope1 = dt1 === 0 ? 0 : (points[next + 1] - points[current + 1]) / dt1;
|
|
62
|
+
|
|
63
|
+
// Average the slopes
|
|
64
|
+
return (slope0 + slope1) * 0.5;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Fits a smooth {@link AnimationCurve} to a set of discrete 2D points using adaptive Cubic Hermite Spline fitting.
|
|
69
|
+
*
|
|
70
|
+
* This utility performs data reduction (lossy compression) on dense time-series data.
|
|
71
|
+
* It recursively subdivides the dataset, inserting {@link Keyframe}s only where the interpolated curve deviates from the original points by more than `maxError`.
|
|
72
|
+
*
|
|
73
|
+
* Tangents are automatically estimated based on the slope of the input data (Catmull-Rom style), ensuring smooth transitions between keyframes.
|
|
74
|
+
*
|
|
75
|
+
* @param {number[]} points flat array of coordinates [x0, y0, x1, y1, ... xn, yn]
|
|
76
|
+
* @param {number} [input_offset] flat offset into the input array where to start reading data
|
|
77
|
+
* @param {number} [input_count] number of points to fit, counted in points i.e., pairs of (x,y) values
|
|
78
|
+
* @param {number} [maxError] Maximum allowed deviation. Higher values produce fewer keys (more compression), lower values preserve more detail.
|
|
79
|
+
* @returns {AnimationCurve}
|
|
80
|
+
*/
|
|
81
|
+
export function animation_curve_fit(
|
|
82
|
+
points,
|
|
83
|
+
input_offset = 0,
|
|
84
|
+
input_count = ((points.length - input_offset) / 2),
|
|
85
|
+
maxError = 0.01
|
|
86
|
+
) {
|
|
87
|
+
assert.defined(points, 'points');
|
|
88
|
+
assert.isNonNegativeInteger(input_offset, 'input_offset');
|
|
89
|
+
assert.isNonNegativeInteger(input_count, 'input_count');
|
|
90
|
+
assert.notNaN(maxError, 'maxError');
|
|
91
|
+
assert.greaterThanOrEqual(maxError, 0, 'maxError must be non-negative');
|
|
92
|
+
|
|
93
|
+
if (input_count === 0) {
|
|
94
|
+
return new AnimationCurve();
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (input_count === 1) {
|
|
98
|
+
return AnimationCurve.from([Keyframe.from(points[input_offset], points[input_offset + 1])]);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// 1. Identify which indices from the source array we need to keep as Keyframes
|
|
102
|
+
const keyIndices = new Set();
|
|
103
|
+
|
|
104
|
+
// Always keep first and last
|
|
105
|
+
keyIndices.add(0);
|
|
106
|
+
keyIndices.add(input_count - 1);
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Recursive function to find split points
|
|
110
|
+
* @param {number} firstIndex
|
|
111
|
+
* @param {number} lastIndex
|
|
112
|
+
*/
|
|
113
|
+
function fitSegment(firstIndex, lastIndex) {
|
|
114
|
+
if (lastIndex - firstIndex <= 1) {
|
|
115
|
+
// done
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// A. Estimate tangents for the start and end of this segment
|
|
120
|
+
// We calculate tangents based on the *original* dense data to ensure accurate slope
|
|
121
|
+
const m0 = calculateTangent(points, input_offset, input_count, firstIndex);
|
|
122
|
+
const m1 = calculateTangent(points, input_offset, input_count, lastIndex);
|
|
123
|
+
|
|
124
|
+
const address_0 = input_offset + firstIndex * 2;
|
|
125
|
+
const address_1 = input_offset + lastIndex * 2;
|
|
126
|
+
|
|
127
|
+
const tStart = points[address_0];
|
|
128
|
+
const tEnd = points[address_1];
|
|
129
|
+
const vStart = points[address_0 + 1];
|
|
130
|
+
const vEnd = points[address_1 + 1];
|
|
131
|
+
const duration = tEnd - tStart;
|
|
132
|
+
|
|
133
|
+
if (duration < 1e-12) {
|
|
134
|
+
// duration is very low, we're in division-by-zero territory
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// B. Find the point in this range with the greatest error vs the hypothetical curve
|
|
139
|
+
let maxSegmentError = 0;
|
|
140
|
+
let splitIndex = -1;
|
|
141
|
+
|
|
142
|
+
for (let i = firstIndex + 1; i < lastIndex; i++) {
|
|
143
|
+
const address = input_offset + i * 2;
|
|
144
|
+
|
|
145
|
+
// Normalize time t to [0, 1] for the Hermite formula
|
|
146
|
+
const t = (points[address] - tStart) / duration;
|
|
147
|
+
|
|
148
|
+
// Evaluate Cubic Hermite Spline
|
|
149
|
+
const evaluatedValue = spline3_hermite(t, vStart, vEnd, m0 * duration, m1 * duration);
|
|
150
|
+
|
|
151
|
+
const error = Math.abs(points[address + 1] - evaluatedValue);
|
|
152
|
+
|
|
153
|
+
if (error > maxSegmentError) {
|
|
154
|
+
maxSegmentError = error;
|
|
155
|
+
splitIndex = i;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// C. If error is too high, mark the split point as a Keyframe and recurse
|
|
160
|
+
if (maxSegmentError > maxError) {
|
|
161
|
+
keyIndices.add(splitIndex);
|
|
162
|
+
fitSegment(firstIndex, splitIndex);
|
|
163
|
+
fitSegment(splitIndex, lastIndex);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// Start the recursion
|
|
168
|
+
fitSegment(0, input_count - 1);
|
|
169
|
+
|
|
170
|
+
// 2. Build the final curve from the selected indices
|
|
171
|
+
const sortedIndices = Array.from(keyIndices).sort(number_compare_ascending);
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
*
|
|
175
|
+
* @type {Keyframe[]}
|
|
176
|
+
*/
|
|
177
|
+
const resultKeys = [];
|
|
178
|
+
|
|
179
|
+
const fitted_key_count = sortedIndices.length;
|
|
180
|
+
|
|
181
|
+
for (let i = 0; i < fitted_key_count; i++) {
|
|
182
|
+
const idx = sortedIndices[i];
|
|
183
|
+
const address = input_offset + idx * 2;
|
|
184
|
+
|
|
185
|
+
// Calculate the smooth tangent for this key
|
|
186
|
+
// Note: For sharp transitions, you might want to break continuity,
|
|
187
|
+
// but for approximation, continuous slope is usually desired.
|
|
188
|
+
const tangent = calculateTangent(points, input_offset, input_count, idx);
|
|
189
|
+
|
|
190
|
+
// Create a keyframe. Assuming inTangent == outTangent for smooth fitting.
|
|
191
|
+
resultKeys.push(Keyframe.from(points[address], points[address + 1], tangent, tangent));
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
return AnimationCurve.from(resultKeys);
|
|
195
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"animation_curve_optimize.d.ts","sourceRoot":"","sources":["../../../../../src/engine/animation/curve/animation_curve_optimize.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"animation_curve_optimize.d.ts","sourceRoot":"","sources":["../../../../../src/engine/animation/curve/animation_curve_optimize.js"],"names":[],"mappings":"AA+EA;;;;;;;;;;GAUG;AACH,kFANW,MAAM,GACJ,MAAM,CAoElB"}
|
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
import { assert } from "../../../core/assert.js";
|
|
2
2
|
import AABB2 from "../../../core/geom/2d/aabb/AABB2.js";
|
|
3
|
+
import { spline3_hermite_derivative } from "../../../core/math/spline/spline3_hermite_derivative.js";
|
|
3
4
|
import { animation_curve_compute_aabb } from "./animation_curve_compute_aabb.js";
|
|
4
5
|
import { evaluate_two_key_curve } from "./evaluate_two_key_curve.js";
|
|
5
6
|
|
|
6
7
|
const bounds = new AABB2();
|
|
7
8
|
|
|
8
|
-
|
|
9
|
+
// Scaling factor to project slope error into value error.
|
|
10
|
+
// 0.125 (1/8th) is a standard approximation for cubic bezier error bounds.
|
|
11
|
+
const TANGENT_ERROR_WEIGHT = 0.125;
|
|
9
12
|
|
|
10
13
|
/**
|
|
11
|
-
*
|
|
14
|
+
* Computes importance by checking Position AND Slope integrity.
|
|
15
|
+
* Uses exact derivative calculation instead of neighbor sampling
|
|
16
|
+
*
|
|
12
17
|
* @param {Keyframe} key_middle
|
|
13
18
|
* @param {Keyframe} key_previous
|
|
14
19
|
* @param {Keyframe} key_next
|
|
@@ -22,30 +27,54 @@ function compute_keyframe_value_effect(
|
|
|
22
27
|
key_previous,
|
|
23
28
|
key_next
|
|
24
29
|
) {
|
|
30
|
+
const duration = key_next.time - key_previous.time;
|
|
31
|
+
|
|
32
|
+
// Safety check for zero-duration (duplicate keys handled by outer loop, but safe to guard)
|
|
33
|
+
if (duration < 1e-9){
|
|
34
|
+
return 0;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// 1. Calculate Normalized Time t [0, 1]
|
|
38
|
+
const t_relative = key_middle.time - key_previous.time;
|
|
39
|
+
const t_normalized = t_relative / duration;
|
|
25
40
|
|
|
26
|
-
//
|
|
27
|
-
|
|
28
|
-
const
|
|
41
|
+
// 2. Calculate Position Error (The "Hit Test")
|
|
42
|
+
// Does the simplified curve actually hit the middle key's value?
|
|
43
|
+
const v_actual = evaluate_two_key_curve(key_middle.time, key_previous, key_next);
|
|
44
|
+
const v_error = Math.abs(v_actual - key_middle.value);
|
|
29
45
|
|
|
30
|
-
|
|
46
|
+
// 3. Calculate Derivative Error (The "Shape Test")
|
|
47
|
+
// Does the simplified curve flow in the same direction as the original key?
|
|
31
48
|
|
|
32
|
-
//
|
|
33
|
-
|
|
49
|
+
// NOTE: Hermite basis requires tangents scaled by duration (m0, m1)
|
|
50
|
+
// We assume keyframes have .outTangent and .inTangent or similar.
|
|
51
|
+
// If you use standard Hermite data, it looks like this:
|
|
52
|
+
const m0 = key_previous.outTangent * duration;
|
|
53
|
+
const m1 = key_next.inTangent * duration;
|
|
34
54
|
|
|
35
|
-
|
|
36
|
-
const
|
|
55
|
+
// This returns the derivative in "Value per Normalized Time"
|
|
56
|
+
const slope_normalized = spline3_hermite_derivative(
|
|
57
|
+
t_normalized,
|
|
58
|
+
key_previous.value,
|
|
59
|
+
key_next.value,
|
|
60
|
+
m0,
|
|
61
|
+
m1
|
|
62
|
+
);
|
|
37
63
|
|
|
38
|
-
|
|
64
|
+
// Convert to "Value per Second" to match the keyframe's stored tangent
|
|
65
|
+
const slope_actual = slope_normalized / duration;
|
|
39
66
|
|
|
40
|
-
//
|
|
41
|
-
|
|
67
|
+
// We compare against the explicit tangent stored on the middle key (or calculated implicit tangent)
|
|
68
|
+
// Assuming the key has a unified tangent or we use the inTangent
|
|
69
|
+
const slope_expected = key_middle.inTangent; // or .outTangent, or average if smooth
|
|
42
70
|
|
|
43
|
-
const
|
|
44
|
-
const v2_expected = evaluate_two_key_curve(v2_time, key_middle, key_next);
|
|
71
|
+
const slope_delta = Math.abs(slope_actual - slope_expected);
|
|
45
72
|
|
|
46
|
-
|
|
73
|
+
// 4. Project Slope Delta into Value Units
|
|
74
|
+
// If the slope is off by 1 unit/sec, how much drift does that cause over the duration?
|
|
75
|
+
const slope_error_projected = slope_delta * duration * TANGENT_ERROR_WEIGHT;
|
|
47
76
|
|
|
48
|
-
return Math.max(
|
|
77
|
+
return Math.max(v_error, slope_error_projected);
|
|
49
78
|
}
|
|
50
79
|
|
|
51
80
|
/**
|
|
@@ -65,11 +94,22 @@ export function animation_curve_optimize(
|
|
|
65
94
|
) {
|
|
66
95
|
assert.lessThan(error_tolerance, 1, 'error_tolerance must be less than 1');
|
|
67
96
|
|
|
97
|
+
let key_count = curve.length;
|
|
98
|
+
|
|
99
|
+
if (key_count <= 1) {
|
|
100
|
+
// nothing to remove
|
|
101
|
+
return 0;
|
|
102
|
+
}
|
|
103
|
+
|
|
68
104
|
animation_curve_compute_aabb(bounds, curve);
|
|
69
105
|
|
|
70
|
-
const
|
|
106
|
+
const EPSILON = 1e-9;
|
|
71
107
|
|
|
72
|
-
|
|
108
|
+
// Clamp against epsilon to handle the flat-line case or very low tolerances resulting in precision issues
|
|
109
|
+
const absolute_error_tolerance = Math.max(
|
|
110
|
+
bounds.height * error_tolerance,
|
|
111
|
+
EPSILON,
|
|
112
|
+
);
|
|
73
113
|
|
|
74
114
|
const keyframes = curve.keys;
|
|
75
115
|
|
|
@@ -84,9 +124,8 @@ export function animation_curve_optimize(
|
|
|
84
124
|
if (key_current.equals(key_previous)) {
|
|
85
125
|
// adds no semantic value
|
|
86
126
|
should_remove = true;
|
|
87
|
-
}
|
|
127
|
+
} else if (i < key_count - 1) {
|
|
88
128
|
|
|
89
|
-
if (!should_remove && i < key_count - 1) {
|
|
90
129
|
const key_next = keyframes[i + 1];
|
|
91
130
|
|
|
92
131
|
const max_error = compute_keyframe_value_effect(key_current, key_previous, key_next);
|
|
@@ -95,13 +134,18 @@ export function animation_curve_optimize(
|
|
|
95
134
|
// does not significantly affect the curve shape
|
|
96
135
|
should_remove = true;
|
|
97
136
|
}
|
|
137
|
+
|
|
98
138
|
}
|
|
99
139
|
|
|
100
140
|
|
|
101
141
|
if (should_remove) {
|
|
142
|
+
|
|
102
143
|
curve.remove(key_current);
|
|
144
|
+
|
|
145
|
+
// update iterator
|
|
103
146
|
i--;
|
|
104
147
|
key_count--;
|
|
148
|
+
|
|
105
149
|
}
|
|
106
150
|
}
|
|
107
151
|
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Subdivide a curve segment by introducing a new keyframe at a given normalized time.
|
|
3
3
|
* Subdivision does not alter the curve shape in any way, it is intended primarily for editing purposes.
|
|
4
|
+
*
|
|
4
5
|
* @param {Keyframe} out keyframe to be added at the point of subdivision, its tangents, time and value will be overwritten
|
|
5
|
-
* @param {Keyframe} key0
|
|
6
|
-
* @param {Keyframe} key1
|
|
6
|
+
* @param {Keyframe} key0 start of the segment
|
|
7
|
+
* @param {Keyframe} key1 end of the segment
|
|
7
8
|
* @param {number} t normalized time in [0..1] between key0 and key1 where new frame is to be inserted
|
|
8
9
|
* @returns {Keyframe} `out`, for convenience
|
|
10
|
+
*
|
|
9
11
|
* @see AnimationCurve
|
|
10
12
|
* @example
|
|
11
13
|
* const new_frame = animation_curve_subdivide(new Keyframe(), key0, key1, 0.5);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"animation_curve_subdivide.d.ts","sourceRoot":"","sources":["../../../../../src/engine/animation/curve/animation_curve_subdivide.js"],"names":[],"mappings":"AAKA
|
|
1
|
+
{"version":3,"file":"animation_curve_subdivide.d.ts","sourceRoot":"","sources":["../../../../../src/engine/animation/curve/animation_curve_subdivide.js"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;GAcG;AACH,+CAXW,QAAQ,QACR,QAAQ,QACR,QAAQ,KACR,MAAM,GACJ,QAAQ,CAsDpB"}
|
|
@@ -6,11 +6,13 @@ import { spline3_hermite_derivative } from "../../../core/math/spline/spline3_he
|
|
|
6
6
|
/**
|
|
7
7
|
* Subdivide a curve segment by introducing a new keyframe at a given normalized time.
|
|
8
8
|
* Subdivision does not alter the curve shape in any way, it is intended primarily for editing purposes.
|
|
9
|
+
*
|
|
9
10
|
* @param {Keyframe} out keyframe to be added at the point of subdivision, its tangents, time and value will be overwritten
|
|
10
|
-
* @param {Keyframe} key0
|
|
11
|
-
* @param {Keyframe} key1
|
|
11
|
+
* @param {Keyframe} key0 start of the segment
|
|
12
|
+
* @param {Keyframe} key1 end of the segment
|
|
12
13
|
* @param {number} t normalized time in [0..1] between key0 and key1 where new frame is to be inserted
|
|
13
14
|
* @returns {Keyframe} `out`, for convenience
|
|
15
|
+
*
|
|
14
16
|
* @see AnimationCurve
|
|
15
17
|
* @example
|
|
16
18
|
* const new_frame = animation_curve_subdivide(new Keyframe(), key0, key1, 0.5);
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* A Transform represents the position, rotation, and scale of an object in 3D space.
|
|
3
3
|
* Think of it like the object's location, orientation, and size.
|
|
4
|
-
* It has properties for position (like coordinates), rotation (how it's
|
|
5
|
-
*
|
|
6
|
-
* It also uses a "matrix" (a table of numbers) internally to efficiently store and calculate transformations, but you usually interact with the position, rotation, and scale directly.
|
|
4
|
+
* It has properties for {@link position} (like coordinates), {@link rotation} (how it's oriented), and {@link scale} (how big it is).
|
|
7
5
|
*
|
|
8
6
|
* @example
|
|
9
7
|
* const t = new Transform();
|
|
@@ -50,8 +48,11 @@ export class Transform {
|
|
|
50
48
|
*/
|
|
51
49
|
readonly scale: Vector3;
|
|
52
50
|
/**
|
|
53
|
-
* transform matrix, position, rotation, and scale must match, but shear can be different
|
|
54
|
-
* Note: this is managed by the Transform itself
|
|
51
|
+
* Affine transform matrix, {@link position}, {@link rotation}, and {@link scale} must match, but shear can be different.
|
|
52
|
+
* Note: this is managed by the {@link Transform} itself unless {@link TransformFlags.AutomaticChangeDetection} is disabled; do not modify the matrix directly.
|
|
53
|
+
* Generally, if you want to modify it - use {@link fromMatrix} method instead.
|
|
54
|
+
*
|
|
55
|
+
* If you're not comfortable with matrices, just leave defaults on and stick to primary attributes i.e. {@link position}, {@link rotation}, and {@link scale}.
|
|
55
56
|
* @readonly
|
|
56
57
|
* @type {Float32Array}
|
|
57
58
|
*/
|
|
@@ -115,7 +116,9 @@ export class Transform {
|
|
|
115
116
|
*/
|
|
116
117
|
getFlag(flag: number | TransformFlags): boolean;
|
|
117
118
|
/**
|
|
118
|
-
* Update {@link matrix} attribute from current position/rotation/scale
|
|
119
|
+
* Update {@link matrix} attribute from current {@link position}/{@link rotation}/{@link scale}
|
|
120
|
+
*
|
|
121
|
+
* Useful for when {@link TransformFlags.AutomaticChangeDetection} is disabled.
|
|
119
122
|
*/
|
|
120
123
|
updateMatrix(): void;
|
|
121
124
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Transform.d.ts","sourceRoot":"","sources":["../../../../../src/engine/ecs/transform/Transform.js"],"names":[],"mappings":"AAsBA
|
|
1
|
+
{"version":3,"file":"Transform.d.ts","sourceRoot":"","sources":["../../../../../src/engine/ecs/transform/Transform.js"],"names":[],"mappings":"AAsBA;;;;;;;;;;;GAWG;AACH;IAsRI;;;;OAIG;IACH,4BAFa,SAAS,CAQrB;IAED;;;;OAIG;IACH,uBAHW,MAAM,EAAE,GAAC,YAAY,GACnB,SAAS,CAQrB;IA0FD;;;;;OAKG;IACH,wCAJW,UAAU,gBACV,OAAO,wBAejB;IAxZD;;;OAGG;IACH,mBAHU,OAAO,CAGe;IAEhC;;;;;OAKG;IACH,mBAHU,UAAU,CAGkB;IAEtC;;;OAGG;IACH,gBAHU,OAAO,CAGY;IAE7B;;;;;;;;OAQG;IACH,iBAFU,YAAY,CAEC;IAEvB;;;;OAIG;IACH,OAFU,MAAM,CAEM;IAStB;;;;OAIG;IACH,uBAMC;IAED;;;OAGG;IACH,kBAMC;IAED;;;OAGG;IACH,qBAMC;IAED;;;;OAIG;IACH,kDAIC;IAED;;;;OAIG;IACH,oDAIC;IAYD;;;;OAIG;IACH,cAHW,MAAM,GAAC,cAAc,GACnB,IAAI,CAIhB;IAED;;;;OAIG;IACH,gBAHW,MAAM,GAAC,cAAc,GACnB,IAAI,CAIhB;IAED;;;;OAIG;IACH,gBAHW,MAAM,GAAC,cAAc,SACrB,OAAO,QAQjB;IAED;;;;OAIG;IACH,cAHW,MAAM,GAAC,cAAc,GACnB,OAAO,CAInB;IAED;;;;OAIG;IACH,qBAEC;IAED;;;;OAIG;IACH,eAHW,OAAO,OACP,OAAO,QAqBjB;IAED,0BAwBC;IAED;;;;;;;;;;;;;;;;;MAMC;IAED;;;;;OAKG;IACH,YAFW,SAAS,QAenB;IAED;;;OAGG;IACH,SAFa,SAAS,CAQrB;IAED;;;;OAIG;IACH,cAHW,SAAS,GACP,OAAO,CAMnB;IAED;;;OAGG;IACH,QAFa,MAAM,CAKlB;IA4BD;;;;;;OAMG;IACH,gBAHW,SAAS,GACP,IAAI,CAIhB;IAED;;;;;OAKG;IACH,sBAJW,SAAS,KACT,SAAS,GACP,IAAI,CAWhB;IAED;;;;OAIG;IACH,mBAHW,OAAK,MAAM,EAAE,GAAC,YAAY,GACxB,IAAI,CAmBhB;IAED;;;;OAIG;IACH,kBAHW,MAAM,EAAE,GAAC,YAAY,GACnB,MAAM,EAAE,CAOpB;IAED;;;;;OAKG;IACH,qBAEC;IAED;;;OAGG;IACH,cAFa,OAAO,CAMnB;IAED,mBAEC;IA6BL;;;;;;;;OAQG;IACH,sBANU,OAAO,CAMc;IAE/B;;;OAGG;IACH,8BA5Ee,MAAM,EAAE,GAAC,YAAY,KACnB,MAAM,EAAE,CA2EI;IAE7B;;;OAGG;IACH,+BA1Ge,OAAK,MAAM,EAAE,GAAC,YAAY,KACxB,IAAI,CAyGU;;CA7B9B;;kBAIS,MAAM;;oBA1bI,+BAA+B;uBAD5B,kCAAkC;+BAE1B,qBAAqB"}
|
|
@@ -23,9 +23,7 @@ const FLAGS_DEFAULT = TransformFlags.AutomaticChangeDetection;
|
|
|
23
23
|
/**
|
|
24
24
|
* A Transform represents the position, rotation, and scale of an object in 3D space.
|
|
25
25
|
* Think of it like the object's location, orientation, and size.
|
|
26
|
-
* It has properties for position (like coordinates), rotation (how it's
|
|
27
|
-
*
|
|
28
|
-
* It also uses a "matrix" (a table of numbers) internally to efficiently store and calculate transformations, but you usually interact with the position, rotation, and scale directly.
|
|
26
|
+
* It has properties for {@link position} (like coordinates), {@link rotation} (how it's oriented), and {@link scale} (how big it is).
|
|
29
27
|
*
|
|
30
28
|
* @example
|
|
31
29
|
* const t = new Transform();
|
|
@@ -57,8 +55,11 @@ export class Transform {
|
|
|
57
55
|
scale = new Vector3(1, 1, 1);
|
|
58
56
|
|
|
59
57
|
/**
|
|
60
|
-
* transform matrix, position, rotation, and scale must match, but shear can be different
|
|
61
|
-
* Note: this is managed by the Transform itself
|
|
58
|
+
* Affine transform matrix, {@link position}, {@link rotation}, and {@link scale} must match, but shear can be different.
|
|
59
|
+
* Note: this is managed by the {@link Transform} itself unless {@link TransformFlags.AutomaticChangeDetection} is disabled; do not modify the matrix directly.
|
|
60
|
+
* Generally, if you want to modify it - use {@link fromMatrix} method instead.
|
|
61
|
+
*
|
|
62
|
+
* If you're not comfortable with matrices, just leave defaults on and stick to primary attributes i.e. {@link position}, {@link rotation}, and {@link scale}.
|
|
62
63
|
* @readonly
|
|
63
64
|
* @type {Float32Array}
|
|
64
65
|
*/
|
|
@@ -72,7 +73,9 @@ export class Transform {
|
|
|
72
73
|
flags = FLAGS_DEFAULT;
|
|
73
74
|
|
|
74
75
|
constructor() {
|
|
75
|
-
//
|
|
76
|
+
// Watch changes.
|
|
77
|
+
// This creates a data dependency, which makes GC impossible if we keep references to position/rotation/scale
|
|
78
|
+
// Please clone those properties if you need to keep them past the expiry of the Transform
|
|
76
79
|
this.subscribe(this.#handle_component_change, this);
|
|
77
80
|
}
|
|
78
81
|
|
|
@@ -186,7 +189,9 @@ export class Transform {
|
|
|
186
189
|
}
|
|
187
190
|
|
|
188
191
|
/**
|
|
189
|
-
* Update {@link matrix} attribute from current position/rotation/scale
|
|
192
|
+
* Update {@link matrix} attribute from current {@link position}/{@link rotation}/{@link scale}
|
|
193
|
+
*
|
|
194
|
+
* Useful for when {@link TransformFlags.AutomaticChangeDetection} is disabled.
|
|
190
195
|
*/
|
|
191
196
|
updateMatrix() {
|
|
192
197
|
compose_matrix4_array(this.matrix, this.position, this.rotation, this.scale);
|
|
@@ -206,7 +211,9 @@ export class Transform {
|
|
|
206
211
|
const delta_z = target.z - position.z;
|
|
207
212
|
|
|
208
213
|
if (delta_x === 0 && delta_y === 0 && delta_z === 0) {
|
|
209
|
-
//
|
|
214
|
+
// Target is at the same location as this transform, no valid rotation, keep whatever we have.
|
|
215
|
+
// Generally this is a programmer mistake, making any changes to the rotation would be undesirable.
|
|
216
|
+
// The most valid option is to keep the current state.
|
|
210
217
|
return;
|
|
211
218
|
}
|
|
212
219
|
|
|
@@ -11,7 +11,7 @@ const q = new Quaternion();
|
|
|
11
11
|
* @param {Vector3} result
|
|
12
12
|
*/
|
|
13
13
|
export function computeCameraFacingVector(yaw, pitch, roll, result) {
|
|
14
|
-
q.
|
|
14
|
+
q.fromEulerAnglesZYX(pitch, yaw, roll);
|
|
15
15
|
q.normalize();
|
|
16
16
|
|
|
17
17
|
result.copy(Vector3.forward);
|
|
@@ -74,7 +74,7 @@ export function computeTopDownTransform(control, result) {
|
|
|
74
74
|
const roll = control.roll;
|
|
75
75
|
|
|
76
76
|
// compute rotation
|
|
77
|
-
rotation.
|
|
77
|
+
rotation.fromEulerAnglesZYX(pitch, yaw, roll);
|
|
78
78
|
|
|
79
79
|
// compute camera position
|
|
80
80
|
v3_scratch.copy(Vector3.forward);
|
|
@@ -62,7 +62,7 @@ function make_grid(ecd, engine) {
|
|
|
62
62
|
for (let j = 0; j < GRID_SIZE; j++) {
|
|
63
63
|
const quaternion = new Quaternion();
|
|
64
64
|
|
|
65
|
-
quaternion.
|
|
65
|
+
quaternion.fromEulerAnglesXYZ(0, random() * Math.PI, 0);
|
|
66
66
|
|
|
67
67
|
const center = new Vector3(i * 8, 0, j * 8);
|
|
68
68
|
|
|
@@ -1083,7 +1083,7 @@ function makeKnot(engine, position, scale, rotation) {
|
|
|
1083
1083
|
}
|
|
1084
1084
|
});
|
|
1085
1085
|
|
|
1086
|
-
transform.rotation.
|
|
1086
|
+
transform.rotation.fromEulerAnglesXYZ(position[0], position[1], position[2]);
|
|
1087
1087
|
|
|
1088
1088
|
transform.scale.multiplyScalar(scale);
|
|
1089
1089
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MarkerNodeTransformerYRotateByFilter.d.ts","sourceRoot":"","sources":["../../../../../src/generation/markers/transform/MarkerNodeTransformerYRotateByFilter.js"],"names":[],"mappings":"AAQA;IAqBI;;;;OAIG;IACH,yCAFW,MAAM,wCAahB;IAnCD;;;OAGG;IACH,mBAAc;IAEd;;;OAGG;IACH,QAFU,MAAM,CAEL;IAEX,uCAIC;IAqBD,qCAmBC;CACJ;
|
|
1
|
+
{"version":3,"file":"MarkerNodeTransformerYRotateByFilter.d.ts","sourceRoot":"","sources":["../../../../../src/generation/markers/transform/MarkerNodeTransformerYRotateByFilter.js"],"names":[],"mappings":"AAQA;IAqBI;;;;OAIG;IACH,yCAFW,MAAM,wCAahB;IAnCD;;;OAGG;IACH,mBAAc;IAEd;;;OAGG;IACH,QAFU,MAAM,CAEL;IAEX,uCAIC;IAqBD,qCAmBC;CACJ;sCA/DqC,4BAA4B"}
|