@woosh/meep-engine 2.50.2 → 2.51.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 (147) hide show
  1. package/README.md +4 -1
  2. package/editor/actions/concrete/WriteGridValueAction.js +13 -18
  3. package/editor/ecs/component/editors/Sampler2DEditor.js +2 -2
  4. package/editor/process/SymbolicDisplayProcess.js +1 -1
  5. package/editor/process/symbolic/buildThreeJSHelperEntity.js +1 -1
  6. package/editor/process/symbolic/makeCameraSymbolicDisplay.js +1 -1
  7. package/editor/process/symbolic/makeGridPositionSymbolDisplay.js +1 -1
  8. package/editor/process/symbolic/makeLightSymbolicDisplay.js +1 -1
  9. package/editor/process/symbolic/makePathSymbolicDisplay.js +1 -1
  10. package/editor/process/symbolic/makePositionedIconDisplaySymbol.js +1 -1
  11. package/editor/view/ecs/components/GridObstacleController.js +2 -2
  12. package/editor/view/ecs/components/TerrainController.js +2 -2
  13. package/package.json +1 -1
  14. package/samples/terrain/editor.js +2 -2
  15. package/src/core/UUID.spec.js +8 -0
  16. package/src/core/bvh2/bvh3/ExplicitBinaryBoundingVolumeHierarchy.d.ts +4 -0
  17. package/src/core/bvh2/bvh3/ExplicitBinaryBoundingVolumeHierarchy.js +57 -55
  18. package/src/core/bvh2/bvh3/ExplicitBinaryBoundingVolumeHierarchy.spec.js +54 -0
  19. package/src/core/bvh2/bvh3/ebvh_build_for_geometry_morton.js +3 -3
  20. package/src/core/bvh2/bvh3/ebvh_build_for_geometry_morton.spec.js +60 -0
  21. package/src/core/bvh2/visual/convert_bvh_to_dot_format_string.js +2 -2
  22. package/src/core/cache/Cache.d.ts +4 -0
  23. package/src/core/cache/Cache.js +32 -18
  24. package/src/core/cache/Cache.spec.js +33 -0
  25. package/src/core/cache/CacheElement.js +1 -0
  26. package/src/core/cache/FrequencySketch.js +26 -23
  27. package/src/core/cache/FrequencySketch.spec.js +5 -0
  28. package/src/core/cache/LoadingCache.d.ts +2 -0
  29. package/src/core/cache/LoadingCache.js +16 -7
  30. package/src/core/cache/LoadingCache.spec.js +24 -0
  31. package/src/core/collection/HashMap.d.ts +2 -0
  32. package/src/core/collection/HashMap.spec.js +51 -2
  33. package/src/core/collection/list/List.d.ts +13 -1
  34. package/src/core/collection/list/List.js +702 -684
  35. package/src/core/collection/list/List.spec.js +93 -0
  36. package/src/core/collection/map/AsyncLoadingCache.js +1 -0
  37. package/src/core/fsm/simple/SimpleStateMachine.js +23 -22
  38. package/src/core/function/extractFunctionBody.spec.js +15 -0
  39. package/src/core/geom/2d/convex-hull/convex_hull_monotone_2d.js +69 -33
  40. package/src/core/geom/2d/convex-hull/convex_hull_monotone_2d.spec.js +33 -0
  41. package/src/core/geom/2d/convex-hull/orientation3.js +55 -10
  42. package/src/core/geom/2d/quad-tree/PointQuadTree.js +10 -0
  43. package/src/core/geom/3d/aabb/aabb3_array_combine.js +3 -3
  44. package/src/core/graph/{convertGraphToDotString.js → convert_graph_to_dot_string.js} +1 -1
  45. package/src/core/graph/convert_graph_to_dot_string.spec.js +28 -0
  46. package/src/core/math/noise/sdnoise.js +5 -7
  47. package/src/core/math/noise/sdnoise.spec.js +87 -0
  48. package/src/core/process/matcher/Matchers.js +1 -1
  49. package/src/engine/asset/loaders/image/png/PNG.spec.js +5 -0
  50. package/src/engine/asset/loaders/image/png/PNGReader.spec.js +5 -0
  51. package/src/engine/asset/loaders/image/png/crc.spec.js +15 -0
  52. package/src/engine/{Platform.js → browserInfo.js} +1 -5
  53. package/src/engine/ecs/EntityBlueprint.js +4 -0
  54. package/src/engine/ecs/EntityBuilder.js +48 -49
  55. package/src/engine/ecs/EntityBuilderFlags.js +2 -2
  56. package/src/engine/ecs/fow/FogOfWar.js +48 -54
  57. package/src/engine/ecs/guid/GUID.js +1 -0
  58. package/src/engine/ecs/{systems → renderable}/RenderSystem.d.ts +1 -1
  59. package/src/engine/ecs/{systems → renderable}/RenderSystem.js +10 -38
  60. package/src/engine/ecs/renderable/Renderable.d.ts +25 -0
  61. package/src/engine/ecs/{components → renderable}/Renderable.js +18 -83
  62. package/src/engine/ecs/renderable/Renderable.spec.js +10 -0
  63. package/src/engine/ecs/speaker/VoiceSystem.js +15 -9
  64. package/src/engine/ecs/systems/MeshColliderSystem.js +1 -1
  65. package/src/engine/ecs/systems/RangedAttackSystem.js +1 -1
  66. package/src/engine/ecs/systems/ViewportMeshProjectionSystem.js +1 -1
  67. package/src/engine/ecs/terrain/ecs/layers/TerrainLayers.js +2 -2
  68. package/src/engine/ecs/terrain/ecs/splat/SplatMapOptimizerDebugger.js +3 -3
  69. package/src/engine/ecs/terrain/ecs/splat/SplatMapping.js +2 -2
  70. package/src/engine/ecs/terrain/overlay/TerrainOverlay.js +2 -2
  71. package/src/engine/ecs/terrain/util/paintTerrainOverlayViaLookupTable.js +2 -2
  72. package/src/engine/graphics/copy_transform_to_threejs_object.js +12 -0
  73. package/src/engine/graphics/debug/VisualSymbolLine.js +1 -1
  74. package/src/engine/graphics/ecs/decal/DecalSystem.js +1 -1
  75. package/src/engine/graphics/ecs/highlight/renderer/makeGaussianBlurShader.js +1 -4
  76. package/src/engine/graphics/ecs/highlight/system/RenderableHighlightSystem.d.ts +1 -1
  77. package/src/engine/graphics/ecs/highlight/system/RenderableHighlightSystem.js +2 -2
  78. package/src/engine/graphics/ecs/mesh/applyTransformToThreeObject.js +2 -5
  79. package/src/engine/graphics/ecs/path/ribbon/RibbonPathBuilder.js +2 -2
  80. package/src/engine/graphics/geometry/optimization/merge/prototypeGeometryMerge.js +1 -1
  81. package/src/engine/graphics/particles/particular/engine/utils/volume/prototypeParticleVolume.js +1 -1
  82. package/src/engine/graphics/render/forward_plus/plugin/ptototypeFPPlugin.js +1 -1
  83. package/src/engine/graphics/sh3/path_tracer/prototypePathTracer.js +2 -2
  84. package/src/engine/graphics/shaders/SoftOutlineShader.js +2 -4
  85. package/src/engine/graphics/texture/atlas/CachingTextureAtlas.spec.js +24 -0
  86. package/src/engine/graphics/texture/atlas/TextureAtlas.spec.js +46 -0
  87. package/src/engine/graphics/texture/sampler/SampleTraverser.js +1 -1
  88. package/src/engine/graphics/texture/sampler/bicubic.spec.js +13 -0
  89. package/src/engine/graphics/texture/sampler/differenceSampler.js +1 -1
  90. package/src/engine/graphics/texture/sampler/distance/computeSignedDistanceField_NaiveFlood.js +5 -1
  91. package/src/engine/graphics/texture/sampler/distance/computeSignedDistanceField_NaiveFlood.spec.js +183 -0
  92. package/src/engine/graphics/texture/sampler/filter/filter_lanczos3.js +20 -0
  93. package/src/engine/graphics/texture/sampler/filter/mitchell.js +0 -21
  94. package/src/engine/graphics/texture/sampler/filter/mitchell_v1.js +21 -0
  95. package/src/engine/graphics/texture/sampler/filter/sampler2d_scale_down_generic.js +17 -16
  96. package/src/engine/graphics/texture/sampler/prototypeSamplerFiltering.js +11 -9
  97. package/src/engine/graphics/texture/sampler/{scaleSampler2D.js → resize/sampler2d_scale.js} +8 -8
  98. package/src/engine/graphics/texture/sampler/resize/sampler2d_scale.spec.js +73 -0
  99. package/src/engine/graphics/texture/sampler/{sampler2_d_scale_down_lanczos.js → resize/sampler2d_scale_down_lanczos.js} +3 -24
  100. package/src/engine/graphics/texture/sampler/resize/sampler2d_scale_down_lanczos.spec.js +29 -0
  101. package/src/engine/graphics/texture/sampler/{sampler2d_scale_down_linear.js → resize/sampler2d_scale_down_linear.js} +5 -5
  102. package/src/engine/graphics/texture/sampler/resize/sampler2d_scale_down_linear.spec.js +44 -0
  103. package/src/engine/graphics/texture/sampler/resize/{sampler2d_downsample_mipmap.js → sampler2d_scale_down_mipmap.js} +2 -2
  104. package/src/engine/graphics/texture/sampler/resize/{sampler2d_downsample_mipmap.spec.js → sampler2d_scale_down_mipmap.spec.js} +2 -2
  105. package/src/engine/graphics/texture/sampler/{genericResampleSampler2D.js → resize/sampler2d_scale_generic.js} +16 -12
  106. package/src/engine/graphics/texture/sampler/{upsampleSampler2D.js → resize/sampler2d_scale_up_linear.js} +5 -2
  107. package/src/engine/graphics/texture/sampler/resize/sampler2d_scale_up_linear.spec.js +14 -0
  108. package/src/engine/graphics/texture/sampler/sampler2d_channel_compute_min_indices.js +4 -2
  109. package/src/engine/graphics/texture/sampler/sampler2d_channel_compute_min_indices.spec.js +15 -0
  110. package/src/engine/graphics/texture/sampler/util/drawSamplerHTML.js +2 -2
  111. package/src/engine/graphics/three/expand_aabb_by_transformed_three_object.js +66 -0
  112. package/src/engine/graphics/three/expand_aabb_by_transformed_three_object.spec.js +108 -0
  113. package/src/engine/graphics/trail/TemporalPath.js +83 -78
  114. package/src/engine/graphics/trail/TemporalPath.spec.js +5 -0
  115. package/src/engine/graphics/trail/x/RibbonX.spec.js +5 -0
  116. package/src/engine/input/devices/InputDeviceSwitch.spec.js +5 -0
  117. package/src/engine/input/ecs/{InputBinding.js → components/InputBinding.js} +1 -1
  118. package/src/engine/input/ecs/components/InputController.js +2 -2
  119. package/src/engine/input/ecs/ism/InputBinding.js +2 -2
  120. package/src/engine/input/ecs/util/TerrainCameraTargetSampler.js +1 -1
  121. package/src/engine/input/ecs/util/TopDownCameraControllerHelper.js +1 -1
  122. package/src/engine/intelligence/behavior/behavior_to_dot.spec.js +25 -0
  123. package/src/engine/intelligence/behavior/util/DelayBehavior.js +6 -4
  124. package/src/engine/intelligence/blackboard/Blackboard.d.ts +2 -0
  125. package/src/engine/intelligence/blackboard/Blackboard.js +36 -2
  126. package/src/engine/intelligence/blackboard/Blackboard.spec.js +49 -0
  127. package/src/engine/intelligence/blackboard/BlackboardSerializationAdapter.spec.js +2 -0
  128. package/src/engine/navigation/grid/{AStar.js → find_path_on_grid_astar.js} +21 -18
  129. package/src/engine/navigation/grid/find_path_on_grid_astar.spec.js +7 -0
  130. package/src/engine/sound/ecs/SoundListenerSystem.js +1 -1
  131. package/src/generation/markers/debug/visualizeMarkers.js +1 -1
  132. package/src/engine/MeepSettings.js +0 -9
  133. package/src/engine/User.js +0 -28
  134. package/src/engine/UserController.js +0 -273
  135. package/src/engine/ecs/components/AABB.js +0 -33
  136. package/src/engine/ecs/components/AABBCollider.js +0 -15
  137. package/src/engine/ecs/components/Renderable.d.ts +0 -14
  138. package/src/engine/ecs/grid/Sampler2DDecoder.js +0 -57
  139. package/src/engine/ecs/grid/makeTerrainGeometry.js +0 -110
  140. package/src/engine/ecs/systems/AABBColliderSystem.js +0 -61
  141. package/src/engine/ecs/systems/AABBSystem.js +0 -89
  142. package/src/engine/graphics/texture/sampler/sampler2d_make_array_filler_function.js +0 -65
  143. package/src/engine/graphics/texture/sampler/sampler2d_scale_down_linear.spec.js +0 -17
  144. package/src/engine/graphics/trail/x/simulator/RibbonState.js +0 -10
  145. package/src/engine/grid/Grid.js +0 -131
  146. package/src/engine/navigation/grid/GridField.js +0 -328
  147. /package/src/engine/ecs/{components → renderable}/RenderableFlags.js +0 -0
