@woosh/meep-engine 2.49.7 → 2.49.9

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 (108) hide show
  1. package/editor/enableEditor.js +1 -8
  2. package/package.json +1 -1
  3. package/samples/terrain/editor.js +2 -2
  4. package/src/core/cache/Cache.js +1 -1
  5. package/src/core/collection/HashSet.js +1 -1
  6. package/src/core/collection/table/RowFirstTableSpec.js +110 -92
  7. package/src/core/collection/table/RowFirstTableSpec.spec.js +49 -0
  8. package/src/core/color/Color.d.ts +4 -2
  9. package/src/core/color/Color.js +7 -8
  10. package/src/core/color/Color.spec.js +93 -0
  11. package/src/core/color/hex2rgb.spec.js +10 -0
  12. package/src/core/color/rgb2hex.js +1 -1
  13. package/src/core/color/rgb2hex.spec.js +13 -0
  14. package/src/core/fsm/simple/SimpleStateMachine.spec.js +75 -0
  15. package/src/core/fsm/simple/SimpleStateMachineDescription.js +1 -1
  16. package/src/core/fsm/simple/SimpleStateMachineDescription.spec.js +32 -0
  17. package/src/core/geom/2d/Rectangle.spec.js +51 -0
  18. package/src/core/geom/3d/aabb/aabb3_intersects_ray.spec.js +90 -0
  19. package/src/core/geom/3d/line/line3_compute_nearest_point_to_point.spec.js +61 -0
  20. package/src/core/geom/3d/morton/mortonEncode_magicbits.js +1 -34
  21. package/src/core/geom/3d/morton/split_by_2.js +17 -0
  22. package/src/core/geom/3d/morton/split_by_3.js +16 -0
  23. package/src/core/geom/3d/plane/computePlaneLineIntersection.js +6 -1
  24. package/src/core/geom/3d/sphere/sphere_intersects_ray.spec.js +11 -0
  25. package/src/core/geom/3d/sphere/sphere_radius_sqr_from_v3_array_transformed.spec.js +8 -0
  26. package/src/core/geom/3d/topology/samples/sampleFloodFill.js +3 -3
  27. package/src/core/geom/3d/topology/struct/binary/io/OrderedEdge.js +1 -1
  28. package/src/core/geom/random/randomPointOnBox.spec.js +57 -0
  29. package/src/core/math/bessel_i0.spec.js +43 -0
  30. package/src/core/math/bessel_j0.js +30 -0
  31. package/src/core/math/hash/murmur3_32.spec.js +8 -0
  32. package/src/core/math/hash/squirrel3.spec.js +16 -0
  33. package/src/core/math/interval/NumericInterval.js +1 -0
  34. package/src/core/math/{bessel_i0.js → modified_bessel_i0.js} +5 -2
  35. package/src/core/math/noise/{create_noise_2d.js → create_simplex_noise_2d.js} +2 -2
  36. package/src/core/math/noise/create_simplex_noise_2d.spec.js +21 -0
  37. package/src/core/math/normalizeArrayVector.spec.js +15 -0
  38. package/src/core/math/physics/irradiance/interpolate_irradiance_linear.spec.js +20 -0
  39. package/src/core/math/physics/irradiance/interpolate_irradiance_lograrithmic.js +4 -4
  40. package/src/core/math/physics/irradiance/interpolate_irradiance_lograrithmic.spec.js +18 -0
  41. package/src/core/math/physics/irradiance/interpolate_irradiance_smith.js +1 -1
  42. package/src/core/math/physics/irradiance/interpolate_irradiance_smith.spec.js +20 -0
  43. package/src/core/math/random/seededRandomMersenneTwister.spec.js +10 -0
  44. package/src/core/math/spline/spline_bezier3.js +1 -1
  45. package/src/core/math/spline/spline_bezier3_bounds.js +2 -1
  46. package/src/core/math/spline/spline_bezier3_bounds.spec.js +37 -0
  47. package/src/core/math/statistics/computeSampleSize_Cochran.spec.js +12 -0
  48. package/src/core/math/statistics/computeStatisticalPartialMedian.js +4 -0
  49. package/src/core/math/statistics/computeStatisticalPartialMedian.spec.js +13 -0
  50. package/src/engine/Engine.d.ts +4 -2
  51. package/src/engine/Engine.js +62 -41
  52. package/src/engine/Engine.spec.js +11 -0
  53. package/src/engine/InputEngine.js +12 -0
  54. package/src/engine/achievements/Achievement.spec.js +21 -0
  55. package/src/engine/animation/curve/compression/prototypeCurveCompression.js +2 -2
  56. package/src/engine/animation/curve/compression/{animation_curve_to_float_array.js → sample_animation_curve_to_float_array.js} +10 -3
  57. package/src/engine/animation/curve/compression/sample_animation_curve_to_float_array.spec.js +29 -0
  58. package/src/engine/animation/curve/draw/build_curve_editor.js +3 -3
  59. package/src/engine/development/performance/RingBufferMetric.js +1 -1
  60. package/src/engine/ecs/animation/Animation.js +2 -180
  61. package/src/engine/ecs/animation/AnimationClip.js +132 -0
  62. package/src/engine/ecs/animation/AnimationClip.spec.js +5 -0
  63. package/src/engine/ecs/animation/AnimationClipFlag.js +7 -0
  64. package/src/engine/ecs/animation/AnimationFlags.js +8 -0
  65. package/src/engine/ecs/animation/AnimationSerializationAdapter.js +32 -0
  66. package/src/engine/ecs/systems/AnimationSystem.js +3 -1
  67. package/src/engine/graphics/GraphicsEngine.js +2 -13
  68. package/src/engine/graphics/camera/testClippingPlaneComputation.js +1 -1
  69. package/src/engine/graphics/ecs/animation/AnimationControllerSystem.js +2 -1
  70. package/src/engine/graphics/ecs/compileAllMaterials.js +1 -1
  71. package/src/engine/graphics/ecs/mesh/createTaskWaitForMeshesToLoad.js +1 -1
  72. package/src/engine/graphics/ecs/path/testPathDisplaySystem.js +1 -1
  73. package/src/engine/graphics/ecs/path/tube/prototypeAnimatedPathMask.js +1 -1
  74. package/src/engine/graphics/impostors/octahedral/ImpostorBaker.js +1 -1
  75. package/src/engine/graphics/load_and_set_cubemap_v0.js +21 -0
  76. package/src/engine/graphics/material/optimization/MaterialOptimizationContext.js +1 -1
  77. package/src/engine/graphics/particles/particular/engine/utils/volume/prototypeParticleVolume.js +3 -5
  78. package/src/engine/graphics/render/buffer/buffers/prototypeNormalFrameBuffer.js +3 -5
  79. package/src/engine/graphics/render/forward_plus/plugin/ptototypeFPPlugin.js +2 -2
  80. package/src/engine/graphics/render/forward_plus/prototype/prototypeLightManager.js +1 -1
  81. package/src/engine/graphics/render/visibility/hiz/prototypeHiZ.js +3 -5
  82. package/src/engine/graphics/sh3/prototypeSH3Probe.js +4 -4
  83. package/src/engine/graphics/texture/sampler/copy_Sampler2D_channel_data.js +4 -3
  84. package/src/engine/graphics/texture/sampler/filter/kaiser_1.js +8 -4
  85. package/src/engine/graphics/texture/sampler/filter/kaiser_bessel_window.js +2 -0
  86. package/src/engine/graphics/texture/virtual/VirtualTexture.js +9 -0
  87. package/src/engine/graphics/texture/virtual/VirtualTexture.spec.js +5 -4
  88. package/src/engine/graphics/texture/virtual/tile/TileLoader.js +5 -0
  89. package/src/engine/input/devices/PointerDevice.spec.js +7 -0
  90. package/src/engine/platform/InMemoryEnginePlatform.js +20 -0
  91. package/src/engine/save/Storage.d.ts +7 -7
  92. package/src/engine/save/storage/InMemoryStorage.js +34 -0
  93. package/src/generation/filtering/numeric/complex/CellFilterAngleToNormal.js +11 -4
  94. package/src/generation/filtering/numeric/complex/CellFilterAngleToNormal.spec.js +30 -0
  95. package/src/generation/filtering/numeric/complex/CellFilterGaussianBlur.js +18 -2
  96. package/src/generation/filtering/numeric/complex/CellFilterGaussianBlur.spec.js +17 -0
  97. package/src/generation/filtering/numeric/complex/CellFilterSimplexNoise.js +2 -2
  98. package/src/generation/grid/GridData.js +0 -60
  99. package/src/generation/grid/generation/road/GridTaskGenerateRoads.js +2 -2
  100. /package/src/core/collection/{IteratorUtils.js → collectIteratorValueToArray.js} +0 -0
  101. /package/src/core/color/{ColorUtils.js → parseColor.js} +0 -0
  102. /package/src/engine/ecs/{animation → ik}/IKMath.js +0 -0
  103. /package/src/engine/ecs/{animation → ik}/IKProblem.js +0 -0
  104. /package/src/engine/ecs/{animation → ik}/IKSolver.js +0 -0
  105. /package/src/engine/ecs/{animation → ik}/InverseKinematics.js +0 -0
  106. /package/src/engine/ecs/{animation → ik}/InverseKinematicsSystem.js +0 -0
  107. /package/src/engine/ecs/{animation → ik}/OneBoneSurfaceAlignmentSolver.js +0 -0
  108. /package/src/engine/ecs/{animation → ik}/TwoBoneInverseKinematicsSolver.js +0 -0
