@woosh/meep-engine 2.43.1 → 2.43.3

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 (105) hide show
  1. package/core/bvh2/aabb3/aabb3_array_combine.js +2 -2
  2. package/core/collection/RingBuffer.js +4 -2
  3. package/core/collection/RingBuffer.spec.js +59 -0
  4. package/core/collection/array/ArrayIteratorRandom.js +1 -1
  5. package/core/collection/{ArrayUtils.spec.js → array/arrayPickBestElement.spec.js} +1 -1
  6. package/core/collection/array/arrayPickBestElements.js +51 -0
  7. package/core/collection/array/arrayPickMinElement.js +43 -0
  8. package/core/collection/array/arrayQuickSort.js +1 -1
  9. package/core/collection/array/arraySetSortingDiff.js +1 -1
  10. package/core/collection/array/arraySwapElements.js +12 -0
  11. package/core/collection/array/groupArrayBy.js +42 -0
  12. package/core/collection/array/isArrayEqual.js +50 -0
  13. package/core/collection/array/randomMultipleFromArray.js +34 -0
  14. package/core/collection/array/randomizeArrayElementOrder.js +23 -0
  15. package/core/geom/2d/convex-hull/convex_hull_monotone_2d.js +1 -1
  16. package/core/geom/3d/aabb/aabb3_build_frustum.js +1 -1
  17. package/core/geom/3d/aabb/compute_aabb_from_points.js +1 -1
  18. package/core/geom/3d/frustum/frustum3_computeNearestPointToPoint.js +3 -1
  19. package/core/geom/3d/morton/v3_morton_encode_transformed.spec.js +20 -0
  20. package/core/geom/3d/plane/orient3d_fast.js +8 -10
  21. package/core/geom/3d/plane/plane_computeConvex3PlaneIntersection.js +0 -23
  22. package/core/geom/3d/plane/plane_three_compute_convex3_plane_intersection.js +24 -0
  23. package/core/geom/3d/shape/UnionShape3D.js +1 -1
  24. package/core/geom/3d/tetrahedra/README.md +10 -1
  25. package/core/geom/3d/tetrahedra/{tetrahedra_collection.js → TetrahedralMesh.js} +236 -152
  26. package/core/geom/3d/tetrahedra/TetrahedralMesh.spec.js +156 -0
  27. package/core/geom/3d/tetrahedra/compute_bounding_simplex_3d.js +2 -2
  28. package/core/geom/3d/tetrahedra/compute_bounding_simplex_3d.spec.js +4 -4
  29. package/core/geom/3d/tetrahedra/delaunay/Cavity.js +45 -7
  30. package/core/geom/3d/tetrahedra/delaunay/compute_delaunay_tetrahedral_mesh.js +44 -9
  31. package/core/geom/3d/tetrahedra/delaunay/debug_validate_mesh.js +19 -0
  32. package/core/geom/3d/tetrahedra/delaunay/fill_in_a_cavity.js +155 -0
  33. package/core/geom/3d/tetrahedra/delaunay/tetrahedral_mesh_compute_cavity2.js +224 -0
  34. package/core/geom/3d/tetrahedra/delaunay/tetrahedral_mesh_compute_sub_determinant.js +77 -0
  35. package/core/geom/3d/tetrahedra/delaunay/tetrahedral_mesh_compute_sub_determinant.spec.js +30 -0
  36. package/core/geom/3d/tetrahedra/delaunay/tetrahedral_mesh_insert_point.js +98 -0
  37. package/core/geom/3d/tetrahedra/delaunay/tetrahedral_mesh_walk_toward_cavity.js +13 -6
  38. package/core/geom/3d/tetrahedra/point_in_tetrahedron_circumsphere.js +9 -9
  39. package/core/geom/3d/tetrahedra/prototypeTetrahedraBuilder.js +1 -1
  40. package/core/geom/3d/tetrahedra/tetrahedron_compute_signed_volume.js +83 -0
  41. package/core/geom/3d/tetrahedra/tetrahedron_compute_signed_volume.spec.js +24 -0
  42. package/core/geom/3d/tetrahedra/tetrahedron_contains_point.spec.js +66 -0
  43. package/core/geom/3d/tetrahedra/validate_tetrahedral_mesh.js +119 -0
  44. package/core/geom/Bezier.js +0 -27
  45. package/core/geom/Plane.js +0 -4
  46. package/core/geom/packing/miniball/Subspan.js +2 -2
  47. package/core/geom/v3_lerp.js +6 -1
  48. package/core/math/isqrt.js +28 -0
  49. package/core/math/isqrt.spec.js +9 -0
  50. package/core/math/max.spec.js +25 -0
  51. package/core/math/min2.spec.js +25 -0
  52. package/core/model/node-graph/node/NodeInstance.js +3 -3
  53. package/core/primitives/strings/prefixTree/PrefixTreeLeaf.js +1 -1
  54. package/core/process/task/util/randomCountTask.js +1 -1
  55. package/editor/ecs/component/editors/primitive/ArrayEditor.js +1 -1
  56. package/editor/tools/v2/BlenderCameraOrientationGizmo.js +6 -0
  57. package/editor/view/ecs/components/common/AutoCanvasView.js +13 -25
  58. package/engine/asset/AssetManager.d.ts +5 -1
  59. package/engine/asset/AssetManager.js +50 -15
  60. package/engine/asset/AssetManager.spec.js +17 -11
  61. package/engine/asset/AssetRequest.js +57 -0
  62. package/engine/asset/loaders/ArrayBufferLoader.js +22 -0
  63. package/engine/asset/loaders/AssetLoader.js +1 -1
  64. package/engine/ecs/System.js +1 -1
  65. package/engine/ecs/dynamic_actions/DynamicActorSystem.js +1 -1
  66. package/engine/graphics/FrameRunner.js +5 -9
  67. package/engine/graphics/ecs/animation/animator/AnimationClipDefinition.js +1 -1
  68. package/engine/graphics/ecs/animation/animator/graph/definition/AnimationGraphDefinition.js +1 -1
  69. package/engine/graphics/ecs/camera/Camera.js +1 -10
  70. package/engine/graphics/ecs/camera/CameraSystem.js +8 -8
  71. package/engine/graphics/ecs/camera/ProjectionType.js +9 -0
  72. package/engine/graphics/ecs/camera/build_three_camera_object.js +3 -3
  73. package/engine/graphics/ecs/decal/v2/prototypeDecalSystem.js +59 -4
  74. package/engine/graphics/geometry/VertexDataSpec.js +1 -1
  75. package/engine/graphics/impostors/octahedral/prototypeBaker.js +3 -3
  76. package/engine/graphics/micron/plugin/GLTFAssetTransformer.js +1 -1
  77. package/engine/graphics/micron/plugin/MicronRenderPlugin.js +3 -1
  78. package/engine/graphics/particles/node-based/codegen/modules/FunctionSignature.js +1 -1
  79. package/engine/graphics/render/forward_plus/LightManager.js +1 -1
  80. package/engine/graphics/render/forward_plus/LightManager.spec.js +4 -0
  81. package/engine/graphics/render/forward_plus/computeFrustumCorners.js +4 -2
  82. package/engine/graphics/render/forward_plus/prototype/prototypeLightManager.js +2 -2
  83. package/engine/graphics/render/layers/RenderLayerUtils.js +2 -2
  84. package/engine/graphics/shaders/DenoiseShader.js +1 -1
  85. package/engine/graphics/texture/atlas/AtlasPatch.js +11 -3
  86. package/engine/graphics/texture/atlas/CachingTextureAtlas.js +2 -2
  87. package/engine/graphics/texture/atlas/TextureAtlas.js +7 -1
  88. package/engine/graphics/texture/atlas/TextureAtlas.spec.js +22 -0
  89. package/engine/graphics/texture/sampler/Sampler2D.js +0 -64
  90. package/engine/graphics/texture/sampler/Sampler2D.spec.js +2 -1
  91. package/engine/graphics/texture/sampler/sampler2d_combine.js +67 -0
  92. package/engine/intelligence/behavior/ecs/BehaviorSystem.spec.js +0 -3
  93. package/engine/network/PriorityFetch.js +192 -0
  94. package/engine/simulation/DormandPrince.js +1 -1
  95. package/engine/ui/DraggableAspect.js +0 -1
  96. package/generation/grid/generation/road/GridTaskGenerateRoads.js +1 -1
  97. package/package.json +1 -1
  98. package/view/elements/CanvasView.js +7 -1
  99. package/view/elements/image/HTMLElementCacheKey.js +1 -1
  100. package/view/util/DomSizeObserver.js +3 -5
  101. package/core/collection/ArrayUtils.js +0 -263
  102. package/core/geom/3d/tetrahedra/delaunay/tetrahedral_mesh_compute_cavity.js +0 -73
  103. package/core/geom/3d/tetrahedra/hxt/a.js +0 -524
  104. package/core/geom/3d/tetrahedra/hxt/hxt.js +0 -140
  105. package/core/geom/3d/tetrahedra/hxt/hxt.wasm +0 -0
