@woosh/meep-engine 2.42.8 → 2.43.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (137) hide show
  1. package/core/binary/BitSet.js +4 -4
  2. package/core/binary/ctz32.js +40 -0
  3. package/core/collection/ObservedMap.js +61 -57
  4. package/core/collection/heap/FastBinaryHeap.js +7 -1
  5. package/core/collection/heap/Uint32Heap.js +19 -0
  6. package/core/collection/map/AsyncLoadingCache.js +3 -1
  7. package/core/geom/2d/compute_polygon_area_2d.js +32 -0
  8. package/core/geom/2d/compute_polygon_area_2d.spec.js +10 -0
  9. package/core/geom/2d/compute_triangle_area_2d.js +15 -0
  10. package/core/geom/2d/compute_triangle_area_2d.spec.js +9 -0
  11. package/core/geom/2d/convex-hull/convex_hull_jarvis_2d.js +64 -0
  12. package/core/geom/2d/convex-hull/convex_hull_jarvis_2d.spec.js +33 -0
  13. package/core/geom/2d/convex-hull/convex_hull_monotone_2d.js +82 -0
  14. package/core/geom/2d/convex-hull/fixed_convex_hull_humus.js +135 -0
  15. package/core/geom/2d/convex-hull/fixed_convex_hull_relaxation.js +282 -0
  16. package/core/geom/2d/convex-hull/orientation3.js +444 -0
  17. package/core/geom/2d/convex-hull/orientation3_array.js +22 -0
  18. package/core/geom/2d/convex-hull/orientation3_v2.js +12 -0
  19. package/core/geom/2d/intersect_ray_2d.js +56 -0
  20. package/core/geom/2d/quad-tree/QuadTreeNode.js +0 -81
  21. package/core/geom/2d/quad-tree/qt_match_data_by_circle.js +70 -0
  22. package/core/geom/3d/matrix/m4_multiply_alphatensor.js +131 -0
  23. package/core/geom/3d/plane/orient3d_fast.js +2 -6
  24. package/core/geom/3d/tetrahedra/README.md +7 -0
  25. package/core/geom/3d/tetrahedra/compute_bounding_simplex_3d.js +3 -1
  26. package/core/geom/3d/tetrahedra/delaunay/Cavity.js +48 -0
  27. package/core/geom/3d/tetrahedra/{compute_delaunay_tetrahedral_mesh.js → delaunay/compute_delaunay_tetrahedral_mesh.js} +15 -7
  28. package/core/geom/3d/tetrahedra/{compute_delaunay_tetrahedral_mesh.spec.js → delaunay/compute_delaunay_tetrahedral_mesh.spec.js} +0 -0
  29. package/core/geom/3d/tetrahedra/delaunay/tetrahedral_mesh_compute_cavity.js +73 -0
  30. package/core/geom/3d/tetrahedra/delaunay/tetrahedral_mesh_walk_toward_cavity.js +48 -0
  31. package/core/geom/3d/tetrahedra/hxt/a.js +524 -0
  32. package/core/geom/3d/tetrahedra/hxt/hxt.js +140 -0
  33. package/core/geom/3d/tetrahedra/hxt/hxt.wasm +0 -0
  34. package/core/geom/3d/tetrahedra/point_in_tetrahedron_circumsphere.js +35 -20
  35. package/core/geom/3d/tetrahedra/prototypeTetrahedraBuilder.js +98 -0
  36. package/core/geom/3d/tetrahedra/tetrahedra_collection.js +60 -131
  37. package/core/geom/packing/{MaxRectangles.js → max-rect/MaxRectangles.js} +28 -124
  38. package/core/geom/packing/max-rect/removeRedundantBoxes.js +69 -0
  39. package/core/geom/packing/max-rect/removeRedundantBoxesArray.js +40 -0
  40. package/core/geom/v3_distance_above_plane.js +1 -1
  41. package/core/graph/layout/BoxLayouter.js +2 -88
  42. package/core/graph/layout/CircleLayout.js +2 -1
  43. package/core/graph/layout/box/forceIntoBox.js +45 -0
  44. package/core/graph/layout/box/pullBoxTowardsPoint.js +20 -0
  45. package/core/graph/layout/box/resolveAABB2Overlap.js +22 -0
  46. package/core/math/bessel_3.js +11 -0
  47. package/core/math/bessel_i0.js +26 -0
  48. package/core/process/executor/ConcurrentExecutor.spec.js +2 -1
  49. package/core/process/task/util/actionTask.js +19 -0
  50. package/core/process/task/util/countTask.js +62 -0
  51. package/core/process/task/util/delayTask.js +45 -0
  52. package/core/process/task/util/emptyTask.js +19 -0
  53. package/core/process/task/util/failingTask.js +17 -0
  54. package/core/process/task/util/futureTask.js +48 -0
  55. package/core/process/task/util/promiseTask.js +42 -0
  56. package/core/process/task/util/randomCountTask.js +64 -0
  57. package/core/process/task/util/wrapTaskIgnoreFailure.js +47 -0
  58. package/engine/Engine.js +8 -8
  59. package/engine/EngineBootstrapper.js +1 -1
  60. package/engine/asset/AssetManager.d.ts +2 -0
  61. package/engine/asset/AssetManager.js +197 -53
  62. package/engine/asset/AssetRequest.js +32 -0
  63. package/engine/asset/loaders/ArrayBufferLoader.js +62 -50
  64. package/engine/asset/loaders/image/png/PNG.js +15 -1
  65. package/engine/asset/loaders/image/png/PNGReader.js +3 -2
  66. package/engine/ecs/foliage/ecs/InstancedMeshUtils.js +2 -1
  67. package/engine/ecs/storage/BinaryBufferDeSerializer.js +1 -1
  68. package/engine/ecs/storage/JSONDeSerializer.js +2 -1
  69. package/engine/ecs/terrain/ecs/splat/SplatMapOptimizer.js +2 -1
  70. package/engine/ecs/terrain/ecs/splat/SplatMapping.js +1 -1
  71. package/engine/graphics/camera/makeScreenScissorFrustum.js +1 -1
  72. package/engine/graphics/camera/testClippingPlaneComputation.js +4 -45
  73. package/engine/graphics/ecs/camera/FrustumProjector.js +6 -0
  74. package/engine/graphics/ecs/decal/v2/FPDecalSystem.js +5 -0
  75. package/engine/graphics/ecs/decal/v2/prototypeDecalSystem.js +23 -4
  76. package/engine/graphics/ecs/highlight/plugin/OutlineRenderPlugin.js +1 -1
  77. package/engine/graphics/ecs/mesh-v2/ShadedGeometry.js +11 -0
  78. package/engine/graphics/geometry/FULL_SCREEN_TRIANGLE_GEOMETRY.js +1 -2
  79. package/engine/graphics/impostors/octahedral/ImpostorBaker.js +5 -2
  80. package/engine/graphics/impostors/octahedral/ImpostorDescription.js +18 -0
  81. package/engine/graphics/impostors/octahedral/bake/prepare_bake_material.js +15 -0
  82. package/engine/graphics/impostors/octahedral/prototypeBaker.js +66 -79
  83. package/engine/graphics/impostors/octahedral/shader/ImpostorShaderWireframeV0.js +134 -0
  84. package/engine/graphics/impostors/octahedral/util/build_cutout_from_atlas_by_alpha.js +128 -0
  85. package/engine/graphics/impostors/octahedral/util/build_geometry_from_cutout_shape.js +32 -0
  86. package/engine/graphics/impostors/octahedral/util/load_mesh_for_bake.js +31 -0
  87. package/engine/graphics/impostors/octahedral/util/makeImpostorAtlasPreview.js +107 -0
  88. package/engine/graphics/material/manager/ManagedMaterial.js +4 -0
  89. package/engine/graphics/material/manager/MaterialManager.js +1 -0
  90. package/engine/graphics/material/optimization/MaterialOptimizationContext.js +7 -3
  91. package/engine/graphics/particles/particular/engine/renderers/billboard/ParticleBillboardMaterial.js +2 -2
  92. package/engine/graphics/render/forward_plus/prototype/prototypeLightManager.js +2 -2
  93. package/engine/graphics/render/visibility/hiz/buildCanvasViewFromTexture.js +83 -27
  94. package/engine/graphics/shadows/ShadowMapRenderer.js +11 -4
  95. package/engine/graphics/texture/atlas/AbstractTextureAtlas.js +2 -1
  96. package/engine/graphics/texture/atlas/CachingTextureAtlas.js +208 -38
  97. package/engine/graphics/texture/atlas/TextureAtlas.js +31 -24
  98. package/engine/graphics/texture/atlas/gpu/WebGLTextureAtlas.js +1 -1
  99. package/engine/graphics/texture/sampler/filter/box.js +16 -0
  100. package/engine/graphics/texture/sampler/filter/cubic2.js +32 -0
  101. package/engine/graphics/texture/sampler/filter/gaussian.js +16 -0
  102. package/engine/graphics/texture/sampler/filter/kaiser_1.js +19 -0
  103. package/engine/graphics/texture/sampler/filter/kaiser_bessel_window.js +19 -0
  104. package/engine/graphics/texture/sampler/filter/mitchell.js +55 -0
  105. package/engine/graphics/texture/sampler/filter/sampler2d_scale_down_generic.js +109 -0
  106. package/engine/graphics/texture/sampler/filter/triangle.js +19 -0
  107. package/engine/graphics/texture/sampler/prototypeSamplerFiltering.js +187 -86
  108. package/engine/graphics/texture/sampler/sampler2_d_scale_down_lanczos.js +77 -25
  109. package/engine/graphics/texture/sampler/search/make_edge_condition_channel_threshold.js +34 -0
  110. package/engine/graphics/texture/sampler/search/sampler2d_find_pixels.js +24 -0
  111. package/engine/graphics/texture/sprite/prototypeSpriteCutoutGeometry.js +212 -0
  112. package/engine/knowledge/database/StaticKnowledgeDataTable.js +1 -1
  113. package/engine/navigation/grid/AStar.js +1 -1
  114. package/engine/scene/Scene.js +1 -1
  115. package/engine/scene/SerializedScene.js +1 -1
  116. package/engine/scene/transitionToScene.js +3 -1
  117. package/generation/example/main.js +1 -1
  118. package/generation/grid/generation/GridTaskApplyActionToCells.js +1 -1
  119. package/generation/grid/generation/GridTaskDensityMarkerDistribution.js +1 -1
  120. package/generation/grid/generation/GridTaskExecuteRuleTimes.js +1 -1
  121. package/generation/grid/generation/NoopGridTaskGenerator.js +1 -1
  122. package/generation/grid/generation/discrete/GridTaskCellularAutomata.js +2 -1
  123. package/generation/grid/generation/discrete/GridTaskConnectRooms.js +1 -1
  124. package/generation/grid/generation/discrete/layer/GridTaskBuildSourceDistanceMap.js +3 -2
  125. package/generation/grid/generation/discrete/layer/GridTaskDistanceToMarkers.js +1 -1
  126. package/generation/grid/generation/grid/GridTaskAddNodesFixed.js +1 -1
  127. package/generation/grid/generation/road/GridTaskGenerateRoads.js +3 -2
  128. package/generation/grid/generation/util/buildDistanceMapToObjective.js +1 -1
  129. package/generation/markers/GridActionRuleSet.js +2 -1
  130. package/generation/placement/GridCellActionTransformNearbyMarkers.js +2 -4
  131. package/generation/theme/ThemeEngine.js +4 -1
  132. package/package.json +1 -1
  133. package/view/asset/AssetLoaderStatusView.js +5 -5
  134. package/view/minimap/gl/MinimapTerrainGL.js +1 -2
  135. package/view/renderModel.js +1 -1
  136. package/view/tooltip/TooltipView.js +5 -5
  137. package/core/process/task/TaskUtils.js +0 -352
