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