@@ -0,0 +1,192 @@
1
+ import FastBinaryHeap from "../../core/collection/heap/FastBinaryHeap.js";
2
+ import { noop } from "../../core/function/Functions.js";
3
+ import { assert } from "../../core/assert.js";
4
+
5
+ /**
6
+ * @readonly
7
+ * @type {{high: number, auto: number, low: number}}
8
+ */
9
+ const priority_value_map = {
10
+ "high": 10,
11
+ "low": -1,
12
+ "auto": 0
13
+ };
14
+
15
+ /**
16
+ *
17
+ * @param {string|undefined} p
18
+ * @return {number}
19
+ */
20
+ function extract_priority_from_resource(p) {
21
+
22
+ let v = 0;
23
+
24
+ if (typeof p === "string") {
25
+ v = priority_value_map[p];
26
+
27
+ if (v === undefined) {
28
+ console.warn(`Unsupported request priority value '${p}', defaulting to 'auto'`);
29
+ }
30
+
31
+ v = priority_value_map['auto'];
32
+ }
33
+
34
+ return v;
35
+
36
+ }
37
+
38
+ class FetchRequest {
39
+ /**
40
+ *
41
+ * @param {Request|string} resource
42
+ * @param {{}} options
43
+ */
44
+ constructor(resource, options) {
45
+ let priority = 0;
46
+
47
+ this.__resource = resource;
48
+ this.__options = options;
49
+
50
+ if (typeof this.__resource === "object" && typeof this.__resource.priority !== "undefined") {
51
+ priority = extract_priority_from_resource(this.__resource.priority);
52
+ }
53
+
54
+ this.__priority = priority;
55
+
56
+ this.fulfillment = {
57
+ resolve: null, reject: null
58
+ };
59
+
60
+ this.promise = new Promise((resolve, reject) => {
61
+ this.fulfillment.resolve = resolve;
62
+ this.fulfillment.reject = reject;
63
+ });
64
+ }
65
+ }
66
+
67
+ /**
68
+ *
69
+ * @param {FetchRequest} request
70
+ * @returns {number}
71
+ */
72
+ function get_priority_score(request) {
73
+ return -request.__priority;
74
+ }
75
+
76
+ /**
77
+ * @readonly
78
+ * @type {number}
79
+ */
80
+ const DEFAULT_CONCURRENCY = Infinity;
81
+
82
+ /**
83
+ * Wraps {@link fetch} api and adds concurrency management to it by queueing requests,
84
+ * as well as prioritization in that queue
85
+ */
86
+ export class PriorityFetch {
87
+ constructor({
88
+ adapter = noop,
89
+ concurrency = DEFAULT_CONCURRENCY
90
+ }) {
91
+ /**
92
+ *
93
+ * @type {number}
94
+ * @private
95
+ */
96
+ this.__concurrency = concurrency;
97
+
98
+ /**
99
+ *
100
+ * @type {BinaryHeap<FetchRequest>}
101
+ * @private
102
+ */
103
+ this.__queue = new FastBinaryHeap(get_priority_score);
104
+
105
+ /**
106
+ *
107
+ * @type {Set<FetchRequest>}
108
+ * @private
109
+ */
110
+ this.__pending_set = new Set();
111
+
112
+ /**
113
+ *
114
+ * @type {null}
115
+ * @private
116
+ */
117
+ this.__adapter = adapter;
118
+ }
119
+
120
+ /**
121
+ *
122
+ * @param {function} v
123
+ */
124
+ set adapter(v) {
125
+ this.__adapter = v;
126
+ }
127
+
128
+ /**
129
+ *
130
+ * @param {number} v
131
+ */
132
+ set concurrency(v) {
133
+ assert.isNumber(v, 'v');
134
+ assert.notNaN(v, 'v');
135
+ assert.greaterThan(v, 0, 'concurrency must be greater than 0');
136
+
137
+ this.__concurrency = v;
138
+ }
139
+
140
+ /**
141
+ *
142
+ * @return {number}
143
+ */
144
+ get concurrency() {
145
+ return this.__concurrency;
146
+ }
147
+
148
+ /**
149
+ *
150
+ * @param {FetchRequest} req
151
+ * @private
152
+ */
153
+ __dispatch(req) {
154
+ const promise = this.__adapter(req.__resource, req.__options);
155
+
156
+ promise.finally(() => {
157
+ this.__pending_set.delete(req);
158
+
159
+ this.__prod();
160
+ });
161
+
162
+ promise
163
+ .then(
164
+ (v) => {
165
+ req.fulfillment.resolve(v);
166
+ },
167
+ (reason) => {
168
+ req.fulfillment.reject(reason);
169
+ }
170
+ );
171
+ }
172
+
173
+ __prod() {
174
+ if (this.__pending_set.size < this.__concurrency && !this.__queue.isEmpty()) {
175
+ const req = this.__queue.pop();
176
+
177
+ this.__dispatch(req);
178
+ }
179
+ }
180
+
181
+ fetch(resource, options) {
182
+ const req = new FetchRequest(resource, options);
183
+
184
+ if (this.__pending_set.size < this.__concurrency) {
185
+ this.__dispatch(req);
186
+ } else {
187
+ this.__queue.push(req);
188
+ }
189
+
190
+ return req.promise;
191
+ }
192
+ }
@@ -166,7 +166,7 @@ function computeStepSize(fxy, x, y, suggestedStepSize, tolerance, maxIterations,
166
166
  * @param {number} hmax max step size
167
167
  * @param {number} hmin min step size
168
168
  * @param {number} max_iteration maximum number of iterations
169
- * @returns {*[]}
169
+ * @returns {Array.<number>}
170
170
  */
171
171
  function odedopri(fxy, x0, y0, x1, tol, hmax, hmin, max_iteration) {
172
172
 
@@ -34,7 +34,6 @@ export class DraggableAspect {
34
34
  const pointerGlobal = this.pointerGlobal = new PointerDevice(window);
35
35
 
36
36
  const dragOriginalPosition = new Vector2();
37
- const delta = new Vector2();
38
37
  const pointer_position_last = new Vector2();
39
38
 
40
39
  if (stopPropagation) {
@@ -11,7 +11,6 @@ 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 { groupArrayBy } from "../../../../core/collection/ArrayUtils.js";
15
14
  import { collectIteratorValueToArray } from "../../../../core/collection/IteratorUtils.js";
16
15
  import { QuadTreeNode } from "../../../../core/geom/2d/quad-tree/QuadTreeNode.js";
17
16
  import AABB2 from "../../../../core/geom/AABB2.js";
@@ -24,6 +23,7 @@ import { RoadConnectionNetwork } from "./RoadConnectionNetwork.js";
24
23
  import { MirGridLayers } from "../../../example/grid/MirGridLayers.js";
25
24
  import { actionTask } from "../../../../core/process/task/util/actionTask.js";
26
25
  import { countTask } from "../../../../core/process/task/util/countTask.js";
26
+ import { groupArrayBy } from "../../../../core/collection/array/groupArrayBy.js";
27
27
 
28
28
  const NODE_TYPE_ROAD_CONNECTOR = 'Road Connector';
29
29
 
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "productName": "Meep",
6
6
  "description": "production-ready JavaScript game engine based on Entity Component System Architecture",
7
7
  "author": "Alexander Goldring",
8
- "version": "2.43.1",
8
+ "version": "2.43.3",
9
9
  "dependencies": {
10
10
  "gl-matrix": "3.4.3",
11
11
  "fast-levenshtein": "2.0.6",
@@ -1,6 +1,8 @@
1
1
  import View from "../View.js";
2
2
 
3
-
3
+ /**
4
+ * Wrapper around {@link HTMLCanvasElement}, exposes {@link CanvasRenderingContext2D}
5
+ */
4
6
  export class CanvasView extends View {
5
7
  constructor() {
6
8
  super();
@@ -8,6 +10,10 @@ export class CanvasView extends View {
8
10
  const canvas = document.createElement('canvas');
9
11
  this.el = canvas;
10
12
 
13
+ /**
14
+ *
15
+ * @type {CanvasRenderingContext2D}
16
+ */
11
17
  this.context2d = canvas.getContext('2d');
12
18
 
13
19
  this.size.onChanged.add(this.__handleSizeChange, this);
@@ -1,8 +1,8 @@
1
- import { isArrayEqual } from "../../../core/collection/ArrayUtils.js";
2
1
  import { KeyValuePair } from "../../../core/collection/KeyValuePair.js";
3
2
  import { computeStringHash } from "../../../core/primitives/strings/computeStringHash.js";
4
3
  import { computeHashArray } from "../../../core/collection/array/computeHashArray.js";
5
4
  import { computeHashIntegerArray } from "../../../core/collection/array/computeHashIntegerArray.js";
5
+ import { isArrayEqual } from "../../../core/collection/array/isArrayEqual.js";
6
6
 
7
7
  /**
8
8
  *
@@ -54,13 +54,11 @@ export class DomSizeObserver {
54
54
  * @param {number} [depth=0] how deep should the observation go
55
55
  */
56
56
  constructor({ depth = 0 } = {}) {
57
- const rectangle = new Rectangle();
58
-
59
57
  /**
60
58
  *
61
59
  * @type {Rectangle}
62
60
  */
63
- this.dimensions = rectangle;
61
+ this.dimensions = new Rectangle();
64
62
 
65
63
  /**
66
64
  *
@@ -169,7 +167,7 @@ export class DomSizeObserver {
169
167
  }
170
168
 
171
169
  /**
172
- *
170
+ * Will attach to the view's element and automatically start/stop observing when the view is linked/unlinked
173
171
  * @param {View} view
174
172
  */
175
173
  watchView(view) {
@@ -184,7 +182,7 @@ export class DomSizeObserver {
184
182
  }
185
183
 
186
184
  /**
187
- *
185
+ * Counterpart to {@link #watchView}
188
186
  * @param {View} view
189
187
  */
190
188
  unwatchView(view) {
@@ -1,263 +0,0 @@
1
- /**
2
- *
3
- * @param {Array} first
4
- * @param {Array} second
5
- * @returns {boolean}
6
- */
7
- import { assert } from "../assert.js";
8
- import { returnZero } from "../function/Functions.js";
9
- import { min2 } from "../math/min2.js";
10
- import { HashMap } from "./HashMap.js";
11
- import { randomIntegerBetween } from "../math/random/randomIntegerBetween.js";
12
-
13
-
14
- /**
15
- * @template T
16
- * @param {function} random
17
- * @param {T[]} array
18
- */
19
- export function randomizeArrayElementOrder(random, array) {
20
- const n = array.length;
21
-
22
- const lastValidIndex = n - 1;
23
-
24
- for (let i = 0; i < n; i++) {
25
- const t = randomIntegerBetween(random, 0, lastValidIndex);
26
-
27
- if (t === i) {
28
- continue;
29
- }
30
-
31
- arraySwapElements(array, i, t);
32
- }
33
- }
34
-
35
- /**
36
- * Pick multiple random items from an array
37
- *
38
- * @template T
39
- * @param {function} random
40
- * @param {T[]} source
41
- * @param {T[]} target
42
- * @param {number} count how many items to pick
43
- * @returns {T}
44
- */
45
- export function randomMultipleFromArray(random, source, target, count) {
46
-
47
- const order = [];
48
-
49
- const source_length = source.length;
50
- for (let i = 0; i < source_length; i++) {
51
- order[i] = i;
52
- }
53
-
54
- randomizeArrayElementOrder(random, order);
55
-
56
- const target_length = min2(source_length, count);
57
-
58
- for (let i = 0; i < target_length; i++) {
59
- const index = order[i];
60
- const element = source[index];
61
- target.push(element);
62
- }
63
-
64
- return target_length;
65
- }
66
-
67
- /**
68
- * @template T,R
69
- * @param {T[]} first
70
- * @param {R[]} second
71
- * @return {boolean}
72
- */
73
- export function isArrayEqual(first, second) {
74
-
75
- const il = first.length;
76
-
77
- if (il !== second.length) return false;
78
-
79
- let i = 0;
80
-
81
- for (; i < il; i++) {
82
-
83
- const a = first[i];
84
- const b = second[i];
85
-
86
- if (a === b) {
87
- continue;
88
- }
89
-
90
-
91
- if (a === undefined) {
92
- //a is undefined, and B is something else
93
- return false;
94
- }
95
-
96
- if (a === null) {
97
- //a is null and B is something else
98
- return false;
99
- }
100
-
101
- //try "equals" method
102
- if (typeof a.equals === "function") {
103
-
104
- if (!a.equals(b)) {
105
- return false;
106
- }
107
-
108
- } else {
109
- return false;
110
- }
111
-
112
- }
113
-
114
- return true;
115
-
116
- }
117
-
118
- /**
119
- * @template T
120
- * @param {T[]} array
121
- * @param {function(T):number} scoreFunction
122
- * @returns {T[]}
123
- */
124
- export function arrayPickBestElements(array, scoreFunction) {
125
- assert.notEqual(array, undefined, 'array is undefined');
126
- assert.isArray(array, 'array');
127
-
128
- assert.typeOf(scoreFunction, 'function', 'scoreFunction');
129
-
130
- let bestScore;
131
-
132
- const size = array.length;
133
-
134
- if (size === 0) {
135
- return [];
136
- }
137
-
138
- const first = array[0];
139
-
140
- bestScore = scoreFunction(first);
141
-
142
- assert.isNumber(bestScore, 'bestScore');
143
-
144
- const result = [first];
145
-
146
- for (let i = 1; i < size; i++) {
147
- const el = array[i];
148
-
149
- // compute score
150
- const score = scoreFunction(el);
151
-
152
- assert.isNumber(score, 'score');
153
-
154
- if (score > bestScore) {
155
- bestScore = score;
156
-
157
- result.splice(0, result.length);
158
-
159
- result.push(el);
160
- } else if (score === bestScore) {
161
- result.push(el);
162
- }
163
- }
164
-
165
- return result;
166
- }
167
-
168
- /**
169
- * @template T
170
- * @param {T[]} array
171
- * @param {function(T):number} scoreFunction
172
- * @returns {T}
173
- */
174
- export function arrayPickMinElement(array, scoreFunction) {
175
- assert.notEqual(array, undefined, 'array is undefined');
176
- assert.typeOf(scoreFunction, 'function', 'scoreFunction');
177
-
178
- let bestElement;
179
- let bestScore;
180
-
181
- const size = array.length;
182
-
183
- if (size === 0) {
184
- return undefined;
185
- }
186
-
187
- bestElement = array[0];
188
-
189
- bestScore = scoreFunction(bestElement);
190
-
191
- assert.typeOf(bestScore, 'number', 'bestScore');
192
-
193
- for (let i = 1; i < size; i++) {
194
- const el = array[i];
195
-
196
- // compute score
197
- const score = scoreFunction(el);
198
-
199
- assert.typeOf(score, 'number', 'score');
200
-
201
- if (score < bestScore) {
202
- bestScore = score;
203
- bestElement = el;
204
- }
205
- }
206
-
207
- return bestElement;
208
- }
209
-
210
- /**
211
- * @template T,K
212
- * @param {T[]} array
213
- * @param {function(T):K} groupingFunction
214
- * @param keyHashFunction
215
- * @returns {Map<K,T[]>}
216
- */
217
- export function groupArrayBy(array, groupingFunction, keyHashFunction = returnZero) {
218
- const result = new HashMap({
219
- keyHashFunction,
220
- keyEqualityFunction(a, b) {
221
- if (a === b) {
222
- return true;
223
- }
224
-
225
- if (typeof a === "object" && a !== null && typeof a.equals === "function") {
226
- return a.equals(b);
227
- }
228
-
229
- return false;
230
- }
231
- });
232
-
233
- for (let i = 0; i < array.length; i++) {
234
- const element = array[i];
235
-
236
- const groupKey = groupingFunction(element);
237
-
238
- const group = result.get(groupKey);
239
-
240
- if (group === undefined) {
241
- result.set(groupKey, [element]);
242
- } else {
243
- group.push(element);
244
- }
245
- }
246
-
247
- return result;
248
- }
249
-
250
-
251
- /**
252
- * @template T
253
- * @param {T[]} array
254
- * @param {number} index0
255
- * @param {number} index1
256
- */
257
- export function arraySwapElements(array, index0, index1) {
258
- const t = array[index0];
259
-
260
- array[index0] = array[index1];
261
- array[index1] = t;
262
- }
263
-
@@ -1,73 +0,0 @@
1
- import { assert } from "../../../../assert.js";
2
- import { point_in_tetrahedron_circumsphere } from "../point_in_tetrahedron_circumsphere.js";
3
- import { INVALID_NEIGHBOUR } from "../tetrahedra_collection.js";
4
-
5
- /**
6
- *
7
- * @param {TetrahedralMesh} mesh
8
- * @param {Cavity} cavity
9
- * @param {number[]|Float32Array} points
10
- * @param {number} containing_tetra tetrahedron that contains point
11
- * @param {number} point_index point that forms the cavity
12
- */
13
- export function tetrahedral_mesh_compute_cavity(mesh, cavity, points, containing_tetra, point_index) {
14
- assert.isNonNegativeInteger(containing_tetra, 'containing_tetra');
15
-
16
- cavity.reset();
17
-
18
- /**
19
- *
20
- * @type {number[]}
21
- */
22
- const open_set = [
23
- containing_tetra
24
- ];
25
-
26
- /**
27
- *
28
- * @type {number[]}
29
- */
30
- const closed_set = [];
31
-
32
- // 2. find the Delaunay "cavity", a set of tetrahedrons who's circumsphere overlarlaps the point
33
- // perform breadth-first expansion on the containing tetra to identify the cavity
34
- while (open_set.length > 0) {
35
-
36
- const tetra = open_set.pop();
37
- cavity.push(tetra);
38
- closed_set.push(tetra);
39
-
40
- // get neighbours
41
- for (let i = 0; i < 4; i++) {
42
-
43
- const neighbour_encoded = mesh.getNeighbour(tetra, i);
44
- const neighbour_tetra_index = neighbour_encoded >>> 2;
45
-
46
- if (
47
- (neighbour_encoded === INVALID_NEIGHBOUR) // no neighbour
48
- || closed_set.includes(neighbour_tetra_index) // already visited
49
- || open_set.includes(neighbour_tetra_index) // already in open set
50
- ) {
51
-
52
- continue;
53
- }
54
-
55
- const a = mesh.getCornerIndex(neighbour_tetra_index, 0);
56
- const b = mesh.getCornerIndex(neighbour_tetra_index, 1);
57
- const c = mesh.getCornerIndex(neighbour_tetra_index, 2);
58
- const d = mesh.getCornerIndex(neighbour_tetra_index, 3);
59
-
60
- // check neighbour
61
- const is_in_sphere = point_in_tetrahedron_circumsphere(points, a, b, c, d, containing_tetra);
62
-
63
- if (is_in_sphere) {
64
- open_set.push(neighbour_tetra_index);
65
- } else {
66
- // move directly to closed set
67
- closed_set.push(neighbour_tetra_index);
68
- }
69
-
70
-
71
- }
72
- }
73
- }