@@ -1,122 +1,13 @@
1
- import BinaryHeap from "../../collection/heap/FastBinaryHeap.js";
2
- import { assert } from "../../assert.js";
3
- import { max2 } from "../../math/max2.js";
4
- import { min2 } from "../../math/min2.js";
5
- import { QuadTreeDatum } from "../2d/quad-tree/QuadTreeDatum.js";
6
- import { QuadTreeNode } from "../2d/quad-tree/QuadTreeNode.js";
7
- import AABB2 from "../AABB2.js";
8
- import Vector2 from "../Vector2.js";
9
-
10
- /**
11
- * Remove all rectangles that are fully contained within others
12
- * @param {AABB2[]} boxes
13
- */
14
- function removeRedundantBoxesArray(boxes) {
15
- let i, j;
16
- let numBoxes = boxes.length;
17
-
18
- loop_a: for (i = 0; i < numBoxes; i++) {
19
- const a = boxes[i];
20
-
21
- const ax0 = a.x0;
22
- const ay0 = a.y0;
23
- const ax1 = a.x1;
24
- const ay1 = a.y1;
25
-
26
- for (j = i + 1; j < numBoxes; j++) {
27
- const b = boxes[j];
28
-
29
- const bx0 = b.x0;
30
- const by0 = b.y0;
31
- const bx1 = b.x1;
32
- const by1 = b.y1;
33
-
34
- //question is now whether it is containment
35
- if (ax0 >= bx0 && ax1 <= bx1 && ay0 >= by0 && ay1 <= by1) {
36
- //b contains a
37
- boxes.splice(i, 1);
38
- i--;
39
- numBoxes--;
40
- continue loop_a;
41
- } else if (bx0 >= ax0 && bx1 <= ax1 && by0 >= ay0 && by1 <= ay1) {
42
- //a contains b
43
- boxes.splice(j, 1);
44
- j--;
45
- numBoxes--;
46
- }
47
- }
48
- }
49
- }
50
-
51
-
52
- /**
53
- * Remove all rectangles that are fully contained within others
54
- * @param {QuadTreeNode} boxes
55
- */
56
- function removeRedundantBoxes(boxes) {
57
- const removals = [];
58
-
59
-
60
- let datum;
61
-
62
- /**
63
- *
64
- * @param {QuadTreeDatum} intersection
65
- */
66
- function visitDatumIntersection(intersection) {
67
- if (datum === intersection) {
68
- //skip self
69
- return;
70
- }
71
-
72
- const ax0 = intersection.x0;
73
- const ay0 = intersection.y0;
74
- const ax1 = intersection.x1;
75
- const ay1 = intersection.y1;
76
-
77
- const bx0 = datum.x0;
78
- const by0 = datum.y0;
79
- const bx1 = datum.x1;
80
- const by1 = datum.y1;
81
-
82
- //question is now whether it is containment
83
- if (ax0 >= bx0 && ax1 <= bx1 && ay0 >= by0 && ay1 <= by1) {
84
- //b contains a
85
- removals.push(intersection);
86
- } else if (bx0 >= ax0 && bx1 <= ax1 && by0 >= ay0 && by1 <= ay1) {
87
- //a contains b
88
- removals.push(datum);
89
-
90
- //scheduled removal of the datum, prevent further traversal
91
- return false;
92
- }
93
- }
94
-
95
- /**
96
- *
97
- * @param {QuadTreeNode} node
98
- */
99
- function visitTreeNode(node) {
100
- const data = node.data;
101
- const dataCount = data.length;
102
-
103
- for (let i = 0; i < dataCount; i++) {
104
- /**
105
- *
106
- * @type {QuadTreeDatum}
107
- */
108
- datum = data[i];
109
-
110
- node.traverseRectangleIntersections(datum.x0, datum.y0, datum.x1, datum.y1, visitDatumIntersection);
111
- }
112
- }
113
-
114
- boxes.traversePreOrder(visitTreeNode);
115
-
116
- for (const removal of removals) {
117
- removal.disconnect();
118
- }
119
- }
1
+ import BinaryHeap from "../../../collection/heap/FastBinaryHeap.js";
2
+ import { assert } from "../../../assert.js";
3
+ import { max2 } from "../../../math/max2.js";
4
+ import { min2 } from "../../../math/min2.js";
5
+ import { QuadTreeDatum } from "../../2d/quad-tree/QuadTreeDatum.js";
6
+ import { QuadTreeNode } from "../../2d/quad-tree/QuadTreeNode.js";
7
+ import AABB2 from "../../AABB2.js";
8
+ import Vector2 from "../../Vector2.js";
9
+ import { removeRedundantBoxesArray } from "./removeRedundantBoxesArray.js";
10
+ import { removeRedundantBoxes } from "./removeRedundantBoxes.js";
120
11
 