@@ -0,0 +1,21 @@
1
+ import { assert } from "../../../../../core/assert.js";
2
+
3
+ /**
4
+ * Hand-optimized mitchell function with c = 0.3333333 and b = 0.3333333
5
+ * NOTE: assumes non-negative values only
6
+ * @param {number} x
7
+ * @returns {number}
8
+ */
9
+ export function mitchell_v1(x) {
10
+ assert.greaterThanOrEqual(x, 0);
11
+
12
+ if (x < 1.0) {
13
+ return 0.8888888888888888 + x * x * (-2 + x * 1.1666666666666667);
14
+ }
15
+ if (x < 2.0) {
16
+ return 1.7777777777777777 + x * (-3.3333333333333335 + x * (2 + x * -0.3888888888888889));
17
+ }
18
+ return 0.0;
19
+ }
20
+
21
+ mitchell_v1.support = 2;
@@ -3,27 +3,30 @@ import { min2 } from "../../../../../core/math/min2.js";
3
3
 
4
4
  /**
5
5
  *
6
- * @param {Sampler2D} source
7
- * @param {Sampler2D} destination
6
+ * @param {Sampler2D} input
7
+ * @param {Sampler2D} output
8
8
  * @param {(number)=>number|{support:number}} weight_computer
9
9
  * @param {number} support size of support kernel
10
10
  */
