@woosh/meep-engine 2.92.10 → 2.92.12
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/bundle-worker-terrain.js +1 -1
- package/build/meep.cjs +33 -9
- package/build/meep.min.js +1 -1
- package/build/meep.module.js +33 -9
- package/editor/tools/v2/prototypeTransformControls.js +13 -11
- 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 +13 -1
- package/src/core/geom/3d/aabb/aabb3_array_combine.d.ts.map +1 -1
- package/src/core/geom/3d/aabb/aabb3_array_combine.js +34 -6
- package/src/core/geom/3d/aabb/aabb3_array_set.d.ts.map +1 -1
- package/src/core/geom/3d/aabb/aabb3_array_set.js +5 -1
- 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/bvh/buffered/bvh32_from_unindexed_geometry.js +1 -1
- package/src/engine/graphics/geometry/bvh/buffered/bvh32_from_unindexed_geometry.spec.js +6 -2
package/build/meep.module.js
CHANGED
|
@@ -47050,7 +47050,7 @@ function aabb3_array_set(
|
|
|
47050
47050
|
x1, y1, z1
|
|
47051
47051
|
) {
|
|
47052
47052
|
|
|
47053
|
-
result[result_offset
|
|
47053
|
+
result[result_offset] = x0;
|
|
47054
47054
|
result[result_offset + 1] = y0;
|
|
47055
47055
|
result[result_offset + 2] = z0;
|
|
47056
47056
|
|
|
@@ -54958,13 +54958,35 @@ function aabb3_array_combine(
|
|
|
54958
54958
|
b, b_offset
|
|
54959
54959
|
) {
|
|
54960
54960
|
|
|
54961
|
-
|
|
54962
|
-
|
|
54963
|
-
|
|
54961
|
+
const ax0 = a[a_offset + 0];
|
|
54962
|
+
const ay0 = a[a_offset + 1];
|
|
54963
|
+
const az0 = a[a_offset + 2];
|
|
54964
|
+
const ax1 = a[a_offset + 3];
|
|
54965
|
+
const ay1 = a[a_offset + 4];
|
|
54966
|
+
const az1 = a[a_offset + 5];
|
|
54967
|
+
|
|
54968
|
+
const bx0 = b[b_offset + 0];
|
|
54969
|
+
const by0 = b[b_offset + 1];
|
|
54970
|
+
const bz0 = b[b_offset + 2];
|
|
54971
|
+
const bx1 = b[b_offset + 3];
|
|
54972
|
+
const by1 = b[b_offset + 4];
|
|
54973
|
+
const bz1 = b[b_offset + 5];
|
|
54974
|
+
|
|
54975
|
+
const x0 = min2(ax0, bx0);
|
|
54976
|
+
const y0 = min2(ay0, by0);
|
|
54977
|
+
const z0 = min2(az0, bz0);
|
|
54978
|
+
|
|
54979
|
+
const x1 = max2(ax1, bx1);
|
|
54980
|
+
const y1 = max2(ay1, by1);
|
|
54981
|
+
const z1 = max2(az1, bz1);
|
|
54964
54982
|
|
|
54965
|
-
result[result_offset +
|
|
54966
|
-
result[result_offset +
|
|
54967
|
-
result[result_offset +
|
|
54983
|
+
result[result_offset + 0] = x0;
|
|
54984
|
+
result[result_offset + 1] = y0;
|
|
54985
|
+
result[result_offset + 2] = z0;
|
|
54986
|
+
|
|
54987
|
+
result[result_offset + 3] = x1;
|
|
54988
|
+
result[result_offset + 4] = y1;
|
|
54989
|
+
result[result_offset + 5] = z1;
|
|
54968
54990
|
|
|
54969
54991
|
}
|
|
54970
54992
|
|
|
@@ -55292,7 +55314,9 @@ class BinaryUint32BVH {
|
|
|
55292
55314
|
x1, y1, z1
|
|
55293
55315
|
) {
|
|
55294
55316
|
|
|
55295
|
-
const
|
|
55317
|
+
const leaf_block_address = this.__node_count_binary * BVH_BINARY_NODE_SIZE;
|
|
55318
|
+
|
|
55319
|
+
const address = index * BVH_LEAF_NODE_SIZE + leaf_block_address;
|
|
55296
55320
|
|
|
55297
55321
|
aabb3_array_set(
|
|
55298
55322
|
this.__data_float32,
|
|
@@ -65745,7 +65769,7 @@ function bvh32_from_indexed_geometry(bvh, vertices, indices) {
|
|
|
65745
65769
|
*/
|
|
65746
65770
|
function bvh32_from_unindexed_geometry(bvh, vertices) {
|
|
65747
65771
|
|
|
65748
|
-
const triangle_count = vertices.length /
|
|
65772
|
+
const triangle_count = vertices.length / 9;
|
|
65749
65773
|
|
|
65750
65774
|
bvh.setLeafCount(triangle_count);
|
|
65751
65775
|
bvh.initialize_structure();
|
|
@@ -1,18 +1,19 @@
|
|
|
1
|
-
import { EngineHarness } from "../../../src/engine/EngineHarness.js";
|
|
2
|
-
import Entity from "../../../src/engine/ecs/Entity.js";
|
|
3
|
-
import { ShadedGeometry } from "../../../src/engine/graphics/ecs/mesh-v2/ShadedGeometry.js";
|
|
4
1
|
import { BoxBufferGeometry, MeshStandardMaterial } from "three";
|
|
2
|
+
import { GLTFAssetLoader } from "../../../src/engine/asset/loaders/GLTFAssetLoader.js";
|
|
3
|
+
import { TextureAssetLoader } from "../../../src/engine/asset/loaders/texture/TextureAssetLoader.js";
|
|
4
|
+
import Entity from "../../../src/engine/ecs/Entity.js";
|
|
5
|
+
import { TransformAttachmentSystem } from "../../../src/engine/ecs/transform-attachment/TransformAttachmentSystem.js";
|
|
5
6
|
import { Transform } from "../../../src/engine/ecs/transform/Transform.js";
|
|
6
|
-
import {
|
|
7
|
-
import { TransformControls } from "./TransformControls.js";
|
|
7
|
+
import { EngineHarness } from "../../../src/engine/EngineHarness.js";
|
|
8
8
|
import { Camera } from "../../../src/engine/graphics/ecs/camera/Camera.js";
|
|
9
|
-
import {
|
|
10
|
-
import
|
|
11
|
-
import InputControllerSystem from "../../../src/engine/input/ecs/systems/InputControllerSystem.js";
|
|
12
|
-
import { GLTFAssetLoader } from "../../../src/engine/asset/loaders/GLTFAssetLoader.js";
|
|
9
|
+
import { ShadedGeometry } from "../../../src/engine/graphics/ecs/mesh-v2/ShadedGeometry.js";
|
|
10
|
+
import { ShadedGeometrySystem } from "../../../src/engine/graphics/ecs/mesh-v2/ShadedGeometrySystem.js";
|
|
13
11
|
import {
|
|
14
12
|
three_object_to_entity_composition
|
|
15
13
|
} from "../../../src/engine/graphics/ecs/mesh-v2/three_object_to_entity_composition.js";
|
|
14
|
+
import InputController from "../../../src/engine/input/ecs/components/InputController.js";
|
|
15
|
+
import InputControllerSystem from "../../../src/engine/input/ecs/systems/InputControllerSystem.js";
|
|
16
|
+
import { TransformControls } from "./TransformControls.js";
|
|
16
17
|
|
|
17
18
|
const harness = new EngineHarness();
|
|
18
19
|
|
|
@@ -57,8 +58,8 @@ async function main(engine) {
|
|
|
57
58
|
entityNode.transform.scale.multiplyScalar(0.1);
|
|
58
59
|
|
|
59
60
|
controls.build(ecd); // add controls to the scene
|
|
60
|
-
|
|
61
|
-
controls.attach(entityNode.entity.id); // make controls target the cube
|
|
61
|
+
controls.attach(cube_entity); // make controls target the cube
|
|
62
|
+
// controls.attach(entityNode.entity.id); // make controls target the cube
|
|
62
63
|
|
|
63
64
|
new Entity()
|
|
64
65
|
.add(new InputController([{
|
|
@@ -88,5 +89,6 @@ harness.initialize({
|
|
|
88
89
|
config.addSystem(new InputControllerSystem(engine.devices));
|
|
89
90
|
|
|
90
91
|
config.addLoader('gltf', new GLTFAssetLoader());
|
|
92
|
+
config.addLoader('texture', new TextureAssetLoader())
|
|
91
93
|
}
|
|
92
94
|
}).then(main);
|
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,QAgBhB;IAED;;;;;;;;;;OAUG;IACH,mBATW,MAAM,WACN,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,MACN,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,QAsChB;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"}
|
|
@@ -235,6 +235,16 @@ export class BinaryUint32BVH {
|
|
|
235
235
|
x0, y0, z0,
|
|
236
236
|
x1, y1, z1
|
|
237
237
|
) {
|
|
238
|
+
assert.isNonNegativeInteger(index, 'index');
|
|
239
|
+
assert.lessThan(index, this.__node_count_leaf, 'leaf index overflow');
|
|
240
|
+
|
|
241
|
+
assert.isNumber(x0, 'x0');
|
|
242
|
+
assert.isNumber(y0, 'y0');
|
|
243
|
+
assert.isNumber(z0, 'z0');
|
|
244
|
+
assert.isNumber(x1, 'x1');
|
|
245
|
+
assert.isNumber(y1, 'y1');
|
|
246
|
+
assert.isNumber(z1, 'z1');
|
|
247
|
+
|
|
238
248
|
assert.notNaN(x0, 'x0');
|
|
239
249
|
assert.notNaN(y0, 'y0');
|
|
240
250
|
assert.notNaN(z0, 'z0');
|
|
@@ -244,7 +254,9 @@ export class BinaryUint32BVH {
|
|
|
244
254
|
|
|
245
255
|
assert.isNonNegativeInteger(payload, 'payload');
|
|
246
256
|
|
|
247
|
-
const
|
|
257
|
+
const leaf_block_address = this.__node_count_binary * BVH_BINARY_NODE_SIZE;
|
|
258
|
+
|
|
259
|
+
const address = index * BVH_LEAF_NODE_SIZE + leaf_block_address;
|
|
248
260
|
|
|
249
261
|
aabb3_array_set(
|
|
250
262
|
this.__data_float32,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"aabb3_array_combine.d.ts","sourceRoot":"","sources":["../../../../../../src/core/geom/3d/aabb/aabb3_array_combine.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"aabb3_array_combine.d.ts","sourceRoot":"","sources":["../../../../../../src/core/geom/3d/aabb/aabb3_array_combine.js"],"names":[],"mappings":"AAMA;;;;;;;;GAQG;AACH,4CAPW,UAAU,MAAM,CAAC,GAAC,MAAM,EAAE,GAAC,YAAY,iBACvC,MAAM,KACN,UAAU,MAAM,CAAC,GAAC,MAAM,EAAE,GAAC,YAAY,YACvC,MAAM,KACN,UAAU,MAAM,CAAC,GAAC,MAAM,EAAE,GAAC,YAAY,YACvC,MAAM,QA2ChB"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
//
|
|
2
2
|
|
|
3
|
+
import { assert } from "../../../assert.js";
|
|
3
4
|
import { max2 } from "../../../math/max2.js";
|
|
4
5
|
import { min2 } from "../../../math/min2.js";
|
|
5
6
|
|
|
@@ -17,13 +18,40 @@ export function aabb3_array_combine(
|
|
|
17
18
|
a, a_offset,
|
|
18
19
|
b, b_offset
|
|
19
20
|
) {
|
|
21
|
+
assert.isNonNegativeInteger(a_offset, 'a_offset');
|
|
22
|
+
assert.lessThan(a_offset, a.length - 6, 'a_offset array overflow');
|
|
20
23
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
result[result_offset + 2] = min2(a[a_offset + 2], b[b_offset + 2]);
|
|
24
|
+
assert.isNonNegativeInteger(b_offset, 'b_offset');
|
|
25
|
+
assert.lessThan(b_offset, b.length - 6, 'b_offset array overflow');
|
|
24
26
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
27
|
+
const ax0 = a[a_offset + 0];
|
|
28
|
+
const ay0 = a[a_offset + 1];
|
|
29
|
+
const az0 = a[a_offset + 2];
|
|
30
|
+
const ax1 = a[a_offset + 3];
|
|
31
|
+
const ay1 = a[a_offset + 4];
|
|
32
|
+
const az1 = a[a_offset + 5];
|
|
33
|
+
|
|
34
|
+
const bx0 = b[b_offset + 0];
|
|
35
|
+
const by0 = b[b_offset + 1];
|
|
36
|
+
const bz0 = b[b_offset + 2];
|
|
37
|
+
const bx1 = b[b_offset + 3];
|
|
38
|
+
const by1 = b[b_offset + 4];
|
|
39
|
+
const bz1 = b[b_offset + 5];
|
|
40
|
+
|
|
41
|
+
const x0 = min2(ax0, bx0);
|
|
42
|
+
const y0 = min2(ay0, by0);
|
|
43
|
+
const z0 = min2(az0, bz0);
|
|
44
|
+
|
|
45
|
+
const x1 = max2(ax1, bx1);
|
|
46
|
+
const y1 = max2(ay1, by1);
|
|
47
|
+
const z1 = max2(az1, bz1);
|
|
48
|
+
|
|
49
|
+
result[result_offset + 0] = x0;
|
|
50
|
+
result[result_offset + 1] = y0;
|
|
51
|
+
result[result_offset + 2] = z0;
|
|
52
|
+
|
|
53
|
+
result[result_offset + 3] = x1;
|
|
54
|
+
result[result_offset + 4] = y1;
|
|
55
|
+
result[result_offset + 5] = z1;
|
|
28
56
|
|
|
29
57
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"aabb3_array_set.d.ts","sourceRoot":"","sources":["../../../../../../src/core/geom/3d/aabb/aabb3_array_set.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"aabb3_array_set.d.ts","sourceRoot":"","sources":["../../../../../../src/core/geom/3d/aabb/aabb3_array_set.js"],"names":[],"mappings":"AAEA;;;;;;;;;;GAUG;AACH,wCATW,UAAU,MAAM,CAAC,GAAC,YAAY,GAAC,MAAM,EAAE,iBACvC,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,QAiBhB"}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { assert } from "../../../assert.js";
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
*
|
|
3
5
|
* @param {ArrayLike<number>|Float32Array|number[]} result
|
|
@@ -15,7 +17,9 @@ export function aabb3_array_set(
|
|
|
15
17
|
x1, y1, z1
|
|
16
18
|
) {
|
|
17
19
|
|
|
18
|
-
|
|
20
|
+
assert.lessThanOrEqual(result_offset, result.length - 6, 'result_offset overflow')
|
|
21
|
+
|
|
22
|
+
result[result_offset] = x0;
|
|
19
23
|
result[result_offset + 1] = y0;
|
|
20
24
|
result[result_offset + 2] = z0;
|
|
21
25
|
|
|
@@ -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 })
|