@woosh/meep-engine 2.49.9 → 2.50.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/actions/concrete/ArrayCopyAction.js +1 -1
- package/package.json +1 -1
- package/src/core/binary/BinaryBuffer.js +1 -1
- package/src/core/binary/BinaryBuffer.spec.js +128 -0
- package/src/core/binary/int32_to_binary_string.js +4 -1
- package/src/core/binary/int32_to_binary_string.spec.js +9 -0
- package/src/core/bvh2/BinaryNode.js +0 -30
- package/src/core/bvh2/binary/2/BinaryUint32BVH.js +1 -1
- package/src/core/bvh2/binary/IndexedBinaryBVH.js +1 -1
- package/src/core/bvh2/bvh3/ExplicitBinaryBoundingVolumeHierarchy.js +1 -1
- package/src/core/bvh2/bvh3/query/compute_tight_near_far_clipping_planes.js +1 -1
- package/src/core/cache/Cache.js +31 -29
- package/src/core/cache/Cache.spec.js +4 -1
- package/src/core/collection/HashMap.js +1 -1
- package/src/core/collection/array/{copyArray.js → array_copy.js} +1 -24
- package/src/core/collection/array/array_copy_entire.js +21 -0
- package/src/core/collection/array/typed/typed_array_copy.js +1 -1
- package/src/core/collection/queue/Deque.d.ts +4 -0
- package/src/core/collection/queue/Deque.js +5 -7
- package/src/core/collection/queue/Deque.spec.js +107 -0
- package/src/core/collection/table/RowFirstTable.js +1 -1
- package/src/core/geom/2d/aabb/AABB2.d.ts +14 -0
- package/src/core/geom/2d/aabb/AABB2.js +9 -7
- package/src/core/geom/2d/aabb/AABB2.spec.js +100 -0
- package/src/core/geom/2d/aabb/aabb2_compute_center_from_multiple.spec.js +11 -0
- package/src/core/geom/2d/aabb/aabb2_compute_overlap.spec.js +56 -0
- package/src/core/geom/2d/aabb/aabb2_contains.spec.js +40 -0
- package/src/core/geom/2d/bvh/Node2.js +1 -1
- package/src/core/geom/2d/convex-hull/fixed_convex_hull_humus.js +1 -1
- package/src/core/geom/2d/convex-hull/fixed_convex_hull_relaxation.js +1 -1
- package/src/core/geom/2d/line/line_segment_compute_line_segment_intersection_2d.js +35 -0
- package/src/core/geom/2d/line/line_segment_compute_line_segment_intersection_array_2d.js +51 -0
- package/src/core/geom/2d/line/line_segment_compute_line_segment_intersection_vectors_2d.js +15 -0
- package/src/core/geom/2d/line/line_segment_compute_line_segment_intersection_vectors_array_2d.js +30 -0
- package/src/core/geom/2d/line/line_segment_line_segment_intersection_exists_2d.js +29 -0
- package/src/core/geom/3d/aabb/AABB3.d.ts +4 -0
- package/src/core/geom/3d/aabb/AABB3.spec.js +30 -0
- package/src/core/geom/3d/aabb/aabb3_detailed_volume_intersection.js +4 -4
- package/src/core/geom/3d/frustum/frustum3_computeNearestPointToPoint.js +5 -5
- package/src/core/geom/3d/matrix/m4_make_translation.js +1 -1
- package/src/core/geom/3d/plane/is_point_within_planes.js +1 -1
- package/src/core/geom/3d/plane/lerp_planes_to_array.js +2 -0
- package/src/core/geom/3d/plane/{plane_computeConvex3PlaneIntersection.js → plane3_compute_convex_3_plane_intersection.js} +1 -1
- package/src/core/geom/3d/plane/{plane3_computeLineSegmentIntersection.js → plane3_compute_line_segment_intersection.js} +1 -1
- package/src/core/geom/3d/plane/{computePlanePlaneIntersection.js → plane3_compute_plane_intersection.js} +15 -11
- package/src/core/geom/3d/plane/{computePlaneLineIntersection.js → plane3_compute_ray_intersection.js} +5 -1
- package/src/core/geom/3d/plane/plane3_intersect_plane.js +14 -0
- package/src/core/geom/3d/plane/{plane_three_compute_convex3_plane_intersection.js → plane3_three_compute_convex_3_plane_intersection.js} +7 -4
- package/src/core/geom/3d/plane/planeRayIntersection.js +2 -2
- package/src/core/geom/3d/sphere/harmonics/sh3_dering_optimize_positive.js +1 -1
- package/src/core/geom/3d/tetrahedra/TetrahedralMesh.js +1 -1
- package/src/core/geom/3d/tetrahedra/compute_bounding_simplex_3d.js +5 -5
- package/src/core/geom/3d/tetrahedra/compute_circumsphere.js +1 -1
- package/src/core/geom/3d/tetrahedra/delaunay/fill_in_a_cavity.js +1 -1
- package/src/core/geom/3d/topology/bounds/computeTriangleClusterNormalBoundingCone.js +1 -1
- package/src/core/geom/3d/topology/expandConnectivityByLocality.js +1 -1
- package/src/core/geom/3d/topology/struct/binary/BinaryTopology.js +1 -1
- package/src/core/geom/Quaternion.d.ts +11 -0
- package/src/core/geom/Quaternion.js +36 -27
- package/src/core/geom/Quaternion.spec.js +141 -0
- package/src/core/geom/Vector2.d.ts +5 -1
- package/src/core/geom/Vector2.js +24 -0
- package/src/core/geom/Vector3.d.ts +6 -0
- package/src/core/geom/Vector3.spec.js +60 -0
- package/src/core/graph/GraphUtils.js +4 -2
- package/src/core/graph/layout/CircleLayout.js +4 -2
- package/src/core/math/vector_nd_dot.js +16 -0
- package/src/core/math/{normalizeArrayVector.js → vector_nd_normalize.js} +3 -3
- package/src/core/math/{normalizeArrayVector.spec.js → vector_nd_normalize.spec.js} +3 -3
- package/src/core/process/PromiseWatcher.spec.js +1 -1
- package/src/engine/animation/curve/compression/downsample_float_array_curve_by_error.js +1 -1
- package/src/engine/ecs/EntityBlueprint.d.ts +14 -0
- package/src/engine/ecs/EntityBlueprint.js +2 -2
- package/src/engine/ecs/EntityBlueprint.spec.js +52 -0
- package/src/engine/ecs/EntityBuilder.js +8 -0
- package/src/engine/ecs/EntityManager.d.ts +1 -0
- package/src/engine/ecs/EntityManager.js +17 -213
- package/src/engine/ecs/EntityManager.spec.js +62 -1
- package/src/engine/ecs/System.js +8 -2
- package/src/engine/ecs/fow/FogOfWar.js +1 -1
- package/src/engine/ecs/guid/GUID.js +1 -1
- package/src/engine/ecs/terrain/ecs/splat/SplatMapping.js +1 -1
- package/src/engine/ecs/terrain/overlay/TerrainOverlay.js +1 -1
- package/src/engine/ecs/terrain/tiles/TerrainTile.js +1 -1
- package/src/engine/ecs/transform/Transform.d.ts +2 -0
- package/src/engine/ecs/transform/Transform.spec.js +63 -0
- package/src/engine/ecs/transform-attachment/TransformAttachment.d.ts +17 -1
- package/src/engine/ecs/transform-attachment/TransformAttachment.js +12 -2
- package/src/engine/ecs/transform-attachment/TransformAttachment.spec.js +103 -0
- package/src/engine/graphics/ecs/camera/Camera.js +2 -2
- package/src/engine/graphics/ecs/path/entity/EntityPath.js +1 -1
- package/src/engine/graphics/ecs/path/tube/build/computeFrenetFrames.js +1 -1
- package/src/engine/graphics/geometry/MikkT/GenerateTSpaces.js +1 -1
- package/src/engine/graphics/geometry/MikkT/m_getNormal.js +1 -1
- package/src/engine/graphics/geometry/MikkT/m_getTexCoord.js +1 -1
- package/src/engine/graphics/geometry/bvh/buffered/BVHGeometryRaycaster.js +1 -1
- package/src/engine/graphics/geometry/instancing/InstancedMeshGroup.js +1 -1
- package/src/engine/graphics/geometry/optimization/merge/merge_geometry_hierarchy.js +1 -1
- package/src/engine/graphics/impostors/octahedral/util/build_cutout_from_atlas_by_alpha.js +1 -1
- package/src/engine/graphics/particles/particular/engine/utils/volume/AttributeValue.js +1 -1
- package/src/engine/graphics/render/Lines.js +1 -1
- package/src/engine/graphics/render/buffer/simple-fx/taa/TemporalSupersamplingRenderPlugin.js +1 -1
- package/src/engine/graphics/render/forward_plus/LightManager.js +1 -1
- package/src/engine/graphics/render/forward_plus/computeFrustumCorners.js +10 -10
- package/src/engine/graphics/render/forward_plus/model/Decal.js +1 -1
- package/src/engine/graphics/render/forward_plus/prototype/prototypeLightManager.js +1 -1
- package/src/engine/graphics/render/gizmo/GizmoShapeRenderingInterface.js +1 -1
- package/src/engine/graphics/render/layers/RenderLayerUtils.js +3 -3
- package/src/engine/graphics/render/view/CameraView.js +1 -1
- package/src/engine/graphics/render/visibility/hiz/query/BatchOcclusionQuery.js +1 -1
- package/src/engine/graphics/render/webgpu/sample/MeshInstance.js +1 -1
- package/src/engine/graphics/sh3/LightProbeVolume.js +1 -1
- package/src/engine/graphics/sh3/path_tracer/PathTracedMesh.js +1 -1
- package/src/engine/graphics/sh3/path_tracer/PathTracer.js +1 -1
- package/src/engine/graphics/sh3/path_tracer/make_sky_hosek.js +1 -1
- package/src/engine/graphics/sh3/prototypeSH3Probe.js +1 -1
- package/src/engine/graphics/texture/3d/scs3d_read_2d_slice.js +1 -1
- package/src/engine/graphics/texture/CanvasClone.js +5 -1
- package/src/engine/graphics/texture/sampler/Sampler2D.js +14 -75
- package/src/engine/graphics/texture/sampler/bicubic.js +19 -19
- package/src/engine/graphics/texture/sampler/convertSampler2D2DataURL.spec.js +10 -0
- package/src/engine/graphics/texture/sampler/copy_Sampler2D_channel_data.spec.js +90 -0
- package/src/engine/graphics/texture/sampler/differenceSampler.js +13 -8
- package/src/engine/graphics/texture/sampler/distance/computeSignedDistanceField_Chamfer.js +140 -0
- package/src/engine/graphics/texture/sampler/distance/computeSignedDistanceField_NaiveFlood.js +130 -0
- package/src/engine/graphics/texture/sampler/distance/computeUnsignedDistanceField.js +10 -0
- package/src/engine/graphics/texture/sampler/distance/computeUnsignedDistanceField.spec.js +183 -0
- package/src/engine/graphics/texture/sampler/distance/computeUnsignedDistanceField_Chamfer.js +133 -0
- package/src/engine/graphics/texture/sampler/filter/mitchell.js +4 -0
- package/src/engine/graphics/texture/sampler/loadSampler2D.js +5 -2
- package/src/engine/graphics/texture/sampler/resize/sampler2d_downsample_mipmap.js +8 -3
- package/src/engine/graphics/texture/sampler/resize/sampler2d_downsample_mipmap.spec.js +13 -0
- package/src/engine/graphics/texture/sampler/sampler2d_channel_compute_min_indices.js +58 -0
- package/src/engine/graphics/trail/TemporalPath.js +0 -36
- package/src/engine/intelligence/behavior/composite/ParallelBehavior.spec.js +12 -12
- package/src/engine/intelligence/behavior/composite/SequenceBehavior.spec.js +17 -0
- package/src/engine/intelligence/behavior/primitive/SucceedingBehavior.js +3 -1
- package/src/engine/knowledge/database/StaticKnowledgeDataTable.d.ts +7 -1
- package/src/engine/knowledge/database/StaticKnowledgeDataTable.spec.js +21 -0
- package/src/engine/knowledge/database/StaticKnowledgeDataTableDescriptor.d.ts +2 -2
- package/src/engine/logging/ConsoleLoggerBackend.js +4 -0
- package/src/engine/logging/VoidLoggerBackend.js +12 -0
- package/src/engine/navigation/ecs/components/computeCatmullRomSpline.js +1 -1
- package/src/engine/navigation/ecs/components/computeCatmullRomSplineUniformDistance.js +1 -1
- package/src/engine/physics/cannon/CannonJSPhysicsSystem.js +1 -1
- package/src/engine/save/GameStateLoader.js +1 -1
- package/src/engine/scene/Scene.d.ts +2 -0
- package/src/engine/scene/Scene.js +2 -2
- package/src/engine/scene/Scene.spec.js +20 -0
- package/src/engine/scene/SceneManager.d.ts +4 -0
- package/src/engine/scene/SceneManager.js +46 -23
- package/src/engine/scene/SceneManager.spec.js +131 -0
- package/src/engine/sound/material/detector/terrain/TerrainSoundMaterialSurfaceDetector.js +2 -2
- package/src/engine/ui/GUIEngine.js +1 -1
- package/src/generation/grid/GridData.js +8 -2
- package/src/generation/grid/GridData.spec.js +5 -0
- package/src/generation/grid/generation/util/buildUnsignedDistanceField.js +3 -1
- package/src/generation/markers/MarkerNode.js +2 -2
- package/src/generation/markers/actions/MarkerNodeActionEntityPlacement.js +1 -1
- package/src/generation/theme/AreaMask.js +3 -1
- package/src/view/elements/progress/RectangularPieProgressView.js +8 -6
- package/src/view/minimap/dom/MinimapCameraView.js +3 -3
- package/src/core/geom/2d/LineSegment2.js +0 -175
- package/src/core/geom/3d/plane/computePlaneRayIntersection.js +0 -55
- package/src/core/geom/Matrix4.js +0 -275
- package/src/engine/graphics/texture/sampler/distanceField.js +0 -411
- package/src/engine/graphics/texture/sampler/distanceField.spec.js +0 -184
- package/src/engine/physics/cannon/cannon.min.js +0 -27
- package/src/generation/grid/MarkerMatchCounter.js +0 -25
- /package/src/engine/physics/spring/{Spring.js → computeHookeForce.js} +0 -0
|
@@ -45,3 +45,63 @@ test('addVectors', () => {
|
|
|
45
45
|
expect(ut.y).toBe(14);
|
|
46
46
|
expect(ut.z).toBe(18);
|
|
47
47
|
});
|
|
48
|
+
|
|
49
|
+
test("equals", () => {
|
|
50
|
+
expect(new Vector3(1, -2, 3).equals(new Vector3(1, -2, 3)))
|
|
51
|
+
.toBe(true);
|
|
52
|
+
|
|
53
|
+
expect(new Vector3(1, -2, 3).equals(new Vector3(5, -2, 3)))
|
|
54
|
+
.toBe(false);
|
|
55
|
+
|
|
56
|
+
expect(new Vector3(1, -2, 3).equals(new Vector3(1, 5, 3)))
|
|
57
|
+
.toBe(false);
|
|
58
|
+
|
|
59
|
+
expect(new Vector3(1, -2, 3).equals(new Vector3(1, -2, 5)))
|
|
60
|
+
.toBe(false);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
test("roughlyEquals", () => {
|
|
64
|
+
expect(new Vector3(1, -2, 3).roughlyEquals(new Vector3(1, -2, 3), 0))
|
|
65
|
+
.toBe(true);
|
|
66
|
+
|
|
67
|
+
expect(new Vector3(1, -2, 3).roughlyEquals(new Vector3(1, -2, 3), 0.1))
|
|
68
|
+
.toBe(true);
|
|
69
|
+
|
|
70
|
+
expect(new Vector3(1, -2, 3).roughlyEquals(new Vector3(1.01, -2, 3), 0.1))
|
|
71
|
+
.toBe(true);
|
|
72
|
+
|
|
73
|
+
expect(new Vector3(1, -2, 3).roughlyEquals(new Vector3(0.99, -2, 3), 0.1))
|
|
74
|
+
.toBe(true);
|
|
75
|
+
|
|
76
|
+
expect(new Vector3(1, -2, 3).roughlyEquals(new Vector3(0.89, -2, 3), 0.1))
|
|
77
|
+
.toBe(false);
|
|
78
|
+
|
|
79
|
+
expect(new Vector3(1, -2, 3).roughlyEquals(new Vector3(1.11, -2, 3), 0.1))
|
|
80
|
+
.toBe(false);
|
|
81
|
+
|
|
82
|
+
// Y
|
|
83
|
+
expect(new Vector3(1, -2, 3).roughlyEquals(new Vector3(1, -2.01, 3), 0.1))
|
|
84
|
+
.toBe(true);
|
|
85
|
+
|
|
86
|
+
expect(new Vector3(1, -2, 3).roughlyEquals(new Vector3(1, -1.99, 3), 0.1))
|
|
87
|
+
.toBe(true);
|
|
88
|
+
|
|
89
|
+
expect(new Vector3(1, -2, 3).roughlyEquals(new Vector3(1, -2.11, 3), 0.1))
|
|
90
|
+
.toBe(false);
|
|
91
|
+
|
|
92
|
+
expect(new Vector3(1, -2, 3).roughlyEquals(new Vector3(1, -1.89, 3), 0.1))
|
|
93
|
+
.toBe(false);
|
|
94
|
+
|
|
95
|
+
// Z
|
|
96
|
+
expect(new Vector3(1, -2, 3).roughlyEquals(new Vector3(1, -2, 3.01), 0.1))
|
|
97
|
+
.toBe(true);
|
|
98
|
+
|
|
99
|
+
expect(new Vector3(1, -2, 3).roughlyEquals(new Vector3(1, -2, 2.99), 0.1))
|
|
100
|
+
.toBe(true);
|
|
101
|
+
|
|
102
|
+
expect(new Vector3(1, -2, 3).roughlyEquals(new Vector3(1, -2, 2.89), 0.1))
|
|
103
|
+
.toBe(false);
|
|
104
|
+
|
|
105
|
+
expect(new Vector3(1, -2, 3).roughlyEquals(new Vector3(1, -2, 3.11), 0.1))
|
|
106
|
+
.toBe(false);
|
|
107
|
+
});
|
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
line_segment_compute_line_segment_intersection_vectors_array_2d
|
|
8
|
+
} from "../geom/2d/line/line_segment_compute_line_segment_intersection_vectors_array_2d.js";
|
|
7
9
|
|
|
8
10
|
const Utils = {};
|
|
9
11
|
|
|
@@ -155,7 +157,7 @@ function graph2paths(graph, thickness) {
|
|
|
155
157
|
const l = edges.length;
|
|
156
158
|
for (; i < l; i++) {
|
|
157
159
|
const edge = edges[i];
|
|
158
|
-
if (
|
|
160
|
+
if (line_segment_compute_line_segment_intersection_vectors_array_2d(from, to, edge.first, edge.second)) {
|
|
159
161
|
return true;
|
|
160
162
|
}
|
|
161
163
|
}
|
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
import { assert } from "../../assert.js";
|
|
7
7
|
import Circle from "../../geom/2d/circle/Circle.js";
|
|
8
8
|
import AABB2 from "../../geom/2d/aabb/AABB2.js";
|
|
9
|
-
import { line2SegmentsIntersect } from "../../geom/2d/LineSegment2.js";
|
|
10
9
|
import Vector2, { v2_distance } from "../../geom/Vector2.js";
|
|
11
10
|
import { max2 } from "../../math/max2.js";
|
|
12
11
|
import { min2 } from "../../math/min2.js";
|
|
@@ -14,6 +13,9 @@ import { computeDisconnectedSubGraphs } from "./computeDisconnectedSubGraphs.js"
|
|
|
14
13
|
import { Connection } from "./Connection.js";
|
|
15
14
|
import { resolveAABB2Overlap } from "./box/resolveAABB2Overlap.js";
|
|
16
15
|
import { applyCentralGravityAABB2 } from "./box/applyCentralGravityAABB2.js";
|
|
16
|
+
import {
|
|
17
|
+
line_segment_line_segment_intersection_exists_2d
|
|
18
|
+
} from "../../geom/2d/line/line_segment_line_segment_intersection_exists_2d.js";
|
|
17
19
|
|
|
18
20
|
|
|
19
21
|
/**
|
|
@@ -364,7 +366,7 @@ function computeNumberOfCrossOvers(edges, numEdges) {
|
|
|
364
366
|
const b0 = e1.source;
|
|
365
367
|
const b1 = e1.target;
|
|
366
368
|
|
|
367
|
-
if (
|
|
369
|
+
if (line_segment_line_segment_intersection_exists_2d(
|
|
368
370
|
a0.x, a0.y,
|
|
369
371
|
a1.x, a1.y,
|
|
370
372
|
b0.x, b0.y,
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* N-dimensional vector dot product
|
|
3
|
+
* @param {number[]|Float32Array|Float64Array} a
|
|
4
|
+
* @param {number[]|Float32Array|Float64Array} b
|
|
5
|
+
* @param {number} n number of dimensions
|
|
6
|
+
* @return {number}
|
|
7
|
+
*/
|
|
8
|
+
export function vector_nd_dot(a, b, n) {
|
|
9
|
+
let result = 0;
|
|
10
|
+
|
|
11
|
+
for (let i = 0; i < n; i++) {
|
|
12
|
+
result += a[i] * b[i]
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
return result;
|
|
16
|
+
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Assuming the input is an N-dimension vector, normalizes the vector to magnitude of 1
|
|
3
|
-
* @param {number[]|Float32Array} result
|
|
4
|
-
* @param {number[]|Float32Array} data
|
|
3
|
+
* @param {number[]|Float32Array|Float64Array} result
|
|
4
|
+
* @param {number[]|Float32Array|Float64Array} data
|
|
5
5
|
* @param {number} [length] number of dimensions
|
|
6
6
|
*/
|
|
7
|
-
export function
|
|
7
|
+
export function vector_nd_normalize(result, data, length = data.length) {
|
|
8
8
|
|
|
9
9
|
let magnitude2 = 0;
|
|
10
10
|
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { vector_nd_normalize } from "./vector_nd_normalize.js";
|
|
2
2
|
|
|
3
3
|
test("1d vector normalization", () => {
|
|
4
4
|
const v = [7];
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
vector_nd_normalize(v, v, 1);
|
|
7
7
|
|
|
8
8
|
expect(v[0]).toBeCloseTo(1);
|
|
9
9
|
|
|
10
10
|
v[0] = -13;
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
vector_nd_normalize(v, v, 1);
|
|
13
13
|
|
|
14
14
|
expect(v[0]).toBeCloseTo(-1);
|
|
15
15
|
});
|
|
@@ -6,7 +6,7 @@ import { lerp } from "../../../../core/math/lerp.js";
|
|
|
6
6
|
import { min3 } from "../../../../core/math/min3.js";
|
|
7
7
|
import { max3 } from "../../../../core/math/max3.js";
|
|
8
8
|
import { downsample_float_array } from "./downsample_float_array.js";
|
|
9
|
-
import { array_copy } from "../../../../core/collection/array/
|
|
9
|
+
import { array_copy } from "../../../../core/collection/array/array_copy.js";
|
|
10
10
|
import { isPowerOfTwo } from "../../../../core/math/isPowerOrTwo.js";
|
|
11
11
|
|
|
12
12
|
/**
|
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
import EntityBuilder from "./EntityBuilder";
|
|
2
|
+
|
|
3
|
+
interface Type<T> extends Function {
|
|
4
|
+
new(...args: any[]): T;
|
|
5
|
+
}
|
|
6
|
+
|
|
1
7
|
export class EntityBlueprint {
|
|
2
8
|
static from(components: any[]): EntityBlueprint
|
|
9
|
+
|
|
10
|
+
add<T>(component: T): void
|
|
11
|
+
|
|
12
|
+
addJSON<T>(klass: Type<T>, json: any): void
|
|
13
|
+
|
|
14
|
+
clear(): void
|
|
15
|
+
|
|
16
|
+
build(seed?: object): EntityBuilder
|
|
3
17
|
}
|
|
@@ -140,10 +140,10 @@ export class EntityBlueprint {
|
|
|
140
140
|
|
|
141
141
|
|
|
142
142
|
/**
|
|
143
|
-
*
|
|
143
|
+
* @param {object} [templateSeed]
|
|
144
144
|
* @return {EntityBuilder}
|
|
145
145
|
*/
|
|
146
|
-
|
|
146
|
+
build(templateSeed) {
|
|
147
147
|
const eb = new EntityBuilder();
|
|
148
148
|
|
|
149
149
|
this.componentnts.forEach((template, ComponentClass) => {
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { EntityBlueprint } from "./EntityBlueprint.js";
|
|
2
|
+
import EntityBuilder from "./EntityBuilder.js";
|
|
3
|
+
|
|
4
|
+
test("constructor does not throw", () => {
|
|
5
|
+
|
|
6
|
+
expect(() => new EntityBlueprint()).not.toThrow();
|
|
7
|
+
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
test("build empty", () => {
|
|
11
|
+
const blueprint = new EntityBlueprint();
|
|
12
|
+
|
|
13
|
+
const entity = blueprint.build();
|
|
14
|
+
|
|
15
|
+
expect(entity).toBeDefined();
|
|
16
|
+
expect(entity).toBeInstanceOf(EntityBuilder);
|
|
17
|
+
expect(entity.count).toEqual(0);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
class DummyComponent {
|
|
21
|
+
a = 0
|
|
22
|
+
|
|
23
|
+
fromJSON({ a }) {
|
|
24
|
+
this.a = a;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
test("a copy of the added component ends up on built entity", () => {
|
|
29
|
+
|
|
30
|
+
const blueprint = new EntityBlueprint();
|
|
31
|
+
|
|
32
|
+
blueprint.addJSON(DummyComponent, { a: 7 });
|
|
33
|
+
|
|
34
|
+
const entity = blueprint.build();
|
|
35
|
+
|
|
36
|
+
const retrieved = entity.getComponent(DummyComponent);
|
|
37
|
+
|
|
38
|
+
expect(retrieved).toBeInstanceOf(DummyComponent);
|
|
39
|
+
expect(retrieved.a).toEqual(7);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
test("seed template", () => {
|
|
43
|
+
const blueprint = new EntityBlueprint();
|
|
44
|
+
|
|
45
|
+
blueprint.addJSON(DummyComponent, { a: '$x' });
|
|
46
|
+
|
|
47
|
+
const entity = blueprint.build({ x: 13 });
|
|
48
|
+
|
|
49
|
+
const component = entity.getComponent(DummyComponent);
|
|
50
|
+
|
|
51
|
+
expect(component.a).toEqual(13);
|
|
52
|
+
});
|
|
@@ -329,6 +329,9 @@ EntityManager.prototype.simulate = function (timeDelta) {
|
|
|
329
329
|
const fixed_step = this.fixedUpdateStepSize;
|
|
330
330
|
const accumulatedTime = this.systemAccumulatedFixedStepTime;
|
|
331
331
|
|
|
332
|
+
assert.notNaN(fixed_step, 'fixed_step');
|
|
333
|
+
assert.greaterThan(fixed_step, 0, 'fixed_step must be greater than 0');
|
|
334
|
+
|
|
332
335
|
for (let i = 0; i < system_count; i++) {
|
|
333
336
|
|
|
334
337
|
const system = systems[i];
|
|
@@ -337,7 +340,7 @@ EntityManager.prototype.simulate = function (timeDelta) {
|
|
|
337
340
|
let accumulated_time = accumulatedTime.get(system) + timeDelta;
|
|
338
341
|
|
|
339
342
|
|
|
340
|
-
while (accumulated_time
|
|
343
|
+
while (accumulated_time >= fixed_step) {
|
|
341
344
|
|
|
342
345
|
try {
|
|
343
346
|
system.fixedUpdate(fixed_step)
|
|
@@ -458,9 +461,10 @@ function validateSystem(system) {
|
|
|
458
461
|
/**
|
|
459
462
|
* If the {@link EntityManager} is already started, the system will be started automatically before being added
|
|
460
463
|
* @param {System} system
|
|
464
|
+
* @returns {Promise}
|
|
461
465
|
* @throws {IllegalStateException}
|
|
462
466
|
*/
|
|
463
|
-
EntityManager.prototype.addSystem =
|
|
467
|
+
EntityManager.prototype.addSystem = function (system) {
|
|
464
468
|
assert.defined(system, "system");
|
|
465
469
|
assert.isInstanceOf(system, System, 'system', 'System');
|
|
466
470
|
|
|
@@ -469,7 +473,7 @@ EntityManager.prototype.addSystem = async function (system) {
|
|
|
469
473
|
if (existing !== null) {
|
|
470
474
|
if (existing === system) {
|
|
471
475
|
//system already added, do nothing
|
|
472
|
-
return;
|
|
476
|
+
return Promise.resolve();
|
|
473
477
|
} else {
|
|
474
478
|
throw new IllegalStateException(`Another instance of system '${computeSystemName(system)}' is already registered`);
|
|
475
479
|
}
|
|
@@ -508,7 +512,7 @@ EntityManager.prototype.addSystem = async function (system) {
|
|
|
508
512
|
if (this.state === EntityManagerState.Running) {
|
|
509
513
|
//initialize the system
|
|
510
514
|
startup_promise = new Promise((resolve, reject) => {
|
|
511
|
-
|
|
515
|
+
this.startSystem(system, resolve, reject);
|
|
512
516
|
});
|
|
513
517
|
} else {
|
|
514
518
|
startup_promise = Promise.resolve();
|
|
@@ -526,13 +530,13 @@ EntityManager.prototype.addSystem = async function (system) {
|
|
|
526
530
|
|
|
527
531
|
this.on.systemAdded.send1(system);
|
|
528
532
|
|
|
529
|
-
|
|
533
|
+
return startup_promise;
|
|
530
534
|
};
|
|
531
535
|
|
|
532
536
|
/**
|
|
533
537
|
*
|
|
534
538
|
* @param {System} system
|
|
535
|
-
* @returns {boolean}
|
|
539
|
+
* @returns {Promise<boolean>}
|
|
536
540
|
*/
|
|
537
541
|
EntityManager.prototype.removeSystem = async function (system) {
|
|
538
542
|
assert.defined(system, "system");
|
|
@@ -573,11 +577,13 @@ EntityManager.prototype.removeSystem = async function (system) {
|
|
|
573
577
|
this.systemAccumulatedFixedStepTime.delete(system);
|
|
574
578
|
|
|
575
579
|
this.on.systemRemoved.send1(system);
|
|
580
|
+
|
|
581
|
+
return true;
|
|
576
582
|
};
|
|
577
583
|
|
|
578
584
|
|
|
579
585
|
/**
|
|
580
|
-
*
|
|
586
|
+
* @private
|
|
581
587
|
* @param {System} system
|
|
582
588
|
* @param {function(system: System)} successCallback
|
|
583
589
|
* @param {function(reason:*)} errorCallback
|
|
@@ -614,13 +620,15 @@ EntityManager.prototype.stopSystem = function (system, successCallback, errorCal
|
|
|
614
620
|
};
|
|
615
621
|
|
|
616
622
|
/**
|
|
617
|
-
*
|
|
623
|
+
* @private
|
|
618
624
|
* @param {System} system
|
|
619
625
|
* @param {function(system: System)} successCallback
|
|
620
626
|
* @param {function(reason:*)} errorCallback
|
|
621
627
|
*/
|
|
622
628
|
EntityManager.prototype.startSystem = function (system, successCallback, errorCallback) {
|
|
623
629
|
assert.defined(system, "system");
|
|
630
|
+
assert.isFunction(successCallback, "successCallback");
|
|
631
|
+
assert.isFunction(errorCallback, "errorCallback");
|
|
624
632
|
|
|
625
633
|
if (system.state.getValue() === System.State.RUNNING) {
|
|
626
634
|
//system is already running
|
|
@@ -831,7 +839,7 @@ EntityManager.prototype.shutdown = function (readyCallback, errorCallback) {
|
|
|
831
839
|
|
|
832
840
|
system.state.set(System.State.STOPPED);
|
|
833
841
|
|
|
834
|
-
self.on.systemStopped.
|
|
842
|
+
self.on.systemStopped.send1(system);
|
|
835
843
|
if (readyCount === expectedReadyCount) {
|
|
836
844
|
finalizeShutdown();
|
|
837
845
|
}
|
|
@@ -870,210 +878,6 @@ EntityManager.prototype.shutdown = function (readyCallback, errorCallback) {
|
|
|
870
878
|
});
|
|
871
879
|
};
|
|
872
880
|
|
|
873
|
-
|
|
874
|
-
/**
|
|
875
|
-
* @deprecated
|
|
876
|
-
* @returns {number}
|
|
877
|
-
*/
|
|
878
|
-
EntityManager.prototype.createEntity = function () {
|
|
879
|
-
console.warn("EntityManager.createEntity is deprecated");
|
|
880
|
-
|
|
881
|
-
return this.dataset.createEntity();
|
|
882
|
-
};
|
|
883
|
-
|
|
884
|
-
/**
|
|
885
|
-
* @deprecated
|
|
886
|
-
* @param id
|
|
887
|
-
*/
|
|
888
|
-
EntityManager.prototype.createEntitySpecific = function (id) {
|
|
889
|
-
console.warn("EntityManager.createEntitySpecific is deprecated");
|
|
890
|
-
this.dataset.createEntitySpecific(id);
|
|
891
|
-
};
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
/**
|
|
895
|
-
* @deprecated
|
|
896
|
-
* Remove association of specified component type from entity
|
|
897
|
-
* @param {Number} entityId
|
|
898
|
-
* @param {Number} componentType
|
|
899
|
-
*/
|
|
900
|
-
EntityManager.prototype.removeComponentFromEntity = function (entityId, componentType) {
|
|
901
|
-
console.warn("EntityManager.removeComponentFromEntity is deprecated");
|
|
902
|
-
|
|
903
|
-
this.dataset.removeComponentFromEntityByIndex(entityId, componentType);
|
|
904
|
-
};
|
|
905
|
-
|
|
906
|
-
/**
|
|
907
|
-
* @deprecated use dataset directly
|
|
908
|
-
* Retrieves component instance associated with entity
|
|
909
|
-
* @template T
|
|
910
|
-
* @param {Number} entityId
|
|
911
|
-
* @param {class.<T>} componentClass
|
|
912
|
-
* @returns {T|null}
|
|
913
|
-
* @nosideeffects
|
|
914
|
-
*/
|
|
915
|
-
EntityManager.prototype.getComponent = function (entityId, componentClass) {
|
|
916
|
-
console.warn("EntityManager.getComponent is deprecated");
|
|
917
|
-
|
|
918
|
-
return this.dataset.getComponent(entityId, componentClass);
|
|
919
|
-
};
|
|
920
|
-
|
|
921
|
-
/**
|
|
922
|
-
* @deprecated use {@link EntityComponentDataset.entityExists} instead
|
|
923
|
-
* @param {number} entityIndex
|
|
924
|
-
* @returns {boolean}
|
|
925
|
-
*/
|
|
926
|
-
EntityManager.prototype.entityExists = function (entityIndex) {
|
|
927
|
-
console.warn("EntityManager.entityExists is deprecated");
|
|
928
|
-
if (this.dataset === null) {
|
|
929
|
-
//no dataset - no entities
|
|
930
|
-
return false;
|
|
931
|
-
}
|
|
932
|
-
return this.dataset.entityExists(entityIndex);
|
|
933
|
-
};
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
/**
|
|
937
|
-
* @deprecated Use {@link EntityManager#dataset} direction
|
|
938
|
-
* @param entity
|
|
939
|
-
* @returns {Array}
|
|
940
|
-
*/
|
|
941
|
-
EntityManager.prototype.getComponents = function (entity) {
|
|
942
|
-
console.warn("EntityManager.getComponents is deprecated");
|
|
943
|
-
|
|
944
|
-
return this.dataset.getAllComponents(entity);
|
|
945
|
-
};
|
|
946
|
-
|
|
947
|
-
/**
|
|
948
|
-
* @deprecated
|
|
949
|
-
* Retrieves component instance associated with entity
|
|
950
|
-
* @param {Number} entityId
|
|
951
|
-
* @param {Number} componentType
|
|
952
|
-
* @returns {*|undefined} component of specified type or undefined if it was not found
|
|
953
|
-
*/
|
|
954
|
-
EntityManager.prototype.getComponentByType = function (entityId, componentType) {
|
|
955
|
-
console.warn("EntityManager.getComponentByType is deprecated");
|
|
956
|
-
return this.dataset.getComponentByIndex(entityId, componentType);
|
|
957
|
-
};
|
|
958
|
-
|
|
959
|
-
/**
|
|
960
|
-
* @deprecated
|
|
961
|
-
* does traversal on a subset of entities which have specified components.
|
|
962
|
-
* @example traverseEntities([Transform,Renderable,Tag],function(transform, renderable, tag, entity){ ... }, this);
|
|
963
|
-
* @param {Array.<class>} classes
|
|
964
|
-
* @param {Function} callback
|
|
965
|
-
* @param {Object} [thisArg] specifies context object on which callbacks are to be called, optional
|
|
966
|
-
*/
|
|
967
|
-
EntityManager.prototype.traverseEntities = function (classes, callback, thisArg) {
|
|
968
|
-
console.warn("EntityManager.traverseEntities is deprecated");
|
|
969
|
-
|
|
970
|
-
if (this.dataset === null) {
|
|
971
|
-
//no data to traverse
|
|
972
|
-
return;
|
|
973
|
-
}
|
|
974
|
-
this.dataset.traverseEntities(classes, callback, thisArg);
|
|
975
|
-
};
|
|
976
|
-
|
|
977
|
-
/**
|
|
978
|
-
* @deprecated
|
|
979
|
-
* @param entity
|
|
980
|
-
* @param eventName
|
|
981
|
-
* @param listener
|
|
982
|
-
*/
|
|
983
|
-
EntityManager.prototype.addEntityEventListener = function (entity, eventName, listener) {
|
|
984
|
-
console.warn("EntityManager.addEntityEventListener is deprecated");
|
|
985
|
-
this.dataset.addEntityEventListener(entity, eventName, listener);
|
|
986
|
-
};
|
|
987
|
-
|
|
988
|
-
/**
|
|
989
|
-
* @deprecated
|
|
990
|
-
* @param {number} entity
|
|
991
|
-
* @param {string} eventName
|
|
992
|
-
* @param {function} listener
|
|
993
|
-
*/
|
|
994
|
-
EntityManager.prototype.removeEntityEventListener = function (entity, eventName, listener) {
|
|
995
|
-
console.warn("EntityManager.removeEntityEventListener is deprecated");
|
|
996
|
-
this.dataset.removeEntityEventListener(entity, eventName, listener);
|
|
997
|
-
};
|
|
998
|
-
|
|
999
|
-
/**
|
|
1000
|
-
* @deprecated use dataset directly instead
|
|
1001
|
-
* @param entity
|
|
1002
|
-
* @param eventName
|
|
1003
|
-
* @param event
|
|
1004
|
-
*/
|
|
1005
|
-
EntityManager.prototype.sendEvent = function (entity, eventName, event) {
|
|
1006
|
-
console.warn("EntityManager.sendEvent is deprecated");
|
|
1007
|
-
this.dataset.sendEvent(entity, eventName, event);
|
|
1008
|
-
};
|
|
1009
|
-
|
|
1010
|
-
/**
|
|
1011
|
-
* @deprecated
|
|
1012
|
-
* @param {function} klazz
|
|
1013
|
-
* @param {function(component: *, entity: number):boolean} callback
|
|
1014
|
-
* @param {*} [thisArg]
|
|
1015
|
-
* @deprecated
|
|
1016
|
-
*/
|
|
1017
|
-
EntityManager.prototype.traverseComponents = function (klazz, callback, thisArg) {
|
|
1018
|
-
console.warn("EntityManager.traverseComponents is deprecated");
|
|
1019
|
-
if (this.dataset !== null) {
|
|
1020
|
-
this.dataset.traverseComponents(klazz, callback, thisArg);
|
|
1021
|
-
}
|
|
1022
|
-
};
|
|
1023
|
-
|
|
1024
|
-
/**
|
|
1025
|
-
* @deprecated Use {@link #getSystem} instead
|
|
1026
|
-
* @template T,C
|
|
1027
|
-
* @param {C} klazz
|
|
1028
|
-
* @returns {System|T}
|
|
1029
|
-
*/
|
|
1030
|
-
EntityManager.prototype.getOwnerSystemByComponentClass = function (klazz) {
|
|
1031
|
-
|
|
1032
|
-
console.warn("EntityManager.getOwnerSystemByComponentClass is deprecated, use .getSystem instead");
|
|
1033
|
-
const index = this.getOwnerSystemIdByComponentClass(klazz);
|
|
1034
|
-
return this.systems[index];
|
|
1035
|
-
};
|
|
1036
|
-
|
|
1037
|
-
/**
|
|
1038
|
-
* @deprecated
|
|
1039
|
-
* @param {function} clazz
|
|
1040
|
-
* @returns {number} value >= 0, representing system Id, or -1 if system was not found
|
|
1041
|
-
*/
|
|
1042
|
-
EntityManager.prototype.getOwnerSystemIdByComponentClass = function (clazz) {
|
|
1043
|
-
console.warn("EntityManager.getOwnerSystemIdByComponentClass is deprecated, use .getSystem instead");
|
|
1044
|
-
|
|
1045
|
-
const systems = this.systems;
|
|
1046
|
-
let i = 0;
|
|
1047
|
-
const l = systems.length;
|
|
1048
|
-
for (; i < l; i++) {
|
|
1049
|
-
if (systems[i].componentClass === clazz) {
|
|
1050
|
-
return i;
|
|
1051
|
-
}
|
|
1052
|
-
}
|
|
1053
|
-
return -1;
|
|
1054
|
-
};
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
/**
|
|
1058
|
-
* same as getComponent when component exists, if component is not associated with the entity, callback will be invoked once when it is added.
|
|
1059
|
-
* @param {Number} entityId
|
|
1060
|
-
* @param {Class} componentClass
|
|
1061
|
-
* @param {function} callback
|
|
1062
|
-
* @param {*} [thisArg]
|
|
1063
|
-
*/
|
|
1064
|
-
EntityManager.prototype.getComponentAsync = function (entityId, componentClass, callback, thisArg) {
|
|
1065
|
-
console.warn("EntityManager.getComponentAsync is deprecated");
|
|
1066
|
-
|
|
1067
|
-
const dataset = this.dataset;
|
|
1068
|
-
|
|
1069
|
-
if (dataset === undefined) {
|
|
1070
|
-
throw new Error('No dataset attached');
|
|
1071
|
-
}
|
|
1072
|
-
|
|
1073
|
-
dataset.getComponentAsync(entityId, componentClass, callback, thisArg);
|
|
1074
|
-
|
|
1075
|
-
};
|
|
1076
|
-
|
|
1077
881
|
export {
|
|
1078
882
|
EventType,
|
|
1079
883
|
EntityManager
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { EntityManager } from "./EntityManager.js";
|
|
2
|
-
import { System } from "./System.js";
|
|
2
|
+
import { System, SystemState } from "./System.js";
|
|
3
3
|
import { jest } from '@jest/globals';
|
|
4
|
+
import { IllegalStateException } from "../../core/fsm/exceptions/IllegalStateException.js";
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
*
|
|
@@ -97,3 +98,63 @@ test("call to 'simulate' propagate to registered system", () => {
|
|
|
97
98
|
expect(update).toHaveBeenLastCalledWith(7);
|
|
98
99
|
});
|
|
99
100
|
});
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
test("call to 'simulate' ticks fixed update correctly", async () => {
|
|
104
|
+
|
|
105
|
+
const dummySystem = new DummySystem();
|
|
106
|
+
const fixedUpdate = jest.spyOn(dummySystem, 'fixedUpdate');
|
|
107
|
+
|
|
108
|
+
const em = await makeEm([dummySystem]);
|
|
109
|
+
|
|
110
|
+
em.fixedUpdateStepSize = 1.1;
|
|
111
|
+
|
|
112
|
+
em.simulate(3.3001);
|
|
113
|
+
|
|
114
|
+
expect(fixedUpdate).toHaveBeenCalledTimes(3);
|
|
115
|
+
expect(fixedUpdate).toHaveBeenLastCalledWith(1.1);
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
test("hasSystem", async () => {
|
|
119
|
+
|
|
120
|
+
const dummySystem = new DummySystem();
|
|
121
|
+
const em = await makeEm([]);
|
|
122
|
+
|
|
123
|
+
expect(em.hasSystem(DummySystem)).toBe(false);
|
|
124
|
+
|
|
125
|
+
await em.addSystem(dummySystem);
|
|
126
|
+
|
|
127
|
+
expect(em.hasSystem(DummySystem)).toBe(true);
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
test("addSystem", async () => {
|
|
131
|
+
const em = await makeEm([]);
|
|
132
|
+
|
|
133
|
+
const s1 = new DummySystem();
|
|
134
|
+
|
|
135
|
+
await em.addSystem(s1);
|
|
136
|
+
|
|
137
|
+
expect(s1.state.get()).toEqual(SystemState.RUNNING)
|
|
138
|
+
|
|
139
|
+
// system is already added, expect silent return
|
|
140
|
+
expect(() => em.addSystem(s1)).not.toThrow();
|
|
141
|
+
|
|
142
|
+
// 2 systems of the same class are not allowed
|
|
143
|
+
expect(() => em.addSystem(new DummySystem())).toThrow(IllegalStateException);
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
test("removeSystem", async () => {
|
|
147
|
+
|
|
148
|
+
const system = new DummySystem();
|
|
149
|
+
|
|
150
|
+
const em = await makeEm([system]);
|
|
151
|
+
|
|
152
|
+
expect(await em.removeSystem(system)).toBe(true);
|
|
153
|
+
|
|
154
|
+
expect(em.hasSystem(DummySystem)).toBe(false);
|
|
155
|
+
|
|
156
|
+
expect(system.state.get()).toEqual(SystemState.STOPPED);
|
|
157
|
+
|
|
158
|
+
// Try again, this time we expect nothing to happen
|
|
159
|
+
expect(await em.removeSystem(system)).toEqual(false);
|
|
160
|
+
});
|