121
12
 
122
13
  /**
@@ -301,7 +192,7 @@ function packOneBox(box, free) {
301
192
  container.disconnect();
302
193
 
303
194
  //place box at bottom left of the container
304
- const y0 = container.y1 - h;
195
+ const y0 = container.y0;
305
196
  const x0 = container.x0;
306
197
 
307
198
  box.set(x0, y0, x0 + w, y0 + h);
@@ -310,8 +201,8 @@ function packOneBox(box, free) {
310
201
  cutArea(box, free);
311
202
 
312
203
  //split remaining space
313
- if (container.y0 !== y0) {
314
- const splitA = new QuadTreeDatum(container.x0, container.y0, container.x1, y0);
204
+ if (box.y1 !== container.y1) {
205
+ const splitA = new QuadTreeDatum(container.x0, box.y1, container.x1, container.y1);
315
206
 
316
207
  free.insertDatum(splitA);
317
208
  }
@@ -321,7 +212,6 @@ function packOneBox(box, free) {
321
212
  free.insertDatum(splitB);
322
213
  }
323
214
 
324
- removeRedundantBoxes(free);
325
215
 
326
216
  return true;
327
217
  }
@@ -405,6 +295,7 @@ export class MaxRectanglesPacker {
405
295
 
406
296
  if (success) {
407
297
  this.boxes.push(box);
298
+ removeRedundantBoxes(this.free);
408
299
  }
409
300
 
410
301
  // assert.ok(this.validate());
@@ -412,6 +303,16 @@ export class MaxRectanglesPacker {
412
303
  return success;
413
304
  }
414
305
 
306
+ /**
307
+ *
308
+ * @param {number} w
309
+ * @param {number} h
310
+ * @return {boolean}
311
+ */
312
+ canAdd(w, h) {
313
+ return findBestContainer(w, h, this.free, costByRemainingArea) !== null;
314
+ }
315
+
415
316
  /**
416
317
  * Method is transactional, if one box fails to be packed, all fail and packer is reverted to original state
417
318
  * @param {AABB2[]} boxes
@@ -444,7 +345,7 @@ export class MaxRectanglesPacker {
444
345
  const boxIndex = heap.pop();
445
346
  const box = boxes[boxIndex];
446
347
 
447
- if (!this.add(box)) {
348
+ if (!packOneBox(box, this.free)) {
448
349
  //remove whatever has been packed
449
350
  const removeFailCount = this.removeMany(packed);
450
351
 
@@ -452,11 +353,14 @@ export class MaxRectanglesPacker {
452
353
 
453
354
  return false;
454
355
  } else {
356
+ this.boxes.push(box);
455
357
  //box packed successfully
456
358
  packed.push(box);
457
359
  }
458
360
  }
459
361
 
362
+ removeRedundantBoxes(this.free);
363
+
460
364
  return true;
461
365
  }
462
366
 
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Remove all rectangles that are fully contained within others
3
+ * @param {QuadTreeNode} boxes
4
+ */
5
+ export function removeRedundantBoxes(boxes) {
6
+ const removals = [];
7
+
8
+
9
+ let datum;
10
+
11
+ /**
12
+ *
13
+ * @param {QuadTreeDatum} intersection
14
+ */
15
+ function visitDatumIntersection(intersection) {
16
+ if (datum === intersection) {
17
+ //skip self
18
+ return;
19
+ }
20
+
21
+ const ax0 = intersection.x0;
22
+ const ay0 = intersection.y0;
23
+ const ax1 = intersection.x1;
24
+ const ay1 = intersection.y1;
25
+
26
+ const bx0 = datum.x0;
27
+ const by0 = datum.y0;
28
+ const bx1 = datum.x1;
29
+ const by1 = datum.y1;
30
+
31
+ //question is now whether it is containment
32
+ if (ax0 >= bx0 && ax1 <= bx1 && ay0 >= by0 && ay1 <= by1) {
33
+ //b contains a
34
+ removals.push(intersection);
35
+ } else if (bx0 >= ax0 && bx1 <= ax1 && by0 >= ay0 && by1 <= ay1) {
36
+ //a contains b
37
+ removals.push(datum);
38
+
39
+ //scheduled removal of the datum, prevent further traversal
40
+ return false;
41
+ }
42
+ }
43
+
44
+ /**
45
+ *
46
+ * @param {QuadTreeNode} node
47
+ */
48
+ function visitTreeNode(node) {
49
+ const data = node.data;
50
+ const dataCount = data.length;
51
+
52
+ for (let i = 0; i < dataCount; i++) {
53
+ /**
54
+ *
55
+ * @type {QuadTreeDatum}
56
+ */
57
+ datum = data[i];
58
+
59
+ node.traverseRectangleIntersections(datum.x0, datum.y0, datum.x1, datum.y1, visitDatumIntersection);
60
+ }
61
+ }
62
+
63
+ boxes.traversePreOrder(visitTreeNode);
64
+
65
+ for (let i = 0; i < removals.length; i++) {
66
+ const removal = removals[i];
67
+ removal.disconnect();
68
+ }
69
+ }
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Remove all rectangles that are fully contained within others
3
+ * @param {AABB2[]} boxes
4
+ */
5
+ export function removeRedundantBoxesArray(boxes) {
6
+ let i, j;
7
+ let numBoxes = boxes.length;
8
+
9
+ loop_a: for (i = 0; i < numBoxes; i++) {
10
+ const a = boxes[i];
11
+
12
+ const ax0 = a.x0;
13
+ const ay0 = a.y0;
14
+ const ax1 = a.x1;
15
+ const ay1 = a.y1;
16
+
17
+ for (j = i + 1; j < numBoxes; j++) {
18
+ const b = boxes[j];
19
+
20
+ const bx0 = b.x0;
21
+ const by0 = b.y0;
22
+ const bx1 = b.x1;
23
+ const by1 = b.y1;
24
+
25
+ //question is now whether it is containment
26
+ if (ax0 >= bx0 && ax1 <= bx1 && ay0 >= by0 && ay1 <= by1) {
27
+ //b contains a
28
+ boxes.splice(i, 1);
29
+ i--;
30
+ numBoxes--;
31
+ continue loop_a;
32
+ } else if (bx0 >= ax0 && bx1 <= ax1 && by0 >= ay0 && by1 <= ay1) {
33
+ //a contains b
34
+ boxes.splice(j, 1);
35
+ j--;
36
+ numBoxes--;
37
+ }
38
+ }
39
+ }
40
+ }
@@ -15,6 +15,6 @@ export function v3_distance_above_plane(
15
15
  x, y, z,
16
16
  normalX, normalY, normalZ, planeConstant
17
17
  ) {
18
- // this is is the same v4_dot(v4(x,y,z,1.0), v4(plane.normal, plane.constant));
18
+ // this is the same as v4_dot(v4(x,y,z,1.0), v4(plane.normal, plane.constant));
19
19
  return v3_dot(normalX, normalY, normalZ, x, y, z) + planeConstant;
20
20
  }
