@woosh/meep-engine 2.78.1 → 2.80.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 (56) hide show
  1. package/build/meep.cjs +235 -233
  2. package/build/meep.min.js +1 -1
  3. package/build/meep.module.js +235 -233
  4. package/package.json +1 -1
  5. package/src/core/geom/2d/aabb/AABB2.js +6 -18
  6. package/src/core/geom/3d/SurfacePoint3.spec.js +1 -1
  7. package/src/core/geom/3d/{matrix → mat4}/m4_multiply.spec.js +3 -4
  8. package/src/core/geom/3d/{matrix → mat4}/m4_multiply_alphatensor.spec.js +3 -3
  9. package/src/core/geom/3d/morton/v3_morton_encode_transformed.spec.js +1 -1
  10. package/src/core/geom/3d/sphere/sphere_radius_sqr_from_v3_array_transformed.spec.js +1 -1
  11. package/src/core/geom/Quaternion.js +1 -1
  12. package/src/core/geom/Vector3.js +2 -2
  13. package/src/core/geom/Vector3.spec.js +2 -2
  14. package/src/core/geom/packing/max-rect/{MaxRectangles.js → MaxRectanglesPacker.js} +25 -32
  15. package/src/core/geom/packing/max-rect/MaxRectanglesPacker.spec.js +60 -0
  16. package/src/core/geom/packing/max-rect/packMaxRectangles.js +19 -0
  17. package/src/core/geom/vec3/v3_angle_between.js +15 -4
  18. package/src/core/geom/vec3/{v3_computeOffsetVector.js → v3_displace_in_direction.js} +11 -2
  19. package/src/core/graph/cluster_mesh_metis.js +3 -3
  20. package/src/core/graph/metis/metis.js +16 -1
  21. package/src/core/graph/metis/metis_options.js +32 -29
  22. package/src/core/math/interval/overlap1D.js +7 -0
  23. package/src/core/math/noise/create_simplex_noise_2d.js +4 -0
  24. package/src/core/math/spline/computeCatmullRomSplineUniformDistance.js +3 -3
  25. package/src/core/math/spline/v3_computeCatmullRomSplineUniformDistance.js +42 -0
  26. package/src/core/model/node-graph/node/NodeDescription.js +12 -10
  27. package/src/core/model/node-graph/node/NodeDescription.spec.js +14 -1
  28. package/src/core/model/object/objectKeyByValue.js +3 -2
  29. package/src/engine/ecs/ik/OneBoneSurfaceAlignmentSolver.js +2 -2
  30. package/src/engine/ecs/ik/TwoBoneInverseKinematicsSolver.js +2 -2
  31. package/src/engine/ecs/renderable/Renderable.js +1 -1
  32. package/src/engine/ecs/terrain/ecs/TerrainSystem.js +1 -1
  33. package/src/engine/ecs/terrain/tiles/TerrainTile.spec.js +2 -2
  34. package/src/engine/ecs/transform/Transform.js +3 -3
  35. package/src/engine/ecs/transform/Transform.spec.js +3 -3
  36. package/src/engine/ecs/transform-attachment/TransformAttachment.js +2 -1
  37. package/src/engine/ecs/transform-attachment/TransformAttachmentSystem.js +45 -33
  38. package/src/engine/graphics/ecs/path/entity/testEntityPath.js +16 -10
  39. package/src/engine/graphics/material/optimization/MaterialOptimizationContext.js +1 -1
  40. package/src/engine/graphics/texture/atlas/TextureAtlas.js +1 -1
  41. package/src/engine/graphics/texture/atlas/gpu/WebGLTextureAtlas.js +3 -3
  42. package/src/engine/graphics/three/expand_aabb_by_transformed_three_object.js +1 -1
  43. package/src/engine/graphics/three/expand_aabb_by_transformed_three_object.spec.js +2 -2
  44. package/src/engine/navigation/ecs/components/Path.js +5 -12
  45. package/src/engine/simulation/Ticker.js +40 -61
  46. package/src/core/geom/LineSegment.js +0 -207
  47. package/src/core/primitives/strings/prefixTree/PrefixTree.js +0 -225
  48. package/src/core/primitives/strings/prefixTree/PrefixTree.spec.js +0 -39
  49. package/src/core/primitives/strings/prefixTree/PrefixTreeLeaf.js +0 -25
  50. package/src/core/primitives/strings/prefixTree/PrefixTreeNode.js +0 -16
  51. /package/src/core/geom/3d/{matrix → mat4}/MATRIX_4_IDENTITY.js +0 -0
  52. /package/src/core/geom/3d/{matrix → mat4}/MATRIX_4_IDENTITY.spec.js +0 -0
  53. /package/src/core/geom/3d/{matrix → mat4}/allocate_transform_m4.js +0 -0
  54. /package/src/core/geom/3d/{matrix → mat4}/m4_make_translation.js +0 -0
  55. /package/src/core/geom/3d/{matrix → mat4}/m4_multiply.js +0 -0
  56. /package/src/core/geom/3d/{matrix → mat4}/m4_multiply_alphatensor.js +0 -0
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "description": "Fully featured ECS game engine written in JavaScript",
6
6
  "type": "module",
