@woosh/meep-engine 2.66.0 → 2.67.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.
package/build/meep.cjs CHANGED
@@ -37522,8 +37522,8 @@ function middleInside( a, b ) {
37522
37522
  // if one belongs to the outer ring and another to a hole, it merges it into a single ring
37523
37523
  function splitPolygon( a, b ) {
37524
37524
 
37525
- const a2 = new Node$1( a.i, a.x, a.y ),
37526
- b2 = new Node$1( b.i, b.x, b.y ),
37525
+ const a2 = new Node( a.i, a.x, a.y ),
37526
+ b2 = new Node( b.i, b.x, b.y ),
37527
37527
  an = a.next,
37528
37528
  bp = b.prev;
37529
37529
 
@@ -37546,7 +37546,7 @@ function splitPolygon( a, b ) {
37546
37546
  // create a node and optionally link it with previous one (in a circular doubly linked list)
37547
37547
  function insertNode( i, x, y, last ) {
37548
37548
 
37549
- const p = new Node$1( i, x, y );
37549
+ const p = new Node( i, x, y );
37550
37550
 
37551
37551
  if ( ! last ) {
37552
37552
 
@@ -37576,7 +37576,7 @@ function removeNode( p ) {
37576
37576
 
37577
37577
  }
37578
37578
 
37579
- function Node$1( i, x, y ) {
37579
+ function Node( i, x, y ) {
37580
37580
 
37581
37581
  // vertex index in coordinates array
37582
37582
  this.i = i;
@@ -54878,7 +54878,7 @@ function aabb3_intersects_ray(
54878
54878
  return f2 <= extents_x * abs_direction_y + extents_y * abs_direction_x;
54879
54879
  }
54880
54880
 
54881
- const stack$b = SCRATCH_UINT32_TRAVERSAL_STACK;
54881
+ const stack$9 = SCRATCH_UINT32_TRAVERSAL_STACK;
54882
54882
 
54883
54883
 
54884
54884
  /**
@@ -54911,9 +54911,9 @@ function bvh_query_leaves_ray(
54911
54911
  *
54912
54912
  * @type {number}
54913
54913
  */
54914
- const stack_top = stack$b.pointer++;
54914
+ const stack_top = stack$9.pointer++;
54915
54915
 
54916
- stack$b[stack_top] = root;
54916
+ stack$9[stack_top] = root;
54917
54917
 
54918
54918
  let result_cursor = result_offset;
54919
54919
 
@@ -54924,13 +54924,13 @@ function bvh_query_leaves_ray(
54924
54924
  const uint32 = bvh.__data_uint32;
54925
54925
 
54926
54926
  do {
54927
- stack$b.pointer--;
54927
+ stack$9.pointer--;
54928
54928
 
54929
54929
  /**
54930
54930
  *
54931
54931
  * @type {number}
54932
54932
  */
54933
- const node = stack$b[stack$b.pointer];
54933
+ const node = stack$9[stack$9.pointer];
54934
54934
 
54935
54935
  const address = node * ELEMENT_WORD_COUNT;
54936
54936
 
@@ -54952,15 +54952,15 @@ function bvh_query_leaves_ray(
54952
54952
  if (child_1 !== NULL_NODE) {
54953
54953
 
54954
54954
  // this is not a leaf node, push children onto traversal stack
54955
- stack$b[stack$b.pointer++] = child_1;
54956
- stack$b[stack$b.pointer++] = uint32[address + COLUMN_CHILD_2];
54955
+ stack$9[stack$9.pointer++] = child_1;
54956
+ stack$9[stack$9.pointer++] = uint32[address + COLUMN_CHILD_2];
54957
54957
 
54958
54958
  } else {
54959
54959
  // leaf node
54960
54960
 
54961
54961
  result[result_cursor++] = node;
54962
54962
  }
54963
- } while (stack$b.pointer > stack_top);
54963
+ } while (stack$9.pointer > stack_top);
54964
54964
 
54965
54965
  return result_cursor - result_offset;
54966
54966
  }
@@ -56870,7 +56870,7 @@ function build_morton(data, address, matrix) {
56870
56870
  }
56871
56871
 
56872
56872
  const scratch_box_0 = new Float32Array(18);
56873
- const stack$a = [];
56873
+ const stack$8 = [];
56874
56874
 
56875
56875
  class BinaryUint32BVH {
56876
56876
  /**
@@ -57150,16 +57150,16 @@ class BinaryUint32BVH {
57150
57150
  let stackPointer = 2;
57151
57151
  let i, j;
57152
57152
 
57153
- stack$a[0] = 0; // first node
57154
- stack$a[1] = this.__node_count_leaf - 1; // last node
57153
+ stack$8[0] = 0; // first node
57154
+ stack$8[1] = this.__node_count_leaf - 1; // last node
57155
57155
 
57156
57156
  const data = this.__data_float32;
57157
57157
 
57158
57158
  while (stackPointer > 0) {
57159
57159
  stackPointer -= 2;
57160
57160
 
57161
- const right = stack$a[stackPointer + 1];
57162
- const left = stack$a[stackPointer];
57161
+ const right = stack$8[stackPointer + 1];
57162
+ const left = stack$8[stackPointer];
57163
57163
 
57164
57164
  i = left;
57165
57165
  j = right;
@@ -57194,12 +57194,12 @@ class BinaryUint32BVH {
57194
57194
 
57195
57195
  /* recursion */
57196
57196
  if (left < j) {
57197
- stack$a[stackPointer++] = left;
57198
- stack$a[stackPointer++] = j;
57197
+ stack$8[stackPointer++] = left;
57198
+ stack$8[stackPointer++] = j;
57199
57199
  }
57200
57200
  if (i < right) {
57201
- stack$a[stackPointer++] = i;
57202
- stack$a[stackPointer++] = right;
57201
+ stack$8[stackPointer++] = i;
57202
+ stack$8[stackPointer++] = right;
57203
57203
  }
57204
57204
  }
57205
57205
  }
@@ -57325,7 +57325,7 @@ function aabb3_array_intersects_ray(
57325
57325
  );
57326
57326
  }
57327
57327
 
57328
- const stack$9 = SCRATCH_UINT32_TRAVERSAL_STACK;
57328
+ const stack$7 = SCRATCH_UINT32_TRAVERSAL_STACK;
57329
57329
 
57330
57330
  /**
57331
57331
  *
@@ -57359,13 +57359,13 @@ function bvh32_query_user_data_ray(
57359
57359
  *
57360
57360
  * @type {number}
57361
57361
  */
57362
- const stack_top = stack$9.pointer++;
57362
+ const stack_top = stack$7.pointer++;
57363
57363
 
57364
57364
  /**
57365
57365
  * After performing empirical tests, stack-based depth-first traversal turns out faster than using a queue
57366
57366
  * @type {number}
57367
57367
  */
57368
- stack$9[stack_top] = 0;
57368
+ stack$7[stack_top] = 0;
57369
57369
 
57370
57370
  const last_valid_index = binary_node_count + bvh.getLeafNodeCount();
57371
57371
 
@@ -57373,10 +57373,10 @@ function bvh32_query_user_data_ray(
57373
57373
  const uint32 = bvh.uint32;
57374
57374
 
57375
57375
  do {
57376
- stack$9.pointer--;
57376
+ stack$7.pointer--;
57377
57377
 
57378
57378
  // query_bvh_frustum_from_objects.iteration_count++;
57379
- const node_index = stack$9[stack$9.pointer];
57379
+ const node_index = stack$7[stack$7.pointer];
57380
57380
 
57381
57381
  if (node_index < binary_node_count) {
57382
57382
  // is intermediate node
@@ -57395,11 +57395,11 @@ function bvh32_query_user_data_ray(
57395
57395
 
57396
57396
  // left node ends up on top of the stack, which aligns with the desired access sequence
57397
57397
  if (right_index < last_valid_index) {
57398
- stack$9[stack$9.pointer++] = right_index;
57398
+ stack$7[stack$7.pointer++] = right_index;
57399
57399
  // micro-optimization, since we know that right node is valid and left appears before that, left is valid too
57400
- stack$9[stack$9.pointer++] = left_index;
57400
+ stack$7[stack$7.pointer++] = left_index;
57401
57401
  } else if (left_index < last_valid_index) {
57402
- stack$9[stack$9.pointer++] = left_index;
57402
+ stack$7[stack$7.pointer++] = left_index;
57403
57403
  }
57404
57404
 
57405
57405
 
@@ -57415,7 +57415,7 @@ function bvh32_query_user_data_ray(
57415
57415
  hit_count++;
57416
57416
  }
57417
57417
 
57418
- } while (stack$9.pointer > stack_top)
57418
+ } while (stack$7.pointer > stack_top)
57419
57419
 
57420
57420
  return hit_count;
57421
57421
  }
@@ -67447,16 +67447,16 @@ class IndexedBinaryBVH {
67447
67447
  */
67448
67448
  traversePreOrderStack(visitor, startIndex) {
67449
67449
 
67450
- const stackOffset = stackPointer$2;
67450
+ const stackOffset = stackPointer;
67451
67451
 
67452
- stack$8[stackPointer$2++] = startIndex;
67452
+ stack$6[stackPointer++] = startIndex;
67453
67453
 
67454
67454
  const nodeThreshold = this.binaryNodeCount * 6;
67455
67455
  const endAddress = this.boxCount * 6;
67456
67456
 
67457
- while (stackPointer$2-- > stackOffset) {
67457
+ while (stackPointer-- > stackOffset) {
67458
67458
 
67459
- const index = stack$8[stackPointer$2];
67459
+ const index = stack$6[stackPointer];
67460
67460
 
67461
67461
  const address = index * 6;
67462
67462
 
@@ -67472,7 +67472,7 @@ class IndexedBinaryBVH {
67472
67472
  //right
67473
67473
  if (rightAddress < endAddress) {
67474
67474
  if (rightAddress < nodeThreshold) {
67475
- stack$8[stackPointer$2++] = rightIndex;
67475
+ stack$6[stackPointer++] = rightIndex;
67476
67476
  } else {
67477
67477
  visitor.visit(rightAddress, NodeType.LEAF);
67478
67478
  }
@@ -67481,7 +67481,7 @@ class IndexedBinaryBVH {
67481
67481
  //left
67482
67482
  if (leftAddress < endAddress) {
67483
67483
  if (leftAddress < nodeThreshold) {
67484
- stack$8[stackPointer$2++] = leftIndex;
67484
+ stack$6[stackPointer++] = leftIndex;
67485
67485
  } else {
67486
67486
  visitor.visit(leftAddress, NodeType.LEAF);
67487
67487
  }
@@ -67490,7 +67490,7 @@ class IndexedBinaryBVH {
67490
67490
  }
67491
67491
 
67492
67492
  //drop stack
67493
- stackPointer$2 = stackOffset;
67493
+ stackPointer = stackOffset;
67494
67494
  }
67495
67495
 
67496
67496
  /**
@@ -67657,8 +67657,8 @@ function binaryNodeRefit(array, binaryNode, childNode0, childNode1) {
67657
67657
  }
67658
67658
 
67659
67659
 
67660
- const stack$8 = [];
67661
- let stackPointer$2 = 0;
67660
+ const stack$6 = [];
67661
+ let stackPointer = 0;
67662
67662
 
67663
67663
  const rayLeafIntersectionVisitor = new RayLeafIntersectionVisitor();
67664
67664
 
@@ -69208,7 +69208,7 @@ function aabb3_array_intersects_frustum_degree(aabb, frustum) {
69208
69208
 
69209
69209
  //
69210
69210
 
69211
- const stack$7 = SCRATCH_UINT32_TRAVERSAL_STACK;
69211
+ const stack$5 = SCRATCH_UINT32_TRAVERSAL_STACK;
69212
69212
 
69213
69213
  /**
69214
69214
  *
@@ -69231,20 +69231,20 @@ function bvh_collect_user_data(
69231
69231
  *
69232
69232
  * @type {number}
69233
69233
  */
69234
- const stack_top = stack$7.pointer++;
69234
+ const stack_top = stack$5.pointer++;
69235
69235
 
69236
- stack$7[stack_top] = root;
69236
+ stack$5[stack_top] = root;
69237
69237
 
69238
69238
  let result_cursor = destination_offset;
69239
69239
 
69240
- while (stack$7.pointer > stack_top) {
69241
- stack$7.pointer--;
69240
+ while (stack$5.pointer > stack_top) {
69241
+ stack$5.pointer--;
69242
69242
 
69243
69243
  /**
69244
69244
  *
69245
69245
  * @type {number}
69246
69246
  */
69247
- const node = stack$7[stack$7.pointer];
69247
+ const node = stack$5[stack$5.pointer];
69248
69248
 
69249
69249
  const node_is_leaf = bvh.node_is_leaf(node);
69250
69250
 
@@ -69255,8 +69255,8 @@ function bvh_collect_user_data(
69255
69255
  const child2 = bvh.node_get_child2(node);
69256
69256
 
69257
69257
  // write to stack in reverse order, so that fist child ends up being visited first
69258
- stack$7[stack$7.pointer++] = child1;
69259
- stack$7[stack$7.pointer++] = child2;
69258
+ stack$5[stack$5.pointer++] = child1;
69259
+ stack$5[stack$5.pointer++] = child2;
69260
69260
 
69261
69261
  } else {
69262
69262
  // leaf root
@@ -69272,7 +69272,7 @@ function bvh_collect_user_data(
69272
69272
 
69273
69273
  //
69274
69274
 
69275
- const stack$6 = SCRATCH_UINT32_TRAVERSAL_STACK;
69275
+ const stack$4 = SCRATCH_UINT32_TRAVERSAL_STACK;
69276
69276
 
69277
69277
  const scratch_aabb$1 = new Float32Array(6);
69278
69278
 
@@ -69299,20 +69299,20 @@ function bvh_query_user_data_overlaps_frustum(
69299
69299
  *
69300
69300
  * @type {number}
69301
69301
  */
69302
- const stack_top = stack$6.pointer++;
69302
+ const stack_top = stack$4.pointer++;
69303
69303
 
69304
- stack$6[stack_top] = root;
69304
+ stack$4[stack_top] = root;
69305
69305
 
69306
69306
  let result_cursor = result_offset;
69307
69307
 
69308
- while (stack$6.pointer > stack_top) {
69309
- stack$6.pointer--;
69308
+ while (stack$4.pointer > stack_top) {
69309
+ stack$4.pointer--;
69310
69310
 
69311
69311
  /**
69312
69312
  *
69313
69313
  * @type {number}
69314
69314
  */
69315
- const node = stack$6[stack$6.pointer];
69315
+ const node = stack$4[stack$4.pointer];
69316
69316
 
69317
69317
  // test node against the ray
69318
69318
  bvh.node_get_aabb(node, scratch_aabb$1);
@@ -69339,8 +69339,8 @@ function bvh_query_user_data_overlaps_frustum(
69339
69339
  const child2 = bvh.node_get_child2(node);
69340
69340
 
69341
69341
  // write to stack in reverse order, so that fist child ends up being visited first
69342
- stack$6[stack$6.pointer++] = child1;
69343
- stack$6[stack$6.pointer++] = child2;
69342
+ stack$4[stack$4.pointer++] = child1;
69343
+ stack$4[stack$4.pointer++] = child2;
69344
69344
  }
69345
69345
  }
69346
69346
 
@@ -76229,7 +76229,7 @@ class SGMeshSystem extends System {
76229
76229
  }
76230
76230
  }
76231
76231
 
76232
- const stack$5 = SCRATCH_UINT32_TRAVERSAL_STACK;
76232
+ const stack$3 = SCRATCH_UINT32_TRAVERSAL_STACK;
76233
76233
 
76234
76234
  /**
76235
76235
  *
@@ -76253,20 +76253,20 @@ function bvh_query_leaves_generic(
76253
76253
  *
76254
76254
  * @type {number}
76255
76255
  */
76256
- const stack_top = stack$5.pointer++;
76256
+ const stack_top = stack$3.pointer++;
76257
76257
 
76258
- stack$5[stack_top] = root;
76258
+ stack$3[stack_top] = root;
76259
76259
 
76260
76260
  let result_cursor = result_offset;
76261
76261
 
76262
- while (stack$5.pointer > stack_top) {
76263
- stack$5.pointer--;
76262
+ while (stack$3.pointer > stack_top) {
76263
+ stack$3.pointer--;
76264
76264
 
76265
76265
  /**
76266
76266
  *
76267
76267
  * @type {number}
76268
76268
  */
76269
- const node = stack$5[stack$5.pointer];
76269
+ const node = stack$3[stack$3.pointer];
76270
76270
 
76271
76271
  // test node against the ray
76272
76272
  const pass = query.evaluate(node, bvh);
@@ -76284,8 +76284,8 @@ function bvh_query_leaves_generic(
76284
76284
  const child2 = bvh.node_get_child2(node);
76285
76285
 
76286
76286
  // write to stack in reverse order, so that fist child ends up being visited first
76287
- stack$5[stack$5.pointer++] = child2;
76288
- stack$5[stack$5.pointer++] = child1;
76287
+ stack$3[stack$3.pointer++] = child2;
76288
+ stack$3[stack$3.pointer++] = child1;
76289
76289
 
76290
76290
  } else {
76291
76291
  // leaf node
@@ -76683,7 +76683,7 @@ class RuntimeDrawMethodOptimizer {
76683
76683
  }
76684
76684
  }
76685
76685
 
76686
- const stack$4 = [];
76686
+ const stack$2 = [];
76687
76687
 
76688
76688
  /**
76689
76689
  * @template T
@@ -76709,14 +76709,14 @@ function arrayQuickSort(
76709
76709
  let stackPointer = 2;
76710
76710
  let i, j;
76711
76711
 
76712
- stack$4[0] = start;
76713
- stack$4[1] = end;
76712
+ stack$2[0] = start;
76713
+ stack$2[1] = end;
76714
76714
 
76715
76715
  while (stackPointer > 0) {
76716
76716
  stackPointer -= 2;
76717
76717
 
76718
- const right = stack$4[stackPointer + 1];
76719
- const left = stack$4[stackPointer];
76718
+ const right = stack$2[stackPointer + 1];
76719
+ const left = stack$2[stackPointer];
76720
76720
 
76721
76721
  i = left;
76722
76722
  j = right;
@@ -76749,12 +76749,12 @@ function arrayQuickSort(
76749
76749
 
76750
76750
  /* recursion */
76751
76751
  if (left < j) {
76752
- stack$4[stackPointer++] = left;
76753
- stack$4[stackPointer++] = j;
76752
+ stack$2[stackPointer++] = left;
76753
+ stack$2[stackPointer++] = j;
76754
76754
  }
76755
76755
  if (i < right) {
76756
- stack$4[stackPointer++] = i;
76757
- stack$4[stackPointer++] = right;
76756
+ stack$2[stackPointer++] = i;
76757
+ stack$2[stackPointer++] = right;
76758
76758
  }
76759
76759
  }
76760
76760
  }
@@ -76780,14 +76780,14 @@ function array_quick_sort_by_comparator(
76780
76780
  let stackPointer = 2;
76781
76781
  let i, j;
76782
76782
 
76783
- stack$4[0] = start;
76784
- stack$4[1] = end;
76783
+ stack$2[0] = start;
76784
+ stack$2[1] = end;
76785
76785
 
76786
76786
  while (stackPointer > 0) {
76787
76787
  stackPointer -= 2;
76788
76788
 
76789
- const right = stack$4[stackPointer + 1];
76790
- const left = stack$4[stackPointer];
76789
+ const right = stack$2[stackPointer + 1];
76790
+ const left = stack$2[stackPointer];
76791
76791
 
76792
76792
  i = left;
76793
76793
  j = right;
@@ -76823,12 +76823,12 @@ function array_quick_sort_by_comparator(
76823
76823
 
76824
76824
  /* recursion */
76825
76825
  if (left < j) {
76826
- stack$4[stackPointer++] = left;
76827
- stack$4[stackPointer++] = j;
76826
+ stack$2[stackPointer++] = left;
76827
+ stack$2[stackPointer++] = j;
76828
76828
  }
76829
76829
  if (i < right) {
76830
- stack$4[stackPointer++] = i;
76831
- stack$4[stackPointer++] = right;
76830
+ stack$2[stackPointer++] = i;
76831
+ stack$2[stackPointer++] = right;
76832
76832
  }
76833
76833
  }
76834
76834
  }
@@ -89353,1637 +89353,6 @@ class BinarySerializationRegistry {
89353
89353
  */
89354
89354
  BinarySerializationRegistry.prototype.isBinarySerializationRegistry = true;
89355
89355
 
89356
- /**
89357
- *
89358
- * @param {AABB3} node
89359
- * @returns {number}
89360
- */
89361
- function aabb3_box_surface_area_2(node) {
89362
- return aabb3_compute_half_surface_area(node.x0, node.y0, node.z0, node.x1, node.y1, node.z1);
89363
- }
89364
-
89365
- /**
89366
- *
89367
- * @param {AABB3} a
89368
- * @param {AABB3} b
89369
- * @returns {number}
89370
- */
89371
- function aabb3_combined_surface_area(a, b) {
89372
- const x0 = min2(a.x0, b.x0);
89373
- const y0 = min2(a.y0, b.y0);
89374
- const z0 = min2(a.z0, b.z0);
89375
-
89376
- const x1 = max2(a.x1, b.x1);
89377
- const y1 = max2(a.y1, b.y1);
89378
- const z1 = max2(a.z1, b.z1);
89379
-
89380
- return aabb3_compute_half_surface_area(x0, y0, z0, x1, y1, z1);
89381
- }
89382
-
89383
- /**
89384
- * Returns true if two 1D lines intersect, touch is treated as intersection
89385
- * Parameters are assumed to be ordered, a1 >= a0, b1 >= b0
89386
- * @param {Number} a0
89387
- * @param {Number} a1
89388
- * @param {Number} b0
89389
- * @param {Number} b1
89390
- * @returns {boolean}
89391
- */
89392
- function intersects1D(a0, a1, b0, b1) {
89393
- assert.isNumber(a0, "a0");
89394
- assert.isNumber(a1, "a1");
89395
- assert.isNumber(b0, "b0");
89396
- assert.isNumber(b1, "b1");
89397
-
89398
- return a1 >= b0 && b1 >= a0;
89399
- }
89400
-
89401
- /**
89402
- *
89403
- * @param {number} ax0
89404
- * @param {number} ay0
89405
- * @param {number} az0
89406
- * @param {number} ax1
89407
- * @param {number} ay1
89408
- * @param {number} az1
89409
- * @param {number} bx0
89410
- * @param {number} by0
89411
- * @param {number} bz0
89412
- * @param {number} bx1
89413
- * @param {number} by1
89414
- * @param {number} bz1
89415
- * @returns {boolean}
89416
- */
89417
- function aabb3_intersects_aabb3(
89418
- ax0, ay0, az0,
89419
- ax1, ay1, az1,
89420
- bx0, by0, bz0,
89421
- bx1, by1, bz1
89422
- ) {
89423
- return intersects1D(ax0, ax1, bx0, bx1)
89424
- && intersects1D(ay0, ay1, by0, by1)
89425
- && intersects1D(az0, az1, bz0, bz1);
89426
- }
89427
-
89428
- /**
89429
- *
89430
- * @param {number[]} sample
89431
- * @returns {number}
89432
- */
89433
- function computeSampleStandardDeviation(sample) {
89434
- //compute sample mean
89435
- const mean = computeStatisticalMean(sample);
89436
-
89437
- const N = sample.length;
89438
-
89439
- let SUM = 0;
89440
- for (let i = 0; i < N; i++) {
89441
- const x = sample[i];
89442
-
89443
- const delta = x - mean;
89444
-
89445
- const delta2 = delta * delta;
89446
-
89447
- SUM += delta2;
89448
- }
89449
-
89450
- const variance = SUM / (N - 1);
89451
-
89452
- return Math.sqrt(variance);
89453
- }
89454
-
89455
- /**
89456
- * Created by Alex on 17/11/2014.
89457
- */
89458
-
89459
-
89460
- class Node extends AABB3 {
89461
- constructor() {
89462
- super();
89463
-
89464
- /**
89465
- *
89466
- * @type {BinaryNode|null}
89467
- */
89468
- this.parentNode = null;
89469
- this._mortonCode = void 0;
89470
- }
89471
-
89472
- /**
89473
- * @return {boolean}
89474
- */
89475
- validateAncestorChain() {
89476
- //check containment
89477
- const parent = this.parentNode;
89478
- if (parent === null) {
89479
- //nothing to do
89480
- return true;
89481
- }
89482
-
89483
- if (!parent.containsBox(this)) {
89484
- //bounds violated
89485
- return false;
89486
- }
89487
-
89488
- if (parent.left === this || parent.right === this) ; else {
89489
- return false;
89490
- }
89491
-
89492
- return true;
89493
- }
89494
-
89495
- /**
89496
- *
89497
- * @returns {number}
89498
- */
89499
- computeDepth() {
89500
- let d = 0;
89501
- let node = this.parentNode;
89502
-
89503
- while (node !== null) {
89504
- node = node.parentNode;
89505
-
89506
- d++;
89507
- }
89508
-
89509
- return d;
89510
- }
89511
-
89512
- /**
89513
- *
89514
- * @returns {Node}
89515
- */
89516
- computeRoot() {
89517
- let p = this;
89518
-
89519
- while (p.parentNode !== null) {
89520
- p = p.parentNode;
89521
- }
89522
-
89523
- return p;
89524
- }
89525
-
89526
- getMortonCode() {
89527
- if (this._mortonCode === void 0) {
89528
- const hx = (this.x1 + this.x0) / 2;
89529
- const hy = (this.y1 + this.y0) / 2;
89530
- const hz = (this.z1 + this.z0) / 2;
89531
- const mortonCode = mortonEncode_magicbits(hx, hy, hz);
89532
- this._mortonCode = mortonCode;
89533
- return mortonCode;
89534
- } else {
89535
- return this._mortonCode;
89536
- }
89537
- }
89538
-
89539
- /**
89540
- * Expands current node and all ancestors until root to accommodate for given box, terminate if node is already
89541
- * large enough
89542
- * @param {AABB3} box
89543
- */
89544
- bubbleExpandToFit(box) {
89545
- let node = this;
89546
- while (node.expandToFit(box)) {
89547
- node = node.parentNode;
89548
- if (node === null) {
89549
- break;
89550
- }
89551
- }
89552
- }
89553
-
89554
- /**
89555
- * @deprecated
89556
- */
89557
- remove() {
89558
- console.error("This method is deprecated, use 'disconnect' instead.");
89559
- this.disconnect();
89560
- }
89561
-
89562
- /**
89563
- * Detaches this node from its parent
89564
- */
89565
- disconnect() {
89566
- const node = this.parentNode;
89567
-
89568
- if (node === null) {
89569
- //no parent already
89570
- // console.warn(`Node has no parent, nothing to disconnect from`);
89571
- return;
89572
- }
89573
-
89574
- if (this === node.left) {
89575
- node.left = null;
89576
- this.parentNode = null;
89577
- } else if (this === node.right) {
89578
- node.right = null;
89579
- this.parentNode = null;
89580
- } else {
89581
- throw new Error("impostor child");
89582
- }
89583
-
89584
- node.updateLeafNodeCount();
89585
- node.updateHeight();
89586
- }
89587
-
89588
- /**
89589
- * traverses all siblings up to the root
89590
- */
89591
- traverseSiblingsUp() {
89592
- throw new Error('Not Implemented');
89593
- }
89594
- }
89595
-
89596
- /**
89597
- * Created by Alex on 17/11/2014.
89598
- */
89599
-
89600
-
89601
- /**
89602
- *
89603
- * @param {Node|LeafNode} node
89604
- * @returns {boolean}
89605
- */
89606
- function isLeaf(node) {
89607
- return node.isLeafNode;
89608
- }
89609
-
89610
- /**
89611
- * @deprecated use {@link BVH} and {@link BvhClient} respectively
89612
- */
89613
- class LeafNode extends Node {
89614
- /**
89615
- *
89616
- * @param {*} object
89617
- * @param {number} x0
89618
- * @param {number} y0
89619
- * @param {number} z0
89620
- * @param {number} x1
89621
- * @param {number} y1
89622
- * @param {number} z1
89623
- * @constructor
89624
- */
89625
- constructor(object, x0, y0, z0, x1, y1, z1) {
89626
- super();
89627
-
89628
- this.object = object;
89629
- this.parentNode = null;
89630
-
89631
- this.x0 = x0;
89632
- this.y0 = y0;
89633
- this.z0 = z0;
89634
- this.x1 = x1;
89635
- this.y1 = y1;
89636
- this.z1 = z1;
89637
-
89638
- }
89639
-
89640
- /**
89641
- *
89642
- * @param {number} dx
89643
- * @param {number} dy
89644
- * @param {number} dz
89645
- */
89646
- move(dx, dy, dz) {
89647
- this.x0 += dx;
89648
- this.x1 += dx;
89649
- this.y0 += dy;
89650
- this.y1 += dy;
89651
- this.z0 += dz;
89652
- this.z1 += dz;
89653
- if (this.parentNode !== null) {
89654
- this.parentNode.bubbleRefit();
89655
- }
89656
- }
89657
-
89658
- /**
89659
- *
89660
- * @param {number} x0
89661
- * @param {number} y0
89662
- * @param {number} z0
89663
- * @param {number} x1
89664
- * @param {number} y1
89665
- * @param {number} z1
89666
- */
89667
- resize(x0, y0, z0, x1, y1, z1) {
89668
- this.setBounds(x0, y0, z0, x1, y1, z1);
89669
-
89670
- this.bubbleRefit();
89671
- }
89672
-
89673
- bubbleRefit() {
89674
-
89675
- if (this.parentNode !== null) {
89676
- this.parentNode.bubbleRefit();
89677
- }
89678
- }
89679
-
89680
- /**
89681
- *
89682
- * @return {LeafNode}
89683
- */
89684
- clone() {
89685
- const clone = new LeafNode(this.object, this.x0, this.y0, this.z0, this.x1, this.y1, this.z1);
89686
-
89687
- clone.parentNode = this.parentNode;
89688
-
89689
- return clone;
89690
- }
89691
- }
89692
-
89693
- /**
89694
- *
89695
- * @type {boolean}
89696
- */
89697
- LeafNode.prototype.isLeafNode = true;
89698
-
89699
- /**
89700
- * Leaf node will have height 0, root node will have height equal to maximum depth of the tree
89701
- * @type {number}
89702
- */
89703
- LeafNode.prototype.height = 0;
89704
-
89705
- /**
89706
- * Useful shortcut, to avoid having to distinguish between leaf and intermediate nodes
89707
- * @readonly
89708
- * @deprecated
89709
- * @type {number}
89710
- */
89711
- LeafNode.prototype.leafNodeCount = 1;
89712
-
89713
- /**
89714
- * Surface Area Heuristic
89715
- * @param {number} saV Surface Area of the volume being split
89716
- * @param {number} saVL Surface Area of Left Volume
89717
- * @param {number} saVR Surface Area of Right Volume
89718
- * @param {number|int} nL Number of leaf nodes in Left Volume
89719
- * @param {number|int} nR Number of leaf nodes in Right Volume
89720
- * @param {number} kT constant for the estimated cost of a traversal step
89721
- * @param {number} kI constant for the estimated cost of a intersection
89722
- * @returns {number}
89723
- */
89724
- function surfaceAreaHeuristicFull(saV, saVL, saVR, nL, nR, kT, kI) {
89725
- return kT + kI * (saVL * nL / saV + saVR * nR / saV);
89726
- }
89727
-
89728
- /**
89729
- * Surface Area Heuristic
89730
- * @param {number} saV Surface Area of the volume being split
89731
- * @param {number} saVL Surface Area of Left Volume
89732
- * @param {number} saVR Surface Area of Right Volume
89733
- * @param {number|int} nL Number of leaf nodes in Left Volume
89734
- * @param {number|int} nR Number of leaf nodes in Right Volume
89735
- * @returns {number}
89736
- */
89737
- function surfaceAreaHeuristic(saV, saVL, saVR, nL, nR) {
89738
- return surfaceAreaHeuristicFull(saV, saVL, saVR, nL, nR, 1, 1);
89739
- }
89740
-
89741
- class BVHVisitor {
89742
- constructor() {
89743
-
89744
- }
89745
-
89746
- initialize() {
89747
-
89748
- }
89749
-
89750
- finalize() {
89751
-
89752
- }
89753
-
89754
- /**
89755
- *
89756
- * @param {LeafNode} node
89757
- */
89758
- visitLeaf(node) {
89759
-
89760
- }
89761
-
89762
- /**
89763
- *
89764
- * @param {BinaryNode} node
89765
- * @returns {boolean} true if traversal should go deeper, false to exclude descendants from traversal
89766
- */
89767
- visitBinary(node) {
89768
- return true;
89769
- }
89770
- }
89771
-
89772
- const stack$3 = [];
89773
- let stackPointer$1 = 0;
89774
-
89775
- /**
89776
- *
89777
- * @param {BinaryNode} node
89778
- * @param {BVHVisitor} visitor
89779
- */
89780
- function traverseBinaryNodeUsingVisitor(node, visitor) {
89781
- let n;
89782
-
89783
- const stackOffset = stackPointer$1;
89784
-
89785
- stack$3[stackPointer$1++] = node;
89786
-
89787
- while (stackPointer$1-- > stackOffset) {
89788
-
89789
- n = stack$3[stackPointer$1];
89790
-
89791
- if (n.isBinaryNode) {
89792
- const traverseDeeper = visitor.visitBinary(n);
89793
-
89794
- if (traverseDeeper !== false) {
89795
-
89796
- if (n.left !== null) {
89797
-
89798
- // has a LEFT child
89799
-
89800
- stack$3[stackPointer$1++] = n.left;
89801
-
89802
- }
89803
-
89804
- if (n.right !== null) {
89805
-
89806
- // has a RIGHT child
89807
-
89808
- stack$3[stackPointer$1++] = n.right;
89809
-
89810
- }
89811
-
89812
- }
89813
- } else {
89814
- visitor.visitLeaf(n);
89815
- }
89816
-
89817
- }
89818
-
89819
- //drop the stack frame
89820
- stackPointer$1 = stackOffset;
89821
- }
89822
-
89823
- /**
89824
- * Created by Alex on 17/11/2014.
89825
- */
89826
-
89827
-
89828
- /**
89829
- * @callback BinaryNode~Visitor
89830
- * @param {Node} node
89831
- * @returns {boolean} flag, controls traversal of descendants. If false - no traversal is done over descendants
89832
- */
89833
-
89834
-
89835
- /**
89836
- *
89837
- * @type {number}
89838
- */
89839
- let stackPointer = 0;
89840
- /**
89841
- *
89842
- * @type {Node[]}
89843
- */
89844
- const stack$2 = [];
89845
-
89846
- /**
89847
- * @deprecated use {@link BVH} instead
89848
- */
89849
- class BinaryNode extends Node {
89850
- constructor() {
89851
- super();
89852
-
89853
- /**
89854
- *
89855
- * @type {null|BinaryNode|LeafNode}
89856
- */
89857
- this.parentNode = null;
89858
-
89859
- /**
89860
- *
89861
- * @type {null|Node|LeafNode|BinaryNode}
89862
- */
89863
- this.left = null;
89864
-
89865
- /**
89866
- *
89867
- * @type {null|Node|LeafNode|BinaryNode}
89868
- */
89869
- this.right = null;
89870
-
89871
- /**
89872
- * Number of leaf nodes in the hierarchy
89873
- * @deprecated
89874
- * @type {number}
89875
- * @private
89876
- */
89877
- this.leafNodeCount = 0;
89878
-
89879
- /**
89880
- * Leaf node will have height 0, root node will have height equal to maximum depth of the tree
89881
- * @type {number}
89882
- */
89883
- this.height = 0;
89884
- }
89885
-
89886
- /**
89887
- * Same as traversePreOrder but without recursion. This runs faster thanks to avoidance of function call overhead. Especially useful for deeper trees.
89888
- * @param {BinaryNode~Visitor} visitor
89889
- * @param [thisArg]
89890
- * @deprecated use visitor-based traversal instead of callback-based
89891
- */
89892
- traversePreOrderUsingStack(visitor, thisArg) {
89893
- let visitCount = 0;
89894
-
89895
- const stackOffset = stackPointer;
89896
-
89897
- stack$2[stackPointer++] = this;
89898
- let n;
89899
- while (stackPointer-- > stackOffset) {
89900
-
89901
- visitCount++;
89902
-
89903
- n = stack$2[stackPointer];
89904
-
89905
- const traverseDeeper = visitor.call(thisArg, n);
89906
-
89907
- if (traverseDeeper !== false && n.isBinaryNode) {
89908
- if (n.right !== null) {
89909
- stack$2[stackPointer++] = n.right;
89910
- }
89911
- if (n.left !== null) {
89912
- stack$2[stackPointer++] = n.left;
89913
- }
89914
- }
89915
- }
89916
-
89917
- // drop stack frame
89918
- stackPointer = stackOffset;
89919
-
89920
- return visitCount;
89921
- }
89922
-
89923
- /**
89924
- * Traverse leaf nodes in a fast manner
89925
- * @param {function(node:LeafNode)} visitor
89926
- * @param {*} [thisArg]
89927
- */
89928
- traverseLeavesPreOrderUsingStack(visitor, thisArg) {
89929
- let visitCount = 0;
89930
-
89931
- const stackOffset = stackPointer;
89932
-
89933
- stack$2[stackPointer++] = this;
89934
-
89935
- let n;
89936
-
89937
- while (stackPointer-- > stackOffset) {
89938
-
89939
- visitCount++;
89940
-
89941
- n = stack$2[stackPointer];
89942
-
89943
- if (n.isLeafNode) {
89944
- visitor.call(thisArg, n);
89945
- } else {
89946
- //a binary node
89947
- if (n.right !== null) {
89948
- stack$2[stackPointer++] = n.right;
89949
- }
89950
- if (n.left !== null) {
89951
- stack$2[stackPointer++] = n.left;
89952
- }
89953
- }
89954
- }
89955
-
89956
- // drop stack frame
89957
- stackPointer = stackOffset;
89958
-
89959
- return visitCount;
89960
- }
89961
-
89962
-
89963
- /**
89964
- * Contains no children
89965
- * @returns {boolean}
89966
- */
89967
- isEmpty() {
89968
- return this.left === null && this.right === null;
89969
- }
89970
-
89971
- reset() {
89972
- this.left = null;
89973
- this.right = null;
89974
-
89975
- this.leafNodeCount = 0;
89976
- this.height = 0;
89977
-
89978
- this.setNegativelyInfiniteBounds();
89979
- }
89980
-
89981
- /**
89982
- *
89983
- * @param {Node|BinaryNode} left
89984
- * @param {Node|BinaryNode} right
89985
- */
89986
- setChildren(left, right) {
89987
- this.left = left;
89988
- this.right = right;
89989
-
89990
- left.parentNode = this;
89991
- right.parentNode = this;
89992
- }
89993
-
89994
- /**
89995
- *
89996
- * @param {Node} child
89997
- */
89998
- setChildLeft(child) {
89999
- assert.isNull(this.left, 'left');
90000
-
90001
- this.left = child;
90002
- child.parentNode = this;
90003
- }
90004
-
90005
- /**
90006
- *
90007
- * @param {Node} child
90008
- */
90009
- setChildRight(child) {
90010
- assert.isNull(this.right, 'right');
90011
-
90012
- this.right = child;
90013
- child.parentNode = this;
90014
- }
90015
-
90016
- /**
90017
- * For incremental insertion, a sibling needs to be found, newly inserted node will be parented together with this sibling
90018
- * @see https://github.com/erincatto/box2d/blob/9dc24a6fd4f32442c4bcf80791de47a0a7d25afb/src/collision/b2_dynamic_tree.cpp#L197
90019
- * @private
90020
- * @param {AABB3} box
90021
- * @returns {BinaryNode|LeafNode}
90022
- */
90023
- __insertion_findSiblingFor(box) {
90024
-
90025
- let node = this;
90026
- let cost_left = 0;
90027
- let cost_right = 0;
90028
-
90029
- while (node.isBinaryNode === true) {
90030
- const left = node.left;
90031
- const right = node.right;
90032
-
90033
- const area = aabb3_box_surface_area_2(node);
90034
-
90035
- const combined_area = aabb3_combined_surface_area(node, box);
90036
-
90037
- //cost of creating a new parent for this node and the new leaf
90038
- const cost = combined_area;
90039
-
90040
- // minimum cost of pushing the leaf further down the tree
90041
- const inheritance_cost = combined_area - area;
90042
-
90043
- // cost of descending left
90044
- if (left !== null) {
90045
- const combined_left = aabb3_combined_surface_area(left, box);
90046
- if (left.isLeafNode) {
90047
- cost_left = combined_left + inheritance_cost;
90048
- } else {
90049
- cost_left = combined_left - aabb3_box_surface_area_2(left) + inheritance_cost;
90050
- }
90051
- } else {
90052
- cost_left = Infinity;
90053
- }
90054
-
90055
- // cost of descending right
90056
- if (right !== null) {
90057
-
90058
- const combined_right = aabb3_combined_surface_area(right, box);
90059
- if (right.isLeafNode) {
90060
- cost_right = combined_right + inheritance_cost;
90061
- } else {
90062
- cost_right = combined_right - aabb3_box_surface_area_2(right) + inheritance_cost;
90063
- }
90064
- } else {
90065
- cost_right = Infinity;
90066
- }
90067
-
90068
- if (cost < cost_left && cost < cost_right) {
90069
- // descending either branch is too expensive
90070
- break;
90071
- }
90072
-
90073
- if (cost_left < cost_right && left !== null) {
90074
- node = left;
90075
- } else if (right !== null) {
90076
- node = right;
90077
- } else {
90078
- break;
90079
- }
90080
- }
90081
-
90082
- return node;
90083
- }
90084
-
90085
- /**
90086
- *
90087
- * @param {AABB3} box
90088
- * @returns {Node|BinaryNode|LeafNode}
90089
- */
90090
- findParentFor(box) {
90091
- let n = this;
90092
- let aCost = 0;
90093
- let bCost = 0;
90094
-
90095
- for (; ;) {
90096
-
90097
- const a = n.left;
90098
- const b = n.right;
90099
-
90100
- if (a === null || b === null) {
90101
- //unbalanced node, good candidate already
90102
- return n;
90103
- }
90104
-
90105
- const aIsBinary = a.isBinaryNode;
90106
- const bIsBinary = b.isBinaryNode;
90107
-
90108
- aCost = a.costForInclusion(box);
90109
- bCost = b.costForInclusion(box);
90110
-
90111
- if (aCost === bCost) {
90112
-
90113
- if (a.isLeafNode) {
90114
-
90115
- return a;
90116
-
90117
- } else if (b.isLeafNode) {
90118
-
90119
- return b;
90120
-
90121
- }
90122
-
90123
- //change costs to be based on balance
90124
- aCost = a.leafNodeCount / aabb3_box_surface_area_2(a);
90125
- bCost = b.leafNodeCount / aabb3_box_surface_area_2(b);
90126
- }
90127
-
90128
- if (aCost === bCost) {
90129
- //still the same, toss a coin
90130
- aCost = Math.random();
90131
- bCost = 1 - aCost;
90132
- }
90133
-
90134
- if (aCost < bCost) {
90135
- if (aIsBinary) {
90136
- n = a;
90137
- } else {
90138
- return a;
90139
- }
90140
- } else {
90141
- if (bIsBinary) {
90142
- n = b;
90143
- } else {
90144
- return b;
90145
- }
90146
- }
90147
- }
90148
- }
90149
-
90150
- traverse(visitor) {
90151
- if (this.left !== null) {
90152
- const cA = visitor(this.left);
90153
- if (cA !== false) {
90154
- this.left.traverse(visitor);
90155
- }
90156
- }
90157
- if (this.right !== null) {
90158
- const cB = visitor(this.right);
90159
- if (cB !== false) {
90160
- this.right.traverse(visitor);
90161
- }
90162
- }
90163
- }
90164
-
90165
- /**
90166
- * Bottom-up tree traversal, children first
90167
- * @param visitor
90168
- */
90169
- traversePostOrder(visitor) {
90170
- //left
90171
- if (this.left instanceof BinaryNode) {
90172
- this.left.traversePostOrder(visitor);
90173
- } else if (this.left instanceof LeafNode) {
90174
- visitor(this.left);
90175
- }
90176
- //right
90177
- if (this.right instanceof BinaryNode) {
90178
- this.right.traversePostOrder(visitor);
90179
- } else if (this.right instanceof LeafNode) {
90180
- visitor(this.right);
90181
- }
90182
- visitor(this);
90183
- }
90184
-
90185
- traversePreOrder(visitor) {
90186
- const carryOn = visitor(this);
90187
- if (carryOn !== false) {
90188
- //left
90189
- if (this.left instanceof BinaryNode) {
90190
- this.left.traversePreOrder(visitor);
90191
- } else if (this.left instanceof LeafNode) {
90192
- visitor(this.left);
90193
- }
90194
- //right
90195
- if (this.right instanceof BinaryNode) {
90196
- this.right.traversePreOrder(visitor);
90197
- } else if (this.right instanceof LeafNode) {
90198
- visitor(this.right);
90199
- }
90200
- }
90201
- }
90202
-
90203
- refitFor2() {
90204
- const a = this.left;
90205
- const b = this.right;
90206
-
90207
- const x0 = min2(a.x0, b.x0);
90208
- const y0 = min2(a.y0, b.y0);
90209
- const z0 = min2(a.z0, b.z0);
90210
-
90211
- const x1 = max2(a.x1, b.x1);
90212
- const y1 = max2(a.y1, b.y1);
90213
- const z1 = max2(a.z1, b.z1);
90214
-
90215
- this.setBounds(x0, y0, z0, x1, y1, z1);
90216
- }
90217
-
90218
- bubbleRefit() {
90219
- let n = this;
90220
-
90221
- n.refit();
90222
-
90223
- //bubble up
90224
- for (; ;) {
90225
- //record old node size
90226
- const _x0 = n.x0;
90227
- const _y0 = n.y0;
90228
- const _z0 = n.z0;
90229
- const _x1 = n.x1;
90230
- const _y1 = n.y1;
90231
- const _z1 = n.z1;
90232
-
90233
- n = n.parentNode;
90234
-
90235
- if (n === null) {
90236
- // hit the root
90237
- return;
90238
- }
90239
-
90240
-
90241
- //check if this node violates bounds of the parent
90242
- let flag = false;
90243
-
90244
- if (_x0 < n.x0) {
90245
- n.x0 = _x0;
90246
- flag = true;
90247
- }
90248
- if (_y0 < n.y0) {
90249
- n.y0 = _y0;
90250
- flag = true;
90251
- }
90252
- if (_z0 < n.z0) {
90253
- n.z0 = _z0;
90254
- flag = true;
90255
- }
90256
-
90257
- if (_x1 > n.x1) {
90258
- n.x1 = _x1;
90259
- flag = true;
90260
- }
90261
- if (_y1 > n.y1) {
90262
- n.y1 = _y1;
90263
- flag = true;
90264
- }
90265
- if (_z1 > n.z1) {
90266
- n.z1 = _z1;
90267
- flag = true;
90268
- }
90269
-
90270
- if (!flag) {
90271
- //no violation, we can stop here
90272
- break;
90273
- }
90274
- }
90275
- }
90276
-
90277
- refit() {
90278
- if (this.left !== null && this.right !== null) {
90279
- this.refitFor2();
90280
- } else if (this.left !== null) {
90281
- this.copy(this.left);
90282
- } else if (this.right !== null) {
90283
- this.copy(this.right);
90284
- }
90285
- }
90286
-
90287
- sumSurfaceArea() {
90288
- let result = 0;
90289
- this.traversePreOrderUsingStack(function (node) {
90290
- const nodeArea = node.computeSurfaceArea();
90291
- result += nodeArea;
90292
- });
90293
-
90294
- return result;
90295
- }
90296
-
90297
- countDescendants() {
90298
- let result = 0;
90299
- this.traversePreOrderUsingStack(function (node) {
90300
- result++;
90301
- });
90302
- return result;
90303
- }
90304
-
90305
- /**
90306
- * @deprecated Incorrect usage of SAH
90307
- * @return {number}
90308
- */
90309
- computeSAH() {
90310
- let leftLeaves, rightLeaves, leftArea, rightArea;
90311
-
90312
- const left = this.left;
90313
-
90314
- if (left === null) {
90315
- leftArea = 0;
90316
- leftLeaves = 0;
90317
- } else {
90318
- leftArea = aabb3_box_surface_area_2(left);
90319
- leftLeaves = left.leafNodeCount;
90320
- }
90321
-
90322
- const right = this.right;
90323
- if (right === null) {
90324
- rightArea = 0;
90325
- rightLeaves = 0;
90326
- } else {
90327
- rightArea = aabb3_box_surface_area_2(right);
90328
- rightLeaves = right.leafNodeCount;
90329
- }
90330
-
90331
- const thisArea = aabb3_box_surface_area_2(this);
90332
-
90333
- return surfaceAreaHeuristic(thisArea, leftArea, rightArea, leftLeaves, rightLeaves);
90334
- }
90335
-
90336
- updateHeight() {
90337
- let node = this;
90338
- let n = 0;
90339
-
90340
- while (node !== null) {
90341
- n = 0;
90342
-
90343
- const right = node.right;
90344
-
90345
- if (right !== null) {
90346
- n = right.height;
90347
- }
90348
-
90349
- const left = this.left;
90350
-
90351
- if (left !== null) {
90352
- n = max2(n, left.height);
90353
- }
90354
-
90355
- node.height = n + 1;
90356
-
90357
- // propagate update up the tree
90358
- node = node.parentNode;
90359
- }
90360
- }
90361
-
90362
- /**
90363
- * @deprecated
90364
- */
90365
- updateLeafNodeCount() {
90366
- let node = this;
90367
-
90368
- while (node !== null) {
90369
- let n = 0;
90370
-
90371
- const right = node.right;
90372
-
90373
- if (right !== null) {
90374
- if (right.isLeafNode) {
90375
- n++;
90376
- } else {
90377
- n += right.leafNodeCount;
90378
- }
90379
- }
90380
-
90381
- const left = this.left;
90382
-
90383
- if (left !== null) {
90384
- if (left.isLeafNode) {
90385
- n++;
90386
- } else {
90387
- n += left.leafNodeCount;
90388
- }
90389
- }
90390
-
90391
- node.leafNodeCount = n;
90392
-
90393
- // propagate update up the tree
90394
- node = node.parentNode;
90395
- }
90396
-
90397
- }
90398
-
90399
- /**
90400
- * As a result of rotation, this node 'becomes' the right node, and left node get's replaced by the right node with necessary adjustments
90401
- */
90402
- rotateLeft() {
90403
-
90404
- /**
90405
- *
90406
- * @type {BinaryNode}
90407
- */
90408
- const r = this.right;
90409
-
90410
- const l = this.left;
90411
-
90412
- const rL = r.left;
90413
- const rR = r.right;
90414
-
90415
- this.left = r;
90416
- this.right = rR;
90417
-
90418
- if (rR !== null) {
90419
- rR.parentNode = this;
90420
- }
90421
-
90422
- r.left = l;
90423
- if (l !== null) {
90424
- l.parentNode = r;
90425
- }
90426
-
90427
- r.right = rL;
90428
-
90429
- r.updateLeafNodeCount();
90430
- r.updateHeight();
90431
-
90432
- r.bubbleRefit();
90433
- }
90434
-
90435
- rotateRight() {
90436
- const r = this.right;
90437
-
90438
- const left = this.left;
90439
-
90440
- const lL = left.left;
90441
- const lR = left.right;
90442
-
90443
- if (lL !== null) {
90444
- lL.parentNode = this;
90445
- }
90446
-
90447
- left.right = r;
90448
- if (r !== null) {
90449
- r.parentNode = left;
90450
- }
90451
-
90452
- left.left = lR;
90453
-
90454
- left.updateLeafNodeCount();
90455
- left.updateHeight();
90456
-
90457
- left.bubbleRefit();
90458
- }
90459
-
90460
- /**
90461
- *
90462
- * @param {function(index:int):LeafNode} leafFactory
90463
- * @param {int} numNodes
90464
- */
90465
- insertManyBoxes2(leafFactory, numNodes) {
90466
- let i, n;
90467
- //create leaf nodes
90468
- const nodes = new Array(numNodes);
90469
-
90470
- for (i = 0; i < numNodes; i++) {
90471
- //leaf needs to be set up inside the callback
90472
- n = leafFactory(i);
90473
-
90474
- nodes[i] = n;
90475
- }
90476
-
90477
- //sort leaves
90478
- arrayQuickSort(nodes, n => n.computeMortonCode(), null, 0, max2(0, numNodes - 1));
90479
-
90480
- let remaining_nodes = numNodes;
90481
-
90482
- while (remaining_nodes > 2) {
90483
-
90484
- //pair
90485
- for (i = 0; i < remaining_nodes - 1; i += 2) {
90486
- const a = nodes[i];
90487
- const b = nodes[i + 1];
90488
-
90489
- n = new BinaryNode();
90490
-
90491
- n.setChildren(a, b);
90492
-
90493
- n.updateHeight();
90494
- n.refitFor2();
90495
-
90496
- nodes[i >> 1] = n;
90497
- }
90498
-
90499
- const numNodesMod2 = remaining_nodes & 1; //faster version of %2
90500
-
90501
- if (numNodesMod2 !== 0) {
90502
- //shift remaining node up so it will be considered later
90503
- nodes[i >> 1] = nodes[i];
90504
- }
90505
-
90506
- remaining_nodes = (remaining_nodes >> 1) + numNodesMod2;
90507
- }
90508
-
90509
- //finally insert these boxes from this node
90510
- for (i = 0; i < remaining_nodes; i++) {
90511
- n = nodes[i];
90512
- this.insertNode(n);
90513
- }
90514
- }
90515
-
90516
- /**
90517
- *
90518
- * @param {LeafNode[]} result destination
90519
- * @param {number} x0
90520
- * @param {number} y0
90521
- * @param {number} z0
90522
- * @param {number} x1
90523
- * @param {number} y1
90524
- * @param {number} z1
90525
- * @returns {number} number of objects added to the result
90526
- */
90527
- requestLeafIntersectionsAABB3(result, x0, y0, z0, x1, y1, z1) {
90528
- const startOffset = stackPointer;
90529
-
90530
- stack$2[stackPointer++] = this;
90531
-
90532
- let count = 0;
90533
-
90534
- while (stackPointer > startOffset) {
90535
- stackPointer--;
90536
- const node = stack$2[stackPointer];
90537
-
90538
- if (!aabb3_intersects_aabb3(
90539
- x0, y0, z0, x1, y1, z1,
90540
- node.x0, node.y0, node.z0, node.x1, node.y1, node.z1
90541
- )) {
90542
- //no overlap
90543
- continue;
90544
- }
90545
-
90546
- if (node.isLeafNode) {
90547
- result[count++] = node;
90548
-
90549
- count++;
90550
- } else {
90551
- const left = node.left;
90552
- if (left !== null) {
90553
- stack$2[stackPointer++] = left;
90554
- }
90555
-
90556
- const right = node.right;
90557
- if (right !== null) {
90558
- stack$2[stackPointer++] = right;
90559
- }
90560
- }
90561
- }
90562
-
90563
- return count;
90564
- }
90565
-
90566
- traverseSegmentLeafIntersections(startX, startY, startZ, endX, endY, endZ, visitor) {
90567
- this.traversePreOrder(function (node) {
90568
- let b = node.intersectSegment(startX, startY, startZ, endX, endY, endZ);
90569
- if (!b) {
90570
- return false;
90571
- }
90572
- if (node instanceof LeafNode) {
90573
- visitor(node);
90574
- return false;
90575
- } else {
90576
- return true;
90577
- }
90578
- });
90579
- }
90580
-
90581
- /**
90582
- *
90583
- * @param {Frustum[]} frustums Collection of THREE.js Frustums
90584
- * @param {function(node:LeafNode, boolean)} visitor
90585
- * @returns {number}
90586
- * @deprecated Use {@link ThreeFrustumsIntersectionBVHVisitor}
90587
- */
90588
- threeTraverseFrustumsIntersections(frustums, visitor) {
90589
- const numFrustums = frustums.length;
90590
-
90591
- /**
90592
- *
90593
- * @param {LeafNode|BinaryNode} node
90594
- * @returns {boolean}
90595
- */
90596
- function visitNode(node) {
90597
- let b = false;
90598
- let i = 0;
90599
-
90600
- for (; i < numFrustums; i++) {
90601
-
90602
- const degree = node.intersectFrustumDegree(frustums[i]);
90603
-
90604
- if (degree === 2) {
90605
- //completely inside frustum
90606
-
90607
- if (node.isLeafNode) {
90608
- visitor(node, true);
90609
- } else {
90610
- node.traverseLeavesPreOrderUsingStack(fastVisitLeafNodeIntersection, visitor);
90611
- }
90612
-
90613
- //prevent further traversal
90614
- return false;
90615
-
90616
- } else if (degree === 1) {
90617
-
90618
- //partially inside frustum
90619
- b = true;
90620
-
90621
- }
90622
- }
90623
-
90624
- if (!b) {
90625
- return false;
90626
- }
90627
-
90628
- if (node.isLeafNode) {
90629
- visitor(node, false);
90630
- }
90631
-
90632
- return true;
90633
- }
90634
-
90635
- return this.traversePreOrderUsingStack(visitNode);
90636
- }
90637
-
90638
- /**
90639
- * As recursion goes on, we remove frustums and planes from checks reducing total number of checks necessary
90640
- * @param {Array.<THREE.Frustum>} frustums
90641
- * @param {function} visitor
90642
- * @returns {number}
90643
- */
90644
- threeTraverseFrustumsIntersections2(frustums, visitor) {
90645
- const numFrustums = frustums.length;
90646
-
90647
- function visitLeaves(node) {
90648
- if (node instanceof LeafNode) {
90649
- visitor(node);
90650
- return false;
90651
- } else {
90652
- return true;
90653
- }
90654
- }
90655
-
90656
- function fastTraverseLeaves(node) {
90657
- if (node instanceof LeafNode) {
90658
- visitor(node);
90659
- } else {
90660
- node.traversePreOrderUsingStack(visitLeaves);
90661
- }
90662
- }
90663
-
90664
- function removeElementFromClone(original, clone, mask, originalIndex) {
90665
- if (clone === original) {
90666
- //clone planes
90667
- clone = clone.slice();
90668
- }
90669
- //remove the plane from new set
90670
- clone.splice(originalIndex, 1);
90671
- return clone;
90672
- }
90673
-
90674
- function processVolumesIntersections(node, planeSets, planeSetCount) {
90675
- let newPlaneSets = planeSets;
90676
- for (let iPS = planeSetCount - 1; iPS >= 0; iPS--) {
90677
-
90678
- const planes = planeSets[iPS];
90679
- let newPlanes = planes;
90680
- const numPlanes = planes.length;
90681
-
90682
- //check plane set
90683
- for (let i = numPlanes - 1; i >= 0; i--) {
90684
- const plane = planes[i];
90685
- const planeSide = node.computePlaneSide(plane);
90686
- if (planeSide < 0) {
90687
- //completely inside
90688
- newPlanes = removeElementFromClone(planes, newPlanes);
90689
- } else if (planeSide > 0) {
90690
- //on the wrong side of the plane
90691
- //drop plane set
90692
- newPlaneSets = removeElementFromClone(planeSets, newPlaneSets);
90693
-
90694
- break;
90695
- }
90696
- }
90697
-
90698
- //update plane sets as needed
90699
- if (newPlanes !== planes && newPlaneSets.indexOf(planes) !== -1) {
90700
- //replace
90701
- if (newPlaneSets === planeSets) {
90702
- //clone if needed
90703
- newPlaneSets = newPlaneSets.slice();
90704
- }
90705
- newPlaneSets[iPS] = newPlanes;
90706
- }
90707
- }
90708
-
90709
- return newPlaneSets;
90710
- }
90711
-
90712
- function traverseVolumeIntersections(node, planeSets, numPlaneSets) {
90713
- function internalVisitor(node) {
90714
- let newPlaneSet = processVolumesIntersections(node, planeSets, numPlaneSets);
90715
- if (newPlaneSet !== planeSets) {
90716
- let newPlaneSetCount = newPlaneSet.length;
90717
- if (newPlaneSetCount !== 0) {
90718
- //some intersections
90719
-
90720
- //check if all plane sets are trivial (contain no test planes)
90721
- let trivialPlaneSets = 0;
90722
- for (let i = 0; i < newPlaneSetCount; i++) {
90723
- if (newPlaneSet[i].length === 0) {
90724
- trivialPlaneSets++;
90725
- }
90726
- }
90727
-
90728
- if (isLeaf(node)) {
90729
- visitor(node);
90730
- } else {
90731
- if (trivialPlaneSets === newPlaneSetCount) {
90732
- fastTraverseLeaves(node);
90733
- } else {
90734
- traverseVolumeIntersections(node, newPlaneSet, newPlaneSetCount);
90735
- }
90736
- }
90737
- }
90738
- } else {
90739
- if (isLeaf(node)) {
90740
- visitor(node);
90741
- } else {
90742
- return true;
90743
- }
90744
- }
90745
-
90746
- return false;
90747
- }
90748
-
90749
- node.traversePreOrderUsingStack(internalVisitor);
90750
- }
90751
-
90752
- function startTraversal(node) {
90753
- let planeSets = [];
90754
- for (let i = 0; i < numFrustums; i++) {
90755
- const frustum = frustums[i];
90756
- const planes = frustum.planes;
90757
- planeSets.push(planes);
90758
- }
90759
- traverseVolumeIntersections(node, planeSets, numFrustums);
90760
- }
90761
-
90762
- startTraversal(this);
90763
- }
90764
-
90765
- /**
90766
- *
90767
- * @param {number} startX
90768
- * @param {number} startY
90769
- * @param {number} startZ
90770
- * @param {number} directionX
90771
- * @param {number} directionY
90772
- * @param {number} directionZ
90773
- * @param {function(node:LeafNode)} visitor
90774
- * @param thisArg
90775
- * @deprecated use {@link RaycastBVHVisitor} instead
90776
- */
90777
- traverseRayLeafIntersections(startX, startY, startZ, directionX, directionY, directionZ, visitor, thisArg) {
90778
- this.traversePreOrderUsingStack(function (node) {
90779
- let b = node.intersectRay(startX, startY, startZ, directionX, directionY, directionZ);
90780
-
90781
- if (!b) {
90782
- //no intersection, terminate this branch
90783
- return false;
90784
- }
90785
-
90786
- if (isLeaf(node)) {
90787
- //leaf node, supply to visitor
90788
- visitor.call(thisArg, node);
90789
- return false;
90790
- } else {
90791
- //intermediate node, continue traversal
90792
- return true;
90793
- }
90794
- });
90795
- }
90796
-
90797
- /**
90798
- * Fraction of balanced nodes in the tree (those that have both children)
90799
- * @returns {number}
90800
- */
90801
- computeBalanceFactor() {
90802
-
90803
- const bvhVisitor = new BVHVisitor();
90804
-
90805
-
90806
- const depths = [];
90807
-
90808
- bvhVisitor.visitLeaf = (leaf) => {
90809
- const depth = leaf.computeDepth();
90810
-
90811
- depths.push(depth);
90812
- };
90813
-
90814
- traverseBinaryNodeUsingVisitor(this, bvhVisitor);
90815
-
90816
- if (depths.length === 0) {
90817
- return 1;
90818
- } else {
90819
- return computeSampleStandardDeviation(depths);
90820
- }
90821
-
90822
- }
90823
-
90824
- /**
90825
- * @template T
90826
- * @param {number} x0
90827
- * @param {number} y0
90828
- * @param {number} z0
90829
- * @param {number} x1
90830
- * @param {number} y1
90831
- * @param {number} z1
90832
- * @param {T} value
90833
- * @returns {LeafNode}
90834
- */
90835
- insert(x0, y0, z0, x1, y1, z1, value) {
90836
- const leaf = new LeafNode(value, x0, y0, z0, x1, y1, z1);
90837
- this.insertNode(leaf);
90838
- return leaf;
90839
- }
90840
-
90841
- /**
90842
- *
90843
- * @param {Node|BinaryNode|LeafNode} child
90844
- */
90845
- insertNode(child) {
90846
-
90847
- assert.notNull(child, "child");
90848
- assert.defined(child, "child");
90849
- assert.isInstanceOf(child, Node, 'child', "Node");
90850
- assert.equal(child.parentNode, null, "parentNode must be null, otherwise Node still belongs to another tree");
90851
-
90852
- const sibling = this.__insertion_findSiblingFor(child);
90853
-
90854
- let parent = sibling.parentNode;
90855
-
90856
- if (parent === null) {
90857
- // "sibling" is the root node
90858
-
90859
- parent = sibling;
90860
-
90861
- if (sibling.left === null) {
90862
- sibling.setChildLeft(child);
90863
- } else if (sibling.right === null) {
90864
- sibling.setChildRight(child);
90865
- } else {
90866
- parent = new BinaryNode();
90867
-
90868
- parent.setChildren(sibling.right, child);
90869
- sibling.right = parent;
90870
- parent.parentNode = sibling;
90871
- }
90872
-
90873
- } else {
90874
-
90875
- // non-root
90876
-
90877
- if (parent.left === sibling && parent.right === null) {
90878
-
90879
- // right node is free, take it
90880
- parent.setChildRight(child);
90881
-
90882
- } else if (parent.right === sibling && parent.left === null) {
90883
-
90884
- // left node is free, take it
90885
- parent.setChildLeft(child);
90886
-
90887
- } else {
90888
-
90889
- parent = transplantNewCommonParent(sibling, child);
90890
-
90891
- }
90892
-
90893
- }
90894
-
90895
- // walk back up the tree fixing heights and bounds
90896
- do {
90897
- // parent = this.balance();
90898
-
90899
- const left = parent.left;
90900
- const right = parent.right;
90901
-
90902
- parent.height = 1 + max2(left !== null ? left.height : 0, right !== null ? right.height : 0);
90903
- parent.refit();
90904
-
90905
- parent = parent.parentNode;
90906
- } while (parent !== null);
90907
- }
90908
-
90909
- /**
90910
- * @param {boolean} deep
90911
- * @returns {BinaryNode}
90912
- */
90913
- clone(deep = false) {
90914
- const clone = new BinaryNode();
90915
-
90916
- clone.x0 = this.x0;
90917
- clone.y0 = this.y0;
90918
- clone.z0 = this.z0;
90919
- clone.x1 = this.x1;
90920
- clone.y1 = this.y1;
90921
- clone.z1 = this.z1;
90922
-
90923
- clone.leafNodeCount = this.leafNodeCount;
90924
-
90925
- clone.parentNode = this.parentNode;
90926
-
90927
- if (deep === true) {
90928
- if (this.left !== null) {
90929
- clone.left = this.left.clone(true);
90930
- clone.left.parentNode = clone;
90931
- }
90932
- if (this.right !== null) {
90933
- clone.right = this.right.clone(true);
90934
- clone.right.parentNode = clone;
90935
- }
90936
- } else {
90937
- clone.left = this.left;
90938
- clone.right = this.right;
90939
- }
90940
-
90941
- clone.modifiers = this.modifiers;
90942
-
90943
- return clone;
90944
- }
90945
- }
90946
-
90947
- /**
90948
- * @readonly
90949
- * @type {boolean}
90950
- */
90951
- BinaryNode.prototype.isBinaryNode = true;
90952
-
90953
- /**
90954
- * @private
90955
- * Used in intersection traversal methods. Should be invoked via Function.apply and Function.call only and not be called directly
90956
- * @param {LeafNode} node
90957
- */
90958
- function fastVisitLeafNodeIntersection(node) {
90959
- this(node, true);
90960
- }
90961
-
90962
- /**
90963
- *
90964
- * @param {Node} node
90965
- * @param {Node} child
90966
- * @return {BinaryNode}
90967
- */
90968
- function transplantNewCommonParent(node, child) {
90969
- const bNode = new BinaryNode();
90970
-
90971
- //
90972
- const parent = node.parentNode;
90973
- if (node === parent.left) {
90974
- parent.left = bNode;
90975
- } else if (node === parent.right) {
90976
- parent.right = bNode;
90977
- } else {
90978
- throw new Error("Not a child of specified parent node(impostor)");
90979
- }
90980
-
90981
- bNode.setChildren(node, child);
90982
- bNode.parentNode = parent;
90983
-
90984
- return bNode;
90985
- }
90986
-
90987
89356
  class MetricsGateway {
90988
89357
  constructor() {
90989
89358
 
@@ -92663,47 +91032,39 @@ class RenderLayerState {
92663
91032
  */
92664
91033
 
92665
91034
  class RenderLayer {
92666
- constructor() {
92667
- /**
92668
- * @deprecated
92669
- * @type {BinaryNode}
92670
- */
92671
- this.bvh = new BinaryNode();
92672
- this.bvh.setNegativelyInfiniteBounds();
92673
91035
 
92674
- /**
92675
- *
92676
- * @type {RenderLayerState}
92677
- */
92678
- this.state = new RenderLayerState();
91036
+ /**
91037
+ *
91038
+ * @type {RenderLayerState}
91039
+ */
91040
+ state = new RenderLayerState();
92679
91041
 
92680
- /**
92681
- *
92682
- * @type {String|null}
92683
- */
92684
- this.name = null;
91042
+ /**
91043
+ *
91044
+ * @type {String|null}
91045
+ */
91046
+ name = null;
92685
91047
 
92686
- /**
92687
- * Layer is managed externally, visibility will not be updated in the rendering engine
92688
- * @deprecated
92689
- * @type {boolean}
92690
- */
92691
- this.managed = false;
91048
+ /**
91049
+ * Layer is managed externally, visibility will not be updated in the rendering engine
91050
+ * @deprecated
91051
+ * @type {boolean}
91052
+ */
91053
+ managed = false;
92692
91054
 
92693
- /**
92694
- *
92695
- * @type {function(*): Object3D}
92696
- */
92697
- this.extractRenderable = passThrough$1;
91055
+ /**
91056
+ *
91057
+ * @type {function(*): Object3D}
91058
+ */
91059
+ extractRenderable = passThrough$1;
92698
91060
 
92699
- /**
92700
- * @deprecated use CameraView's visible set instead
92701
- * Contains visible elements across all views, if element is in at least one view - it will be here
92702
- * @deprecated
92703
- * @type {IncrementalDeltaSet<THREE.Object3D>}
92704
- */
92705
- this.visibleSet = new IncrementalDeltaSet(compare_three_objects);
92706
- }
91061
+ /**
91062
+ * @deprecated use CameraView's visible set instead
91063
+ * Contains visible elements across all views, if element is in at least one view - it will be here
91064
+ * @deprecated
91065
+ * @type {IncrementalDeltaSet<THREE.Object3D>}
91066
+ */
91067
+ visibleSet = new IncrementalDeltaSet(compare_three_objects);
92707
91068
 
92708
91069
  /**
92709
91070
  * @deprecated
@@ -92736,7 +91097,7 @@ class RenderLayer {
92736
91097
  }
92737
91098
 
92738
91099
  /**
92739
- @deprecated
91100
+ * @deprecated
92740
91101
  * @param {THREE.Object3D[]} destination
92741
91102
  * @param {number} destination_offset
92742
91103
  * @param {CameraView} view
@@ -93858,13 +92219,6 @@ class GraphicsEngine {
93858
92219
  */
93859
92220
  this.layers = new RenderLayerManager();
93860
92221
 
93861
- /**
93862
- *
93863
- * @type {BinaryNode}
93864
- */
93865
- this.bvh = new BinaryNode();
93866
- this.bvh.setNegativelyInfiniteBounds();
93867
-
93868
92222
  //renderer setup
93869
92223
  const scene = new Scene$1();
93870
92224
  //prevent automatic updates to all descendants of the scene, such updates are very wasteful
@@ -104893,6 +103247,24 @@ class TooltipManager {
104893
103247
 
104894
103248
  }
104895
103249
 
103250
+ /**
103251
+ * Returns true if two 1D lines intersect, touch is treated as intersection
103252
+ * Parameters are assumed to be ordered, a1 >= a0, b1 >= b0
103253
+ * @param {Number} a0
103254
+ * @param {Number} a1
103255
+ * @param {Number} b0
103256
+ * @param {Number} b1
103257
+ * @returns {boolean}
103258
+ */
103259
+ function intersects1D(a0, a1, b0, b1) {
103260
+ assert.isNumber(a0, "a0");
103261
+ assert.isNumber(a1, "a1");
103262
+ assert.isNumber(b0, "b0");
103263
+ assert.isNumber(b1, "b1");
103264
+
103265
+ return a1 >= b0 && b1 >= a0;
103266
+ }
103267
+
104896
103268
  /**
104897
103269
  * Created by Alex on 14/03/2016.
104898
103270
  */