@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
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { seededRandom } from "../../../../../core/math/random/seededRandom.js";
|
|
2
|
+
import { Sampler2D } from "../Sampler2D.js";
|
|
3
|
+
import { randomIntegerBetween } from "../../../../../core/math/random/randomIntegerBetween.js";
|
|
4
|
+
import { computeUnsignedDistanceField } from "./computeUnsignedDistanceField.js";
|
|
5
|
+
|
|
6
|
+
test('empty', () => {
|
|
7
|
+
const source = Sampler2D.uint8(1, 0, 0);
|
|
8
|
+
const target = Sampler2D.uint8(1, 0, 0);
|
|
9
|
+
|
|
10
|
+
computeUnsignedDistanceField(source, target, 0);
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
test('1 pixel empty source', () => {
|
|
14
|
+
const source = Sampler2D.uint8(1, 1, 1);
|
|
15
|
+
const target = Sampler2D.uint8(1, 1, 1);
|
|
16
|
+
|
|
17
|
+
computeUnsignedDistanceField(source, target, 0);
|
|
18
|
+
|
|
19
|
+
expect(target.readChannel(0, 0, 0)).toBe(255);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
test('1 pixel filled source', () => {
|
|
23
|
+
const source = Sampler2D.uint8(1, 1, 1);
|
|
24
|
+
source.set(0, 0, [255]);
|
|
25
|
+
|
|
26
|
+
const target = Sampler2D.uint8(1, 1, 1);
|
|
27
|
+
|
|
28
|
+
computeUnsignedDistanceField(source, target, 0);
|
|
29
|
+
|
|
30
|
+
expect(target.readChannel(0, 0, 0)).toBe(0);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
test('3x3 pixel source with filled middle', () => {
|
|
34
|
+
const source = Sampler2D.uint8(1, 3, 3);
|
|
35
|
+
source.set(1, 1, [255]);
|
|
36
|
+
|
|
37
|
+
const target = Sampler2D.uint8(1, 3, 3);
|
|
38
|
+
|
|
39
|
+
computeUnsignedDistanceField(source, target, 0);
|
|
40
|
+
|
|
41
|
+
expect(target.readChannel(0, 0, 0)).toBe(1);
|
|
42
|
+
expect(target.readChannel(1, 0, 0)).toBe(1);
|
|
43
|
+
expect(target.readChannel(2, 0, 0)).toBe(1);
|
|
44
|
+
|
|
45
|
+
expect(target.readChannel(0, 1, 0)).toBe(1);
|
|
46
|
+
expect(target.readChannel(1, 1, 0)).toBe(0);
|
|
47
|
+
expect(target.readChannel(2, 1, 0)).toBe(1);
|
|
48
|
+
|
|
49
|
+
expect(target.readChannel(0, 2, 0)).toBe(1);
|
|
50
|
+
expect(target.readChannel(1, 2, 0)).toBe(1);
|
|
51
|
+
expect(target.readChannel(2, 2, 0)).toBe(1);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
test('3x3 pixel source with empty middle', () => {
|
|
55
|
+
const source = Sampler2D.uint8(1, 3, 3);
|
|
56
|
+
source.data.fill(255);
|
|
57
|
+
source.set(1, 1, [0]);
|
|
58
|
+
|
|
59
|
+
const target = Sampler2D.uint8(1, 3, 3);
|
|
60
|
+
|
|
61
|
+
computeUnsignedDistanceField(source, target, 0);
|
|
62
|
+
|
|
63
|
+
expect(target.readChannel(0, 0, 0)).toBe(0);
|
|
64
|
+
expect(target.readChannel(1, 0, 0)).toBe(0);
|
|
65
|
+
expect(target.readChannel(2, 0, 0)).toBe(0);
|
|
66
|
+
|
|
67
|
+
expect(target.readChannel(0, 1, 0)).toBe(0);
|
|
68
|
+
expect(target.readChannel(1, 1, 0)).toBe(1);
|
|
69
|
+
expect(target.readChannel(2, 1, 0)).toBe(0);
|
|
70
|
+
|
|
71
|
+
expect(target.readChannel(0, 2, 0)).toBe(0);
|
|
72
|
+
expect(target.readChannel(1, 2, 0)).toBe(0);
|
|
73
|
+
expect(target.readChannel(2, 2, 0)).toBe(0);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
test('3x3 pixel source with empty corners', () => {
|
|
77
|
+
const source = Sampler2D.uint8(1, 3, 3);
|
|
78
|
+
source.data.fill(255);
|
|
79
|
+
source.set(0, 0, [0]);
|
|
80
|
+
source.set(2, 0, [0]);
|
|
81
|
+
source.set(0, 2, [0]);
|
|
82
|
+
source.set(2, 2, [0]);
|
|
83
|
+
|
|
84
|
+
const target = Sampler2D.uint8(1, 3, 3);
|
|
85
|
+
|
|
86
|
+
computeUnsignedDistanceField(source, target, 0);
|
|
87
|
+
|
|
88
|
+
expect(target.readChannel(0, 0, 0)).toBe(1);
|
|
89
|
+
expect(target.readChannel(1, 0, 0)).toBe(0);
|
|
90
|
+
expect(target.readChannel(2, 0, 0)).toBe(1);
|
|
91
|
+
|
|
92
|
+
expect(target.readChannel(0, 1, 0)).toBe(0);
|
|
93
|
+
expect(target.readChannel(1, 1, 0)).toBe(0);
|
|
94
|
+
expect(target.readChannel(2, 1, 0)).toBe(0);
|
|
95
|
+
|
|
96
|
+
expect(target.readChannel(0, 2, 0)).toBe(1);
|
|
97
|
+
expect(target.readChannel(1, 2, 0)).toBe(0);
|
|
98
|
+
expect(target.readChannel(2, 2, 0)).toBe(1);
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
test('3x3 pixel source with filled corners', () => {
|
|
102
|
+
const source = Sampler2D.uint8(1, 3, 3);
|
|
103
|
+
source.data.fill(0);
|
|
104
|
+
source.set(0, 0, [255]);
|
|
105
|
+
source.set(2, 0, [255]);
|
|
106
|
+
source.set(0, 2, [255]);
|
|
107
|
+
source.set(2, 2, [255]);
|
|
108
|
+
|
|
109
|
+
const target = Sampler2D.uint8(1, 3, 3);
|
|
110
|
+
|
|
111
|
+
computeUnsignedDistanceField(source, target, 0);
|
|
112
|
+
|
|
113
|
+
expect(target.readChannel(0, 0, 0)).toBe(0);
|
|
114
|
+
expect(target.readChannel(1, 0, 0)).toBe(1);
|
|
115
|
+
expect(target.readChannel(2, 0, 0)).toBe(0);
|
|
116
|
+
|
|
117
|
+
expect(target.readChannel(0, 1, 0)).toBe(1);
|
|
118
|
+
expect(target.readChannel(1, 1, 0)).toBe(1);
|
|
119
|
+
expect(target.readChannel(2, 1, 0)).toBe(1);
|
|
120
|
+
|
|
121
|
+
expect(target.readChannel(0, 2, 0)).toBe(0);
|
|
122
|
+
expect(target.readChannel(1, 2, 0)).toBe(1);
|
|
123
|
+
expect(target.readChannel(2, 2, 0)).toBe(0);
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
test('3x1 pixel source with 1 filled corner', () => {
|
|
127
|
+
const source = Sampler2D.uint8(1, 3, 1);
|
|
128
|
+
source.data.fill(0);
|
|
129
|
+
source.set(0, 0, [255]);
|
|
130
|
+
|
|
131
|
+
const target = Sampler2D.uint8(1, 3, 1);
|
|
132
|
+
|
|
133
|
+
computeUnsignedDistanceField(source, target, 0);
|
|
134
|
+
|
|
135
|
+
expect(target.readChannel(0, 0, 0)).toBe(0);
|
|
136
|
+
expect(target.readChannel(1, 0, 0)).toBe(1);
|
|
137
|
+
expect(target.readChannel(2, 0, 0)).toBe(2);
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
test('3x3 pixel source with 1 filled corner', () => {
|
|
141
|
+
const source = Sampler2D.uint8(1, 3, 3);
|
|
142
|
+
source.data.fill(0);
|
|
143
|
+
source.set(0, 0, [255]);
|
|
144
|
+
|
|
145
|
+
const target = Sampler2D.uint8(1, 3, 3);
|
|
146
|
+
|
|
147
|
+
computeUnsignedDistanceField(source, target, 0);
|
|
148
|
+
|
|
149
|
+
expect(target.readChannel(0, 0, 0)).toBe(0);
|
|
150
|
+
expect(target.readChannel(1, 0, 0)).toBe(1);
|
|
151
|
+
expect(target.readChannel(2, 0, 0)).toBe(2);
|
|
152
|
+
|
|
153
|
+
expect(target.readChannel(0, 1, 0)).toBe(1);
|
|
154
|
+
expect(target.readChannel(1, 1, 0)).toBe(1);
|
|
155
|
+
expect(target.readChannel(2, 1, 0)).toBe(2);
|
|
156
|
+
|
|
157
|
+
expect(target.readChannel(0, 2, 0)).toBe(2);
|
|
158
|
+
expect(target.readChannel(1, 2, 0)).toBe(2);
|
|
159
|
+
expect(target.readChannel(2, 2, 0)).toBe(2);
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
test.skip('performance', () => {
|
|
163
|
+
|
|
164
|
+
const sizeX = 100;
|
|
165
|
+
const sizeY = 100;
|
|
166
|
+
|
|
167
|
+
const source = Sampler2D.uint8(1, sizeX, sizeY);
|
|
168
|
+
|
|
169
|
+
const random = seededRandom(42);
|
|
170
|
+
source.data.fill(0);
|
|
171
|
+
for (let i = 0; i < source.data.length * 0.1; i++) {
|
|
172
|
+
const x = randomIntegerBetween(random, 0, sizeX);
|
|
173
|
+
const y = randomIntegerBetween(random, 0, sizeY);
|
|
174
|
+
source.set(x, y, [255]);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
const target = Sampler2D.uint8(1, sizeX, sizeY);
|
|
178
|
+
|
|
179
|
+
console.time('p');
|
|
180
|
+
computeUnsignedDistanceField(source, target, 0);
|
|
181
|
+
console.timeEnd('p');
|
|
182
|
+
|
|
183
|
+
});
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { max2 } from "../../../../../core/math/max2.js";
|
|
2
|
+
import { min2 } from "../../../../../core/math/min2.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* algorithm proposed by Borgefors, Chamfer distance [J. ACM 15 (1968) 600, Comput. Vis. Graph. Image Process. 34 (1986) 344], h
|
|
6
|
+
* @param {Sampler2D} source
|
|
7
|
+
* @param {Sampler2D} distanceField
|
|
8
|
+
* @param {number} emptyValue
|
|
9
|
+
* @param {number} d1 distance between two adjacent pixels in either x or y direction
|
|
10
|
+
* @param {number} d2 distance between two diagonally adjacent pixels
|
|
11
|
+
* @param {number} maxD highest value that distance field can hold
|
|
12
|
+
*/
|
|
13
|
+
export function computeUnsignedDistanceField_Chamfer(source, distanceField, emptyValue, d1, d2, maxD) {
|
|
14
|
+
const sourceData = source.data;
|
|
15
|
+
const distanceFieldData = distanceField.data;
|
|
16
|
+
|
|
17
|
+
const width = source.width;
|
|
18
|
+
const height = source.height;
|
|
19
|
+
|
|
20
|
+
const maxX = width - 1;
|
|
21
|
+
const maxY = height - 1;
|
|
22
|
+
|
|
23
|
+
let x, y, i, v;
|
|
24
|
+
|
|
25
|
+
//initialize distance field
|
|
26
|
+
const dataSize = height * width;
|
|
27
|
+
for (i = 0; i < dataSize; i++) {
|
|
28
|
+
if (sourceData[i] !== emptyValue) {
|
|
29
|
+
distanceFieldData[i] = 0;
|
|
30
|
+
} else {
|
|
31
|
+
distanceFieldData[i] = maxD;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
//first pass (forward)
|
|
36
|
+
for (y = 0; y < height; y++) {
|
|
37
|
+
|
|
38
|
+
const y_m1 = max2(y - 1, 0);
|
|
39
|
+
|
|
40
|
+
const y_w = y * width;
|
|
41
|
+
|
|
42
|
+
const y_m1_w = y_m1 * width;
|
|
43
|
+
|
|
44
|
+
for (x = 0; x < width; x++) {
|
|
45
|
+
|
|
46
|
+
i = y_w + x;
|
|
47
|
+
|
|
48
|
+
v = distanceFieldData[i];
|
|
49
|
+
|
|
50
|
+
const x_m1 = max2(x - 1, 0);
|
|
51
|
+
const x_p1 = min2(x + 1, maxX);
|
|
52
|
+
|
|
53
|
+
const v0_i = x_m1 + y_m1_w;
|
|
54
|
+
const v0 = distanceFieldData[v0_i] + d2;
|
|
55
|
+
|
|
56
|
+
if (v0 < v) {
|
|
57
|
+
distanceFieldData[i] = v0;
|
|
58
|
+
v = v0;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const v1_i = x + y_m1_w;
|
|
62
|
+
const v1 = distanceFieldData[v1_i] + d1;
|
|
63
|
+
|
|
64
|
+
if (v1 < v) {
|
|
65
|
+
distanceFieldData[i] = v1;
|
|
66
|
+
v = v1;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const v2_i = x_p1 + y_m1_w;
|
|
70
|
+
const v2 = distanceFieldData[v2_i] + d2;
|
|
71
|
+
|
|
72
|
+
if (v2 < v) {
|
|
73
|
+
distanceFieldData[i] = v2;
|
|
74
|
+
v = v2;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const v3_i = x_m1 + y_w;
|
|
78
|
+
const v3 = distanceFieldData[v3_i] + d1;
|
|
79
|
+
|
|
80
|
+
if (v3 < v) {
|
|
81
|
+
distanceFieldData[i] = v3;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
//second pass (backward)
|
|
87
|
+
for (y = maxY; y >= 0; y--) {
|
|
88
|
+
const y_w = y * width;
|
|
89
|
+
|
|
90
|
+
const y_p1 = min2(y + 1, maxY);
|
|
91
|
+
const y_p1_w = y_p1 * width;
|
|
92
|
+
|
|
93
|
+
for (x = maxX; x >= 0; x--) {
|
|
94
|
+
const x_p1 = min2(x + 1, maxX);
|
|
95
|
+
const x_m1 = max2(x - 1, 0);
|
|
96
|
+
|
|
97
|
+
i = y_w + x;
|
|
98
|
+
|
|
99
|
+
v = distanceFieldData[i];
|
|
100
|
+
|
|
101
|
+
const v0_i = x_p1 + y_w;
|
|
102
|
+
const v0 = distanceFieldData[v0_i] + d1;
|
|
103
|
+
|
|
104
|
+
if (v0 < v) {
|
|
105
|
+
distanceFieldData[i] = v0;
|
|
106
|
+
v = v0;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const v1_i = x_m1 + y_p1_w;
|
|
110
|
+
const v1 = distanceFieldData[v1_i] + d2;
|
|
111
|
+
|
|
112
|
+
if (v1 < v) {
|
|
113
|
+
distanceFieldData[i] = v1;
|
|
114
|
+
v = v1;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const v2_i = x + y_p1_w;
|
|
118
|
+
const v2 = distanceFieldData[v2_i] + d1;
|
|
119
|
+
|
|
120
|
+
if (v2 < v) {
|
|
121
|
+
distanceFieldData[i] = v2;
|
|
122
|
+
v = v2;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const v3_i = x_p1 + y_p1_w;
|
|
126
|
+
const v3 = distanceFieldData[v3_i] + d2;
|
|
127
|
+
|
|
128
|
+
if (v3 < v) {
|
|
129
|
+
distanceFieldData[i] = v3;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { assert } from "../../../../../core/assert.js";
|
|
2
|
+
|
|
1
3
|
const b = 1.0 / 3.0;
|
|
2
4
|
const c = 1.0 / 3.0;
|
|
3
5
|
|
|
@@ -33,6 +35,7 @@ export function mitchell(x) {
|
|
|
33
35
|
}
|
|
34
36
|
return 0.0;
|
|
35
37
|
}
|
|
38
|
+
|
|
36
39
|
mitchell.support = 2;
|
|
37
40
|
|
|
38
41
|
/**
|
|
@@ -42,6 +45,7 @@ mitchell.support = 2;
|
|
|
42
45
|
* @returns {number}
|
|
43
46
|
*/
|
|
44
47
|
export function mitchell_v1(x) {
|
|
48
|
+
assert.greaterThanOrEqual(x, 0);
|
|
45
49
|
|
|
46
50
|
if (x < 1.0) {
|
|
47
51
|
return 0.8888888888888888 + x * x * (-2 + x * 1.1666666666666667);
|
|
@@ -14,7 +14,9 @@ import { GameAssetType } from "../../../asset/GameAssetType.js";
|
|
|
14
14
|
export default function loadSampler2D(url, assetManager) {
|
|
15
15
|
return new Promise(function (resolve, reject) {
|
|
16
16
|
assetManager.get({
|
|
17
|
-
path: url,
|
|
17
|
+
path: url,
|
|
18
|
+
type: GameAssetType.Image,
|
|
19
|
+
callback: (asset) => {
|
|
18
20
|
const imageData = asset.create();
|
|
19
21
|
|
|
20
22
|
const width = imageData.width;
|
|
@@ -32,7 +34,8 @@ export default function loadSampler2D(url, assetManager) {
|
|
|
32
34
|
}
|
|
33
35
|
const sampler2D = new Sampler2D(buffer, 1, width, height);
|
|
34
36
|
resolve(sampler2D);
|
|
35
|
-
},
|
|
37
|
+
},
|
|
38
|
+
failure: reject
|
|
36
39
|
});
|
|
37
40
|
});
|
|
38
41
|
};
|
|
@@ -44,12 +44,15 @@ export function sampler2d_downsample_mipmap(source, destination) {
|
|
|
44
44
|
const m0_sx = (current_mip.width + 1) / (current_mip.width);
|
|
45
45
|
const m0_sy = (current_mip.height + 1) / (current_mip.height);
|
|
46
46
|
|
|
47
|
+
const destination_v_scale = dest_height > 1 ? 1 / (dest_height - 1) : 0;
|
|
48
|
+
const destination_u_scale = dest_width > 1 ? 1 / (dest_width - 1) : 0;
|
|
49
|
+
|
|
47
50
|
for (let y = 0; y < dest_height; y++) {
|
|
48
|
-
const v = y
|
|
51
|
+
const v = y * destination_v_scale;
|
|
49
52
|
|
|
50
53
|
for (let x = 0; x < dest_width; x++) {
|
|
51
54
|
|
|
52
|
-
const u = x
|
|
55
|
+
const u = x * destination_u_scale;
|
|
53
56
|
|
|
54
57
|
for (let i = 0; i < itemSize; i++) {
|
|
55
58
|
|
|
@@ -58,7 +61,9 @@ export function sampler2d_downsample_mipmap(source, destination) {
|
|
|
58
61
|
|
|
59
62
|
const c_out = lerp(c0, c1, mip_mix);
|
|
60
63
|
|
|
61
|
-
|
|
64
|
+
const destination_address = (y * dest_width + x) * itemSize + i;
|
|
65
|
+
|
|
66
|
+
destination.data[destination_address] = c_out;
|
|
62
67
|
}
|
|
63
68
|
}
|
|
64
69
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Sampler2D } from "../Sampler2D.js";
|
|
2
|
+
import { sampler2d_downsample_mipmap } from "./sampler2d_downsample_mipmap.js";
|
|
3
|
+
|
|
4
|
+
test("downsample solid fill from 2x2 to 1x1", () => {
|
|
5
|
+
const input = Sampler2D.uint8(1, 2, 2);
|
|
6
|
+
|
|
7
|
+
input.data.fill(7);
|
|
8
|
+
|
|
9
|
+
const result = Sampler2D.uint8(1, 1, 1);
|
|
10
|
+
sampler2d_downsample_mipmap(input, result);
|
|
11
|
+
|
|
12
|
+
expect(result.readChannel(0, 0, 0)).toBeCloseTo(7)
|
|
13
|
+
});
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { assert } from "../../../../core/assert.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
* @param {number[]|Float32Array|Uint8Array|Uint32Array} result
|
|
6
|
+
* @param {number} result_offset
|
|
7
|
+
* @param {Sampler2D} sampler
|
|
8
|
+
* @param {number} [channel]
|
|
9
|
+
* @return {number}
|
|
10
|
+
*/
|
|
11
|
+
export function sampler2d_channel_compute_min_indices(
|
|
12
|
+
result, result_offset,
|
|
13
|
+
sampler, channel = 0
|
|
14
|
+
) {
|
|
15
|
+
assert.defined(sampler, 'sampler');
|
|
16
|
+
assert.isNonNegativeInteger(result_offset, 'result_offset');
|
|
17
|
+
|
|
18
|
+
const itemSize = sampler.itemSize;
|
|
19
|
+
|
|
20
|
+
assert.isNumber(channel, "channel");
|
|
21
|
+
assert.isNonNegativeInteger(channel, 'channel');
|
|
22
|
+
assert.ok(channel >= 0, `channel must be >= 0, was ${channel}`);
|
|
23
|
+
assert.ok(channel < itemSize, `channel must be less than itemSize(=${itemSize}), was ${channel}`);
|
|
24
|
+
|
|
25
|
+
assert.isArrayLike(result, "result");
|
|
26
|
+
|
|
27
|
+
const data = this.data;
|
|
28
|
+
|
|
29
|
+
const l = data.length;
|
|
30
|
+
|
|
31
|
+
if (l === 0) {
|
|
32
|
+
//no data
|
|
33
|
+
return 0;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
let bestValue = data[channel];
|
|
37
|
+
|
|
38
|
+
let result_count = 0;
|
|
39
|
+
|
|
40
|
+
for (let i = channel + itemSize; i < l; i += itemSize) {
|
|
41
|
+
const value = data[i];
|
|
42
|
+
|
|
43
|
+
if (bestValue > value) {
|
|
44
|
+
bestValue = value;
|
|
45
|
+
//drop result
|
|
46
|
+
result_count = 1;
|
|
47
|
+
|
|
48
|
+
result[result_offset] = i;
|
|
49
|
+
} else if (value === bestValue) {
|
|
50
|
+
result[result_offset + result_count] = i;
|
|
51
|
+
|
|
52
|
+
result_count++;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return result_count;
|
|
58
|
+
}
|
|
@@ -59,33 +59,6 @@ TemporalPath.prototype.update = function (timeDelta) {
|
|
|
59
59
|
this.updateSequence();
|
|
60
60
|
};
|
|
61
61
|
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
*
|
|
65
|
-
* @param {number} t value between 0..1, falls between points p1 and p2
|
|
66
|
-
* @param {number[]} p0
|
|
67
|
-
* @param {number[]} p1
|
|
68
|
-
* @param {number[]} p2
|
|
69
|
-
* @param {number[]} p3
|
|
70
|
-
* @param {number[]} result
|
|
71
|
-
*/
|
|
72
|
-
function catmullRomSample(t, p0, p1, p2, p3, result) {
|
|
73
|
-
|
|
74
|
-
for (let j = 0; j < 4; j++) {
|
|
75
|
-
const v0 = p0[j];
|
|
76
|
-
const v1 = p1[j];
|
|
77
|
-
const v2 = p2[j];
|
|
78
|
-
const v3 = p3[j];
|
|
79
|
-
|
|
80
|
-
const t2 = t * t;
|
|
81
|
-
const t3 = t2 * t;
|
|
82
|
-
|
|
83
|
-
const qT = 0.5 * (2 * v1 + (v2 - v0) * t + (2 * v0 - 5 * v1 + 4 * v2 - v3) * t2 + (3 * v1 - v0 - 3 * v2 + v3) * t3);
|
|
84
|
-
|
|
85
|
-
result[j] = qT;
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
62
|
/**
|
|
90
63
|
* @returns {number}
|
|
91
64
|
*/
|
|
@@ -133,15 +106,6 @@ TemporalPath.prototype.computeLength = function () {
|
|
|
133
106
|
return result;
|
|
134
107
|
};
|
|
135
108
|
|
|
136
|
-
/**
|
|
137
|
-
*
|
|
138
|
-
* @param {number} sampleCount
|
|
139
|
-
* @param {Float32Array} result
|
|
140
|
-
*/
|
|
141
|
-
TemporalPath.prototype.sampleSmoothPath = function (sampleCount, result) {
|
|
142
|
-
|
|
143
|
-
};
|
|
144
|
-
|
|
145
109
|
/**
|
|
146
110
|
*
|
|
147
111
|
* @param {number} x
|
|
@@ -21,7 +21,7 @@ test("1 succeeding child", () => {
|
|
|
21
21
|
|
|
22
22
|
p.initialize();
|
|
23
23
|
|
|
24
|
-
expect(p.tick()).toBe(BehaviorStatus.Succeeded);
|
|
24
|
+
expect(p.tick(1)).toBe(BehaviorStatus.Succeeded);
|
|
25
25
|
|
|
26
26
|
p.finalize();
|
|
27
27
|
|
|
@@ -43,8 +43,8 @@ test("1 succeeding child, 1 tick delay", () => {
|
|
|
43
43
|
|
|
44
44
|
p.initialize();
|
|
45
45
|
|
|
46
|
-
expect(p.tick()).toBe(BehaviorStatus.Running);
|
|
47
|
-
expect(p.tick()).toBe(BehaviorStatus.Succeeded);
|
|
46
|
+
expect(p.tick(1)).toBe(BehaviorStatus.Running);
|
|
47
|
+
expect(p.tick(1)).toBe(BehaviorStatus.Succeeded);
|
|
48
48
|
|
|
49
49
|
p.finalize();
|
|
50
50
|
|
|
@@ -66,7 +66,7 @@ test("1 failing child", () => {
|
|
|
66
66
|
|
|
67
67
|
p.initialize();
|
|
68
68
|
|
|
69
|
-
expect(p.tick()).toBe(BehaviorStatus.Failed);
|
|
69
|
+
expect(p.tick(1)).toBe(BehaviorStatus.Failed);
|
|
70
70
|
|
|
71
71
|
p.finalize();
|
|
72
72
|
|
|
@@ -88,8 +88,8 @@ test("1 failing child, 1 tick delay", () => {
|
|
|
88
88
|
|
|
89
89
|
p.initialize();
|
|
90
90
|
|
|
91
|
-
expect(p.tick()).toBe(BehaviorStatus.Running);
|
|
92
|
-
expect(p.tick()).toBe(BehaviorStatus.Failed);
|
|
91
|
+
expect(p.tick(1)).toBe(BehaviorStatus.Running);
|
|
92
|
+
expect(p.tick(1)).toBe(BehaviorStatus.Failed);
|
|
93
93
|
|
|
94
94
|
p.finalize();
|
|
95
95
|
|
|
@@ -111,7 +111,7 @@ test("policy success-One, failure-One. Succeeding", () => {
|
|
|
111
111
|
|
|
112
112
|
p.initialize();
|
|
113
113
|
|
|
114
|
-
expect(p.tick()).toBe(BehaviorStatus.Succeeded);
|
|
114
|
+
expect(p.tick(1)).toBe(BehaviorStatus.Succeeded);
|
|
115
115
|
});
|
|
116
116
|
|
|
117
117
|
test("policy success-All, failure-One. Succeeding", () => {
|
|
@@ -127,8 +127,8 @@ test("policy success-All, failure-One. Succeeding", () => {
|
|
|
127
127
|
|
|
128
128
|
p.initialize();
|
|
129
129
|
|
|
130
|
-
expect(p.tick()).toBe(BehaviorStatus.Running);
|
|
131
|
-
expect(p.tick()).toBe(BehaviorStatus.Succeeded);
|
|
130
|
+
expect(p.tick(1)).toBe(BehaviorStatus.Running);
|
|
131
|
+
expect(p.tick(1)).toBe(BehaviorStatus.Succeeded);
|
|
132
132
|
});
|
|
133
133
|
|
|
134
134
|
test("policy success-One, failure-One. Failing", () => {
|
|
@@ -144,7 +144,7 @@ test("policy success-One, failure-One. Failing", () => {
|
|
|
144
144
|
|
|
145
145
|
p.initialize();
|
|
146
146
|
|
|
147
|
-
expect(p.tick()).toBe(BehaviorStatus.Failed);
|
|
147
|
+
expect(p.tick(1)).toBe(BehaviorStatus.Failed);
|
|
148
148
|
});
|
|
149
149
|
|
|
150
150
|
test("policy success-One, failure-All. Failing", () => {
|
|
@@ -160,6 +160,6 @@ test("policy success-One, failure-All. Failing", () => {
|
|
|
160
160
|
|
|
161
161
|
p.initialize();
|
|
162
162
|
|
|
163
|
-
expect(p.tick()).toBe(BehaviorStatus.Running);
|
|
164
|
-
expect(p.tick()).toBe(BehaviorStatus.Failed);
|
|
163
|
+
expect(p.tick(1)).toBe(BehaviorStatus.Running);
|
|
164
|
+
expect(p.tick(1)).toBe(BehaviorStatus.Failed);
|
|
165
165
|
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { SequenceBehavior } from "./SequenceBehavior.js";
|
|
2
|
+
import { SucceedingBehavior } from "../primitive/SucceedingBehavior.js";
|
|
3
|
+
import { BehaviorStatus } from "../BehaviorStatus.js";
|
|
4
|
+
|
|
5
|
+
test("constructor does not throw", () => {
|
|
6
|
+
expect(() => new SequenceBehavior()).not.toThrow();
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
test("succeed in 1 tick with 1 succeeding child", () => {
|
|
10
|
+
|
|
11
|
+
const b = SequenceBehavior.from([new SucceedingBehavior()]);
|
|
12
|
+
|
|
13
|
+
b.initialize();
|
|
14
|
+
|
|
15
|
+
expect(b.tick(1)).toEqual(BehaviorStatus.Succeeded);
|
|
16
|
+
|
|
17
|
+
});
|
|
@@ -20,7 +20,7 @@ export class SucceedingBehavior extends Behavior {
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
|
-
*
|
|
23
|
+
* @deprecated use static INSTANCE instead
|
|
24
24
|
* @param {number} delayTicks
|
|
25
25
|
* @return {SucceedingBehavior}
|
|
26
26
|
*/
|
|
@@ -36,6 +36,8 @@ export class SucceedingBehavior extends Behavior {
|
|
|
36
36
|
return BehaviorStatus.Running;
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
|
+
|
|
40
|
+
static INSTANCE = new SucceedingBehavior();
|
|
39
41
|
}
|
|
40
42
|
|
|
41
43
|
SucceedingBehavior.typeName = "SucceedingBehavior";
|
|
@@ -3,3 +3,24 @@ import { StaticKnowledgeDataTable } from "./StaticKnowledgeDataTable.js";
|
|
|
3
3
|
test("constructor does not throw", () => {
|
|
4
4
|
expect(() => new StaticKnowledgeDataTable()).not.toThrow();
|
|
5
5
|
});
|
|
6
|
+
|
|
7
|
+
test("resetting empty works as expected", () => {
|
|
8
|
+
const table = new StaticKnowledgeDataTable();
|
|
9
|
+
|
|
10
|
+
table.reset();
|
|
11
|
+
|
|
12
|
+
expect(table.size()).toEqual(0);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
test("getter", () => {
|
|
16
|
+
|
|
17
|
+
const table = new StaticKnowledgeDataTable();
|
|
18
|
+
|
|
19
|
+
expect(table.get("x")).toEqual(null);
|
|
20
|
+
|
|
21
|
+
const item = { id: "x" };
|
|
22
|
+
|
|
23
|
+
table.add(item);
|
|
24
|
+
|
|
25
|
+
expect(table.get('x')).toBe(item);
|
|
26
|
+
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {StaticKnowledgeDataTable} from "./StaticKnowledgeDataTable";
|
|
2
2
|
|
|
3
|
-
export class StaticKnowledgeDataTableDescriptor {
|
|
4
|
-
public table: StaticKnowledgeDataTable
|
|
3
|
+
export class StaticKnowledgeDataTableDescriptor<T> {
|
|
4
|
+
public table: StaticKnowledgeDataTable<T>
|
|
5
5
|
public id: string
|
|
6
6
|
public source: string
|
|
7
7
|
}
|
|
@@ -3,6 +3,10 @@ import { LogLevel } from "./LogLevel.js";
|
|
|
3
3
|
|
|
4
4
|
let instance;
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Directs output into system console
|
|
8
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/console
|
|
9
|
+
*/
|
|
6
10
|
export class ConsoleLoggerBackend extends LoggerBackend {
|
|
7
11
|
log(level, message) {
|
|
8
12
|
switch (level) {
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { LoggerBackend } from "./LoggerBackend.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Non-logging backend, used for testing or when log collection is unwanted
|
|
5
|
+
*/
|
|
6
|
+
export class VoidLoggerBackend extends LoggerBackend {
|
|
7
|
+
log(level, message) {
|
|
8
|
+
// do nothing
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
static INSTANCE = new VoidLoggerBackend()
|
|
12
|
+
}
|