@xeokit/xeokit-sdk 2.6.28 → 2.6.30

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 (58) hide show
  1. package/README.md +1 -0
  2. package/dist/xeokit-sdk.cjs.js +1425 -649
  3. package/dist/xeokit-sdk.es.js +1420 -650
  4. package/dist/xeokit-sdk.es5.js +629 -552
  5. package/dist/xeokit-sdk.min.cjs.js +5 -5
  6. package/dist/xeokit-sdk.min.es.js +5 -5
  7. package/dist/xeokit-sdk.min.es5.js +4 -4
  8. package/package.json +1 -1
  9. package/src/extras/PointerCircle/PointerCircle.js +1 -1
  10. package/src/plugins/AngleMeasurementsPlugin/AngleMeasurementsMouseControl.js +22 -41
  11. package/src/plugins/AngleMeasurementsPlugin/AngleMeasurementsTouchControl.js +3 -18
  12. package/src/plugins/DistanceMeasurementsPlugin/DistanceMeasurementsMouseControl.js +20 -41
  13. package/src/plugins/DistanceMeasurementsPlugin/DistanceMeasurementsTouchControl.js +4 -20
  14. package/src/plugins/DistanceMeasurementsPlugin/index.js +1 -1
  15. package/src/plugins/GLTFLoaderPlugin/GLTFLoaderPlugin.js +2 -110
  16. package/src/plugins/GLTFLoaderPlugin/GLTFSceneModelLoader.js +252 -222
  17. package/src/plugins/StoreyViewsPlugin/StoreyViewsPlugin.js +31 -1
  18. package/src/plugins/XKTLoaderPlugin/XKTLoaderPlugin.js +20 -8
  19. package/src/plugins/ZonesPlugin/ZonesPlugin.js +1939 -0
  20. package/src/plugins/ZonesPlugin/index.js +1 -1875
  21. package/src/viewer/Viewer.js +2 -2
  22. package/src/viewer/metadata/MetaScene.js +0 -2
  23. package/src/viewer/scene/math/MeshSurfaceArea.js +90 -0
  24. package/src/viewer/scene/math/MeshVolume.js +102 -0
  25. package/src/viewer/scene/math/index.js +3 -0
  26. package/src/viewer/scene/math/isTriangleMeshSolid.js +162 -0
  27. package/src/viewer/scene/math/math.js +8 -0
  28. package/src/viewer/scene/model/SceneModel.js +73 -34
  29. package/src/viewer/scene/model/SceneModelEntity.js +46 -1
  30. package/src/viewer/scene/model/SceneModelMesh.js +74 -1
  31. package/src/viewer/scene/model/SceneModelTextureSet.js +5 -0
  32. package/src/viewer/scene/model/dtx/lines/DTXLinesLayer.js +7 -1
  33. package/src/viewer/scene/model/dtx/triangles/DTXTrianglesLayer.js +77 -1
  34. package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesSnapInitRenderer.js +8 -0
  35. package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesSnapRenderer.js +8 -0
  36. package/src/viewer/scene/model/vbo/VBORenderer.js +10 -1
  37. package/src/viewer/scene/model/vbo/batching/lines/VBOBatchingLinesLayer.js +6 -1
  38. package/src/viewer/scene/model/vbo/batching/lines/renderers/VBOBatchingLinesSnapRenderer.js +1 -1
  39. package/src/viewer/scene/model/vbo/batching/points/VBOBatchingPointsLayer.js +6 -1
  40. package/src/viewer/scene/model/vbo/batching/triangles/VBOBatchingTrianglesLayer.js +59 -18
  41. package/src/viewer/scene/model/vbo/batching/triangles/renderers/Renderers.js +40 -12
  42. package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesBatchingRenderer.js +2 -3
  43. package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesColorTextureRenderer.js +25 -7
  44. package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesSnapRenderer.js +1 -1
  45. package/src/viewer/scene/model/vbo/instancing/lines/VBOInstancingLinesLayer.js +6 -1
  46. package/src/viewer/scene/model/vbo/instancing/lines/renderers/VBOInstancingLinesSnapRenderer.js +1 -1
  47. package/src/viewer/scene/model/vbo/instancing/points/VBOInstancingPointsLayer.js +6 -1
  48. package/src/viewer/scene/model/vbo/instancing/triangles/VBOInstancingTrianglesLayer.js +48 -14
  49. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/Renderers.js +74 -47
  50. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesColorTextureRenderer.js +29 -14
  51. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesInstancingRenderer.js +5 -4
  52. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesSnapRenderer.js +1 -1
  53. package/src/viewer/scene/scene/Scene.js +16 -5
  54. package/src/viewer/scene/webgl/occlusion/OcclusionLayer.js +1 -1
  55. package/src/viewer/scene/webgl/occlusion/OcclusionTester.js +1 -5
  56. package/types/plugins/DistanceMeasurementsPlugin/DistanceMeasurement.d.ts +7 -0
  57. package/types/plugins/DistanceMeasurementsPlugin/DistanceMeasurementsPlugin.d.ts +26 -1
  58. package/types/plugins/DistanceMeasurementsPlugin/index.d.ts +3 -1
@@ -5280,6 +5280,14 @@ const math = {
5280
5280
  return aabb[0] > p[0] || aabb[3] < p[0] || aabb[1] > p[1] || aabb[4] < p[1] || aabb[2] > p[2] || aabb[5] < p[2];
5281
5281
  },
5282
5282
 
5283
+ point3AABB3AbsoluteIntersect(aabb, p) {
5284
+ return (
5285
+ aabb[0] <= p[0] && aabb[3] >= p[0] &&
5286
+ aabb[1] <= p[1] && aabb[4] >= p[1] &&
5287
+ aabb[2] <= p[2] && aabb[5] >= p[2]
5288
+ );
5289
+ },
5290
+
5283
5291
  /**
5284
5292
  *
5285
5293
  * @param dir
@@ -9285,7 +9293,7 @@ class PointerCircle {
9285
9293
  destroy() {
9286
9294
  if (!this._destroyed) {
9287
9295
  this.stop();
9288
- document.body.removeChild(this._circleDiv);
9296
+ this._circleDiv.parentElement.removeChild(this._circleDiv);
9289
9297
  this._destroyed = true;
9290
9298
  }
9291
9299
  }
@@ -10541,7 +10549,7 @@ class SceneModelEntity {
10541
10549
  for (let i = 0, len = this.meshes.length; i < len; i++) {
10542
10550
  this.meshes[i]._setOffset(this._offset);
10543
10551
  }
10544
- this._aabbDirty = true;
10552
+ this._aabbDirty = true;
10545
10553
  this.model._aabbDirty = true;
10546
10554
  this.scene._aabbDirty = true;
10547
10555
  this.scene._objectOffsetUpdated(this, offset);
@@ -10558,6 +10566,51 @@ class SceneModelEntity {
10558
10566
  }
10559
10567
  }
10560
10568
 
10569
+ getEachIndex(callback) {
10570
+ for (let i = 0, len = this.meshes.length; i < len; i++) {
10571
+ this.meshes[i].getEachIndex(callback);
10572
+ }
10573
+ }
10574
+
10575
+ /**
10576
+ * Returns the volume of this SceneModelEntity.
10577
+ *
10578
+ * Only works when {@link Scene.readableGeometryEnabled | Scene.readableGeometryEnabled} is `true` and the
10579
+ * SceneModelEntity contains solid triangle meshes; returns `0` otherwise.
10580
+ *
10581
+ * @returns {number}
10582
+ */
10583
+ get volume() {
10584
+ let volume = 0;
10585
+ for (let i = 0, len = this.meshes.length; i < len; i++) {
10586
+ const meshVolume = this.meshes[i].volume;
10587
+ if (meshVolume < 0) {
10588
+ return -1;
10589
+ }
10590
+ volume += meshVolume;
10591
+ }
10592
+ return volume;
10593
+ }
10594
+
10595
+ /**
10596
+ * Returns the surface area of this SceneModelEntity.
10597
+ *
10598
+ * Only works when {@link Scene.readableGeometryEnabled | Scene.readableGeometryEnabled} is `true` and the
10599
+ * SceneModelEntity contains triangle meshes; returns `0` otherwise.
10600
+ *
10601
+ * @returns {number}
10602
+ */
10603
+ get surfaceArea() {
10604
+ let surfaceArea = 0;
10605
+ for (let i = 0, len = this.meshes.length; i < len; i++) {
10606
+ const meshSurfaceArea = this.meshes[i].surfaceArea;
10607
+ if (meshSurfaceArea >= 0) {
10608
+ surfaceArea += meshSurfaceArea;
10609
+ }
10610
+ }
10611
+ return surfaceArea > 0 ? surfaceArea : -1;
10612
+ }
10613
+
10561
10614
  _getFlag(flag) {
10562
10615
  return !!(this._flags & flag);
10563
10616
  }
@@ -10622,7 +10675,7 @@ class SceneModelEntity {
10622
10675
  }
10623
10676
  }
10624
10677
 
10625
- const tempVec4a$9 = math.vec4();
10678
+ const tempVec4a$a = math.vec4();
10626
10679
  const tempVec4b$6 = math.vec4();
10627
10680
 
10628
10681
 
@@ -10782,9 +10835,9 @@ class Marker extends Component {
10782
10835
  this.fire("viewPos", this._viewPos);
10783
10836
  }