@@ -26,7 +26,7 @@ import { RingBuffer } from "../../../../../core/collection/RingBuffer.js";
26
26
  import { query_bvh_frustum_from_objects } from "../query/query_bvh_frustum_from_objects.js";
27
27
  import { prettyPrint } from "../../../../../core/NumberFormat.js";
28
28
  import { FPlusDebugMaterial } from "../materials/FPlusDebugMaterial.js";
29
- import { parseColor } from "../../../../../core/color/ColorUtils.js";
29
+ import { parseColor } from "../../../../../core/color/parseColor.js";
30
30
  import { buildLightClusterWidget } from "../debug/buildLightClusterWidget.js";
31
31
  import domify from "../../../../../view/DOM.js";
32
32
  import { createScreenGrid } from "../debug/createScreenGrid.js";
@@ -39,7 +39,7 @@ import { FogOfWarSystem } from "../../../../ecs/fow/FogOfWarSystem.js";
39
39
  import { FogOfWarRevealerSystem } from "../../../../ecs/fow/FogOfWarRevealerSystem.js";
40
40
  import { BehaviorSystem } from "../../../../intelligence/behavior/ecs/BehaviorSystem.js";
41
41
  import { SerializationMetadataSystem } from "../../../../ecs/systems/SerializationMetadataSystem.js";
