@woosh/meep-engine 2.61.0 → 2.63.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/build/meep.cjs +1277 -1259
  2. package/build/meep.min.js +1 -1
  3. package/build/meep.module.js +1277 -1259
  4. package/package.json +1 -1
  5. package/src/core/binary/EncodingBinaryBuffer.js +7 -43
  6. package/src/core/binary/EncodingBinaryBuffer.spec.js +16 -0
  7. package/src/core/bvh2/BinaryNode.js +16 -13
  8. package/src/core/bvh2/LeafNode.js +6 -3
  9. package/src/core/bvh2/bvh3/EBBVHLeafProxy.js +4 -2
  10. package/src/core/bvh2/bvh3/query/bvh_query_user_data_overlaps_sphere.js +81 -0
  11. package/src/core/cache/LoadingCache.js +4 -1
  12. package/src/core/collection/map/BiMap.js +49 -0
  13. package/src/core/geom/3d/aabb/AABB3.js +24 -36
  14. package/src/core/geom/3d/aabb/aabb3_array_compute_from_sphere.js +22 -0
  15. package/src/core/geom/3d/aabb/aabb3_array_intersects_sphere.js +22 -0
  16. package/src/core/geom/3d/aabb/aabb3_array_intersects_sphere_array.js +11 -0
  17. package/src/core/geom/3d/aabb/aabb3_signed_distance_to_aabb3.js +28 -0
  18. package/src/core/geom/3d/aabb/serializeAABB3Quantized16Uint.js +19 -10
  19. package/src/core/geom/3d/tetrahedra/delaunay/Cavity.js +3 -4
  20. package/src/engine/ecs/components/Tag.d.ts +2 -0
  21. package/src/engine/ecs/components/Tag.js +19 -28
  22. package/src/engine/ecs/components/Tag.spec.js +47 -0
  23. package/src/engine/ecs/foliage/ecs/Foliage2System.js +3 -0
  24. package/src/engine/ecs/foliage/ecs/InstancedMeshComponent.js +4 -1
  25. package/src/engine/ecs/foliage/ecs/convertInstancedMeshComponents2Entities.js +64 -0
  26. package/src/engine/ecs/foliage/ecs/{InstancedMeshUtils.js → optimizeIndividualMeshesEntitiesToInstances.js} +11 -70
  27. package/src/engine/ecs/fow/FogOfWar.js +4 -0
  28. package/src/engine/ecs/fow/FogOfWarEditor.js +3 -0
  29. package/src/engine/ecs/terrain/TerrainPreview.js +45 -44
  30. package/src/engine/ecs/terrain/ecs/cling/ClingToTerrain.js +22 -4
  31. package/src/engine/ecs/terrain/tiles/TerrainTile.js +17 -12
  32. package/src/engine/graphics/camera/testClippingPlaneComputation.js +25 -27
  33. package/src/engine/graphics/ecs/mesh/Mesh.d.ts +0 -4
  34. package/src/engine/graphics/ecs/mesh/Mesh.js +0 -11
  35. package/src/engine/graphics/ecs/mesh/MeshSystem.js +57 -67
  36. package/src/engine/graphics/ecs/path/testPathDisplaySystem.js +49 -52
  37. package/src/engine/graphics/ecs/path/tube/prototypeAnimatedPathMask.js +40 -42
  38. package/src/engine/graphics/particles/ecs/ParticleEmitterSystem.js +43 -25
  39. package/src/engine/graphics/particles/particular/engine/ParticularEngine.js +10 -6
  40. package/src/engine/graphics/particles/particular/engine/emitter/ParticleEmitter.js +37 -41
  41. package/src/engine/graphics/particles/particular/engine/utils/volume/prototypeParticleVolume.js +44 -46
  42. package/src/engine/graphics/render/buffer/buffers/prototypeNormalFrameBuffer.js +24 -26
  43. package/src/engine/graphics/render/forward_plus/plugin/ptototypeFPPlugin.js +40 -42
  44. package/src/engine/graphics/render/visibility/hiz/prototypeHiZ.js +36 -38
  45. package/src/engine/graphics/shadows/testShadowMapRendering.js +19 -19
  46. package/src/engine/grid/ORTHOGONAL_NEIGHBOURHOOD_MASK.js +11 -0
  47. package/src/engine/sound/dB2Volume.js +8 -0
  48. package/src/engine/sound/ecs/emitter/SoundEmitter.js +125 -99
  49. package/src/engine/sound/ecs/emitter/SoundEmitterComponentContext.js +4 -42
  50. package/src/engine/sound/ecs/emitter/SoundEmitterSystem.js +31 -121
  51. package/src/engine/sound/volume2dB.js +8 -0
  52. package/src/generation/theme/ThemeEngine.js +19 -53
  53. package/src/core/binary/stringToByteArray.js +0 -24
  54. package/src/engine/graphics/geometry/bvh/buffered/BVHFromBufferGeometry.js +0 -133
  55. package/src/engine/save/storage/LocalStorage.js +0 -148
  56. package/src/engine/save/storage/MsgPackCodec.js +0 -22
@@ -49814,6 +49814,95 @@ function array_quick_sort_by_comparator(
49814
49814
  }
49815
49815
  }
49816
49816
 
49817
+ /**
49818
+ *
49819
+ * @param {number} x0
49820
+ * @param {number} y0
49821
+ * @param {number} z0
49822
+ * @param {number} x1
49823
+ * @param {number} y1
49824
+ * @param {number} z1
49825
+ * @returns {number}
49826
+ */
49827
+ function aabb3_compute_half_surface_area(x0, y0, z0, x1, y1, z1) {
49828
+ const dx = x1 - x0;
49829
+ const dy = y1 - y0;
49830
+ const dz = z1 - z0;
49831
+ return dy * (dx + dz) + dz * dx; //1 side, since it's a heuristic only
49832
+ }
49833
+
49834
+ /**
49835
+ *
49836
+ * @param {AABB3} node
49837
+ * @returns {number}
49838
+ */
49839
+ function aabb3_box_surface_area_2(node) {
49840
+ return aabb3_compute_half_surface_area(node.x0, node.y0, node.z0, node.x1, node.y1, node.z1);
49841
+ }
49842
+
49843
+ /**
49844
+ *
49845
+ * @param {AABB3} a
49846
+ * @param {AABB3} b
49847
+ * @returns {number}
49848
+ */
49849
+ function aabb3_combined_surface_area(a, b) {
49850
+ const x0 = min2(a.x0, b.x0);
49851
+ const y0 = min2(a.y0, b.y0);
49852
+ const z0 = min2(a.z0, b.z0);
49853
+
49854
+ const x1 = max2(a.x1, b.x1);
49855
+ const y1 = max2(a.y1, b.y1);
49856
+ const z1 = max2(a.z1, b.z1);
49857
+
49858
+ return aabb3_compute_half_surface_area(x0, y0, z0, x1, y1, z1);
49859
+ }
49860
+
49861
+ /**
49862
+ * Returns true if two 1D lines intersect, touch is treated as intersection
49863
+ * Parameters are assumed to be ordered, a1 >= a0, b1 >= b0
49864
+ * @param {Number} a0
49865
+ * @param {Number} a1
49866
+ * @param {Number} b0
49867
+ * @param {Number} b1
49868
+ * @returns {boolean}
49869
+ */
49870
+ function intersects1D(a0, a1, b0, b1) {
49871
+ assert.isNumber(a0, "a0");
49872
+ assert.isNumber(a1, "a1");
49873
+ assert.isNumber(b0, "b0");
49874
+ assert.isNumber(b1, "b1");
49875
+
49876
+ return a1 >= b0 && b1 >= a0;
49877
+ }
49878
+
49879
+ /**
49880
+ *
49881
+ * @param {number} ax0
49882
+ * @param {number} ay0
49883
+ * @param {number} az0
49884
+ * @param {number} ax1
49885
+ * @param {number} ay1
49886
+ * @param {number} az1
49887
+ * @param {number} bx0
49888
+ * @param {number} by0
49889
+ * @param {number} bz0
49890
+ * @param {number} bx1
49891
+ * @param {number} by1
49892
+ * @param {number} bz1
49893
+ * @returns {boolean}
49894
+ */
49895
+ function aabb3_intersects_aabb3(
49896
+ ax0, ay0, az0,
49897
+ ax1, ay1, az1,
49898
+ bx0, by0, bz0,
49899
+ bx1, by1, bz1
49900
+ ) {
49901
+ return intersects1D(ax0, ax1, bx0, bx1)
49902
+ && intersects1D(ay0, ay1, by0, by1)
49903
+ && intersects1D(az0, az1, bz0, bz1);
49904
+ }
49905
+
49817
49906
  /**
49818
49907
  *
49819
49908
  * @param {number[]} values
@@ -49900,6 +49989,73 @@ function mortonEncode_magicbits(x, y, z) {
49900
49989
  return x_bits | y_bits | z_bits;
49901
49990
  }
49902
49991
 
49992
+ //
49993
+
49994
+ /**
49995
+ *
49996
+ * @param {ArrayLike<number>|number[]|AABB3} aabb
49997
+ * @param {number} x
49998
+ * @param {number} y
49999
+ * @param {number} z
50000
+ * @return {boolean}
50001
+ */
50002
+ function aabb3_array_intersects_point(
50003
+ aabb,
50004
+ x, y, z
50005
+ ) {
50006
+ return x >= aabb[0]
50007
+ && x <= aabb[3]
50008
+ && y >= aabb[1]
50009
+ && y <= aabb[4]
50010
+ && z >= aabb[2]
50011
+ && z <= aabb[5];
50012
+ }
50013
+
50014
+ /**
50015
+ *
50016
+ * @param {number[]|Float32Array|Float64Array} destination
50017
+ * @param {number} destination_offset
50018
+ * @param {number} x0
50019
+ * @param {number} y0
50020
+ * @param {number} z0
50021
+ * @param {number} x1
50022
+ * @param {number} y1
50023
+ * @param {number} z1
50024
+ */
50025
+ function aabb3_build_corners(destination, destination_offset, x0, y0, z0, x1, y1, z1) {
50026
+ destination[destination_offset] = x0;
50027
+ destination[destination_offset + 1] = y0;
50028
+ destination[destination_offset + 2] = z0;
50029
+
50030
+ destination[destination_offset + 3] = x1;
50031
+ destination[destination_offset + 4] = y0;
50032
+ destination[destination_offset + 5] = z0;
50033
+
50034
+ destination[destination_offset + 6] = x0;
50035
+ destination[destination_offset + 7] = y1;
50036
+ destination[destination_offset + 8] = z0;
50037
+
50038
+ destination[destination_offset + 9] = x1;
50039
+ destination[destination_offset + 10] = y1;
50040
+ destination[destination_offset + 11] = z0;
50041
+
50042
+ destination[destination_offset + 12] = x0;
50043
+ destination[destination_offset + 13] = y0;
50044
+ destination[destination_offset + 14] = z1;
50045
+
50046
+ destination[destination_offset + 15] = x1;
50047
+ destination[destination_offset + 16] = y0;
50048
+ destination[destination_offset + 17] = z1;
50049
+
50050
+ destination[destination_offset + 18] = x0;
50051
+ destination[destination_offset + 19] = y1;
50052
+ destination[destination_offset + 20] = z1;
50053
+
50054
+ destination[destination_offset + 21] = x1;
50055
+ destination[destination_offset + 22] = y1;
50056
+ destination[destination_offset + 23] = z1;
50057
+ }
50058
+
49903
50059
  /**
49904
50060
  * Distance of the farthest point along the plane normal from the plane. If the result is >= 0, at least a portion of AABB pokes above the plane
49905
50061
  * @param {number} plane_normal_x
@@ -50014,47 +50170,53 @@ function aabb3_compute_plane_side(
50014
50170
 
50015
50171
  /**
50016
50172
  *
50017
- * @param {number[]|Float32Array|Float64Array} destination
50018
- * @param {number} destination_offset
50019
50173
  * @param {number} x0
50020
50174
  * @param {number} y0
50021
50175
  * @param {number} z0
50022
50176
  * @param {number} x1
50023
50177
  * @param {number} y1
50024
50178
  * @param {number} z1
50179
+ * @returns {number}
50025
50180
  */
