@woosh/meep-engine 2.90.0 → 2.91.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 (57) hide show
  1. package/build/bundle-worker-terrain.js +1 -1
  2. package/build/meep.cjs +20 -9
  3. package/build/meep.min.js +1 -1
  4. package/build/meep.module.js +20 -9
  5. package/package.json +1 -1
  6. package/src/core/binary/de_interleave_2_bits.spec.d.ts.map +1 -0
  7. package/src/core/binary/de_interleave_bits_by_2.d.ts.map +1 -0
  8. package/src/core/binary/reinterpret_float32_as_int32.d.ts.map +1 -0
  9. package/src/core/binary/split_by_2.d.ts.map +1 -0
  10. package/src/core/binary/split_by_3.d.ts.map +1 -0
  11. package/src/core/bvh2/binary/2/BinaryUint32BVH.d.ts.map +1 -1
  12. package/src/core/bvh2/binary/2/BinaryUint32BVH.js +3 -4
  13. package/src/core/bvh2/bvh3/BVH.js +1 -1
  14. package/src/core/geom/2d/aabb/AABB2.d.ts.map +1 -1
  15. package/src/core/geom/2d/aabb/AABB2.js +2 -4
  16. package/src/core/geom/2d/aabb/aabb2_array_combine.d.ts +11 -0
  17. package/src/core/geom/2d/aabb/aabb2_array_combine.d.ts.map +1 -0
  18. package/src/core/geom/2d/aabb/aabb2_array_combine.js +35 -0
  19. package/src/core/geom/2d/aabb/aabb2_array_set.d.ts +11 -0
  20. package/src/core/geom/2d/aabb/aabb2_array_set.d.ts.map +1 -0
  21. package/src/core/geom/2d/aabb/aabb2_array_set.js +21 -0
  22. package/src/core/geom/2d/aabb/aabb2_compute_area.d.ts +10 -0
  23. package/src/core/geom/2d/aabb/aabb2_compute_area.d.ts.map +1 -0
  24. package/src/core/geom/2d/aabb/aabb2_compute_area.js +14 -0
  25. package/src/core/geom/2d/bvh/BVH2D.d.ts +289 -0
  26. package/src/core/geom/2d/bvh/BVH2D.d.ts.map +1 -0
  27. package/src/core/geom/2d/bvh/BVH2D.js +1143 -0
  28. package/src/core/geom/2d/bvh/BVH2D.spec.d.ts +2 -0
  29. package/src/core/geom/2d/bvh/BVH2D.spec.d.ts.map +1 -0
  30. package/src/core/geom/2d/bvh/BVH2D.spec.js +358 -0
  31. package/src/core/geom/2d/lt-grid/LooseTightGrid.js +2 -2
  32. package/src/core/geom/2d/quad-tree/QuadTreeNode.spec.js +1 -1
  33. package/src/core/geom/2d/r-tree/StaticR2Tree.d.ts +79 -0
  34. package/src/core/geom/2d/r-tree/StaticR2Tree.d.ts.map +1 -0
  35. package/src/core/geom/2d/r-tree/StaticR2Tree.js +384 -0
  36. package/src/core/geom/2d/r-tree/StaticR2Tree.spec.d.ts +2 -0
  37. package/src/core/geom/2d/r-tree/StaticR2Tree.spec.d.ts.map +1 -0
  38. package/src/core/geom/2d/r-tree/StaticR2Tree.spec.js +62 -0
  39. package/src/core/geom/3d/morton/mortonEncode_magicbits.js +1 -1
  40. package/src/core/geom/3d/topology/struct/binary/io/OrderedEdge.js +1 -1
  41. package/src/engine/graphics/texture/virtual/tile/compose_tile_address.js +1 -1
  42. package/src/engine/graphics/texture/virtual/tile/tile_address_to_finger_print.js +1 -1
  43. package/src/core/geom/3d/morton/de_interleave_2_bits.spec.d.ts.map +0 -1
  44. package/src/core/geom/3d/morton/de_interleave_bits_by_2.d.ts.map +0 -1
  45. package/src/core/geom/3d/morton/reinterpret_float32_as_int32.d.ts.map +0 -1
  46. package/src/core/geom/3d/morton/split_by_2.d.ts.map +0 -1
  47. package/src/core/geom/3d/morton/split_by_3.d.ts.map +0 -1
  48. /package/src/core/{geom/3d/morton → binary}/de_interleave_2_bits.spec.d.ts +0 -0
  49. /package/src/core/{geom/3d/morton → binary}/de_interleave_2_bits.spec.js +0 -0
  50. /package/src/core/{geom/3d/morton → binary}/de_interleave_bits_by_2.d.ts +0 -0
  51. /package/src/core/{geom/3d/morton → binary}/de_interleave_bits_by_2.js +0 -0
  52. /package/src/core/{geom/3d/morton → binary}/reinterpret_float32_as_int32.d.ts +0 -0
  53. /package/src/core/{geom/3d/morton → binary}/reinterpret_float32_as_int32.js +0 -0
  54. /package/src/core/{geom/3d/morton → binary}/split_by_2.d.ts +0 -0
  55. /package/src/core/{geom/3d/morton → binary}/split_by_2.js +0 -0
  56. /package/src/core/{geom/3d/morton → binary}/split_by_3.d.ts +0 -0
  57. /package/src/core/{geom/3d/morton → binary}/split_by_3.js +0 -0
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=BVH2D.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BVH2D.spec.d.ts","sourceRoot":"","sources":["../../../../../../src/core/geom/2d/bvh/BVH2D.spec.js"],"names":[],"mappings":""}
@@ -0,0 +1,358 @@
1
+ import { randomFloatBetween } from "../../../math/random/randomFloatBetween.js";
2
+ import { seededRandom } from "../../../math/random/seededRandom.js";
3
+ import { BVH2D, NULL_NODE } from "./BVH2D.js";
4
+
5
+ test("constructor doesn't throw", () => {
6
+ expect(() => new BVH2D()).not.toThrow();
7
+ });
8
+
9
+ test("initial root is NULL", () => {
10
+ const bvh = new BVH2D();
11
+
12
+ expect(bvh.root).toBe(NULL_NODE);
13
+ });
14
+
15
+ test("allocate a node", () => {
16
+ const bvh = new BVH2D();
17
+
18
+ const id = bvh.allocate_node();
19
+
20
+ expect(typeof id).toBe("number");
21
+ expect(Number.isInteger(id)).toBe(true);
22
+ expect(id).toBeGreaterThanOrEqual(0);
23
+ });
24
+
25
+ test("set/get aabb", () => {
26
+ const bvh = new BVH2D();
27
+
28
+ const node = bvh.allocate_node();
29
+
30
+ bvh.node_set_aabb(node, [1, -2, -5, 7]);
31
+
32
+ const result = [];
33
+
34
+ bvh.node_get_aabb(node, result);
35
+
36
+ expect(result).toEqual([
37
+ 1, -2, -5, 7
38
+ ]);
39
+ });
40
+
41
+ test("insert one leaf", () => {
42
+ const bvh = new BVH2D();
43
+
44
+ const node = bvh.allocate_node();
45
+
46
+ bvh.insert_leaf(node);
47
+
48
+ expect(bvh.root).toBe(node);
49
+ });
50
+
51
+ test("node reuse after de-allocation", () => {
52
+
53
+ const bvh = new BVH2D();
54
+
55
+ const a = bvh.allocate_node();
56
+
57
+ bvh.release_node(a);
58
+
59
+ const b = bvh.allocate_node();
60
+
61
+ expect(b).toEqual(a);
62
+ });
63
+
64
+ test("insert two leaves", () => {
65
+
66
+ const bvh = new BVH2D();
67
+
68
+ const a = bvh.allocate_node();
69
+ bvh.insert_leaf(a);
70
+
71
+ const b = bvh.allocate_node();
72
+ bvh.insert_leaf(b);
73
+
74
+ const nodes = [];
75
+ bvh.collect_nodes_all(nodes, 0);
76
+
77
+ expect(nodes).toContain(a);
78
+ expect(nodes).toContain(b);
79
+ });
80
+
81
+
82
+ test("set/get user data", () => {
83
+
84
+ const bvh = new BVH2D();
85
+
86
+ const a = bvh.allocate_node();
87
+
88
+ bvh.node_set_user_data(a, 42);
89
+
90
+ expect(bvh.node_get_user_data(a)).toBe(42);
91
+ });
92
+
93
+ test("remove single leaf", () => {
94
+ const bvh = new BVH2D();
95
+
96
+ const a = bvh.allocate_node();
97
+ bvh.insert_leaf(a);
98
+
99
+ bvh.remove_leaf(a);
100
+
101
+ const nodes = [];
102
+ bvh.collect_nodes_all(nodes, 0);
103
+
104
+ expect(nodes).not.toContain(a);
105
+ });
106
+
107
+ test("add and remove 5 nodes", () => {
108
+
109
+ const bvh = new BVH2D();
110
+
111
+ const leaves = [];
112
+ const removed_leaves = [];
113
+
114
+ for (let i = 0; i < 5; i++) {
115
+ const a = bvh.allocate_node();
116
+ bvh.node_set_user_data(a, a);
117
+ bvh.insert_leaf(a);
118
+
119
+ leaves.push(a);
120
+ }
121
+
122
+ while (leaves.length > 0) {
123
+ const nodes = [];
124
+ bvh.collect_nodes_all(nodes, 0);
125
+
126
+ for (let j = 0; j < leaves.length; j++) {
127
+ const leaf = leaves[j];
128
+ expect(nodes).toContain(leaf);
129
+ }
130
+
131
+ const leaf = leaves.shift();
132
+
133
+ expect(bvh.node_get_user_data(leaf)).toBe(leaf);
134
+
135
+ bvh.remove_leaf(leaf);
136
+
137
+ removed_leaves.push(leaf);
138
+
139
+ }
140
+
141
+ const nodes = [];
142
+ bvh.collect_nodes_all(nodes, 0);
143
+ for (let i = 0; i < removed_leaves.length; i++) {
144
+ expect(nodes).not.toContain(removed_leaves[i]);
145
+ }
146
+
147
+ });
148
+
149
+
150
+ test("release_all from empty doesn't throw", () => {
151
+ const bvh = new BVH2D();
152
+
153
+ expect(() => bvh.release_all()).not.toThrow();
154
+ });
155
+
156
+ test("release_all with 1 leaf", () => {
157
+ const bvh = new BVH2D();
158
+
159
+ const a = bvh.allocate_node();
160
+
161
+ bvh.insert_leaf(a);
162
+
163
+ bvh.release_all();
164
+
165
+ expect(bvh.root).toBe(NULL_NODE);
166
+ });
167
+
168
+ test("capacity grows as necessary when allocating", () => {
169
+ const bvh = new BVH2D();
170
+
171
+ bvh.node_capacity = 1;
172
+
173
+ bvh.allocate_node();
174
+
175
+ bvh.allocate_node();
176
+
177
+ expect(bvh.node_capacity).toBeGreaterThanOrEqual(2);
178
+ });
179
+
180
+ test("trim sets capacity to exact allocated size", () => {
181
+ const bvh = new BVH2D();
182
+
183
+ bvh.node_capacity = 1;
184
+
185
+ bvh.allocate_node();
186
+
187
+ bvh.allocate_node();
188
+
189
+ bvh.trim();
190
+
191
+ expect(bvh.node_capacity).toBe(2);
192
+ });
193
+
194
+
195
+ test("node property setters/getters", () => {
196
+
197
+ const bvh = new BVH2D();
198
+
199
+ const node = bvh.allocate_node();
200
+
201
+ bvh.node_set_user_data(node, 3);
202
+
203
+ expect(bvh.node_get_user_data(node)).toBe(3);
204
+
205
+ bvh.node_set_child1(node, 7);
206
+ bvh.node_set_child2(node, 11);
207
+ bvh.node_set_parent(node, 13);
208
+ bvh.node_set_height(node, 17);
209
+
210
+ const expected_aabb = new Float32Array([1.1, 3.2, 11.4, 13.5]);
211
+ bvh.node_set_aabb(node, expected_aabb);
212
+
213
+ expect(bvh.node_get_child1(node)).toBe(7);
214
+ expect(bvh.node_get_child2(node)).toBe(11);
215
+ expect(bvh.node_get_parent(node)).toBe(13);
216
+ expect(bvh.node_get_height(node)).toBe(17);
217
+
218
+ const actual_aabb = [];
219
+ bvh.node_get_aabb(node, actual_aabb)
220
+
221
+ expect(actual_aabb).toEqual(Array.from(expected_aabb));
222
+ });
223
+
224
+
225
+ test("node_set_aabb_primitive", () => {
226
+ const bvh = new BVH2D();
227
+
228
+ const node = bvh.allocate_node();
229
+
230
+ bvh.node_set_aabb_primitive(node, -1, -3, 7, 11);
231
+
232
+ const aabb = [];
233
+
234
+ bvh.node_get_aabb(node, aabb);
235
+
236
+ expect(aabb).toEqual([-1, -3, 7, 11]);
237
+ });
238
+
239
+ test("swap two detached nodes", () => {
240
+ const bvh = new BVH2D();
241
+
242
+ const a = bvh.allocate_node();
243
+ const b = bvh.allocate_node();
244
+
245
+ bvh.node_set_user_data(a, 7);
246
+ bvh.node_set_user_data(b, 11);
247
+
248
+ bvh.swap_nodes(a, b);
249
+
250
+ expect(bvh.node_get_user_data(a)).toBe(11);
251
+ expect(bvh.node_get_user_data(b)).toBe(7);
252
+ });
253
+
254
+ test("setting capacity", () => {
255
+ const bvh = new BVH2D();
256
+
257
+ bvh.node_capacity = 3;
258
+
259
+ expect(bvh.node_capacity).toEqual(3);
260
+
261
+ bvh.node_capacity = 3;
262
+
263
+ expect(bvh.node_capacity).toEqual(3);
264
+
265
+ bvh.node_capacity = 0;
266
+
267
+ expect(bvh.node_capacity).toEqual(0);
268
+
269
+ bvh.allocate_node();
270
+
271
+ bvh.node_capacity = 3;
272
+
273
+ expect(bvh.node_capacity).toEqual(3);
274
+
275
+ bvh.node_capacity = 1;
276
+
277
+ expect(bvh.node_capacity).toEqual(1);
278
+
279
+ expect(() => bvh.node_capacity = 0).toThrow();
280
+ });
281
+
282
+ test("move leaf node", () => {
283
+ const bvh = new BVH2D();
284
+
285
+ const a = bvh.allocate_node();
286
+ const b = bvh.allocate_node();
287
+
288
+ bvh.node_set_aabb(a, [-1.1, -1.2, 2.1, 2.2]);
289
+ bvh.node_set_aabb(b, [3.1, 3.2, 5.1, 5.2]);
290
+
291
+ bvh.insert_leaf(a);
292
+ bvh.insert_leaf(b);
293
+
294
+ // convert to float32 and back to account for rounding errors when checking results
295
+ const a_new_bounds = Array.from(new Float32Array([
296
+ 7.1, 7.2,
297
+ 11.1, 11.2
298
+ ]));
299
+
300
+ bvh.node_move_aabb(a, a_new_bounds);
301
+
302
+ const actual_bounds = [];
303
+ bvh.node_get_aabb(a, actual_bounds);
304
+
305
+ expect(actual_bounds).toEqual(a_new_bounds);
306
+ });
307
+
308
+ test.skip("performance, insert 100k random nodes", () => {
309
+
310
+ const random = seededRandom(1);
311
+
312
+ const bvh = new BVH2D();
313
+
314
+ const min_bound = -1000;
315
+ const max_bound = 1000;
316
+
317
+ const OBJECT_COUNT = 100000;
318
+
319
+ const leaves = new Uint32Array(OBJECT_COUNT);
320
+ for (let i = 0; i < OBJECT_COUNT; i++) {
321
+ const node = bvh.allocate_node();
322
+
323
+ bvh.node_set_user_data(node, i);
324
+
325
+ const x = randomFloatBetween(random, min_bound, max_bound);
326
+ const y = randomFloatBetween(random, min_bound, max_bound);
327
+
328
+ const extents = randomFloatBetween(random, 1, 10);
329
+
330
+ const x0 = x - extents;
331
+ const y0 = y - extents;
332
+
333
+ const x1 = x + extents;
334
+ const y1 = y + extents;
335
+
336
+ // console.log([x0, y0, z0, x1, y1, z1].join(', '))
337
+
338
+ bvh.node_set_aabb_primitive(
339
+ node,
340
+ x0, y0,
341
+ x1, y1,
342
+ );
343
+ }
344
+
345
+ const t0 = performance.now();
346
+ for (let i = 0; i < OBJECT_COUNT; i++) {
347
+ const node = leaves[i];
348
+
349
+ bvh.insert_leaf(node);
350
+ }
351
+
352
+ const duration = performance.now() - t0;
353
+
354
+ const duration_seconds = duration * 1e-3;
355
+
356
+ console.log(`Duration ${duration_seconds}s, ${(OBJECT_COUNT / duration_seconds).toFixed(2)} records per second`);
357
+
358
+ });
@@ -1,8 +1,8 @@
1
1
  import { assert } from "../../../assert.js";