@@ -6,31 +6,11 @@
6
6
 
7
7
  import AABB2 from "../../geom/AABB2.js";
8
8
  import Vector2 from "../../geom/Vector2.js";
9
- import { resolveBoxOverlapUsingForce } from "./box/resolveBoxOverlapUsingForce.js";
10
9
  import { computeDisconnectedSubGraphs } from "./computeDisconnectedSubGraphs.js";
11
10
  import { Connection } from "./Connection.js";
11
+ import { resolveAABB2Overlap } from "./box/resolveAABB2Overlap.js";
12
12
 
13
13
 
14
- /**
15
- *
16
- * @param {AABB2[]} boxes
17
- * @param {number} maxSteps
18
- */
19
- export function resolveAABB2Overlap(boxes, maxSteps) {
20
- const forces = [];
21
-
22
- const n = boxes.length;
23
- for (let i = 0; i < n; i++) {
24
- forces.push(new Vector2(0, 0));
25
- }
26
-
27
- let overlapMoves = -1;
28
- while (maxSteps > 0 && overlapMoves !== 0) {
29
- maxSteps--;
30
- overlapMoves = resolveBoxOverlapUsingForce(forces, boxes);
31
- }
32
- }
33
-
34
14
  /**
35
15
  *
36
16
  * @param {Connection} edge
@@ -201,27 +181,6 @@ function applyPull(edges, strength) {
201
181
  }
202
182
  }
203
183
 
204
- /**
205
- *
206
- * @param {AABB2} box
207
- * @param {number} targetX target point X coordinate
208
- * @param {number} targetY target point Y coordinate
209
- * @param {number} strength
210
- */
211
- export function pullBoxTowardsPoint(box, targetX, targetY, strength) {
212
- const midX = box.midX();
213
- const midY = box.midY();
214
-
215
- const deltaX = targetX - midX;
216
- const deltaY = targetY - midY;
217
-
218
- //multiply by strength
219
- const displacementX = deltaX * strength;
220
- const displacementY = deltaY * strength;
221
-
222
- box.move(displacementX, displacementY);
223
- }
224
-
225
184
  /**
226
185
  *
227
186
  * @param {Array.<AABB2>} boxes
@@ -502,50 +461,6 @@ function doLayerLayout(boxes) {
502
461
  }
503
462
  }
504
463
 
505
- /**
506
- * Note: assumes that boxes to be contained are strictly smaller than the container in both dimensions
507
- * @param {AABB2} container
508
- * @param {Array.<AABB2>} boxes
509
- */
510
- function forceIntoBox(container, boxes) {
511
- for (let i = 0, l = boxes.length; i < l; i++) {
512
- const box = boxes[i];
513
-
514
- if (box.locked === true) {
515
- continue;
516
- }
517
-
518
- let dX = 0;
519
- let dY = 0;
520
-
521
- const bx0 = box.x0;
522
- const bx1 = box.x1;
523
-
524
- const by0 = box.y0;
525
- const by1 = box.y1;
526
-
527
- const cx0 = container.x0;
528
- const cx1 = container.x1;
529
-
530
- const cy0 = container.y0;
531
- const cy1 = container.y1;
532
-
533
- if (bx0 < cx0) {
534
- dX = cx0 - bx0;
535
- } else if (bx1 > cx1) {
536
- dX = cx1 - bx1;
537
- }
538
-
539
- if (by0 < cy0) {
540
- dY = cy0 - by0;
541
- } else if (by1 > cy1) {
542
- dY = cy1 - by1;
543
- }
544
-
545
- box.move(dX, dY);
546
- }
547
- }
548
-
549
464
  /**
550
465
  *
551
466
  * @param {AABB2[]} boxes
@@ -665,6 +580,5 @@ function forceLayout(input, graph, center = null) {
665
580
 
666
581
  export {
667
582
  forceLayout,
668
- alignOnOrigin,
669
- forceIntoBox
583
+ alignOnOrigin
670
584
  };
@@ -10,9 +10,10 @@ import { line2SegmentsIntersect } from "../../geom/LineSegment2.js";
10
10
  import Vector2, { v2_distance } from "../../geom/Vector2.js";
11
11
  import { max2 } from "../../math/max2.js";
12
12
  import { min2 } from "../../math/min2.js";
13
- import { applyCentralGravityAABB2, resolveAABB2Overlap } from "./BoxLayouter.js";
13
+ import { applyCentralGravityAABB2 } from "./BoxLayouter.js";
14
14
  import { computeDisconnectedSubGraphs } from "./computeDisconnectedSubGraphs.js";
15
15
  import { Connection } from "./Connection.js";
16
+ import { resolveAABB2Overlap } from "./box/resolveAABB2Overlap.js";
16
17
 
17
18
 
18
19
  /**
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Note: assumes that boxes to be contained are strictly smaller than the container in both dimensions
3
+ * @param {AABB2} container
4
+ * @param {Array.<AABB2>} boxes
5
+ */
6
+ function forceIntoBox(container, boxes) {
7
+ for (let i = 0, l = boxes.length; i < l; i++) {
8
+ const box = boxes[i];
9
+
10
+ if (box.locked === true) {
11
+ continue;
12
+ }
13
+
14
+ let dX = 0;
15
+ let dY = 0;
16
+
17
+ const bx0 = box.x0;
18
+ const bx1 = box.x1;
19
+
20
+ const by0 = box.y0;
21
+ const by1 = box.y1;
22
+
23
+ const cx0 = container.x0;
24
+ const cx1 = container.x1;
25
+
26
+ const cy0 = container.y0;
27
+ const cy1 = container.y1;
28
+
29
+ if (bx0 < cx0) {
30
+ dX = cx0 - bx0;
31
+ } else if (bx1 > cx1) {
32
+ dX = cx1 - bx1;
33
+ }
34
+
35
+ if (by0 < cy0) {
36
+ dY = cy0 - by0;
37
+ } else if (by1 > cy1) {
38
+ dY = cy1 - by1;
39
+ }
40
+
41
+ box.move(dX, dY);
42
+ }
43
+ }
44
+
45
+ export { forceIntoBox };
@@ -0,0 +1,20 @@
1
+ /**
2
+ *
3
+ * @param {AABB2} box
4
+ * @param {number} targetX target point X coordinate
5
+ * @param {number} targetY target point Y coordinate
6
+ * @param {number} strength
7
+ */
8
+ export function pullBoxTowardsPoint(box, targetX, targetY, strength) {
9
+ const midX = box.midX();
10
+ const midY = box.midY();
11
+
12
+ const deltaX = targetX - midX;
13
+ const deltaY = targetY - midY;
14
+
15
+ //multiply by strength
16
+ const displacementX = deltaX * strength;
17
+ const displacementY = deltaY * strength;
18
+
19
+ box.move(displacementX, displacementY);
20
+ }
@@ -0,0 +1,22 @@
1
+ import Vector2 from "../../../geom/Vector2.js";
2
+ import { resolveBoxOverlapUsingForce } from "./resolveBoxOverlapUsingForce.js";
3
+
4
+ /**
5
+ *
6
+ * @param {AABB2[]} boxes
7
+ * @param {number} maxSteps
8
+ */
9
+ export function resolveAABB2Overlap(boxes, maxSteps) {
10
+ const forces = [];
11
+
12
+ const n = boxes.length;
13
+ for (let i = 0; i < n; i++) {
14
+ forces.push(new Vector2(0, 0));
15
+ }
16
+
17
+ let overlapMoves = -1;
18
+ while (maxSteps > 0 && overlapMoves !== 0) {
19
+ maxSteps--;
20
+ overlapMoves = resolveBoxOverlapUsingForce(forces, boxes);
21
+ }
22
+ }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Kaiser Bessel Function of third kind
3
+ * @see https://www.shadertoy.com/view/wlf3RH
4
+ * @returns {number}
5
+ * @param {number} x
6
+ */
7
+ export function bessel_3(x) {
8
+ const y = 0.5 * x;
9
+ const y2 = (y * y);
10
+ return (y2 * y * (1.0 / 6.0 + y2 * (1.0 / 24.0 + y2 * (1.0 / 240.0 + y2 * (1.0 / 4320.0 + y2 / 120960.0)))));
11
+ }
@@ -0,0 +1,26 @@
1
+ import { assert } from "../assert.js";
2
+
3
+ /**
4
+ * Modified bessel function of the first kind
5
+ * @see https://mathworld.wolfram.com/ModifiedBesselFunctionoftheFirstKind.html
6
+ * @see https://computergraphics.stackexchange.com/questions/6393/kaiser-windowed-sinc-filter-for-mip-mapping
7
+ * @see https://github.com/terifan/ImageResampler/blob/dbc212ce6aaa769bf3c9623cb6ead58ffd51d76c/src/org/terifan/image_resampler/FilterFactory.java
8
+ * @param {number} x
9
+ * @returns {number}
10
+ */
11
+ export function bessel_i0(x) {
12
+ assert.notNaN(x, 'x');
13
+
14
+ let sum = 1.0;
15
+
16
+ const y = x * x * 0.25;
17
+
18
+ let t = y;
19
+
20
+ for (let i = 2; t > 1e-7; i++) {
21
+ sum += t;
22
+ t *= y / (i * i);
23
+ }
24
+
25
+ return sum;
26
+ }
@@ -3,8 +3,9 @@ import Task from "../task/Task.js"
3
3
  import TaskGroup from "../task/TaskGroup.js";
