@woosh/meep-engine 2.92.9 → 2.92.11
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/build/meep.cjs +7 -13
- package/build/meep.min.js +1 -1
- package/build/meep.module.js +7 -13
- package/package.json +1 -1
- package/src/core/bvh2/binary/2/BinaryUint32BVH.d.ts.map +1 -1
- package/src/core/bvh2/binary/2/BinaryUint32BVH.js +4 -0
- package/src/core/math/interval/NumericInterval.d.ts +3 -3
- package/src/core/math/interval/NumericInterval.d.ts.map +1 -1
- package/src/core/math/interval/NumericInterval.js +7 -13
- package/src/core/math/interval/NumericInterval.spec.js +9 -0
- package/src/core/math/max3.spec.js +2 -0
- package/src/core/math/min3.spec.js +2 -0
- package/src/core/math/spline/spline_bezier3_bounds.js +3 -3
- package/src/core/math/spline/spline_hermite3.d.ts +11 -0
- package/src/core/math/spline/spline_hermite3.d.ts.map +1 -0
- package/src/core/math/spline/spline_hermite3.js +21 -0
- package/src/core/math/spline/spline_hermite3_bounds.d.ts +17 -0
- package/src/core/math/spline/spline_hermite3_bounds.d.ts.map +1 -0
- package/src/core/math/spline/spline_hermite3_bounds.js +95 -0
- package/src/core/math/spline/spline_hermite3_bounds.spec.d.ts +2 -0
- package/src/core/math/spline/spline_hermite3_bounds.spec.d.ts.map +1 -0
- package/src/core/math/spline/spline_hermite3_bounds.spec.js +37 -0
- package/src/engine/animation/curve/AnimationCurve.d.ts.map +1 -1
- package/src/engine/animation/curve/AnimationCurve.js +10 -16
- package/src/engine/animation/curve/AnimationCurve.spec.js +11 -0
- package/src/engine/animation/curve/compression/prototypeCurveCompression.js +13 -2
- package/src/engine/animation/curve/compute_curve_aabb.d.ts.map +1 -1
- package/src/engine/animation/curve/compute_curve_aabb.js +25 -4
- package/src/engine/animation/curve/draw/build_plot_entity_from_array.d.ts.map +1 -1
- package/src/engine/animation/curve/draw/build_plot_entity_from_array.js +10 -2
- package/src/engine/animation/curve/prototypeGLTF.js +14 -14
- package/src/engine/graphics/canvas/canvas2d_draw_label.d.ts +4 -1
- package/src/engine/graphics/canvas/canvas2d_draw_label.d.ts.map +1 -1
- package/src/engine/graphics/canvas/canvas2d_draw_label.js +10 -4
- package/src/engine/graphics/geometry/buffered/query/GeometrySpatialQueryAccelerator.js +2 -2
package/build/meep.module.js
CHANGED
|
@@ -54355,13 +54355,6 @@ function inverseLerp(a, b, value) {
|
|
|
54355
54355
|
return scaledValue / range;
|
|
54356
54356
|
}
|
|
54357
54357
|
|
|
54358
|
-
/**
|
|
54359
|
-
*
|
|
54360
|
-
* @param {number} min
|
|
54361
|
-
* @param {number} max
|
|
54362
|
-
* @constructor
|
|
54363
|
-
*/
|
|
54364
|
-
|
|
54365
54358
|
class NumericInterval {
|
|
54366
54359
|
/**
|
|
54367
54360
|
*
|
|
@@ -54435,9 +54428,9 @@ class NumericInterval {
|
|
|
54435
54428
|
}
|
|
54436
54429
|
|
|
54437
54430
|
/**
|
|
54438
|
-
*
|
|
54439
|
-
* @param {number} v
|
|
54440
|
-
* @returns {number}
|
|
54431
|
+
* Compute normalized position of input within this interval, where result is 0 if input is equal to `min`, and 1 when input is equal to `max`
|
|
54432
|
+
* @param {number} v value to be normalized
|
|
54433
|
+
* @returns {number} value between 0..1 if input is within [min,max] range, otherwise result will be extrapolated proportionately outside the 0,1 region
|
|
54441
54434
|
*/
|
|
54442
54435
|
normalizeValue(v) {
|
|
54443
54436
|
return inverseLerp(this.min, this.max, v);
|
|
@@ -54465,7 +54458,7 @@ class NumericInterval {
|
|
|
54465
54458
|
* @returns {number}
|
|
54466
54459
|
*/
|
|
54467
54460
|
computeAverage() {
|
|
54468
|
-
return (this.min + this.max)
|
|
54461
|
+
return (this.min + this.max) * 0.5;
|
|
54469
54462
|
}
|
|
54470
54463
|
|
|
54471
54464
|
/**
|
|
@@ -55268,6 +55261,7 @@ class BinaryUint32BVH {
|
|
|
55268
55261
|
* @param {number} count
|
|
55269
55262
|
*/
|
|
55270
55263
|
setLeafCount(count) {
|
|
55264
|
+
|
|
55271
55265
|
this.__node_count_leaf = count;
|
|
55272
55266
|
|
|
55273
55267
|
const twoLeafLimit = ceilPowerOfTwo(count);
|
|
@@ -66306,14 +66300,14 @@ class GeometrySpatialQueryAccelerator {
|
|
|
66306
66300
|
* @returns {BinaryUint32BVH}
|
|
66307
66301
|
*/
|
|
66308
66302
|
__buildBVH(geometry) {
|
|
66303
|
+
const bvh = new BinaryUint32BVH();
|
|
66304
|
+
|
|
66309
66305
|
const position_attribute = geometry.getAttribute('position');
|
|
66310
66306
|
const index_attribute = geometry.getIndex();
|
|
66311
66307
|
|
|
66312
66308
|
const de_interleaved_position_attribute = deinterleaveBufferAttribute(position_attribute);
|
|
66313
66309
|
const vertices = de_interleaved_position_attribute.array;
|
|
66314
66310
|
|
|
66315
|
-
const bvh = new BinaryUint32BVH();
|
|
66316
|
-
|
|
66317
66311
|
if (index_attribute === undefined || index_attribute === null) {
|
|
66318
66312
|
bvh32_from_unindexed_geometry(bvh, vertices);
|
|
66319
66313
|
} else {
|
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BinaryUint32BVH.d.ts","sourceRoot":"","sources":["../../../../../../src/core/bvh2/binary/2/BinaryUint32BVH.js"],"names":[],"mappings":"AAcA;;;GAGG;AACH,gCAFU,MAAM,CAEmB;AAEnC;;;;GAIG;AACH,mCAFU,MAAM,CAEsB;AACtC;;;GAGG;AACH,iCAFU,MAAM,CAEoB;AAiDpC;IACI;;;;OAIG;IACH,sBAAc;IAEd;;;;OAIG;IACH,gCAAe;IAEf;;;;OAIG;IACH,+BAAc;IAEd;;;;OAIG;IACH,4BAAwB;IAExB;;;;OAIG;IACH,0BAAsB;IA0CtB;;;OAGG;IACH,2BAOC;IAED,wBAEC;IAnDD;;;OAGG;IACH,oBAFa,MAAM,CAIlB;IAED,2BAEC;IAED,gCAEC;IAED,8BAEC;IAED;;;OAGG;IACH,uBAFa,MAAM,CAIlB;IAED,4BAEC;IAED,0BAEC;IAmBD;;;;OAIG;IACH,2BAHW,MAAM,GACJ,MAAM,CAalB;IAED,6BASC;IAED;;;OAGG;IACH,oBAFW,MAAM,
|
|
1
|
+
{"version":3,"file":"BinaryUint32BVH.d.ts","sourceRoot":"","sources":["../../../../../../src/core/bvh2/binary/2/BinaryUint32BVH.js"],"names":[],"mappings":"AAcA;;;GAGG;AACH,gCAFU,MAAM,CAEmB;AAEnC;;;;GAIG;AACH,mCAFU,MAAM,CAEsB;AACtC;;;GAGG;AACH,iCAFU,MAAM,CAEoB;AAiDpC;IACI;;;;OAIG;IACH,sBAAc;IAEd;;;;OAIG;IACH,gCAAe;IAEf;;;;OAIG;IACH,+BAAc;IAEd;;;;OAIG;IACH,4BAAwB;IAExB;;;;OAIG;IACH,0BAAsB;IA0CtB;;;OAGG;IACH,2BAOC;IAED,wBAEC;IAnDD;;;OAGG;IACH,oBAFa,MAAM,CAIlB;IAED,2BAEC;IAED,gCAEC;IAED,8BAEC;IAED;;;OAGG;IACH,uBAFa,MAAM,CAIlB;IAED,4BAEC;IAED,0BAEC;IAmBD;;;;OAIG;IACH,2BAHW,MAAM,GACJ,MAAM,CAalB;IAED,6BASC;IAED;;;OAGG;IACH,oBAFW,MAAM,QAgBhB;IAED;;;;;;;;;;OAUG;IACH,mBATW,MAAM,WACN,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,QA0BhB;IAED;;;;;OAKG;IACH,oBAJW,MAAM,eACN,MAAM,EAAE,GAAC,YAAY,sBACrB,MAAM,QAIhB;IAED;;;;OAIG;IACH,4BAHW,MAAM,GACJ,MAAM,CAQlB;IAED,qCAoBC;IAED;;;;;;;OAOG;IACH,yCAYC;IAED;;;;;;OAMG;IACH,kDAuBC;IAED,wBAUC;IAGD;;;OAGG;IACH,oBAFW,MAAM,EAAE,QAkElB;IAED;;;;;OAKG;IACH,sBAUC;IAED;;OAEG;IACH,cAsEC;CACJ"}
|
|
@@ -204,6 +204,8 @@ export class BinaryUint32BVH {
|
|
|
204
204
|
* @param {number} count
|
|
205
205
|
*/
|
|
206
206
|
setLeafCount(count) {
|
|
207
|
+
assert.isNonNegativeInteger(count, 'count');
|
|
208
|
+
|
|
207
209
|
this.__node_count_leaf = count;
|
|
208
210
|
|
|
209
211
|
const twoLeafLimit = ceilPowerOfTwo(count);
|
|
@@ -240,6 +242,8 @@ export class BinaryUint32BVH {
|
|
|
240
242
|
assert.notNaN(y1, 'y1');
|
|
241
243
|
assert.notNaN(z1, 'z1');
|
|
242
244
|
|
|
245
|
+
assert.isNonNegativeInteger(payload, 'payload');
|
|
246
|
+
|
|
243
247
|
const address = index * BVH_LEAF_NODE_SIZE + this.__node_count_binary * BVH_BINARY_NODE_SIZE;
|
|
244
248
|
|
|
245
249
|
aabb3_array_set(
|
|
@@ -34,9 +34,9 @@ export class NumericInterval {
|
|
|
34
34
|
*/
|
|
35
35
|
multiplyScalar(value: number): void;
|
|
36
36
|
/**
|
|
37
|
-
*
|
|
38
|
-
* @param {number} v
|
|
39
|
-
* @returns {number}
|
|
37
|
+
* Compute normalized position of input within this interval, where result is 0 if input is equal to `min`, and 1 when input is equal to `max`
|
|
38
|
+
* @param {number} v value to be normalized
|
|
39
|
+
* @returns {number} value between 0..1 if input is within [min,max] range, otherwise result will be extrapolated proportionately outside the 0,1 region
|
|
40
40
|
*/
|
|
41
41
|
normalizeValue(v: number): number;
|
|
42
42
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NumericInterval.d.ts","sourceRoot":"","sources":["../../../../../src/core/math/interval/NumericInterval.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"NumericInterval.d.ts","sourceRoot":"","sources":["../../../../../src/core/math/interval/NumericInterval.js"],"names":[],"mappings":"AAKA;IACI;;;;;OAKG;IACH,kBAJW,MAAM,QACN,MAAM,EAwBhB;IAZG;;;OAGG;IACH,KAFU,MAAM,CAEF;IACd;;;OAGG;IACH,KAFU,MAAM,CAEF;IAEd,0DAA6B;IAIjC;;;;OAIG;IACH,SAHW,MAAM,OACN,MAAM,QAsBhB;IAED;;;OAGG;IACH,YAFW,eAAe,QAIzB;IAED;;;OAGG;IACH,sBAFW,MAAM,QAahB;IAED;;;;OAIG;IACH,kBAHW,MAAM,GACJ,MAAM,CAIlB;IAED;;;OAGG;IACH,UAFa,OAAO,CAInB;IAED;;;;OAIG;IACH,WAFa,OAAO,CAInB;IAED;;;OAGG;IACH,kBAFa,MAAM,CAIlB;IAED;;;;OAIG;IACH,gCAFa,MAAM,CAMlB;IAED,0BAEC;IAED;;;MAKC;IAED;;;OAGG;IACH,2CAGC;IAED;;;OAGG;IACH,6CAGC;IAED;;;;OAIG;IACH,cAHW,eAAe,GACb,OAAO,CAInB;IAED;;;OAGG;IACH,QAFa,MAAM,CAQlB;IAED;;;OAGG;IACH,mBAEC;IAGL;;;OAGG;IACH,4BAFU,OAAO,CAE0B;CAN1C;;iBAUS,eAAe;mBAKf,eAAe;;mBA5MN,+BAA+B"}
|
|
@@ -1,13 +1,7 @@
|
|
|
1
|
-
/**
|
|
2
|
-
*
|
|
3
|
-
* @param {number} min
|
|
4
|
-
* @param {number} max
|
|
5
|
-
* @constructor
|
|
6
|
-
*/
|
|
7
1
|
import { assert } from "../../assert.js";
|
|
8
2
|
import Signal from "../../events/signal/Signal.js";
|
|
9
|
-
import { inverseLerp } from "../inverseLerp.js";
|
|
10
3
|
import { computeHashFloat } from "../../primitives/numbers/computeHashFloat.js";
|
|
4
|
+
import { inverseLerp } from "../inverseLerp.js";
|
|
11
5
|
|
|
12
6
|
export class NumericInterval {
|
|
13
7
|
/**
|
|
@@ -23,7 +17,7 @@ export class NumericInterval {
|
|
|
23
17
|
assert.isNumber(min, 'min');
|
|
24
18
|
assert.isNumber(max, 'max');
|
|
25
19
|
|
|
26
|
-
assert.
|
|
20
|
+
assert.greaterThanOrEqual(max, min, `max [${max}] must be >= than min[${min}]`);
|
|
27
21
|
|
|
28
22
|
/**
|
|
29
23
|
*
|
|
@@ -93,9 +87,9 @@ export class NumericInterval {
|
|
|
93
87
|
}
|
|
94
88
|
|
|
95
89
|
/**
|
|
96
|
-
*
|
|
97
|
-
* @param {number} v
|
|
98
|
-
* @returns {number}
|
|
90
|
+
* Compute normalized position of input within this interval, where result is 0 if input is equal to `min`, and 1 when input is equal to `max`
|
|
91
|
+
* @param {number} v value to be normalized
|
|
92
|
+
* @returns {number} value between 0..1 if input is within [min,max] range, otherwise result will be extrapolated proportionately outside the 0,1 region
|
|
99
93
|
*/
|
|
100
94
|
normalizeValue(v) {
|
|
101
95
|
return inverseLerp(this.min, this.max, v);
|
|
@@ -123,7 +117,7 @@ export class NumericInterval {
|
|
|
123
117
|
* @returns {number}
|
|
124
118
|
*/
|
|
125
119
|
computeAverage() {
|
|
126
|
-
return (this.min + this.max)
|
|
120
|
+
return (this.min + this.max) * 0.5;
|
|
127
121
|
}
|
|
128
122
|
|
|
129
123
|
/**
|
|
@@ -132,7 +126,7 @@ export class NumericInterval {
|
|
|
132
126
|
* @returns {number}
|
|
133
127
|
*/
|
|
134
128
|
sampleRandom(random) {
|
|
135
|
-
assert.
|
|
129
|
+
assert.isFunction(random, "random");
|
|
136
130
|
|
|
137
131
|
return this.min + random() * (this.max - this.min);
|
|
138
132
|
}
|
|
@@ -78,3 +78,12 @@ test("sampleRandom", () => {
|
|
|
78
78
|
expect(sut.sampleRandom(() => 1)).toBe(7);
|
|
79
79
|
expect(sut.sampleRandom(() => 0.5)).toBeCloseTo(2);
|
|
80
80
|
});
|
|
81
|
+
|
|
82
|
+
test("computeAverage", () => {
|
|
83
|
+
expect(new NumericInterval(0, 0).computeAverage()).toBe(0);
|
|
84
|
+
expect(new NumericInterval(1, 1).computeAverage()).toBe(1);
|
|
85
|
+
expect(new NumericInterval(-1, -1).computeAverage()).toBe(-1);
|
|
86
|
+
|
|
87
|
+
expect(new NumericInterval(3, 7).computeAverage()).toBe(5);
|
|
88
|
+
expect(new NumericInterval(3.1, 7.1).computeAverage()).toBe(5.1);
|
|
89
|
+
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { min2 } from "../min2.js";
|
|
2
|
-
import { max2 } from "../max2.js";
|
|
3
1
|
import { assert } from "../../assert.js";
|
|
4
|
-
import {
|
|
2
|
+
import { max2 } from "../max2.js";
|
|
3
|
+
import { min2 } from "../min2.js";
|
|
4
|
+
import { spline_bezier3 } from './spline_bezier3.js'
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Compute bounds of a 3-rd degree bezier curve
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Perform cubic hermite interpolation
|
|
3
|
+
* @param {number} t normalized interpolation position (0..1)
|
|
4
|
+
* @param {number} p0 first value
|
|
5
|
+
* @param {number} p1 second value
|
|
6
|
+
* @param {number} m0 first tangent
|
|
7
|
+
* @param {number} m1 second tangent
|
|
8
|
+
* @return {number}
|
|
9
|
+
*/
|
|
10
|
+
export function spline_hermite3(t: number, p0: number, p1: number, m0: number, m1: number): number;
|
|
11
|
+
//# sourceMappingURL=spline_hermite3.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spline_hermite3.d.ts","sourceRoot":"","sources":["../../../../../src/core/math/spline/spline_hermite3.js"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,mCAPW,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,GACL,MAAM,CAajB"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Perform cubic hermite interpolation
|
|
3
|
+
* @param {number} t normalized interpolation position (0..1)
|
|
4
|
+
* @param {number} p0 first value
|
|
5
|
+
* @param {number} p1 second value
|
|
6
|
+
* @param {number} m0 first tangent
|
|
7
|
+
* @param {number} m1 second tangent
|
|
8
|
+
* @return {number}
|
|
9
|
+
*/
|
|
10
|
+
export function spline_hermite3(t, p0, p1, m0, m1) {
|
|
11
|
+
|
|
12
|
+
const t2 = t * t;
|
|
13
|
+
const t3 = t2 * t;
|
|
14
|
+
|
|
15
|
+
const a = 2 * t3 - 3 * t2 + 1;
|
|
16
|
+
const b = t3 - 2 * t2 + t;
|
|
17
|
+
const c = t3 - t2;
|
|
18
|
+
const d = -2 * t3 + 3 * t2;
|
|
19
|
+
|
|
20
|
+
return a * p0 + b * m0 + c * m1 + d * p1;
|
|
21
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compute bounds of a 3-rd degree hermite curve
|
|
3
|
+
* Note that this is a 1d case solver
|
|
4
|
+
* Lower bound will be written into result[offset], upper bounds will be written into result[offset+result_stride]
|
|
5
|
+
* Solution is based on https://stackoverflow.com/questions/24809978/calculating-the-bounding-box-of-cubic-bezier-curve
|
|
6
|
+
* Differentiation of hermite polynomial is done in WolframAlpha
|
|
7
|
+
* 0 = 3 t^2 (m0 + m1 + 2 p0 - 2 p1) - 2 t (2 m0 + m1 + 3 p0 - 3 p1) + m0
|
|
8
|
+
* @param {number[]|Float32Array} result
|
|
9
|
+
* @param {number} result_offset offset into the result array
|
|
10
|
+
* @param {number} result_stride
|
|
11
|
+
* @param {number} p0
|
|
12
|
+
* @param {number} p1
|
|
13
|
+
* @param {number} m0
|
|
14
|
+
* @param {number} m1
|
|
15
|
+
*/
|
|
16
|
+
export function spline_hermite3_bounds(result: number[] | Float32Array, result_offset: number, result_stride: number, p0: number, p1: number, m0: number, m1: number): void;
|
|
17
|
+
//# sourceMappingURL=spline_hermite3_bounds.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spline_hermite3_bounds.d.ts","sourceRoot":"","sources":["../../../../../src/core/math/spline/spline_hermite3_bounds.js"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;GAcG;AACH,+CARW,MAAM,EAAE,GAAC,YAAY,iBACrB,MAAM,iBACN,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,QA4EhB"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { assert } from "../../assert.js";
|
|
2
|
+
import { max2 } from "../max2.js";
|
|
3
|
+
import { min2 } from "../min2.js";
|
|
4
|
+
import { spline_hermite3 } from "./spline_hermite3.js";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Compute bounds of a 3-rd degree hermite curve
|
|
8
|
+
* Note that this is a 1d case solver
|
|
9
|
+
* Lower bound will be written into result[offset], upper bounds will be written into result[offset+result_stride]
|
|
10
|
+
* Solution is based on https://stackoverflow.com/questions/24809978/calculating-the-bounding-box-of-cubic-bezier-curve
|
|
11
|
+
* Differentiation of hermite polynomial is done in WolframAlpha
|
|
12
|
+
* 0 = 3 t^2 (m0 + m1 + 2 p0 - 2 p1) - 2 t (2 m0 + m1 + 3 p0 - 3 p1) + m0
|
|
13
|
+
* @param {number[]|Float32Array} result
|
|
14
|
+
* @param {number} result_offset offset into the result array
|
|
15
|
+
* @param {number} result_stride
|
|
16
|
+
* @param {number} p0
|
|
17
|
+
* @param {number} p1
|
|
18
|
+
* @param {number} m0
|
|
19
|
+
* @param {number} m1
|
|
20
|
+
*/
|
|
21
|
+
export function spline_hermite3_bounds(
|
|
22
|
+
result,
|
|
23
|
+
result_offset,
|
|
24
|
+
result_stride,
|
|
25
|
+
p0, p1, m0, m1) {
|
|
26
|
+
|
|
27
|
+
assert.greaterThan(result_stride, 0, 'result_stride must be greater than 0');
|
|
28
|
+
assert.isInteger(result_stride, 'result_stride');
|
|
29
|
+
|
|
30
|
+
const a = 3 * (m0 + m1 + 2 * p0 - 2 * p1);
|
|
31
|
+
const b = -2 * (2 * m0 + m1 + 3 * p0 - 3 * p1);
|
|
32
|
+
const c = m0;
|
|
33
|
+
|
|
34
|
+
let min = min2(p0, p1);
|
|
35
|
+
let max = max2(p0, p1);
|
|
36
|
+
|
|
37
|
+
if (Math.abs(a) < 1e-12) {
|
|
38
|
+
|
|
39
|
+
if (Math.abs(b) >= 1e-12) {
|
|
40
|
+
const t = -c / b;
|
|
41
|
+
|
|
42
|
+
if (0 < t && t < 1) {
|
|
43
|
+
const value = spline_hermite3(t, p0, p1, m0, m1);
|
|
44
|
+
|
|
45
|
+
if (value < min) {
|
|
46
|
+
min = value;
|
|
47
|
+
}
|
|
48
|
+
if (value > max) {
|
|
49
|
+
max = value;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
} else {
|
|
57
|
+
|
|
58
|
+
const b2ac = b * b - 4 * c * a;
|
|
59
|
+
const sqrtb2ac = Math.sqrt(b2ac);
|
|
60
|
+
|
|
61
|
+
if (b2ac >= 0) {
|
|
62
|
+
|
|
63
|
+
const t1 = (-b + sqrtb2ac) / (2 * a);
|
|
64
|
+
|
|
65
|
+
if (0 < t1 && t1 < 1) {
|
|
66
|
+
const value = spline_hermite3(t1, p0, p1, m0, m1);
|
|
67
|
+
|
|
68
|
+
if (value < min) {
|
|
69
|
+
min = value;
|
|
70
|
+
}
|
|
71
|
+
if (value > max) {
|
|
72
|
+
max = value;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const t2 = (-b - sqrtb2ac) / (2 * a);
|
|
77
|
+
|
|
78
|
+
if (0 < t2 && t2 < 1) {
|
|
79
|
+
const value = spline_hermite3(t2, p0, p1, m0, m1);
|
|
80
|
+
|
|
81
|
+
if (value < min) {
|
|
82
|
+
min = value;
|
|
83
|
+
}
|
|
84
|
+
if (value > max) {
|
|
85
|
+
max = value;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
result[result_offset] = min;
|
|
94
|
+
result[result_offset + result_stride] = max;
|
|
95
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spline_hermite3_bounds.spec.d.ts","sourceRoot":"","sources":["../../../../../src/core/math/spline/spline_hermite3_bounds.spec.js"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { spline_hermite3_bounds } from "./spline_hermite3_bounds.js";
|
|
2
|
+
|
|
3
|
+
test("spline of 0 length", () => {
|
|
4
|
+
const bounds = [];
|
|
5
|
+
|
|
6
|
+
spline_hermite3_bounds(
|
|
7
|
+
bounds, 0, 1,
|
|
8
|
+
0, 0, 0, 0
|
|
9
|
+
);
|
|
10
|
+
|
|
11
|
+
expect(bounds[0]).toBeCloseTo(0);
|
|
12
|
+
expect(bounds[1]).toBeCloseTo(0);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
test("0-slope line", () => {
|
|
16
|
+
const bounds = [];
|
|
17
|
+
|
|
18
|
+
spline_hermite3_bounds(
|
|
19
|
+
bounds, 0, 1,
|
|
20
|
+
-2, 2, 0, 0
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
expect(bounds[0]).toBeCloseTo(-2);
|
|
24
|
+
expect(bounds[1]).toBeCloseTo(2);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
test("overshooting control points", () => {
|
|
28
|
+
const bounds = [];
|
|
29
|
+
|
|
30
|
+
spline_hermite3_bounds(
|
|
31
|
+
bounds, 0, 1,
|
|
32
|
+
0, 1, 100, 100
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
expect(bounds[0]).toBeLessThan(0);
|
|
36
|
+
expect(bounds[1]).toBeGreaterThan(1);
|
|
37
|
+
});
|
|
@@ -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":"AAmCA;;;GAGG;AACH;IA4EI;;;;OAIG;IACH,kBAHW,QAAQ,EAAE,GACR,cAAc,CAU1B;IAxFD;;;OAGG;IACH,eAFU,QAAQ,EAAE,CAEV;IAEV;;;;OAIG;IACH,SAHW,QAAQ,GACN,MAAM,CA4BlB;IAED;;;OAGG;IACH,cAFW,QAAQ,EAAE,QAQpB;IAED;;;;OAIG;IACH,YAHW,QAAQ,GACN,OAAO,CAYnB;IAED;;OAEG;IACH,cAEC;IAiBD;;;OAGG;IACH,qBAEC;IAGD;;;;OAIG;IACH,YAHW,MAAM,GACL,MAAM,CA+BjB;IAED;;;OAGG;IACH,qBAFW,MAAM,QAoBhB;IAED;;;;OAIG;IACH,sBAHW,MAAM,UACN,MAAM,QAWhB;IAED,0BAKC;IAED;;MAIC;IAED;;aAeC;CACJ;yBA/OwB,eAAe"}
|
|
@@ -1,32 +1,26 @@
|
|
|
1
1
|
import { binarySearchHighIndex } from "../../../core/collection/array/binarySearchHighIndex.js";
|
|
2
2
|
import { inverseLerp } from "../../../core/math/inverseLerp.js";
|
|
3
3
|
import { lerp } from "../../../core/math/lerp.js";
|
|
4
|
+
import { spline_hermite3 } from "../../../core/math/spline/spline_hermite3.js";
|
|
4
5
|
import { invokeObjectToJSON } from "../../../core/model/object/invokeObjectToJSON.js";
|
|
5
6
|
import { Keyframe } from "./Keyframe.js";
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
*
|
|
9
|
-
* @param {number} t
|
|
10
|
+
* @param {number} t interpolation value, between 0 and 1
|
|
10
11
|
* @param {Keyframe} keyframe0
|
|
11
12
|
* @param {Keyframe} keyframe1
|
|
12
13
|
* @return {number}
|
|
13
14
|
*/
|
|
14
15
|
function evaluate(t, keyframe0, keyframe1) {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
const a = 2 * t3 - 3 * t2 + 1;
|
|
25
|
-
const b = t3 - 2 * t2 + t;
|
|
26
|
-
const c = t3 - t2;
|
|
27
|
-
const d = -2 * t3 + 3 * t2;
|
|
28
|
-
|
|
29
|
-
return a * keyframe0.value + b * m0 + c * m1 + d * keyframe1.value;
|
|
16
|
+
const time_distance = keyframe1.time - keyframe0.time;
|
|
17
|
+
|
|
18
|
+
return spline_hermite3(
|
|
19
|
+
t,
|
|
20
|
+
keyframe0.value, keyframe1.value,
|
|
21
|
+
keyframe0.outTangent * time_distance,
|
|
22
|
+
keyframe1.inTangent * time_distance
|
|
23
|
+
);
|
|
30
24
|
}
|
|
31
25
|
|
|
32
26
|
/**
|
|
@@ -113,6 +113,17 @@ test("smooth tangents on a middle frame", () => {
|
|
|
113
113
|
expect(key.inTangent).toEqual(key.outTangent);
|
|
114
114
|
});
|
|
115
115
|
|
|
116
|
+
test("extreme tangent interpolation", () => {
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
const curve = new AnimationCurve();
|
|
120
|
+
|
|
121
|
+
curve.add(Keyframe.from(0, 1, 0, -1));
|
|
122
|
+
curve.add(Keyframe.from(1, 2, 1, 0));
|
|
123
|
+
|
|
124
|
+
expect(curve.evaluate(0.5)).toBe(0.5);
|
|
125
|
+
|
|
126
|
+
});
|
|
116
127
|
|
|
117
128
|
test("to/from JSON consistency", () => {
|
|
118
129
|
|
|
@@ -9,7 +9,7 @@ import { AnimationCurve } from "../AnimationCurve.js";
|
|
|
9
9
|
import { build_curve_editor } from "../draw/build_curve_editor.js";
|
|
10
10
|
import { build_plot_entity_from_array } from "../draw/build_plot_entity_from_array.js";
|
|
11
11
|
import { Keyframe } from "../Keyframe.js";
|
|
12
|
-
import {
|
|
12
|
+
import { CURVE_EASE_IN_OUT } from "../preset/CURVE_EASE_IN_OUT.js";
|
|
13
13
|
import { downsample_float_array_curve_by_error } from "./downsample_float_array_curve_by_error.js";
|
|
14
14
|
import { sample_animation_curve_to_float_array } from "./sample_animation_curve_to_float_array.js";
|
|
15
15
|
|
|
@@ -139,11 +139,22 @@ async function main(engine) {
|
|
|
139
139
|
return curve;
|
|
140
140
|
}
|
|
141
141
|
|
|
142
|
+
function sample_curve_5() {
|
|
143
|
+
|
|
144
|
+
const curve = new AnimationCurve();
|
|
145
|
+
|
|
146
|
+
curve.add(Keyframe.from(0, 1, 0, -1));
|
|
147
|
+
curve.add(Keyframe.from(10, 1, 1, 0));
|
|
148
|
+
|
|
149
|
+
return curve;
|
|
150
|
+
}
|
|
151
|
+
|
|
142
152
|
// const curve = sample_curve_0();
|
|
143
153
|
|
|
144
154
|
// curve.smoothAllTangents();
|
|
145
155
|
|
|
146
|
-
const curve =
|
|
156
|
+
// const curve = sample_curve_5();
|
|
157
|
+
const curve = CURVE_EASE_IN_OUT;
|
|
147
158
|
|
|
148
159
|
const ecd = engine.entityManager.dataset;
|
|
149
160
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compute_curve_aabb.d.ts","sourceRoot":"","sources":["../../../../../src/engine/animation/curve/compute_curve_aabb.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"compute_curve_aabb.d.ts","sourceRoot":"","sources":["../../../../../src/engine/animation/curve/compute_curve_aabb.js"],"names":[],"mappings":"AAMA;;;;GAIG;AACH,4EAmCC"}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { max2 } from "../../../core/math/max2.js";
|
|
2
2
|
import { min2 } from "../../../core/math/min2.js";
|
|
3
|
+
import { spline_hermite3_bounds } from "../../../core/math/spline/spline_hermite3_bounds.js";
|
|
4
|
+
|
|
5
|
+
const temp_bounds = new Float32Array(4);
|
|
3
6
|
|
|
4
7
|
/**
|
|
5
8
|
*
|
|
@@ -12,14 +15,32 @@ export function compute_curve_aabb(out, curve) {
|
|
|
12
15
|
let y0 = Number.POSITIVE_INFINITY;
|
|
13
16
|
let y1 = Number.NEGATIVE_INFINITY;
|
|
14
17
|
|
|
15
|
-
|
|
16
|
-
|
|
18
|
+
const keys = curve.keys;
|
|
19
|
+
const key_count = keys.length;
|
|
20
|
+
|
|
21
|
+
let previous = keys[0];
|
|
22
|
+
x0 = x1 = previous.time;
|
|
23
|
+
y0 = y1 = previous.value;
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
for (let i = 1; i < key_count; i++) {
|
|
27
|
+
const keyframe = keys[i];
|
|
28
|
+
|
|
29
|
+
const time_delta = keyframe.time - previous.time;
|
|
30
|
+
|
|
31
|
+
spline_hermite3_bounds(temp_bounds, 0, 1,
|
|
32
|
+
previous.value, keyframe.value,
|
|
33
|
+
previous.outTangent * time_delta,
|
|
34
|
+
keyframe.inTangent * time_delta
|
|
35
|
+
);
|
|
17
36
|
|
|
18
37
|
x0 = min2(x0, keyframe.time)
|
|
19
38
|
x1 = max2(x1, keyframe.time)
|
|
20
39
|
|
|
21
|
-
y0 = min2(y0,
|
|
22
|
-
y1 = max2(y1,
|
|
40
|
+
y0 = min2(y0, temp_bounds[0]);
|
|
41
|
+
y1 = max2(y1, temp_bounds[1]);
|
|
42
|
+
|
|
43
|
+
previous = keyframe;
|
|
23
44
|
}
|
|
24
45
|
|
|
25
46
|
out.set(x0, y0, x1, y1);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build_plot_entity_from_array.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/animation/curve/draw/build_plot_entity_from_array.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"build_plot_entity_from_array.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/animation/curve/draw/build_plot_entity_from_array.js"],"names":[],"mappings":"AASA;;;;;;;;;;GAUG;AACH,2FATW,MAAM,EAAE,GAOP,MAAM,CAyCjB;mBAxDkB,wBAAwB"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { array_compute_min_max } from "../../../../core/collection/array/array_compute_min_max.js";
|
|
1
2
|
import Vector2 from "../../../../core/geom/Vector2.js";
|
|
2
3
|
import { CanvasView } from "../../../../view/elements/CanvasView.js";
|
|
3
4
|
import Entity from "../../../ecs/Entity.js";
|
|
@@ -35,10 +36,17 @@ export function build_plot_entity_from_array({
|
|
|
35
36
|
});
|
|
36
37
|
const ctx = canvasView.context2d;
|
|
37
38
|
|
|
38
|
-
canvas2d_plot_data_line({ ctx, data, width, height, margin });
|
|
39
|
+
canvas2d_plot_data_line({ ctx, data, width, height, margin, range_x: [0, 1], range_y: array_compute_min_max(data) });
|
|
39
40
|
|
|
40
41
|
const text = `${data.length}`;
|
|
41
|
-
canvas2d_draw_label({
|
|
42
|
+
canvas2d_draw_label({
|
|
43
|
+
ctx: ctx,
|
|
44
|
+
text: text,
|
|
45
|
+
x: margin.x,
|
|
46
|
+
y: height - (20),
|
|
47
|
+
fontSize: 20,
|
|
48
|
+
color: 'red'
|
|
49
|
+
});
|
|
42
50
|
|
|
43
51
|
if (typeof label === "string" && label.length > 0) {
|
|
44
52
|
canvas2d_draw_label({ ctx: ctx, text: label, x: width - margin.x - 50, y: 20 })
|
|
@@ -38,22 +38,22 @@ async function main(engine) {
|
|
|
38
38
|
yaw: 3.123185307179593,
|
|
39
39
|
});
|
|
40
40
|
//
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
// ],engine.entityManager.dataset);
|
|
52
|
-
//
|
|
53
|
-
make_sample('data/models/samples/BoxAnimated.glb',[
|
|
54
|
-
'animation_0'
|
|
41
|
+
make_sample('data/models/samples/InterpolationTest.glb',[
|
|
42
|
+
'Step Scale',
|
|
43
|
+
'Linear Scale',
|
|
44
|
+
'CubicSpline Scale',
|
|
45
|
+
'Step Rotation',
|
|
46
|
+
'CubicSpline Rotation',
|
|
47
|
+
'Linear Rotation',
|
|
48
|
+
'Step Translation',
|
|
49
|
+
'CubicSpline Translation',
|
|
50
|
+
'Linear Translation'
|
|
55
51
|
],engine.entityManager.dataset);
|
|
56
52
|
|
|
53
|
+
// make_sample('data/models/samples/BoxAnimated.glb',[
|
|
54
|
+
// 'animation_0'
|
|
55
|
+
// ],engine.entityManager.dataset);
|
|
56
|
+
|
|
57
57
|
// make_sample('data/models/samples/animatedbox1.gltf', [
|
|
58
58
|
// 'All Animations'
|
|
59
59
|
// ], engine.entityManager.dataset);
|
|
@@ -4,6 +4,9 @@
|
|
|
4
4
|
* @param {string} text
|
|
5
5
|
* @param {number} x
|
|
6
6
|
* @param {number} y
|
|
7
|
+
* @param {string} [color] CSS color
|
|
8
|
+
* @param {number} [fontSize] in pixels
|
|
9
|
+
* @param {string} [outline] CSS color
|
|
7
10
|
*/
|
|
8
|
-
export function canvas2d_draw_label({ ctx, text, x, y }: CanvasRenderingContext2D): void;
|
|
11
|
+
export function canvas2d_draw_label({ ctx, text, x, y, color, fontSize, outline }: CanvasRenderingContext2D): void;
|
|
9
12
|
//# sourceMappingURL=canvas2d_draw_label.d.ts.map
|