11
- export function sampler2d_scale_down_generic(source, destination, weight_computer, support = weight_computer.support) {
11
+ export function sampler2d_scale_down_generic(
12
+ input, output,
13
+ weight_computer, support = weight_computer.support
14
+ ) {
12
15
 
13
- const d_w = destination.width;
14
- const d_h = destination.height;
16
+ const d_w = output.width;
17
+ const d_h = output.height;
15
18
 
16
- const item_size = destination.itemSize;
19
+ const item_size = output.itemSize;
17
20
 
18
- const source_width = source.width;
19
- const source_height = source.height;
21
+ const source_width = input.width;
22
+ const source_height = input.height;
20
23
 
21
24
  if (source_width < d_w || source_height < d_h) {
22
25
  throw new Error('Invalid scale, source is larger than destination in at least 1 dimension');
23
26
  }
24
27
 
25
- const source_data = source.data;
26
- const destination_data = destination.data;
28
+ const source_data = input.data;
29
+ const destination_data = output.data;
27
30
 
28
31
  const ratio_x = source_width / d_w;
29
32
  const ratio_y = source_height / d_h;
@@ -35,7 +38,7 @@ export function sampler2d_scale_down_generic(source, destination, weight_compute
35
38
  const range2_x = Math.ceil(ratio_x * support / 2);
36
39
  const range2_y = Math.ceil(ratio_y * support / 2);
37
40
 
38
- const sample = new Array(item_size);
41
+ const sample = new Float64Array(item_size);
39
42
 
40
43
  let v, u, i, j, k;
41
44
 
@@ -55,11 +58,6 @@ export function sampler2d_scale_down_generic(source, destination, weight_compute
55
58
  const source_x1 = min2(i_center_x + range2_x, source_width - 1);
56
59
 
57
60
  let z = 0;
58
- // reset sample
59
- for (i = 0; i < item_size; i++) {
60
- sample[i] = 0;
61
- }
62
-
63
61
  for (j = source_y0; j <= source_y1; j++) {
64
62
 
65
63
  const f_y = (j - center_y);
@@ -102,6 +100,9 @@ export function sampler2d_scale_down_generic(source, destination, weight_compute
102
100
 
103
101
  for (i = 0; i < item_size; i++) {
104
102
  destination_data[texel_address + i] = sample[i] * inv_z;
103
+
104
+ // reset sample for next tap
105
+ sample[i] = 0;
105
106
  }
106
107
  }
107
108
  }
@@ -2,20 +2,22 @@ import { EngineHarness } from "../../../EngineHarness.js";
2
2
  import { ImageRGBADataLoader } from "../../../asset/loaders/image/ImageRGBADataLoader.js";
3
3
  import sampler2D2Canvas from "./Sampler2D2Canvas.js";
4
4
  import { CanvasView } from "../../../../view/elements/CanvasView.js";
5
- import { filter_lanczos3, sampler2D_scale_down_lanczos } from "./sampler2_d_scale_down_lanczos.js";
5
+ import { sampler2d_scale_down_lanczos } from "./resize/sampler2d_scale_down_lanczos.js";
6
6
  import { Sampler2D } from "./Sampler2D.js";
7
- import { genericResampleSampler2D } from "./genericResampleSampler2D.js";
7
+ import { sampler2d_scale_generic } from "./resize/sampler2d_scale_generic.js";
8
8
  import Vector2 from "../../../../core/geom/Vector2.js";
9
9
  import LabelView from "../../../../view/common/LabelView.js";
10
10
  import EmptyView from "../../../../view/elements/EmptyView.js";
11
- import { sampler2d_downsample_mipmap } from "./resize/sampler2d_downsample_mipmap.js";
11
+ import { sampler2d_scale_down_mipmap } from "./resize/sampler2d_scale_down_mipmap.js";
12
12
  import { kaiser_bessel_window } from "./filter/kaiser_bessel_window.js";
13
13
  import { sampler2d_scale_down_generic } from "./filter/sampler2d_scale_down_generic.js";
14
- import { mitchell, mitchell_v1 } from "./filter/mitchell.js";
14
+ import { mitchell } from "./filter/mitchell.js";
15
15
  import { kaiser_1 } from "./filter/kaiser_1.js";
16
16
  import { triangle } from "./filter/triangle.js";
17
17
  import { box } from "./filter/box.js";
18
18
  import { gaussian } from "./filter/gaussian.js";
19
+ import { mitchell_v1 } from "./filter/mitchell_v1.js";
20
+ import { filter_lanczos3 } from "./filter/filter_lanczos3.js";
19
21
 
20
22
  function grid({ engine, input, transforms, size = new Vector2(input.width, input.height), display_labels = true }) {
21
23
 
@@ -158,7 +160,7 @@ new EngineHarness().initialize({
158
160
 
159
161
  // sampler2D_lanczos(source, small);
160
162
  console.time('filter');
161
- sampler2D_scale_down_lanczos(source, small, 3);
163
+ sampler2d_scale_down_lanczos(source, small, 3);
162
164
  console.timeEnd('filter');
163
165
 
164
166
  display(engine, small, COMPARE_X_OFFSET, 0);
@@ -170,7 +172,7 @@ new EngineHarness().initialize({
170
172
 
171
173
  const small_scale_2 = Sampler2D.uint8(source.itemSize, TARGET_WIDTH, TARGET_HEIGHT);
172
174
  console.time('filter-generic');
173
- genericResampleSampler2D(source, small_scale_2);
175
+ sampler2d_scale_generic(source, small_scale_2);
174
176
  console.timeEnd('filter-generic');
175
177
  display(engine, small_scale_2, COMPARE_X_OFFSET, TARGET_HEIGHT);
176
178
  })
@@ -251,7 +253,7 @@ function test_sampling(source, engine) {
251
253
  params.label = 'mip';
252
254
 
253
255
 
254
- sampler2d_downsample_mipmap(input, out);
256
+ sampler2d_scale_down_mipmap(input, out);
255
257
 
256
258
  },
257
259
  (out, input, params) => {
@@ -261,7 +263,7 @@ function test_sampling(source, engine) {
261
263
 
262
264
  // return;
263
265
 
264
- sampler2D_scale_down_lanczos(input, out, lobes);
266
+ sampler2d_scale_down_lanczos(input, out, lobes);
265
267
 
266
268
  },
267
269
  (out, input, params) => {
@@ -283,7 +285,7 @@ function test_sampling(source, engine) {
283
285
 
284
286
  return;
285
287
 
286
- sampler2D_scale_down_lanczos(input, out, lobes);
288
+ sampler2d_scale_down_lanczos(input, out, lobes);
287
289
 
288
290
  },
289
291
  (out, input, params) => {
@@ -1,15 +1,15 @@
1
- import { assert } from "../../../../core/assert.js";
1
+ import { assert } from "../../../../../core/assert.js";
2
2
  import { sampler2d_scale_down_linear } from "./sampler2d_scale_down_linear.js";
3
- import { Sampler2D } from "./Sampler2D.js";
4
- import { upsampleSampler2D } from "./upsampleSampler2D.js";
5
- import { genericResampleSampler2D } from "./genericResampleSampler2D.js";
3
+ import { Sampler2D } from "../Sampler2D.js";
4
+ import { sampler2d_scale_up_linear } from "./sampler2d_scale_up_linear.js";
5
+ import { sampler2d_scale_generic } from "./sampler2d_scale_generic.js";
6
6
 
7
7
  /**
8
8
  *
9
9
  * @param {Sampler2D} input
10
10
  * @param {Sampler2D} output
11
11
  */
12
- export function scaleSampler2D(input, output) {
12
+ export function sampler2d_scale(input, output) {
13
13
  assert.equal(input.isSampler2D, true, 'input.isSampler2D !== true');
14
14
  assert.equal(output.isSampler2D, true, 'output.isSampler2D !== true');
15
15
 
@@ -32,13 +32,13 @@ export function scaleSampler2D(input, output) {
32
32
  sampler2d_scale_down_linear(input, output);
33
33
  } else {
34
34
  // generic downsample
35
- genericResampleSampler2D(input, output, 3);
35
+ sampler2d_scale_generic(input, output);
36
36
  }
37
37
  } else if (sourceWidth < targetWidth && sourceHeight < targetHeight) {
38
38
  // upscaling
39
- upsampleSampler2D(input, output);
39
+ sampler2d_scale_up_linear(input, output);
40
40
  } else {
41
41
  // mixed resampling
42
- genericResampleSampler2D(input, output);
42
+ sampler2d_scale_generic(input, output);
43
43
  }
44
44
  }
@@ -0,0 +1,73 @@
1
+ import { Sampler2D } from "../Sampler2D.js";
2
+ import { sampler2d_scale } from "./sampler2d_scale.js";
3
+
4
+ test("scale 1:1", () => {
5
+
6
+ const input = new Sampler2D(new Uint8Array([17]), 1, 1, 1);
7
+ const output = new Sampler2D(new Uint8Array([3]), 1, 1, 1);
8
+
9
+ sampler2d_scale(input, output);
10
+
11
+ expect(output.readChannel(0, 0, 0)).toEqual(17);
12
+ });
13
+
14
+ test("scale up 1x1 to 2x2", () => {
15
+ const input = new Sampler2D([7], 1, 1, 1);
16
+ const output = new Sampler2D([1, 2, 3, 4], 1, 2, 2);
17
+
18
+ sampler2d_scale(input, output);
19
+
20
+ expect(output.readChannel(0, 0, 0)).toBe(7);
21
+ expect(output.readChannel(1, 0, 0)).toBe(7);
22
+ expect(output.readChannel(0, 1, 0)).toBe(7);
23
+ expect(output.readChannel(1, 1, 0)).toBe(7);
24
+ });
25
+
26
+ test("scale up 1x1 to 3x1", () => {
27
+ const input = new Sampler2D([7], 1, 1, 1);
28
+ const output = new Sampler2D([1, 2, 3], 1, 3, 1);
29
+
30
+ sampler2d_scale(input, output);
31
+
32
+ expect(output.readChannel(0, 0, 0)).toBe(7);
33
+ expect(output.readChannel(1, 0, 0)).toBe(7);
34
+ expect(output.readChannel(2, 0, 0)).toBe(7);
35
+ });
36
+
37
+ test("scale up 1x1 to 1x3", () => {
38
+ const input = new Sampler2D([7], 1, 1, 1);
39
+ const output = new Sampler2D([1, 2, 3], 1, 1, 3);
40
+
41
+ sampler2d_scale(input, output);
42
+
43
+ expect(output.readChannel(0, 0, 0)).toBe(7);
44
+ expect(output.readChannel(0, 1, 0)).toBe(7);
45
+ expect(output.readChannel(0, 2, 0)).toBe(7);
46
+ });
47
+
48
+ test("scale down 2x2 to 1x1", () => {
49
+ const output = new Sampler2D([7], 1, 1, 1);
50
+ const input = new Sampler2D([1, 2, 3, 4], 1, 2, 2);
51
+
52
+ sampler2d_scale(input, output);
53
+
54
+ expect(output.readChannel(0, 0, 0)).toBeCloseTo(2.5);
55
+ });
56
+
57
+ test("scale down 3x1 to 1x1", () => {
58
+ const output = new Sampler2D([7], 1, 1, 1);
59
+ const input = new Sampler2D([1, 2, 3], 1, 3, 1);
60
+
61
+ sampler2d_scale(input, output);
62
+
63
+ expect(output.readChannel(0, 0, 0)).toBeCloseTo(2);
64
+ });
65
+
66
+ test("scale down 1x3 to 1x1", () => {
67
+ const output = new Sampler2D([7], 1, 1, 1);
68
+ const input = new Sampler2D([1, 2, 3], 1, 1, 3);
69
+
70
+ sampler2d_scale(input, output);
71
+
72
+ expect(output.readChannel(0, 0, 0)).toBeCloseTo(2);
73
+ });
@@ -1,5 +1,5 @@
1
- import { max2 } from "../../../../core/math/max2.js";
2
- import { min2 } from "../../../../core/math/min2.js";
1
+ import { max2 } from "../../../../../core/math/max2.js";
2
+ import { min2 } from "../../../../../core/math/min2.js";
3
3
 
4
4
 
5
5
  /**
@@ -63,27 +63,6 @@ function lanczos_orig(x, lobes) {
63
63
  return (lobes * Math.sin(Math.PI * x) * Math.sin(Math.PI * x / lobes)) / (Math.PI * Math.PI * x * x);
64
64
  }
65
65
 
66
- export function filter_lanczos3(x) {
67
- // assume the input is positive
68
-
69
- // if (x < 0) {
70
- // x = -x;
71
- // }
72
-
73
- if (x > 3) {
74
- return 0;
75
- }
76
-
77
- if (x < 1.1920929e-7) {
78
- return 1;
79
- }
80
-
81
- return (3 * Math.sin(Math.PI * x) * Math.sin(Math.PI * x / 3)) / (Math.PI * Math.PI * x * x);
82
-
83
- }
84
-
85
- filter_lanczos3.support = 3;
86
-
87
66
 
88
67
  /**
89
68
  * Good for down-sampling
@@ -91,7 +70,7 @@ filter_lanczos3.support = 3;
91
70
  * @param {Sampler2D} destination
92
71
  * @param {number} [lobes]
93
72
  */
94
- export function sampler2D_scale_down_lanczos(source, destination, lobes = 2) {
73
+ export function sampler2d_scale_down_lanczos(source, destination, lobes = 2) {
95
74
 
96
75
  const d_w = destination.width;
97
76
  const d_h = destination.height;
@@ -0,0 +1,29 @@
1
+ import { sampler2d_scale_down_lanczos } from "./sampler2d_scale_down_lanczos.js";
2
+ import { Sampler2D } from "../Sampler2D.js";
3
+
4
+ test("scale down 2x2 to 1x1 single channel", () => {
5
+ const input = new Sampler2D([1, 2, 3, 4], 1, 2, 2);
6
+ const output = new Sampler2D([7], 1, 1, 1);
7
+
8
+ sampler2d_scale_down_lanczos(input, output);
9
+
10
+ expect(output.readChannel(0, 0, 0)).toBeCloseTo(2.5);
11
+ });
12
+
13
+ test("scale down 3x1 to 1x1", () => {
14
+ const input = new Sampler2D([1, 2, 3], 1, 3, 1);
15
+ const output = new Sampler2D([7], 1, 1, 1);
16
+
17
+ sampler2d_scale_down_lanczos(input, output);
18
+
19
+ expect(output.readChannel(0, 0, 0)).toBeCloseTo(2);
20
+ });
21
+
22
+ test("scale down 1x3 to 1x1", () => {
23
+ const input = new Sampler2D([1, 2, 3], 1, 1, 3);
24
+ const output = new Sampler2D([7], 1, 1, 1);
25
+
26
+ sampler2d_scale_down_lanczos(input, output);
27
+
28
+ expect(output.readChannel(0, 0, 0)).toBeCloseTo(2);
29
+ });
@@ -1,4 +1,4 @@
1
- import { assert } from "../../../../core/assert.js";
1
+ import { assert } from "../../../../../core/assert.js";
2
2
 
3
3
  /**
4
4
  *
@@ -6,8 +6,8 @@ import { assert } from "../../../../core/assert.js";
6
6
  * @param {Sampler2D} output
7
7
  */
8
8
  export function sampler2d_scale_down_linear(input, output) {
9
- assert.notEqual(input, undefined, 'input is undefined');
10
- assert.notEqual(output, undefined, 'output is undefined');
9
+ assert.defined(input, 'input');
10
+ assert.defined(output, 'output');
11
11
 
12
12
  const iW = input.width;
13
13
  const iH = input.height;
@@ -21,8 +21,8 @@ export function sampler2d_scale_down_linear(input, output) {
21
21
 
22
22
  assert.equal(input.itemSize, output.itemSize, `input.itemSize(=${input.itemSize}) is not equal to output.itemSize(=${output.itemSize})`);
23
23
 
24
- assert.ok(Number.isInteger(sW), `x scale must be an integer, instead was ${sW}`);
25
- assert.ok(Number.isInteger(sH), `y scale must be an integer, instead was ${sH}`);
24
+ assert.notNaN(sW, "x scale");
25
+ assert.notNaN(sH, "y scale");
26
26
 
27
27
  assert.ok(sW >= 1, `x scale must be positive, instead was ${sW}`);
28
28
  assert.ok(sH >= 1, `y scale must be positive, instead was ${sH}`);
@@ -0,0 +1,44 @@
1
+ import { Sampler2D } from "../Sampler2D.js";
2
+ import { sampler2d_scale_down_linear } from "./sampler2d_scale_down_linear.js";
3
+
4
+ test('2x2 -> 1x1, 2 channels', () => {
5
+ const input = Sampler2D.float32(2, 2, 2);
6
+ const output = Sampler2D.float32(2, 1, 1);
7
+
8
+ input.set(0, 0, [1, 3]);
9
+ input.set(1, 0, [5, 7]);
10
+ input.set(0, 1, [11, 13]);
11
+ input.set(1, 1, [17, 19]);
12
+
13
+ sampler2d_scale_down_linear(input, output);
14
+
15
+ expect(output.data[0]).toEqual(8.5);
16
+ expect(output.data[1]).toEqual(10.5);
17
+ });
18
+
19
+ test("scale down 2x2 to 1x1 single channel", () => {
20
+ const output = new Sampler2D([7], 1, 1, 1);
21
+ const input = new Sampler2D([1, 2, 3, 4], 1, 2, 2);
22
+
23
+ sampler2d_scale_down_linear(input, output);
24
+
25
+ expect(output.readChannel(0, 0, 0)).toBeCloseTo(2.5);
26
+ });
27
+
28
+ test("scale down 3x1 to 1x1", () => {
29
+ const output = new Sampler2D([7], 1, 1, 1);
30
+ const input = new Sampler2D([1, 2, 3], 1, 3, 1);
31
+
32
+ sampler2d_scale_down_linear(input, output);
33
+
34
+ expect(output.readChannel(0, 0, 0)).toBeCloseTo(2);
35
+ });
36
+
37
+ test("scale down 1x3 to 1x1", () => {
38
+ const output = new Sampler2D([7], 1, 1, 1);
39
+ const input = new Sampler2D([1, 2, 3], 1, 1, 3);
40
+
41
+ sampler2d_scale_down_linear(input, output);
42
+
43
+ expect(output.readChannel(0, 0, 0)).toBeCloseTo(2);
44
+ });
@@ -1,5 +1,5 @@
1
1
  import { Sampler2D } from "../Sampler2D.js";
2
- import { sampler2d_scale_down_linear } from "../sampler2d_scale_down_linear.js";
2
+ import { sampler2d_scale_down_linear } from "./sampler2d_scale_down_linear.js";
3
3
  import { inverseLerp } from "../../../../../core/math/inverseLerp.js";
4
4
  import { lerp } from "../../../../../core/math/lerp.js";
5
5
 
@@ -8,7 +8,7 @@ import { lerp } from "../../../../../core/math/lerp.js";
8
8
  * @param {Sampler2D} source
9
9
  * @param {Sampler2D} destination
10
10
  */
11
- export function sampler2d_downsample_mipmap(source, destination) {
11
+ export function sampler2d_scale_down_mipmap(source, destination) {
12
12
  let current_mip = source;
13
13
  let previous_mip = source;
14
14
 
@@ -1,5 +1,5 @@
1
1
  import { Sampler2D } from "../Sampler2D.js";
2
- import { sampler2d_downsample_mipmap } from "./sampler2d_downsample_mipmap.js";
2
+ import { sampler2d_scale_down_mipmap } from "./sampler2d_scale_down_mipmap.js";
3
3
 
4
4
  test("downsample solid fill from 2x2 to 1x1", () => {
5
5
  const input = Sampler2D.uint8(1, 2, 2);
@@ -7,7 +7,7 @@ test("downsample solid fill from 2x2 to 1x1", () => {
7
7
  input.data.fill(7);
8
8
 
9
9
  const result = Sampler2D.uint8(1, 1, 1);
10
- sampler2d_downsample_mipmap(input, result);
10
+ sampler2d_scale_down_mipmap(input, result);
11
11
 
12
12
  expect(result.readChannel(0, 0, 0)).toBeCloseTo(7)
13
13
  });
@@ -1,18 +1,22 @@
1
- import { max2 } from "../../../../core/math/max2.js";
1
+ import { max2 } from "../../../../../core/math/max2.js";
2
+ import { assert } from "../../../../../core/assert.js";
2
3
 
3
4
  /**
4
- *
5
- * @param {Sampler2D} source
6
- * @param {Sampler2D} target
5
+ * Relatively slow, but handles all cases
6
+ * @param {Sampler2D} input
7
+ * @param {Sampler2D} output
7
8
  */
8
- export function genericResampleSampler2D(source, target) {
9
- const target_width = target.width;
10
- const target_height = target.height;
9
+ export function sampler2d_scale_generic(input, output) {
10
+ assert.defined(input, 'input');
11
+ assert.defined(output, 'output');
12
+
13
+ const target_width = output.width;
14
+ const target_height = output.height;
11
15
 
12
16
  // build kernel
13
17
 
14
- const u_scale = source.width / target_width;
15
- const v_scale = source.height / target_height;
18
+ const u_scale = input.width / target_width;
19
+ const v_scale = input.height / target_height;
16
20
 
17
21
  const kernel_width = max2(1, Math.ceil(u_scale));
18
22
  const kernel_height = max2(1, Math.ceil(v_scale));
@@ -20,7 +24,7 @@ export function genericResampleSampler2D(source, target) {
20
24
  const kernel_size = kernel_width * kernel_height;
21
25
  const kernel_size_inv = 1 / kernel_size;
22
26
 
23
- const itemSize = source.itemSize;
27
+ const itemSize = input.itemSize;
24
28
 
25
29
  const sample = new Float32Array(itemSize);
26
30
 
@@ -47,7 +51,7 @@ export function genericResampleSampler2D(source, target) {
47
51
  for (k_x = 0; k_x < kernel_width; k_x++) {
48
52
 
49
53
  for (i = 0; i < itemSize; i++) {
50
- sample[i] += source.sampleChannelBilinear(source_x + k_x, source_y + k_y, i);
54
+ sample[i] += input.sampleChannelBilinear(source_x + k_x, source_y + k_y, i);
51
55
  }
52
56
 
53
57
  }
@@ -55,7 +59,7 @@ export function genericResampleSampler2D(source, target) {
55
59
 
56
60
  for (i = 0; i < itemSize; i++) {
57
61
  // dilute sample
58
- target.data[output_texel_address + i] = sample[i] * kernel_size_inv;
62
+ output.data[output_texel_address + i] = sample[i] * kernel_size_inv;
59
63
 
60
64
  //reset sample
61
65
  sample[i] = 0;
@@ -1,11 +1,14 @@
1
- import { assert } from "../../../../core/assert.js";
1
+ import { assert } from "../../../../../core/assert.js";
2
2
 
3
3
  /**
4
4
  *
5
5
  * @param {Sampler2D} input
6
6
  * @param {Sampler2D} output
7
7
  */
8
- export function upsampleSampler2D(input, output) {
8
+ export function sampler2d_scale_up_linear(input, output) {
9
+ assert.defined(input, 'input');
10
+ assert.defined(output, 'output');
11
+
9
12
  const targetItemSize = output.itemSize;
10
13
 
11
14
  assert.equal(input.itemSize, targetItemSize, 'both source and target must have the same number of channels');
@@ -0,0 +1,14 @@
1
+ import { sampler2d_scale_up_linear } from "./sampler2d_scale_up_linear.js";
2
+ import { Sampler2D } from "../Sampler2D.js";
3
+
4
+ test("scale up 1x1 to 2x2", () => {
5
+ const input = new Sampler2D([7], 1, 1, 1);
6
+ const output = new Sampler2D([1, 2, 3, 4], 1, 2, 2);
7
+
8
+ sampler2d_scale_up_linear(input, output);
9
+
10
+ expect(output.readChannel(0, 0, 0)).toBe(7);
11
+ expect(output.readChannel(1, 0, 0)).toBe(7);
12
+ expect(output.readChannel(0, 1, 0)).toBe(7);
13
+ expect(output.readChannel(1, 1, 0)).toBe(7);
14
+ });
@@ -24,7 +24,7 @@ export function sampler2d_channel_compute_min_indices(
24
24
 
25
25
  assert.isArrayLike(result, "result");
26
26
 
27
- const data = this.data;
27
+ const data = sampler.data;
28
28
 
29
29
  const l = data.length;
30
30
 
@@ -35,7 +35,9 @@ export function sampler2d_channel_compute_min_indices(
35
35
 
36
36
  let bestValue = data[channel];
37
37
 
38
- let result_count = 0;
38
+ result[result_offset] = 0;
39
+
40
+ let result_count = 1;
39
41
 
40
42
  for (let i = channel + itemSize; i < l; i += itemSize) {
41
43
  const value = data[i];
@@ -0,0 +1,15 @@
1
+ import { sampler2d_channel_compute_min_indices } from "./sampler2d_channel_compute_min_indices.js";
2
+ import { Sampler2D } from "./Sampler2D.js";
3
+
4
+ test("sanity", () => {
5
+ const result = [];
6
+
7
+ const index_count = sampler2d_channel_compute_min_indices(
8
+ result, 0,
9
+ new Sampler2D([1, 2], 1, 2, 1),
10
+ 0
11
+ );
12
+
13
+ expect(index_count).toEqual(1);
14
+ expect(result).toEqual([0]);
15
+ });
@@ -1,5 +1,5 @@
1
1
  import { Sampler2D } from "../Sampler2D.js";
2
- import { scaleSampler2D } from "../scaleSampler2D.js";
2
+ import { sampler2d_scale } from "../resize/sampler2d_scale.js";
3
3
  import convertSampler2D2Canvas from "../Sampler2D2Canvas.js";
4
4
  import { typedArrayConstructorByInstance } from "../typedArrayConstructorByInstance.js";
5
5
 
@@ -31,7 +31,7 @@ export function drawSamplerHTML(parentNode, sampler, x, y, scale, offset, size)
31
31
 
32
32
  const target = new Sampler2D(new TA(target_width * target_height * sampler.itemSize), sampler.itemSize, target_width, target_height);
33
33
 
34
- scaleSampler2D(sampler, target);
34
+ sampler2d_scale(sampler, target);
35
35
 
36
36
  const c = convertSampler2D2Canvas(target, scale, offset);
37
37
  c.style.zIndex = 1000;
@@ -0,0 +1,66 @@
1
+ import { ensureGeometryBoundingBox } from "../util/ensureGeometryBoundingBox.js";
2
+ import { aabb3_matrix4_project } from "../../../core/geom/3d/aabb/aabb3_matrix4_project.js";
3
+ import { aabb3_array_combine } from "../../../core/geom/3d/aabb/aabb3_array_combine.js";
4
+ import { m4_multiply } from "../../../core/geom/3d/matrix/m4_multiply.js";
5
+
6
+ const scratch_aabb3_array_0 = new Float32Array(6);
7
+ const scratch_aabb3_array_1 = new Float32Array(6);
8
+
9
+ /**
10
+ *
11
+ * @param {number[]|Float32Array} result
12
+ * @param {Object3D} object
13
+ * @param {number[]|Float32Array} transform
14
+ */
15
+ export function expand_aabb_by_transformed_three_object(result, object, transform) {
16
+
17
+ /**
18
+ * @type {BufferGeometry}
19
+ */
20
+ const geometry = object.geometry;
21
+
22
+ if (geometry !== undefined) {
23
+
24
+ ensureGeometryBoundingBox(geometry);
25
+
26
+ const gbb = geometry.boundingBox;
27
+
28
+ const min = gbb.min;
29
+
30
+ const x0 = min.x;
31
+ const y0 = min.y;
32
+ const z0 = min.z;
33
+
34
+ const max = gbb.max;
35
+
36
+ const x1 = max.x;
37
+ const y1 = max.y;
38
+ const z1 = max.z;
39
+
40
+ scratch_aabb3_array_0[0] = x0;
41
+ scratch_aabb3_array_0[1] = y0;
42
+ scratch_aabb3_array_0[2] = z0;
43
+
44
+ scratch_aabb3_array_0[3] = x1;
45
+ scratch_aabb3_array_0[4] = y1;
46
+ scratch_aabb3_array_0[5] = z1;
47
+
48
+ aabb3_matrix4_project(scratch_aabb3_array_1, scratch_aabb3_array_0, transform);
49
+
50
+ aabb3_array_combine(result, result, scratch_aabb3_array_1);
51
+ }
52
+
53
+ const children = object.children;
54
+ const child_count = children.length;
55
+
56
+ for (let i = 0; i < child_count; i++) {
57
+ const child_matrix = new Float32Array(16);
58
+
59
+ const child = children[i];
60
+
61
+ m4_multiply(child_matrix, transform, child.matrix.elements)
62
+
63
+ expand_aabb_by_transformed_three_object(result, child, child_matrix);
64
+ }
65
+
66
+ }