2
+ import { de_interleave_2_bits } from "../../../binary/de_interleave_bits_by_2.js";
3
+ import { split_by_2 } from "../../../binary/split_by_2.js";
2
4
  import { UINT32_MAX } from "../../../binary/UINT32_MAX.js";
3
5
  import { SCRATCH_UINT32_TRAVERSAL_STACK } from "../../../collection/SCRATCH_UINT32_TRAVERSAL_STACK.js";
4
- import { de_interleave_2_bits } from "../../3d/morton/de_interleave_bits_by_2.js";
5
- import { split_by_2 } from "../../3d/morton/split_by_2.js";
6
6
  import { BinaryElementPool } from "../../3d/topology/struct/binary/BinaryElementPool.js";
7
7
 
8
8
  const NULL_POINTER = UINT32_MAX;
@@ -183,7 +183,7 @@ test('test traverseRectangleIntersections', () => {
183
183
  expect(visitor0).toHaveBeenCalledWith(e, 0, 0, 3, 3);
184
184
  });
185
185
 
186
- test.skip("performance, insertion 1m random", () => {
186
+ test("performance, insertion 1m random", () => {
187
187
  const tree = new QuadTreeNode(0, 0, 100, 100);
188
188
 
189
189
  const random = seededRandom(42);
@@ -0,0 +1,79 @@
1
+ /**
2
+ * NOTE: code is based on BinaryUint32BVH
3
+ * NOTE: this code is mostly untested
4
+ */
5
+ export class StaticR2Tree {
6
+ /**
7
+ * @type {ArrayBuffer}
8
+ * @private
9
+ */
10
+ private __data_buffer;
11
+ /**
12
+ * @readonly
13
+ * @private
14
+ * @type {Uint32Array}
15
+ */
16
+ private readonly __data_uint32;
17
+ /**
18
+ *
19
+ * @type {number}
20
+ * @private
21
+ */
22
+ private __node_count_binary;
23
+ /**
24
+ *
25
+ * @type {number}
26
+ * @private
27
+ */
28
+ private __node_count_leaf;
29
+ /**
30
+ *
31
+ * @param {ArrayBuffer} buffer
32
+ */
33
+ setBuffer(buffer: ArrayBuffer): void;
34
+ __data_float32: Float32Array;
35
+ initialize_structure(): void;
36
+ /**
37
+ *
38
+ * @param {number} count
39
+ */
40
+ setLeafCount(count: number): void;
41
+ /**
42
+ *
43
+ * @param {number} index
44
+ * @param {number} payload
45
+ * @param {number} x0
46
+ * @param {number} y0
47
+ * @param {number} x1
48
+ * @param {number} y1
49
+ */
50
+ setLeafData(index: number, payload: number, x0: number, y0: number, x1: number, y1: number): void;
51
+ /**
52
+ *
53
+ * @returns {number}
54
+ */
55
+ getLeafBlockAddress(): number;
56
+ /**
57
+ *
58
+ * @param {number} leaf_index
59
+ * @returns {number}
60
+ */
61
+ readLeafPayload(leaf_index: number): number;
62
+ /**
63
+ * Sort leaf nodes according to their morton codes
64
+ * @param {number[]} bounds
65
+ */
66
+ sort_morton(bounds: number[]): void;
67
+ /**
68
+ *
69
+ * @param {number} i
70
+ * @param {number} j
71
+ * @private
72
+ */
73
+ private __swap_leaves;
74
+ /**
75
+ * Assemble leaf nodes into hierarchy, set binary node bounds iteratively bottom up
76
+ */
77
+ build(): void;
78
+ }
79
+ //# sourceMappingURL=StaticR2Tree.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StaticR2Tree.d.ts","sourceRoot":"","sources":["../../../../../../src/core/geom/2d/r-tree/StaticR2Tree.js"],"names":[],"mappings":"AAoEA;;;GAGG;AACH;IAEI;;;OAGG;IACH,sBAAc;IAEd;;;;OAIG;IACH,+BAAc;IAEd;;;;OAIG;IACH,4BAAwB;IAExB;;;;OAIG;IACH,0BAAsB;IAOtB;;;OAGG;IACH,kBAFW,WAAW,QASrB;IAFG,6BAA0D;IAK9D,6BASC;IAED;;;OAGG;IACH,oBAFW,MAAM,QAchB;IAGD;;;;;;;;OAQG;IACH,mBAPW,MAAM,WACN,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,QAwBhB;IAED;;;OAGG;IACH,uBAFa,MAAM,CAIlB;IAED;;;;OAIG;IACH,4BAHW,MAAM,GACJ,MAAM,CAQlB;IAGD;;;OAGG;IACH,oBAFW,MAAM,EAAE,QAgFlB;IAED;;;;;OAKG;IACH,sBAYC;IAED;;OAEG;IACH,cAsEC;CACJ"}