42
- import { InverseKinematicsSystem } from "../../../../ecs/animation/InverseKinematicsSystem.js";
42
+ import { InverseKinematicsSystem } from "../../../../ecs/ik/InverseKinematicsSystem.js";
43
43
  import Vector3 from "../../../../../core/geom/Vector3.js";
44
44
  import Vector2 from "../../../../../core/geom/Vector2.js";
45
45
  import RenderSystem from "../../../../ecs/systems/RenderSystem.js";
@@ -49,7 +49,6 @@ import EntityBuilder from "../../../../ecs/EntityBuilder.js";
49
49
  import { Transform } from "../../../../ecs/transform/Transform.js";
50
50
  import Mesh from "../../../ecs/mesh/Mesh.js";
51
51
  import { PathDisplaySystem } from "../../../ecs/path/PathDisplaySystem.js";
52
- import { MicronRenderPlugin } from "../../../micron/plugin/MicronRenderPlugin.js";
53
52
  import { StandardFrameBuffers } from "../../../StandardFrameBuffers.js";
54
53
  import { HierarchicalZBuffer } from "./buffer/HierarchicalZBuffer.js";
55
54
  import ViewportPosition from "../../../../ecs/gui/position/ViewportPosition.js";
@@ -67,9 +66,9 @@ import { inverseLerp } from "../../../../../core/math/inverseLerp.js";
67
66
  import { clamp } from "../../../../../core/math/clamp.js";
68
67
  import { max2 } from "../../../../../core/math/max2.js";
69
68
  import { min2 } from "../../../../../core/math/min2.js";
70
- import { buildCubeURLs } from "../../../texture/cubemap/buildCubeURLs.js";
71
69
  import { mat4 } from "gl-matrix";
72
70
  import { randomFloatBetween } from "../../../../../core/math/random/randomFloatBetween.js";
71
+ import { load_and_set_cubemap_v0 } from "../../../load_and_set_cubemap_v0.js";
73
72
 
74
73
  const engineHarness = new EngineHarness();
75
74
 
