@woosh/meep-engine 2.55.0 → 2.56.1
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/view/node-graph/PortView.js +2 -2
- package/package.json +1 -1
- package/src/core/binary/BinaryBuffer.js +2 -1
- package/src/core/cache/LoadingCache.js +10 -5
- package/src/core/collection/array/array_remove_element.js +6 -9
- package/src/core/collection/array/array_remove_first.js +13 -6
- package/src/core/collection/array/array_remove_first.spec.js +39 -0
- package/src/core/collection/array/binarySearchHighIndex.spec.js +10 -9
- package/src/core/collection/heap/Uin32Heap.spec.js +36 -0
- package/src/core/collection/heap/Uint32Heap.js +10 -5
- package/src/core/function/FunctionCompiler.js +4 -4
- package/src/core/function/Functions.js +0 -19
- package/src/core/geom/3d/SurfacePoint3.js +30 -20
- package/src/core/geom/3d/SurfacePoint3.spec.js +116 -0
- package/src/core/geom/3d/aabb/AABB3.js +10 -9
- package/src/core/geom/3d/aabb/{aabb3_array_contains_point.js → aabb3_array_intersects_point.js} +4 -1
- package/src/core/geom/3d/aabb/aabb3_from_min_max.js +25 -1
- package/src/core/geom/3d/aabb/aabb3_from_threejs_geometry.js +2 -25
- package/src/core/geom/3d/aabb/aabb3_signed_distance_sqr_to_point.js +5 -1
- package/src/core/geom/3d/apply_mat4_transform_to_direction_v3_array.js +5 -1
- package/src/core/geom/3d/apply_mat4_transform_to_v3_array.js +5 -1
- package/src/core/geom/3d/tetrahedra/TetrahedralMesh.js +2 -2
- package/src/core/geom/3d/triangle/computeTriangleRayIntersectionBarycentric.spec.js +26 -0
- package/src/core/geom/3d/v3_compute_triangle_normal.spec.js +18 -0
- package/src/core/geom/Vector2.js +1 -1
- package/src/core/geom/Vector3.js +1 -1
- package/src/core/geom/packing/miniball/Miniball.spec.js +24 -0
- package/src/core/math/statistics/computeStatisticalPartialMedian.js +2 -2
- package/src/core/model/object/read_property.js +2 -2
- package/src/core/model/object/write_property.js +3 -3
- package/src/core/primitives/numbers/compareNumbers.js +4 -4
- package/src/core/primitives/numbers/number_compare_ascending.js +9 -0
- package/src/core/primitives/numbers/number_compare_ascending.spec.js +9 -0
- package/src/core/primitives/numbers/number_compare_descending.js +9 -0
- package/src/core/primitives/numbers/number_compare_descending.spec.js +9 -0
- package/src/core/primitives/numbers/number_format_by_thousands.spec.js +12 -0
- package/src/core/primitives/numbers/number_pretty_print.js +1 -1
- package/src/core/primitives/strings/compareStrings.spec.js +12 -0
- package/src/core/primitives/strings/string_capitalize.js +15 -0
- package/src/core/primitives/strings/string_capitalize.spec.js +13 -0
- package/src/core/primitives/strings/string_compute_byte_size.js +21 -0
- package/src/core/primitives/strings/string_compute_common_prefix.js +44 -0
- package/src/core/primitives/strings/string_compute_common_prefix.spec.js +23 -0
- package/src/core/primitives/strings/string_format_camel_to_kebab.js +9 -0
- package/src/core/primitives/strings/string_format_camel_to_kebab.spec.js +8 -0
- package/src/core/primitives/strings/string_format_kebab_to_underscore.js +8 -0
- package/src/core/time/current_time_in_seconds.js +11 -0
- package/src/engine/Clock.js +3 -13
- package/src/engine/animation/curve/AnimationCurve.spec.js +27 -0
- package/src/engine/asset/AssetManager.js +2 -2
- package/src/engine/ecs/EntityManager.js +8 -1
- package/src/engine/ecs/EntityManager.spec.js +56 -6
- package/src/engine/ecs/animation/Animation.spec.js +22 -0
- package/src/engine/ecs/attachment/Attachment.js +24 -25
- package/src/engine/ecs/attachment/AttachmentBinding.js +27 -30
- package/src/engine/ecs/attachment/AttachmentSystem.js +21 -24
- package/src/engine/ecs/attachment/BoneAttachmentBinding.js +6 -9
- package/src/engine/ecs/attachment/TransformAttachmentBinding.js +0 -3
- package/src/engine/ecs/components/CharacterController.js +24 -18
- package/src/engine/ecs/dynamic_actions/DynamicActorSystem.js +3 -2
- package/src/engine/ecs/fow/FogOfWarRevealer.js +2 -3
- package/src/engine/ecs/ik/IKMath.js +6 -1
- package/src/engine/ecs/ik/IKProblem.js +17 -17
- package/src/engine/ecs/ik/InverseKinematics.js +6 -7
- package/src/engine/ecs/ik/InverseKinematicsSystem.js +24 -26
- package/src/engine/ecs/storage/BinaryBufferSerializer.js +3 -3
- package/src/engine/ecs/systems/TagSystem.js +1 -6
- package/src/engine/ecs/terrain/ecs/layers/TerrainLayer.js +2 -2
- package/src/engine/graphics/ecs/mesh/skeleton/BoneMapping.js +2 -2
- package/src/engine/graphics/ecs/mesh-v2/ShadedGeometry.spec.js +14 -0
- package/src/engine/graphics/ecs/mesh-v2/render/adapters/SGCacheKey.js +21 -9
- package/src/engine/graphics/ecs/mesh-v2/render/adapters/SGCacheKey.spec.js +79 -0
- package/src/engine/graphics/render/visibility/IncrementalDeltaSet.spec.js +7 -6
- package/src/engine/options/OptionGroup.js +10 -0
- package/src/engine/simulation/Ticker.js +17 -20
- package/src/generation/GridTaskGroup.js +5 -9
- package/src/generation/filtering/numeric/CellFilterCache.js +12 -16
- package/src/generation/filtering/numeric/complex/CellFilterFXAA.js +31 -32
- package/src/generation/filtering/numeric/complex/CellFilterLookupTable.js +6 -9
- package/src/generation/filtering/numeric/complex/CellFilterSimplexNoise.js +7 -10
- package/src/generation/filtering/numeric/complex/CellFilterSobel.js +6 -9
- package/src/generation/filtering/numeric/math/CellFilterMembershipGeneralizedBell.js +18 -21
- package/src/generation/filtering/numeric/sampling/AbstractCellFilterSampleGridLayer.js +24 -25
- package/src/generation/filtering/numeric/sampling/CellFilterSampleLayerLinear.js +1 -1
- package/src/generation/grid/GridData.js +23 -22
- package/src/generation/grid/GridData.spec.js +41 -0
- package/src/generation/grid/GridTaskGenerator.js +7 -8
- package/src/generation/grid/layers/GridDataLayer.js +23 -25
- package/src/generation/markers/GridActionRuleSet.js +20 -22
- package/src/generation/markers/GridCellActionPlaceMarker.js +40 -43
- package/src/generation/markers/GridCellActionPlaceMarkerGroup.js +7 -9
- package/src/generation/markers/MarkerNode.js +44 -44
- package/src/generation/markers/actions/MarkerNodeActionEntityPlacement.js +15 -18
- package/src/generation/markers/actions/MarkerNodeActionSequence.js +6 -9
- package/src/generation/markers/actions/MarkerNodeProcessingRuleSet.js +5 -7
- package/src/generation/markers/actions/MarkerProcessingRule.js +25 -26
- package/src/generation/markers/actions/placement/MarkerNodeEntityProcessorClingToTerrain.js +12 -15
- package/src/generation/markers/actions/placement/MarkerNodeEntityProcessorRandomRotation.js +2 -5
- package/src/generation/markers/actions/placement/MarkerNodeEntityProcessorSequence.js +6 -9
- package/src/generation/markers/actions/probability/MarkerNodeActionSelectWeighted.js +8 -11
- package/src/generation/markers/actions/probability/MarkerNodeActionWeightedElement.js +13 -13
- package/src/generation/markers/actions/util/GridCellActionDebugBreak.js +5 -8
- package/src/generation/markers/actions/util/GridCellActionLogToConsole.js +1 -4
- package/src/generation/markers/emitter/MarkerNodeConsumerBuffer.js +10 -13
- package/src/generation/markers/emitter/MarkerNodeEmitterFromAction.js +5 -9
- package/src/generation/markers/emitter/MarkerNodeEmitterGridCellAction.js +12 -15
- package/src/generation/markers/emitter/MarkerNodeEmitterGroup.js +5 -8
- package/src/generation/markers/emitter/MarkerNodeEmitterPredicated.js +18 -21
- package/src/generation/markers/matcher/MarkerNodeMatcher.js +2 -1
- package/src/generation/markers/matcher/MarkerNodeMatcherBinary.js +12 -13
- package/src/generation/markers/matcher/MarkerNodeMatcherContainsTag.js +7 -9
- package/src/generation/markers/matcher/MarkerNodeMatcherNot.js +7 -9
- package/src/generation/markers/predicate/GridDataNodePredicateBinary.js +10 -14
- package/src/generation/markers/predicate/GridDataNodePredicateNot.js +9 -11
- package/src/generation/markers/predicate/GridDataNodePredicateOverlaps.js +6 -9
- package/src/generation/markers/transform/MarkerNodeTransformRotateRandom.js +2 -6
- package/src/generation/markers/transform/MarkerNodeTransformerAddPositionYFromFilter.js +6 -9
- package/src/generation/markers/transform/MarkerNodeTransformerOffsetPosition.js +1 -4
- package/src/generation/markers/transform/MarkerNodeTransformerRecordProperty.js +12 -15
- package/src/generation/markers/transform/MarkerNodeTransformerRecordPropertyClosure.js +14 -17
- package/src/generation/markers/transform/MarkerNodeTransformerRecordUniqueRandomEnum.js +21 -23
- package/src/generation/markers/transform/MarkerNodeTransformerRemoveTag.js +1 -4
- package/src/generation/markers/transform/MarkerNodeTransformerSequence.js +6 -9
- package/src/generation/markers/transform/MarkerNodeTransformerYRotateByFilter.js +13 -17
- package/src/generation/markers/transform/MarkerNodeTransformerYRotateByFilterGradient.js +12 -16
- package/src/generation/placement/GridCellActionTransformNearbyMarkers.js +26 -29
- package/src/generation/placement/GridCellPlacementRule.js +30 -32
- package/src/generation/placement/action/GridCellActionPlaceTags.js +26 -28
- package/src/generation/placement/action/GridCellActionWriteFilterToLayer.js +16 -20
- package/src/generation/placement/action/random/weighted/CellActionSelectWeightedRandom.js +13 -16
- package/src/generation/placement/action/random/weighted/WeightedGridCellAction.js +11 -14
- package/src/generation/placement/action/util/CellMatcherWithinAABB.js +2 -6
- package/src/generation/placement/action/util/GridCellActionSequence.js +7 -9
- package/src/generation/placement/action/util/GridCellDisplacedAction.js +9 -12
- package/src/generation/rules/CellMatcherFromFilter.js +6 -9
- package/src/generation/rules/CellMatcherLayerBitMaskTest.js +6 -9
- package/src/generation/rules/GridLayerCellMatcher.js +11 -14
- package/src/generation/rules/cell/CellMatcherContainsMarkerWithinRadius.js +11 -14
- package/src/generation/rules/cell/CellMatcherGridPattern.js +6 -8
- package/src/generation/rules/cell/GridPatternMatcherCell.js +11 -12
- package/src/generation/rules/logic/CellMatcherBinary.js +10 -14
- package/src/generation/rules/logic/CellMatcherDecorator.js +5 -8
- package/src/generation/theme/AreaMask.js +15 -17
- package/src/generation/theme/AreaTheme.js +7 -8
- package/src/generation/theme/TerrainLayerDescription.js +10 -12
- package/src/generation/theme/TerrainLayerRule.js +11 -13
- package/src/generation/theme/TerrainTheme.js +6 -7
- package/src/generation/theme/Theme.js +15 -17
- package/src/generation/theme/ThemeEngine.js +16 -18
- package/src/view/string_tag_to_css_class_name.js +2 -2
- package/src/view/tooltip/gml/TooltipParser.js +2 -2
- package/src/core/cache/PersistentCacheAdapter.js +0 -378
- package/src/core/primitives/strings/StringUtils.js +0 -105
- package/src/core/primitives/strings/StringUtils.spec.js +0 -42
- package/src/engine/ecs/components/MonsterAI.js +0 -15
- package/src/generation/markers/MarkerRelation.js +0 -13
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { assert } from "../../../assert.js";
|
|
2
|
+
import { aabb3_from_min_max } from "./aabb3_from_min_max.js";
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
*
|
|
@@ -13,29 +14,5 @@ export function aabb3_from_threejs_geometry(result, geometry) {
|
|
|
13
14
|
const min = gbb.min;
|
|
14
15
|
const max = gbb.max;
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
const y0 = min.y;
|
|
18
|
-
const z0 = min.z;
|
|
19
|
-
|
|
20
|
-
const x1 = max.x;
|
|
21
|
-
const y1 = max.y;
|
|
22
|
-
const z1 = max.z;
|
|
23
|
-
|
|
24
|
-
// validate bounds
|
|
25
|
-
assert.notNaN(x0, 'x0');
|
|
26
|
-
assert.notNaN(y0, 'y0');
|
|
27
|
-
assert.notNaN(z0, 'z0');
|
|
28
|
-
|
|
29
|
-
assert.notNaN(x1, 'x1');
|
|
30
|
-
assert.notNaN(y1, 'y1');
|
|
31
|
-
assert.notNaN(z1, 'z1');
|
|
32
|
-
|
|
33
|
-
// marshal into transform-accepted format
|
|
34
|
-
result[0] = x0;
|
|
35
|
-
result[1] = y0;
|
|
36
|
-
result[2] = z0;
|
|
37
|
-
|
|
38
|
-
result[3] = x1;
|
|
39
|
-
result[4] = y1;
|
|
40
|
-
result[5] = z1;
|
|
17
|
+
aabb3_from_min_max(result, min, max);
|
|
41
18
|
}
|
|
@@ -13,7 +13,11 @@ import { max2 } from "../../../math/max2.js";
|
|
|
13
13
|
* @param {number} point_z
|
|
14
14
|
* @returns {number}
|
|
15
15
|
*/
|
|
16
|
-
export function aabb3_signed_distance_sqr_to_point(
|
|
16
|
+
export function aabb3_signed_distance_sqr_to_point(
|
|
17
|
+
x0, y0, z0,
|
|
18
|
+
x1, y1, z1,
|
|
19
|
+
point_x, point_y, point_z
|
|
20
|
+
) {
|
|
17
21
|
//do projection
|
|
18
22
|
const xp0 = x0 - point_x;
|
|
19
23
|
const xp1 = point_x - x1;
|
|
@@ -8,7 +8,11 @@
|
|
|
8
8
|
* @param {number} vertex_count
|
|
9
9
|
* @param {mat4|number[]|Float32Array} mat4
|
|
10
10
|
*/
|
|
11
|
-
export function apply_mat4_transform_to_direction_v3_array(
|
|
11
|
+
export function apply_mat4_transform_to_direction_v3_array(
|
|
12
|
+
source, source_offset,
|
|
13
|
+
destination, destination_offset,
|
|
14
|
+
vertex_count, mat4
|
|
15
|
+
) {
|
|
12
16
|
|
|
13
17
|
const a0 = mat4[0];
|
|
14
18
|
const a1 = mat4[1];
|
|
@@ -8,7 +8,11 @@
|
|
|
8
8
|
* @param {number} vertex_count
|
|
9
9
|
* @param {mat4|number[]|Float32Array} mat4
|
|
10
10
|
*/
|
|
11
|
-
export function apply_mat4_transform_to_v3_array(
|
|
11
|
+
export function apply_mat4_transform_to_v3_array(
|
|
12
|
+
source, source_offset,
|
|
13
|
+
destination, destination_offset,
|
|
14
|
+
vertex_count, mat4
|
|
15
|
+
) {
|
|
12
16
|
|
|
13
17
|
const a0 = mat4[0];
|
|
14
18
|
const a1 = mat4[1];
|
|
@@ -4,9 +4,9 @@ import { max3 } from "../../../math/max3.js";
|
|
|
4
4
|
import { assert } from "../../../assert.js";
|
|
5
5
|
import { array_copy } from "../../../collection/array/array_copy.js";
|
|
6
6
|
import { array_quick_sort_by_comparator } from "../../../collection/array/arrayQuickSort.js";
|
|
7
|
-
import { compareNumbersDescending } from "../../../function/Functions.js";
|
|
8
7
|
import { BinaryBuffer } from "../../../binary/BinaryBuffer.js";
|
|
9
8
|
import { Base64 } from "../../../binary/Base64.js";
|
|
9
|
+
import { number_compare_descending } from "../../../primitives/numbers/number_compare_descending.js";
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* @readonly
|
|
@@ -546,7 +546,7 @@ export class TetrahedralMesh {
|
|
|
546
546
|
*/
|
|
547
547
|
compact() {
|
|
548
548
|
// sort free
|
|
549
|
-
array_quick_sort_by_comparator(this.__free,
|
|
549
|
+
array_quick_sort_by_comparator(this.__free, number_compare_descending, null, 0, this.__free_pointer - 1);
|
|
550
550
|
|
|
551
551
|
let relocation_count = 0;
|
|
552
552
|
let free_head_pointer = 0;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { computeTriangleRayIntersectionBarycentric } from "./computeTriangleRayIntersectionBarycentric.js";
|
|
2
|
+
|
|
3
|
+
test("orthogonal, through center", () => {
|
|
4
|
+
|
|
5
|
+
const result = [];
|
|
6
|
+
|
|
7
|
+
const hit_found = computeTriangleRayIntersectionBarycentric(
|
|
8
|
+
result,
|
|
9
|
+
0, 0, 3,
|
|
10
|
+
0, 0, -1,
|
|
11
|
+
-1, -1, 0,
|
|
12
|
+
1, -1, 0,
|
|
13
|
+
1, 1, 0
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
expect(hit_found).toBe(true);
|
|
17
|
+
|
|
18
|
+
expect(result[0]).toBeCloseTo(3);
|
|
19
|
+
|
|
20
|
+
// note that UVs are just checked for sanity
|
|
21
|
+
expect(result[1]).toBeGreaterThanOrEqual(0);
|
|
22
|
+
expect(result[1]).toBeLessThanOrEqual(1);
|
|
23
|
+
|
|
24
|
+
expect(result[2]).toBeGreaterThanOrEqual(0);
|
|
25
|
+
expect(result[2]).toBeLessThanOrEqual(1);
|
|
26
|
+
});
|
|
@@ -25,3 +25,21 @@ test("axis aligned triangles on -X plane", () => {
|
|
|
25
25
|
|
|
26
26
|
expect(result).toEqual([-1, 0, 0]);
|
|
27
27
|
});
|
|
28
|
+
|
|
29
|
+
test("degenerate triangle with all points at the same position", () => {
|
|
30
|
+
const result = [];
|
|
31
|
+
|
|
32
|
+
v3_compute_triangle_normal(
|
|
33
|
+
result, 0,
|
|
34
|
+
1, 3, 5,
|
|
35
|
+
1, 3, 5,
|
|
36
|
+
1, 3, 5,
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
expect(result[0]).not.toBeNaN();
|
|
40
|
+
expect(result[1]).not.toBeNaN();
|
|
41
|
+
expect(result[2]).not.toBeNaN();
|
|
42
|
+
|
|
43
|
+
// normal vector length should be 1
|
|
44
|
+
expect(Math.hypot(result[0], result[1], result[2])).toBeCloseTo(1);
|
|
45
|
+
});
|
package/src/core/geom/Vector2.js
CHANGED
package/src/core/geom/Vector3.js
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import { Miniball } from "./Miniball.js";
|
|
2
2
|
import { PointSet } from "./PointSet.js";
|
|
3
3
|
|
|
4
|
+
|
|
5
|
+
test("empty point set in 1d", () => {
|
|
6
|
+
|
|
7
|
+
new Miniball(new PointSet(0, 1, []));
|
|
8
|
+
|
|
9
|
+
});
|
|
10
|
+
|
|
4
11
|
test("single point in 1d", () => {
|
|
5
12
|
|
|
6
13
|
const miniball = new Miniball(new PointSet(1, 1, [7]));
|
|
@@ -9,3 +16,20 @@ test("single point in 1d", () => {
|
|
|
9
16
|
expect(miniball.radius()).toEqual(0);
|
|
10
17
|
|
|
11
18
|
});
|
|
19
|
+
|
|
20
|
+
test("3 points in 1d", () => {
|
|
21
|
+
const miniball = new Miniball(new PointSet(3, 1, [-3, 7, 11]));
|
|
22
|
+
|
|
23
|
+
expect(miniball.center()[0]).toBeCloseTo(4);
|
|
24
|
+
expect(miniball.radius()).toBeCloseTo(7);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
test("toString produces a valid string", () => {
|
|
28
|
+
|
|
29
|
+
const miniball = new Miniball(new PointSet(1, 1, [7]));
|
|
30
|
+
|
|
31
|
+
const s = miniball.toString();
|
|
32
|
+
|
|
33
|
+
expect(typeof s).toBe("string");
|
|
34
|
+
expect(s.trim().length).toBeGreaterThan(0);
|
|
35
|
+
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { compareNumbersAscending } from "../../function/Functions.js";
|
|
2
1
|
import { assert } from "../../assert.js";
|
|
2
|
+
import { number_compare_ascending } from "../../primitives/numbers/number_compare_ascending.js";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
*
|
|
@@ -14,7 +14,7 @@ export function computeStatisticalPartialMedian(values, start, end) {
|
|
|
14
14
|
|
|
15
15
|
const copy = values.slice();
|
|
16
16
|
|
|
17
|
-
copy.sort(
|
|
17
|
+
copy.sort(number_compare_ascending);
|
|
18
18
|
|
|
19
19
|
const range = end - start;
|
|
20
20
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { string_capitalize } from "../../primitives/strings/string_capitalize.js";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* @template T
|
|
@@ -19,7 +19,7 @@ export function read_property(root, parts, part_offset, part_count) {
|
|
|
19
19
|
if (typeof thing[part] !== 'undefined') {
|
|
20
20
|
thing = thing[part];
|
|
21
21
|
} else {
|
|
22
|
-
const getter_name = `get${
|
|
22
|
+
const getter_name = `get${string_capitalize(part)}`;
|
|
23
23
|
const getter = thing[getter_name];
|
|
24
24
|
|
|
25
25
|
if (typeof getter === "function") {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { string_capitalize } from "../../primitives/strings/string_capitalize.js";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* @template T
|
|
@@ -23,7 +23,7 @@ export function write_property(root, parts, part_offset, part_count, value) {
|
|
|
23
23
|
thing = thing_part;
|
|
24
24
|
} else {
|
|
25
25
|
|
|
26
|
-
const getter_name = `get${
|
|
26
|
+
const getter_name = `get${string_capitalize(part)}`;
|
|
27
27
|
const getter = thing[getter_name];
|
|
28
28
|
|
|
29
29
|
if (typeof getter === "function") {
|
|
@@ -38,7 +38,7 @@ export function write_property(root, parts, part_offset, part_count, value) {
|
|
|
38
38
|
|
|
39
39
|
const last_part = parts[last_index];
|
|
40
40
|
|
|
41
|
-
const setter_name = `set${
|
|
41
|
+
const setter_name = `set${string_capitalize(last_part)}`;
|
|
42
42
|
const setter = thing[setter_name];
|
|
43
43
|
|
|
44
44
|
if (typeof setter === "function") {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
+
import { number_compare_ascending } from "./number_compare_ascending.js";
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
|
-
*
|
|
4
|
+
* @deprecated use {@link number_compare_ascending} directly
|
|
3
5
|
* @param {number} a
|
|
4
6
|
* @param {number} b
|
|
5
7
|
* @returns {number}
|
|
6
8
|
*/
|
|
7
|
-
export
|
|
8
|
-
return a - b;
|
|
9
|
-
}
|
|
9
|
+
export const compareNumbers = number_compare_ascending;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { number_format_by_thousands } from "./number_format_by_thousands.js";
|
|
2
|
+
|
|
3
|
+
test("basics", () => {
|
|
4
|
+
|
|
5
|
+
expect(number_format_by_thousands(0, ',')).toEqual("0");
|
|
6
|
+
expect(number_format_by_thousands(987, ',')).toEqual("987");
|
|
7
|
+
expect(number_format_by_thousands(1234, ',')).toEqual("1,234");
|
|
8
|
+
expect(number_format_by_thousands(987654321, ',')).toEqual("987,654,321");
|
|
9
|
+
|
|
10
|
+
// different separator
|
|
11
|
+
expect(number_format_by_thousands(1234, ' -> ')).toEqual("1 -> 234");
|
|
12
|
+
});
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { compareStrings } from "./compareStrings.js";
|
|
2
|
+
|
|
3
|
+
test("stability", () => {
|
|
4
|
+
|
|
5
|
+
const array_a = ["a", undefined, "test", null, ""];
|
|
6
|
+
const array_b = [null, undefined, "", "a", "test"];
|
|
7
|
+
|
|
8
|
+
array_a.sort(compareStrings);
|
|
9
|
+
array_b.sort(compareStrings);
|
|
10
|
+
|
|
11
|
+
expect(array_a).toEqual(array_b);
|
|
12
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Turn first letter in the string to capital
|
|
3
|
+
* @example "text" will become "Text"
|
|
4
|
+
* @param {string} string
|
|
5
|
+
* @returns {string}
|
|
6
|
+
*/
|
|
7
|
+
export function string_capitalize(string) {
|
|
8
|
+
const length = string.length;
|
|
9
|
+
|
|
10
|
+
if (length === 0) {
|
|
11
|
+
return string;
|
|
12
|
+
} else {
|
|
13
|
+
return string.charAt(0).toLocaleUpperCase() + string.substring(1);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { string_capitalize } from "./string_capitalize.js";
|
|
2
|
+
|
|
3
|
+
test("capitalize", () => {
|
|
4
|
+
expect(string_capitalize("")).toBe("");
|
|
5
|
+
|
|
6
|
+
expect(string_capitalize("a")).toBe("A");
|
|
7
|
+
|
|
8
|
+
expect(string_capitalize("A")).toBe("A");
|
|
9
|
+
|
|
10
|
+
expect(string_capitalize("aa")).toBe("Aa");
|
|
11
|
+
|
|
12
|
+
expect(string_capitalize("AA")).toBe("AA");
|
|
13
|
+
});
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compute byte size of a UTF8 string
|
|
3
|
+
* @param {string} value
|
|
4
|
+
* @returns {number}
|
|
5
|
+
*/
|
|
6
|
+
export function string_compute_byte_size(value) {
|
|
7
|
+
const length = value.length;
|
|
8
|
+
|
|
9
|
+
let p = 0;
|
|
10
|
+
|
|
11
|
+
for (let i = 0; i < length; i++) {
|
|
12
|
+
let c = value.charCodeAt(i);
|
|
13
|
+
while (c > 0xff) {
|
|
14
|
+
p++;
|
|
15
|
+
c >>= 8;
|
|
16
|
+
}
|
|
17
|
+
p++;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return p;
|
|
21
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @example: ['abra', 'abc', 'abode'] => 'ab'
|
|
3
|
+
* @param {String[]} strings
|
|
4
|
+
* @returns string
|
|
5
|
+
*/
|
|
6
|
+
export function string_compute_common_prefix(strings) {
|
|
7
|
+
let i, j;
|
|
8
|
+
|
|
9
|
+
const numInputs = strings.length;
|
|
10
|
+
|
|
11
|
+
let result = "";
|
|
12
|
+
|
|
13
|
+
if (numInputs === 0) {
|
|
14
|
+
return result;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const firstString = strings[0];
|
|
18
|
+
|
|
19
|
+
let lengthLimit = firstString.length;
|
|
20
|
+
|
|
21
|
+
for (i = 1; i < numInputs; i++) {
|
|
22
|
+
lengthLimit = Math.min(strings[i].length, lengthLimit);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
main_loop:for (i = 0; i < lengthLimit; i++) {
|
|
27
|
+
const letter0 = firstString.charAt(i);
|
|
28
|
+
|
|
29
|
+
for (j = 1; j < numInputs; j++) {
|
|
30
|
+
|
|
31
|
+
const string = strings[j];
|
|
32
|
+
|
|
33
|
+
const letter1 = string.charAt(i);
|
|
34
|
+
|
|
35
|
+
if (letter0 !== letter1) {
|
|
36
|
+
break main_loop;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
result += letter0;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return result;
|
|
44
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { string_compute_common_prefix } from "./string_compute_common_prefix.js";
|
|
2
|
+
|
|
3
|
+
test("common prefix", () => {
|
|
4
|
+
expect(string_compute_common_prefix([])).toBe("");
|
|
5
|
+
|
|
6
|
+
expect(string_compute_common_prefix([""])).toBe("");
|
|
7
|
+
|
|
8
|
+
expect(string_compute_common_prefix(["a"])).toBe("a");
|
|
9
|
+
|
|
10
|
+
expect(string_compute_common_prefix(["abc"])).toBe("abc");
|
|
11
|
+
|
|
12
|
+
expect(string_compute_common_prefix(["aa"])).toBe("aa");
|
|
13
|
+
|
|
14
|
+
expect(string_compute_common_prefix(["aa", "ab"])).toBe("a");
|
|
15
|
+
|
|
16
|
+
expect(string_compute_common_prefix(["abc", "abb"])).toBe("ab");
|
|
17
|
+
|
|
18
|
+
expect(string_compute_common_prefix(["abc", "abc"])).toBe("abc");
|
|
19
|
+
|
|
20
|
+
expect(string_compute_common_prefix(["abc", "abc", "a"])).toBe("a");
|
|
21
|
+
|
|
22
|
+
expect(string_compute_common_prefix(["abc", "abc", ""])).toBe("");
|
|
23
|
+
});
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Convert camelCaseString to kebab-format-string
|
|
3
|
+
* useful for resolving CSS property names
|
|
4
|
+
* @param {string} string
|
|
5
|
+
* @returns {string}
|
|
6
|
+
*/
|
|
7
|
+
export function string_format_camel_to_kebab(string) {
|
|
8
|
+
return string.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
|
|
9
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { string_format_camel_to_kebab } from "./string_format_camel_to_kebab.js";
|
|
2
|
+
|
|
3
|
+
test('camelToKebab', () => {
|
|
4
|
+
expect(string_format_camel_to_kebab('a')).toBe('a');
|
|
5
|
+
expect(string_format_camel_to_kebab('aA')).toBe('a-a');
|
|
6
|
+
expect(string_format_camel_to_kebab('helloWoRLD')).toBe('hello-wo-rld');
|
|
7
|
+
expect(string_format_camel_to_kebab('A')).toBe('a');
|
|
8
|
+
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
|
|
2
|
+
//Use highest available resolution time source
|
|
3
|
+
const source = typeof performance === "undefined" ? Date : performance;
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Current time in seconds
|
|
7
|
+
* @returns {number}
|
|
8
|
+
*/
|
|
9
|
+
export function current_time_in_seconds() {
|
|
10
|
+
return source.now() * 1e-3;
|
|
11
|
+
}
|
package/src/engine/Clock.js
CHANGED
|
@@ -4,24 +4,14 @@
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
import Stat from "../core/model/stat/Stat.js";
|
|
7
|
-
|
|
8
|
-
//Use highest available resolution time source
|
|
9
|
-
const source = typeof performance === "undefined" ? Date : performance;
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
*
|
|
13
|
-
* @returns {number}
|
|
14
|
-
*/
|
|
15
|
-
export function currentTimeInSeconds() {
|
|
16
|
-
return source.now() * 0.001;
|
|
17
|
-
}
|
|
7
|
+
import { current_time_in_seconds } from "../core/time/current_time_in_seconds.js";
|
|
18
8
|
|
|
19
9
|
/**
|
|
20
10
|
*
|
|
21
11
|
* @param {Clock} clock
|
|
22
12
|
*/
|
|
23
13
|
function updateElapsedTime(clock) {
|
|
24
|
-
const now =
|
|
14
|
+
const now = current_time_in_seconds();
|
|
25
15
|
const delta = (now - clock.__lastMeasurement) * clock.speed;
|
|
26
16
|
clock.__lastMeasurement = now;
|
|
27
17
|
clock.elapsedTime += delta;
|
|
@@ -79,7 +69,7 @@ class Clock {
|
|
|
79
69
|
}
|
|
80
70
|
|
|
81
71
|
start() {
|
|
82
|
-
this.__lastMeasurement =
|
|
72
|
+
this.__lastMeasurement = current_time_in_seconds();
|
|
83
73
|
this.timeAtDelta = this.updateElapsedTime();
|
|
84
74
|
this.__isRunning = true;
|
|
85
75
|
}
|
|
@@ -46,6 +46,19 @@ test("removing exising key", () => {
|
|
|
46
46
|
expect(curve.length).toBe(0);
|
|
47
47
|
});
|
|
48
48
|
|
|
49
|
+
test("evaluate on empty curve", () => {
|
|
50
|
+
const curve = new AnimationCurve();
|
|
51
|
+
|
|
52
|
+
expect(curve.evaluate(0)).toBe(0);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
test("evaluate before first frame", () => {
|
|
56
|
+
const curve = new AnimationCurve();
|
|
57
|
+
|
|
58
|
+
curve.add(Keyframe.from(1, 7));
|
|
59
|
+
|
|
60
|
+
expect(curve.evaluate(0.9)).toEqual(7);
|
|
61
|
+
});
|
|
49
62
|
|
|
50
63
|
test("sample linear curve with 2 points", () => {
|
|
51
64
|
const curve = new AnimationCurve();
|
|
@@ -78,6 +91,20 @@ test("smooth tangents with a single keyframe does not throw", () => {
|
|
|
78
91
|
|
|
79
92
|
expect(() => curve.smoothTangents(0, 1)).not.toThrow()
|
|
80
93
|
});
|
|
94
|
+
test("smooth tangents on a middle frame", () => {
|
|
95
|
+
const curve = new AnimationCurve();
|
|
96
|
+
|
|
97
|
+
curve.add(Keyframe.from(0, 1));
|
|
98
|
+
curve.add(Keyframe.from(1, 2));
|
|
99
|
+
curve.add(Keyframe.from(2, 3));
|
|
100
|
+
|
|
101
|
+
curve.smoothTangents(1, 1);
|
|
102
|
+
|
|
103
|
+
const key = curve.keys[1];
|
|
104
|
+
|
|
105
|
+
expect(key.inTangent).toEqual(key.outTangent);
|
|
106
|
+
});
|
|
107
|
+
|
|
81
108
|
|
|
82
109
|
test("to/from JSON consistency", () => {
|
|
83
110
|
|
|
@@ -9,7 +9,6 @@ import { extractAssetListFromManager } from "./preloader/extractAssetListFromMan
|
|
|
9
9
|
import { assert } from "../../core/assert.js";
|
|
10
10
|
import { HashSet } from "../../core/collection/set/HashSet.js";
|
|
11
11
|
import { CrossOriginConfig } from "./CORS/CrossOriginConfig.js";
|
|
12
|
-
import { array_remove_element } from "../../core/collection/array/array_remove_element.js";
|
|
13
12
|
import { AssetDescription } from "./AssetDescription.js";
|
|
14
13
|
import { noop } from "../../core/function/Functions.js";
|
|
15
14
|
import { Deque } from "../../core/collection/queue/Deque.js";
|
|
@@ -23,6 +22,7 @@ import ConcurrentExecutor from "../../core/process/executor/ConcurrentExecutor.j
|
|
|
23
22
|
import { AssetLoader } from "./loaders/AssetLoader.js";
|
|
24
23
|
import { array_push_if_unique } from "../../core/collection/array/array_push_if_unique.js";
|
|
25
24
|
import { AssetRequestScope } from "./AssetRequestScope.js";
|
|
25
|
+
import { array_remove_first } from "../../core/collection/array/array_remove_first.js";
|
|
26
26
|
|
|
27
27
|
|
|
28
28
|
class Response {
|
|
@@ -701,7 +701,7 @@ export class AssetManager {
|
|
|
701
701
|
return false;
|
|
702
702
|
}
|
|
703
703
|
|
|
704
|
-
if (!
|
|
704
|
+
if (!array_remove_first(transformers, transformer)) {
|
|
705
705
|
// not found
|
|
706
706
|
return false;
|
|
707
707
|
}
|
|
@@ -202,7 +202,7 @@ EntityManager.prototype.detachDataSet = function () {
|
|
|
202
202
|
};
|
|
203
203
|
|
|
204
204
|
/**
|
|
205
|
-
*
|
|
205
|
+
* Get list of all components referenced by active systems
|
|
206
206
|
* @returns {Class[]}
|
|
207
207
|
*/
|
|
208
208
|
EntityManager.prototype.getComponentTypeMap = function () {
|
|
@@ -237,6 +237,12 @@ EntityManager.prototype.getComponentTypeMap = function () {
|
|
|
237
237
|
EntityManager.prototype.attachDataSet = function (dataset) {
|
|
238
238
|
//check if another dataset is attached
|
|
239
239
|
if (this.dataset !== null) {
|
|
240
|
+
|
|
241
|
+
if (this.dataset === dataset) {
|
|
242
|
+
// special case, we already have this dataset attached. Nothing to more to do
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
|
|
240
246
|
throw new Error("Illegal status, another dataset is currently attached");
|
|
241
247
|
}
|
|
242
248
|
|
|
@@ -285,6 +291,7 @@ EntityManager.prototype.getSystem = function (systemClass) {
|
|
|
285
291
|
|
|
286
292
|
|
|
287
293
|
/**
|
|
294
|
+
* @deprecated use {@link EntityComponentDataset.getComponentClassByName} instead
|
|
288
295
|
* @template T
|
|
289
296
|
* @param {string} className
|
|
290
297
|
* @returns {null|Class<T>}
|