@woosh/meep-engine 2.49.9 → 2.50.0

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.
Files changed (141) hide show
  1. package/editor/actions/concrete/ArrayCopyAction.js +1 -1
  2. package/package.json +1 -1
  3. package/src/core/binary/BinaryBuffer.js +1 -1
  4. package/src/core/binary/BinaryBuffer.spec.js +128 -0
  5. package/src/core/binary/int32_to_binary_string.js +4 -1
  6. package/src/core/binary/int32_to_binary_string.spec.js +9 -0
  7. package/src/core/bvh2/BinaryNode.js +0 -30
  8. package/src/core/bvh2/binary/2/BinaryUint32BVH.js +1 -1
  9. package/src/core/bvh2/binary/IndexedBinaryBVH.js +1 -1
  10. package/src/core/bvh2/bvh3/ExplicitBinaryBoundingVolumeHierarchy.js +1 -1
  11. package/src/core/bvh2/bvh3/query/compute_tight_near_far_clipping_planes.js +1 -1
  12. package/src/core/cache/Cache.js +31 -29
  13. package/src/core/cache/Cache.spec.js +4 -1
  14. package/src/core/collection/HashMap.js +1 -1
  15. package/src/core/collection/array/{copyArray.js → array_copy.js} +1 -24
  16. package/src/core/collection/array/array_copy_entire.js +21 -0
  17. package/src/core/collection/array/typed/typed_array_copy.js +1 -1
  18. package/src/core/collection/queue/Deque.d.ts +4 -0
  19. package/src/core/collection/queue/Deque.js +5 -7
  20. package/src/core/collection/queue/Deque.spec.js +107 -0
  21. package/src/core/collection/table/RowFirstTable.js +1 -1
  22. package/src/core/geom/2d/aabb/AABB2.d.ts +14 -0
  23. package/src/core/geom/2d/aabb/AABB2.js +9 -7
  24. package/src/core/geom/2d/aabb/AABB2.spec.js +100 -0
  25. package/src/core/geom/2d/aabb/aabb2_compute_center_from_multiple.spec.js +11 -0
  26. package/src/core/geom/2d/aabb/aabb2_compute_overlap.spec.js +56 -0
  27. package/src/core/geom/2d/aabb/aabb2_contains.spec.js +40 -0
  28. package/src/core/geom/2d/bvh/Node2.js +1 -1
  29. package/src/core/geom/2d/convex-hull/fixed_convex_hull_humus.js +1 -1
  30. package/src/core/geom/2d/convex-hull/fixed_convex_hull_relaxation.js +1 -1
  31. package/src/core/geom/2d/line/line_segment_compute_line_segment_intersection_2d.js +35 -0
  32. package/src/core/geom/2d/line/line_segment_compute_line_segment_intersection_array_2d.js +51 -0
  33. package/src/core/geom/2d/line/line_segment_compute_line_segment_intersection_vectors_2d.js +15 -0
  34. package/src/core/geom/2d/line/line_segment_compute_line_segment_intersection_vectors_array_2d.js +30 -0
  35. package/src/core/geom/2d/line/line_segment_line_segment_intersection_exists_2d.js +29 -0
  36. package/src/core/geom/3d/aabb/AABB3.d.ts +4 -0
  37. package/src/core/geom/3d/aabb/AABB3.spec.js +30 -0
  38. package/src/core/geom/3d/matrix/m4_make_translation.js +1 -1
  39. package/src/core/geom/3d/sphere/harmonics/sh3_dering_optimize_positive.js +1 -1
  40. package/src/core/geom/3d/tetrahedra/TetrahedralMesh.js +1 -1
  41. package/src/core/geom/3d/tetrahedra/compute_circumsphere.js +1 -1
  42. package/src/core/geom/3d/tetrahedra/delaunay/fill_in_a_cavity.js +1 -1
  43. package/src/core/geom/3d/topology/bounds/computeTriangleClusterNormalBoundingCone.js +1 -1
  44. package/src/core/geom/3d/topology/expandConnectivityByLocality.js +1 -1
  45. package/src/core/geom/3d/topology/struct/binary/BinaryTopology.js +1 -1
  46. package/src/core/geom/Quaternion.d.ts +11 -0
  47. package/src/core/geom/Quaternion.js +36 -27
  48. package/src/core/geom/Quaternion.spec.js +141 -0
  49. package/src/core/geom/Vector2.d.ts +5 -1
  50. package/src/core/geom/Vector2.js +24 -0
  51. package/src/core/geom/Vector3.d.ts +4 -0
  52. package/src/core/geom/Vector3.spec.js +60 -0
  53. package/src/core/graph/GraphUtils.js +4 -2
  54. package/src/core/graph/layout/CircleLayout.js +4 -2
  55. package/src/core/math/vector_nd_dot.js +16 -0
  56. package/src/core/math/{normalizeArrayVector.js → vector_nd_normalize.js} +3 -3
  57. package/src/core/math/{normalizeArrayVector.spec.js → vector_nd_normalize.spec.js} +3 -3
  58. package/src/core/process/PromiseWatcher.spec.js +1 -1
  59. package/src/engine/animation/curve/compression/downsample_float_array_curve_by_error.js +1 -1
  60. package/src/engine/ecs/EntityManager.js +1 -205
  61. package/src/engine/ecs/fow/FogOfWar.js +1 -1
  62. package/src/engine/ecs/guid/GUID.js +1 -1
  63. package/src/engine/ecs/terrain/ecs/splat/SplatMapping.js +1 -1
  64. package/src/engine/ecs/terrain/overlay/TerrainOverlay.js +1 -1
  65. package/src/engine/ecs/terrain/tiles/TerrainTile.js +1 -1
  66. package/src/engine/ecs/transform/Transform.d.ts +2 -0
  67. package/src/engine/ecs/transform/Transform.spec.js +63 -0
  68. package/src/engine/ecs/transform-attachment/TransformAttachment.d.ts +17 -1
  69. package/src/engine/ecs/transform-attachment/TransformAttachment.js +12 -2
  70. package/src/engine/ecs/transform-attachment/TransformAttachment.spec.js +103 -0
  71. package/src/engine/graphics/ecs/path/tube/build/computeFrenetFrames.js +1 -1
  72. package/src/engine/graphics/geometry/MikkT/GenerateTSpaces.js +1 -1
  73. package/src/engine/graphics/geometry/MikkT/m_getNormal.js +1 -1
  74. package/src/engine/graphics/geometry/MikkT/m_getTexCoord.js +1 -1
  75. package/src/engine/graphics/geometry/bvh/buffered/BVHGeometryRaycaster.js +1 -1
  76. package/src/engine/graphics/geometry/instancing/InstancedMeshGroup.js +1 -1
  77. package/src/engine/graphics/geometry/optimization/merge/merge_geometry_hierarchy.js +1 -1
  78. package/src/engine/graphics/impostors/octahedral/util/build_cutout_from_atlas_by_alpha.js +1 -1
  79. package/src/engine/graphics/particles/particular/engine/utils/volume/AttributeValue.js +1 -1
  80. package/src/engine/graphics/render/Lines.js +1 -1
  81. package/src/engine/graphics/render/buffer/simple-fx/taa/TemporalSupersamplingRenderPlugin.js +1 -1
  82. package/src/engine/graphics/render/forward_plus/LightManager.js +1 -1
  83. package/src/engine/graphics/render/forward_plus/model/Decal.js +1 -1
  84. package/src/engine/graphics/render/forward_plus/prototype/prototypeLightManager.js +1 -1
  85. package/src/engine/graphics/render/gizmo/GizmoShapeRenderingInterface.js +1 -1
  86. package/src/engine/graphics/render/view/CameraView.js +1 -1
  87. package/src/engine/graphics/render/visibility/hiz/query/BatchOcclusionQuery.js +1 -1
  88. package/src/engine/graphics/render/webgpu/sample/MeshInstance.js +1 -1
  89. package/src/engine/graphics/sh3/LightProbeVolume.js +1 -1
  90. package/src/engine/graphics/sh3/path_tracer/PathTracedMesh.js +1 -1
  91. package/src/engine/graphics/sh3/path_tracer/PathTracer.js +1 -1
  92. package/src/engine/graphics/sh3/path_tracer/make_sky_hosek.js +1 -1
  93. package/src/engine/graphics/sh3/prototypeSH3Probe.js +1 -1
  94. package/src/engine/graphics/texture/3d/scs3d_read_2d_slice.js +1 -1
  95. package/src/engine/graphics/texture/CanvasClone.js +5 -1
  96. package/src/engine/graphics/texture/sampler/Sampler2D.js +14 -75
  97. package/src/engine/graphics/texture/sampler/bicubic.js +19 -19
  98. package/src/engine/graphics/texture/sampler/convertSampler2D2DataURL.spec.js +10 -0
  99. package/src/engine/graphics/texture/sampler/copy_Sampler2D_channel_data.spec.js +90 -0
  100. package/src/engine/graphics/texture/sampler/differenceSampler.js +13 -8
  101. package/src/engine/graphics/texture/sampler/distance/computeSignedDistanceField_Chamfer.js +140 -0
  102. package/src/engine/graphics/texture/sampler/distance/computeSignedDistanceField_NaiveFlood.js +130 -0
  103. package/src/engine/graphics/texture/sampler/distance/computeUnsignedDistanceField.js +10 -0
  104. package/src/engine/graphics/texture/sampler/distance/computeUnsignedDistanceField.spec.js +183 -0
  105. package/src/engine/graphics/texture/sampler/distance/computeUnsignedDistanceField_Chamfer.js +133 -0
  106. package/src/engine/graphics/texture/sampler/filter/mitchell.js +4 -0
  107. package/src/engine/graphics/texture/sampler/loadSampler2D.js +5 -2
  108. package/src/engine/graphics/texture/sampler/resize/sampler2d_downsample_mipmap.js +8 -3
  109. package/src/engine/graphics/texture/sampler/resize/sampler2d_downsample_mipmap.spec.js +13 -0
  110. package/src/engine/graphics/texture/sampler/sampler2d_channel_compute_min_indices.js +58 -0
  111. package/src/engine/graphics/trail/TemporalPath.js +0 -36
  112. package/src/engine/intelligence/behavior/composite/ParallelBehavior.spec.js +12 -12
  113. package/src/engine/intelligence/behavior/composite/SequenceBehavior.spec.js +17 -0
  114. package/src/engine/intelligence/behavior/primitive/SucceedingBehavior.js +2 -0
  115. package/src/engine/knowledge/database/StaticKnowledgeDataTable.d.ts +7 -1
  116. package/src/engine/knowledge/database/StaticKnowledgeDataTable.spec.js +21 -0
  117. package/src/engine/knowledge/database/StaticKnowledgeDataTableDescriptor.d.ts +2 -2
  118. package/src/engine/logging/ConsoleLoggerBackend.js +4 -0
  119. package/src/engine/logging/VoidLoggerBackend.js +12 -0
  120. package/src/engine/navigation/ecs/components/computeCatmullRomSpline.js +1 -1
  121. package/src/engine/navigation/ecs/components/computeCatmullRomSplineUniformDistance.js +1 -1
  122. package/src/engine/physics/cannon/CannonJSPhysicsSystem.js +1 -1
  123. package/src/engine/save/GameStateLoader.js +1 -1
  124. package/src/engine/scene/Scene.d.ts +2 -0
  125. package/src/engine/scene/Scene.js +2 -2
  126. package/src/engine/scene/Scene.spec.js +20 -0
  127. package/src/engine/scene/SceneManager.d.ts +4 -0
  128. package/src/engine/scene/SceneManager.js +46 -23
  129. package/src/engine/scene/SceneManager.spec.js +107 -0
  130. package/src/engine/sound/material/detector/terrain/TerrainSoundMaterialSurfaceDetector.js +2 -2
  131. package/src/engine/ui/GUIEngine.js +1 -1
  132. package/src/generation/grid/generation/util/buildUnsignedDistanceField.js +3 -1
  133. package/src/generation/markers/MarkerNode.js +2 -2
  134. package/src/generation/theme/AreaMask.js +3 -1
  135. package/src/view/elements/progress/RectangularPieProgressView.js +8 -6
  136. package/src/core/geom/2d/LineSegment2.js +0 -175
  137. package/src/core/geom/Matrix4.js +0 -275
  138. package/src/engine/graphics/texture/sampler/distanceField.js +0 -411
  139. package/src/engine/graphics/texture/sampler/distanceField.spec.js +0 -184
  140. package/src/engine/physics/cannon/cannon.min.js +0 -27
  141. /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, type: GameAssetType.Image, callback: (asset) => {
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
- }, failure: reject
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 / (dest_height - 1);
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 / (dest_width - 1);
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
- destination.data[(y * dest_width + x) * itemSize + i] = c_out;
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
+ });
@@ -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";
@@ -1,3 +1,9 @@
1
- export class StaticKnowledgeDataTable {
1
+ export class StaticKnowledgeDataTable<T> {
2
+ reset(): void
2
3
 
4
+ size(): number
5
+
6
+ get(id: string): T | null
7
+
8
+ add(item: T): boolean
3
9
  }
@@ -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
+ }