4
4
  import { TaskSignal } from "../task/TaskSignal.js";
5
5
  import TaskState from "../task/TaskState.js";
6
- import { emptyTask, failingTask } from "../task/TaskUtils.js";
7
6
  import ConcurrentExecutor from "./ConcurrentExecutor.js";
7
+ import { emptyTask } from "../task/util/emptyTask.js";
8
+ import { failingTask } from "../task/util/failingTask.js";
8
9
 
9
10
  /**
10
11
  *
@@ -0,0 +1,19 @@
1
+ import Task from "../Task.js";
2
+ import { TaskSignal } from "../TaskSignal.js";
3
+
4
+ /**
5
+ *
6
+ * @param {function} action
7
+ * @param {string} name
8
+ * @return {Task}
9
+ */
10
+ export function actionTask(action, name = "unnamed") {
11
+ return new Task({
12
+ name,
13
+ cycleFunction() {
14
+ action();
15
+
16
+ return TaskSignal.EndSuccess;
17
+ }
18
+ });
19
+ }
@@ -0,0 +1,62 @@
1
+ import { TaskSignal } from "../TaskSignal.js";
2
+ import Task from "../Task.js";
3
+
4
+ /**
5
+ *
6
+ * @param {number|function(*):number} initial
7
+ * @param {number|function(*):number} limit
8
+ * @param {function(index:int)} callback
9
+ * @returns {Task}
10
+ */
11
+ export function countTask(initial, limit, callback) {
12
+ let initialValue = 0;
13
+ let limitValue = 0;
14
+
15
+ let i = initialValue;
16
+
17
+ function cycle() {
18
+ if (i >= limitValue) {
19
+ return TaskSignal.EndSuccess;
20
+ }
21
+ callback(i);
22
+ i++;
23
+
24
+ return TaskSignal.Continue;
25
+ }
26
+
27
+ const initialType = typeof initial;
28
+ const limitType = typeof limit;
29
+
30
+ const name = "count (from " + ((initialType === 'number') ? initial : 'variable') + " to " + ((limitType === 'number') ? limit : 'variable') + ")";
31
+
32
+ return new Task({
33
+ name: name,
34
+ initializer() {
35
+
36
+ if (initialType === "number") {
37
+ initialValue = initial;
38
+ } else if (initialType === "function") {
39
+ initialValue = initial();
40
+ }
41
+
42
+ if (limitType === "number") {
43
+ limitValue = limit;
44
+ } else if (limitType === "function") {
45
+ limitValue = limit();
46
+ }
47
+
48
+ i = initialValue;
49
+
50
+ },
51
+ cycleFunction: cycle,
52
+ computeProgress: function () {
53
+ const span = limitValue - initialValue;
54
+
55
+ if (span === 0) {
56
+ return 0;
57
+ }
58
+
59
+ return (i - initialValue) / span;
60
+ }
61
+ });
62
+ }