50026
- function aabb3_build_corners(destination, destination_offset, x0, y0, z0, x1, y1, z1) {
50027
- destination[destination_offset] = x0;
50028
- destination[destination_offset + 1] = y0;
50029
- destination[destination_offset + 2] = z0;
50030
-
50031
- destination[destination_offset + 3] = x1;
50032
- destination[destination_offset + 4] = y0;
50033
- destination[destination_offset + 5] = z0;
50034
-
50035
- destination[destination_offset + 6] = x0;
50036
- destination[destination_offset + 7] = y1;
50037
- destination[destination_offset + 8] = z0;
50181
+ function aabb3_compute_surface_area(x0, y0, z0, x1, y1, z1) {
50182
+ const dx = x1 - x0;
50183
+ const dy = y1 - y0;
50184
+ const dz = z1 - z0;
50185
+ return (dy * (dx + dz) + dz * dx) * 2; //2 of each side
50186
+ }
50187
+
50188
+ /**
50189
+ *
50190
+ * @param {number} x0
50191
+ * @param {number} y0
50192
+ * @param {number} z0
50193
+ * @param {number} x1
50194
+ * @param {number} y1
50195
+ * @param {number} z1
50196
+ * @param {ArrayLike<number>|number[]|Float32Array|Float64Array} frustum
50197
+ * @return {boolean}
50198
+ */
50199
+ function aabb3_intersects_frustum_array(x0, y0, z0, x1, y1, z1, frustum) {
50200
+ for (let i = 0; i < 24; i += 4) {
50038
50201
 
50039
- destination[destination_offset + 9] = x1;
50040
- destination[destination_offset + 10] = y1;
50041
- destination[destination_offset + 11] = z0;
50202
+ const plane_x = frustum[i];
50203
+ const plane_y = frustum[i + 1];
50204
+ const plane_z = frustum[i + 2];
50205
+ const plane_w = frustum[i + 3];
50042
50206
 
50043
- destination[destination_offset + 12] = x0;
50044
- destination[destination_offset + 13] = y0;
50045
- destination[destination_offset + 14] = z1;
50207
+ const plane_distance = aabb3_compute_distance_above_plane_max(
50208
+ plane_x, plane_y, plane_z, plane_w,
50209
+ x0, y0, z0,
50210
+ x1, y1, z1
50211
+ );
50046
50212
 
50047
- destination[destination_offset + 15] = x1;
50048
- destination[destination_offset + 16] = y0;
50049
- destination[destination_offset + 17] = z1;
50213
+ if (plane_distance < 0) {
50214
+ return false;
50215
+ }
50050
50216
 
50051
- destination[destination_offset + 18] = x0;
50052
- destination[destination_offset + 19] = y1;
50053
- destination[destination_offset + 20] = z1;
50217
+ }
50054
50218
 
50055
- destination[destination_offset + 21] = x1;
50056
- destination[destination_offset + 22] = y1;
50057
- destination[destination_offset + 23] = z1;
50219
+ return true;
50058
50220
  }
50059
50221
 
50060
50222
  //
@@ -50274,57 +50436,6 @@ function aabb3_intersects_ray(
50274
50436
  return f2 <= extents_x * abs_direction_y + extents_y * abs_direction_x;
50275
50437
  }
50276
50438
 
50277
- /**
50278
- *
50279
- * @param {number} x0
50280
- * @param {number} y0
50281
- * @param {number} z0
50282
- * @param {number} x1
50283
- * @param {number} y1
50284
- * @param {number} z1
50285
- * @returns {number}
50286
- */
50287
- function aabb3_compute_surface_area(x0, y0, z0, x1, y1, z1) {
50288
- const dx = x1 - x0;
50289
- const dy = y1 - y0;
50290
- const dz = z1 - z0;
50291
- return (dy * (dx + dz) + dz * dx) * 2; //2 of each side
50292
- }
50293
-
50294
- /**
50295
- *
50296
- * @param {number} x0
50297
- * @param {number} y0
50298
- * @param {number} z0
50299
- * @param {number} x1
50300
- * @param {number} y1
50301
- * @param {number} z1
50302
- * @param {ArrayLike<number>|number[]|Float32Array|Float64Array} frustum
50303
- * @return {boolean}
50304
- */
50305
- function aabb3_intersects_frustum_array(x0, y0, z0, x1, y1, z1, frustum) {
50306
- for (let i = 0; i < 24; i += 4) {
50307
-
50308
- const plane_x = frustum[i];
50309
- const plane_y = frustum[i + 1];
50310
- const plane_z = frustum[i + 2];
50311
- const plane_w = frustum[i + 3];
50312
-
50313
- const plane_distance = aabb3_compute_distance_above_plane_max(
50314
- plane_x, plane_y, plane_z, plane_w,
50315
- x0, y0, z0,
50316
- x1, y1, z1
50317
- );
50318
-
50319
- if (plane_distance < 0) {
50320
- return false;
50321
- }
50322
-
50323
- }
50324
-
50325
- return true;
50326
- }
50327
-
50328
50439
  /**
50329
50440
  * NOTE: Based on Transforming Axis-Aligned Bounding Boxes by Jim Arvo from "Graphics Gems", Academic Press, 1990
50330
50441
  * NOTE: {@link result} and {@link aabb} must be different objects
@@ -50407,26 +50518,33 @@ function aabb3_signed_distance_sqr_to_point(
50407
50518
  }
50408
50519
  }
50409
50520
 
50410
- //
50521
+ function aabb3_signed_distance_to_aabb3(
50522
+ ax0,ay0,az0,ax1,ay1,az1,
50523
+ bx0,by0,bz0, bx1,by1,bz1
50524
+ ){
50411
50525
 
50412
- /**
50413
- *
50414
- * @param {ArrayLike<number>|number[]|AABB3} aabb
50415
- * @param {number} x
50416
- * @param {number} y
50417
- * @param {number} z
50418
- * @return {boolean}
50419
- */
50420
- function aabb3_array_intersects_point(
50421
- aabb,
50422
- x, y, z
50423
- ) {
50424
- return x >= aabb[0]
50425
- && x <= aabb[3]
50426
- && y >= aabb[1]
50427
- && y <= aabb[4]
50428
- && z >= aabb[2]
50429
- && z <= aabb[5];
50526
+ //do projection
50527
+ const xp0 = bx0 - ax1;
50528
+ const xp1 = ax0 - bx1;
50529
+ const yp0 = by0 - ay1;
50530
+ const yp1 = ay0 - by1;
50531
+ const zp0 = bz0 - az1;
50532
+ const zp1 = az0 - bz1;
50533
+
50534
+ //calculate separation in each axis
50535
+ const dx = Math.max(xp0, xp1);
50536
+ const dy = Math.max(yp0, yp1);
50537
+ const dz = Math.max(zp0, zp1);
50538
+
50539
+ //straight-line distance
50540
+ let distance = Math.sqrt(dx * dx + dy * dy + dz * dz);
50541
+
50542
+ if (dx < 0 && dy < 0 && dz < 0) {
50543
+ //penetration
50544
+ return -distance;
50545
+ } else {
50546
+ return distance;
50547
+ }
50430
50548
  }
50431
50549
 
50432
50550
  /**
@@ -50435,6 +50553,7 @@ function aabb3_array_intersects_point(
50435
50553
 
50436
50554
  /**
50437
50555
  * Axis-Aligned bounding box in 3D
50556
+ * NOTE: In cases where all you want is raw performance - prefer to use typed arrays instead along with `aabb3_` functions
50438
50557
  */
50439
50558
  class AABB3 {
50440
50559
  /**
@@ -50654,7 +50773,12 @@ class AABB3 {
50654
50773
  * @returns {boolean}
50655
50774
  */
50656
50775
  _equals(x0, y0, z0, x1, y1, z1) {
50657
- return this.x0 === x0 && this.y0 === y0 && this.z0 === z0 && this.x1 === x1 && this.y1 === y1 && this.z1 === z1;
50776
+ return this.x0 === x0
50777
+ && this.y0 === y0
50778
+ && this.z0 === z0
50779
+ && this.x1 === x1
50780
+ && this.y1 === y1
50781
+ && this.z1 === z1;
50658
50782
  }
50659
50783
 
50660
50784
  /**
@@ -50748,28 +50872,10 @@ class AABB3 {
50748
50872
  const _y1 = this.y1;
50749
50873
  const _z1 = this.z1;
50750
50874
 
50751
- //do projection
50752
- const xp0 = _x0 - x1;
50753
- const xp1 = x0 - _x1;
50754
- const yp0 = _y0 - y1;
50755
- const yp1 = y0 - _y1;
50756
- const zp0 = _z0 - z1;
50757
- const zp1 = z0 - _z1;
50758
-
50759
- //calculate separation in each axis
50760
- const dx = Math.max(xp0, xp1);
50761
- const dy = Math.max(yp0, yp1);
50762
- const dz = Math.max(zp0, zp1);
50763
-
50764
- //straight-line distance
50765
- let distance = Math.sqrt(dx * dx + dy * dy + dz * dz);
50766
-
50767
- if (dx < 0 && dy < 0 && dz < 0) {
50768
- //penetration
50769
- return -distance;
50770
- } else {
50771
- return distance;
50772
- }
50875
+ return aabb3_signed_distance_to_aabb3(
50876
+ _x0, _y0, _z0, _x1, _y1, _z1,
50877
+ x0, y0, z0, x1, y1, z1
50878
+ );
50773
50879
  }
50774
50880
 
50775
50881
  /**
@@ -51194,7 +51300,6 @@ class AABB3 {
51194
51300
  }
51195
51301
 
51196
51302
  /**
51197
- *
51198
51303
  * @param {Plane[]} clippingPlanes
51199
51304
  * @returns {boolean}
51200
51305
  */
@@ -51489,6 +51594,9 @@ function isLeaf(node) {
51489
51594
  return node.isLeafNode;
51490
51595
  }
51491
51596
 
51597
+ /**
51598
+ * @deprecated use {@link ExplicitBinaryBoundingVolumeHierarchy} and {@link EBBVHLeafProxy} respectively
51599
+ */
51492
51600
  class LeafNode extends Node {
51493
51601
  /**
51494
51602
  *
@@ -51699,95 +51807,6 @@ function traverseBinaryNodeUsingVisitor(node, visitor) {
51699
51807
  stackPointer$3 = stackOffset;
51700
51808
  }
51701
51809
 
51702
- /**
51703
- * Returns true if two 1D lines intersect, touch is treated as intersection
51704
- * Parameters are assumed to be ordered, a1 >= a0, b1 >= b0
51705
- * @param {Number} a0
51706
- * @param {Number} a1
51707
- * @param {Number} b0
51708
- * @param {Number} b1
51709
- * @returns {boolean}
51710
- */
51711
- function intersects1D(a0, a1, b0, b1) {
51712
- assert.isNumber(a0, "a0");
51713
- assert.isNumber(a1, "a1");
51714
- assert.isNumber(b0, "b0");
51715
- assert.isNumber(b1, "b1");
51716
-
51717
- return a1 >= b0 && b1 >= a0;
51718
- }
51719
-
51720
- /**
51721
- *
51722
- * @param {number} ax0
51723
- * @param {number} ay0
51724
- * @param {number} az0
51725
- * @param {number} ax1
51726
- * @param {number} ay1
51727
- * @param {number} az1
51728
- * @param {number} bx0
51729
- * @param {number} by0
51730
- * @param {number} bz0
51731
- * @param {number} bx1
51732
- * @param {number} by1
51733
- * @param {number} bz1
51734
- * @returns {boolean}
51735
- */
51736
- function aabb3_intersects_aabb3(
51737
- ax0, ay0, az0,
51738
- ax1, ay1, az1,
51739
- bx0, by0, bz0,
51740
- bx1, by1, bz1
51741
- ) {
51742
- return intersects1D(ax0, ax1, bx0, bx1)
51743
- && intersects1D(ay0, ay1, by0, by1)
51744
- && intersects1D(az0, az1, bz0, bz1);
51745
- }
51746
-
51747
- /**
51748
- *
51749
- * @param {number} x0
51750
- * @param {number} y0
51751
- * @param {number} z0
51752
- * @param {number} x1
51753
- * @param {number} y1
51754
- * @param {number} z1
51755
- * @returns {number}
51756
- */
51757
- function aabb3_compute_half_surface_area(x0, y0, z0, x1, y1, z1) {
51758
- const dx = x1 - x0;
51759
- const dy = y1 - y0;
51760
- const dz = z1 - z0;
51761
- return dy * (dx + dz) + dz * dx; //1 side, since it's a heuristic only
51762
- }
51763
-
51764
- /**
51765
- *
51766
- * @param {AABB3} node
51767
- * @returns {number}
51768
- */
51769
- function aabb3_box_surface_area_2(node) {
51770
- return aabb3_compute_half_surface_area(node.x0, node.y0, node.z0, node.x1, node.y1, node.z1);
51771
- }
51772
-
51773
- /**
51774
- *
51775
- * @param {AABB3} a
51776
- * @param {AABB3} b
51777
- * @returns {number}
51778
- */
51779
- function aabb3_combined_surface_area(a, b) {
51780
- const x0 = min2(a.x0, b.x0);
51781
- const y0 = min2(a.y0, b.y0);
51782
- const z0 = min2(a.z0, b.z0);
51783
-
51784
- const x1 = max2(a.x1, b.x1);
51785
- const y1 = max2(a.y1, b.y1);
51786
- const z1 = max2(a.z1, b.z1);
51787
-
51788
- return aabb3_compute_half_surface_area(x0, y0, z0, x1, y1, z1);
51789
- }
51790
-
51791
51810
  /**
51792
51811
  * Created by Alex on 17/11/2014.
51793
51812
  */
@@ -51811,6 +51830,9 @@ let stackPointer$2 = 0;
51811
51830
  */
51812
51831
  const stack$9 = [];
51813
51832
 
51833
+ /**
51834
+ * @deprecated use {@link ExplicitBinaryBoundingVolumeHierarchy} instead
51835
+ */
51814
51836
  class BinaryNode extends Node {
51815
51837
  constructor() {
51816
51838
  super();
@@ -55566,79 +55588,314 @@ ObservedValue.prototype.fromJSON = function (value) {
55566
55588
  this.set(value);
55567
55589
  };
55568
55590
 
55569
- /**
55570
- * Created by Alex on 28/01/2017.
55571
- */
55572
-
55573
- function prepareObject(object) {
55574
- //turn off automatic matrix re-calculations each frame
55575
- object.matrixAutoUpdate = false;
55576
- //disable frustum culling
55577
- object.frustumCulled = false;
55578
- }
55579
-
55580
- /**
55581
- *
55582
- * @param {BufferGeometry} [geometry]
55583
- * @param {Material} [material]
55584
- * @returns {Mesh}
55585
- */
55586
- function createMesh(geometry, material) {
55587
- const result = new Mesh(geometry, material);
55588
-
55589
- prepareObject(result);
55590
-
55591
- return result;
55592
- }
55593
-
55594
- /**
55595
- *
55596
- * @param {BufferGeometry} geometry
55597
- * @param {THREE.Material} material
55598
- * @returns {THREE.SkinnedMesh}
55599
- */
55600
- function createSkinnedMesh(geometry, material) {
55601
- const result = new SkinnedMesh(geometry, material);
55602
-
55603
- prepareObject(result);
55604
-
55605
- return result;
55606
- }
55607
-
55608
- /**
55609
- *
55610
- * @param {Material} material
55611
- */
55612
- function prepareMaterial(material) {
55613
-
55614
- //make shadows render from front side, this avoids artifacts due to gaps in geometry that can't be seen from the front
55615
- material.shadowSide = DoubleSide;
55616
-
55617
- if (typeof material.envMapIntensity === 'number' && material.envMapIntensity !== 1) {
55618
- // make material react to environment map in the same way as others
55619
- material.envMapIntensity = 1;
55620
- }
55621
- }
55622
-
55623
- /**
55624
- *
55625
- * @returns {Group}
55626
- */
55627
- function createGroup() {
55628
- const result = new Group();
55629
-
55630
- prepareObject(result);
55631
-
55632
- return result;
55633
- }
55634
-
55635
- var ThreeFactory = {
55636
- createMesh,
55637
- createSkinnedMesh,
55638
- createGroup,
55639
- prepareMaterial
55591
+ /**
55592
+ * Common utilities
55593
+ * @module glMatrix
55594
+ */
55595
+ var ARRAY_TYPE = typeof Float32Array !== 'undefined' ? Float32Array : Array;
55596
+ if (!Math.hypot) Math.hypot = function () {
55597
+ var y = 0,
55598
+ i = arguments.length;
55599
+
55600
+ while (i--) {
55601
+ y += arguments[i] * arguments[i];
55602
+ }
55603
+
55604
+ return Math.sqrt(y);
55640
55605
  };
55641
55606
 
55607
+ /**
55608
+ * 4x4 Matrix<br>Format: column-major, when typed out it looks like row-major<br>The matrices are being post multiplied.
55609
+ * @module mat4
55610
+ */
55611
+
55612
+ /**
55613
+ * Creates a new identity mat4
55614
+ *
55615
+ * @returns {mat4} a new 4x4 matrix
55616
+ */
55617
+
55618
+ function create$1() {
55619
+ var out = new ARRAY_TYPE(16);
55620
+
55621
+ if (ARRAY_TYPE != Float32Array) {
55622
+ out[1] = 0;
55623
+ out[2] = 0;
55624
+ out[3] = 0;
55625
+ out[4] = 0;
55626
+ out[6] = 0;
55627
+ out[7] = 0;
55628
+ out[8] = 0;
55629
+ out[9] = 0;
55630
+ out[11] = 0;
55631
+ out[12] = 0;
55632
+ out[13] = 0;
55633
+ out[14] = 0;
55634
+ }
55635
+
55636
+ out[0] = 1;
55637
+ out[5] = 1;
55638
+ out[10] = 1;
55639
+ out[15] = 1;
55640
+ return out;
55641
+ }
55642
+ /**
55643
+ * Copy the values from one mat4 to another
55644
+ *
55645
+ * @param {mat4} out the receiving matrix
55646
+ * @param {ReadonlyMat4} a the source matrix
55647
+ * @returns {mat4} out
55648
+ */
55649
+
55650
+ function copy(out, a) {
55651
+ out[0] = a[0];
55652
+ out[1] = a[1];
55653
+ out[2] = a[2];
55654
+ out[3] = a[3];
55655
+ out[4] = a[4];
55656
+ out[5] = a[5];
55657
+ out[6] = a[6];
55658
+ out[7] = a[7];
55659
+ out[8] = a[8];
55660
+ out[9] = a[9];
55661
+ out[10] = a[10];
55662
+ out[11] = a[11];
55663
+ out[12] = a[12];
55664
+ out[13] = a[13];
55665
+ out[14] = a[14];
55666
+ out[15] = a[15];
55667
+ return out;
55668
+ }
55669
+ /**
55670
+ * Inverts a mat4
55671
+ *
55672
+ * @param {mat4} out the receiving matrix
55673
+ * @param {ReadonlyMat4} a the source matrix
55674
+ * @returns {mat4} out
55675
+ */
55676
+
55677
+ function invert(out, a) {
55678
+ var a00 = a[0],
55679
+ a01 = a[1],
55680
+ a02 = a[2],
55681
+ a03 = a[3];
55682
+ var a10 = a[4],
55683
+ a11 = a[5],
55684
+ a12 = a[6],
55685
+ a13 = a[7];
55686
+ var a20 = a[8],
55687
+ a21 = a[9],
55688
+ a22 = a[10],
55689
+ a23 = a[11];
55690
+ var a30 = a[12],
55691
+ a31 = a[13],
55692
+ a32 = a[14],
55693
+ a33 = a[15];
55694
+ var b00 = a00 * a11 - a01 * a10;
55695
+ var b01 = a00 * a12 - a02 * a10;
55696
+ var b02 = a00 * a13 - a03 * a10;
55697
+ var b03 = a01 * a12 - a02 * a11;
55698
+ var b04 = a01 * a13 - a03 * a11;
55699
+ var b05 = a02 * a13 - a03 * a12;
55700
+ var b06 = a20 * a31 - a21 * a30;
55701
+ var b07 = a20 * a32 - a22 * a30;
55702
+ var b08 = a20 * a33 - a23 * a30;
55703
+ var b09 = a21 * a32 - a22 * a31;
55704
+ var b10 = a21 * a33 - a23 * a31;
55705
+ var b11 = a22 * a33 - a23 * a32; // Calculate the determinant
55706
+
55707
+ var det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
55708
+
55709
+ if (!det) {
55710
+ return null;
55711
+ }
55712
+
55713
+ det = 1.0 / det;
55714
+ out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det;
55715
+ out[1] = (a02 * b10 - a01 * b11 - a03 * b09) * det;
55716
+ out[2] = (a31 * b05 - a32 * b04 + a33 * b03) * det;
55717
+ out[3] = (a22 * b04 - a21 * b05 - a23 * b03) * det;
55718
+ out[4] = (a12 * b08 - a10 * b11 - a13 * b07) * det;
55719
+ out[5] = (a00 * b11 - a02 * b08 + a03 * b07) * det;
55720
+ out[6] = (a32 * b02 - a30 * b05 - a33 * b01) * det;
55721
+ out[7] = (a20 * b05 - a22 * b02 + a23 * b01) * det;
55722
+ out[8] = (a10 * b10 - a11 * b08 + a13 * b06) * det;
55723
+ out[9] = (a01 * b08 - a00 * b10 - a03 * b06) * det;
55724
+ out[10] = (a30 * b04 - a31 * b02 + a33 * b00) * det;
55725
+ out[11] = (a21 * b02 - a20 * b04 - a23 * b00) * det;
55726
+ out[12] = (a11 * b07 - a10 * b09 - a12 * b06) * det;
55727
+ out[13] = (a00 * b09 - a01 * b07 + a02 * b06) * det;
55728
+ out[14] = (a31 * b01 - a30 * b03 - a32 * b00) * det;
55729
+ out[15] = (a20 * b03 - a21 * b01 + a22 * b00) * det;
55730
+ return out;
55731
+ }
55732
+ /**
55733
+ * Multiplies two mat4s
55734
+ *
55735
+ * @param {mat4} out the receiving matrix
55736
+ * @param {ReadonlyMat4} a the first operand
55737
+ * @param {ReadonlyMat4} b the second operand
55738
+ * @returns {mat4} out
55739
+ */
55740
+
55741
+ function multiply(out, a, b) {
55742
+ var a00 = a[0],
55743
+ a01 = a[1],
55744
+ a02 = a[2],
55745
+ a03 = a[3];
55746
+ var a10 = a[4],
55747
+ a11 = a[5],
55748
+ a12 = a[6],
55749
+ a13 = a[7];
55750
+ var a20 = a[8],
55751
+ a21 = a[9],
55752
+ a22 = a[10],
55753
+ a23 = a[11];
55754
+ var a30 = a[12],
55755
+ a31 = a[13],
55756
+ a32 = a[14],
55757
+ a33 = a[15]; // Cache only the current line of the second matrix
55758
+
55759
+ var b0 = b[0],
55760
+ b1 = b[1],
55761
+ b2 = b[2],
55762
+ b3 = b[3];
55763
+ out[0] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
55764
+ out[1] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
55765
+ out[2] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
55766
+ out[3] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
55767
+ b0 = b[4];
55768
+ b1 = b[5];
55769
+ b2 = b[6];
55770
+ b3 = b[7];
55771
+ out[4] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
55772
+ out[5] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
55773
+ out[6] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
55774
+ out[7] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
55775
+ b0 = b[8];
55776
+ b1 = b[9];
55777
+ b2 = b[10];
55778
+ b3 = b[11];
55779
+ out[8] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
55780
+ out[9] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
55781
+ out[10] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
55782
+ out[11] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
55783
+ b0 = b[12];
55784
+ b1 = b[13];
55785
+ b2 = b[14];
55786
+ b3 = b[15];
55787
+ out[12] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
55788
+ out[13] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
55789
+ out[14] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
55790
+ out[15] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
55791
+ return out;
55792
+ }
55793
+
55794
+ /**
55795
+ * 3 Dimensional Vector
55796
+ * @module vec3
55797
+ */
55798
+
55799
+ /**
55800
+ * Creates a new, empty vec3
55801
+ *
55802
+ * @returns {vec3} a new 3D vector
55803
+ */
55804
+
55805
+ function create() {
55806
+ var out = new ARRAY_TYPE(3);
55807
+
55808
+ if (ARRAY_TYPE != Float32Array) {
55809
+ out[0] = 0;
55810
+ out[1] = 0;
55811
+ out[2] = 0;
55812
+ }
55813
+
55814
+ return out;
55815
+ }
55816
+ /**
55817
+ * Creates a new vec3 initialized with the given values
55818
+ *
55819
+ * @param {Number} x X component
55820
+ * @param {Number} y Y component
55821
+ * @param {Number} z Z component
55822
+ * @returns {vec3} a new 3D vector
55823
+ */
55824
+
55825
+ function fromValues(x, y, z) {
55826
+ var out = new ARRAY_TYPE(3);
55827
+ out[0] = x;
55828
+ out[1] = y;
55829
+ out[2] = z;
55830
+ return out;
55831
+ }
55832
+ /**
55833
+ * Transforms the vec3 with a mat4.
55834
+ * 4th vector component is implicitly '1'
55835
+ *
55836
+ * @param {vec3} out the receiving vector
55837
+ * @param {ReadonlyVec3} a the vector to transform
55838
+ * @param {ReadonlyMat4} m matrix to transform with
55839
+ * @returns {vec3} out
55840
+ */
55841
+
55842
+ function transformMat4(out, a, m) {
55843
+ var x = a[0],
55844
+ y = a[1],
55845
+ z = a[2];
55846
+ var w = m[3] * x + m[7] * y + m[11] * z + m[15];
55847
+ w = w || 1.0;
55848
+ out[0] = (m[0] * x + m[4] * y + m[8] * z + m[12]) / w;
55849
+ out[1] = (m[1] * x + m[5] * y + m[9] * z + m[13]) / w;
55850
+ out[2] = (m[2] * x + m[6] * y + m[10] * z + m[14]) / w;
55851
+ return out;
55852
+ }
55853
+ /**
55854
+ * Perform some operation over an array of vec3s.
55855
+ *
55856
+ * @param {Array} a the array of vectors to iterate over
55857
+ * @param {Number} stride Number of elements between the start of each vec3. If 0 assumes tightly packed
55858
+ * @param {Number} offset Number of elements to skip at the beginning of the array
55859
+ * @param {Number} count Number of vec3s to iterate over. If 0 iterates over entire array
55860
+ * @param {Function} fn Function to call for each vector in the array
55861
+ * @param {Object} [arg] additional argument to pass to fn
55862
+ * @returns {Array} a
55863
+ * @function
55864
+ */
55865
+
55866
+ (function () {
55867
+ var vec = create();
55868
+ return function (a, stride, offset, count, fn, arg) {
55869
+ var i, l;
55870
+
55871
+ if (!stride) {
55872
+ stride = 3;
55873
+ }
55874
+
55875
+ if (!offset) {
55876
+ offset = 0;
55877
+ }
55878
+
55879
+ if (count) {
55880
+ l = Math.min(count * stride + offset, a.length);
55881
+ } else {
55882
+ l = a.length;
55883
+ }
55884
+
55885
+ for (i = offset; i < l; i += stride) {
55886
+ vec[0] = a[i];
55887
+ vec[1] = a[i + 1];
55888
+ vec[2] = a[i + 2];
55889
+ fn(vec, vec, arg);
55890
+ a[i] = vec[0];
55891
+ a[i + 1] = vec[1];
55892
+ a[i + 2] = vec[2];
55893
+ }
55894
+
55895
+ return a;
55896
+ };
55897
+ })();
55898
+
55642
55899
  class IndexedBinaryBVHVisitor {
55643
55900
  /**
55644
55901
  *
@@ -56352,6 +56609,445 @@ class SurfacePoint3 {
56352
56609
  }
56353
56610
  }
56354
56611
 
56612
+ /**
56613
+ * Compute fraction of linear interpolation
56614
+ * @param {number} a
56615
+ * @param {number} b
56616
+ * @param {number} value
56617
+ * @returns {number} fraction
56618
+ */
56619
+ function inverseLerp(a, b, value) {
56620
+ const range = b - a;
56621
+ const scaledValue = value - a;
56622
+
56623
+ if (range === 0) {
56624
+
56625
+ // avoid division by zero error
56626
+
56627
+ // this is arbitrary output, as actual answer is undefined
56628
+
56629
+ return 0;
56630
+ }
56631
+
56632
+ return scaledValue / range;
56633
+ }
56634
+
56635
+ /**
56636
+ *
56637
+ * @param {number} min
56638
+ * @param {number} max
56639
+ * @constructor
56640
+ */
56641
+
56642
+ class NumericInterval {
56643
+ /**
56644
+ *
56645
+ * @param {number} [min=-Infinity]
56646
+ * @param {number} [max=Infinity]
56647
+ * @constructor
56648
+ */
56649
+ constructor(
56650
+ min = Number.NEGATIVE_INFINITY,
56651
+ max = Number.POSITIVE_INFINITY
56652
+ ) {
56653
+ assert.isNumber(min, 'min');
56654
+ assert.isNumber(max, 'max');
56655
+
56656
+ assert.ok(max >= min, `max=${max} must be >= than min=${min}`);
56657
+
56658
+ /**
56659
+ *
56660
+ * @type {number}
56661
+ */
56662
+ this.min = min;
56663
+ /**
56664
+ *
56665
+ * @type {number}
56666
+ */
56667
+ this.max = max;
56668
+
56669
+ this.onChanged = new Signal();
56670
+ }
56671
+
56672
+
56673
+ /**
56674
+ *
56675
+ * @param {number} min
56676
+ * @param {number} max
56677
+ */
56678
+ set(min, max) {
56679
+ assert.isNumber(min, 'min');
56680
+ assert.isNumber(max, 'max');
56681
+
56682
+ assert.notNaN(min, 'min');
56683
+ assert.notNaN(max, 'max');
56684
+
56685
+ assert.greaterThanOrEqual(max, min, `max [${max}] must be >= than min[${min}]`);
56686
+
56687
+ const oldMin = this.min;
56688
+ const oldMax = this.max;
56689
+
56690
+ if (min !== oldMin || max !== oldMax) {
56691
+ this.min = min;
56692
+ this.max = max;
56693
+
56694
+ if (this.onChanged.hasHandlers()) {
56695
+ this.onChanged.send4(min, max, oldMin, oldMax);
56696
+ }
56697
+ }
56698
+ }
56699
+
56700
+ /**
56701
+ *
56702
+ * @param {NumericInterval} other
56703
+ */
56704
+ copy(other) {
56705
+ this.set(other.min, other.max);
56706
+ }
56707
+
56708
+ /**
56709
+ *
56710
+ * @param {number} value
56711
+ */
56712
+ multiplyScalar(value) {
56713
+ const v0 = this.min * value;
56714
+ const v1 = this.max * value;
56715
+
56716
+ if (v0 > v1) {
56717
+ //probably negative scale
56718
+ this.set(v1, v0);
56719
+ } else {
56720
+
56721
+ this.set(v0, v1);
56722
+ }
56723
+ }
56724
+
56725
+ /**
56726
+ * Performs inverse linear interpolation on a given input
56727
+ * @param {number} v
56728
+ * @returns {number}
56729
+ */
56730
+ normalizeValue(v) {
56731
+ return inverseLerp(this.min, this.max, v);
56732
+ }
56733
+
56734
+ /**
56735
+ * Both min and max are exactly 0
56736
+ * @returns {boolean}
56737
+ */
56738
+ isZero() {
56739
+ return this.min === 0 && this.max === 0;
56740
+ }
56741
+
56742
+ /**
56743
+ * Whether min and max are the same
56744
+ * In other words if span is 0
56745
+ * @returns {boolean}
56746
+ */
56747
+ isExact() {
56748
+ return this.min === this.max;
56749
+ }
56750
+
56751
+ /**
56752
+ *
56753
+ * @returns {number}
56754
+ */
56755
+ computeAverage() {
56756
+ return (this.min + this.max) / 2;
56757
+ }
56758
+
56759
+ /**
56760
+ *
56761
+ * @param {function} random Random number generator function, must return values between 0 and 1
56762
+ * @returns {number}
56763
+ */
56764
+ sampleRandom(random) {
56765
+ assert.equal(typeof random, 'function', `random must be a function, instead was ${typeof random}`);
56766
+
56767
+ return this.min + random() * (this.max - this.min);
56768
+ }
56769
+
56770
+ fromJSON(json) {
56771
+ this.set(json.min, json.max);
56772
+ }
56773
+
56774
+ toJSON() {
56775
+ return {
56776
+ min: this.min,
56777
+ max: this.max
56778
+ };
56779
+ }
56780
+
56781
+ /**
56782
+ *
56783
+ * @param {BinaryBuffer} buffer
56784
+ */
56785
+ toBinaryBuffer(buffer) {
56786
+ buffer.writeFloat64(this.min);
56787
+ buffer.writeFloat64(this.max);
56788
+ }
56789
+
56790
+ /**
56791
+ *
56792
+ * @param {BinaryBuffer} buffer
56793
+ */
56794
+ fromBinaryBuffer(buffer) {
56795
+ this.min = buffer.readFloat64();
56796
+ this.max = buffer.readFloat64();
56797
+ }
56798
+
56799
+ /**
56800
+ *
56801
+ * @param {NumericInterval} other
56802
+ * @returns {boolean}
56803
+ */
56804
+ equals(other) {
56805
+ return this.min === other.min && this.max === other.max;
56806
+ }
56807
+
56808
+ /**
56809
+ *
56810
+ * @returns {number}
56811
+ */
56812
+ hash() {
56813
+ let hash = computeHashFloat(this.min);
56814
+
56815
+ hash = ((hash << 5) - hash) + computeHashFloat(this.max);
56816
+
56817
+ return hash;
56818
+ }
56819
+
56820
+ /**
56821
+ * Distance between min and max (= max - min)
56822
+ * @returns {number}
56823
+ */
56824
+ get span() {
56825
+ return this.max - this.min;
56826
+ }
56827
+ }
56828
+
56829
+ /**
56830
+ * @readonly
56831
+ * @type {boolean}
56832
+ */
56833
+ NumericInterval.prototype.isNumericInterval = true;
56834
+
56835
+ /**
56836
+ * @readonly
56837
+ * @type {NumericInterval}
56838
+ */
56839
+ NumericInterval.one_one = Object.freeze(new NumericInterval(1, 1));
56840
+ /**
56841
+ * @readonly
56842
+ * @type {NumericInterval}
56843
+ */
56844
+ NumericInterval.zero_zero = Object.freeze(new NumericInterval(0, 0));
56845
+
56846
+ class ObservedInteger extends Number {
56847
+ /**
56848
+ * @readonly
56849
+ * @type {Signal}
56850
+ */
56851
+ onChanged = new Signal();
56852
+
56853
+ /**
56854
+ *
56855
+ * @param {Number} [value]
56856
+ * @constructor
56857
+ */
56858
+ constructor(value = 0) {
56859
+ super();
56860
+
56861
+ assert.isNumber(value, 'value');
56862
+ assert.ok(Number.isInteger(value) || !Number.isFinite(value), `Value must be an integer, instead was ${value}`);
56863
+
56864
+
56865
+ /**
56866
+ *
56867
+ * @type {Number}
56868
+ * @private
56869
+ */
56870
+ this.__value = value;
56871
+
56872
+ }
56873
+
56874
+ /**
56875
+ *
56876
+ * @returns {Number}
56877
+ */
56878
+ valueOf() {
56879
+ return this.getValue();
56880
+ }
56881
+
56882
+ toString() {
56883
+ return this.getValue().toString();
56884
+ }
56885
+
56886
+ /**
56887
+ *
56888
+ * @param {Number} value
56889
+ * @returns {ObservedInteger}
56890
+ */
56891
+ set(value) {
56892
+ assert.isNumber(value, 'value');
56893
+ assert.ok(Number.isInteger(value) || !Number.isFinite(value), `Value must be an integer, instead was ${value}`);
56894
+
56895
+ const oldValue = this.__value;
56896
+ if (oldValue !== value) {
56897
+ this.__value = value;
56898
+ this.onChanged.send2(value, oldValue);
56899
+ }
56900
+
56901
+ return this;
56902
+ }
56903
+
56904
+ /**
56905
+ * Set value without dispatching change notification
56906
+ * @param {number} value
56907
+ */
56908
+ setSilent(value) {
56909
+ assert.isNumber(value, 'value');
56910
+ assert.ok(Number.isInteger(value) || !Number.isFinite(value), `Value must be an integer, instead was ${value}`);
56911
+
56912
+ this.__value = value;
56913
+ }
56914
+
56915
+ /**
56916
+ *
56917
+ * @return {boolean}
56918
+ */
56919
+ isZero() {
56920
+ return this.getValue() === 0;
56921
+ }
56922
+
56923
+ /**
56924
+ *
56925
+ * @param {ObservedInteger} other
56926
+ */
56927
+ subtract(other) {
56928
+ this._add(-other.getValue());
56929
+ }
56930
+
56931
+ /**
56932
+ *
56933
+ * @param {number} value
56934
+ */
56935
+ _subtract(value) {
56936
+ this.set(this.getValue() - value);
56937
+ }
56938
+
56939
+ /**
56940
+ *
56941
+ * @param {ObservedInteger} other
56942
+ */
56943
+ add(other) {
56944
+ this._add(other.getValue());
56945
+ }
56946
+
56947
+ /**
56948
+ *
56949
+ * @param {number} value
56950
+ */
56951
+ _add(value) {
56952
+ this.set(this.getValue() + value);
56953
+ }
56954
+
56955
+ /**
56956
+ * Increment the stored value by 1, same as adding 1
56957
+ */
56958
+ increment() {
56959
+ this.set(this.getValue() + 1);
56960
+ }
56961
+
56962
+ /**
56963
+ * Decrement the stored value by 1, same as subtracting 1
56964
+ */
56965
+ decrement() {
56966
+ this.set(this.getValue() - 1);
56967
+ }
56968
+
56969
+ /**
56970
+ *
56971
+ * @returns {Number}
56972
+ */
56973
+ getValue() {
56974
+ return this.__value;
56975
+ }
56976
+
56977
+ /**
56978
+ *
56979
+ * @param {ObservedInteger} other
56980
+ */
56981
+ copy(other) {
56982
+ this.set(other.__value);
56983
+ }
56984
+
56985
+ /**
56986
+ *
56987
+ * @param {ObservedInteger} other
56988
+ * @returns {boolean}
56989
+ */
56990
+ equals(other) {
56991
+ return this.__value === other.__value;
56992
+ }
56993
+
56994
+ /**
56995
+ *
56996
+ * @returns {Number}
56997
+ */
56998
+ hash() {
56999
+ return this.__value;
57000
+ }
57001
+
57002
+ toJSON() {
57003
+ return this.__value;
57004
+ }
57005
+
57006
+ fromJSON(obj) {
57007
+ this.set(obj);
57008
+ }
57009
+
57010
+ /**
57011
+ *
57012
+ * @param {BinaryBuffer} buffer
57013
+ */
57014
+ toBinaryBuffer(buffer) {
57015
+ const v = this.__value;
57016
+
57017
+ if (v === Infinity) {
57018
+ buffer.writeInt32(2147483647);
57019
+ } else if (v === -Infinity) {
57020
+ buffer.writeInt32(-2147483648);
57021
+ } else {
57022
+ //TODO it's possible to write encoded Infinity values by accident
57023
+ buffer.writeInt32(v);
57024
+ }
57025
+ }
57026
+
57027
+ /**
57028
+ *
57029
+ * @param {BinaryBuffer} buffer
57030
+ */
57031
+ fromBinaryBuffer(buffer) {
57032
+ const value = buffer.readInt32();
57033
+
57034
+ if (value === 2147483647) {
57035
+ this.set(Infinity);
57036
+ } else if (value === -2147483648) {
57037
+ this.set(-Infinity);
57038
+ } else {
57039
+ this.set(value);
57040
+ }
57041
+ }
57042
+ }
57043
+
57044
+
57045
+ /**
57046
+ * @readonly
57047
+ * @type {boolean}
57048
+ */
57049
+ ObservedInteger.prototype.isObservedInteger = true;
57050
+
56355
57051
  /**
56356
57052
  * NOTE: adapted from http://www.geometrictools.com/GTEngine/Include/Mathematics/GteIntrRay3Triangle3.h
56357
57053
  * @source https://en.wikipedia.org/wiki/M%C3%B6ller%E2%80%93Trumbore_intersection_algorithm (Möller and Trumbore, « Fast, Minimum Storage Ray-Triangle Intersection », Journal of Graphics Tools, vol. 2,‎ 1997, p. 21–28)
@@ -56601,332 +57297,24 @@ function ray3_array_apply_matrix4(output, output_offset, input, input_offset, m4
56601
57297
  return true;
56602
57298
  }
56603
57299
 
56604
- /**
56605
- * Common utilities
56606
- * @module glMatrix
56607
- */
56608
- var ARRAY_TYPE = typeof Float32Array !== 'undefined' ? Float32Array : Array;
56609
- if (!Math.hypot) Math.hypot = function () {
56610
- var y = 0,
56611
- i = arguments.length;
56612
-
56613
- while (i--) {
56614
- y += arguments[i] * arguments[i];
56615
- }
56616
-
56617
- return Math.sqrt(y);
56618
- };
56619
-
56620
- /**
56621
- * 4x4 Matrix<br>Format: column-major, when typed out it looks like row-major<br>The matrices are being post multiplied.
56622
- * @module mat4
56623
- */
56624
-
56625
- /**
56626
- * Creates a new identity mat4
56627
- *
56628
- * @returns {mat4} a new 4x4 matrix
56629
- */
56630
-
56631
- function create$1() {
56632
- var out = new ARRAY_TYPE(16);
56633
-
56634
- if (ARRAY_TYPE != Float32Array) {
56635
- out[1] = 0;
56636
- out[2] = 0;
56637
- out[3] = 0;
56638
- out[4] = 0;
56639
- out[6] = 0;
56640
- out[7] = 0;
56641
- out[8] = 0;
56642
- out[9] = 0;
56643
- out[11] = 0;
56644
- out[12] = 0;
56645
- out[13] = 0;
56646
- out[14] = 0;
56647
- }
56648
-
56649
- out[0] = 1;
56650
- out[5] = 1;
56651
- out[10] = 1;
56652
- out[15] = 1;
56653
- return out;
56654
- }
56655
- /**
56656
- * Copy the values from one mat4 to another
56657
- *
56658
- * @param {mat4} out the receiving matrix
56659
- * @param {ReadonlyMat4} a the source matrix
56660
- * @returns {mat4} out
56661
- */
56662
-
56663
- function copy(out, a) {
56664
- out[0] = a[0];
56665
- out[1] = a[1];
56666
- out[2] = a[2];
56667
- out[3] = a[3];
56668
- out[4] = a[4];
56669
- out[5] = a[5];
56670
- out[6] = a[6];
56671
- out[7] = a[7];
56672
- out[8] = a[8];
56673
- out[9] = a[9];
56674
- out[10] = a[10];
56675
- out[11] = a[11];
56676
- out[12] = a[12];
56677
- out[13] = a[13];
56678
- out[14] = a[14];
56679
- out[15] = a[15];
56680
- return out;
56681
- }
56682
- /**
56683
- * Inverts a mat4
56684
- *
56685
- * @param {mat4} out the receiving matrix
56686
- * @param {ReadonlyMat4} a the source matrix
56687
- * @returns {mat4} out
56688
- */
56689
-
56690
- function invert(out, a) {
56691
- var a00 = a[0],
56692
- a01 = a[1],
56693
- a02 = a[2],
56694
- a03 = a[3];
56695
- var a10 = a[4],
56696
- a11 = a[5],
56697
- a12 = a[6],
56698
- a13 = a[7];
56699
- var a20 = a[8],
56700
- a21 = a[9],
56701
- a22 = a[10],
56702
- a23 = a[11];
56703
- var a30 = a[12],
56704
- a31 = a[13],
56705
- a32 = a[14],
56706
- a33 = a[15];
56707
- var b00 = a00 * a11 - a01 * a10;
56708
- var b01 = a00 * a12 - a02 * a10;
56709
- var b02 = a00 * a13 - a03 * a10;
56710
- var b03 = a01 * a12 - a02 * a11;
56711
- var b04 = a01 * a13 - a03 * a11;
56712
- var b05 = a02 * a13 - a03 * a12;
56713
- var b06 = a20 * a31 - a21 * a30;
56714
- var b07 = a20 * a32 - a22 * a30;
56715
- var b08 = a20 * a33 - a23 * a30;
56716
- var b09 = a21 * a32 - a22 * a31;
56717
- var b10 = a21 * a33 - a23 * a31;
56718
- var b11 = a22 * a33 - a23 * a32; // Calculate the determinant
56719
-
56720
- var det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
56721
-
56722
- if (!det) {
56723
- return null;
56724
- }
56725
-
56726
- det = 1.0 / det;
56727
- out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det;
56728
- out[1] = (a02 * b10 - a01 * b11 - a03 * b09) * det;
56729
- out[2] = (a31 * b05 - a32 * b04 + a33 * b03) * det;
56730
- out[3] = (a22 * b04 - a21 * b05 - a23 * b03) * det;
56731
- out[4] = (a12 * b08 - a10 * b11 - a13 * b07) * det;
56732
- out[5] = (a00 * b11 - a02 * b08 + a03 * b07) * det;
56733
- out[6] = (a32 * b02 - a30 * b05 - a33 * b01) * det;
56734
- out[7] = (a20 * b05 - a22 * b02 + a23 * b01) * det;
56735
- out[8] = (a10 * b10 - a11 * b08 + a13 * b06) * det;
56736
- out[9] = (a01 * b08 - a00 * b10 - a03 * b06) * det;
56737
- out[10] = (a30 * b04 - a31 * b02 + a33 * b00) * det;
56738
- out[11] = (a21 * b02 - a20 * b04 - a23 * b00) * det;
56739
- out[12] = (a11 * b07 - a10 * b09 - a12 * b06) * det;
56740
- out[13] = (a00 * b09 - a01 * b07 + a02 * b06) * det;
56741
- out[14] = (a31 * b01 - a30 * b03 - a32 * b00) * det;
56742
- out[15] = (a20 * b03 - a21 * b01 + a22 * b00) * det;
56743
- return out;
56744
- }
56745
- /**
56746
- * Multiplies two mat4s
56747
- *
56748
- * @param {mat4} out the receiving matrix
56749
- * @param {ReadonlyMat4} a the first operand
56750
- * @param {ReadonlyMat4} b the second operand
56751
- * @returns {mat4} out
56752
- */
56753
-
56754
- function multiply(out, a, b) {
56755
- var a00 = a[0],
56756
- a01 = a[1],
56757
- a02 = a[2],
56758
- a03 = a[3];
56759
- var a10 = a[4],
56760
- a11 = a[5],
56761
- a12 = a[6],
56762
- a13 = a[7];
56763
- var a20 = a[8],
56764
- a21 = a[9],
56765
- a22 = a[10],
56766
- a23 = a[11];
56767
- var a30 = a[12],
56768
- a31 = a[13],
56769
- a32 = a[14],
56770
- a33 = a[15]; // Cache only the current line of the second matrix
56771
-
56772
- var b0 = b[0],
56773
- b1 = b[1],
56774
- b2 = b[2],
56775
- b3 = b[3];
56776
- out[0] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
56777
- out[1] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
56778
- out[2] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
56779
- out[3] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
56780
- b0 = b[4];
56781
- b1 = b[5];
56782
- b2 = b[6];
56783
- b3 = b[7];
56784
- out[4] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
56785
- out[5] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
56786
- out[6] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
56787
- out[7] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
56788
- b0 = b[8];
56789
- b1 = b[9];
56790
- b2 = b[10];
56791
- b3 = b[11];
56792
- out[8] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
56793
- out[9] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
56794
- out[10] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
56795
- out[11] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
56796
- b0 = b[12];
56797
- b1 = b[13];
56798
- b2 = b[14];
56799
- b3 = b[15];
56800
- out[12] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
56801
- out[13] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
56802
- out[14] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
56803
- out[15] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
56804
- return out;
56805
- }
56806
-
56807
- /**
56808
- * 3 Dimensional Vector
56809
- * @module vec3
56810
- */
56811
-
56812
- /**
56813
- * Creates a new, empty vec3
56814
- *
56815
- * @returns {vec3} a new 3D vector
56816
- */
56817
-
56818
- function create() {
56819
- var out = new ARRAY_TYPE(3);
56820
-
56821
- if (ARRAY_TYPE != Float32Array) {
56822
- out[0] = 0;
56823
- out[1] = 0;
56824
- out[2] = 0;
56825
- }
56826
-
56827
- return out;
56828
- }
56829
- /**
56830
- * Creates a new vec3 initialized with the given values
56831
- *
56832
- * @param {Number} x X component
56833
- * @param {Number} y Y component
56834
- * @param {Number} z Z component
56835
- * @returns {vec3} a new 3D vector
56836
- */
56837
-
56838
- function fromValues(x, y, z) {
56839
- var out = new ARRAY_TYPE(3);
56840
- out[0] = x;
56841
- out[1] = y;
56842
- out[2] = z;
56843
- return out;
56844
- }
56845
- /**
56846
- * Transforms the vec3 with a mat4.
56847
- * 4th vector component is implicitly '1'
56848
- *
56849
- * @param {vec3} out the receiving vector
56850
- * @param {ReadonlyVec3} a the vector to transform
56851
- * @param {ReadonlyMat4} m matrix to transform with
56852
- * @returns {vec3} out
56853
- */
56854
-
56855
- function transformMat4(out, a, m) {
56856
- var x = a[0],
56857
- y = a[1],
56858
- z = a[2];
56859
- var w = m[3] * x + m[7] * y + m[11] * z + m[15];
56860
- w = w || 1.0;
56861
- out[0] = (m[0] * x + m[4] * y + m[8] * z + m[12]) / w;
56862
- out[1] = (m[1] * x + m[5] * y + m[9] * z + m[13]) / w;
56863
- out[2] = (m[2] * x + m[6] * y + m[10] * z + m[14]) / w;
56864
- return out;
56865
- }
56866
- /**
56867
- * Perform some operation over an array of vec3s.
56868
- *
56869
- * @param {Array} a the array of vectors to iterate over
56870
- * @param {Number} stride Number of elements between the start of each vec3. If 0 assumes tightly packed
56871
- * @param {Number} offset Number of elements to skip at the beginning of the array
56872
- * @param {Number} count Number of vec3s to iterate over. If 0 iterates over entire array
56873
- * @param {Function} fn Function to call for each vector in the array
56874
- * @param {Object} [arg] additional argument to pass to fn
56875
- * @returns {Array} a
56876
- * @function
56877
- */
56878
-
56879
- (function () {
56880
- var vec = create();
56881
- return function (a, stride, offset, count, fn, arg) {
56882
- var i, l;
56883
-
56884
- if (!stride) {
56885
- stride = 3;
56886
- }
56887
-
56888
- if (!offset) {
56889
- offset = 0;
56890
- }
56891
-
56892
- if (count) {
56893
- l = Math.min(count * stride + offset, a.length);
56894
- } else {
56895
- l = a.length;
56896
- }
56897
-
56898
- for (i = offset; i < l; i += stride) {
56899
- vec[0] = a[i];
56900
- vec[1] = a[i + 1];
56901
- vec[2] = a[i + 2];
56902
- fn(vec, vec, arg);
56903
- a[i] = vec[0];
56904
- a[i + 1] = vec[1];
56905
- a[i + 2] = vec[2];
56906
- }
56907
-
56908
- return a;
56909
- };
56910
- })();
56911
-
56912
- /**
56913
- *
56914
- * @param {number[]|ArrayLike<number>|Float32Array} output
56915
- * @param {number} origin_x
56916
- * @param {number} origin_y
56917
- * @param {number} origin_z
56918
- * @param {number} direction_x
56919
- * @param {number} direction_y
56920
- * @param {number} direction_z
56921
- */
56922
- function ray3_array_compose(output, origin_x, origin_y, origin_z, direction_x, direction_y, direction_z) {
56923
- output[0] = origin_x;
56924
- output[1] = origin_y;
56925
- output[2] = origin_z;
56926
-
56927
- output[3] = direction_x;
56928
- output[4] = direction_y;
56929
- output[5] = direction_z;
57300
+ /**
57301
+ *
57302
+ * @param {number[]|ArrayLike<number>|Float32Array} output
57303
+ * @param {number} origin_x
57304
+ * @param {number} origin_y
57305
+ * @param {number} origin_z
57306
+ * @param {number} direction_x
57307
+ * @param {number} direction_y
57308
+ * @param {number} direction_z
57309
+ */
57310
+ function ray3_array_compose(output, origin_x, origin_y, origin_z, direction_x, direction_y, direction_z) {
57311
+ output[0] = origin_x;
57312
+ output[1] = origin_y;
57313
+ output[2] = origin_z;
57314
+
57315
+ output[3] = direction_x;
57316
+ output[4] = direction_y;
57317
+ output[5] = direction_z;
56930
57318
  }
56931
57319
 
56932
57320
  const hit$1 = new Vector3();
@@ -56943,657 +57331,295 @@ const m4_tmp = [];
56943
57331
  * @param {number[]|Uint8Array|Uint16Array|Uint32Array} indices
56944
57332
  * @param {number[]|Float32Array|Float64Array} vertices
56945
57333
  * @param {number} index
56946
- */
56947
- function bindGeometryFace(indices, vertices, index) {
56948
- const index3 = index * 3;
56949
-
56950
- assert.lessThan(index3, indices.length, 'index underflow');
56951
-
56952
- const a = indices[index3] * 3;
56953
- const b = indices[index3 + 1] * 3;
56954
- const c = indices[index3 + 2] * 3;
56955
-
56956
- vA.set(vertices[a], vertices[a + 1], vertices[a + 2]);
56957
- vB.set(vertices[b], vertices[b + 1], vertices[b + 2]);
56958
- vC.set(vertices[c], vertices[c + 1], vertices[c + 2]);
56959
- }
56960
-
56961
- const vNormal = new Vector3$1();
56962
-
56963
- function bindGeometryFaceNormal(indices, normals, index) {
56964
-
56965
- const index3 = index * 3;
56966
-
56967
- const a = indices[index3] * 3;
56968
- const b = indices[index3 + 1] * 3;
56969
- const c = indices[index3 + 2] * 3;
56970
-
56971
- //read vertex normals
56972
- const naX = normals[a];
56973
- const naY = normals[a + 1];
56974
- const naZ = normals[a + 2];
56975
-
56976
- const nbX = normals[b];
56977
- const nbY = normals[b + 1];
56978
- const nbZ = normals[b + 2];
56979
-
56980
- const ncX = normals[c];
56981
- const ncY = normals[c + 1];
56982
- const ncZ = normals[c + 2];
56983
-
56984
- //add normals
56985
- const nsX = (naX + nbX + ncX);
56986
- const nsY = (naY + nbY + ncY);
56987
- const nsZ = (naZ + nbZ + ncZ);
56988
-
56989
- //normalize
56990
- const l = v3_length(nsX, nsY, nsZ);
56991
- const m = 1 / l;
56992
-
56993
- const nx = nsX * m;
56994
- const ny = nsY * m;
56995
- const nz = nsZ * m;
56996
-
56997
- vNormal.set(nx, ny, nz);
56998
- }
56999
-
57000
-
57001
- function extractFaceIndexFromLeaf_default(leaf) {
57002
- return leaf.object;
57003
- }
57004
-
57005
- class BVHGeometryRaycaster {
57006
- constructor() {
57007
- /**
57008
- *
57009
- * @type {BufferGeometry|null}
57010
- */
57011
- this.geometry = null;
57012
- /**
57013
- *
57014
- * @type {BinaryNode|null}
57015
- */
57016
- this.bvh = null;
57017
-
57018
- /**
57019
- *
57020
- * @type {Vector2|null}
57021
- */
57022
- this.position = null;
57023
- /**
57024
- *
57025
- * @type {Vector2|null}
57026
- */
57027
- this.scale = null;
57028
- /**
57029
- *
57030
- * @type {number}
57031
- */
57032
- this.resolution = 0;
57033
-
57034
- /**
57035
- *
57036
- * @type {Vector2|null}
57037
- */
57038
- this.size = null;
57039
-
57040
- this.__bestDistance = 0;
57041
- this.__bestPosition = new Vector3$1();
57042
- this.__bestIndex = 0;
57043
-
57044
-
57045
- this.origin = new Vector3$1();
57046
- this.direction = new Vector3$1();
57047
-
57048
- /**
57049
- *
57050
- * @type {Float32Array}
57051
- */
57052
- this.transform = new Float32Array(16);
57053
-
57054
- array_copy(MATRIX_4_IDENTITY, 0, this.transform, 0, 16);
57055
-
57056
- this.extractFaceIndexFromLeaf = extractFaceIndexFromLeaf_default;
57057
- }
57058
-
57059
- /**
57060
- *
57061
- * @param {*} leaf
57062
- */
57063
- visitLeafIntersection(leaf) {
57064
-
57065
- const geometry = this.geometry;
57066
-
57067
- const geometryIndices = geometry.getIndex().array;
57068
- const geometryVertices = geometry.getAttribute('position').array;
57069
-
57070
- const extractFaceIndexFromLeaf = this.extractFaceIndexFromLeaf;
57071
-
57072
- const index = extractFaceIndexFromLeaf(leaf);
57073
-
57074
- bindGeometryFace(geometryIndices, geometryVertices, index);
57075
-
57076
- const hitFound = rayTriangleIntersection(hit$1, this.origin, this.direction, vA, vB, vC);
57077
-
57078
- if (hitFound) {
57079
-
57080
- const d = this.origin.distanceSqrTo(hit$1);
57081
- if (d < this.__bestDistance) {
57082
- this.__bestDistance = d;
57083
- this.__bestPosition.copy(hit$1);
57084
- this.__bestIndex = index;
57085
- }
57086
-
57087
- }
57088
- }
57089
-
57090
- /**
57091
- *
57092
- * @param {SurfacePoint3} hit
57093
- * @param {number} originX
57094
- * @param {number} originY
57095
- * @param {number} originZ
57096
- * @param {number} directionX
57097
- * @param {number} directionY
57098
- * @param {number} directionZ
57099
- * @returns {boolean}
57100
- */
57101
- raycast(
57102
- hit,
57103
- originX, originY, originZ,
57104
- directionX, directionY, directionZ
57105
- ) {
57106
-
57107
- invert(m4_tmp, this.transform);
57108
-
57109
- ray3_array_compose(
57110
- ray_tmp,
57111
- originX, originY, originZ,
57112
- directionX, directionY, directionZ
57113
- );
57114
-
57115
- ray3_array_apply_matrix4(ray_tmp, 0,ray_tmp,0, m4_tmp);
57116
-
57117
- const _originX = ray_tmp[0];
57118
- const _originY = ray_tmp[1];
57119
- const _originZ = ray_tmp[2];
57120
-
57121
- const _directionX = ray_tmp[3];
57122
- const _directionY = ray_tmp[4];
57123
- const _directionZ = ray_tmp[5];
57124
-
57125
- this.origin.set(_originX, _originY, _originZ);
57126
- this.direction.set(_directionX, _directionY, _directionZ);
57127
-
57128
- this.__bestDistance = Number.POSITIVE_INFINITY;
57129
-
57130
- this.bvh.traverseRayLeafIntersections(_originX, _originY, _originZ, _directionX, _directionY, _directionZ, this.visitLeafIntersection, this);
57131
-
57132
- if (this.__bestDistance !== Number.POSITIVE_INFINITY) {
57133
-
57134
- const geometry = this.geometry;
57135
-
57136
- const geometryIndices = geometry.getIndex().array;
57137
- const geometryNormals = geometry.getAttribute('normal').array;
57138
-
57139
- bindGeometryFaceNormal(geometryIndices, geometryNormals, this.__bestIndex);
57140
-
57141
- hit.position.copy(this.__bestPosition);
57142
- hit.normal.copy(vNormal);
57143
-
57144
- hit.applyMatrix4(this.transform);
57145
-
57146
- return true;
57147
- } else {
57148
- //no hit
57149
- return false;
57150
- }
57151
- }
57152
- }
57153
-
57154
- class ObservedInteger extends Number {
57155
- /**
57156
- * @readonly
57157
- * @type {Signal}
57158
- */
57159
- onChanged = new Signal();
57160
-
57161
- /**
57162
- *
57163
- * @param {Number} [value]
57164
- * @constructor
57165
- */
57166
- constructor(value = 0) {
57167
- super();
57168
-
57169
- assert.isNumber(value, 'value');
57170
- assert.ok(Number.isInteger(value) || !Number.isFinite(value), `Value must be an integer, instead was ${value}`);
57171
-
57172
-
57173
- /**
57174
- *
57175
- * @type {Number}
57176
- * @private
57177
- */
57178
- this.__value = value;
57179
-
57180
- }
57181
-
57182
- /**
57183
- *
57184
- * @returns {Number}
57185
- */
57186
- valueOf() {
57187
- return this.getValue();
57188
- }
57189
-
57190
- toString() {
57191
- return this.getValue().toString();
57192
- }
57193
-
57194
- /**
57195
- *
57196
- * @param {Number} value
57197
- * @returns {ObservedInteger}
57198
- */
57199
- set(value) {
57200
- assert.isNumber(value, 'value');
57201
- assert.ok(Number.isInteger(value) || !Number.isFinite(value), `Value must be an integer, instead was ${value}`);
57202
-
57203
- const oldValue = this.__value;
57204
- if (oldValue !== value) {
57205
- this.__value = value;
57206
- this.onChanged.send2(value, oldValue);
57207
- }
57208
-
57209
- return this;
57210
- }
57211
-
57212
- /**
57213
- * Set value without dispatching change notification
57214
- * @param {number} value
57215
- */
57216
- setSilent(value) {
57217
- assert.isNumber(value, 'value');
57218
- assert.ok(Number.isInteger(value) || !Number.isFinite(value), `Value must be an integer, instead was ${value}`);
57219
-
57220
- this.__value = value;
57221
- }
57222
-
57223
- /**
57224
- *
57225
- * @return {boolean}
57226
- */
57227
- isZero() {
57228
- return this.getValue() === 0;
57229
- }
57230
-
57231
- /**
57232
- *
57233
- * @param {ObservedInteger} other
57234
- */
57235
- subtract(other) {
57236
- this._add(-other.getValue());
57237
- }
57238
-
57239
- /**
57240
- *
57241
- * @param {number} value
57242
- */
57243
- _subtract(value) {
57244
- this.set(this.getValue() - value);
57245
- }
57246
-
57247
- /**
57248
- *
57249
- * @param {ObservedInteger} other
57250
- */
57251
- add(other) {
57252
- this._add(other.getValue());
57253
- }
57254
-
57255
- /**
57256
- *
57257
- * @param {number} value
57258
- */
57259
- _add(value) {
57260
- this.set(this.getValue() + value);
57261
- }
57262
-
57263
- /**
57264
- * Increment the stored value by 1, same as adding 1
57265
- */
57266
- increment() {
57267
- this.set(this.getValue() + 1);
57268
- }
57269
-
57270
- /**
57271
- * Decrement the stored value by 1, same as subtracting 1
57272
- */
57273
- decrement() {
57274
- this.set(this.getValue() - 1);
57275
- }
57276
-
57277
- /**
57278
- *
57279
- * @returns {Number}
57280
- */
57281
- getValue() {
57282
- return this.__value;
57283
- }
57284
-
57285
- /**
57286
- *
57287
- * @param {ObservedInteger} other
57288
- */
57289
- copy(other) {
57290
- this.set(other.__value);
57291
- }
57292
-
57293
- /**
57294
- *
57295
- * @param {ObservedInteger} other
57296
- * @returns {boolean}
57297
- */
57298
- equals(other) {
57299
- return this.__value === other.__value;
57300
- }
57334
+ */
57335
+ function bindGeometryFace(indices, vertices, index) {
57336
+ const index3 = index * 3;
57301
57337
 
57302
- /**
57303
- *
57304
- * @returns {Number}
57305
- */
57306
- hash() {
57307
- return this.__value;
57308
- }
57338
+ assert.lessThan(index3, indices.length, 'index underflow');
57309
57339
 
57310
- toJSON() {
57311
- return this.__value;
57312
- }
57340
+ const a = indices[index3] * 3;
57341
+ const b = indices[index3 + 1] * 3;
57342
+ const c = indices[index3 + 2] * 3;
57313
57343
 
57314
- fromJSON(obj) {
57315
- this.set(obj);
57316
- }
57344
+ vA.set(vertices[a], vertices[a + 1], vertices[a + 2]);
57345
+ vB.set(vertices[b], vertices[b + 1], vertices[b + 2]);
57346
+ vC.set(vertices[c], vertices[c + 1], vertices[c + 2]);
57347
+ }
57317
57348
 
57318
- /**
57319
- *
57320
- * @param {BinaryBuffer} buffer
57321
- */
57322
- toBinaryBuffer(buffer) {
57323
- const v = this.__value;
57349
+ const vNormal = new Vector3$1();
57324
57350
 
57325
- if (v === Infinity) {
57326
- buffer.writeInt32(2147483647);
57327
- } else if (v === -Infinity) {
57328
- buffer.writeInt32(-2147483648);
57329
- } else {
57330
- //TODO it's possible to write encoded Infinity values by accident
57331
- buffer.writeInt32(v);
57332
- }
57333
- }
57351
+ function bindGeometryFaceNormal(indices, normals, index) {
57334
57352
 
57335
- /**
57336
- *
57337
- * @param {BinaryBuffer} buffer
57338
- */
57339
- fromBinaryBuffer(buffer) {
57340
- const value = buffer.readInt32();
57353
+ const index3 = index * 3;
57341
57354
 
57342
- if (value === 2147483647) {
57343
- this.set(Infinity);
57344
- } else if (value === -2147483648) {
57345
- this.set(-Infinity);
57346
- } else {
57347
- this.set(value);
57348
- }
57349
- }
57350
- }
57355
+ const a = indices[index3] * 3;
57356
+ const b = indices[index3 + 1] * 3;
57357
+ const c = indices[index3 + 2] * 3;
57351
57358
 
57359
+ //read vertex normals
57360
+ const naX = normals[a];
57361
+ const naY = normals[a + 1];
57362
+ const naZ = normals[a + 2];
57352
57363
 
57353
- /**
57354
- * @readonly
57355
- * @type {boolean}
57356
- */
57357
- ObservedInteger.prototype.isObservedInteger = true;
57358
-
57359
- /**
57360
- * Compute fraction of linear interpolation
57361
- * @param {number} a
57362
- * @param {number} b
57363
- * @param {number} value
57364
- * @returns {number} fraction
57365
- */
57366
- function inverseLerp(a, b, value) {
57367
- const range = b - a;
57368
- const scaledValue = value - a;
57364
+ const nbX = normals[b];
57365
+ const nbY = normals[b + 1];
57366
+ const nbZ = normals[b + 2];
57369
57367
 
57370
- if (range === 0) {
57368
+ const ncX = normals[c];
57369
+ const ncY = normals[c + 1];
57370
+ const ncZ = normals[c + 2];
57371
57371
 
57372
- // avoid division by zero error
57372
+ //add normals
57373
+ const nsX = (naX + nbX + ncX);
57374
+ const nsY = (naY + nbY + ncY);
57375
+ const nsZ = (naZ + nbZ + ncZ);
57373
57376
 
57374
- // this is arbitrary output, as actual answer is undefined
57377
+ //normalize
57378
+ const l = v3_length(nsX, nsY, nsZ);
57379
+ const m = 1 / l;
57375
57380
 
57376
- return 0;
57377
- }
57381
+ const nx = nsX * m;
57382
+ const ny = nsY * m;
57383
+ const nz = nsZ * m;
57378
57384
 
57379
- return scaledValue / range;
57380
- }
57381
-
57382
- /**
57383
- *
57384
- * @param {number} min
57385
- * @param {number} max
57386
- * @constructor
57387
- */
57385
+ vNormal.set(nx, ny, nz);
57386
+ }
57388
57387
 
57389
- class NumericInterval {
57390
- /**
57391
- *
57392
- * @param {number} [min=-Infinity]
57393
- * @param {number} [max=Infinity]
57394
- * @constructor
57395
- */
57396
- constructor(
57397
- min = Number.NEGATIVE_INFINITY,
57398
- max = Number.POSITIVE_INFINITY
57399
- ) {
57400
- assert.isNumber(min, 'min');
57401
- assert.isNumber(max, 'max');
57402
57388
 
57403
- assert.ok(max >= min, `max=${max} must be >= than min=${min}`);
57389
+ function extractFaceIndexFromLeaf_default(leaf) {
57390
+ return leaf.object;
57391
+ }
57404
57392
 
57393
+ class BVHGeometryRaycaster {
57394
+ constructor() {
57405
57395
  /**
57406
57396
  *
57407
- * @type {number}
57397
+ * @type {BufferGeometry|null}
57408
57398
  */
57409
- this.min = min;
57399
+ this.geometry = null;
57400
+ /**
57401
+ *
57402
+ * @type {BinaryNode|null}
57403
+ */
57404
+ this.bvh = null;
57405
+
57406
+ /**
57407
+ *
57408
+ * @type {Vector2|null}
57409
+ */
57410
+ this.position = null;
57411
+ /**
57412
+ *
57413
+ * @type {Vector2|null}
57414
+ */
57415
+ this.scale = null;
57410
57416
  /**
57411
57417
  *
57412
57418
  * @type {number}
57413
57419
  */
57414
- this.max = max;
57420
+ this.resolution = 0;
57415
57421
 
57416
- this.onChanged = new Signal();
57417
- }
57422
+ /**
57423
+ *
57424
+ * @type {Vector2|null}
57425
+ */
57426
+ this.size = null;
57418
57427
 
57428
+ this.__bestDistance = 0;
57429
+ this.__bestPosition = new Vector3$1();
57430
+ this.__bestIndex = 0;
57431
+
57432
+
57433
+ this.origin = new Vector3$1();
57434
+ this.direction = new Vector3$1();
57435
+
57436
+ /**
57437
+ *
57438
+ * @type {Float32Array}
57439
+ */
57440
+ this.transform = new Float32Array(16);
57441
+
57442
+ array_copy(MATRIX_4_IDENTITY, 0, this.transform, 0, 16);
57443
+
57444
+ this.extractFaceIndexFromLeaf = extractFaceIndexFromLeaf_default;
57445
+ }
57419
57446
 
57420
57447
  /**
57421
57448
  *
57422
- * @param {number} min
57423
- * @param {number} max
57449
+ * @param {*} leaf
57424
57450
  */
57425
- set(min, max) {
57426
- assert.isNumber(min, 'min');
57427
- assert.isNumber(max, 'max');
57451
+ visitLeafIntersection(leaf) {
57428
57452
 
57429
- assert.notNaN(min, 'min');
57430
- assert.notNaN(max, 'max');
57453
+ const geometry = this.geometry;
57431
57454
 
57432
- assert.greaterThanOrEqual(max, min, `max [${max}] must be >= than min[${min}]`);
57455
+ const geometryIndices = geometry.getIndex().array;
57456
+ const geometryVertices = geometry.getAttribute('position').array;
57433
57457
 
57434
- const oldMin = this.min;
57435
- const oldMax = this.max;
57458
+ const extractFaceIndexFromLeaf = this.extractFaceIndexFromLeaf;
57436
57459
 
57437
- if (min !== oldMin || max !== oldMax) {
57438
- this.min = min;
57439
- this.max = max;
57460
+ const index = extractFaceIndexFromLeaf(leaf);
57440
57461
 
57441
- if (this.onChanged.hasHandlers()) {
57442
- this.onChanged.send4(min, max, oldMin, oldMax);
57462
+ bindGeometryFace(geometryIndices, geometryVertices, index);
57463
+
57464
+ const hitFound = rayTriangleIntersection(hit$1, this.origin, this.direction, vA, vB, vC);
57465
+
57466
+ if (hitFound) {
57467
+
57468
+ const d = this.origin.distanceSqrTo(hit$1);
57469
+ if (d < this.__bestDistance) {
57470
+ this.__bestDistance = d;
57471
+ this.__bestPosition.copy(hit$1);
57472
+ this.__bestIndex = index;
57443
57473
  }
57474
+
57444
57475
  }
57445
57476
  }
57446
57477
 
57447
57478
  /**
57448
57479
  *
57449
- * @param {NumericInterval} other
57480
+ * @param {SurfacePoint3} hit
57481
+ * @param {number} originX
57482
+ * @param {number} originY
57483
+ * @param {number} originZ
57484
+ * @param {number} directionX
57485
+ * @param {number} directionY
57486
+ * @param {number} directionZ
57487
+ * @returns {boolean}
57450
57488
  */
57451
- copy(other) {
57452
- this.set(other.min, other.max);
57453
- }
57489
+ raycast(
57490
+ hit,
57491
+ originX, originY, originZ,
57492
+ directionX, directionY, directionZ
57493
+ ) {
57454
57494
 
57455
- /**
57456
- *
57457
- * @param {number} value
57458
- */
57459
- multiplyScalar(value) {
57460
- const v0 = this.min * value;
57461
- const v1 = this.max * value;
57495
+ invert(m4_tmp, this.transform);
57462
57496
 
57463
- if (v0 > v1) {
57464
- //probably negative scale
57465
- this.set(v1, v0);
57466
- } else {
57497
+ ray3_array_compose(
57498
+ ray_tmp,
57499
+ originX, originY, originZ,
57500
+ directionX, directionY, directionZ
57501
+ );
57467
57502
 
57468
- this.set(v0, v1);
57469
- }
57470
- }
57503
+ ray3_array_apply_matrix4(ray_tmp, 0,ray_tmp,0, m4_tmp);
57471
57504
 
57472
- /**
57473
- * Performs inverse linear interpolation on a given input
57474
- * @param {number} v
57475
- * @returns {number}
57476
- */
57477
- normalizeValue(v) {
57478
- return inverseLerp(this.min, this.max, v);
57479
- }
57505
+ const _originX = ray_tmp[0];
57506
+ const _originY = ray_tmp[1];
57507
+ const _originZ = ray_tmp[2];
57480
57508
 
57481
- /**
57482
- * Both min and max are exactly 0
57483
- * @returns {boolean}
57484
- */
57485
- isZero() {
57486
- return this.min === 0 && this.max === 0;
57487
- }
57509
+ const _directionX = ray_tmp[3];
57510
+ const _directionY = ray_tmp[4];
57511
+ const _directionZ = ray_tmp[5];
57488
57512
 
57489
- /**
57490
- * Whether min and max are the same
57491
- * In other words if span is 0
57492
- * @returns {boolean}
57493
- */
57494
- isExact() {
57495
- return this.min === this.max;
57496
- }
57513
+ this.origin.set(_originX, _originY, _originZ);
57514
+ this.direction.set(_directionX, _directionY, _directionZ);
57497
57515
 
57498
- /**
57499
- *
57500
- * @returns {number}
57501
- */
57502
- computeAverage() {
57503
- return (this.min + this.max) / 2;
57504
- }
57516
+ this.__bestDistance = Number.POSITIVE_INFINITY;
57505
57517
 
57506
- /**
57507
- *
57508
- * @param {function} random Random number generator function, must return values between 0 and 1
57509
- * @returns {number}
57510
- */
57511
- sampleRandom(random) {
57512
- assert.equal(typeof random, 'function', `random must be a function, instead was ${typeof random}`);
57518
+ this.bvh.traverseRayLeafIntersections(_originX, _originY, _originZ, _directionX, _directionY, _directionZ, this.visitLeafIntersection, this);
57513
57519
 
57514
- return this.min + random() * (this.max - this.min);
57515
- }
57520
+ if (this.__bestDistance !== Number.POSITIVE_INFINITY) {
57516
57521
 
57517
- fromJSON(json) {
57518
- this.set(json.min, json.max);
57519
- }
57522
+ const geometry = this.geometry;
57520
57523
 
57521
- toJSON() {
57522
- return {
57523
- min: this.min,
57524
- max: this.max
57525
- };
57526
- }
57524
+ const geometryIndices = geometry.getIndex().array;
57525
+ const geometryNormals = geometry.getAttribute('normal').array;
57527
57526
 
57528
- /**
57529
- *
57530
- * @param {BinaryBuffer} buffer
57531
- */
57532
- toBinaryBuffer(buffer) {
57533
- buffer.writeFloat64(this.min);
57534
- buffer.writeFloat64(this.max);
57535
- }
57527
+ bindGeometryFaceNormal(geometryIndices, geometryNormals, this.__bestIndex);
57536
57528
 
57537
- /**
57538
- *
57539
- * @param {BinaryBuffer} buffer
57540
- */
57541
- fromBinaryBuffer(buffer) {
57542
- this.min = buffer.readFloat64();
57543
- this.max = buffer.readFloat64();
57544
- }
57529
+ hit.position.copy(this.__bestPosition);
57530
+ hit.normal.copy(vNormal);
57545
57531
 
57546
- /**
57547
- *
57548
- * @param {NumericInterval} other
57549
- * @returns {boolean}
57550
- */
57551
- equals(other) {
57552
- return this.min === other.min && this.max === other.max;
57532
+ hit.applyMatrix4(this.transform);
57533
+
57534
+ return true;
57535
+ } else {
57536
+ //no hit
57537
+ return false;
57538
+ }
57553
57539
  }
57540
+ }
57541
+
57542
+ /**
57543
+ * Created by Alex on 28/01/2017.
57544
+ */
57554
57545
 
57555
- /**
57556
- *
57557
- * @returns {number}
57558
- */
57559
- hash() {
57560
- let hash = computeHashFloat(this.min);
57546
+ function prepareObject(object) {
57547
+ //turn off automatic matrix re-calculations each frame
57548
+ object.matrixAutoUpdate = false;
57549
+ //disable frustum culling
57550
+ object.frustumCulled = false;
57551
+ }
57561
57552
 
57562
- hash = ((hash << 5) - hash) + computeHashFloat(this.max);
57553
+ /**
57554
+ *
57555
+ * @param {BufferGeometry} [geometry]
57556
+ * @param {Material} [material]
57557
+ * @returns {Mesh}
57558
+ */
57559
+ function createMesh(geometry, material) {
57560
+ const result = new Mesh(geometry, material);
57563
57561
 
57564
- return hash;
57565
- }
57562
+ prepareObject(result);
57566
57563
 
57567
- /**
57568
- * Distance between min and max (= max - min)
57569
- * @returns {number}
57570
- */
57571
- get span() {
57572
- return this.max - this.min;
57573
- }
57564
+ return result;
57574
57565
  }
57575
57566
 
57576
57567
  /**
57577
- * @readonly
57578
- * @type {boolean}
57568
+ *
57569
+ * @param {BufferGeometry} geometry
57570
+ * @param {THREE.Material} material
57571
+ * @returns {THREE.SkinnedMesh}
57579
57572
  */
57580
- NumericInterval.prototype.isNumericInterval = true;
57573
+ function createSkinnedMesh(geometry, material) {
57574
+ const result = new SkinnedMesh(geometry, material);
57575
+
57576
+ prepareObject(result);
57577
+
57578
+ return result;
57579
+ }
57581
57580
 
57582
57581
  /**
57583
- * @readonly
57584
- * @type {NumericInterval}
57582
+ *
57583
+ * @param {Material} material
57585
57584
  */
57586
- NumericInterval.one_one = Object.freeze(new NumericInterval(1, 1));
57585
+ function prepareMaterial(material) {
57586
+
57587
+ //make shadows render from front side, this avoids artifacts due to gaps in geometry that can't be seen from the front
57588
+ material.shadowSide = DoubleSide;
57589
+
57590
+ if (typeof material.envMapIntensity === 'number' && material.envMapIntensity !== 1) {
57591
+ // make material react to environment map in the same way as others
57592
+ material.envMapIntensity = 1;
57593
+ }
57594
+ }
57595
+
57587
57596
  /**
57588
- * @readonly
57589
- * @type {NumericInterval}
57597
+ *
57598
+ * @returns {Group}
57590
57599
  */
57591
- NumericInterval.zero_zero = Object.freeze(new NumericInterval(0, 0));
57600
+ function createGroup() {
57601
+ const result = new Group();
57602
+
57603
+ prepareObject(result);
57604
+
57605
+ return result;
57606
+ }
57607
+
57608
+ var ThreeFactory = {
57609
+ createMesh,
57610
+ createSkinnedMesh,
57611
+ createGroup,
57612
+ prepareMaterial
57613
+ };
57592
57614
 
57593
57615
  /**
57594
57616
  * Created by Alex on 09/11/2014.
57595
57617
  */
57596
57618
 
57619
+
57620
+ const EMPTY_GEOMETRY = new BufferGeometry();
57621
+ const DEFAULT_MATERIAL = new MeshBasicMaterial();
57622
+
57597
57623
  /**
57598
57624
  * terrain tile is a part of a 2d array
57599
57625
  */
@@ -57609,7 +57635,7 @@ class TerrainTile {
57609
57635
  * @type {Material}
57610
57636
  */
57611
57637
  material = null;
57612
- mesh = ThreeFactory.createMesh();
57638
+ mesh = ThreeFactory.createMesh(EMPTY_GEOMETRY, DEFAULT_MATERIAL);
57613
57639
 
57614
57640
 
57615
57641
  /**
@@ -60053,70 +60079,70 @@ class TerrainTileManager {
60053
60079
  const raycastBVHVisitor = new RaycastBVHVisitor();
60054
60080
  const firstRayIntersectionTerrainBVHVisitor = new FirstRayIntersectionTerrainBVHVisitor();
60055
60081
 
60056
- function TerrainPreview() {
60082
+ class TerrainPreview {
60057
60083
  /**
60058
60084
  *
60059
60085
  * @type {String}
60060
60086
  */
60061
- this.url = "";
60087
+ url = "";
60062
60088
 
60063
60089
  /**
60064
60090
  *
60065
60091
  * @type {Vector2}
60066
60092
  */
60067
- this.offset = new Vector2(0, 0);
60093
+ offset = new Vector2(0, 0);
60068
60094
  /**
60069
60095
  *
60070
60096
  * @type {Vector2}
60071
60097
  */
60072
- this.scale = new Vector2(1, 1);
60073
- }
60098
+ scale = new Vector2(1, 1);
60074
60099
 
60075
- /**
60076
- *
60077
- * @param {TerrainPreview} other
60078
- */
60079
- TerrainPreview.prototype.copy = function (other) {
60080
- this.url = other.url;
60081
- this.scale.copy(other.scale);
60082
- this.offset.copy(other.offset);
60083
- };
60100
+ /**
60101
+ *
60102
+ * @param {TerrainPreview} other
60103
+ */
60104
+ copy(other) {
60105
+ this.url = other.url;
60106
+ this.scale.copy(other.scale);
60107
+ this.offset.copy(other.offset);
60108
+ }
60084
60109
 
60085
- TerrainPreview.prototype.toJSON = function () {
60086
- return {
60087
- url: this.url,
60088
- offset: this.offset.toJSON(),
60089
- scale: this.scale.toJSON()
60090
- };
60091
- };
60110
+ toJSON() {
60111
+ return {
60112
+ url: this.url,
60113
+ offset: this.offset.toJSON(),
60114
+ scale: this.scale.toJSON()
60115
+ };
60116
+ }
60092
60117
 
60093
- TerrainPreview.prototype.fromJSON = function (obj) {
60094
- this.url = obj.url;
60095
- this.offset.fromJSON(obj.offset);
60096
- this.scale.fromJSON(obj.scale);
60097
- };
60118
+ fromJSON(obj) {
60119
+ this.url = obj.url;
60120
+ this.offset.fromJSON(obj.offset);
60121
+ this.scale.fromJSON(obj.scale);
60122
+ }
60098
60123
 
60099
- /**
60100
- *
60101
- * @param {BinaryBuffer} buffer
60102
- */
60103
- TerrainPreview.prototype.toBinaryBuffer = function (buffer) {
60104
- buffer.writeUTF8String(this.url);
60124
+ /**
60125
+ *
60126
+ * @param {BinaryBuffer} buffer
60127
+ */
60128
+ toBinaryBuffer(buffer) {
60129
+ buffer.writeUTF8String(this.url);
60105
60130
 
60106
- this.offset.toBinaryBuffer(buffer);
60107
- this.scale.toBinaryBuffer(buffer);
60108
- };
60131
+ this.offset.toBinaryBuffer(buffer);
60132
+ this.scale.toBinaryBuffer(buffer);
60133
+ }
60109
60134
 
60110
- /**
60111
- *
60112
- * @param {BinaryBuffer} buffer
60113
- */
60114
- TerrainPreview.prototype.fromBinaryBuffer = function (buffer) {
60115
- this.url = buffer.readUTF8String();
60135
+ /**
60136
+ *
60137
+ * @param {BinaryBuffer} buffer
60138
+ */
60139
+ fromBinaryBuffer(buffer) {
60140
+ this.url = buffer.readUTF8String();
60116
60141
 
60117
- this.offset.fromBinaryBuffer(buffer);
60118
- this.scale.fromBinaryBuffer(buffer);
60119
- };
60142
+ this.offset.fromBinaryBuffer(buffer);
60143
+ this.scale.fromBinaryBuffer(buffer);
60144
+ }
60145
+ }
60120
60146
 
60121
60147
  /**
60122
60148
  * NOTE, trying to keep to IANA registry: https://www.iana.org/assignments/media-types/media-types.xhtml
@@ -68645,8 +68671,10 @@ class EBBVHLeafProxy {
68645
68671
  unlink() {
68646
68672
  assert.equal(this.is_linked, true, 'not linked');
68647
68673
 
68648
- this.#tree.remove_leaf(this.#node_id);
68649
- this.#tree.release_node(this.#node_id);
68674
+ const node_id = this.#node_id;
68675
+
68676
+ this.#tree.remove_leaf(node_id);
68677
+ this.#tree.release_node(node_id);
68650
68678
 
68651
68679
  this.#node_id = -1;
68652
68680
  this.#tree = null;
@@ -109981,7 +110009,7 @@ class WebEnginePlatform extends EnginePlatform {
109981
110009
  class Tag {
109982
110010
  /**
109983
110011
  * @private
109984
- * @type {String[]}
110012
+ * @type {string[]}
109985
110013
  */
109986
110014
  values = [];
109987
110015
 
@@ -110163,41 +110191,31 @@ class Tag {
110163
110191
  * @return {boolean}
110164
110192
  */
110165
110193
  equals(other) {
110166
-
110167
- const s0 = this.values;
110168
-
110169
- const s1 = other.values;
110170
-
110171
- const n0 = s0.length;
110172
- const n1 = s1.length;
110173
-
110174
- if (n0 !== n1) {
110175
- //wrong length
110176
- return false;
110177
- }
110178
-
110179
- for (let i = 0; i < n0; i++) {
110180
- const v0 = s0[i];
110181
- const v1 = s1[i];
110182
-
110183
- if (v0 !== v1) {
110184
- return false;
110185
- }
110186
- }
110187
-
110188
- return true;
110194
+ return isArrayEqualStrict(this.values, other.values);
110189
110195
  }
110190
110196
 
110191
110197
  toJSON() {
110192
110198
  return this.values;
110193
110199
  }
110194
110200
 
110201
+ /**
110202
+ *
110203
+ * @param {string[]|string} json
110204
+ */
110195
110205
  fromJSON(json) {
110206
+
110207
+ this.clear();
110208
+
110196
110209
  if (typeof json === "string") {
110197
- this.clear();
110198
110210
  this.add(json);
110199
- } else if (Array.isArray(json)) {
110200
- this.values = json;
110211
+ } else {
110212
+ assert.isArray(json, 'json');
110213
+
110214
+ const n = json.length;
110215
+
110216
+ for (let i = 0; i < n; i++) {
110217
+ this.add(json[i]);
110218
+ }
110201
110219
  }
110202
110220
  }
110203
110221