10784
10837
  if (this._canvasPosDirty) {
10785
- tempVec4a$9.set(this._viewPos);
10786
- tempVec4a$9[3] = 1.0;
10787
- math.transformPoint4(this.scene.camera.projMatrix, tempVec4a$9, tempVec4b$6);
10838
+ tempVec4a$a.set(this._viewPos);
10839
+ tempVec4a$a[3] = 1.0;
10840
+ math.transformPoint4(this.scene.camera.projMatrix, tempVec4a$a, tempVec4b$6);
10788
10841
  const aabb = this.scene.canvas.boundary;
10789
10842
  this._canvasPos[0] = Math.floor((1 + tempVec4b$6[0] / tempVec4b$6[3]) * aabb[2] / 2);
10790
10843
  this._canvasPos[1] = Math.floor((1 - tempVec4b$6[1] / tempVec4b$6[3]) * aabb[3] / 2);
@@ -12614,22 +12667,13 @@ class AngleMeasurementsMouseControl extends AngleMeasurementsControl {
12614
12667
  this.pointerLens = cfg.pointerLens;
12615
12668
 
12616
12669
  this._active = false;
12617
- this._mouseState = MOUSE_FINDING_ORIGIN;
12618
12670
 
12619
12671
  this._currentAngleMeasurement = null;
12620
12672
 
12621
- // init markerDiv element (think about making its style configurable)
12622
12673
  this._initMarkerDiv();
12623
12674
 
12624
- this._onMouseHoverSurface = null;
12625
- this._onHoverNothing = null;
12626
- this._onPickedNothing = null;
12627
- this._onPickedSurface = null;
12628
-
12629
- this._onInputMouseDown = null;
12630
- this._onInputMouseUp = null;
12631
-
12632
12675
  this._snapping = cfg.snapping !== false;
12676
+ this._mouseState = MOUSE_FINDING_ORIGIN;
12633
12677
 
12634
12678
  this._attachPlugin(angleMeasurementsPlugin, cfg);
12635
12679
  }
@@ -12694,20 +12738,10 @@ class AngleMeasurementsMouseControl extends AngleMeasurementsControl {
12694
12738
  *
12695
12739
  * This is `true` by default.
12696
12740
  *
12697
- * Internally, this deactivates then activates the AngleMeasurementsMouseControl when changed, which means that
12698
- * it will destroy any AngleMeasurements currently under construction, and incurs some overhead, since it unbinds
12699
- * and rebinds various input handlers.
12700
- *
12701
12741
  * @param {boolean} snapping Whether to enable snap-to-vertex and snap-edge for this AngleMeasurementsMouseControl.
12702
12742
  */
12703
12743
  set snapping(snapping) {
12704
- if (snapping !== this._snapping) {
12705
- this._snapping = snapping;
12706
- this.deactivate();
12707
- this.activate();
12708
- } else {
12709
- this._snapping = snapping;
12710
- }
12744
+ this._snapping = snapping;
12711
12745
  }
12712
12746
 
12713
12747
  /**
@@ -12751,11 +12785,7 @@ class AngleMeasurementsMouseControl extends AngleMeasurementsControl {
12751
12785
 
12752
12786
  const pagePos = math.vec2();
12753
12787
 
12754
- this._onMouseHoverSurface = cameraControl.on(
12755
- this._snapping
12756
- ? "hoverSnapOrSurface"
12757
- : "hoverSurface",
12758
- event => {
12788
+ const hoverOn = event => {
12759
12789
  if (event.snappedToVertex || event.snappedToEdge) {
12760
12790
  if (pointerLens) {
12761
12791
  pointerLens.visible = true;
@@ -12817,7 +12847,10 @@ class AngleMeasurementsMouseControl extends AngleMeasurementsControl {
12817
12847
  canvas.style.cursor = "pointer";
12818
12848
  break;
12819
12849
  }
12820
- });
12850
+ };
12851
+ this._onHoverSnapOrSurface = cameraControl.on("hoverSnapOrSurface", e => { if (this._snapping) hoverOn(e); });
12852
+ this._onHoverSurface = cameraControl.on("hoverSurface", e => { if (! this._snapping) hoverOn(e); });
12853
+
12821
12854
  canvas.addEventListener('mousedown', this._onMouseDown = (e) => {
12822
12855
  if (e.which !== 1) {
12823
12856
  return;
@@ -12905,11 +12938,8 @@ class AngleMeasurementsMouseControl extends AngleMeasurementsControl {
12905
12938
  break;
12906
12939
  }
12907
12940
  });
12908
- this._onMouseHoverOff = cameraControl.on(
12909
- this._snapping
12910
- ? "hoverSnapOrSurfaceOff"
12911
- : "hoverOff",
12912
- event => {
12941
+
12942
+ const hoverOff = event => {
12913
12943
  mouseHovering = false;
12914
12944
  if (pointerLens) {
12915
12945
  pointerLens.visible = true;
@@ -12939,7 +12969,10 @@ class AngleMeasurementsMouseControl extends AngleMeasurementsControl {
12939
12969
  }
12940
12970
  canvas.style.cursor = "default";
12941
12971
  }
12942
- });
12972
+ };
12973
+ this._onHoverSnapOrSurfaceOff = cameraControl.on("hoverSnapOrSurfaceOff", e => { if (this._snapping) hoverOff(e); });
12974
+ this._onHoverOff = cameraControl.on("hoverOff", e => { if (! this._snapping) hoverOff(e); });
12975
+
12943
12976
  this._active = true;
12944
12977
  }
12945
12978
 
@@ -12952,22 +12985,22 @@ class AngleMeasurementsMouseControl extends AngleMeasurementsControl {
12952
12985
  if (!this._active) {
12953
12986
  return;
12954
12987
  }
12988
+
12955
12989
  if (this.pointerLens) {
12956
12990
  this.pointerLens.visible = false;
12957
12991
  }
12958
- if (this.markerDiv) {
12959
- this._destroyMarkerDiv();
12960
- }
12992
+
12961
12993
  this.reset();
12994
+
12962
12995
  const canvas = this.scene.canvas.canvas;
12963
12996
  canvas.removeEventListener("mousedown", this._onMouseDown);
12964
12997
  canvas.removeEventListener("mouseup", this._onMouseUp);
12965
12998
  const cameraControl = this.angleMeasurementsPlugin.viewer.cameraControl;
12966
- cameraControl.off(this._onMouseHoverSurface);
12967
- cameraControl.off(this._onPickedSurface);
12968
- cameraControl.off(this._onHoverNothing);
12969
- cameraControl.off(this._onPickedNothing);
12970
- this._currentAngleMeasurement = null;
12999
+ cameraControl.off(this._onHoverSnapOrSurface);
13000
+ cameraControl.off(this._onHoverSurface);
13001
+ cameraControl.off(this._onHoverSnapOrSurfaceOff);
13002
+ cameraControl.off(this._onHoverOff);
13003
+
12971
13004
  this._active = false;
12972
13005
  }
12973
13006
 
@@ -12990,6 +13023,7 @@ class AngleMeasurementsMouseControl extends AngleMeasurementsControl {
12990
13023
  this._currentAngleMeasurement.destroy();
12991
13024
  this._currentAngleMeasurement = null;
12992
13025
  }
13026
+
12993
13027
  this._mouseState = MOUSE_FINDING_ORIGIN;
12994
13028
  }
12995
13029
 
@@ -13505,8 +13539,6 @@ class AngleMeasurementsTouchControl extends AngleMeasurementsControl {
13505
13539
 
13506
13540
  this._currentAngleMeasurement = null;
13507
13541
 
13508
- this._onCanvasTouchStart = null;
13509
- this._onCanvasTouchEnd = null;
13510
13542
  this._longTouchTimeoutMs = 300;
13511
13543
  this._snapping = cfg.snapping !== false;
13512
13544
  this._touchState = WAITING_FOR_ORIGIN_TOUCH_START$1;
@@ -13542,20 +13574,10 @@ class AngleMeasurementsTouchControl extends AngleMeasurementsControl {
13542
13574
  *
13543
13575
  * This is `true` by default.
13544
13576
  *
13545
- * Internally, this deactivates then activates the AngleMeasurementsMouseControl when changed, which means that
13546
- * it will destroy any AngleMeasurements currently under construction, and incurs some overhead, since it unbinds
13547
- * and rebinds various input handlers.
13548
- *
13549
13577
  * @param {boolean} snapping Whether to enable snap-to-vertex and snap-edge for this AngleMeasurementsMouseControl.
13550
13578
  */
13551
13579
  set snapping(snapping) {
13552
- if (snapping !== this._snapping) {
13553
- this._snapping = snapping;
13554
- this.deactivate();
13555
- this.activate();
13556
- } else {
13557
- this._snapping = snapping;
13558
- }
13580
+ this._snapping = snapping;
13559
13581
  }
13560
13582
 
13561
13583
  /**
@@ -14325,14 +14347,11 @@ class AngleMeasurementsTouchControl extends AngleMeasurementsControl {
14325
14347
  this.plugin.pointerLens.visible = false;
14326
14348
  }
14327
14349
  this.reset();
14350
+
14328
14351
  const canvas = this.plugin.viewer.scene.canvas.canvas;
14329
14352
  canvas.removeEventListener("touchstart", this._onCanvasTouchStart);
14330
14353
  canvas.removeEventListener("touchend", this._onCanvasTouchEnd);
14331
- if (this._currentAngleMeasurement) {
14332
- this.angleMeasurementsPlugin.fire("measurementCancel", this._currentAngleMeasurement);
14333
- this._currentAngleMeasurement.destroy();
14334
- this._currentAngleMeasurement = null;
14335
- }
14354
+
14336
14355
  this._active = false;
14337
14356
  this.plugin.viewer.cameraControl.active = true;
14338
14357
  }
@@ -17448,7 +17467,7 @@ class OcclusionLayer {
17448
17467
  for (let i = 0; i < this.numMarkers; i++) {
17449
17468
  if (this.markerList[i]) {
17450
17469
  const marker = this.markerList[i];
17451
- const worldPos = marker.worldPos;
17470
+ const worldPos = marker.rtcPos;
17452
17471
  this.positions[j++] = worldPos[0];
17453
17472
  this.positions[j++] = worldPos[1];
17454
17473
  this.positions[j++] = worldPos[2];
@@ -17890,10 +17909,7 @@ class OcclusionTester {
17890
17909
  continue;
17891
17910
  }
17892
17911
 
17893
- // The `origin` has been changed from `occlusionLayer.origin` to `[ 0, 0, 0 ]`
17894
- // because OcclusionLayer markers' transformation is being applied through the
17895
- // OcclusionLayer::positions array. See XEOK-33
17896
- const origin = [ 0, 0, 0 ];
17912
+ const origin = occlusionLayer.origin;
17897
17913
 
17898
17914
  gl.uniformMatrix4fv(this._uViewMatrix, false, createRTCViewMat(camera.viewMatrix, origin));
17899
17915
 
@@ -23515,7 +23531,7 @@ const tempVec3c$u = math.vec3();
23515
23531
  const tempVec3d$d = math.vec3();
23516
23532
  const tempVec3e$2 = math.vec3();
23517
23533
  const tempVec3f$2 = math.vec3();
23518
- const tempVec4a$8 = math.vec4();
23534
+ const tempVec4a$9 = math.vec4();
23519
23535
  const tempVec4b$5 = math.vec4();
23520
23536
  const tempVec4c$2 = math.vec4();
23521
23537
  const tempMat = math.mat4();
@@ -24381,7 +24397,7 @@ class Camera extends Component {
24381
24397
  * @returns {[number, number]} the canvas position
24382
24398
  */
24383
24399
  projectWorldPos(worldPos) {
24384
- const _worldPos = tempVec4a$8;
24400
+ const _worldPos = tempVec4a$9;
24385
24401
  const viewPos = tempVec4b$5;
24386
24402
  const screenPos = tempVec4c$2;
24387
24403
  _worldPos[0] = worldPos[0];
@@ -30136,6 +30152,8 @@ class Scene extends Component {
30136
30152
 
30137
30153
  this._aabbDirty = true;
30138
30154
 
30155
+ this._readableGeometry = !!cfg.readableGeometryEnabled;
30156
+
30139
30157
  /**
30140
30158
  * The {@link Viewer} this Scene belongs to.
30141
30159
  * @type {Viewer}
@@ -31015,18 +31033,27 @@ class Scene extends Component {
31015
31033
  }
31016
31034
 
31017
31035
  /**
31018
- * Whether precision surface picking is enabled.
31036
+ * Whether geometry is readable.
31019
31037
  *
31020
31038
  * This is set via the {@link Viewer} constructor and is ````false```` by default.
31021
31039
  *
31022
- * The ````pickSurfacePrecision```` option for ````Scene#pick```` only works if this is set ````true````.
31040
+ * The ````readableGeometryEnabled```` option for ````Scene#pick```` only works if this is set ````true````.
31023
31041
  *
31024
31042
  * Note that when ````true````, this configuration will increase the amount of browser memory used by the Viewer.
31025
31043
  *
31026
- * @returns {Boolean} True if precision picking is enabled.
31044
+ * @returns {Boolean} True if geometry is readable.
31045
+ */
31046
+ get readableGeometryEnabled() {
31047
+ return this._readableGeometry;
31048
+ }
31049
+
31050
+ /**
31051
+ * Whether precision surface picking is enabled.
31052
+ * @deprecated
31053
+ * @returns {*|boolean}
31027
31054
  */
31028
31055
  get pickSurfacePrecisionEnabled() {
31029
- return false; // Removed
31056
+ return this._readableGeometry;
31030
31057
  }
31031
31058
 
31032
31059
  /**
@@ -32004,7 +32031,7 @@ class Scene extends Component {
32004
32031
  *
32005
32032
  * @param {*} params Picking parameters.
32006
32033
  * @param {Boolean} [params.pickSurface=false] Whether to find the picked position on the surface of the Entity.
32007
- * @param {Boolean} [params.pickSurfacePrecision=false] When picking an Entity surface position, indicates whether or not we want full-precision {@link PickResult#worldPos}. Only works when {@link Scene#pickSurfacePrecisionEnabled} is ````true````. If pick succeeds, the returned {@link PickResult} will have {@link PickResult#precision} set ````true````, to indicate that it contains full-precision surface pick results.
32034
+ * @param {Boolean} [params.pickSurfacePrecision=false] When picking an Entity surface position, indicates whether or not we want full-precision {@link PickResult#worldPos}. Only works when {@link Scene#readableGeometryEnabled} is ````true````. If pick succeeds, the returned {@link PickResult} will have {@link PickResult#precision} set ````true````, to indicate that it contains full-precision surface pick results.
32008
32035
  * @param {Boolean} [params.pickSurfaceNormal=false] Whether to find the picked normal on the surface of the Entity. Only works if ````pickSurface```` is given.
32009
32036
  * @param {Number[]} [params.canvasPos] Canvas-space coordinates. When ray-picking, this will override the **origin** and ** direction** parameters and will cause the ray to be fired through the canvas at this position, directly along the negative View-space Z-axis.
32010
32037
  * @param {Number[]} [params.origin] World-space ray origin when ray-picking. Ignored when canvasPos given.
@@ -50604,10 +50631,360 @@ class Bitmap extends Component {
50604
50631
  }
50605
50632
  }
50606
50633
 
50634
+ /**
50635
+ * Uses edge adjacency counts to identify if the given triangle mesh can be rendered with backface culling enabled.
50636
+ *
50637
+ * If all edges are connected to exactly two triangles, then the mesh will likely be a closed solid, and we can safely
50638
+ * render it with backface culling enabled.
50639
+ *
50640
+ * Otherwise, the mesh is a surface, and we must render it with backface culling disabled.
50641
+ *
50642
+ * @private
50643
+ */
50644
+ const isTriangleMeshSolid = (indices, positions) => {
50645
+
50646
+ const vertexIndexMapping = [];
50647
+ let edges = [];
50648
+
50649
+ function compareIndexPositions(a, b) {
50650
+ let posA, posB;
50651
+
50652
+ for (let i = 0; i < 3; i++) {
50653
+ posA = positions [a * 3 + i];
50654
+ posB = positions [b * 3 + i];
50655
+
50656
+ if (posA !== posB) {
50657
+ return posB - posA;
50658
+ }
50659
+ }
50660
+
50661
+ return 0;
50662
+ }
50663
+ // Group together indices corresponding to same position coordinates
50664
+ let newIndices = indices.slice().sort(compareIndexPositions);
50665
+
50666
+ // Calculate the mapping:
50667
+ // - from original index in indices array
50668
+ // - to indices-for-unique-positions
50669
+ let uniqueVertexIndex = null;
50670
+
50671
+ for (let i = 0, len = newIndices.length; i < len; i++) {
50672
+ if (i === 0 || 0 !== compareIndexPositions(
50673
+ newIndices[i],
50674
+ newIndices[i - 1],
50675
+ )) {
50676
+ // different position
50677
+ uniqueVertexIndex = newIndices [i];
50678
+ }
50679
+
50680
+ vertexIndexMapping [
50681
+ newIndices[i]
50682
+ ] = uniqueVertexIndex;
50683
+ }
50684
+
50685
+ // Generate the list of edges
50686
+ for (let i = 0, len = indices.length; i < len; i += 3) {
50687
+
50688
+ const a = vertexIndexMapping[indices[i]];
50689
+ const b = vertexIndexMapping[indices[i + 1]];
50690
+ const c = vertexIndexMapping[indices[i + 2]];
50691
+
50692
+ let a2 = a;
50693
+ let b2 = b;
50694
+ let c2 = c;
50695
+
50696
+ if (a > b && a > c) {
50697
+ if (b > c) {
50698
+ a2 = a;
50699
+ b2 = b;
50700
+ c2 = c;
50701
+ } else {
50702
+ a2 = a;
50703
+ b2 = c;
50704
+ c2 = b;
50705
+ }
50706
+ } else if (b > a && b > c) {
50707
+ if (a > c) {
50708
+ a2 = b;
50709
+ b2 = a;
50710
+ c2 = c;
50711
+ } else {
50712
+ a2 = b;
50713
+ b2 = c;
50714
+ c2 = a;
50715
+ }
50716
+ } else if (c > a && c > b) {
50717
+ if (a > b) {
50718
+ a2 = c;
50719
+ b2 = a;
50720
+ c2 = b;
50721
+ } else {
50722
+ a2 = c;
50723
+ b2 = b;
50724
+ c2 = a;
50725
+ }
50726
+ }
50727
+
50728
+ edges[i + 0] = [
50729
+ a2, b2
50730
+ ];
50731
+ edges[i + 1] = [
50732
+ b2, c2
50733
+ ];
50734
+
50735
+ if (a2 > c2) {
50736
+ const temp = c2;
50737
+ c2 = a2;
50738
+ a2 = temp;
50739
+ }
50740
+
50741
+ edges[i + 2] = [
50742
+ c2, a2
50743
+ ];
50744
+ }
50745
+
50746
+ // Group semantically equivalent edgdes together
50747
+ function compareEdges(e1, e2) {
50748
+ let a, b;
50749
+
50750
+ for (let i = 0; i < 2; i++) {
50751
+ a = e1[i];
50752
+ b = e2[i];
50753
+
50754
+ if (b !== a) {
50755
+ return b - a;
50756
+ }
50757
+ }
50758
+
50759
+ return 0;
50760
+ }
50761
+
50762
+ edges = edges.slice(0, indices.length);
50763
+
50764
+ edges.sort(compareEdges);
50765
+
50766
+ // Make sure each edge is used exactly twice
50767
+ let sameEdgeCount = 0;
50768
+
50769
+ for (let i = 0; i < edges.length; i++) {
50770
+ if (i === 0 || 0 !== compareEdges(
50771
+ edges[i], edges[i - 1]
50772
+ )) {
50773
+ // different edge
50774
+ if (0 !== i && sameEdgeCount !== 2) {
50775
+ return false;
50776
+ }
50777
+
50778
+ sameEdgeCount = 1;
50779
+ } else {
50780
+ // same edge
50781
+ sameEdgeCount++;
50782
+ }
50783
+ }
50784
+
50785
+ if (edges.length > 0 && sameEdgeCount !== 2) {
50786
+ return false;
50787
+ }
50788
+
50789
+ // Each edge is used exactly twice, this is a
50790
+ // watertight surface and hence a solid geometry.
50791
+ return true;
50792
+ };
50793
+
50794
+ const v1$1 = math.vec3();
50795
+ const v2$1 = math.vec3();
50796
+ const v3$1 = math.vec3();
50797
+
50798
+ /**
50799
+ * Calculates the volume of triangle meshes.
50800
+ */
50801
+ class MeshVolume {
50802
+ constructor() {
50803
+ this.vertices = [];
50804
+ this.indices = [];
50805
+ this.reset();
50806
+ }
50807
+
50808
+ /**
50809
+ * Resets, ready to add vertices and indices for a new mesh.
50810
+ */
50811
+ reset() {
50812
+ this.lenVertices = 0;
50813
+ this.lenIndices = 0;
50814
+ this.primitive = null;
50815
+ }
50816
+
50817
+ setPrimitive(primitive) {
50818
+ this.primitive = primitive;
50819
+ }
50820
+
50821
+ /**
50822
+ * Adds a vertex.
50823
+ * @param vertex
50824
+ */
50825
+ addVertex(vertex) {
50826
+ this.vertices[this.lenVertices++] = vertex[0];
50827
+ this.vertices[this.lenVertices++] = vertex[1];
50828
+ this.vertices[this.lenVertices++] = vertex[2];
50829
+ }
50830
+
50831
+ /**
50832
+ * Adds an index.
50833
+ * @param index
50834
+ */
50835
+ addIndex(index) {
50836
+ this.indices[this.lenIndices++] = index;
50837
+ }
50838
+
50839
+ /**
50840
+ * Gets the volume of the mesh.
50841
+ *
50842
+ * The mesh must be a closed solid.
50843
+ *
50844
+ * @returns {number} The volume of the mesh, or -1 if the mesh is not solid, in which case volume cannot be determined.
50845
+ */
50846
+ get volume() {
50847
+
50848
+ const vertices = this.vertices;
50849
+ const indices = this.indices;
50850
+
50851
+ if (this.primitive !== "solid" && this.primitive !== "surface" && this.primitive !== "triangles") {
50852
+ return -1;
50853
+ }
50854
+
50855
+ if (this.primitive !== "solid" && !isTriangleMeshSolid(indices, vertices)) {
50856
+ return -1;
50857
+ }
50858
+
50859
+ let volume = 0;
50860
+
50861
+ for (let i = 0; i < this.lenIndices; i += 3) {
50862
+
50863
+ const index1 = indices[i] * 3;
50864
+ const index2 = indices[i + 1] * 3;
50865
+ const index3 = indices[i + 2] * 3;
50866
+
50867
+ v1$1[0] = vertices[index1];
50868
+ v1$1[1] = vertices[index1 + 1];
50869
+ v1$1[2] = vertices[index1 + 2];
50870
+
50871
+ v2$1[0] = vertices[index2];
50872
+ v2$1[1] = vertices[index2 + 1];
50873
+ v2$1[2] = vertices[index2 + 2];
50874
+
50875
+ v3$1[0] = vertices[index3];
50876
+ v3$1[1] = vertices[index3 + 1];
50877
+ v3$1[2] = vertices[index3 + 2];
50878
+
50879
+ math.cross3Vec3(v1$1, v2$1, v1$1);
50880
+
50881
+ volume += math.dotVec3(v1$1, v3$1);
50882
+ }
50883
+
50884
+ return volume;
50885
+ }
50886
+ }
50887
+
50888
+ /**
50889
+ * Singleton instance of {@link MeshVolume}.
50890
+ * @type {MeshVolume}
50891
+ */
50892
+ const meshVolume = new MeshVolume();
50893
+
50894
+ const v1 = math.vec3();
50895
+ const v2 = math.vec3();
50896
+ const v3 = math.vec3();
50897
+ const v4 = math.vec3();
50898
+ const v5 = math.vec3();
50899
+ const v6 = math.vec3();
50900
+
50901
+ /**
50902
+ * Calculates the surface area of triangle meshes.
50903
+ */
50904
+ class MeshSurfaceArea {
50905
+ constructor() {
50906
+ this.vertices = [];
50907
+ this.indices = [];
50908
+ this.reset();
50909
+ }
50910
+
50911
+ /**
50912
+ * Resets, ready to add vertices and indices for a new mesh.
50913
+ */
50914
+ reset() {
50915
+ this.lenVertices = 0;
50916
+ this.lenIndices = 0;
50917
+ }
50918
+
50919
+ /**
50920
+ * Adds a vertex.
50921
+ * @param vertex
50922
+ */
50923
+ addVertex(vertex) {
50924
+ this.vertices[this.lenVertices++] = vertex[0];
50925
+ this.vertices[this.lenVertices++] = vertex[1];
50926
+ this.vertices[this.lenVertices++] = vertex[2];
50927
+ }
50928
+
50929
+ /**
50930
+ * Adds an index.
50931
+ * @param index
50932
+ */
50933
+ addIndex(index) {
50934
+ this.indices[this.lenIndices++] = index;
50935
+ }
50936
+
50937
+ /**
50938
+ * Gets the surface area of the mesh.
50939
+ *
50940
+ * @returns {number}
50941
+ */
50942
+ get surfaceArea() {
50943
+
50944
+ const vertices = this.vertices;
50945
+ const indices = this.indices;
50946
+
50947
+ let surfaceArea = 0;
50948
+
50949
+ for (let i = 0; i < this.lenIndices; i += 3) {
50950
+
50951
+ const index1 = indices[i] * 3;
50952
+ const index2 = indices[i + 1] * 3;
50953
+ const index3 = indices[i + 2] * 3;
50954
+
50955
+ v1[0] = vertices[index1];
50956
+ v1[1] = vertices[index1 + 1];
50957
+ v1[2] = vertices[index1 + 2];
50958
+
50959
+ v2[0] = vertices[index2];
50960
+ v2[1] = vertices[index2 + 1];
50961
+ v2[2] = vertices[index2 + 2];
50962
+
50963
+ v3[0] = vertices[index3];
50964
+ v3[1] = vertices[index3 + 1];
50965
+ v3[2] = vertices[index3 + 2];
50966
+
50967
+ math.subVec3(v1, v2, v4);
50968
+ math.subVec3(v3, v2, v5);
50969
+
50970
+ surfaceArea += math.lenVec3(math.cross3Vec3(v4, v5, v6)) * 0.5;
50971
+ }
50972
+
50973
+ return surfaceArea;
50974
+ }
50975
+ }
50976
+
50977
+ /**
50978
+ * Singleton instance of {@link MeshSurfaceArea}.
50979
+ * @type {MeshSurfaceArea}
50980
+ */
50981
+ const meshSurfaceArea = new MeshSurfaceArea();
50982
+
50607
50983
  const tempOBB3$1 = math.OBB3();
50608
50984
  const tempOBB3b = math.OBB3();
50609
50985
  const tempOBB3c = math.OBB3();
50610
50986
 
50987
+
50611
50988
  /**
50612
50989
  * A mesh within a {@link SceneModel}.
50613
50990
  *
@@ -50720,6 +51097,9 @@ class SceneModelMesh {
50720
51097
  if (transform) {
50721
51098
  transform._addMesh(this);
50722
51099
  }
51100
+
51101
+ this._volume = null;
51102
+ this._surfaceArea = null;
50723
51103
  }
50724
51104
 
50725
51105
  _sceneModelDirty() {
@@ -50898,7 +51278,75 @@ class SceneModelMesh {
50898
51278
  * @private
50899
51279
  */
50900
51280
  getEachVertex(callback) {
50901
- this.layer.getEachVertex(this.portionId, callback);
51281
+ if (this.layer.getEachVertex) {
51282
+ this.layer.getEachVertex(this.portionId, callback);
51283
+ }
51284
+ }
51285
+
51286
+ /**
51287
+ * @private
51288
+ */
51289
+ getEachIndex(callback) {
51290
+ if (this.layer.getEachIndex ) {
51291
+ this.layer.getEachIndex(this.portionId, callback);
51292
+ }
51293
+ }
51294
+
51295
+ /**
51296
+ * Returns the volume of this SceneModelMesh.
51297
+ * @returns {number}
51298
+ */
51299
+ get volume() {
51300
+ if (this._volume !== null) {
51301
+ return this._volume;
51302
+ }
51303
+ switch (this.layer.primitive) {
51304
+ case "solid":
51305
+ case "surface":
51306
+ case "triangles":
51307
+ meshVolume.reset();
51308
+ meshVolume.setPrimitive(this.layer.primitive);
51309
+ this.getEachVertex((vertex) =>{
51310
+ meshVolume.addVertex(vertex);
51311
+ });
51312
+ this.getEachIndex((index)=>{
51313
+ meshVolume.addIndex(index);
51314
+ });
51315
+ this._volume = meshVolume.volume;
51316
+ break;
51317
+ default:
51318
+ this._volume = 0;
51319
+ break;
51320
+ }
51321
+ return this._volume;
51322
+ }
51323
+
51324
+ /**
51325
+ * Returns the surface area of this SceneModelMesh.
51326
+ * @returns {number}
51327
+ */
51328
+ get surfaceArea() {
51329
+ if (this._surfaceArea !== null) {
51330
+ return this._surfaceArea;
51331
+ }
51332
+ switch (this.layer.primitive) {
51333
+ case "solid":
51334
+ case "surface":
51335
+ case "triangles":
51336
+ meshSurfaceArea.reset();
51337
+ this.getEachVertex((vertex) =>{
51338
+ meshSurfaceArea.addVertex(vertex);
51339
+ });
51340
+ this.getEachIndex((index)=>{
51341
+ meshSurfaceArea.addIndex(index);
51342
+ });
51343
+ this._surfaceArea = meshSurfaceArea.surfaceArea;
51344
+ break;
51345
+ default:
51346
+ this._surfaceArea = 0;
51347
+ break;
51348
+ }
51349
+ return this._surfaceArea;
50902
51350
  }
50903
51351
 
50904
51352
  /**
@@ -51051,11 +51499,12 @@ const tempMat4a$r = math.mat4();
51051
51499
  * @private
51052
51500
  */
51053
51501
  class VBORenderer {
51054
- constructor(scene, withSAO = false, {instancing = false, edges = false} = {}) {
51502
+ constructor(scene, withSAO = false, {instancing = false, edges = false, useAlphaCutoff = false} = {}) {
51055
51503
  this._scene = scene;
51056
51504
  this._withSAO = withSAO;
51057
51505
  this._instancing = instancing;
51058
51506
  this._edges = edges;
51507
+ this._useAlphaCutoff = useAlphaCutoff;
51059
51508
  this._hash = this._getHash();
51060
51509
 
51061
51510
  /**
@@ -51306,6 +51755,10 @@ class VBORenderer {
51306
51755
  this._uSAOParams = program.getLocation("uSAOParams");
51307
51756
  }
51308
51757
 
51758
+ if (this._useAlphaCutoff) {
51759
+ this._alphaCutoffLocation = program.getLocation("materialAlphaCutoff");
51760
+ }
51761
+
51309
51762
  if (scene.logarithmicDepthBufferEnabled) {
51310
51763
  this._uLogDepthBufFC = program.getLocation("logDepthBufFC");
51311
51764
  }
@@ -51643,6 +52096,10 @@ class VBORenderer {
51643
52096
  }
51644
52097
  }
51645
52098
 
52099
+ if (this._useAlphaCutoff) {
52100
+ gl.uniform1f(this._alphaCutoffLocation, textureSet.alphaCutoff);
52101
+ }
52102
+
51646
52103
  if (colorUniform) {
51647
52104
  const colorKey = this._edges ? "edgeColor" : "fillColor";
51648
52105
  const alphaKey = this._edges ? "edgeAlpha" : "fillAlpha";
@@ -51693,8 +52150,8 @@ class VBORenderer {
51693
52150
  */
51694
52151
  class TrianglesBatchingRenderer extends VBORenderer {
51695
52152
 
51696
- constructor(scene, withSAO, {edges = false} = {}) {
51697
- super(scene, withSAO, {instancing: false, edges});
52153
+ constructor(scene, withSAO, {edges = false, useAlphaCutoff = false} = {}) {
52154
+ super(scene, withSAO, {instancing: false, edges, useAlphaCutoff});
51698
52155
  }
51699
52156
 
51700
52157
  _draw(drawCfg) {
@@ -51711,7 +52168,6 @@ class TrianglesBatchingRenderer extends VBORenderer {
51711
52168
  } else {
51712
52169
  const count = frameCtx.pickElementsCount || state.indicesBuf.numItems;
51713
52170
  const offset = frameCtx.pickElementsOffset ? frameCtx.pickElementsOffset * state.indicesBuf.itemByteSize : 0;
51714
-
51715
52171
  gl.drawElements(gl.TRIANGLES, count, state.indicesBuf.itemType, offset);
51716
52172
 
51717
52173
  if (incrementDrawState) {
@@ -54164,6 +54620,7 @@ class TrianglesPickNormalsFlatRenderer$1 extends TrianglesBatchingRenderer {
54164
54620
  /**
54165
54621
  * @private
54166
54622
  */
54623
+
54167
54624
  class TrianglesColorTextureRenderer$1 extends TrianglesBatchingRenderer {
54168
54625
  _getHash() {
54169
54626
  const scene = this._scene;
@@ -54171,11 +54628,10 @@ class TrianglesColorTextureRenderer$1 extends TrianglesBatchingRenderer {
54171
54628
  }
54172
54629
 
54173
54630
  drawLayer(frameCtx, layer, renderPass) {
54174
- super.drawLayer(frameCtx, layer, renderPass, {incrementDrawState: true});
54631
+ super.drawLayer(frameCtx, layer, renderPass, { incrementDrawState: true });
54175
54632
  }
54176
54633
 
54177
54634
  _buildVertexShader() {
54178
-
54179
54635
  const scene = this._scene;
54180
54636
  const sectionPlanesState = scene._sectionPlanesState;
54181
54637
  const clipping = sectionPlanesState.getNumAllocatedSectionPlanes() > 0;
@@ -54230,6 +54686,7 @@ class TrianglesColorTextureRenderer$1 extends TrianglesBatchingRenderer {
54230
54686
  if (scene.entityOffsetsEnabled) {
54231
54687
  src.push("worldPosition.xyz = worldPosition.xyz + offset;");
54232
54688
  }
54689
+
54233
54690
  src.push("vec4 viewPosition = viewMatrix * worldPosition; ");
54234
54691
  src.push("vViewPosition = viewPosition;");
54235
54692
  src.push("vColor = vec4(float(color.r) / 255.0, float(color.g) / 255.0, float(color.b) / 255.0, float(color.a) / 255.0);");
@@ -54240,10 +54697,12 @@ class TrianglesColorTextureRenderer$1 extends TrianglesBatchingRenderer {
54240
54697
  src.push("vFragDepth = 1.0 + clipPos.w;");
54241
54698
  src.push("isPerspective = float (isPerspectiveMatrix(projMatrix));");
54242
54699
  }
54700
+
54243
54701
  if (clipping) {
54244
54702
  src.push("vWorldPosition = worldPosition;");
54245
54703
  src.push("vFlags = flags;");
54246
54704
  }
54705
+
54247
54706
  src.push("gl_Position = clipPos;");
54248
54707
  src.push("}");
54249
54708
  src.push("}");
@@ -54256,6 +54715,7 @@ class TrianglesColorTextureRenderer$1 extends TrianglesBatchingRenderer {
54256
54715
  const lightsState = scene._lightsState;
54257
54716
  const sectionPlanesState = scene._sectionPlanesState;
54258
54717
  const clipping = sectionPlanesState.getNumAllocatedSectionPlanes() > 0;
54718
+ const useAlphaCutoff = this._useAlphaCutoff;
54259
54719
  const src = [];
54260
54720
  src.push("#version 300 es");
54261
54721
  src.push("// Triangles batching color texture fragment shader");
@@ -54314,6 +54774,7 @@ class TrianglesColorTextureRenderer$1 extends TrianglesBatchingRenderer {
54314
54774
  src.push("uniform vec4 sliceColor;");
54315
54775
  }
54316
54776
  this._addMatricesUniformBlockLines(src);
54777
+
54317
54778
  src.push("uniform vec4 lightAmbient;");
54318
54779
  for (let i = 0, len = lightsState.lights.length; i < len; i++) {
54319
54780
  const light = lightsState.lights[i];
@@ -54333,6 +54794,10 @@ class TrianglesColorTextureRenderer$1 extends TrianglesBatchingRenderer {
54333
54794
  }
54334
54795
  }
54335
54796
 
54797
+ if (useAlphaCutoff) {
54798
+ src.push("uniform float materialAlphaCutoff;");
54799
+ }
54800
+
54336
54801
  src.push("in vec4 vViewPosition;");
54337
54802
  src.push("in vec4 vColor;");
54338
54803
  src.push("in vec2 vUV;");
@@ -54400,11 +54865,21 @@ class TrianglesColorTextureRenderer$1 extends TrianglesBatchingRenderer {
54400
54865
  }
54401
54866
 
54402
54867
  src.push("vec4 color = vec4((lightAmbient.rgb * lightAmbient.a * newColor.rgb) + (reflectedColor * newColor.rgb), newColor.a);");
54868
+
54869
+ src.push("vec4 sampleColor = texture(uColorMap, vUV);");
54870
+
54871
+ if (useAlphaCutoff) {
54872
+ src.push("if (sampleColor.a < materialAlphaCutoff) {");
54873
+ src.push(" discard;");
54874
+ src.push("}");
54875
+ }
54876
+
54403
54877
  if (gammaOutput) {
54404
- src.push("vec4 colorTexel = color * sRGBToLinear(texture(uColorMap, vUV));");
54405
- } else {
54406
- src.push("vec4 colorTexel = color * texture(uColorMap, vUV);");
54878
+ src.push("sampleColor = sRGBToLinear(sampleColor);");
54407
54879
  }
54880
+
54881
+ src.push("vec4 colorTexel = color * sampleColor;");
54882
+
54408
54883
  src.push("float opacity = color.a;");
54409
54884
 
54410
54885
  if (this._withSAO) {
@@ -54951,7 +55426,7 @@ class TrianglesSnapRenderer$1 extends VBORenderer{
54951
55426
 
54952
55427
  src.push(`int pickFlag = int(flags) >> 12 & 0xF;`);
54953
55428
  src.push(`if (pickFlag != renderPass) {`);
54954
- src.push(" gl_Position = vec4(0.0, 0.0, 0.0, 0.0);"); // Cull vertex
55429
+ src.push(" gl_Position = vec4(2.0, 0.0, 0.0, 0.0);"); // Cull vertex
54955
55430
  src.push(" } else {");
54956
55431
  src.push(" vec4 worldPosition = worldMatrix * (positionsDecodeMatrix * vec4(position, 1.0)); ");
54957
55432
  if (scene.entityOffsetsEnabled) {
@@ -55078,6 +55553,14 @@ class Renderers$1 {
55078
55553
  this._colorTextureRendererWithSAO.destroy();
55079
55554
  this._colorTextureRendererWithSAO = null;
55080
55555
  }
55556
+ if (this._colorTextureRendererAlphaCutoff && (!this._colorTextureRendererAlphaCutoff.getValid())) {
55557
+ this._colorTextureRendererAlphaCutoff.destroy();
55558
+ this._colorTextureRendererAlphaCutoff = null;
55559
+ }
55560
+ if (this._colorTextureRendererWithSAOAlphaCutoff && (!this._colorTextureRendererWithSAOAlphaCutoff.getValid())) {
55561
+ this._colorTextureRendererWithSAOAlphaCutoff.destroy();
55562
+ this._colorTextureRendererWithSAOAlphaCutoff = null;
55563
+ }
55081
55564
  if (this._pbrRenderer && (!this._pbrRenderer.getValid())) {
55082
55565
  this._pbrRenderer.destroy();
55083
55566
  this._pbrRenderer = null;
@@ -55205,6 +55688,20 @@ class Renderers$1 {
55205
55688
  return this._colorTextureRendererWithSAO;
55206
55689
  }
55207
55690
 
55691
+ get colorTextureRendererAlphaCutoff() {
55692
+ if (!this._colorTextureRendererAlphaCutoff) {
55693
+ this._colorTextureRendererAlphaCutoff = new TrianglesColorTextureRenderer$1(this._scene, false, { useAlphaCutoff: true });
55694
+ }
55695
+ return this._colorTextureRendererAlphaCutoff;
55696
+ }
55697
+
55698
+ get colorTextureRendererWithSAOAlphaCutoff() {
55699
+ if (!this._colorTextureRendererWithSAOAlphaCutoff) {
55700
+ this._colorTextureRendererWithSAOAlphaCutoff = new TrianglesColorTextureRenderer$1(this._scene, true, { useAlphaCutoff: true });
55701
+ }
55702
+ return this._colorTextureRendererWithSAOAlphaCutoff;
55703
+ }
55704
+
55208
55705
  get pbrRenderer() {
55209
55706
  if (!this._pbrRenderer) {
55210
55707
  this._pbrRenderer = new TrianglesPBRRenderer$1(this._scene, false);
@@ -55329,6 +55826,12 @@ class Renderers$1 {
55329
55826
  if (this._colorTextureRendererWithSAO) {
55330
55827
  this._colorTextureRendererWithSAO.destroy();
55331
55828
  }
55829
+ if (this._colorTextureRendererAlphaCutoff) {
55830
+ this._colorTextureRendererAlphaCutoff.destroy();
55831
+ }
55832
+ if (this._colorTextureRendererWithSAOAlphaCutoff) {
55833
+ this._colorTextureRendererWithSAOAlphaCutoff.destroy();
55834
+ }
55332
55835
  if (this._pbrRenderer) {
55333
55836
  this._pbrRenderer.destroy();
55334
55837
  }
@@ -55377,29 +55880,29 @@ class Renderers$1 {
55377
55880
  }
55378
55881
  }
55379
55882
 
55380
- const cachdRenderers$1 = {};
55883
+ const cachedRenderers$6 = {};
55381
55884
 
55382
55885
  /**
55383
55886
  * @private
55384
55887
  */
55385
55888
  function getRenderers$7(scene) {
55386
55889
  const sceneId = scene.id;
55387
- let batchingRenderers = cachdRenderers$1[sceneId];
55388
- if (!batchingRenderers) {
55389
- batchingRenderers = new Renderers$1(scene);
55390
- cachdRenderers$1[sceneId] = batchingRenderers;
55391
- batchingRenderers._compile();
55392
- batchingRenderers.eagerCreateRenders();
55890
+ let renderers = cachedRenderers$6[sceneId];
55891
+ if (!renderers) {
55892
+ renderers = new Renderers$1(scene);
55893
+ cachedRenderers$6[sceneId] = renderers;
55894
+ renderers._compile();
55895
+ renderers.eagerCreateRenders();
55393
55896
  scene.on("compile", () => {
55394
- batchingRenderers._compile();
55395
- batchingRenderers.eagerCreateRenders();
55897
+ renderers._compile();
55898
+ renderers.eagerCreateRenders();
55396
55899
  });
55397
55900
  scene.on("destroyed", () => {
55398
- delete cachdRenderers$1[sceneId];
55399
- batchingRenderers._destroy();
55901
+ delete cachedRenderers$6[sceneId];
55902
+ renderers._destroy();
55400
55903
  });
55401
55904
  }
55402
- return batchingRenderers;
55905
+ return renderers;
55403
55906
  }
55404
55907
 
55405
55908
  let maxDataTextureHeight = 1 << 16;
@@ -55702,7 +56205,7 @@ function octDecodeVec2(oct) { // Decode an oct-encoded normal
55702
56205
 
55703
56206
  const tempMat4$1 = math.mat4();
55704
56207
  const tempMat4b = math.mat4();
55705
- const tempVec4a$7 = math.vec4([0, 0, 0, 1]);
56208
+ const tempVec4a$8 = math.vec4([0, 0, 0, 1]);
55706
56209
 
55707
56210
  const tempVec3a$z = math.vec3();
55708
56211
  const tempVec3b$v = math.vec3();
@@ -55732,7 +56235,7 @@ class VBOBatchingTrianglesLayer {
55732
56235
  */
55733
56236
  constructor(cfg) {
55734
56237
 
55735
- console.info("Creating VBOBatchingTrianglesLayer");
56238
+ // console.info("Creating VBOBatchingTrianglesLayer");
55736
56239
 
55737
56240
  /**
55738
56241
  * Owner model
@@ -55822,6 +56325,11 @@ class VBOBatchingTrianglesLayer {
55822
56325
  * @type {boolean}
55823
56326
  */
55824
56327
  this.solid = !!cfg.solid;
56328
+
56329
+ /**
56330
+ * The type of primitives in this layer.
56331
+ */
56332
+ this.primitive = cfg.primitive;
55825
56333
  }
55826
56334
 
55827
56335
  get aabb() {
@@ -56018,7 +56526,7 @@ class VBOBatchingTrianglesLayer {
56018
56526
  numIndices: indices.length,
56019
56527
  };
56020
56528
 
56021
- if (scene.pickSurfacePrecisionEnabled) {
56529
+ if (scene.readableGeometryEnabled) {
56022
56530
  // Quantized in-memory positions are initialized in finalize()
56023
56531
 
56024
56532
  portion.indices = indices;
@@ -56055,7 +56563,7 @@ class VBOBatchingTrianglesLayer {
56055
56563
  ? new Uint16Array(buffer.positions)
56056
56564
  : quantizePositions(buffer.positions, this._modelAABB, this._state.positionsDecodeMatrix = math.mat4()); // BOTTLENECK
56057
56565
  state.positionsBuf = new ArrayBuf(gl, gl.ARRAY_BUFFER, quantizedPositions, quantizedPositions.length, 3, gl.STATIC_DRAW);
56058
- if (this.model.scene.pickSurfacePrecisionEnabled) {
56566
+ if (this.model.scene.readableGeometryEnabled) {
56059
56567
  for (let i = 0, numPortions = this._portions.length; i < numPortions; i++) {
56060
56568
  const portion = this._portions[i];
56061
56569
  const start = portion.vertsBaseIndex * 3;
@@ -56484,7 +56992,7 @@ class VBOBatchingTrianglesLayer {
56484
56992
  if (this._state.offsetsBuf) {
56485
56993
  this._state.offsetsBuf.setData(tempArray, firstOffset, lenOffsets);
56486
56994
  }
56487
- if (this.model.scene.pickSurfacePrecisionEnabled) {
56995
+ if (this.model.scene.readableGeometryEnabled) {
56488
56996
  portion.offset[0] = offset[0];
56489
56997
  portion.offset[1] = offset[1];
56490
56998
  portion.offset[2] = offset[2];
@@ -56492,7 +57000,7 @@ class VBOBatchingTrianglesLayer {
56492
57000
  }
56493
57001
 
56494
57002
  getEachVertex(portionId, callback) {
56495
- if (!this.model.scene.pickSurfacePrecisionEnabled) {
57003
+ if (!this.model.scene.readableGeometryEnabled) {
56496
57004
  return;
56497
57005
  }
56498
57006
  const state = this._state;
@@ -56503,18 +57011,19 @@ class VBOBatchingTrianglesLayer {
56503
57011
  }
56504
57012
  const positions = portion.quantizedPositions;
56505
57013
  const origin = state.origin;
56506
- const offset = portion.offset;
56507
- const offsetX = origin[0] + offset[0];
56508
- const offsetY = origin[1] + offset[1];
56509
- const offsetZ = origin[2] + offset[2];
56510
- const worldPos = tempVec4a$7;
57014
+ const offsetX = origin[0] ;
57015
+ const offsetY = origin[1] ;
57016
+ const offsetZ = origin[2] ;
57017
+ const worldPos = tempVec4a$8;
57018
+ const sceneModelMatrix = this.model.matrix;
57019
+ const positionsDecodeMatrix = state.positionsDecodeMatrix;
56511
57020
  for (let i = 0, len = positions.length; i < len; i += 3) {
56512
57021
  worldPos[0] = positions[i];
56513
57022
  worldPos[1] = positions[i + 1];
56514
57023
  worldPos[2] = positions[i + 2];
56515
57024
  worldPos[3] = 1.0;
56516
- math.decompressPosition(worldPos, state.positionsDecodeMatrix);
56517
- math.transformPoint4(this.model.worldMatrix, worldPos);
57025
+ math.decompressPosition(worldPos, positionsDecodeMatrix);
57026
+ math.transformPoint4(sceneModelMatrix, worldPos);
56518
57027
  worldPos[0] += offsetX;
56519
57028
  worldPos[1] += offsetY;
56520
57029
  worldPos[2] += offsetZ;
@@ -56522,6 +57031,21 @@ class VBOBatchingTrianglesLayer {
56522
57031
  }
56523
57032
  }
56524
57033
 
57034
+ getEachIndex(portionId, callback) {
57035
+ if (!this.model.scene.readableGeometryEnabled) {
57036
+ return;
57037
+ }
57038
+ const portion = this._portions[portionId];
57039
+ if (!portion) {
57040
+ this.model.error("portion not found: " + portionId);
57041
+ return;
57042
+ }
57043
+ const indices = portion.indices;
57044
+ for (let i = 0, len = indices.length; i < len; i++) {
57045
+ callback(indices[i]);
57046
+ }
57047
+ }
57048
+
56525
57049
  getElementsCountAndOffset(portionId) {
56526
57050
  let count = null;
56527
57051
  let offset = null;
@@ -56542,14 +57066,21 @@ class VBOBatchingTrianglesLayer {
56542
57066
  return;
56543
57067
  }
56544
57068
  this._updateBackfaceCull(renderFlags, frameCtx);
57069
+ const useAlphaCutoff = this._state.textureSet && (typeof(this._state.textureSet.alphaCutoff) === "number");
56545
57070
  if (frameCtx.withSAO && this.model.saoEnabled) {
56546
57071
  if (frameCtx.pbrEnabled && this.model.pbrEnabled && this._state.pbrSupported) {
56547
57072
  if (this._renderers.pbrRendererWithSAO) {
56548
57073
  this._renderers.pbrRendererWithSAO.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
56549
57074
  }
56550
57075
  } else if (frameCtx.colorTextureEnabled && this.model.colorTextureEnabled && this._state.colorTextureSupported) {
56551
- if (this._renderers.colorTextureRendererWithSAO) {
56552
- this._renderers.colorTextureRendererWithSAO.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
57076
+ if (useAlphaCutoff) {
57077
+ if (this._renderers.colorTextureRendererWithSAOAlphaCutoff) {
57078
+ this._renderers.colorTextureRendererWithSAOAlphaCutoff.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
57079
+ }
57080
+ } else {
57081
+ if (this._renderers.colorTextureRendererWithSAO) {
57082
+ this._renderers.colorTextureRendererWithSAO.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
57083
+ }
56553
57084
  }
56554
57085
  } else if (this._state.normalsBuf) {
56555
57086
  if (this._renderers.colorRendererWithSAO) {
@@ -56566,8 +57097,14 @@ class VBOBatchingTrianglesLayer {
56566
57097
  this._renderers.pbrRenderer.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
56567
57098
  }
56568
57099
  } else if (frameCtx.colorTextureEnabled && this.model.colorTextureEnabled && this._state.colorTextureSupported) {
56569
- if (this._renderers.colorTextureRenderer) {
56570
- this._renderers.colorTextureRenderer.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
57100
+ if (useAlphaCutoff) {
57101
+ if (this._renderers.colorTextureRendererAlphaCutoff) {
57102
+ this._renderers.colorTextureRendererAlphaCutoff.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
57103
+ }
57104
+ } else {
57105
+ if (this._renderers.colorTextureRenderer) {
57106
+ this._renderers.colorTextureRenderer.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
57107
+ }
56571
57108
  }
56572
57109
  } else if (this._state.normalsBuf) {
56573
57110
  if (this._renderers.colorRenderer) {
@@ -56604,8 +57141,15 @@ class VBOBatchingTrianglesLayer {
56604
57141
  this._renderers.pbrRenderer.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_TRANSPARENT);
56605
57142
  }
56606
57143
  } else if (frameCtx.colorTextureEnabled && this.model.colorTextureEnabled && this._state.colorTextureSupported) {
56607
- if (this._renderers.colorTextureRenderer) {
56608
- this._renderers.colorTextureRenderer.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_TRANSPARENT);
57144
+ const useAlphaCutoff = this._state.textureSet && (typeof(this._state.textureSet.alphaCutoff) === "number");
57145
+ if (useAlphaCutoff) {
57146
+ if (this._renderers.colorTextureRendererAlphaCutoff) {
57147
+ this._renderers.colorTextureRendererAlphaCutoff.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_TRANSPARENT);
57148
+ }
57149
+ } else {
57150
+ if (this._renderers.colorTextureRenderer) {
57151
+ this._renderers.colorTextureRenderer.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_TRANSPARENT);
57152
+ }
56609
57153
  }
56610
57154
  } else if (this._state.normalsBuf) {
56611
57155
  if (this._renderers.colorRenderer) {
@@ -56809,7 +57353,7 @@ class VBOBatchingTrianglesLayer {
56809
57353
 
56810
57354
  precisionRayPickSurface(portionId, worldRayOrigin, worldRayDir, worldSurfacePos, worldNormal) {
56811
57355
 
56812
- if (!this.model.scene.pickSurfacePrecisionEnabled) {
57356
+ if (!this.model.scene.readableGeometryEnabled) {
56813
57357
  return false;
56814
57358
  }
56815
57359
 
@@ -56949,8 +57493,8 @@ class VBOBatchingTrianglesLayer {
56949
57493
  * @private
56950
57494
  */
56951
57495
  class TrianglesInstancingRenderer extends VBORenderer {
56952
- constructor(scene, withSAO, {edges = false} = {}) {
56953
- super(scene, withSAO, {instancing: true, edges});
57496
+ constructor(scene, withSAO, {edges = false, useAlphaCutoff = false} = {}) {
57497
+ super(scene, withSAO, {instancing: true, edges, useAlphaCutoff});
56954
57498
  }
56955
57499
 
56956
57500
  _draw(drawCfg) {
@@ -56959,13 +57503,14 @@ class TrianglesInstancingRenderer extends VBORenderer {
56959
57503
  const {
56960
57504
  state,
56961
57505
  frameCtx,
56962
- incrementDrawState,
57506
+ incrementDrawState
56963
57507
  } = drawCfg;
56964
57508
 
56965
57509
  if (this._edges) {
56966
57510
  gl.drawElementsInstanced(gl.LINES, state.edgeIndicesBuf.numItems, state.edgeIndicesBuf.itemType, 0, state.numInstances);
56967
57511
  } else {
56968
57512
  gl.drawElementsInstanced(gl.TRIANGLES, state.indicesBuf.numItems, state.indicesBuf.itemType, 0, state.numInstances);
57513
+
56969
57514
  if (incrementDrawState) {
56970
57515
  frameCtx.drawElements++;
56971
57516
  }
@@ -59494,7 +60039,6 @@ class TrianglesPickNormalsFlatRenderer extends TrianglesInstancingRenderer {
59494
60039
  * @private
59495
60040
  */
59496
60041
 
59497
-
59498
60042
  class TrianglesColorTextureRenderer extends TrianglesInstancingRenderer {
59499
60043
  _getHash() {
59500
60044
  const scene = this._scene;
@@ -59563,7 +60107,7 @@ class TrianglesColorTextureRenderer extends TrianglesInstancingRenderer {
59563
60107
  src.push("vec4 worldPosition = positionsDecodeMatrix * vec4(position, 1.0); ");
59564
60108
  src.push("worldPosition = worldMatrix * vec4(dot(worldPosition, modelMatrixCol0), dot(worldPosition, modelMatrixCol1), dot(worldPosition, modelMatrixCol2), 1.0);");
59565
60109
  if (scene.entityOffsetsEnabled) {
59566
- src.push(" worldPosition.xyz = worldPosition.xyz + offset;");
60110
+ src.push("worldPosition.xyz = worldPosition.xyz + offset;");
59567
60111
  }
59568
60112
 
59569
60113
  src.push("vec4 viewPosition = viewMatrix * worldPosition; ");
@@ -59591,11 +60135,10 @@ class TrianglesColorTextureRenderer extends TrianglesInstancingRenderer {
59591
60135
  _buildFragmentShader() {
59592
60136
  const scene = this._scene;
59593
60137
  const gammaOutput = scene.gammaOutput; // If set, then it expects that all textures and colors need to be outputted in premultiplied gamma. Default is false.
59594
- const sectionPlanesState = scene._sectionPlanesState;
59595
60138
  const lightsState = scene._lightsState;
59596
- let i;
59597
- let len;
60139
+ const sectionPlanesState = scene._sectionPlanesState;
59598
60140
  const clipping = sectionPlanesState.getNumAllocatedSectionPlanes() > 0;
60141
+ const useAlphaCutoff = this._useAlphaCutoff;
59599
60142
  const src = [];
59600
60143
  src.push("#version 300 es");
59601
60144
  src.push("// Instancing geometry drawing fragment shader");
@@ -59607,6 +60150,7 @@ class TrianglesColorTextureRenderer extends TrianglesInstancingRenderer {
59607
60150
  src.push("precision mediump float;");
59608
60151
  src.push("precision mediump int;");
59609
60152
  src.push("#endif");
60153
+
59610
60154
  if (scene.logarithmicDepthBufferEnabled) {
59611
60155
  src.push("in float isPerspective;");
59612
60156
  src.push("uniform float logDepthBufFC;");
@@ -59655,7 +60199,7 @@ class TrianglesColorTextureRenderer extends TrianglesInstancingRenderer {
59655
60199
  this._addMatricesUniformBlockLines(src);
59656
60200
 
59657
60201
  src.push("uniform vec4 lightAmbient;");
59658
- for (i = 0, len = lightsState.lights.length; i < len; i++) {
60202
+ for (let i = 0, len = lightsState.lights.length; i < len; i++) {
59659
60203
  const light = lightsState.lights[i];
59660
60204
  if (light.type === "ambient") {
59661
60205
  continue;
@@ -59673,6 +60217,10 @@ class TrianglesColorTextureRenderer extends TrianglesInstancingRenderer {
59673
60217
  }
59674
60218
  }
59675
60219
 
60220
+ if (useAlphaCutoff) {
60221
+ src.push("uniform float materialAlphaCutoff;");
60222
+ }
60223
+
59676
60224
  src.push("in vec4 vViewPosition;");
59677
60225
  src.push("in vec4 vColor;");
59678
60226
  src.push("in vec2 vUV;");
@@ -59708,7 +60256,7 @@ class TrianglesColorTextureRenderer extends TrianglesInstancingRenderer {
59708
60256
  src.push("vec3 yTangent = dFdy( vViewPosition.xyz );");
59709
60257
  src.push("vec3 viewNormal = normalize( cross( xTangent, yTangent ) );");
59710
60258
 
59711
- for (i = 0, len = lightsState.lights.length; i < len; i++) {
60259
+ for (let i = 0, len = lightsState.lights.length; i < len; i++) {
59712
60260
  const light = lightsState.lights[i];
59713
60261
  if (light.type === "ambient") {
59714
60262
  continue;
@@ -59734,16 +60282,27 @@ class TrianglesColorTextureRenderer extends TrianglesInstancingRenderer {
59734
60282
  } else {
59735
60283
  continue;
59736
60284
  }
60285
+
59737
60286
  src.push("lambertian = max(dot(-viewNormal, viewLightDir), 0.0);");
59738
60287
  src.push("reflectedColor += lambertian * (lightColor" + i + ".rgb * lightColor" + i + ".a);");
59739
60288
  }
59740
60289
 
59741
60290
  src.push("vec4 color = vec4((lightAmbient.rgb * lightAmbient.a * newColor.rgb) + (reflectedColor * newColor.rgb), newColor.a);");
60291
+
60292
+ src.push("vec4 sampleColor = texture(uColorMap, vUV);");
60293
+
60294
+ if (useAlphaCutoff) {
60295
+ src.push("if (sampleColor.a < materialAlphaCutoff) {");
60296
+ src.push(" discard;");
60297
+ src.push("}");
60298
+ }
60299
+
59742
60300
  if (gammaOutput) {
59743
- src.push("vec4 colorTexel = color * sRGBToLinear(texture(uColorMap, vUV));");
59744
- } else {
59745
- src.push("vec4 colorTexel = color * texture(uColorMap, vUV);");
60301
+ src.push("sampleColor = sRGBToLinear(sampleColor);");
59746
60302
  }
60303
+
60304
+ src.push("vec4 colorTexel = color * sampleColor;");
60305
+
59747
60306
  src.push("float opacity = color.a;");
59748
60307
 
59749
60308
  if (this._withSAO) {
@@ -59755,9 +60314,10 @@ class TrianglesColorTextureRenderer extends TrianglesInstancingRenderer {
59755
60314
  src.push(" float blendFactor = uSAOParams[3];");
59756
60315
  src.push(" vec2 uv = vec2(gl_FragCoord.x / viewportWidth, gl_FragCoord.y / viewportHeight);");
59757
60316
  src.push(" float ambient = smoothstep(blendCutoff, 1.0, unpackRGBToFloat(texture(uOcclusionTexture, uv))) * blendFactor;");
59758
- src.push(" outColor = vec4(newColor.rgb * colorTexel.rgb * ambient, opacity);");
60317
+
60318
+ src.push(" outColor = vec4(colorTexel.rgb * ambient, opacity);");
59759
60319
  } else {
59760
- src.push(" outColor = vec4(newColor.rgb * colorTexel.rgb, opacity);");
60320
+ src.push(" outColor = vec4(colorTexel.rgb, opacity);");
59761
60321
  }
59762
60322
 
59763
60323
  if (gammaOutput) {
@@ -59765,7 +60325,7 @@ class TrianglesColorTextureRenderer extends TrianglesInstancingRenderer {
59765
60325
  }
59766
60326
 
59767
60327
  if (scene.logarithmicDepthBufferEnabled) {
59768
- src.push(" gl_FragDepth = isPerspective == 0.0 ? gl_FragCoord.z : log2( vFragDepth ) * logDepthBufFC * 0.5;");
60328
+ src.push("gl_FragDepth = isPerspective == 0.0 ? gl_FragCoord.z : log2( vFragDepth ) * logDepthBufFC * 0.5;");
59769
60329
  }
59770
60330
 
59771
60331
  src.push("}");
@@ -60335,7 +60895,7 @@ class TrianglesSnapRenderer extends VBORenderer {
60335
60895
  // renderPass = PICK
60336
60896
  src.push(`int pickFlag = int(flags) >> 12 & 0xF;`);
60337
60897
  src.push(`if (pickFlag != renderPass) {`);
60338
- src.push(" gl_Position = vec4(0.0, 0.0, 0.0, 0.0);"); // Cull vertex
60898
+ src.push(" gl_Position = vec4(2.0, 0.0, 0.0, 0.0);"); // Cull vertex
60339
60899
  src.push("} else {");
60340
60900
  src.push(" vec4 worldPosition = positionsDecodeMatrix * vec4(position, 1.0); ");
60341
60901
  src.push(" worldPosition = worldMatrix * vec4(dot(worldPosition, modelMatrixCol0), dot(worldPosition, modelMatrixCol1), dot(worldPosition, modelMatrixCol2), 1.0);");
@@ -60455,14 +61015,6 @@ class Renderers {
60455
61015
  this._flatColorRendererWithSAO.destroy();
60456
61016
  this._flatColorRendererWithSAO = null;
60457
61017
  }
60458
- if (this._pbrRenderer && (!this._pbrRenderer.getValid())) {
60459
- this._pbrRenderer.destroy();
60460
- this._pbrRenderer = null;
60461
- }
60462
- if (this._pbrRendererWithSAO && (!this._pbrRendererWithSAO.getValid())) {
60463
- this._pbrRendererWithSAO.destroy();
60464
- this._pbrRendererWithSAO = null;
60465
- }
60466
61018
  if (this._colorTextureRenderer && (!this._colorTextureRenderer.getValid())) {
60467
61019
  this._colorTextureRenderer.destroy();
60468
61020
  this._colorTextureRenderer = null;
@@ -60471,6 +61023,22 @@ class Renderers {
60471
61023
  this._colorTextureRendererWithSAO.destroy();
60472
61024
  this._colorTextureRendererWithSAO = null;
60473
61025
  }
61026
+ if (this._colorTextureRendererAlphaCutoff && (!this._colorTextureRendererAlphaCutoff.getValid())) {
61027
+ this._colorTextureRendererAlphaCutoff.destroy();
61028
+ this._colorTextureRendererAlphaCutoff = null;
61029
+ }
61030
+ if (this._colorTextureRendererWithSAOAlphaCutoff && (!this._colorTextureRendererWithSAOAlphaCutoff.getValid())) {
61031
+ this._colorTextureRendererWithSAOAlphaCutoff.destroy();
61032
+ this._colorTextureRendererWithSAOAlphaCutoff = null;
61033
+ }
61034
+ if (this._pbrRenderer && (!this._pbrRenderer.getValid())) {
61035
+ this._pbrRenderer.destroy();
61036
+ this._pbrRenderer = null;
61037
+ }
61038
+ if (this._pbrRendererWithSAO && (!this._pbrRendererWithSAO.getValid())) {
61039
+ this._pbrRendererWithSAO.destroy();
61040
+ this._pbrRendererWithSAO = null;
61041
+ }
60474
61042
  if (this._depthRenderer && (!this._depthRenderer.getValid())) {
60475
61043
  this._depthRenderer.destroy();
60476
61044
  this._depthRenderer = null;
@@ -60503,7 +61071,7 @@ class Renderers {
60503
61071
  this._pickNormalsRenderer.destroy();
60504
61072
  this._pickNormalsRenderer = null;
60505
61073
  }
60506
- if (this._pickNormalsFlatRenderer && (!this._pickNormalsFlatRenderer.getValid())) {
61074
+ if (this._pickNormalsFlatRenderer && this._pickNormalsFlatRenderer.getValid() === false) {
60507
61075
  this._pickNormalsFlatRenderer.destroy();
60508
61076
  this._pickNormalsFlatRenderer = null;
60509
61077
  }
@@ -60576,20 +61144,6 @@ class Renderers {
60576
61144
  return this._flatColorRendererWithSAO;
60577
61145
  }
60578
61146
 
60579
- get pbrRenderer() {
60580
- if (!this._pbrRenderer) {
60581
- this._pbrRenderer = new TrianglesPBRRenderer(this._scene, false);
60582
- }
60583
- return this._pbrRenderer;
60584
- }
60585
-
60586
- get pbrRendererWithSAO() {
60587
- if (!this._pbrRendererWithSAO) {
60588
- this._pbrRendererWithSAO = new TrianglesPBRRenderer(this._scene, true);
60589
- }
60590
- return this._pbrRendererWithSAO;
60591
- }
60592
-
60593
61147
  get colorTextureRenderer() {
60594
61148
  if (!this._colorTextureRenderer) {
60595
61149
  this._colorTextureRenderer = new TrianglesColorTextureRenderer(this._scene, false);
@@ -60604,6 +61158,34 @@ class Renderers {
60604
61158
  return this._colorTextureRendererWithSAO;
60605
61159
  }
60606
61160
 
61161
+ get colorTextureRendererAlphaCutoff() {
61162
+ if (!this._colorTextureRendererAlphaCutoff) {
61163
+ this._colorTextureRendererAlphaCutoff = new TrianglesColorTextureRenderer(this._scene, false, { useAlphaCutoff: true });
61164
+ }
61165
+ return this._colorTextureRendererAlphaCutoff;
61166
+ }
61167
+
61168
+ get colorTextureRendererWithSAOAlphaCutoff() {
61169
+ if (!this._colorTextureRendererWithSAOAlphaCutoff) {
61170
+ this._colorTextureRendererWithSAOAlphaCutoff = new TrianglesColorTextureRenderer(this._scene, true, { useAlphaCutoff: true });
61171
+ }
61172
+ return this._colorTextureRendererWithSAOAlphaCutoff;
61173
+ }
61174
+
61175
+ get pbrRenderer() {
61176
+ if (!this._pbrRenderer) {
61177
+ this._pbrRenderer = new TrianglesPBRRenderer(this._scene, false);
61178
+ }
61179
+ return this._pbrRenderer;
61180
+ }
61181
+
61182
+ get pbrRendererWithSAO() {
61183
+ if (!this._pbrRendererWithSAO) {
61184
+ this._pbrRendererWithSAO = new TrianglesPBRRenderer(this._scene, true);
61185
+ }
61186
+ return this._pbrRendererWithSAO;
61187
+ }
61188
+
60607
61189
  get silhouetteRenderer() {
60608
61190
  if (!this._silhouetteRenderer) {
60609
61191
  this._silhouetteRenderer = new TrianglesSilhouetteRenderer(this._scene);
@@ -60681,13 +61263,6 @@ class Renderers {
60681
61263
  return this._shadowRenderer;
60682
61264
  }
60683
61265
 
60684
- get snapInitRenderer() {
60685
- if (!this._snapInitRenderer) {
60686
- this._snapInitRenderer = new TrianglesSnapInitRenderer(this._scene, false);
60687
- }
60688
- return this._snapInitRenderer;
60689
- }
60690
-
60691
61266
  get snapRenderer() {
60692
61267
  if (!this._snapRenderer) {
60693
61268
  this._snapRenderer = new TrianglesSnapRenderer(this._scene);
@@ -60695,6 +61270,13 @@ class Renderers {
60695
61270
  return this._snapRenderer;
60696
61271
  }
60697
61272
 
61273
+ get snapInitRenderer() {
61274
+ if (!this._snapInitRenderer) {
61275
+ this._snapInitRenderer = new TrianglesSnapInitRenderer(this._scene);
61276
+ }
61277
+ return this._snapInitRenderer;
61278
+ }
61279
+
60698
61280
  _destroy() {
60699
61281
  if (this._colorRenderer) {
60700
61282
  this._colorRenderer.destroy();
@@ -60708,18 +61290,24 @@ class Renderers {
60708
61290
  if (this._flatColorRendererWithSAO) {
60709
61291
  this._flatColorRendererWithSAO.destroy();
60710
61292
  }
60711
- if (this._pbrRenderer) {
60712
- this._pbrRenderer.destroy();
60713
- }
60714
- if (this._pbrRendererWithSAO) {
60715
- this._pbrRendererWithSAO.destroy();
60716
- }
60717
61293
  if (this._colorTextureRenderer) {
60718
61294
  this._colorTextureRenderer.destroy();
60719
61295
  }
60720
61296
  if (this._colorTextureRendererWithSAO) {
60721
61297
  this._colorTextureRendererWithSAO.destroy();
60722
61298
  }
61299
+ if (this._colorTextureRendererAlphaCutoff) {
61300
+ this._colorTextureRendererAlphaCutoff.destroy();
61301
+ }
61302
+ if (this._colorTextureRendererWithSAOAlphaCutoff) {
61303
+ this._colorTextureRendererWithSAOAlphaCutoff.destroy();
61304
+ }
61305
+ if (this._pbrRenderer) {
61306
+ this._pbrRenderer.destroy();
61307
+ }
61308
+ if (this._pbrRendererWithSAO) {
61309
+ this._pbrRendererWithSAO.destroy();
61310
+ }
60723
61311
  if (this._depthRenderer) {
60724
61312
  this._depthRenderer.destroy();
60725
61313
  }
@@ -60769,27 +61357,27 @@ const cachedRenderers$5 = {};
60769
61357
  */
60770
61358
  function getRenderers$6(scene) {
60771
61359
  const sceneId = scene.id;
60772
- let instancingRenderers = cachedRenderers$5[sceneId];
60773
- if (!instancingRenderers) {
60774
- instancingRenderers = new Renderers(scene);
60775
- cachedRenderers$5[sceneId] = instancingRenderers;
60776
- instancingRenderers._compile();
60777
- instancingRenderers.eagerCreateRenders();
61360
+ let renderers = cachedRenderers$5[sceneId];
61361
+ if (!renderers) {
61362
+ renderers = new Renderers(scene);
61363
+ cachedRenderers$5[sceneId] = renderers;
61364
+ renderers._compile();
61365
+ renderers.eagerCreateRenders();
60778
61366
  scene.on("compile", () => {
60779
- instancingRenderers._compile();
60780
- instancingRenderers.eagerCreateRenders();
61367
+ renderers._compile();
61368
+ renderers.eagerCreateRenders();
60781
61369
  });
60782
61370
  scene.on("destroyed", () => {
60783
61371
  delete cachedRenderers$5[sceneId];
60784
- instancingRenderers._destroy();
61372
+ renderers._destroy();
60785
61373
  });
60786
61374
  }
60787
- return instancingRenderers;
61375
+ return renderers;
60788
61376
  }
60789
61377
 
60790
61378
  const tempUint8Vec4$2 = new Uint8Array(4);
60791
61379
  const tempFloat32$2 = new Float32Array(1);
60792
- const tempVec4a$6 = math.vec4([0, 0, 0, 1]);
61380
+ const tempVec4a$7 = math.vec4([0, 0, 0, 1]);
60793
61381
  const tempVec3fa$2 = new Float32Array(3);
60794
61382
 
60795
61383
  const tempVec3a$w = math.vec3();
@@ -60817,7 +61405,7 @@ class VBOInstancingTrianglesLayer {
60817
61405
  */
60818
61406
  constructor(cfg) {
60819
61407
 
60820
- console.info("Creating VBOInstancingTrianglesLayer");
61408
+ // console.info("Creating VBOInstancingTrianglesLayer");
60821
61409
 
60822
61410
  /**
60823
61411
  * Owner model
@@ -60920,6 +61508,11 @@ class VBOInstancingTrianglesLayer {
60920
61508
  * @type {number|*}
60921
61509
  */
60922
61510
  this.numIndices = cfg.geometry.numIndices;
61511
+
61512
+ /**
61513
+ * The type of primitives in this layer.
61514
+ */
61515
+ this.primitive = cfg.geometry.primitive;
60923
61516
  }
60924
61517
 
60925
61518
  get aabb() {
@@ -61033,7 +61626,7 @@ class VBOInstancingTrianglesLayer {
61033
61626
 
61034
61627
  const portion = {};
61035
61628
 
61036
- if (this.model.scene.pickSurfacePrecisionEnabled) {
61629
+ if (this.model.scene.readableGeometryEnabled) {
61037
61630
  portion.matrix = meshMatrix.slice();
61038
61631
  portion.inverseMatrix = null; // Lazy-computed in precisionRayPickSurface
61039
61632
  portion.normalMatrix = null; // Lazy-computed in precisionRayPickSurface
@@ -61471,7 +62064,7 @@ class VBOInstancingTrianglesLayer {
61471
62064
  }
61472
62065
 
61473
62066
  getEachVertex(portionId, callback) {
61474
- if (!this.model.scene.pickSurfacePrecisionEnabled) {
62067
+ if (!this.model.scene.readableGeometryEnabled) {
61475
62068
  return false;
61476
62069
  }
61477
62070
  const state = this._state;
@@ -61483,13 +62076,12 @@ class VBOInstancingTrianglesLayer {
61483
62076
  }
61484
62077
  const positions = geometry.quantizedPositions;
61485
62078
  const origin = state.origin;
61486
- const offset = portion.offset;
61487
- const offsetX = origin[0] + offset[0];
61488
- const offsetY = origin[1] + offset[1];
61489
- const offsetZ = origin[2] + offset[2];
61490
- const worldPos = tempVec4a$6;
62079
+ const offsetX = origin[0] ;
62080
+ const offsetY = origin[1] ;
62081
+ const offsetZ = origin[2] ;
62082
+ const worldPos = tempVec4a$7;
61491
62083
  const portionMatrix = portion.matrix;
61492
- const sceneModelPatrix = this.model.sceneModelMatrix;
62084
+ const sceneModelMatrix = this.model.matrix;
61493
62085
  const positionsDecodeMatrix = state.positionsDecodeMatrix;
61494
62086
  for (let i = 0, len = positions.length; i < len; i += 3) {
61495
62087
  worldPos[0] = positions[i];
@@ -61497,7 +62089,7 @@ class VBOInstancingTrianglesLayer {
61497
62089
  worldPos[2] = positions[i + 2];
61498
62090
  math.decompressPosition(worldPos, positionsDecodeMatrix);
61499
62091
  math.transformPoint3(portionMatrix, worldPos);
61500
- math.transformPoint3(sceneModelPatrix, worldPos);
62092
+ math.transformPoint3(sceneModelMatrix, worldPos);
61501
62093
  worldPos[0] += offsetX;
61502
62094
  worldPos[1] += offsetY;
61503
62095
  worldPos[2] += offsetZ;
@@ -61505,6 +62097,23 @@ class VBOInstancingTrianglesLayer {
61505
62097
  }
61506
62098
  }
61507
62099
 
62100
+ getEachIndex(portionId, callback) {
62101
+ if (!this.model.scene.readableGeometryEnabled) {
62102
+ return false;
62103
+ }
62104
+ const state = this._state;
62105
+ const geometry = state.geometry;
62106
+ const portion = this._portions[portionId];
62107
+ if (!portion) {
62108
+ this.model.error("portion not found: " + portionId);
62109
+ return;
62110
+ }
62111
+ const indices = geometry.indices;
62112
+ for (let i = 0, len = indices.length; i < len; i++) {
62113
+ callback(indices[i]);
62114
+ }
62115
+ }
62116
+
61508
62117
  setMatrix(portionId, matrix) {
61509
62118
  if (!this._finalized) {
61510
62119
  throw "Not finalized";
@@ -61545,14 +62154,21 @@ class VBOInstancingTrianglesLayer {
61545
62154
  return;
61546
62155
  }
61547
62156
  this._updateBackfaceCull(renderFlags, frameCtx);
62157
+ const useAlphaCutoff = this._state.textureSet && (typeof(this._state.textureSet.alphaCutoff) === "number");
61548
62158
  if (frameCtx.withSAO && this.model.saoEnabled) {
61549
62159
  if (frameCtx.pbrEnabled && this.model.pbrEnabled && this._state.pbrSupported) {
61550
62160
  if (this._renderers.pbrRendererWithSAO) {
61551
62161
  this._renderers.pbrRendererWithSAO.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
61552
62162
  }
61553
62163
  } else if (frameCtx.colorTextureEnabled && this.model.colorTextureEnabled && this._state.colorTextureSupported) {
61554
- if (this._renderers.colorTextureRendererWithSAO) {
61555
- this._renderers.colorTextureRendererWithSAO.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
62164
+ if (useAlphaCutoff) {
62165
+ if (this._renderers.colorTextureRendererWithSAOAlphaCutoff) {
62166
+ this._renderers.colorTextureRendererWithSAOAlphaCutoff.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
62167
+ }
62168
+ } else {
62169
+ if (this._renderers.colorTextureRendererWithSAO) {
62170
+ this._renderers.colorTextureRendererWithSAO.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
62171
+ }
61556
62172
  }
61557
62173
  } else if (this._state.normalsBuf) {
61558
62174
  if (this._renderers.colorRendererWithSAO) {
@@ -61568,8 +62184,14 @@ class VBOInstancingTrianglesLayer {
61568
62184
  this._renderers.pbrRenderer.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
61569
62185
  }
61570
62186
  } else if (frameCtx.colorTextureEnabled && this.model.colorTextureEnabled && this._state.colorTextureSupported) {
61571
- if (this._renderers.colorTextureRenderer) {
61572
- this._renderers.colorTextureRenderer.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
62187
+ if (useAlphaCutoff) {
62188
+ if (this._renderers.colorTextureRendererAlphaCutoff) {
62189
+ this._renderers.colorTextureRendererAlphaCutoff.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
62190
+ }
62191
+ } else {
62192
+ if (this._renderers.colorTextureRenderer) {
62193
+ this._renderers.colorTextureRenderer.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
62194
+ }
61573
62195
  }
61574
62196
  } else if (this._state.normalsBuf) {
61575
62197
  if (this._renderers.colorRenderer) {
@@ -61811,7 +62433,7 @@ class VBOInstancingTrianglesLayer {
61811
62433
 
61812
62434
  precisionRayPickSurface(portionId, worldRayOrigin, worldRayDir, worldSurfacePos, worldNormal) {
61813
62435
 
61814
- if (!this.model.scene.pickSurfacePrecisionEnabled) {
62436
+ if (!this.model.scene.readableGeometryEnabled) {
61815
62437
  return false;
61816
62438
  }
61817
62439
 
@@ -62744,7 +63366,7 @@ class VBOBatchingLinesSnapRenderer extends VBORenderer{
62744
63366
 
62745
63367
  src.push(`int pickFlag = int(flags) >> 12 & 0xF;`);
62746
63368
  src.push(`if (pickFlag != renderPass) {`);
62747
- src.push(" gl_Position = vec4(0.0, 0.0, 0.0, 0.0);"); // Cull vertex
63369
+ src.push(" gl_Position = vec4(2.0, 0.0, 0.0, 0.0);"); // Cull vertex
62748
63370
  src.push(" } else {");
62749
63371
  src.push(" vec4 worldPosition = worldMatrix * (positionsDecodeMatrix * vec4(position, 1.0)); ");
62750
63372
  if (scene.entityOffsetsEnabled) {
@@ -62968,7 +63590,7 @@ class VBOBatchingLinesLayer {
62968
63590
  */
62969
63591
  constructor(cfg) {
62970
63592
 
62971
- console.info("Creating VBOBatchingLinesLayer");
63593
+ // console.info("Creating VBOBatchingLinesLayer");
62972
63594
 
62973
63595
  /**
62974
63596
  * Index of this LinesBatchingLayer in {@link VBOSceneModel#_layerList}.
@@ -63023,6 +63645,11 @@ class VBOBatchingLinesLayer {
63023
63645
  if (cfg.origin) {
63024
63646
  this._state.origin = math.vec3(cfg.origin);
63025
63647
  }
63648
+
63649
+ /**
63650
+ * The type of primitives in this layer.
63651
+ */
63652
+ this.primitive = cfg.primitive;
63026
63653
  }
63027
63654
 
63028
63655
  get aabb() {
@@ -64481,7 +65108,7 @@ class VBOInstancingLinesSnapRenderer extends VBORenderer {
64481
65108
  // renderPass = PICK
64482
65109
  src.push(`int pickFlag = int(flags) >> 12 & 0xF;`);
64483
65110
  src.push(`if (pickFlag != renderPass) {`);
64484
- src.push(" gl_Position = vec4(0.0, 0.0, 0.0, 0.0);"); // Cull vertex
65111
+ src.push(" gl_Position = vec4(2.0, 0.0, 0.0, 0.0);"); // Cull vertex
64485
65112
  src.push("} else {");
64486
65113
  src.push(" vec4 worldPosition = positionsDecodeMatrix * vec4(position, 1.0); ");
64487
65114
  src.push(" worldPosition = worldMatrix * vec4(dot(worldPosition, modelMatrixCol0), dot(worldPosition, modelMatrixCol1), dot(worldPosition, modelMatrixCol2), 1.0);");
@@ -64731,7 +65358,7 @@ class VBOInstancingLinesLayer {
64731
65358
  */
64732
65359
  constructor(cfg) {
64733
65360
 
64734
- console.info("VBOInstancingLinesLayer");
65361
+ // console.info("VBOInstancingLinesLayer");
64735
65362
 
64736
65363
  /**
64737
65364
  * Owner model
@@ -64811,6 +65438,11 @@ class VBOInstancingLinesLayer {
64811
65438
  }
64812
65439
 
64813
65440
  this._finalized = false;
65441
+
65442
+ /**
65443
+ * The type of primitives in this layer.
65444
+ */
65445
+ this.primitive = cfg.primitive;
64814
65446
  }
64815
65447
 
64816
65448
  get aabb() {
@@ -66944,7 +67576,7 @@ class VBOBatchingPointsLayer {
66944
67576
  */
66945
67577
  constructor(cfg) {
66946
67578
 
66947
- console.info("Creating VBOBatchingPointsLayer");
67579
+ // console.info("Creating VBOBatchingPointsLayer");
66948
67580
 
66949
67581
  /**
66950
67582
  * Owner model
@@ -69541,7 +70173,7 @@ class VBOInstancingPointsLayer {
69541
70173
  */
69542
70174
  constructor(cfg) {
69543
70175
 
69544
- console.info("VBOInstancingPointsLayer");
70176
+ // console.info("VBOInstancingPointsLayer");
69545
70177
 
69546
70178
  /**
69547
70179
  * Owner model
@@ -69615,6 +70247,11 @@ class VBOInstancingPointsLayer {
69615
70247
  this.aabbDirty = true;
69616
70248
 
69617
70249
  this._finalized = false;
70250
+
70251
+ /**
70252
+ * The type of primitives in this layer.
70253
+ */
70254
+ this.primitive = cfg.geometry.primitive;
69618
70255
  }
69619
70256
 
69620
70257
  get aabb() {
@@ -71276,7 +71913,7 @@ class DTXLinesLayer {
71276
71913
 
71277
71914
  constructor(model, cfg) {
71278
71915
 
71279
- console.info("Creating DTXLinesLayer");
71916
+ // console.info("Creating DTXLinesLayer");
71280
71917
 
71281
71918
  dataTextureRamStats$1.numberOfLayers++;
71282
71919
 
@@ -71315,6 +71952,12 @@ class DTXLinesLayer {
71315
71952
  this._aabb = math.collapseAABB3();
71316
71953
  this.aabbDirty = true;
71317
71954
  this._numUpdatesInFrame = 0;
71955
+
71956
+ /**
71957
+ * The type of primitives in this layer.
71958
+ */
71959
+ this.primitive = cfg.primitive;
71960
+
71318
71961
  this._finalized = false;
71319
71962
  }
71320
71963
 
@@ -72140,7 +72783,7 @@ const tempVec3b$i = math.vec3();
72140
72783
  const tempVec3c$e = math.vec3();
72141
72784
  math.vec3();
72142
72785
 
72143
- const tempVec4a$5 = math.vec4();
72786
+ const tempVec4a$6 = math.vec4();
72144
72787
 
72145
72788
  const tempMat4a$c = math.mat4();
72146
72789
 
@@ -72419,11 +73062,11 @@ class DTXTrianglesColorRenderer {
72419
73062
  if (saoEnabled) {
72420
73063
  const viewportWidth = gl.drawingBufferWidth;
72421
73064
  const viewportHeight = gl.drawingBufferHeight;
72422
- tempVec4a$5[0] = viewportWidth;
72423
- tempVec4a$5[1] = viewportHeight;
72424
- tempVec4a$5[2] = sao.blendCutoff;
72425
- tempVec4a$5[3] = sao.blendFactor;
72426
- gl.uniform4fv(this._uSAOParams, tempVec4a$5);
73065
+ tempVec4a$6[0] = viewportWidth;
73066
+ tempVec4a$6[1] = viewportHeight;
73067
+ tempVec4a$6[2] = sao.blendCutoff;
73068
+ tempVec4a$6[3] = sao.blendFactor;
73069
+ gl.uniform4fv(this._uSAOParams, tempVec4a$6);
72427
73070
  this._program.bindTexture(this._uOcclusionTexture, frameCtx.occlusionTexture, 10);
72428
73071
  }
72429
73072
  }
@@ -75232,6 +75875,14 @@ class DTXTrianglesSnapRenderer {
75232
75875
  src.push("uvec4 flags = texelFetch (uObjectPerObjectColorsAndFlags, ivec2(objectIndexCoords.x*8+2, objectIndexCoords.y), 0);");
75233
75876
  src.push("uvec4 flags2 = texelFetch (uObjectPerObjectColorsAndFlags, ivec2(objectIndexCoords.x*8+3, objectIndexCoords.y), 0);");
75234
75877
 
75878
+ // flags.w = NOT_RENDERED | PICK
75879
+ // renderPass = PICK
75880
+
75881
+ src.push(`if (int(flags.w) != renderPass) {`);
75882
+ src.push(" gl_Position = vec4(3.0, 3.0, 3.0, 1.0);"); // Cull vertex
75883
+ src.push(" return;"); // Cull vertex
75884
+ src.push("}");
75885
+
75235
75886
  src.push("{");
75236
75887
 
75237
75888
  // get vertex base
@@ -75647,6 +76298,14 @@ class DTXTrianglesSnapInitRenderer {
75647
76298
  src.push("uvec4 flags = texelFetch (uObjectPerObjectColorsAndFlags, ivec2(objectIndexCoords.x*8+2, objectIndexCoords.y), 0);");
75648
76299
  src.push("uvec4 flags2 = texelFetch (uObjectPerObjectColorsAndFlags, ivec2(objectIndexCoords.x*8+3, objectIndexCoords.y), 0);");
75649
76300
 
76301
+ // flags.w = NOT_RENDERED | PICK
76302
+ // renderPass = PICK
76303
+
76304
+ src.push(`if (int(flags.w) != renderPass) {`);
76305
+ src.push(" gl_Position = vec4(3.0, 3.0, 3.0, 1.0);"); // Cull vertex
76306
+ src.push(" return;"); // Cull vertex
76307
+ src.push("}");
76308
+
75650
76309
  src.push("{");
75651
76310
 
75652
76311
  // get color
@@ -78650,6 +79309,7 @@ const INDICES_EDGE_INDICES_ALIGNEMENT_SIZE = 8;
78650
79309
  */
78651
79310
  const MAX_OBJECT_UPDATES_IN_FRAME_WITHOUT_BATCHED_UPDATE = 10;
78652
79311
 
79312
+ const tempVec4a$5 = math.vec4();
78653
79313
  const tempMat4a = new Float32Array(16);
78654
79314
  const tempUint8Array4 = new Uint8Array(4);
78655
79315
  const tempFloat32Array3 = new Float32Array(3);
@@ -78665,7 +79325,7 @@ class DTXTrianglesLayer {
78665
79325
 
78666
79326
  constructor(model, cfg) {
78667
79327
 
78668
- console.info("Creating DTXTrianglesLayer");
79328
+ //console.info("Creating DTXTrianglesLayer");
78669
79329
 
78670
79330
  dataTextureRamStats.numberOfLayers++;
78671
79331
 
@@ -78705,6 +79365,10 @@ class DTXTrianglesLayer {
78705
79365
 
78706
79366
  this._subPortions = [];
78707
79367
 
79368
+ if (this.model.scene.readableGeometryEnabled) {
79369
+ this._subPortionReadableGeometries = {};
79370
+ }
79371
+
78708
79372
  /**
78709
79373
  * Due to `index rebucketting` process in ```prepareMeshGeometry``` function, it's possible that a single
78710
79374
  * portion is expanded to more than 1 real sub-portion.
@@ -78734,6 +79398,11 @@ class DTXTrianglesLayer {
78734
79398
  */
78735
79399
  this._numUpdatesInFrame = 0;
78736
79400
 
79401
+ /**
79402
+ * The type of primitives in this layer.
79403
+ */
79404
+ this.primitive = cfg.primitive;
79405
+
78737
79406
  this._finalized = false;
78738
79407
  }
78739
79408
 
@@ -79038,6 +79707,15 @@ class DTXTrianglesLayer {
79038
79707
  numVertices: bucketGeometry.numTriangles
79039
79708
  });
79040
79709
 
79710
+ if (this.model.scene.readableGeometryEnabled) {
79711
+ this._subPortionReadableGeometries[subPortionId] = {
79712
+ indices: bucket.indices,
79713
+ positionsCompressed: bucket.positionsCompressed,
79714
+ positionsDecodeMatrix: portionCfg.positionsDecodeMatrix,
79715
+ meshMatrix: portionCfg.meshMatrix
79716
+ };
79717
+ }
79718
+
79041
79719
  this._numPortions++;
79042
79720
 
79043
79721
  dataTextureRamStats.numberOfPortions++;
@@ -79688,6 +80366,63 @@ class DTXTrianglesLayer {
79688
80366
  // gl.bindTexture (gl.TEXTURE_2D, null);
79689
80367
  }
79690
80368
 
80369
+ getEachVertex(portionId, callback) {
80370
+ if (!this.model.scene.readableGeometryEnabled) {
80371
+ return;
80372
+ }
80373
+ const state = this._state;
80374
+ const subPortionIds = this._portionToSubPortionsMap[portionId];
80375
+ if (!subPortionIds) {
80376
+ this.model.error("portion not found: " + portionId);
80377
+ return;
80378
+ }
80379
+ for (let i = 0, len = subPortionIds.length; i < len; i++) {
80380
+ const subPortionId = subPortionIds[i];
80381
+ const subPortionReadableGeometry = this._subPortionReadableGeometries[subPortionId];
80382
+ const positions = subPortionReadableGeometry.positionsCompressed;
80383
+ const positionsDecodeMatrix = subPortionReadableGeometry.positionsDecodeMatrix;
80384
+ subPortionReadableGeometry.meshMatrix;
80385
+ const origin = state.origin;
80386
+ const offsetX = origin[0] ;
80387
+ const offsetY = origin[1] ;
80388
+ const offsetZ = origin[2] ;
80389
+ const worldPos = tempVec4a$5;
80390
+ for (let i = 0, len = positions.length; i < len; i += 3) {
80391
+ worldPos[0] = positions[i];
80392
+ worldPos[1] = positions[i + 1];
80393
+ worldPos[2] = positions[i + 2];
80394
+ worldPos[3] = 1.0;
80395
+ math.decompressPosition(worldPos, positionsDecodeMatrix);
80396
+ math.transformPoint4(this.model.worldMatrix, worldPos);
80397
+ math.transformPoint4(this.model.worldMatrix, worldPos);
80398
+ worldPos[0] += offsetX;
80399
+ worldPos[1] += offsetY;
80400
+ worldPos[2] += offsetZ;
80401
+ callback(worldPos);
80402
+ }
80403
+ }
80404
+ }
80405
+
80406
+ getEachIndex(portionId, callback) {
80407
+ if (!this.model.scene.readableGeometryEnabled) {
80408
+ return;
80409
+ }
80410
+ const subPortionIds = this._portionToSubPortionsMap[portionId];
80411
+ if (!subPortionIds) {
80412
+ this.model.error("portion not found: " + portionId);
80413
+ return;
80414
+ }
80415
+ for (let i = 0, len = subPortionIds.length; i < len; i++) {
80416
+ const subPortionId = subPortionIds[i];
80417
+ const subPortionReadableGeometry = this._subPortionReadableGeometries[subPortionId];
80418
+ const indices = subPortionReadableGeometry.indices;
80419
+ for (let i = 0, len = indices.length; i < len; i++) {
80420
+ callback(indices[i]);
80421
+ }
80422
+ }
80423
+ }
80424
+
80425
+
79691
80426
  // ---------------------- COLOR RENDERING -----------------------------------
79692
80427
 
79693
80428
  drawColorOpaque(renderFlags, frameCtx) {
@@ -79963,6 +80698,11 @@ class SceneModelTextureSet {
79963
80698
  */
79964
80699
  this.colorTexture = cfg.colorTexture;
79965
80700
 
80701
+ /**
80702
+ * The alpha cutoff [float]
80703
+ */
80704
+ this.alphaCutoff = cfg.alphaCutoff;
80705
+
79966
80706
  /**
79967
80707
  * The metallic-roughness texture.
79968
80708
  * @type {SceneModelTexture|*}
@@ -83030,7 +83770,10 @@ class SceneModel extends Component {
83030
83770
  this._meshList = [];
83031
83771
 
83032
83772
  this.layerList = []; // For GL state efficiency when drawing, InstancingLayers are in first part, BatchingLayers are in second
83773
+ this._layersToFinalize = [];
83774
+
83033
83775
  this._entityList = [];
83776
+ this._entitiesToFinalize = [];
83034
83777
 
83035
83778
  this._geometries = {};
83036
83779
  this._dtxBuckets = {}; // Geometries with optimizations used for data texture representation
@@ -83106,6 +83849,7 @@ class SceneModel extends Component {
83106
83849
  this._numTriangles = 0;
83107
83850
  this._numLines = 0;
83108
83851
  this._numPoints = 0;
83852
+ this._layersFinalized = false;
83109
83853
 
83110
83854
  this._edgeThreshold = cfg.edgeThreshold || 10;
83111
83855
 
@@ -84515,6 +85259,7 @@ class SceneModel extends Component {
84515
85259
  id: textureSetId,
84516
85260
  model: this,
84517
85261
  colorTexture,
85262
+ alphaCutoff: cfg.alphaCutoff,
84518
85263
  metallicRoughnessTexture,
84519
85264
  normalsTexture,
84520
85265
  emissiveTexture,
@@ -84948,6 +85693,14 @@ class SceneModel extends Component {
84948
85693
  return this._createMesh(cfg);
84949
85694
  }
84950
85695
 
85696
+ _createDefaultIndices(numIndices) {
85697
+ const indices = [];
85698
+ for (let i = 0; i < numIndices; i++) {
85699
+ indices.push(i);
85700
+ }
85701
+ return indices;
85702
+ }
85703
+
84951
85704
  _createMesh(cfg) {
84952
85705
  const mesh = new SceneModelMesh(this, cfg.id, cfg.color, cfg.opacity, cfg.transform, cfg.textureSet);
84953
85706
  mesh.pickId = this.scene._renderer.getPickID(mesh);
@@ -85047,7 +85800,7 @@ class SceneModel extends Component {
85047
85800
  let dtxLayer = this._dtxLayers[layerId];
85048
85801
  if (dtxLayer) {
85049
85802
  if (!dtxLayer.canCreatePortion(cfg)) {
85050
- dtxLayer.finalize();
85803
+ // dtxLayer.finalize();
85051
85804
  delete this._dtxLayers[layerId];
85052
85805
  dtxLayer = null;
85053
85806
  } else {
@@ -85058,16 +85811,17 @@ class SceneModel extends Component {
85058
85811
  case "triangles":
85059
85812
  case "solid":
85060
85813
  case "surface":
85061
- dtxLayer = new DTXTrianglesLayer(this, {layerIndex: 0, origin}); // layerIndex is set in #finalize()
85814
+ dtxLayer = new DTXTrianglesLayer(this, {layerIndex: 0, origin, primitive}); // layerIndex is set in #finalize()
85062
85815
  break;
85063
85816
  case "lines":
85064
- dtxLayer = new DTXLinesLayer(this, {layerIndex: 0, origin}); // layerIndex is set in #finalize()
85817
+ dtxLayer = new DTXLinesLayer(this, {layerIndex: 0, origin, primitive}); // layerIndex is set in #finalize()
85065
85818
  break;
85066
85819
  default:
85067
85820
  return;
85068
85821
  }
85069
85822
  this._dtxLayers[layerId] = dtxLayer;
85070
85823
  this.layerList.push(dtxLayer);
85824
+ this._layersToFinalize.push(dtxLayer);
85071
85825
  return dtxLayer;
85072
85826
  }
85073
85827
 
@@ -85099,7 +85853,8 @@ class SceneModel extends Component {
85099
85853
  origin,
85100
85854
  maxGeometryBatchSize: this._maxGeometryBatchSize,
85101
85855
  solid: (cfg.primitive === "solid"),
85102
- autoNormals: true
85856
+ autoNormals: true,
85857
+ primitive: cfg.primitive
85103
85858
  });
85104
85859
  break;
85105
85860
  case "solid":
@@ -85114,7 +85869,8 @@ class SceneModel extends Component {
85114
85869
  origin,
85115
85870
  maxGeometryBatchSize: this._maxGeometryBatchSize,
85116
85871
  solid: (cfg.primitive === "solid"),
85117
- autoNormals: true
85872
+ autoNormals: true,
85873
+ primitive: cfg.primitive
85118
85874
  });
85119
85875
  break;
85120
85876
  case "surface":
@@ -85129,7 +85885,8 @@ class SceneModel extends Component {
85129
85885
  origin,
85130
85886
  maxGeometryBatchSize: this._maxGeometryBatchSize,
85131
85887
  solid: (cfg.primitive === "solid"),
85132
- autoNormals: true
85888
+ autoNormals: true,
85889
+ primitive: cfg.primitive
85133
85890
  });
85134
85891
  break;
85135
85892
  case "lines":
@@ -85141,7 +85898,8 @@ class SceneModel extends Component {
85141
85898
  positionsDecodeMatrix: cfg.positionsDecodeMatrix, // Can be undefined
85142
85899
  uvDecodeMatrix: cfg.uvDecodeMatrix, // Can be undefined
85143
85900
  origin,
85144
- maxGeometryBatchSize: this._maxGeometryBatchSize
85901
+ maxGeometryBatchSize: this._maxGeometryBatchSize,
85902
+ primitive: cfg.primitive
85145
85903
  });
85146
85904
  break;
85147
85905
  case "points":
@@ -85153,7 +85911,8 @@ class SceneModel extends Component {
85153
85911
  positionsDecodeMatrix: cfg.positionsDecodeMatrix, // Can be undefined
85154
85912
  uvDecodeMatrix: cfg.uvDecodeMatrix, // Can be undefined
85155
85913
  origin,
85156
- maxGeometryBatchSize: this._maxGeometryBatchSize
85914
+ maxGeometryBatchSize: this._maxGeometryBatchSize,
85915
+ primitive: cfg.primitive
85157
85916
  });
85158
85917
  break;
85159
85918
  }
@@ -85169,6 +85928,7 @@ class SceneModel extends Component {
85169
85928
  }
85170
85929
  this._vboBatchingLayers[layerId] = vboBatchingLayer;
85171
85930
  this.layerList.push(vboBatchingLayer);
85931
+ this._layersToFinalize.push(vboBatchingLayer);
85172
85932
  return vboBatchingLayer;
85173
85933
  }
85174
85934
 
@@ -85261,6 +86021,7 @@ class SceneModel extends Component {
85261
86021
  }
85262
86022
  this._vboInstancingLayers[layerId] = vboInstancingLayer;
85263
86023
  this.layerList.push(vboInstancingLayer);
86024
+ this._layersToFinalize.push(vboInstancingLayer);
85264
86025
  return vboInstancingLayer;
85265
86026
  }
85266
86027
 
@@ -85361,38 +86122,47 @@ class SceneModel extends Component {
85361
86122
  lodCullable); // Internally sets SceneModelEntity#parent to this SceneModel
85362
86123
  this._entityList.push(entity);
85363
86124
  this._entities[cfg.id] = entity;
86125
+ this._entitiesToFinalize.push(entity);
85364
86126
  this.numEntities++;
85365
86127
  }
85366
86128
 
85367
86129
  /**
85368
- * Finalizes this SceneModel.
85369
- *
85370
- * Once finalized, you can't add anything more to this SceneModel.
86130
+ * Pre-renders all meshes that have been added, even if the SceneModel has not bee finalized yet.
86131
+ * This is use for progressively showing the SceneModel while it is being loaded or constructed.
86132
+ * @returns {boolean}
85371
86133
  */
85372
- finalize() {
86134
+ preFinalize() {
85373
86135
  if (this.destroyed) {
85374
- return;
86136
+ return false;
86137
+ }
86138
+ if (this._layersToFinalize.length === 0) {
86139
+ return false;
85375
86140
  }
85376
86141
  this._createDummyEntityForUnusedMeshes();
85377
- for (let i = 0, len = this.layerList.length; i < len; i++) {
85378
- const layer = this.layerList[i];
86142
+ for (let i = 0, len = this._layersToFinalize.length; i < len; i++) {
86143
+ const layer = this._layersToFinalize[i];
85379
86144
  layer.finalize();
85380
86145
  }
85381
- this._geometries = {};
85382
- this._dtxBuckets = {};
85383
- this._textures = {};
85384
- this._textureSets = {};
85385
- this._dtxLayers = {};
85386
- this._vboInstancingLayers = {};
85387
86146
  this._vboBatchingLayers = {};
85388
- for (let i = 0, len = this._entityList.length; i < len; i++) {
85389
- const entity = this._entityList[i];
86147
+ this._vboInstancingLayers = {};
86148
+ this._dtxLayers = {};
86149
+ this._layersToFinalize = [];
86150
+ for (let i = 0, len = this._entitiesToFinalize.length; i < len; i++) {
86151
+ const entity = this._entitiesToFinalize[i];
85390
86152
  entity._finalize();
85391
86153
  }
85392
- for (let i = 0, len = this._entityList.length; i < len; i++) {
85393
- const entity = this._entityList[i];
86154
+ for (let i = 0, len = this._entitiesToFinalize.length; i < len; i++) {
86155
+ const entity = this._entitiesToFinalize[i];
85394
86156
  entity._finalize2();
85395
86157
  }
86158
+ this._entitiesToFinalize = [];
86159
+ this.scene._aabbDirty = true;
86160
+ this._viewMatrixDirty = true;
86161
+ this._matrixDirty = true;
86162
+ this._aabbDirty = true;
86163
+ this._setWorldMatrixDirty();
86164
+ this._sceneModelDirty();
86165
+ this.position = this._position;
85396
86166
  // Sort layers to reduce WebGL shader switching when rendering them
85397
86167
  this.layerList.sort((a, b) => {
85398
86168
  if (a.sortId < b.sortId) {
@@ -85408,15 +86178,23 @@ class SceneModel extends Component {
85408
86178
  layer.layerIndex = i;
85409
86179
  }
85410
86180
  this.glRedraw();
85411
- this.scene._aabbDirty = true;
85412
- this._viewMatrixDirty = true;
85413
- this._matrixDirty = true;
85414
- this._aabbDirty = true;
85415
-
85416
- this._setWorldMatrixDirty();
85417
- this._sceneModelDirty();
86181
+ this._layersFinalized = true;
86182
+ }
85418
86183
 
85419
- this.position = this._position;
86184
+ /**
86185
+ * Finalizes this SceneModel.
86186
+ *
86187
+ * Once finalized, you can't add anything more to this SceneModel.
86188
+ */
86189
+ finalize() {
86190
+ if (this.destroyed) {
86191
+ return;
86192
+ }
86193
+ this.preFinalize();
86194
+ this._geometries = {};
86195
+ this._dtxBuckets = {};
86196
+ this._textures = {};
86197
+ this._textureSets = {};
85420
86198
  }
85421
86199
 
85422
86200
  /** @private */
@@ -85454,7 +86232,7 @@ class SceneModel extends Component {
85454
86232
  _createDummyEntityForUnusedMeshes() {
85455
86233
  const unusedMeshIds = Object.keys(this._unusedMeshes);
85456
86234
  if (unusedMeshIds.length > 0) {
85457
- const entityId = `${this.id}-dummyEntityForUnusedMeshes`;
86235
+ const entityId = `${this.id}-${math.createUUID()}`;
85458
86236
  this.warn(`Creating dummy SceneModelEntity "${entityId}" for unused SceneMeshes: [${unusedMeshIds.join(",")}]`);
85459
86237
  this.createEntity({
85460
86238
  id: entityId,
@@ -85826,6 +86604,7 @@ class SceneModel extends Component {
85826
86604
  for (let i = 0, len = this._entityList.length; i < len; i++) {
85827
86605
  this._entityList[i]._destroy();
85828
86606
  }
86607
+ this._layersToFinalize = {};
85829
86608
  // Object.entries(this._geometries).forEach(([id, geometry]) => {
85830
86609
  // geometry.destroy();
85831
86610
  // });
@@ -88323,12 +89102,6 @@ class DistanceMeasurementsMouseControl extends DistanceMeasurementsControl {
88323
89102
 
88324
89103
  this._initMarkerDiv();
88325
89104
 
88326
- this._onCameraControlHoverSnapOrSurface = null;
88327
- this._onCameraControlHoverSnapOrSurfaceOff = null;
88328
- this._onMouseDown = null;
88329
- this._onMouseUp = null;
88330
- this._onCanvasTouchStart = null;
88331
- this._onCanvasTouchEnd = null;
88332
89105
  this._snapping = cfg.snapping !== false;
88333
89106
  this._mouseState = MOUSE_FIRST_CLICK_EXPECTED;
88334
89107
 
@@ -88392,20 +89165,10 @@ class DistanceMeasurementsMouseControl extends DistanceMeasurementsControl {
88392
89165
  *
88393
89166
  * This is `true` by default.
88394
89167
  *
88395
- * Internally, this deactivates then activates the DistanceMeasurementsMouseControl when changed, which means that
88396
- * it will destroy any DistanceMeasurements currently under construction, and incurs some overhead, since it unbinds
88397
- * and rebinds various input handlers.
88398
- *
88399
89168
  * @param snapping
88400
89169
  */
88401
89170
  set snapping(snapping) {
88402
- if (snapping !== this._snapping) {
88403
- this._snapping = snapping;
88404
- this.deactivate();
88405
- this.activate();
88406
- } else {
88407
- this._snapping = snapping;
88408
- }
89171
+ this._snapping = snapping;
88409
89172
  }
88410
89173
 
88411
89174
  /**
@@ -88417,7 +89180,7 @@ class DistanceMeasurementsMouseControl extends DistanceMeasurementsControl {
88417
89180
  get snapping() {
88418
89181
  return this._snapping;
88419
89182
  }
88420
-
89183
+
88421
89184
  /**
88422
89185
  * Activates this DistanceMeasurementsMouseControl, ready to respond to input.
88423
89186
  */
@@ -88452,11 +89215,8 @@ class DistanceMeasurementsMouseControl extends DistanceMeasurementsControl {
88452
89215
  const getLeft = el => el.offsetLeft + (el.offsetParent && (el.offsetParent !== canvas.parentNode) && getLeft(el.offsetParent));
88453
89216
 
88454
89217
  const pagePos = math.vec2();
88455
-
88456
- this._onCameraControlHoverSnapOrSurface = cameraControl.on(
88457
- this._snapping
88458
- ? "hoverSnapOrSurface"
88459
- : "hoverSurface", event => {
89218
+
89219
+ const hoverOn = event => {
88460
89220
  const canvasPos = event.snappedCanvasPos || event.canvasPos;
88461
89221
  mouseHovering = true;
88462
89222
  pointerWorldPos.set(event.worldPos);
@@ -88509,7 +89269,9 @@ class DistanceMeasurementsMouseControl extends DistanceMeasurementsControl {
88509
89269
  this._markerDiv.style.left = `-10000px`;
88510
89270
  this._markerDiv.style.top = `-10000px`;
88511
89271
  }
88512
- });
89272
+ };
89273
+ this._onHoverSnapOrSurface = cameraControl.on("hoverSnapOrSurface", e => { if (this._snapping) hoverOn(e); });
89274
+ this._onHoverSurface = cameraControl.on("hoverSurface", e => { if (! this._snapping) hoverOn(e); });
88513
89275
 
88514
89276
  canvas.addEventListener('mousedown', this._onMouseDown = (e) => {
88515
89277
  if (e.which !== 1) {
@@ -88570,10 +89332,7 @@ class DistanceMeasurementsMouseControl extends DistanceMeasurementsControl {
88570
89332
  }
88571
89333
  });
88572
89334
 
88573
- this._onCameraControlHoverSnapOrSurfaceOff = cameraControl.on(
88574
- this._snapping
88575
- ? "hoverSnapOrSurfaceOff"
88576
- : "hoverOff", event => {
89335
+ const hoverOff = event => {
88577
89336
  if (this.pointerLens) {
88578
89337
  this.pointerLens.visible = true;
88579
89338
  this.pointerLens.canvasPos = event.canvasPos;
@@ -88588,7 +89347,9 @@ class DistanceMeasurementsMouseControl extends DistanceMeasurementsControl {
88588
89347
  this._currentDistanceMeasurement.axisVisible = false;
88589
89348
  }
88590
89349
  canvas.style.cursor = "default";
88591
- });
89350
+ };
89351
+ this._onHoverSnapOrSurfaceOff = cameraControl.on("hoverSnapOrSurfaceOff", e => { if (this._snapping) hoverOff(e); });
89352
+ this._onHoverOff = cameraControl.on("hoverOff", e => { if (! this._snapping) hoverOff(e); });
88592
89353
 
88593
89354
  this._active = true;
88594
89355
  }
@@ -88602,27 +89363,24 @@ class DistanceMeasurementsMouseControl extends DistanceMeasurementsControl {
88602
89363
  if (!this._active) {
88603
89364
  return;
88604
89365
  }
88605
-
89366
+
88606
89367
  this.fire("activated", false);
88607
89368
 
88608
89369
  if (this.pointerLens) {
88609
89370
  this.pointerLens.visible = false;
88610
89371
  }
88611
- // if (this._markerDiv) {
88612
- // this._destroyMarkerDiv()
88613
- // }
88614
- // this.reset();
89372
+
89373
+ this.reset();
89374
+
88615
89375
  const canvas = this.scene.canvas.canvas;
88616
89376
  canvas.removeEventListener("mousedown", this._onMouseDown);
88617
89377
  canvas.removeEventListener("mouseup", this._onMouseUp);
88618
89378
  const cameraControl = this.distanceMeasurementsPlugin.viewer.cameraControl;
88619
- cameraControl.off(this._onCameraControlHoverSnapOrSurface);
88620
- cameraControl.off(this._onCameraControlHoverSnapOrSurfaceOff);
88621
- // if (this._currentDistanceMeasurement) {
88622
- // this.distanceMeasurementsPlugin.fire("measurementCancel", this._currentDistanceMeasurement);
88623
- // this._currentDistanceMeasurement.destroy();
88624
- // this._currentDistanceMeasurement = null;
88625
- // }
89379
+ cameraControl.off(this._onHoverSnapOrSurface);
89380
+ cameraControl.off(this._onHoverSurface);
89381
+ cameraControl.off(this._onHoverSnapOrSurfaceOff);
89382
+ cameraControl.off(this._onHoverOff);
89383
+
88626
89384
  this._active = false;
88627
89385
  }
88628
89386
 
@@ -89306,11 +90064,8 @@ class DistanceMeasurementsTouchControl extends DistanceMeasurementsControl {
89306
90064
  targetVisible: null,
89307
90065
  };
89308
90066
 
89309
- this._onCanvasTouchStart = null;
89310
- this._onCanvasTouchEnd = null;
89311
90067
  this._longTouchTimeoutMs = 300;
89312
90068
  this._snapping = cfg.snapping !== false;
89313
- this._touchState = WAITING_FOR_ORIGIN_TOUCH_START;
89314
90069
 
89315
90070
  this._attachPlugin(distanceMeasurementsPlugin, cfg);
89316
90071
  }
@@ -89343,20 +90098,10 @@ class DistanceMeasurementsTouchControl extends DistanceMeasurementsControl {
89343
90098
  *
89344
90099
  * This is `true` by default.
89345
90100
  *
89346
- * Internally, this deactivates then activates the DistanceMeasurementsTouchControl when changed, which means that
89347
- * it will destroy any DistanceMeasurements currently under construction, and incurs some overhead, since it unbinds
89348
- * and rebinds various input handlers.
89349
- *
89350
90101
  * @param {boolean} snapping Whether to enable snap-to-vertex and snap-edge for this DistanceMeasurementsTouchControl.
89351
90102
  */
89352
90103
  set snapping(snapping) {
89353
- if (snapping !== this._snapping) {
89354
- this._snapping = snapping;
89355
- this.deactivate();
89356
- this.activate();
89357
- } else {
89358
- this._snapping = snapping;
89359
- }
90104
+ this._snapping = snapping;
89360
90105
  }
89361
90106
 
89362
90107
  /**
@@ -89968,14 +90713,11 @@ class DistanceMeasurementsTouchControl extends DistanceMeasurementsControl {
89968
90713
  this.plugin.pointerLens.visible = false;
89969
90714
  }
89970
90715
  this.reset();
90716
+
89971
90717
  const canvas = this.plugin.viewer.scene.canvas.canvas;
89972
90718
  canvas.removeEventListener("touchstart", this._onCanvasTouchStart);
89973
90719
  canvas.removeEventListener("touchend", this._onCanvasTouchEnd);
89974
- if (this._currentDistanceMeasurement) {
89975
- this.distanceMeasurementsPlugin.fire("measurementCancel", this._currentDistanceMeasurement);
89976
- this._currentDistanceMeasurement.destroy();
89977
- this._currentDistanceMeasurement = null;
89978
- }
90720
+
89979
90721
  this._active = false;
89980
90722
  this.plugin.viewer.cameraControl.active = true;
89981
90723
  }
@@ -89991,12 +90733,12 @@ class DistanceMeasurementsTouchControl extends DistanceMeasurementsControl {
89991
90733
  if (!this._active) {
89992
90734
  return;
89993
90735
  }
90736
+
89994
90737
  if (this._currentDistanceMeasurement) {
89995
90738
  this.distanceMeasurementsPlugin.fire("measurementCancel", this._currentDistanceMeasurement);
89996
90739
  this._currentDistanceMeasurement.destroy();
89997
90740
  this._currentDistanceMeasurement = null;
89998
90741
  }
89999
- this._mouseState = WAITING_FOR_ORIGIN_TOUCH_START;
90000
90742
  }
90001
90743
 
90002
90744
  /**
@@ -101008,8 +101750,6 @@ class MetaScene {
101008
101750
  * @param {String} modelId ID for the new {@link MetaModel}, which will have {@link MetaModel#id} set to this value.
101009
101751
  * @param {Object} metaModelData Data for the {@link MetaModel}.
101010
101752
  * @param {Object} [options] Options for creating the {@link MetaModel}.
101011
- * @param {Object} [options.includeTypes] When provided, only create {@link MetaObject}s with types in this list.
101012
- * @param {Object} [options.excludeTypes] When provided, never create {@link MetaObject}s with types in this list.
101013
101753
  * @param {Boolean} [options.globalizeObjectIds=false] Whether to globalize each {@link MetaObject#id}. Set this ````true```` when you need to load multiple instances of the same meta model, to avoid ID clashes between the meta objects in the different instances.
101014
101754
  * @returns {MetaModel} The new MetaModel.
101015
101755
  */
@@ -109082,7 +109822,7 @@ class Viewer {
109082
109822
  * @throws {String} Throws an exception when both canvasId or canvasElement are missing or they aren't pointing to a valid HTMLCanvasElement.
109083
109823
  * @param {Boolean} [cfg.alphaDepthMask=true] Whether writing into the depth buffer is enabled or disabled when rendering transparent objects.
109084
109824
  * @param {Boolean} [cfg.entityOffsetsEnabled=false] Whether to enable {@link Entity#offset}. For best performance, only set this ````true```` when you need to use {@link Entity#offset}.
109085
- * @param {Boolean} [cfg.pickSurfacePrecisionEnabled=false] Whether to enable full-precision accuracy when surface picking with {@link Scene#pick}. Note that when ````true````, this configuration will increase the amount of browser memory used by the Viewer. The ````pickSurfacePrecision```` option for ````Scene#pick```` only works if this is set ````true````.
109825
+ * @param {Boolean} [cfg.readableGeometryEnabled=false] Whether to enable full-precision accuracy when surface picking with {@link Scene#pick}. Note that when ````true````, this configuration will increase the amount of browser memory used by the Viewer. The ````pickSurfacePrecision```` option for ````Scene#pick```` only works if this is set ````true````.
109086
109826
  * @param {Boolean} [cfg.logarithmicDepthBufferEnabled=false] Whether to enable logarithmic depth buffer. When this is true,
109087
109827
  * you can set huge values for {@link Perspective#far} and {@link Ortho#far}, to push the far clipping plane back so
109088
109828
  * that it does not clip huge models.
@@ -109152,7 +109892,7 @@ class Viewer {
109152
109892
  saoEnabled: cfg.saoEnabled,
109153
109893
  alphaDepthMask: (cfg.alphaDepthMask !== false),
109154
109894
  entityOffsetsEnabled: (!!cfg.entityOffsetsEnabled),
109155
- pickSurfacePrecisionEnabled: (!!cfg.pickSurfacePrecisionEnabled),
109895
+ readableGeometryEnabled: (!!cfg.readableGeometryEnabled),
109156
109896
  logarithmicDepthBufferEnabled: (!!cfg.logarithmicDepthBufferEnabled),
109157
109897
  pbrEnabled: (!!cfg.pbrEnabled),
109158
109898
  colorTextureEnabled: (cfg.colorTextureEnabled !== false),
@@ -116995,40 +117735,6 @@ class GLTFSceneModelLoader {
116995
117735
  }
116996
117736
  }
116997
117737
 
116998
- function getMetaModelCorrections(metaModelJSON) {
116999
- const eachRootStats = {};
117000
- const eachChildRoot = {};
117001
- const metaObjects = metaModelJSON.metaObjects || [];
117002
- const metaObjectsMap = {};
117003
- for (let i = 0, len = metaObjects.length; i < len; i++) {
117004
- const metaObject = metaObjects[i];
117005
- metaObjectsMap[metaObject.id] = metaObject;
117006
- }
117007
- for (let i = 0, len = metaObjects.length; i < len; i++) {
117008
- const metaObject = metaObjects[i];
117009
- if (metaObject.parent !== undefined && metaObject.parent !== null) {
117010
- const metaObjectParent = metaObjectsMap[metaObject.parent];
117011
- if (metaObject.type === metaObjectParent.type) {
117012
- let rootMetaObject = metaObjectParent;
117013
- while (rootMetaObject.parent && metaObjectsMap[rootMetaObject.parent].type === rootMetaObject.type) {
117014
- rootMetaObject = metaObjectsMap[rootMetaObject.parent];
117015
- }
117016
- const rootStats = eachRootStats[rootMetaObject.id] || (eachRootStats[rootMetaObject.id] = {
117017
- numChildren: 0,
117018
- countChildren: 0
117019
- });
117020
- rootStats.numChildren++;
117021
- eachChildRoot[metaObject.id] = rootMetaObject;
117022
- }
117023
- }
117024
- }
117025
- return {
117026
- metaObjectsMap,
117027
- eachRootStats,
117028
- eachChildRoot
117029
- };
117030
- }
117031
-
117032
117738
  function loadGLTF(plugin, src, metaModelJSON, options, sceneModel, ok, error) {
117033
117739
  const spinner = plugin.viewer.scene.canvas.spinner;
117034
117740
  spinner.processes++;
@@ -117070,7 +117776,9 @@ function parseGLTF(plugin, src, gltf, metaModelJSON, options, sceneModel, ok) {
117070
117776
  const ctx = {
117071
117777
  src: src,
117072
117778
  entityId: options.entityId,
117073
- metaModelCorrections: metaModelJSON ? getMetaModelCorrections(metaModelJSON) : null,
117779
+ metaModelJSON,
117780
+ autoMetaModel: options.autoMetaModel,
117781
+ metaObjects: [],
117074
117782
  loadBuffer: options.loadBuffer,
117075
117783
  basePath: options.basePath,
117076
117784
  handlenode: options.handlenode,
@@ -117089,8 +117797,20 @@ function parseGLTF(plugin, src, gltf, metaModelJSON, options, sceneModel, ok) {
117089
117797
  };
117090
117798
  loadTextures(ctx);
117091
117799
  loadMaterials(ctx);
117800
+ if (options.autoMetaModel) {
117801
+ ctx.metaObjects.push({
117802
+ id: sceneModel.id,
117803
+ type: "Default",
117804
+ name: sceneModel.id
117805
+ });
117806
+ }
117092
117807
  loadDefaultScene(ctx);
117093
117808
  sceneModel.finalize();
117809
+ if (options.autoMetaModel) {
117810
+ plugin.viewer.metaScene.createMetaModel(sceneModel.id, {
117811
+ metaObjects: ctx.metaObjects
117812
+ });
117813
+ }
117094
117814
  spinner.processes--;
117095
117815
  ok();
117096
117816
  });
@@ -117219,23 +117939,17 @@ function loadTextureSet(ctx, material) {
117219
117939
  if (material.emissiveTexture) {
117220
117940
  textureSetCfg.emissiveTextureId = material.emissiveTexture.texture._textureId;
117221
117941
  }
117222
- // const alphaMode = material.alphaMode;
117223
- // switch (alphaMode) {
117224
- // case "NORMAL_OPAQUE":
117225
- // materialCfg.alphaMode = "opaque";
117226
- // break;
117227
- // case "MASK":
117228
- // materialCfg.alphaMode = "mask";
117229
- // break;
117230
- // case "BLEND":
117231
- // materialCfg.alphaMode = "blend";
117232
- // break;
117233
- // default:
117234
- // }
117235
- // const alphaCutoff = material.alphaCutoff;
117236
- // if (alphaCutoff !== undefined) {
117237
- // materialCfg.alphaCutoff = alphaCutoff;
117238
- // }
117942
+
117943
+ switch (material.alphaMode) {
117944
+ case "OPAQUE":
117945
+ break;
117946
+ case "MASK":
117947
+ const alphaCutoff = material.alphaCutoff;
117948
+ // Default from the spec https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#reference-material
117949
+ textureSetCfg.alphaCutoff = (alphaCutoff !== undefined) ? alphaCutoff : 0.5;
117950
+ break;
117951
+ }
117952
+
117239
117953
  const metallicPBR = material.pbrMetallicRoughness;
117240
117954
  if (material.pbrMetallicRoughness) {
117241
117955
  const pbrMetallicRoughness = material.pbrMetallicRoughness;
@@ -117281,7 +117995,7 @@ function loadMaterialAttributes(ctx, material) { // Substitute RGBA for material
117281
117995
  opacity: 1,
117282
117996
  metallic: 0,
117283
117997
  roughness: 1,
117284
- doubleSided : true
117998
+ doubleSided: true
117285
117999
  };
117286
118000
  if (extensions) {
117287
118001
  const specularPBR = extensions["KHR_materials_pbrSpecularGlossiness"];
@@ -117355,9 +118069,22 @@ function loadScene(ctx, scene) {
117355
118069
  const node = nodes[i];
117356
118070
  countMeshUsage(ctx, node);
117357
118071
  }
117358
- for (let i = 0, len = nodes.length; i < len; i++) {
118072
+ for (let i = 0, len = nodes.length; i < len && !ctx.nodesHaveNames; i++) {
117359
118073
  const node = nodes[i];
117360
- loadNode(ctx, node, 0, null);
118074
+ if (testIfNodesHaveNames(node)) {
118075
+ ctx.nodesHaveNames = true;
118076
+ }
118077
+ }
118078
+ if (!ctx.nodesHaveNames) {
118079
+ for (let i = 0, len = nodes.length; i < len; i++) {
118080
+ const node = nodes[i];
118081
+ parseNodesWithoutNames(ctx, node, 0, null);
118082
+ }
118083
+ } else {
118084
+ for (let i = 0, len = nodes.length; i < len; i++) {
118085
+ const node = nodes[i];
118086
+ parseNodesWithNames(ctx, node, 0, null);
118087
+ }
117361
118088
  }
117362
118089
  }
117363
118090
 
@@ -117379,10 +118106,131 @@ function countMeshUsage(ctx, node) {
117379
118106
  }
117380
118107
  }
117381
118108
 
117382
- const deferredMeshIds = [];
118109
+ function testIfNodesHaveNames(node) {
118110
+ if (node.name) {
118111
+ return true;
118112
+ }
118113
+ if (node.children) {
118114
+ const children = node.children;
118115
+ for (let i = 0, len = children.length; i < len; i++) {
118116
+ const childNode = children[i];
118117
+ if (testIfNodesHaveNames(childNode)) {
118118
+ return true;
118119
+ }
118120
+ }
118121
+ }
118122
+ return false;
118123
+ }
118124
+
118125
+ /**
118126
+ * Parses a glTF node hierarchy that is known to NOT contain "name" attributes on the nodes.
118127
+ * Create a SceneMesh for each mesh primitive, and a single SceneObject.
118128
+ */
118129
+ const parseNodesWithoutNames = (function () {
118130
+ const meshIds = [];
118131
+ return function (ctx, node, depth, matrix, parentNode) {
118132
+ matrix = parseNodeMatrix(node, matrix);
118133
+ if (node.mesh) {
118134
+ parseNodeMesh(node, ctx, matrix, meshIds);
118135
+ }
118136
+ if (node.children) {
118137
+ const children = node.children;
118138
+ for (let i = 0, len = children.length; i < len; i++) {
118139
+ const childNode = children[i];
118140
+ parseNodesWithoutNames(ctx, childNode, depth + 1, matrix, node);
118141
+ }
118142
+ }
118143
+ if (depth === 0) {
118144
+ let entityId = "entity-" + ctx.nextId++;
118145
+ if (meshIds && meshIds.length > 0) {
118146
+ ctx.sceneModel.createEntity({
118147
+ id: entityId,
118148
+ meshIds,
118149
+ isObject: true
118150
+ });
118151
+ if (ctx.autoMetaModel) {
118152
+ ctx.metaObjects.push({
118153
+ id: entityId,
118154
+ type: "Default",
118155
+ name: entityId,
118156
+ parent: ctx.sceneModel.id
118157
+ });
118158
+ }
118159
+ meshIds.length = 0;
118160
+ }
118161
+ }
118162
+ }
118163
+ })();
117383
118164
 
117384
- function loadNode(ctx, node, depth, matrix) {
117385
- ctx.gltfData;
118165
+ const parseNodesWithNames = (function () {
118166
+
118167
+ const objectIdStack = [];
118168
+ const meshIdsStack = [];
118169
+ let meshIds = null;
118170
+
118171
+ return function (ctx, node, depth, matrix) {
118172
+ matrix = parseNodeMatrix(node, matrix);
118173
+ if (meshIds && node.mesh) {
118174
+ parseNodeMesh(node, ctx, matrix, meshIds);
118175
+ }
118176
+
118177
+ if (node.name) {
118178
+ meshIds = [];
118179
+ let entityId = node.name;
118180
+ if (!!entityId && ctx.sceneModel.objects[entityId]) ;
118181
+ while (!entityId || ctx.sceneModel.objects[entityId]) {
118182
+ entityId = "entity-" + ctx.nextId++;
118183
+ }
118184
+ objectIdStack.push(entityId);
118185
+ meshIdsStack.push(meshIds);
118186
+ }
118187
+
118188
+ if (node.children) {
118189
+ const children = node.children;
118190
+ for (let i = 0, len = children.length; i < len; i++) {
118191
+ const childNode = children[i];
118192
+ parseNodesWithNames(ctx, childNode, depth + 1, matrix);
118193
+ }
118194
+ }
118195
+
118196
+ // Post-order visit scene node
118197
+
118198
+ const nodeName = node.name;
118199
+ if ((nodeName !== undefined && nodeName !== null) || depth === 0) {
118200
+ let entityId = objectIdStack.pop();
118201
+ if (!entityId) { // For when there are no nodes with names
118202
+ entityId = "entity-" + ctx.nextId++;
118203
+ }
118204
+ let entityMeshIds = meshIdsStack.pop();
118205
+ if (meshIds && meshIds.length > 0) {
118206
+ ctx.sceneModel.createEntity({
118207
+ id: entityId,
118208
+ meshIds: entityMeshIds,
118209
+ isObject: true
118210
+ });
118211
+ if (ctx.autoMetaModel) {
118212
+ ctx.metaObjects.push({
118213
+ id: entityId,
118214
+ type: "Default",
118215
+ name: entityId,
118216
+ parent: ctx.sceneModel.id
118217
+ });
118218
+ }
118219
+ }
118220
+ meshIds = meshIdsStack.length > 0 ? meshIdsStack[meshIdsStack.length - 1] : null;
118221
+ }
118222
+ };
118223
+ })();
118224
+
118225
+
118226
+ /**
118227
+ * Parses transform at the given glTF node.
118228
+ *
118229
+ * @param node the glTF node
118230
+ * @param matrix Transfor matrix from parent nodes
118231
+ * @returns {*} Transform matrix for the node
118232
+ */
118233
+ function parseNodeMatrix(node, matrix) {
117386
118234
  let localMatrix;
117387
118235
  if (node.matrix) {
117388
118236
  localMatrix = node.matrix;
@@ -117416,171 +118264,92 @@ function loadNode(ctx, node, depth, matrix) {
117416
118264
  matrix = localMatrix;
117417
118265
  }
117418
118266
  }
118267
+ return matrix;
118268
+ }
117419
118269
 
117420
- const sceneModel = ctx.sceneModel;
117421
- if (node.mesh) {
117422
- const mesh = node.mesh;
117423
- if (ctx.handlenode) {
117424
- const actions = {};
117425
- if (!ctx.handlenode(ctx.sceneModel.id, node, actions)) {
117426
- return;
117427
- }
117428
- if (actions.createEntity) ;
117429
- }
117430
- const worldMatrix = matrix ? matrix.slice() : math.identityMat4();
117431
- const numPrimitives = mesh.primitives.length;
117432
-
117433
- if (numPrimitives > 0) {
117434
-
117435
- for (let i = 0; i < numPrimitives; i++) {
117436
-
117437
- const primitive = mesh.primitives[i];
117438
- if (primitive.mode < 4) {
117439
- continue;
117440
- }
117441
-
117442
- const meshCfg = {
117443
- id: sceneModel.id + "." + ctx.numObjects++
117444
- };
117445
-
117446
- const material = primitive.material;
117447
- if (material) {
117448
- meshCfg.textureSetId = material._textureSetId;
117449
- meshCfg.color = material._attributes.color;
117450
- meshCfg.opacity = material._attributes.opacity;
117451
- meshCfg.metallic = material._attributes.metallic;
117452
- meshCfg.roughness = material._attributes.roughness;
117453
- } else {
117454
- meshCfg.color = new Float32Array([1.0, 1.0, 1.0]);
117455
- meshCfg.opacity = 1.0;
117456
- }
117457
-
117458
- const backfaces = ((ctx.backfaces !== false) || (material && material.doubleSided !== false));
117459
-
117460
- switch (primitive.mode) {
117461
- case 0: // POINTS
117462
- meshCfg.primitive = "points";
117463
- break;
117464
- case 1: // LINES
117465
- meshCfg.primitive = "lines";
117466
- break;
117467
- case 2: // LINE_LOOP
117468
- meshCfg.primitive = "lines";
117469
- break;
117470
- case 3: // LINE_STRIP
117471
- meshCfg.primitive = "lines";
117472
- break;
117473
- case 4: // TRIANGLES
117474
- meshCfg.primitive = backfaces ? "triangles" : "solid";
117475
- break;
117476
- case 5: // TRIANGLE_STRIP
117477
- meshCfg.primitive = backfaces ? "triangles" : "solid";
117478
- break;
117479
- case 6: // TRIANGLE_FAN
117480
- meshCfg.primitive = backfaces ? "triangles" : "solid";
117481
- break;
117482
- default:
117483
- meshCfg.primitive = backfaces ? "triangles" : "solid";
117484
- }
117485
-
117486
- const POSITION = primitive.attributes.POSITION;
117487
- if (!POSITION) {
117488
- continue;
117489
- }
117490
- meshCfg.localPositions = POSITION.value;
117491
- meshCfg.positions = new Float64Array(meshCfg.localPositions.length);
117492
-
117493
- if (primitive.attributes.NORMAL) {
117494
- meshCfg.normals = primitive.attributes.NORMAL.value;
117495
- }
117496
-
117497
- if (primitive.attributes.TEXCOORD_0) {
117498
- meshCfg.uv = primitive.attributes.TEXCOORD_0.value;
117499
- }
117500
-
117501
- if (primitive.indices) {
117502
- meshCfg.indices = primitive.indices.value;
117503
- }
117504
-
117505
- math.transformPositions3(worldMatrix, meshCfg.localPositions, meshCfg.positions);
117506
- const origin = math.vec3();
117507
- const rtcNeeded = worldToRTCPositions(meshCfg.positions, meshCfg.positions, origin); // Small cellsize guarantees better accuracy
117508
- if (rtcNeeded) {
117509
- meshCfg.origin = origin;
117510
- }
117511
-
117512
- sceneModel.createMesh(meshCfg);
117513
- deferredMeshIds.push(meshCfg.id);
117514
- }
117515
- }
117516
- }
117517
-
117518
- if (node.children) {
117519
- const children = node.children;
117520
- for (let i = 0, len = children.length; i < len; i++) {
117521
- const childNode = children[i];
117522
- loadNode(ctx, childNode, depth + 1, matrix);
117523
- }
118270
+ /**
118271
+ * Parses primitives referenced by the mesh belonging to the given node, creating XKTMeshes in the XKTModel.
118272
+ *
118273
+ * @param node glTF node
118274
+ * @param ctx Parsing context
118275
+ * @param matrix Matrix for the XKTMeshes
118276
+ * @param meshIds returns IDs of the new XKTMeshes
118277
+ */
118278
+ function parseNodeMesh(node, ctx, matrix, meshIds) {
118279
+ const mesh = node.mesh;
118280
+ if (!mesh) {
118281
+ return;
117524
118282
  }
117525
-
117526
- // Post-order visit scene node
117527
-
117528
- if (ctx.entityId) {
117529
- if (depth ===0) {
117530
- sceneModel.createEntity({
117531
- id: ctx.entityId,
117532
- meshIds: deferredMeshIds,
117533
- isObject: true
117534
- });
117535
- deferredMeshIds.length = 0;
117536
- }
117537
- } else {
117538
- const nodeName = node.name;
117539
- if (((nodeName !== undefined && nodeName !== null) || depth === 0) && deferredMeshIds.length > 0) {
117540
- if (nodeName === undefined || nodeName === null) {
117541
- ctx.log(`Warning: 'name' properties not found on glTF scene nodes - will randomly-generate object IDs in XKT`);
118283
+ const numPrimitives = mesh.primitives.length;
118284
+ if (numPrimitives > 0) {
118285
+ for (let i = 0; i < numPrimitives; i++) {
118286
+ const primitive = mesh.primitives[i];
118287
+ if (primitive.mode < 4) {
118288
+ continue;
117542
118289
  }
117543
- let entityId = nodeName; // Fall back on generated ID when `name` not found on glTF scene node(s)
117544
- // if (!!entityId && sceneModel.entities[entityId]) {
117545
- // ctx.log(`Warning: Two or more glTF nodes found with same 'name' attribute: '${nodeName} - will randomly-generating an object ID in XKT`);
117546
- // }
117547
- // while (!entityId || sceneModel.entities[entityId]) {
117548
- // entityId = "entity-" + ctx.nextId++;
117549
- // }
117550
- if (ctx.metaModelCorrections) {
117551
- // Merging meshes into XKTObjects that map to metaobjects
117552
- const rootMetaObject = ctx.metaModelCorrections.eachChildRoot[entityId];
117553
- if (rootMetaObject) {
117554
- const rootMetaObjectStats = ctx.metaModelCorrections.eachRootStats[rootMetaObject.id];
117555
- rootMetaObjectStats.countChildren++;
117556
- if (rootMetaObjectStats.countChildren >= rootMetaObjectStats.numChildren) {
117557
- sceneModel.createEntity({
117558
- id: rootMetaObject.id,
117559
- meshIds: deferredMeshIds,
117560
- isObject: true
117561
- });
117562
- deferredMeshIds.length = 0;
117563
- }
117564
- } else {
117565
- const metaObject = ctx.metaModelCorrections.metaObjectsMap[entityId];
117566
- if (metaObject) {
117567
- sceneModel.createEntity({
117568
- id: entityId,
117569
- meshIds: deferredMeshIds,
117570
- isObject: true
117571
- });
117572
- deferredMeshIds.length = 0;
117573
- }
117574
- }
118290
+ const meshCfg = {
118291
+ id: ctx.sceneModel.id + "." + ctx.numObjects++
118292
+ };
118293
+ const material = primitive.material;
118294
+ if (material) {
118295
+ meshCfg.textureSetId = material._textureSetId;
118296
+ meshCfg.color = material._attributes.color;
118297
+ meshCfg.opacity = material._attributes.opacity;
118298
+ meshCfg.metallic = material._attributes.metallic;
118299
+ meshCfg.roughness = material._attributes.roughness;
117575
118300
  } else {
117576
- // Create an XKTObject from the meshes at each named glTF node, don't care about metaobjects
117577
- sceneModel.createEntity({
117578
- id: entityId,
117579
- meshIds: deferredMeshIds,
117580
- isObject: true
117581
- });
117582
- deferredMeshIds.length = 0;
118301
+ meshCfg.color = new Float32Array([1.0, 1.0, 1.0]);
118302
+ meshCfg.opacity = 1.0;
118303
+ }
118304
+ const backfaces = ((ctx.backfaces !== false) || (material && material.doubleSided !== false));
118305
+ switch (primitive.mode) {
118306
+ case 0: // POINTS
118307
+ meshCfg.primitive = "points";
118308
+ break;
118309
+ case 1: // LINES
118310
+ meshCfg.primitive = "lines";
118311
+ break;
118312
+ case 2: // LINE_LOOP
118313
+ meshCfg.primitive = "lines";
118314
+ break;
118315
+ case 3: // LINE_STRIP
118316
+ meshCfg.primitive = "lines";
118317
+ break;
118318
+ case 4: // TRIANGLES
118319
+ meshCfg.primitive = backfaces ? "triangles" : "solid";
118320
+ break;
118321
+ case 5: // TRIANGLE_STRIP
118322
+ meshCfg.primitive = backfaces ? "triangles" : "solid";
118323
+ break;
118324
+ case 6: // TRIANGLE_FAN
118325
+ meshCfg.primitive = backfaces ? "triangles" : "solid";
118326
+ break;
118327
+ default:
118328
+ meshCfg.primitive = backfaces ? "triangles" : "solid";
118329
+ }
118330
+ const POSITION = primitive.attributes.POSITION;
118331
+ if (!POSITION) {
118332
+ continue;
118333
+ }
118334
+ meshCfg.localPositions = POSITION.value;
118335
+ meshCfg.positions = new Float64Array(meshCfg.localPositions.length);
118336
+ if (primitive.attributes.NORMAL) {
118337
+ meshCfg.normals = primitive.attributes.NORMAL.value;
118338
+ }
118339
+ if (primitive.attributes.TEXCOORD_0) {
118340
+ meshCfg.uv = primitive.attributes.TEXCOORD_0.value;
117583
118341
  }
118342
+ if (primitive.indices) {
118343
+ meshCfg.indices = primitive.indices.value;
118344
+ }
118345
+ math.transformPositions3(matrix, meshCfg.localPositions, meshCfg.positions);
118346
+ const origin = math.vec3();
118347
+ const rtcNeeded = worldToRTCPositions(meshCfg.positions, meshCfg.positions, origin); // Small cellsize guarantees better accuracy
118348
+ if (rtcNeeded) {
118349
+ meshCfg.origin = origin;
118350
+ }
118351
+ ctx.sceneModel.createMesh(meshCfg);
118352
+ meshIds.push(meshCfg.id);
117584
118353
  }
117585
118354
  }
117586
118355
  }
@@ -117907,8 +118676,6 @@ class GLTFLoaderPlugin extends Plugin {
117907
118676
  * @param {String} [params.metaModelSrc] Path to an optional metadata file, as an alternative to the ````metaModelJSON```` parameter.
117908
118677
  * @param {*} [params.metaModelJSON] JSON model metadata, as an alternative to the ````metaModelSrc```` parameter.
117909
118678
  * @param {{String:Object}} [params.objectDefaults] Map of initial default states for each loaded {@link Entity} that represents an object. Default value is {@link IFCObjectDefaults}.
117910
- * @param {String[]} [params.includeTypes] When loading metadata, only loads objects that have {@link MetaObject}s with {@link MetaObject#type} values in this list.
117911
- * @param {String[]} [params.excludeTypes] When loading metadata, never loads objects that have {@link MetaObject}s with {@link MetaObject#type} values in this list.
117912
118679
  * @param {Boolean} [params.edges=false] Whether or not xeokit renders the model with edges emphasized.
117913
118680
  * @param {Number[]} [params.origin=[0,0,0]] The double-precision World-space origin of the model's coordinates.
117914
118681
  * @param {Number[]} [params.position=[0,0,0]] The single-precision position, relative to ````origin````.
@@ -117924,150 +118691,47 @@ class GLTFLoaderPlugin extends Plugin {
117924
118691
  * represent the returned model. Set false to always use vertex buffer objects (VBOs). Note that DTX is only applicable
117925
118692
  * to non-textured triangle meshes, and that VBOs are always used for meshes that have textures, line segments, or point
117926
118693
  * primitives. Only works while {@link DTX#enabled} is also ````true````.
117927
- * @param {String} [params.entityId] When supplied, causes the entire model to be loaded into a single {@link Entity} that gets this ID.
118694
+ * @param {Boolean} [params.autoMetaModel] When supplied, creates a default MetaModel with a single MetaObject.
117928
118695
  * @returns {Entity} Entity representing the model, which will have {@link Entity#isModel} set ````true```` and will be registered by {@link Entity#id} in {@link Scene#models}
117929
118696
  */
117930
118697
  load(params = {}) {
117931
-
117932
118698
  if (params.id && this.viewer.scene.components[params.id]) {
117933
118699
  this.error("Component with this ID already exists in viewer: " + params.id + " - will autogenerate this ID");
117934
118700
  delete params.id;
117935
118701
  }
117936
-
117937
118702
  const sceneModel = new SceneModel(this.viewer.scene, utils.apply(params, {
117938
118703
  isModel: true,
117939
118704
  dtxEnabled: params.dtxEnabled
117940
118705
  }));
117941
-
117942
118706
  const modelId = sceneModel.id; // In case ID was auto-generated
117943
-
117944
118707
  if (!params.src && !params.gltf) {
117945
118708
  this.error("load() param expected: src or gltf");
117946
118709
  return sceneModel; // Return new empty model
117947
118710
  }
117948
-
117949
118711
  if (params.metaModelSrc || params.metaModelJSON) {
117950
-
117951
- const objectDefaults = params.objectDefaults || this._objectDefaults || IFCObjectDefaults;
117952
-
117953
118712
  const processMetaModelJSON = (metaModelJSON) => {
117954
-
117955
- this.viewer.metaScene.createMetaModel(modelId, metaModelJSON, {
117956
- includeTypes: params.includeTypes,
117957
- excludeTypes: params.excludeTypes
117958
- });
117959
-
118713
+ this.viewer.metaScene.createMetaModel(modelId, metaModelJSON, {});
117960
118714
  this.viewer.scene.canvas.spinner.processes--;
117961
-
117962
- let includeTypes;
117963
- if (params.includeTypes) {
117964
- includeTypes = {};
117965
- for (let i = 0, len = params.includeTypes.length; i < len; i++) {
117966
- includeTypes[params.includeTypes[i]] = true;
117967
- }
117968
- }
117969
- if (params.excludeTypes) {
117970
- if (!includeTypes) {
117971
- includeTypes = {};
117972
- }
117973
- for (let i = 0, len = params.excludeTypes.length; i < len; i++) {
117974
- includeTypes[params.excludeTypes[i]] = true;
117975
- }
117976
- }
117977
-
117978
- params.readableGeometry = false;
117979
-
117980
- params.handleGLTFNode = (modelId, glTFNode, actions) => {
117981
-
117982
- const name = glTFNode.name;
117983
-
117984
- if (!name) {
117985
- return true; // Continue descending this node subtree
117986
- }
117987
-
117988
- const nodeId = name;
117989
- const metaObject = this.viewer.metaScene.metaObjects[nodeId];
117990
- const type = (metaObject ? metaObject.type : "DEFAULT") || "DEFAULT";
117991
-
117992
- actions.createEntity = {
117993
- id: nodeId,
117994
- isObject: true // Registers the Entity in Scene#objects
117995
- };
117996
-
117997
- const props = objectDefaults[type];
117998
-
117999
- if (props) { // Set Entity's initial rendering state for recognized type
118000
-
118001
- if (props.visible === false) {
118002
- actions.createEntity.visible = false;
118003
- }
118004
-
118005
- if (props.colorize) {
118006
- actions.createEntity.colorize = props.colorize;
118007
- }
118008
-
118009
- if (props.pickable === false) {
118010
- actions.createEntity.pickable = false;
118011
- }
118012
-
118013
- if (props.opacity !== undefined && props.opacity !== null) {
118014
- actions.createEntity.opacity = props.opacity;
118015
- }
118016
- }
118017
-
118018
- return true; // Continue descending this glTF node subtree
118019
- };
118020
-
118021
118715
  if (params.src) {
118022
118716
  this._sceneModelLoader.load(this, params.src, metaModelJSON, params, sceneModel);
118023
118717
  } else {
118024
118718
  this._sceneModelLoader.parse(this, params.gltf, metaModelJSON, params, sceneModel);
118025
118719
  }
118026
118720
  };
118027
-
118028
118721
  if (params.metaModelSrc) {
118029
-
118030
118722
  const metaModelSrc = params.metaModelSrc;
118031
-
118032
118723
  this.viewer.scene.canvas.spinner.processes++;
118033
-
118034
118724
  this._dataSource.getMetaModel(metaModelSrc, (metaModelJSON) => {
118035
-
118036
118725
  this.viewer.scene.canvas.spinner.processes--;
118037
-
118038
118726
  processMetaModelJSON(metaModelJSON);
118039
-
118040
118727
  }, (errMsg) => {
118041
118728
  this.error(`load(): Failed to load model metadata for model '${modelId} from '${metaModelSrc}' - ${errMsg}`);
118042
118729
  this.viewer.scene.canvas.spinner.processes--;
118043
118730
  });
118044
-
118045
118731
  } else if (params.metaModelJSON) {
118046
-
118047
118732
  processMetaModelJSON(params.metaModelJSON);
118048
118733
  }
118049
-
118050
118734
  } else {
118051
-
118052
- params.handleGLTFNode = (modelId, glTFNode, actions) => {
118053
-
118054
- const name = glTFNode.name;
118055
-
118056
- if (!name) {
118057
- return true; // Continue descending this node subtree
118058
- }
118059
-
118060
- const id = name;
118061
-
118062
- actions.createEntity = { // Create an Entity for this glTF scene node
118063
- id: id,
118064
- isObject: true // Registers the Entity in Scene#objects
118065
- };
118066
-
118067
- return true; // Continue descending this glTF node subtree
118068
- };
118069
-
118070
-
118071
118735
  if (params.src) {
118072
118736
  this._sceneModelLoader.load(this, params.src, null, params, sceneModel);
118073
118737
  } else {
@@ -122938,13 +123602,43 @@ class StoreyViewsPlugin extends Plugin {
122938
123602
  getStoreyContainingWorldPos(worldPos) {
122939
123603
  for (var storeyId in this.storeys) {
122940
123604
  const storey = this.storeys[storeyId];
122941
- if (math.point3AABB3Intersect(storey.storeyAABB, worldPos)) {
123605
+ if (math.point3AABB3AbsoluteIntersect(storey.storeyAABB, worldPos)) {
122942
123606
  return storeyId;
122943
123607
  }
122944
123608
  }
122945
123609
  return null;
122946
123610
  }
122947
123611
 
123612
+ /**
123613
+ * Gets the ID of the storey which's bounding box contains the y point of the world position
123614
+ *
123615
+ * @param {Number[]} worldPos 3D World-space position.
123616
+ * @returns {String} ID of the storey containing the position, or null if the position falls outside all the storeys.
123617
+ */
123618
+ getStoreyInVerticalRange(worldPos) {
123619
+ for(let storeyId in this.storeys) {
123620
+ const storey = this.storeys[storeyId];
123621
+ const aabb = [0,0,0,0,0,0], pos = [0,0,0];
123622
+ aabb[1] = storey.storeyAABB[1];
123623
+ aabb[4] = storey.storeyAABB[4];
123624
+ pos[1] = worldPos[1];
123625
+ if (math.point3AABB3AbsoluteIntersect(aabb, pos)) {
123626
+ return storeyId;
123627
+ }
123628
+ }
123629
+ return null;
123630
+ }
123631
+
123632
+ isPositionAboveOrBelowBuilding(worldPos){
123633
+ const keys = Object.keys(this.storeys);
123634
+ const ids = [keys[0], keys[keys.length-1]];
123635
+ if(worldPos[1] < this.storeys[ids[0]].storeyAABB[1])
123636
+ return ids[0];
123637
+ else if (worldPos[1] > this.storeys[ids[1]].storeyAABB[4])
123638
+ return ids[1];
123639
+ return null;
123640
+ }
123641
+
122948
123642
  /**
122949
123643
  * Converts a 3D World-space position to a 2D position within a StoreyMap image.
122950
123644
  *
@@ -131832,6 +132526,9 @@ class XKTLoaderPlugin extends Plugin {
131832
132526
  this.viewer.scene.canvas.spinner.processes++;
131833
132527
 
131834
132528
  const finish = () => {
132529
+ if (sceneModel.destroyed) {
132530
+ return;
132531
+ }
131835
132532
  // this._createDefaultMetaModelIfNeeded(sceneModel, params, options);
131836
132533
  sceneModel.finalize();
131837
132534
  metaModel.finalize();
@@ -131913,7 +132610,9 @@ class XKTLoaderPlugin extends Plugin {
131913
132610
  const loadJSONs = (metaDataFiles, done, error) => {
131914
132611
  let i = 0;
131915
132612
  const loadNext = () => {
131916
- if (i >= metaDataFiles.length) {
132613
+ if (sceneModel.destroyed) {
132614
+ done();
132615
+ } else if (i >= metaDataFiles.length) {
131917
132616
  done();
131918
132617
  } else {
131919
132618
  this._dataSource.getMetaModel(`${baseDir}${metaDataFiles[i]}`, (metaModelData) => {
@@ -131923,7 +132622,7 @@ class XKTLoaderPlugin extends Plugin {
131923
132622
  globalizeObjectIds: options.globalizeObjectIds
131924
132623
  });
131925
132624
  i++;
131926
- this.scheduleTask(loadNext, 100);
132625
+ this.scheduleTask(loadNext, 200);
131927
132626
  }, error);
131928
132627
  }
131929
132628
  };
@@ -131932,13 +132631,16 @@ class XKTLoaderPlugin extends Plugin {
131932
132631
  const loadXKTs_excludeTheirMetaModels = (xktFiles, done, error) => { // Load XKTs, ignore metamodels in the XKT
131933
132632
  let i = 0;
131934
132633
  const loadNext = () => {
131935
- if (i >= xktFiles.length) {
132634
+ if (sceneModel.destroyed) {
132635
+ done();
132636
+ } else if (i >= xktFiles.length) {
131936
132637
  done();
131937
132638
  } else {
131938
132639
  this._dataSource.getXKT(`${baseDir}${xktFiles[i]}`, (arrayBuffer) => {
131939
132640
  this._parseModel(arrayBuffer, params, options, sceneModel, null /* Ignore metamodel in XKT */, manifestCtx);
132641
+ sceneModel.preFinalize();
131940
132642
  i++;
131941
- this.scheduleTask(loadNext, 100);
132643
+ this.scheduleTask(loadNext, 200);
131942
132644
  }, error);
131943
132645
  }
131944
132646
  };
@@ -131947,13 +132649,16 @@ class XKTLoaderPlugin extends Plugin {
131947
132649
  const loadXKTs_includeTheirMetaModels = (xktFiles, done, error) => { // Load XKTs, parse metamodels from the XKT
131948
132650
  let i = 0;
131949
132651
  const loadNext = () => {
131950
- if (i >= xktFiles.length) {
132652
+ if (sceneModel.destroyed) {
132653
+ done();
132654
+ } else if (i >= xktFiles.length) {
131951
132655
  done();
131952
132656
  } else {
131953
132657
  this._dataSource.getXKT(`${baseDir}${xktFiles[i]}`, (arrayBuffer) => {
131954
132658
  this._parseModel(arrayBuffer, params, options, sceneModel, metaModel, manifestCtx);
132659
+ sceneModel.preFinalize();
131955
132660
  i++;
131956
- this.scheduleTask(loadNext, 100);
132661
+ this.scheduleTask(loadNext, 200);
131957
132662
  }, error);
131958
132663
  }
131959
132664
  };
@@ -132003,11 +132708,12 @@ class XKTLoaderPlugin extends Plugin {
132003
132708
  _loadModel(src, params, options, sceneModel, metaModel, manifestCtx, done, error) {
132004
132709
  this._dataSource.getXKT(params.src, (arrayBuffer) => {
132005
132710
  this._parseModel(arrayBuffer, params, options, sceneModel, metaModel, manifestCtx);
132711
+ sceneModel.preFinalize();
132006
132712
  done();
132007
132713
  }, error);
132008
132714
  }
132009
132715
 
132010
- _parseModel(arrayBuffer, params, options, sceneModel, metaModel, manifestCtx) {
132716
+ async _parseModel(arrayBuffer, params, options, sceneModel, metaModel, manifestCtx) {
132011
132717
  if (sceneModel.destroyed) {
132012
132718
  return;
132013
132719
  }
@@ -132019,7 +132725,7 @@ class XKTLoaderPlugin extends Plugin {
132019
132725
  this.error("Unsupported .XKT file version: " + xktVersion + " - this XKTLoaderPlugin supports versions " + Object.keys(parsers));
132020
132726
  return;
132021
132727
  }
132022
- this.log("Loading .xkt V" + xktVersion);
132728
+ // this.log("Loading .xkt V" + xktVersion);
132023
132729
  const numElements = dataView.getUint32(4, true);
132024
132730
  const elements = [];
132025
132731
  let byteOffset = (numElements + 2) * 4;
@@ -138781,7 +139487,7 @@ const triangulateEarClipping = function(planeCoords) {
138781
139487
  next.prev = ear.prev;
138782
139488
  }
138783
139489
 
138784
- return [ planeCoords, baseTriangles ];
139490
+ return [ planeCoords, baseTriangles, isCCW ];
138785
139491
  };
138786
139492
 
138787
139493
  const marker3D = function(scene, color) {
@@ -139303,7 +140009,7 @@ class Zone extends Component {
139303
140009
  const altitude = this._geometry.altitude + (downward ? this._geometry.height : 0);
139304
140010
  const height = this._geometry.height * (downward ? -1 : 1);
139305
140011
 
139306
- const [ baseVertices, baseTriangles ] = triangulateEarClipping(planeCoords); // TODO: prevent crossing edges
140012
+ const [ baseVertices, baseTriangles, isCCW ] = triangulateEarClipping(planeCoords); // TODO: prevent crossing edges
139307
140013
 
139308
140014
  const pos = [ ];
139309
140015
  const ind = [ ];
@@ -139327,7 +140033,7 @@ class Zone extends Component {
139327
140033
  // sides
139328
140034
  for (let i = 0; i < baseVertices.length; ++i) {
139329
140035
  const a = baseVertices[i];
139330
- const b = baseVertices[(i+1) % baseVertices.length];
140036
+ const b = baseVertices[(baseVertices.length + i + (isCCW ? 1 : -1)) % baseVertices.length];
139331
140037
  const f = altitude;
139332
140038
  const c = altitude + height;
139333
140039
 
@@ -139370,6 +140076,28 @@ class Zone extends Component {
139370
140076
 
139371
140077
  this._zoneMesh.zone = this;
139372
140078
 
140079
+ {
140080
+ const u = math.vec2();
140081
+ const v = math.vec2();
140082
+
140083
+ let baseArea = 0;
140084
+
140085
+ for (let t of baseTriangles) {
140086
+ const p0 = baseVertices[t[0]];
140087
+ const p1 = baseVertices[t[1]];
140088
+ const p2 = baseVertices[t[2]];
140089
+
140090
+ math.subVec2(p1, p0, u);
140091
+ math.subVec2(p2, p0, v);
140092
+
140093
+ baseArea += Math.abs(u[0] * v[1] - u[1] * v[0]);
140094
+ }
140095
+
140096
+ this._baseArea = baseArea / 2;
140097
+ }
140098
+
140099
+ this._metrics = null;
140100
+
139373
140101
 
139374
140102
  const min = idx => Math.min(...pos.map(p => p[idx]));
139375
140103
  const max = idx => Math.max(...pos.map(p => p[idx]));
@@ -139384,6 +140112,48 @@ class Zone extends Component {
139384
140112
  this._center = math.vec3([ (xmin + xmax) / 2, (ymin + ymax) / 2, (zmin + zmax) / 2 ]);
139385
140113
  }
139386
140114
 
140115
+ get baseArea() {
140116
+ return this._baseArea;
140117
+ }
140118
+
140119
+ get area() {
140120
+ return this._getMetrics().area;
140121
+ }
140122
+
140123
+ get volume() {
140124
+ return this._getMetrics().volume;
140125
+ }
140126
+
140127
+ _getMetrics() {
140128
+ if (this._metrics === null) {
140129
+ // Sum the volume of tetrahedrons formed by the origin and face triangles
140130
+ let volume = 0;
140131
+ let area = 0;
140132
+ const geo = this._zoneMesh.geometry;
140133
+ const pts = [ math.vec3(), math.vec3(), math.vec3() ];
140134
+ const tmpVec3 = math.vec3();
140135
+ for (let i = 0; i < geo.indices.length; i += 3) {
140136
+ for (let off = 0; off < 3; ++off) {
140137
+ const p = pts[off];
140138
+ const pIdx = 3 * geo.indices[i + off];
140139
+ for (let c = 0; c < 3; ++c) {
140140
+ p[c] = geo.positions[pIdx + c];
140141
+ }
140142
+ }
140143
+ volume += math.dotVec3(pts[0], math.cross3Vec3(pts[1], pts[2], tmpVec3));
140144
+ math.subVec3(pts[1], pts[0], pts[1]);
140145
+ math.subVec3(pts[2], pts[0], pts[2]);
140146
+ area += math.lenVec3(math.cross3Vec3(pts[1], pts[2], tmpVec3));
140147
+ }
140148
+
140149
+ this._metrics = {
140150
+ area: area / 2,
140151
+ volume: volume / 6
140152
+ };
140153
+ }
140154
+ return this._metrics;
140155
+ }
140156
+
139387
140157
  sectionedAverage(sectionPlanes) {
139388
140158
  const planeCoords = this._geometry.planeCoordinates.slice();
139389
140159
 
@@ -140512,4 +141282,4 @@ class ZoneTranslateTouchControl extends ZoneTranslateControl {
140512
141282
  }
140513
141283
  }
140514
141284
 
140515
- export { AlphaFormat, AmbientLight, AngleMeasurementEditMouseControl, AngleMeasurementEditTouchControl, AngleMeasurementsControl, AngleMeasurementsMouseControl, AngleMeasurementsPlugin, AngleMeasurementsTouchControl, AnnotationsPlugin, AxisGizmoPlugin, BCFViewpointsPlugin, Bitmap, ByteType, CameraMemento, CameraPath, CameraPathAnimation, CityJSONLoaderPlugin, ClampToEdgeWrapping, Component, CompressedMediaType, Configs, ContextMenu, CubicBezierCurve, Curve, DefaultLoadingManager, DepthFormat, DepthStencilFormat, DirLight, DistanceMeasurementEditMouseControl, DistanceMeasurementEditTouchControl, DistanceMeasurementsControl, DistanceMeasurementsMouseControl, DistanceMeasurementsPlugin, DistanceMeasurementsTouchControl, DotBIMDefaultDataSource, DotBIMLoaderPlugin, EdgeMaterial, EmphasisMaterial, FaceAlignedSectionPlanesPlugin, FastNavPlugin, FloatType, Fresnel, Frustum$1 as Frustum, FrustumPlane, GIFMediaType, GLTFDefaultDataSource, GLTFLoaderPlugin, HalfFloatType, ImagePlane, IntType, JPEGMediaType, KTX2TextureTranscoder, LASLoaderPlugin, LambertMaterial, LightMap, LineSet, LinearEncoding, LinearFilter, LinearMipMapLinearFilter, LinearMipMapNearestFilter, LinearMipmapLinearFilter, LinearMipmapNearestFilter, Loader, LoadingManager, LocaleService, LuminanceAlphaFormat, LuminanceFormat, Map$1 as Map, Marker, MarqueePicker, MarqueePickerMouseControl, Mesh, MetallicMaterial, MirroredRepeatWrapping, ModelMemento, NavCubePlugin, NearestFilter, NearestMipMapLinearFilter, NearestMipMapNearestFilter, NearestMipmapLinearFilter, NearestMipmapNearestFilter, Node$2 as Node, OBJLoaderPlugin, ObjectsKdTree3, ObjectsMemento, PNGMediaType, Path, PerformanceModel, PhongMaterial, PickResult, Plugin, PointLight, PointerCircle, PointerLens, QuadraticBezierCurve, Queue, RGBAFormat, RGBAIntegerFormat, RGBA_ASTC_10x10_Format, RGBA_ASTC_10x5_Format, RGBA_ASTC_10x6_Format, RGBA_ASTC_10x8_Format, RGBA_ASTC_12x10_Format, RGBA_ASTC_12x12_Format, RGBA_ASTC_4x4_Format, RGBA_ASTC_5x4_Format, RGBA_ASTC_5x5_Format, RGBA_ASTC_6x5_Format, RGBA_ASTC_6x6_Format, RGBA_ASTC_8x5_Format, RGBA_ASTC_8x6_Format, RGBA_ASTC_8x8_Format, RGBA_BPTC_Format, RGBA_ETC2_EAC_Format, RGBA_PVRTC_2BPPV1_Format, RGBA_PVRTC_4BPPV1_Format, RGBA_S3TC_DXT1_Format, RGBA_S3TC_DXT3_Format, RGBA_S3TC_DXT5_Format, RGBFormat, RGB_ETC1_Format, RGB_ETC2_Format, RGB_PVRTC_2BPPV1_Format, RGB_PVRTC_4BPPV1_Format, RGB_S3TC_DXT1_Format, RGFormat, RGIntegerFormat, ReadableGeometry, RedFormat, RedIntegerFormat, ReflectionMap, RepeatWrapping, STLDefaultDataSource, STLLoaderPlugin, SceneModel, SceneModelMesh, SceneModelTransform, SectionPlane, SectionPlanesPlugin, ShortType, Skybox, SkyboxesPlugin, SpecularMaterial, SplineCurve, SpriteMarker, StoreyViewsPlugin, Texture, TextureTranscoder, TreeViewPlugin, UnsignedByteType, UnsignedInt248Type, UnsignedIntType, UnsignedShort4444Type, UnsignedShort5551Type, UnsignedShortType, VBOGeometry, ViewCullPlugin, Viewer, WebIFCLoaderPlugin, WorkerPool$1 as WorkerPool, XKTDefaultDataSource, XKTLoaderPlugin, XML3DLoaderPlugin, ZoneEditControl, ZoneEditMouseControl, ZoneEditTouchControl, ZoneTranslateControl, ZoneTranslateMouseControl, ZoneTranslateTouchControl, ZonesMouseControl, ZonesPlugin, ZonesPolysurfaceMouseControl, ZonesPolysurfaceTouchControl, ZonesTouchControl, buildBoxGeometry, buildBoxLinesGeometry, buildBoxLinesGeometryFromAABB, buildCylinderGeometry, buildGridGeometry, buildLineGeometry, buildPlaneGeometry, buildPolylineGeometry, buildPolylineGeometryFromCurve, buildSphereGeometry, buildTorusGeometry, buildVectorTextGeometry, createRTCViewMat, frustumIntersectsAABB3, getKTX2TextureTranscoder, getPlaneRTCPos, load3DSGeometry, loadOBJGeometry, math, rtcToWorldPos, sRGBEncoding, setFrustum, stats, utils, worldToRTCPos, worldToRTCPositions };
141285
+ export { AlphaFormat, AmbientLight, AngleMeasurementEditMouseControl, AngleMeasurementEditTouchControl, AngleMeasurementsControl, AngleMeasurementsMouseControl, AngleMeasurementsPlugin, AngleMeasurementsTouchControl, AnnotationsPlugin, AxisGizmoPlugin, BCFViewpointsPlugin, Bitmap, ByteType, CameraMemento, CameraPath, CameraPathAnimation, CityJSONLoaderPlugin, ClampToEdgeWrapping, Component, CompressedMediaType, Configs, ContextMenu, CubicBezierCurve, Curve, DefaultLoadingManager, DepthFormat, DepthStencilFormat, DirLight, DistanceMeasurementEditControl, DistanceMeasurementEditMouseControl, DistanceMeasurementEditTouchControl, DistanceMeasurementsControl, DistanceMeasurementsMouseControl, DistanceMeasurementsPlugin, DistanceMeasurementsTouchControl, DotBIMDefaultDataSource, DotBIMLoaderPlugin, EdgeMaterial, EmphasisMaterial, FaceAlignedSectionPlanesPlugin, FastNavPlugin, FloatType, Fresnel, Frustum$1 as Frustum, FrustumPlane, GIFMediaType, GLTFDefaultDataSource, GLTFLoaderPlugin, HalfFloatType, ImagePlane, IntType, JPEGMediaType, KTX2TextureTranscoder, LASLoaderPlugin, LambertMaterial, LightMap, LineSet, LinearEncoding, LinearFilter, LinearMipMapLinearFilter, LinearMipMapNearestFilter, LinearMipmapLinearFilter, LinearMipmapNearestFilter, Loader, LoadingManager, LocaleService, LuminanceAlphaFormat, LuminanceFormat, Map$1 as Map, Marker, MarqueePicker, MarqueePickerMouseControl, Mesh, MeshSurfaceArea, MeshVolume, MetallicMaterial, MirroredRepeatWrapping, ModelMemento, NavCubePlugin, NearestFilter, NearestMipMapLinearFilter, NearestMipMapNearestFilter, NearestMipmapLinearFilter, NearestMipmapNearestFilter, Node$2 as Node, OBJLoaderPlugin, ObjectsKdTree3, ObjectsMemento, PNGMediaType, Path, PerformanceModel, PhongMaterial, PickResult, Plugin, PointLight, PointerCircle, PointerLens, QuadraticBezierCurve, Queue, RGBAFormat, RGBAIntegerFormat, RGBA_ASTC_10x10_Format, RGBA_ASTC_10x5_Format, RGBA_ASTC_10x6_Format, RGBA_ASTC_10x8_Format, RGBA_ASTC_12x10_Format, RGBA_ASTC_12x12_Format, RGBA_ASTC_4x4_Format, RGBA_ASTC_5x4_Format, RGBA_ASTC_5x5_Format, RGBA_ASTC_6x5_Format, RGBA_ASTC_6x6_Format, RGBA_ASTC_8x5_Format, RGBA_ASTC_8x6_Format, RGBA_ASTC_8x8_Format, RGBA_BPTC_Format, RGBA_ETC2_EAC_Format, RGBA_PVRTC_2BPPV1_Format, RGBA_PVRTC_4BPPV1_Format, RGBA_S3TC_DXT1_Format, RGBA_S3TC_DXT3_Format, RGBA_S3TC_DXT5_Format, RGBFormat, RGB_ETC1_Format, RGB_ETC2_Format, RGB_PVRTC_2BPPV1_Format, RGB_PVRTC_4BPPV1_Format, RGB_S3TC_DXT1_Format, RGFormat, RGIntegerFormat, ReadableGeometry, RedFormat, RedIntegerFormat, ReflectionMap, RepeatWrapping, STLDefaultDataSource, STLLoaderPlugin, SceneModel, SceneModelMesh, SceneModelTransform, SectionPlane, SectionPlanesPlugin, ShortType, Skybox, SkyboxesPlugin, SpecularMaterial, SplineCurve, SpriteMarker, StoreyViewsPlugin, Texture, TextureTranscoder, TreeViewPlugin, UnsignedByteType, UnsignedInt248Type, UnsignedIntType, UnsignedShort4444Type, UnsignedShort5551Type, UnsignedShortType, VBOGeometry, ViewCullPlugin, Viewer, WebIFCLoaderPlugin, WorkerPool$1 as WorkerPool, XKTDefaultDataSource, XKTLoaderPlugin, XML3DLoaderPlugin, ZoneEditControl, ZoneEditMouseControl, ZoneEditTouchControl, ZoneTranslateControl, ZoneTranslateMouseControl, ZoneTranslateTouchControl, ZonesMouseControl, ZonesPlugin, ZonesPolysurfaceMouseControl, ZonesPolysurfaceTouchControl, ZonesTouchControl, buildBoxGeometry, buildBoxLinesGeometry, buildBoxLinesGeometryFromAABB, buildCylinderGeometry, buildGridGeometry, buildLineGeometry, buildPlaneGeometry, buildPolylineGeometry, buildPolylineGeometryFromCurve, buildSphereGeometry, buildTorusGeometry, buildVectorTextGeometry, createRTCViewMat, frustumIntersectsAABB3, getKTX2TextureTranscoder, getPlaneRTCPos, isTriangleMeshSolid, load3DSGeometry, loadOBJGeometry, math, meshSurfaceArea, meshVolume, rtcToWorldPos, sRGBEncoding, setFrustum, stats, utils, worldToRTCPos, worldToRTCPositions };