7
7
  "author": "Alexander Goldring",
8
- "version": "2.78.1",
8
+ "version": "2.80.0",
9
9
  "main": "build/meep.module.js",
10
10
  "module": "build/meep.module.js",
11
11
  "exports": {
@@ -9,11 +9,11 @@ import { clamp } from "../../../math/clamp.js";
9
9
  import { max2 } from "../../../math/max2.js";
10
10
  import { min2 } from "../../../math/min2.js";
11
11
  import Vector2 from "../../Vector2.js";
12
- import { aabb2_compute_overlap } from "./aabb2_compute_overlap.js";
13
- import { aabb2_overlap_exists } from "./aabb2_overlap_exists.js";
14
12
  import {
15
13
  line_segment_compute_line_segment_intersection_2d
16
14
  } from "../line/line_segment_compute_line_segment_intersection_2d.js";
15
+ import { aabb2_compute_overlap } from "./aabb2_compute_overlap.js";
16
+ import { aabb2_overlap_exists } from "./aabb2_overlap_exists.js";
17
17
 
18
18
  /**
19
19
  *
@@ -146,7 +146,7 @@ class AABB2 {
146
146
  /**
147
147
  *
148
148
  * @param {AABB2} other
149
- * @returns {number}
149
+ * @returns {boolean}
150
150
  */
151
151
  overlapExists(other) {
152
152
  const ax0 = this.x0;
@@ -173,6 +173,7 @@ class AABB2 {
173
173
  _expandToFit(x0, y0, x1, y1) {
174
174
  this.x0 = min2(this.x0, x0);
175
175
  this.y0 = min2(this.y0, y0);
176
+
176
177
  this.x1 = max2(this.x1, x1);
177
178
  this.y1 = max2(this.y1, y1);
178
179
  }
@@ -183,21 +184,8 @@ class AABB2 {
183
184
  * @param {number} y
184
185
  */
185
186
  _expandToFitPoint(x, y) {
186
- if (x < this.x0) {
187
- this.x0 = x;
188
- }
189
-
190
- if (x > this.x1) {
191
- this.x1 = x;
192
- }
193
-
194
- if (y < this.y0) {
195
- this.y0 = y;
196
- }
197
-
198
- if (y > this.y1) {
199
- this.y1 = y;
200
- }
187
+ // shortcut, use a 0-size box
188
+ this._expandToFit(x, y, x, y);
201
189
  }
202
190
 
203
191
  /**
@@ -1,5 +1,5 @@
1
+ import { MATRIX_4_IDENTITY } from "./mat4/MATRIX_4_IDENTITY.js";
1
2
  import { SurfacePoint3 } from "./SurfacePoint3.js";
2
- import { MATRIX_4_IDENTITY } from "./matrix/MATRIX_4_IDENTITY.js";
3
3
 
4
4
 
5
5
  test("equals", () => {
@@ -1,7 +1,6 @@
1
- import {MATRIX_4_IDENTITY} from "./MATRIX_4_IDENTITY.js";
2
- import {m4_multiply} from "./m4_multiply.js";
3
- import {m4_multiply_alphatensor} from "./m4_multiply_alphatensor.js";
4
- import {number_pretty_print} from "../../../primitives/numbers/number_pretty_print.js";
1
+ import { number_pretty_print } from "../../../primitives/numbers/number_pretty_print.js";
2
+ import { m4_multiply } from "./m4_multiply.js";
3
+ import { MATRIX_4_IDENTITY } from "./MATRIX_4_IDENTITY.js";
5
4
 
6
5
  test("identity multiplication", () => {
7
6
 
@@ -1,6 +1,6 @@
1
- import {m4_multiply_alphatensor} from "./m4_multiply_alphatensor.js";
2
- import {MATRIX_4_IDENTITY} from "./MATRIX_4_IDENTITY.js";
3
- import {number_pretty_print} from "../../../primitives/numbers/number_pretty_print.js";
1
+ import { number_pretty_print } from "../../../primitives/numbers/number_pretty_print.js";
2
+ import { m4_multiply_alphatensor } from "./m4_multiply_alphatensor.js";
3
+ import { MATRIX_4_IDENTITY } from "./MATRIX_4_IDENTITY.js";
4
4
 
5
5
  test("identity multiplication", () => {
6
6
 
@@ -1,5 +1,5 @@
1
+ import { MATRIX_4_IDENTITY } from "../mat4/MATRIX_4_IDENTITY.js";
1
2
  import { v3_morton_encode_transformed } from "./v3_morton_encode_transformed.js";
2
- import { MATRIX_4_IDENTITY } from "../matrix/MATRIX_4_IDENTITY.js";
3
3
 
4
4
  test("valid number with identity transform", () => {
5
5
  const v = v3_morton_encode_transformed(0, 0, 0, MATRIX_4_IDENTITY);
@@ -1,5 +1,5 @@
1
+ import { MATRIX_4_IDENTITY } from "../mat4/MATRIX_4_IDENTITY.js";
1
2
  import { sphere_radius_sqr_from_v3_array_transformed } from "./sphere_radius_sqr_from_v3_array_transformed.js";
2
- import { MATRIX_4_IDENTITY } from "../matrix/MATRIX_4_IDENTITY.js";
3
3
 
4
4
  test("base case", () => {
5
5
  expect(sphere_radius_sqr_from_v3_array_transformed([0, 0, 0], 3, MATRIX_4_IDENTITY)).toBe(0);
@@ -1546,7 +1546,7 @@ class Quaternion {
1546
1546
  * @param {Quaternion} result
1547
1547
  * @param {Quaternion} from
1548
1548
  * @param {Quaternion} to
1549
- * @param {number} max_delta
1549
+ * @param {number} max_delta in radians
1550
1550
  */
1551
1551
  static rotateTowards(result, from, to, max_delta) {
1552
1552
  assert.isNumber(max_delta, 'max_delta');
@@ -37,7 +37,7 @@ class Vector3 {
37
37
 
38
38
  /**
39
39
  *
40
- * @param {number[]} array
40
+ * @param {number[]|Float32Array} array
41
41
  * @param {number} offset
42
42
  */
43
43
  readFromArray(array, offset = 0) {
@@ -50,7 +50,7 @@ class Vector3 {
50
50
 
51
51
  /**
52
52
  *
53
- * @param {number[]} array
53
+ * @param {number[]|Float32Array} array
54
54
  * @param {number} offset
55
55
  */
56
56
  writeToArray(array, offset = 0) {
@@ -1,5 +1,5 @@
1
- import {MATRIX_4_IDENTITY} from "./3d/matrix/MATRIX_4_IDENTITY.js";
2
- import {v3_slerp} from "./vec3/v3_slerp.js";
1
+ import { MATRIX_4_IDENTITY } from "./3d/mat4/MATRIX_4_IDENTITY.js";
2
+ import { v3_slerp } from "./vec3/v3_slerp.js";
3
3
  import Vector3 from "./Vector3.js";
4
4
 
5
5
  test('slerp', () => {
@@ -1,15 +1,19 @@
1
- import BinaryHeap from "../../../collection/heap/FastBinaryHeap.js";
2
1
  import { assert } from "../../../assert.js";
2
+ import BinaryHeap from "../../../collection/heap/FastBinaryHeap.js";
3
+ import AABB2 from "../../2d/aabb/AABB2.js";
3
4
  import { QuadTreeDatum } from "../../2d/quad-tree/QuadTreeDatum.js";
4
5
  import { QuadTreeNode } from "../../2d/quad-tree/QuadTreeNode.js";
5
- import AABB2 from "../../2d/aabb/AABB2.js";
6
6
  import Vector2 from "../../Vector2.js";
7
- import { removeRedundantBoxes } from "./removeRedundantBoxes.js";
8
7
  import { costByRemainingArea } from "./cost/costByRemainingArea.js";
9
8
  import { findBestContainer } from "./findBestContainer.js";
10
9
  import { packOneBox } from "./packOneBox.js";
10
+ import { removeRedundantBoxes } from "./removeRedundantBoxes.js";
11
11
 
12
-
12
+ /**
13
+ * Packs rectangles into a finite area, packer is incremental and supports both insertions and removals of rectangles
14
+ * Implementation of "max rectangles" packing algorithm.
15
+ * Useful for packing texture atlases
16
+ */
13
17
  export class MaxRectanglesPacker {
14
18
  /**
15
19
  *
@@ -24,6 +28,8 @@ export class MaxRectanglesPacker {
24
28
  * @type {QuadTreeNode}
25
29
  */
26
30
  this.free = new QuadTreeNode(0, 0, width, height);
31
+
32
+ // initialize a with a free space occupying the entire area
27
33
  this.free.add(null, 0, 0, width, height);
28
34
 
29
35
  /**
@@ -98,7 +104,8 @@ export class MaxRectanglesPacker {
98
104
  }
99
105
 
100
106
  /**
101
- *
107
+ * Tests whether a rectangle of given dimensions can be packed into remaining space
108
+ * Essentially, if this method succeeds - insertion will succeed as well, and if it fails - insertion will fail too
102
109
  * @param {number} w
103
110
  * @param {number} h
104
111
  * @return {boolean}
@@ -184,9 +191,10 @@ export class MaxRectanglesPacker {
184
191
  }
185
192
 
186
193
  /**
187
- * Resize the packer canvas
194
+ * Resize the packer canvas, may trigger repacking if new dimensions are smaller than the existing ones
188
195
  * @param {number} width
189
196
  * @param {number} height
197
+ * @returns {boolean} false if packing fails after resize, true otherwise
190
198
  */
191
199
  resize(width, height) {
192
200
 
@@ -199,18 +207,20 @@ export class MaxRectanglesPacker {
199
207
 
200
208
  if (oldWidth > width || oldHeight > height) {
201
209
  //canvas was made smaller in at least one dimension, re-pack is required
202
- this.repack();
203
- } else {
204
- //canvas was enlarged, we can simply add new free areas
205
- if (width > oldWidth) {
206
- this.free.insertDatum(new QuadTreeDatum(oldWidth, 0, width, height));
207
- }
208
- if (height > oldHeight) {
209
- this.free.insertDatum(new QuadTreeDatum(0, oldHeight, width, height))
210
- }
210
+ return this.repack();
211
+ }
212
+
213
+ //canvas was enlarged, we can simply add new free areas
214
+ if (width > oldWidth) {
215
+ this.free.insertDatum(new QuadTreeDatum(oldWidth, 0, width, height));
216
+ }
217
+ if (height > oldHeight) {
218
+ this.free.insertDatum(new QuadTreeDatum(0, oldHeight, width, height))
211
219
  }
212
220
 
213
221
  // assert.ok(this.validate());
222
+
223
+ return true;
214
224
  }
215
225
 
216
226
  validate() {
@@ -239,20 +249,3 @@ export class MaxRectanglesPacker {
239
249
  }
240
250
 
241
251
 
242
- /**
243
- * Packs {@link AABB2} boxes into defined bounds
244
- *
245
- * Based on paper "A Thousand Ways to Pack the Bin - A Practical Approach to Two-Dimensional Rectangle Bin Packing" 2010 Jukka Jylänki
246
- * Method presented called Maximal Rectangles
247
- *
248
- * @param {number} width
249
- * @param {number} height
250
- * @param {AABB2[]} boxes
251
- * @returns {boolean} true if packing was successful, false otherwise
252
- */
253
- export function packMaxRectangles(width, height, boxes) {
254
-
255
- const packer = new MaxRectanglesPacker(width, height);
256
-
257
- return packer.addMany(boxes);
258
- }
@@ -0,0 +1,60 @@
1
+ import AABB2 from "../../2d/aabb/AABB2.js";
2
+ import { MaxRectanglesPacker } from "./MaxRectanglesPacker.js";
3
+
4
+ test("constructor does not throw", () => {
5
+ new MaxRectanglesPacker(1, 1)
6
+ });
7
+
8
+ test("pack 1 box that takes up entire available area", () => {
9
+ const packer = new MaxRectanglesPacker(1, 1);
10
+
11
+ const box = new AABB2(3, 5, 4, 6);
12
+
13
+ expect(packer.add(box)).toBe(true);
14
+
15
+ expect(box.x0).toBe(0);
16
+ expect(box.y0).toBe(0);
17
+ });
18
+
19
+ test("packing a box larger than available area", () => {
20
+
21
+ const packer = new MaxRectanglesPacker(1, 1);
22
+
23
+ const box = new AABB2(0, 0, 2, 1);
24
+
25
+ expect(packer.add(box)).toBe(false);
26
+
27
+ box.set(0, 0, 1, 2);
28
+
29
+ expect(packer.add(box)).toBe(false);
30
+
31
+ box.set(0, 0, 2, 2)
32
+
33
+ expect(packer.add(box)).toBe(false);
34
+ });
35
+
36
+ test("pack 4 squares that fit exactly", () => {
37
+
38
+ const packer = new MaxRectanglesPacker(2, 2);
39
+
40
+ const boxes = [
41
+ new AABB2(0, 0, 1, 1),
42
+ new AABB2(0, 0, 1, 1),
43
+ new AABB2(0, 0, 1, 1),
44
+ new AABB2(0, 0, 1, 1)
45
+ ];
46
+
47
+ for (let i = 0; i < boxes.length; i++) {
48
+ expect(packer.add(boxes[i])).toBe(true);
49
+ }
50
+
51
+ // validate overlap constraints
52
+ for (let i = 0; i < boxes.length; i++) {
53
+ const box_0 = boxes[i];
54
+ for (let j = i + 1; j < boxes.length; j++) {
55
+ const box_1 = boxes[j];
56
+
57
+ expect(box_0.overlapExists(box_1)).toBe(false);
58
+ }
59
+ }
60
+ });
@@ -0,0 +1,19 @@
1
+ import { MaxRectanglesPacker } from "./MaxRectanglesPacker.js";
2
+
3
+ /**
4
+ * Packs {@link AABB2} boxes into defined bounds
5
+ *
6
+ * Based on paper "A Thousand Ways to Pack the Bin - A Practical Approach to Two-Dimensional Rectangle Bin Packing" 2010 Jukka Jylänki
7
+ * Method presented called Maximal Rectangles
8
+ *
9
+ * @param {number} width
10
+ * @param {number} height
11
+ * @param {AABB2[]} boxes
12
+ * @returns {boolean} true if packing was successful, false otherwise
13
+ */
14
+ export function packMaxRectangles(width, height, boxes) {
15
+
16
+ const packer = new MaxRectanglesPacker(width, height);
17
+
18
+ return packer.addMany(boxes);
19
+ }
@@ -1,6 +1,6 @@
1
+ import { clamp } from "../../math/clamp.js";
1
2
  import { v3_dot } from "./v3_dot.js";
2
3
  import { v3_length } from "./v3_length.js";
3
- import { clamp } from "../../math/clamp.js";
4
4
 
5
5
  /**
6
6
  *
@@ -12,10 +12,15 @@ import { clamp } from "../../math/clamp.js";
12
12
  * @param {number} z1
13
13
  * @returns {number}
14
14
  */
15
- export function v3_angle_between(x0, y0, z0, x1, y1, z1) {
15
+ export function v3_angle_between(
16
+ x0, y0, z0,
17
+ x1, y1, z1
18
+ ) {
19
+
16
20
  const theta = v3_angle_cos_between(x0, y0, z0, x1, y1, z1);
17
21
 
18
22
  return Math.acos(theta);
23
+
19
24
  }
20
25
 
21
26
  /**
@@ -26,9 +31,13 @@ export function v3_angle_between(x0, y0, z0, x1, y1, z1) {
26
31
  * @param {number} x1
27
32
  * @param {number} y1
28
33
  * @param {number} z1
29
- * @returns {number}
34
+ * @returns {number} value between -1 and 1, cosine of the angle between vectors
30
35
  */
31
- export function v3_angle_cos_between(x0, y0, z0, x1, y1, z1){
36
+ export function v3_angle_cos_between(
37
+ x0, y0, z0,
38
+ x1, y1, z1
39
+ ) {
40
+
32
41
  const d = v3_dot(x0, y0, z0, x1, y1, z1);
33
42
 
34
43
  const magnitude_0 = v3_length(x0, y0, z0);
@@ -38,10 +47,12 @@ export function v3_angle_cos_between(x0, y0, z0, x1, y1, z1){
38
47
 
39
48
  if (l === 0) {
40
49
  // collective magnitude is 0, provide arbitrary angle
50
+ // avoid division by 0
41
51
  return 0;
42
52
  }
43
53
 
44
54
  return clamp(d / l, -1, 1);
55
+
45
56
  }
46
57
 
47
58
  /**
@@ -8,8 +8,9 @@
8
8
  * @param {number} directionX
9
9
  * @param {number} directionY
10
10
  * @param {number} directionZ
11
+ * @returns {boolean} true if displaced successfully, false if direction had 0 magnitude
11
12
  */
12
- export function v3_computeOffsetVector(
13
+ export function v3_displace_in_direction(
13
14
  result,
14
15
  distance,
15
16
  sourceX, sourceY, sourceZ,
@@ -17,13 +18,19 @@ export function v3_computeOffsetVector(
17
18
  ) {
18
19
  if (distance === 0) {
19
20
  result.set(sourceX, sourceY, sourceZ);
20
- return;
21
+ return true;
21
22
  }
22
23
 
23
24
  //scale direction to have length equal to distance
24
25
 
25
26
  const directionLength = Math.sqrt(directionX * directionX + directionY * directionY + directionZ * directionZ);
26
27
 
28
+ if(directionLength === 0){
29
+ // direction vector is zero length, avoid division by zero, clamp to source instead
30
+ result.set(sourceX, sourceY, sourceZ);
31
+ return false;
32
+ }
33
+
27
34
  const m = distance / directionLength;
28
35
 
29
36
  const x = sourceX + directionX * m;
@@ -31,4 +38,6 @@ export function v3_computeOffsetVector(
31
38
  const z = sourceZ + directionZ * m;
32
39
 
33
40
  result.set(x, y, z);
41
+
42
+ return true;
34
43
  }
@@ -12,12 +12,12 @@ const MAX_STEPS = 50;
12
12
  * @param {Uint32Array} result
13
13
  * @param {number} node_count
14
14
  * @param {Uint32Array} edge_addresses
15
- * @param {Uint32Array} adjecency_uint32
15
+ * @param {Uint32Array} adjacency_uint32
16
16
  * @param {Uint32Array} edge_weights_uint32
17
17
  * @param {number} patch_size
18
18
  * @returns {Promise<number>}
19
19
  */
20
- export async function metis_cluster_bs(result, node_count, edge_addresses, adjecency_uint32, edge_weights_uint32, patch_size) {
20
+ export async function metis_cluster_bs(result, node_count, edge_addresses, adjacency_uint32, edge_weights_uint32, patch_size) {
21
21
 
22
22
  const metis = Metis.INSTANCE;
23
23
 
@@ -46,7 +46,7 @@ export async function metis_cluster_bs(result, node_count, edge_addresses, adjec
46
46
  node_count,
47
47
  partition_count,
48
48
  edge_addresses,
49
- adjecency_uint32,
49
+ adjacency_uint32,
50
50
  edge_weights_uint32,
51
51
  metisOptions
52
52
  );
@@ -1,5 +1,5 @@
1
- import WorkerBuilder from "../../process/worker/WorkerBuilder.js";
2
1
  import { OnDemandWorkerManager } from "../../process/worker/OnDemandWorkerManager.js";
2
+ import WorkerBuilder from "../../process/worker/WorkerBuilder.js";
3
3
 
4
4
 
5
5
  export class Metis {
@@ -13,6 +13,16 @@ export class Metis {
13
13
  this.service = manager;
14
14
  }
15
15
 
16
+ /**
17
+ *
18
+ * @param {number} n_vertices
19
+ * @param {number} n_parts
20
+ * @param {Uint32Array} edge_addresses
21
+ * @param {Uint32Array} adjacency
22
+ * @param {Uint32Array} edge_weights
23
+ * @param {metis_options} options
24
+ * @returns {Promise<T>}
25
+ */
16
26
  partition(
17
27
  n_vertices,
18
28
  n_parts,
@@ -32,4 +42,9 @@ export class Metis {
32
42
  }
33
43
  }
34
44
 
45
+ /**
46
+ * Singleton instance
47
+ * @readonly
48
+ * @type {Metis}
49
+ */
35
50
  Metis.INSTANCE = new Metis();
@@ -1,33 +1,36 @@
1
+
2
+ /**
3
+ * See metis.h for more details
4
+ * -1 is the used to signal absence of value, in which case a default will be used
5
+ */
1
6
  export class metis_options {
7
+ ptype = -1;
8
+ objtype = -1;
2
9
  /**
3
- * See metis.h for more details
4
- * -1 is the used to signal absence of value, in which case a default will be used
10
+ * Coarsening scheme
11
+ * 0 - METIS_CTYPE_RM
12
+ * 1 - METIS_CTYPE_SHEM
13
+ * @type {number}
5
14
  */
6
- constructor() {
7
- this.ptype = -1;
8
- this.objtype = -1;
9
- /**
10
- * Coarsening scheme
11
- * 0 - METIS_CTYPE_RM
12
- * 1 - METIS_CTYPE_SHEM
13
- * @type {number}
14
- */
15
- this.ctype = -1;
16
- this.iptype = -1;
17
- this.rtype = -1;
18
- this.dbglvl = -1;
19
- this.niter = -1;
20
- this.ncuts = -1;
21
- this.seed = -1;
22
- this.no2hop = -1;
23
- this.minconn = -1;
24
- this.contig = -1;
25
- this.compress - 1;
26
- this.ccorder = -1;
27
- this.pfactor = -1;
28
- this.nseps = -1;
29
- this.ufactor = -1;
30
- this.numbering = -1;
31
-
32
- }
15
+ ctype = -1;
16
+ iptype = -1;
17
+ rtype = -1;
18
+ dbglvl = -1;
19
+ niter = -1;
20
+ ncuts = -1;
21
+ /**
22
+ * Random seed
23
+ * Integer
24
+ * @type {number}
25
+ */
26
+ seed = -1;
27
+ no2hop = -1;
28
+ minconn = -1;
29
+ contig = -1;
30
+ ccorder = -1;
31
+ pfactor = -1;
32
+ nseps = -1;
33
+ ufactor = -1;
34
+ numbering = -1;
35
+ compress = - 1;
33
36
  }
@@ -12,8 +12,15 @@ import { assert } from "../../assert.js";
12
12
  export function overlap1D(a0, a1, b0, b1) {
13
13
  assert.isNumber(a0, "a0");
14
14
  assert.isNumber(a1, "a1");
15
+
15
16
  assert.isNumber(b0, "b0");
16
17
  assert.isNumber(b1, "b1");
17
18
 
19
+ assert.notNaN(a0, 'a0');
20
+ assert.notNaN(a1, 'a1');
21
+
22
+ assert.notNaN(b0, 'b0');
23
+ assert.notNaN(b1, 'b1');
24
+
18
25
  return a1 > b0 && b1 > a0;
19
26
  }
@@ -73,6 +73,10 @@ export function create_simplex_noise_2d(random = Math.random) {
73
73
  permMod12[i] = (perm[i] % 12) * 2;
74
74
  }
75
75
 
76
+ /**
77
+ * @param {number} x
78
+ * @param {number} y
79
+ */
76
80
  return function noise2D(x, y) {
77
81
  // if(!isFinite(x) || !isFinite(y)) return 0;
78
82
  let n0 = 0; // Noise contributions from the three corners
@@ -30,9 +30,9 @@ const p2 = [];
30
30
  const p3 = [];
31
31
 
32
32
  /**
33
- * Takes distances between points into account and samples at equal intervals along linear distance along the point sequence. Computationally slightly more expensive, but produces very predictable and sable results
34
- * @param {number[]} result
35
- * @param {number[]} input
33
+ * Takes distances between points into account and samples at equal intervals along linear distance along the point sequence. Computationally slightly more expensive, but produces very predictable and stable results
34
+ * @param {number[]|Float32Array} result
35
+ * @param {number[]|Float32Array} input
36
36
  * @param {number} input_length number of points in the input
37
37
  * @param {number} dimensions number of dimensions per vertex
38
38
  * @param {number} sample_count number of discrete points to be generated
@@ -0,0 +1,42 @@
1
+ import Vector3 from "../../geom/Vector3.js";
2
+ import { computeCatmullRomSplineUniformDistance } from "./computeCatmullRomSplineUniformDistance.js";
3
+
4
+ /**
5
+ *
6
+ * @param {Vector3[]} inputs
7
+ * @param {number} samples
8
+ * @returns {Vector3[]}
9
+ */
10
+ export function v3_computeCatmullRomSplineUniformDistance(
11
+ inputs, samples
12
+ ) {
13
+
14
+ const input_count = inputs.length;
15
+
16
+ const inputs_array = new Float32Array(3 * input_count);
17
+ const result_array = new Float32Array(3 * samples);
18
+
19
+ for (let i = 0; i < input_count; i++) {
20
+ const v3 = inputs[i];
21
+
22
+ v3.writeToArray(inputs_array, i * 3);
23
+ }
24
+
25
+ computeCatmullRomSplineUniformDistance(
26
+ result_array, inputs_array, input_count, 3, samples
27
+ );
28
+
29
+ // convert numeric result to array of Vector3 objects
30
+ const result = [];
31
+
32
+ for (let i = 0; i < samples; i++) {
33
+ const v3 = new Vector3();
34
+
35
+ v3.readFromArray(result_array, i * 3);
36
+
37
+ result[i] = v3;
38
+
39
+ }
40
+
41
+ return result;
42
+ }