@@ -137,7 +136,6 @@ function makeConfig(engine) {
137
136
 
138
137
 
139
138
  // Plugins
140
- config.addPlugin(MicronRenderPlugin);
141
139
 
142
140
 
143
141
  // Knowledge
@@ -162,7 +160,7 @@ async function init(harness) {
162
160
 
163
161
  enableEditor(engine);
164
162
 
165
- await engine.graphics.loadEnvironmentMap(buildCubeURLs('data/textures/cubemaps/hip_miramar/32/', '.png'));
163
+ await load_and_set_cubemap_v0(engine.graphics, 'data/textures/cubemaps/hip_miramar/32/', '.png');
166
164
 
167
165
  await harness.initialize();
168
166
 
@@ -25,13 +25,13 @@ import { GLTFAssetLoader } from "../../asset/loaders/GLTFAssetLoader.js";
25
25
  import { three_object_to_entity_composition } from "../ecs/mesh-v2/three_object_to_entity_composition.js";
26
26
  import { TransformAttachmentSystem } from "../../ecs/transform-attachment/TransformAttachmentSystem.js";
27
27
  import { ShadedGeometryFlags } from "../ecs/mesh-v2/ShadedGeometryFlags.js";
28
- import { AABB3 } from "../../../core/bvh2/aabb3/AABB3.js";
28
+ import { AABB3 } from "../../../core/geom/3d/aabb/AABB3.js";
29
29
  import { delay } from "../../../core/process/delay.js";
30
30
  import { make_justified_point_grid } from "../../../core/geom/3d/util/make_justified_point_grid.js";
31
31
  import LightSystem from "../ecs/light/LightSystem.js";
32
32
  import { Light } from "../ecs/light/Light.js";
33
33
  import { LightType } from "../ecs/light/LightType.js";
34
- import { buildCubeURLs } from "../texture/cubemap/buildCubeURLs.js";
34
+ import { load_and_set_cubemap_v0 } from "../load_and_set_cubemap_v0.js";
35
35
 
36
36
  /**
37
37
  *
@@ -193,7 +193,7 @@ async function main(engine) {
193
193
  distance: 54,
194
194
  shadowmapResolution: 4096
195
195
  });
196
- engine.graphics.loadEnvironmentMap(buildCubeURLs('data/textures/cubemaps/hip_miramar/32/', '.png'));
196
+ load_and_set_cubemap_v0(engine.graphics, 'data/textures/cubemaps/hip_miramar/32/', '.png');
197
197
 
198
198
  const ecd = engine.entityManager.dataset;
199
199
 
@@ -421,7 +421,7 @@ new EngineHarness().initialize({
421
421
  configuration(config, engine) {
422
422
  config.addSystem(new ShadedGeometrySystem(engine));
423
423
  config.addSystem(new TransformAttachmentSystem());
424
- config.addSystem(new LightSystem(engine,{
424
+ config.addSystem(new LightSystem(engine, {
425
425
  shadowResolution: 2048
426
426
  }));
427
427
 
@@ -19,9 +19,7 @@ export function copy_Sampler2D_channel_data(source, destination) {
19
19
  const destination_data = destination.data;
20
20
  const source_data = source.data;
21
21
 
22
- let i, j;
23
-
24
- const saturated_channel_value = saturated_value_by_constructor(destination_data.constructor);
22
+ let i=0, j=0;
25
23
 
26
24
  if (source_item_size === destination_item_size) {
27
25
  // just copy data chunk
@@ -39,6 +37,9 @@ export function copy_Sampler2D_channel_data(source, destination) {
39
37
  }
40
38
 
41
39
  } else if (source_item_size === 3 && destination_item_size === 4) {
40
+
41
+ const saturated_channel_value = saturated_value_by_constructor(destination_data.constructor);
42
+
42
43
  // RGB -> RGBA
43
44
  for (i = 0; i < pixel_count; i++) {
44
45
  const i3 = i * 3;
@@ -1,7 +1,10 @@
1
- import { bessel_i0 } from "../../../../../core/math/bessel_i0.js";
1
+ import { modified_bessel_i0 } from "../../../../../core/math/modified_bessel_i0.js";
2
2
  import { clamp } from "../../../../../core/math/clamp.js";
3
3
 
4
- const BASE_I0 = bessel_i0(6.5);
4
+ const PI2 = 2 * Math.PI;
5
+
6
+ const BASE_I0 = modified_bessel_i0(PI2);
7
+ const INV_BESSEL_I0 = 1 / BASE_I0;
5
8
 
6
9
  /**
7
10
  * Support kernel size is 1
@@ -11,9 +14,10 @@ const BASE_I0 = bessel_i0(6.5);
11
14
  */
12
15
  export function kaiser_1(x) {
13
16
  const i = clamp(x * 0.6666666666666666, -1.0, 1.0);
14
- const i0a = 1 / BASE_I0;
15
17
 
16
- return bessel_i0(6.5 * Math.sqrt(1 - i * i)) * i0a;
18
+ const t = Math.sqrt(1 - i * i);
19
+
20
+ return modified_bessel_i0(PI2 * t) * INV_BESSEL_I0;
17
21
  }
18
22
 
19
23
  kaiser_1.support = 1;
@@ -13,7 +13,9 @@ const INV_BESSEL_3_PI_3 = 1 / BESSEL_3_PI_3;
13
13
  */
14
14
  export function kaiser_bessel_window(x) {
15
15
  const i = clamp(x * 0.6666666666666666, -1.0, 1.0);
16
+
16
17
  const t = Math.sqrt(1.0 - i * i);
18
+
17
19
  return bessel_3(PI3 * t) * INV_BESSEL_3_PI_3;
18
20
  }
19
21
 
@@ -5,6 +5,7 @@ import Vector2 from "../../../../core/geom/Vector2.js";
5
5
  import { TilePage } from "./page/TilePage.js";
6
6
  import { create32BitCodec } from "../../../../core/binary/32BitEncoder.js";
7
7
  import { TileStatus } from "./tile/TileStatus.js";
8
+ import { assert } from "../../../../core/assert.js";
8
9
 
9
10
  /**
10
11
  *
@@ -13,6 +14,14 @@ import { TileStatus } from "./tile/TileStatus.js";
13
14
  * @returns {{encode: (function(..value:number): number), decode: (function(number, number[]): void)}}
14
15
  */
15
16
  function buildAddressEncoder(tileSize, textureSize) {
17
+ assert.isNumber(tileSize,'tileSize');
18
+ assert.notNaN(tileSize,'tileSize');
19
+ assert.isNonNegativeInteger(tileSize,'tileSize');
20
+
21
+ assert.isNumber(textureSize,'textureSize');
22
+ assert.notNaN(textureSize,'textureSize');
23
+ assert.isNonNegativeInteger(textureSize,'textureSize');
24
+
16
25
  const numberOfTiles = Math.ceil(textureSize / tileSize);
17
26
  const numberOfMips = Math.ceil(Math.log2(numberOfTiles));
18
27
 
@@ -3,7 +3,7 @@ import Vector2 from "../../../../core/geom/Vector2.js";
3
3
 
4
4
  function mockAssetManager() {
5
5
  const assetManager = {
6
- get: function (path, type, success, failure) {
6
+ get: function ({ path, type, success, failure }) {
7
7
  const delay = Math.random() * 100;
8
8
  setTimeout(function () {
9
9
  success({
@@ -12,7 +12,8 @@ function mockAssetManager() {
12
12
  }
13
13
  });
14
14
  }, delay);
15
- }
15
+ },
16
+ isAssetManager: true
16
17
  };
17
18
 
18
19
  return assetManager;
@@ -21,13 +22,13 @@ function mockAssetManager() {
21
22
  test("constructor doesn't throw", () => {
22
23
  const assetManager = mockAssetManager();
23
24
 
24
- new VirtualTexture({ assetManager })
25
+ new VirtualTexture(assetManager)
25
26
  });
26
27
 
27
28
  test("init computes sizes correctly", () => {
28
29
  const assetManager = mockAssetManager();
29
30
 
30
- const sut = new VirtualTexture({ assetManager });
31
+ const sut = new VirtualTexture(assetManager);
31
32
 
32
33
  sut.init({ padding: 4, resolution: new Vector2(16, 3), tileResolution: new Vector2(1, 1) });
33
34
 
@@ -5,6 +5,7 @@
5
5
  import { Tile } from "./Tile.js";
6
6
  import { TileStatus } from "./TileStatus.js";
7
7
  import { TileRequest } from "./TileRequest.js";
8
+ import { assert } from "../../../../../core/assert.js";
8
9
 
9
10
 
10
11
  export class TileLoader {
@@ -13,6 +14,10 @@ export class TileLoader {
13
14
  * @param {AssetManager} assetManager
14
15
  */
15
16
  constructor(assetManager) {
17
+ assert.defined(assetManager, 'assetManager');
18
+ assert.notNull(assetManager, 'assetManager');
19
+ assert.equal(assetManager.isAssetManager, true, 'assetManager.isAssetManager !== true');
20
+
16
21
  /**
17
22
  * @type {AssetManager}
18
23
  */
@@ -0,0 +1,7 @@
1
+ import { PointerDevice } from "./PointerDevice.js";
2
+
3
+ test("constructor does not throw", () => {
4
+ const element = document.createElement('div');
5
+
6
+ expect(() => new PointerDevice(element)).not.toThrow();
7
+ });
@@ -0,0 +1,20 @@
1
+ import { EnginePlatform } from "./EnginePlatform.js";
2
+ import { StorageAchievementGateway } from "../achievements/gateway/StorageAchievementGateway.js";
3
+ import { InMemoryStorage } from "../save/storage/InMemoryStorage.js";
4
+
5
+ export class InMemoryEnginePlatform extends EnginePlatform {
6
+ #storage = new InMemoryStorage();
7
+ #achievements = new StorageAchievementGateway(this.#storage);
8
+
9
+ getStorage() {
10
+ return this.#storage;
11
+ }
12
+
13
+ getAchievementGateway() {
14
+ return this.#achievements;
15
+ }
16
+
17
+ pickDefaultLocale(options) {
18
+ return options[0];
19
+ }
20
+ }
@@ -1,15 +1,15 @@
1
1
  export default class Storage {
2
- storeBinary(key: string, value: ArrayBuffer, resolve: Function, reject: Function, progress: Function)
2
+ storeBinary(key: string, value: ArrayBuffer, resolve: Function, reject: Function, progress: Function): void
3
3
 
4
- loadBinary(key:string, resolve:Function, reject:Function, progress:Function)
4
+ loadBinary(key: string, resolve: Function, reject: Function, progress: Function): void
5
5
 
6
- store(key:string, value:any, resolve:Function, reject:Function, progress:Function)
6
+ store(key: string, value: any, resolve: Function, reject: Function, progress: Function): void
7
7
 
8
- load(key:string, resolve:Function, reject:Function, progress:Function)
8
+ load(key: string, resolve: Function, reject: Function, progress: Function): void
9
9
 
10
- list(resolve:Function, reject:Function)
10
+ list(resolve: Function, reject: Function): void
11
11
 
12
- remove(key:string, resolve:Function, reject:Function)
12
+ remove(key: string, resolve: Function, reject: Function): void
13
13
 
14
- contains(key:string, resolve:Function, reject:Function)
14
+ contains(key: string, resolve: Function, reject: Function): void
15
15
  }
@@ -0,0 +1,34 @@
1
+ import Storage from "../Storage.js";
2
+ import { collectIteratorValueToArray } from "../../../core/collection/collectIteratorValueToArray.js";
3
+
4
+ export class InMemoryStorage extends Storage {
5
+ #data = new Map();
6
+
7
+ store(key, value, resolve, reject, progress) {
8
+ this.#data.set(key, value);
9
+
10
+ resolve();
11
+ }
12
+
13
+ load(key, resolve, reject, progress) {
14
+ resolve(this.#data.get(key));
15
+ }
16
+
17
+ remove(key, resolve, reject) {
18
+ this.#data.delete(key);
19
+
20
+ resolve();
21
+ }
22
+
23
+ contains(key, resolve, reject) {
24
+ resolve(this.#data.has(key));
25
+ }
26
+
27
+ list(resolve, reject) {
28
+ const result = [];
29
+
30
+ collectIteratorValueToArray(result, this.#data.keys());
31
+
32
+ resolve(result);
33
+ }
34
+ }
@@ -3,6 +3,12 @@ import Vector3 from "../../../../core/geom/Vector3.js";
3
3
  import { assert } from "../../../../core/assert.js";
4
4
  import { v3_angle_between } from "../../../../core/geom/v3_angle_between.js";
5
5
 
6
+ /**
7
+ * Distance from the reference point where support points will be sampled to compute derivative
8
+ * @type {number}
9
+ */
10
+ const DERIVATIVE_OFFSET = 1;
11
+
6
12
  /**
7
13
  * Builds surface normal of another filter, and then computes the angle to a fixed 3d vector
8
14
  */
@@ -27,6 +33,7 @@ export class CellFilterAngleToNormal extends CellFilter {
27
33
  *
28
34
  * @param {CellFilter} surface
29
35
  * @param {Vector3} [reference=Vector3.forward]
36
+ * @returns {CellFilterAngleToNormal}
30
37
  */
31
38
  static from(surface, reference = Vector3.forward) {
32
39
  assert.equal(surface.isCellFilter, true, 'surface.isCellFilter !== true');
@@ -51,12 +58,12 @@ export class CellFilterAngleToNormal extends CellFilter {
51
58
  const filter = this.surface;
52
59
 
53
60
  //read surrounding points
54
- const top = filter.execute(grid, x, y - 1, 0);
61
+ const top = filter.execute(grid, x, y - DERIVATIVE_OFFSET, 0);
55
62
 
56
- const left = filter.execute(grid, x - 1, y, 0);
57
- const right = filter.execute(grid, x + 1, y, 0);
63
+ const left = filter.execute(grid, x - DERIVATIVE_OFFSET, y, 0);
64
+ const right = filter.execute(grid, x + DERIVATIVE_OFFSET, y, 0);
58
65
 
59
- const bottom = filter.execute(grid, x, y + 1, 0);
66
+ const bottom = filter.execute(grid, x, y + DERIVATIVE_OFFSET, 0);
60
67
 
61
68
  // compute gradients
62
69
  const dX = (right) - (left);
@@ -0,0 +1,30 @@
1
+ import { CellFilterAngleToNormal } from "./CellFilterAngleToNormal.js";
2
+ import { CellFilterLiteralFloat } from "../CellFilterLiteralFloat.js";
3
+ import Vector3 from "../../../../core/geom/Vector3.js";
4
+ import { GridData } from "../../../grid/GridData.js";
5
+ import { DEG_TO_RAD } from "../../../../core/math/DEG_TO_RAD.js";
6
+
7
+ test("constructor does not throw", () => {
8
+ expect(() => new CellFilterAngleToNormal()).not.toThrow();
9
+ });
10
+
11
+ test("angle to flat surface exactly on normal", () => {
12
+ const data = new GridData();
13
+
14
+ const filter = CellFilterAngleToNormal.from(CellFilterLiteralFloat.from(0), new Vector3(0, 0, 1));
15
+
16
+ filter.initialize(data, 0);
17
+
18
+ expect(filter.execute(data, 0, 0, 0)).toBeCloseTo(0);
19
+ });
20
+
21
+ test("angle to flat surface at 30deg off normal", () => {
22
+
23
+ const data = new GridData();
24
+
25
+ const filter = CellFilterAngleToNormal.from(CellFilterLiteralFloat.from(0), new Vector3(0, 0.49999999999999994, 0.8660254037844386));
26
+
27
+ filter.initialize(data, 0);
28
+
29
+ expect(filter.execute(data, 0, 0, 0)).toBeCloseTo(30 * DEG_TO_RAD);
30
+ })
@@ -47,6 +47,22 @@ function buildKernel(result, samplesX, samplesY, sigma_x, sigma_y) {
47
47
  return powerTotal;
48
48
  }
49
49
 
50
+ /**
51
+ *
52
+ * even number of samples, make odd to ensure we sample reference point
53
+ * @param {number} x
54
+ * @return {number}
55
+ */
56
+ function makeNextOdd(x) {
57
+ if (x % 2 === 0) {
58
+ // even, make odd
59
+ return x + 1;
60
+ }
61
+
62
+ // already odd
63
+ return x;
64
+ }
65
+
50
66
  export class CellFilterGaussianBlur extends CellFilter {
51
67
  constructor() {
52
68
  super();
@@ -141,8 +157,8 @@ export class CellFilterGaussianBlur extends CellFilter {
141
157
 
142
158
  r.source = source;
143
159
 
144
- r.samples_x = max2(2, Math.round(quality * x));
145
- r.samples_y = max2(2, Math.round(quality * y));
160
+ r.samples_x = max2(3, makeNextOdd(Math.round(quality * x)));
161
+ r.samples_y = max2(3, makeNextOdd(Math.round(quality * y)));
146
162
 
147
163
  r.size_x = x;
148
164
  r.size_y = y;
@@ -0,0 +1,17 @@
1
+ import { CellFilterGaussianBlur } from "./CellFilterGaussianBlur.js";
2
+ import { GridData } from "../../../grid/GridData.js";
3
+ import { CellFilterLiteralFloat } from "../CellFilterLiteralFloat.js";
4
+
5
+ test("constructor does not throw", () => {
6
+ expect(() => new CellFilterGaussianBlur()).not.toThrow();
7
+ });
8
+
9
+ test("sample on constant value source", () => {
10
+ const data = new GridData();
11
+
12
+ const filter = CellFilterGaussianBlur.from(CellFilterLiteralFloat.from(7), 3, 3, 1);
13
+
14
+ filter.initialize(data, 0);
15
+
16
+ expect(filter.execute(data, 0, 0, 0)).toBeCloseTo(7);
17
+ });
@@ -4,7 +4,7 @@ import { CellFilterAdd } from "../math/algebra/CellFilterAdd.js";
4
4
  import { CellFilterMultiply } from "../math/algebra/CellFilterMultiply.js";
5
5
  import { CellFilterLiteralFloat } from "../CellFilterLiteralFloat.js";
6
6
  import { CellFilterDivide } from "../math/algebra/CellFilterDivide.js";
7
- import { createNoise2D } from "../../../../core/math/noise/create_noise_2d.js";
7
+ import { create_simplex_noise_2d } from "../../../../core/math/noise/create_simplex_noise_2d.js";
8
8
 
9
9
  export class CellFilterSimplexNoise extends CellFilter {
10
10
  constructor() {
@@ -109,7 +109,7 @@ export class CellFilterSimplexNoise extends CellFilter {
109
109
  initialize(grid, seed) {
110
110
  this.random.setCurrentSeed(seed + this.__seed);
111
111
 
112
- this.noise = createNoise2D(this.random);
112
+ this.noise = create_simplex_noise_2d(this.random);
113
113
 
114
114
  super.initialize(grid, seed);
115
115
  }
@@ -203,66 +203,6 @@ export class GridData {
203
203
  );
204
204
  }
205
205
 
206
- /**
207
- *
208
- * @param {number} x
209
- * @param {number} y
210
- * @param {number} mask
211
- */
212
- clearTags(x, y, mask) {
213
-
214
- const cellIndex = y * this.width + x;
215
-
216
- const current = this.tags[cellIndex];
217
-
218
- const newValue = current & (~mask);
219
-
220
- this.tags[cellIndex] = newValue;
221
- }
222
-
223
- /**
224
- *
225
- * @param {number} x
226
- * @param {number} y
227
- * @param {number} tags
228
- */
229
- writeTags(x, y, tags) {
230
- const cellIndex = y * this.width + x;
231
-
232
- this.tags[cellIndex] = tags;
233
- }
234
-
235
- /**
236
- *
237
- * @param {number} x
238
- * @param {number} y
239
- * @param {number} mask
240
- */
241
- setTags(x, y, mask) {
242
-
243
- const cellIndex = y * this.width + x;
244
-
245
- const current = this.tags[cellIndex];
246
-
247
- const newValue = current | mask;
248
-
249
- this.tags[cellIndex] = newValue;
250
- }
251
-
252
- /**
253
- *
254
- * @param {number} x
255
- * @param {number} y
256
- * @return {number}
257
- */
258
- readTags(x, y) {
259
- const _x = x | 0;
260
- const _y = y | 0;
261
-
262
- const cellIndex = _y * this.width + _x;
263
-
264
- return this.tags[cellIndex];
265
- }
266
206
  }
267
207
 
268
208
 
@@ -11,9 +11,9 @@ import { buildPathFromDistanceMap } from "../util/buildPathFromDistanceMap.js";
11
11
  import { GridCellActionPlaceTags } from "../../../placement/action/GridCellActionPlaceTags.js";
12
12
  import { GridTags } from "../../../GridTags.js";
13
13
  import { CellMatcher } from "../../../rules/CellMatcher.js";
14
- import { collectIteratorValueToArray } from "../../../../core/collection/IteratorUtils.js";
14
+ import { collectIteratorValueToArray } from "../../../../core/collection/collectIteratorValueToArray.js";
15
15
  import { QuadTreeNode } from "../../../../core/geom/2d/quad-tree/QuadTreeNode.js";
16
- import AABB2 from "../../../../core/geom/AABB2.js";
16
+ import AABB2 from "../../../../core/geom/2d/aabb/AABB2.js";
17
17
  import { PathEndPoint } from "./PathEndPoint.js";
18
18
  import { RoadConnection } from "./RoadConnection.js";
19
19
  import { readMarkerNodeGroupId } from "./readMarkerNodeGroupId.js";
File without changes
File without changes
File without changes
File without changes