@xeokit/xeokit-sdk 2.6.54 → 2.6.57

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 (37) hide show
  1. package/dist/xeokit-sdk.cjs.js +1414 -1786
  2. package/dist/xeokit-sdk.es.js +1412 -1787
  3. package/dist/xeokit-sdk.es5.js +732 -725
  4. package/dist/xeokit-sdk.min.cjs.js +5 -5
  5. package/dist/xeokit-sdk.min.es.js +5 -5
  6. package/dist/xeokit-sdk.min.es5.js +4 -4
  7. package/package.json +1 -1
  8. package/src/plugins/AngleMeasurementsPlugin/AngleMeasurement.js +155 -415
  9. package/src/plugins/AngleMeasurementsPlugin/AngleMeasurementsMouseControl.js +1 -1
  10. package/src/plugins/AnnotationsPlugin/Annotation.js +7 -5
  11. package/src/plugins/DistanceMeasurementsPlugin/DistanceMeasurement.js +236 -750
  12. package/src/plugins/StoreyViewsPlugin/StoreyViewsPlugin.js +51 -0
  13. package/src/plugins/TreeViewPlugin/RenderService.js +2 -1
  14. package/src/plugins/XKTLoaderPlugin/XKTLoaderPlugin.js +5 -1
  15. package/src/plugins/ZonesPlugin/ZonesPlugin.js +15 -79
  16. package/src/plugins/lib/html/Dot.js +14 -41
  17. package/src/plugins/lib/html/Label.js +10 -37
  18. package/src/plugins/lib/html/MenuEvent.js +74 -0
  19. package/src/plugins/lib/html/Wire.js +20 -47
  20. package/src/plugins/lib/ui/index.js +370 -12
  21. package/src/viewer/Viewer.js +9 -0
  22. package/src/viewer/index.js +1 -0
  23. package/src/viewer/scene/CameraControl/CameraControl.js +38 -0
  24. package/src/viewer/scene/CameraControl/lib/CameraUpdater.js +5 -4
  25. package/src/viewer/scene/CameraControl/lib/handlers/KeyboardPanRotateDollyHandler.js +0 -8
  26. package/src/viewer/scene/CameraControl/lib/handlers/MousePanRotateDollyHandler.js +1 -2
  27. package/src/viewer/scene/CameraControl/lib/handlers/TouchPanRotateAndDollyHandler.js +2 -1
  28. package/src/viewer/scene/marker/Marker.js +20 -23
  29. package/src/viewer/scene/model/SceneModelEntity.js +5 -0
  30. package/src/viewer/scene/model/vbo/instancing/triangles/VBOInstancingTrianglesLayer.js +1 -1
  31. package/src/viewer/utils/index.js +1 -0
  32. package/src/viewer/utils/os.js +8 -1
  33. package/types/viewer/scene/CameraControl/CameraControl.d.ts +23 -0
  34. package/types/viewer/scene/models/PerformanceModel/index.d.ts +0 -1
  35. package/types/viewer/scene/models/SceneModel.d.ts +0 -3
  36. package/types/viewer/scene/models/SceneModelEntity.d.ts +6 -0
  37. package/types/viewer/scene/nodes/Node.d.ts +1 -1
@@ -9569,9 +9569,89 @@ const os = {
9569
9569
  const isSafari = /Safari/i.test(userAgent) && !/Chrome/i.test(userAgent);
9570
9570
 
9571
9571
  return isIphone && isSafari;
9572
+ },
9573
+ isTouchDevice() {
9574
+ return (
9575
+ 'ontouchstart' in window || //works for most devices
9576
+ navigator.maxTouchPoints > 0 || //works for modern touch devices
9577
+ navigator.mxMaxTouchPoints > 0 //works for older microsoft touch devices
9578
+ )
9572
9579
  }
9573
9580
  };
9574
9581
 
9582
+ function addContextMenuListener(elem, callback) {
9583
+ if (!elem || !callback) return;
9584
+
9585
+ let timeout = null;
9586
+ const longPressTimer = 500;
9587
+ const MOVE_THRESHOLD = 3;
9588
+ let startX, startY;
9589
+
9590
+ const touchStartHandler = (event) => {
9591
+ event.preventDefault();
9592
+ const touch = event.touches[0];
9593
+ startX = touch.clientX;
9594
+ startY = touch.clientY;
9595
+
9596
+ if (timeout) {
9597
+ clearTimeout(timeout);
9598
+ timeout = null;
9599
+ }
9600
+
9601
+ timeout = setTimeout(() => {
9602
+ event.clientX = touch.clientX;
9603
+ event.clientY = touch.clientY;
9604
+ callback(event);
9605
+ clearTimeout(timeout);
9606
+ timeout = null;
9607
+ }, longPressTimer);
9608
+ };
9609
+
9610
+ const touchMoveHandler = (event) => {
9611
+ if (!timeout) return;
9612
+ const touch = event.touches[0];
9613
+ const deltaX = Math.abs(touch.clientX - startX);
9614
+ const deltaY = Math.abs(touch.clientY - startY);
9615
+
9616
+ if (deltaX > MOVE_THRESHOLD || deltaY > MOVE_THRESHOLD) {
9617
+ clearTimeout(timeout);
9618
+ timeout = null;
9619
+ }
9620
+ };
9621
+
9622
+ const touchEndHandler = (event) => {
9623
+ event.preventDefault();
9624
+ if (timeout) {
9625
+ clearTimeout(timeout);
9626
+ timeout = null;
9627
+ }
9628
+ };
9629
+
9630
+ const contextMenuHandler = (event) => {
9631
+ callback(event);
9632
+ event.preventDefault();
9633
+ event.stopPropagation();
9634
+ };
9635
+
9636
+ if (os.isIphoneSafari()) {
9637
+ elem.addEventListener('touchstart', touchStartHandler);
9638
+ elem.addEventListener('touchmove', touchMoveHandler);
9639
+ elem.addEventListener('touchend', touchEndHandler);
9640
+ } else {
9641
+ elem.addEventListener('contextmenu', contextMenuHandler);
9642
+ }
9643
+
9644
+ return function removeContextMenuListener() {
9645
+ if (os.isIphoneSafari()) {
9646
+ elem.removeEventListener('touchstart', touchStartHandler);
9647
+ elem.removeEventListener('touchmove', touchMoveHandler);
9648
+ elem.removeEventListener('touchend', touchEndHandler);
9649
+ } else {
9650
+ elem.removeEventListener('contextmenu', contextMenuHandler);
9651
+ }
9652
+ };
9653
+ }
9654
+
9575
9655
  /** @private */
9576
9656
  class Dot {
9577
9657
 
@@ -9685,41 +9765,10 @@ class Dot {
9685
9765
  }
9686
9766
 
9687
9767
  if (cfg.onContextMenu) {
9688
- if(os.isIphoneSafari()){
9689
- dotClickable.addEventListener('touchstart', (event) => {
9690
- event.preventDefault();
9691
- if(this._timeout){
9692
- clearTimeout(this._timeout);
9693
- this._timeout = null;
9694
- }
9695
- this._timeout = setTimeout(() => {
9696
- event.clientX = event.touches[0].clientX;
9697
- event.clientY = event.touches[0].clientY;
9698
- cfg.onContextMenu(event, this);
9699
- clearTimeout(this._timeout);
9700
- this._timeout = null;
9701
- }, 500);
9702
- });
9703
-
9704
- dotClickable.addEventListener('touchend', (event) => {
9705
- event.preventDefault();
9706
- //stops short touches from calling the timeout
9707
- if(this._timeout) {
9708
- clearTimeout(this._timeout);
9709
- this._timeout = null;
9710
- }
9711
- } );
9712
-
9713
- }
9714
- else {
9715
- dotClickable.addEventListener('contextmenu', (event) => {
9716
- console.log(event);
9717
- cfg.onContextMenu(event, this);
9718
- event.preventDefault();
9719
- event.stopPropagation();
9720
- console.log("Label context menu");
9721
- });
9722
- }
9768
+ const contextMenuCallback = (event) => {
9769
+ cfg.onContextMenu(event, this);
9770
+ };
9771
+ addContextMenuListener(dotClickable, contextMenuCallback);
9723
9772
 
9724
9773
  }
9725
9774
 
@@ -9732,12 +9781,12 @@ class Dot {
9732
9781
  this._x = x;
9733
9782
  this._y = y;
9734
9783
  var dotStyle = this._dot.style;
9735
- dotStyle["left"] = (Math.round(x) - 4) + 'px';
9736
- dotStyle["top"] = (Math.round(y) - 4) + 'px';
9784
+ dotStyle["left"] = (Math.round(x) - 6) + 'px';
9785
+ dotStyle["top"] = (Math.round(y) - 6) + 'px';
9737
9786
 
9738
9787
  var dotClickableStyle = this._dotClickable.style;
9739
- dotClickableStyle["left"] = (Math.round(x) - 9) + 'px';
9740
- dotClickableStyle["top"] = (Math.round(y) - 9) + 'px';
9788
+ dotClickableStyle["left"] = (Math.round(x) - 14) + 'px';
9789
+ dotClickableStyle["top"] = (Math.round(y) - 14) + 'px';
9741
9790
  }
9742
9791
 
9743
9792
  setFillColor(color) {
@@ -9752,12 +9801,16 @@ class Dot {
9752
9801
  this._dot.style.opacity = opacity;
9753
9802
  }
9754
9803
 
9804
+ _updateVisibility() {
9805
+ this._dot.style.visibility = this._dotClickable.style.visibility = this._visible && !this._culled ? "visible" : "hidden";
9806
+ }
9807
+
9755
9808
  setVisible(visible) {
9756
9809
  if (this._visible === visible) {
9757
9810
  return;
9758
9811
  }
9759
9812
  this._visible = !!visible;
9760
- this._dot.style.visibility = this._visible && !this._culled ? "visible" : "hidden";
9813
+ this._updateVisibility();
9761
9814
  }
9762
9815
 
9763
9816
  setCulled(culled) {
@@ -9765,7 +9818,7 @@ class Dot {
9765
9818
  return;
9766
9819
  }
9767
9820
  this._culled = !!culled;
9768
- this._dot.style.visibility = this._visible && !this._culled ? "visible" : "hidden";
9821
+ this._updateVisibility();
9769
9822
  }
9770
9823
 
9771
9824
  setClickable(clickable) {
@@ -9795,6 +9848,413 @@ class Dot {
9795
9848
  }
9796
9849
  }
9797
9850
 
9851
+ /** @private */
9852
+ class Label {
9853
+
9854
+ constructor(parentElement, cfg = {}) {
9855
+
9856
+ this._highlightClass = "viewer-ruler-label-highlighted";
9857
+
9858
+ this._prefix = cfg.prefix || "";
9859
+ this._x = 0;
9860
+ this._y = 0;
9861
+ this._visible = true;
9862
+ this._culled = false;
9863
+
9864
+ this._label = document.createElement('div');
9865
+ this._label.className += this._label.className ? ' viewer-ruler-label' : 'viewer-ruler-label';
9866
+ this._timeout = null;
9867
+
9868
+ var label = this._label;
9869
+ var style = label.style;
9870
+
9871
+ style["border-radius"] = 5 + "px";
9872
+ style.color = "white";
9873
+ style.padding = "4px";
9874
+ style.border = "solid 1px";
9875
+ style.background = "lightgreen";
9876
+ style.position = "absolute";
9877
+ style["z-index"] = cfg.zIndex === undefined ? "5000005" : cfg.zIndex;
9878
+ style.width = "auto";
9879
+ style.height = "auto";
9880
+ style.visibility = "visible";
9881
+ style.top = 0 + "px";
9882
+ style.left = 0 + "px";
9883
+ style["pointer-events"] = "all";
9884
+ style["opacity"] = 1.0;
9885
+ if (cfg.onContextMenu) ;
9886
+ label.innerText = "";
9887
+
9888
+ parentElement.appendChild(label);
9889
+
9890
+ this.setPos(cfg.x || 0, cfg.y || 0);
9891
+ this.setFillColor(cfg.fillColor);
9892
+ this.setBorderColor(cfg.fillColor);
9893
+ this.setText(cfg.text);
9894
+
9895
+ if (cfg.onMouseOver) {
9896
+ label.addEventListener('mouseover', (event) => {
9897
+ cfg.onMouseOver(event, this);
9898
+ event.preventDefault();
9899
+ });
9900
+ }
9901
+
9902
+ if (cfg.onMouseLeave) {
9903
+ label.addEventListener('mouseleave', (event) => {
9904
+ cfg.onMouseLeave(event, this);
9905
+ event.preventDefault();
9906
+ });
9907
+ }
9908
+
9909
+ if (cfg.onMouseWheel) {
9910
+ label.addEventListener('wheel', (event) => {
9911
+ cfg.onMouseWheel(event, this);
9912
+ });
9913
+ }
9914
+
9915
+ if (cfg.onMouseDown) {
9916
+ label.addEventListener('mousedown', (event) => {
9917
+ cfg.onMouseDown(event, this);
9918
+ event.stopPropagation();
9919
+ });
9920
+ }
9921
+
9922
+ if (cfg.onMouseUp) {
9923
+ label.addEventListener('mouseup', (event) => {
9924
+ cfg.onMouseUp(event, this);
9925
+ event.stopPropagation();
9926
+ });
9927
+ }
9928
+
9929
+ if (cfg.onMouseMove) {
9930
+ label.addEventListener('mousemove', (event) => {
9931
+ cfg.onMouseMove(event, this);
9932
+ });
9933
+ }
9934
+
9935
+ if (cfg.onContextMenu) {
9936
+ const contextMenuCallback = (event) => {
9937
+ cfg.onContextMenu(event, this);
9938
+ };
9939
+ addContextMenuListener(label, contextMenuCallback);
9940
+
9941
+ }
9942
+ }
9943
+
9944
+ setPos(x, y) {
9945
+ this._x = x;
9946
+ this._y = y;
9947
+ var style = this._label.style;
9948
+ style["left"] = (Math.round(x) - 20) + 'px';
9949
+ style["top"] = (Math.round(y) - 12) + 'px';
9950
+ }
9951
+
9952
+ setPosOnWire(x1, y1, x2, y2) {
9953
+ var x = x1 + ((x2 - x1) * 0.5);
9954
+ var y = y1 + ((y2 - y1) * 0.5);
9955
+ var style = this._label.style;
9956
+ style["left"] = (Math.round(x) - 20) + 'px';
9957
+ style["top"] = (Math.round(y) - 12) + 'px';
9958
+ }
9959
+
9960
+ setPosBetweenWires(x1, y1, x2, y2, x3, y3) {
9961
+ var x = (x1 + x2 + x3) / 3;
9962
+ var y = (y1 + y2 + y3) / 3;
9963
+ var style = this._label.style;
9964
+ style["left"] = (Math.round(x) - 20) + 'px';
9965
+ style["top"] = (Math.round(y) - 12) + 'px';
9966
+ }
9967
+
9968
+ setText(text) {
9969
+ this._label.innerHTML = this._prefix + (text || "");
9970
+ }
9971
+
9972
+ setFillColor(color) {
9973
+ this._fillColor = color || "lightgreen";
9974
+ this._label.style.background =this._fillColor;
9975
+ }
9976
+
9977
+ setBorderColor(color) {
9978
+ this._borderColor = color || "black";
9979
+ this._label.style.border = "solid 1px " + this._borderColor;
9980
+ }
9981
+
9982
+ setOpacity(opacity) {
9983
+ this._label.style.opacity = opacity;
9984
+ }
9985
+
9986
+ _updateVisibility() {
9987
+ this._label.style.visibility = this._visible && !this._culled ? "visible" : "hidden";
9988
+ }
9989
+
9990
+ setVisible(visible) {
9991
+ if (this._visible === visible) {
9992
+ return;
9993
+ }
9994
+ this._visible = !!visible;
9995
+ this._updateVisibility();
9996
+ }
9997
+
9998
+ setCulled(culled) {
9999
+ if (this._culled === culled) {
10000
+ return;
10001
+ }
10002
+ this._culled = !!culled;
10003
+ this._updateVisibility();
10004
+ }
10005
+
10006
+ setHighlighted(highlighted) {
10007
+ if (this._highlighted === highlighted) {
10008
+ return;
10009
+ }
10010
+ this._highlighted = !!highlighted;
10011
+ if (this._highlighted) {
10012
+ this._label.classList.add(this._highlightClass);
10013
+ } else {
10014
+ this._label.classList.remove(this._highlightClass);
10015
+ }
10016
+ }
10017
+
10018
+ setClickable(clickable) {
10019
+ this._label.style["pointer-events"] = (clickable) ? "all" : "none";
10020
+ }
10021
+
10022
+ setPrefix(prefix) {
10023
+ if(this._prefix === prefix){
10024
+ return;
10025
+ }
10026
+ this._prefix = prefix;
10027
+ }
10028
+
10029
+ destroy() {
10030
+ if (this._label.parentElement) {
10031
+ this._label.parentElement.removeChild(this._label);
10032
+ }
10033
+ }
10034
+
10035
+
10036
+ }
10037
+
10038
+ /** @private */
10039
+ class Wire {
10040
+
10041
+ constructor(parentElement, cfg = {}) {
10042
+
10043
+ this._color = cfg.color || "black";
10044
+ this._highlightClass = "viewer-ruler-wire-highlighted";
10045
+
10046
+ this._wire = document.createElement('div');
10047
+ this._wire.className += this._wire.className ? ' viewer-ruler-wire' : 'viewer-ruler-wire';
10048
+
10049
+ this._wireClickable = document.createElement('div');
10050
+ this._wireClickable.className += this._wireClickable.className ? ' viewer-ruler-wire-clickable' : 'viewer-ruler-wire-clickable';
10051
+
10052
+ this._thickness = cfg.thickness || 1.0;
10053
+ this._thicknessClickable = cfg.thicknessClickable || 6.0;
10054
+
10055
+ this._visible = true;
10056
+ this._culled = false;
10057
+
10058
+ var wire = this._wire;
10059
+ var wireStyle = wire.style;
10060
+
10061
+ wireStyle.border = "solid " + this._thickness + "px " + this._color;
10062
+ wireStyle.position = "absolute";
10063
+ wireStyle["z-index"] = cfg.zIndex === undefined ? "2000001" : cfg.zIndex;
10064
+ wireStyle.width = 0 + "px";
10065
+ wireStyle.height = 0 + "px";
10066
+ wireStyle.visibility = "visible";
10067
+ wireStyle.top = 0 + "px";
10068
+ wireStyle.left = 0 + "px";
10069
+ wireStyle['-webkit-transform-origin'] = "0 0";
10070
+ wireStyle['-moz-transform-origin'] = "0 0";
10071
+ wireStyle['-ms-transform-origin'] = "0 0";
10072
+ wireStyle['-o-transform-origin'] = "0 0";
10073
+ wireStyle['transform-origin'] = "0 0";
10074
+ wireStyle['-webkit-transform'] = 'rotate(0deg)';
10075
+ wireStyle['-moz-transform'] = 'rotate(0deg)';
10076
+ wireStyle['-ms-transform'] = 'rotate(0deg)';
10077
+ wireStyle['-o-transform'] = 'rotate(0deg)';
10078
+ wireStyle['transform'] = 'rotate(0deg)';
10079
+ wireStyle["opacity"] = 1.0;
10080
+ wireStyle["pointer-events"] = "none";
10081
+ if (cfg.onContextMenu) ;
10082
+
10083
+ parentElement.appendChild(wire);
10084
+
10085
+ var wireClickable = this._wireClickable;
10086
+ var wireClickableStyle = wireClickable.style;
10087
+
10088
+ wireClickableStyle.border = "solid " + this._thicknessClickable + "px " + this._color;
10089
+ wireClickableStyle.position = "absolute";
10090
+ wireClickableStyle["z-index"] = cfg.zIndex === undefined ? "2000002" : (cfg.zIndex + 1);
10091
+ wireClickableStyle.width = 0 + "px";
10092
+ wireClickableStyle.height = 0 + "px";
10093
+ wireClickableStyle.visibility = "visible";
10094
+ wireClickableStyle.top = 0 + "px";
10095
+ wireClickableStyle.left = 0 + "px";
10096
+ // wireClickableStyle["pointer-events"] = "none";
10097
+ wireClickableStyle['-webkit-transform-origin'] = "0 0";
10098
+ wireClickableStyle['-moz-transform-origin'] = "0 0";
10099
+ wireClickableStyle['-ms-transform-origin'] = "0 0";
10100
+ wireClickableStyle['-o-transform-origin'] = "0 0";
10101
+ wireClickableStyle['transform-origin'] = "0 0";
10102
+ wireClickableStyle['-webkit-transform'] = 'rotate(0deg)';
10103
+ wireClickableStyle['-moz-transform'] = 'rotate(0deg)';
10104
+ wireClickableStyle['-ms-transform'] = 'rotate(0deg)';
10105
+ wireClickableStyle['-o-transform'] = 'rotate(0deg)';
10106
+ wireClickableStyle['transform'] = 'rotate(0deg)';
10107
+ wireClickableStyle["opacity"] = 0.0;
10108
+ wireClickableStyle["pointer-events"] = "none";
10109
+ if (cfg.onContextMenu) ;
10110
+
10111
+ parentElement.appendChild(wireClickable);
10112
+
10113
+ if (cfg.onMouseOver) {
10114
+ wireClickable.addEventListener('mouseover', (event) => {
10115
+ cfg.onMouseOver(event, this);
10116
+ });
10117
+ }
10118
+
10119
+ if (cfg.onMouseLeave) {
10120
+ wireClickable.addEventListener('mouseleave', (event) => {
10121
+ cfg.onMouseLeave(event, this);
10122
+ });
10123
+ }
10124
+
10125
+ if (cfg.onMouseWheel) {
10126
+ wireClickable.addEventListener('wheel', (event) => {
10127
+ cfg.onMouseWheel(event, this);
10128
+ });
10129
+ }
10130
+
10131
+ if (cfg.onMouseDown) {
10132
+ wireClickable.addEventListener('mousedown', (event) => {
10133
+ cfg.onMouseDown(event, this);
10134
+ });
10135
+ }
10136
+
10137
+ if (cfg.onMouseUp) {
10138
+ wireClickable.addEventListener('mouseup', (event) => {
10139
+ cfg.onMouseUp(event, this);
10140
+ });
10141
+ }
10142
+
10143
+ if (cfg.onMouseMove) {
10144
+ wireClickable.addEventListener('mousemove', (event) => {
10145
+ cfg.onMouseMove(event, this);
10146
+ });
10147
+ }
10148
+
10149
+ if (cfg.onContextMenu) {
10150
+ const contextMenuCallback = (event) => {
10151
+ cfg.onContextMenu(event, this);
10152
+ };
10153
+ addContextMenuListener(wireClickable, contextMenuCallback);
10154
+
10155
+ }
10156
+
10157
+ this._x1 = 0;
10158
+ this._y1 = 0;
10159
+ this._x2 = 0;
10160
+ this._y2 = 0;
10161
+
10162
+ this._update();
10163
+ }
10164
+
10165
+ get visible() {
10166
+ return this._wire.style.visibility === "visible";
10167
+ }
10168
+
10169
+ _update() {
10170
+
10171
+ var length = Math.abs(Math.sqrt((this._x1 - this._x2) * (this._x1 - this._x2) + (this._y1 - this._y2) * (this._y1 - this._y2)));
10172
+ var angle = Math.atan2(this._y2 - this._y1, this._x2 - this._x1) * 180.0 / Math.PI;
10173
+
10174
+ var wireStyle = this._wire.style;
10175
+ wireStyle["width"] = Math.round(length) + 'px';
10176
+ wireStyle["left"] = Math.round(this._x1) + 'px';
10177
+ wireStyle["top"] = Math.round(this._y1) + 'px';
10178
+ wireStyle['-webkit-transform'] =
10179
+ wireStyle['-moz-transform'] =
10180
+ wireStyle['-ms-transform'] =
10181
+ wireStyle['-o-transform'] =
10182
+ wireStyle['transform'] = 'rotate(' + angle + 'deg) translate(-' + this._thickness + 'px, -' + this._thickness + 'px)';
10183
+
10184
+ var wireClickableStyle = this._wireClickable.style;
10185
+ wireClickableStyle["width"] = Math.round(length) + 'px';
10186
+ wireClickableStyle["left"] = Math.round(this._x1) + 'px';
10187
+ wireClickableStyle["top"] = Math.round(this._y1) + 'px';
10188
+ wireClickableStyle['-webkit-transform'] =
10189
+ wireClickableStyle['-moz-transform'] =
10190
+ wireClickableStyle['-ms-transform'] =
10191
+ wireClickableStyle['-o-transform'] =
10192
+ wireClickableStyle['transform'] = 'rotate(' + angle + 'deg) translate(-' + this._thicknessClickable + 'px, -' + this._thicknessClickable + 'px)';
10193
+ }
10194
+
10195
+ setStartAndEnd(x1, y1, x2, y2) {
10196
+ this._x1 = x1;
10197
+ this._y1 = y1;
10198
+ this._x2 = x2;
10199
+ this._y2 = y2;
10200
+ this._update();
10201
+ }
10202
+
10203
+ setColor(color) {
10204
+ this._color = color || "black";
10205
+ this._wire.style.border = "solid " + this._thickness + "px " + this._color;
10206
+ }
10207
+
10208
+ setOpacity(opacity) {
10209
+ this._wire.style.opacity = opacity;
10210
+ }
10211
+
10212
+ _updateVisibility() {
10213
+ this._wire.style.visibility = this._wireClickable.style.visibility = this._visible && !this._culled ? "visible" : "hidden";
10214
+ }
10215
+
10216
+ setVisible(visible) {
10217
+ if (this._visible === visible) {
10218
+ return;
10219
+ }
10220
+ this._visible = !!visible;
10221
+ this._updateVisibility();
10222
+ }
10223
+
10224
+ setCulled(culled) {
10225
+ if (this._culled === culled) {
10226
+ return;
10227
+ }
10228
+ this._culled = !!culled;
10229
+ this._updateVisibility();
10230
+ }
10231
+
10232
+ setClickable(clickable) {
10233
+ this._wireClickable.style["pointer-events"] = (clickable) ? "all" : "none";
10234
+ }
10235
+
10236
+ setHighlighted(highlighted) {
10237
+ if (this._highlighted === highlighted) {
10238
+ return;
10239
+ }
10240
+ this._highlighted = !!highlighted;
10241
+ if (this._highlighted) {
10242
+ this._wire.classList.add(this._highlightClass);
10243
+ } else {
10244
+ this._wire.classList.remove(this._highlightClass);
10245
+ }
10246
+ }
10247
+
10248
+ destroy(visible) {
10249
+ if (this._wire.parentElement) {
10250
+ this._wire.parentElement.removeChild(this._wire);
10251
+ }
10252
+ if (this._wireClickable.parentElement) {
10253
+ this._wireClickable.parentElement.removeChild(this._wireClickable);
10254
+ }
10255
+ }
10256
+ }
10257
+
9798
10258
  const tempVec3a$L = math.vec3();
9799
10259
  const tempVec4$1 = math.vec4();
9800
10260
 
@@ -9988,6 +10448,11 @@ class SceneModelEntity {
9988
10448
  */
9989
10449
  this.model = model;
9990
10450
 
10451
+ /**
10452
+ * Identifies if it's a SceneModelEntity
10453
+ */
10454
+ this.isSceneModelEntity = true;
10455
+
9991
10456
  /**
9992
10457
  * The {@link SceneModelMesh}es belonging to this SceneModelEntity.
9993
10458
  *
@@ -10899,28 +11364,13 @@ class Marker extends Component {
10899
11364
  * @type {Entity}
10900
11365
  */
10901
11366
  set entity(entity) {
10902
- if (this._entity) {
10903
- if (this._entity === entity) {
10904
- return;
10905
- }
10906
- if (this._onEntityDestroyed !== null) {
10907
- if (this._entity.model) {
10908
- this._entity.model.off(this._onEntityDestroyed);
10909
- } else {
10910
- this._entity.off(this._onEntityDestroyed);
10911
- }
10912
- this._onEntityDestroyed = null;
10913
- }
10914
- if (this._onEntityModelDestroyed !== null) {
10915
- if (this._entity.model) {
10916
- this._entity.model.off(this._onEntityModelDestroyed);
10917
- }
10918
- this._onEntityModelDestroyed = null;
10919
- }
11367
+ if (this._entity === entity) {
11368
+ return;
10920
11369
  }
11370
+ this._cleanupDestroyedHandlers();
10921
11371
  this._entity = entity;
10922
11372
  if (this._entity) {
10923
- if (this._entity instanceof SceneModelEntity) {
11373
+ if (this._entity.isSceneModelEntity) {
10924
11374
  this._onEntityModelDestroyed = this._entity.model.on("destroyed", () => { // SceneModelEntity does not fire events, and cannot exist beyond its VBOSceneModel
10925
11375
  this._entity = null; // Marker now may become visible, if it was synched to invisible Entity
10926
11376
  this._onEntityModelDestroyed = null;
@@ -11082,19 +11532,42 @@ class Marker extends Component {
11082
11532
  this.fire("destroyed", true);
11083
11533
  this.scene.camera.off(this._onCameraViewMatrix);
11084
11534
  this.scene.camera.off(this._onCameraProjMatrix);
11535
+ this._cleanupDestroyedHandlers();
11536
+ this._renderer.removeMarker(this);
11537
+ super.destroy();
11538
+ }
11539
+
11540
+ _cleanupDestroyedHandlers() {
11085
11541
  if (this._entity) {
11086
11542
  if (this._onEntityDestroyed !== null) {
11087
- this._entity.model.off(this._onEntityDestroyed);
11543
+ if (this._entity.model) {
11544
+ this._entity.model.off(this._onEntityDestroyed);
11545
+ } else {
11546
+ this._entity.off(this._onEntityDestroyed);
11547
+ }
11548
+ this._onEntityDestroyed = null;
11088
11549
  }
11089
11550
  if (this._onEntityModelDestroyed !== null) {
11090
- this._entity.model.off(this._onEntityModelDestroyed);
11551
+ if (this._entity.model) {
11552
+ this._entity.model.off(this._onEntityModelDestroyed);
11553
+ }
11554
+ this._onEntityModelDestroyed = null;
11091
11555
  }
11092
11556
  }
11093
- this._renderer.removeMarker(this);
11094
- super.destroy();
11095
11557
  }
11096
11558
  }
11097
11559
 
11560
+ const tmpVec2a = math.vec2();
11561
+ const tmpVec2b = math.vec2();
11562
+ const tmpVec2c = math.vec2();
11563
+ const tmpVec2d = math.vec2();
11564
+ const tmpVec3a$2 = math.vec3();
11565
+ const tmpVec3b$2 = math.vec3();
11566
+ const tmpVec4a = math.vec4();
11567
+ const tmpVec4b = math.vec4();
11568
+ const tmpVec4c = math.vec4();
11569
+ const tmpVec4d = math.vec4();
11570
+
11098
11571
  const nop = () => { };
11099
11572
 
11100
11573
  function transformToNode(from, to, vec) {
@@ -11103,10 +11576,124 @@ function transformToNode(from, to, vec) {
11103
11576
  vec[0] += fromRec.left - toRec.left;
11104
11577
  vec[1] += fromRec.top - toRec.top;
11105
11578
  }
11579
+ const toClipSpace = (camera, worldPos, p) => {
11580
+ // to homogeneous coords
11581
+ p.set(worldPos);
11582
+ p[3] = 1;
11583
+
11584
+ // to clip space
11585
+ math.mulMat4v4(camera.viewMatrix, p, p);
11586
+ math.mulMat4v4(camera.projMatrix, p, p);
11587
+ };
11588
+
11589
+ const toCanvasSpace = (canvas, parentElement, ndc, p) => {
11590
+ p[0] = (1 + ndc[0]) * 0.5 * canvas.offsetWidth;
11591
+ p[1] = (1 - ndc[1]) * 0.5 * canvas.offsetHeight;
11592
+ transformToNode(canvas, parentElement, p);
11593
+ };
11594
+
11595
+ const clipSegment = (scene, parentElement, start, end, canvasStart, canvasEnd) => {
11596
+ const camera = scene.camera;
11597
+ const canvas = scene.canvas.canvas;
11598
+
11599
+ if (math.distVec3(start, end) < 0.001) {
11600
+ return false;
11601
+ }
11602
+
11603
+ const delta = math.subVec3(end, start, tmpVec3a$2);
11604
+ let s_min = 0.0;
11605
+ let s_max = 1.0;
11606
+
11607
+ for (let plane of scene._sectionPlanesState.sectionPlanes) {
11608
+ const endDot = math.dotVec3(plane.dir, math.subVec3(plane.pos, end, tmpVec3b$2));
11609
+ const startDot = math.dotVec3(plane.dir, math.subVec3(plane.pos, start, tmpVec3b$2));
11610
+
11611
+ if ((startDot > 0) && (endDot > 0)) {
11612
+ return false;
11613
+ } else if ((startDot > 0) || (endDot > 0)) {
11614
+ const denom = math.dotVec3(plane.dir, delta);
11615
+ if (Math.abs(denom) >= 1e-6) {
11616
+ const ratio = math.dotVec3(plane.dir, tmpVec3b$2) / denom;
11617
+ if (startDot > 0) {
11618
+ s_min = Math.max(s_min, ratio);
11619
+ } else {
11620
+ s_max = Math.min(s_max, ratio);
11621
+ }
11622
+ }
11623
+ }
11624
+ }
11625
+
11626
+ const p0 = tmpVec4a;
11627
+ const p1 = tmpVec4b;
11628
+ toClipSpace(camera, (s_min > 0) ? math.addVec3(start, math.mulVec3Scalar(delta, s_min, tmpVec3b$2), tmpVec3b$2) : start, p0);
11629
+ toClipSpace(camera, (s_max < 1) ? math.addVec3(start, math.mulVec3Scalar(delta, s_max, tmpVec3b$2), tmpVec3b$2) : end, p1);
11630
+
11631
+ const p0Behind = ((p0[2] / p0[3]) < -1) || (p0[3] < 0);
11632
+ const p1Behind = ((p1[2] / p1[3]) < -1) || (p1[3] < 0);
11633
+ if (p0Behind && p1Behind) {
11634
+ return false;
11635
+ }
11636
+
11637
+ const t = (p0[3] + p0[2]) / ((p0[3] + p0[2]) - (p1[3] + p1[2]));
11638
+
11639
+ if ((t > 0) && (t < 1)) { //p0Behind || p1Behind) {
11640
+ // Find the intersection of a segment with the near plane in clip space, if it exists."""
11641
+ // Calculate the interpolation factor t where the line segment crosses the near plane
11642
+ const delta = math.subVec4(p1, p0, tmpVec4c);
11643
+ math.mulVec4Scalar(delta, t, delta);
11644
+ math.addVec4(p0, delta, p0Behind ? p0 : p1);
11645
+ }
11646
+
11647
+ // normalize clip space coords
11648
+ math.mulVec4Scalar(p0, 1.0 / p0[3]);
11649
+ math.mulVec4Scalar(p1, 1.0 / p1[3]);
11650
+
11651
+ let t_min = 0.0;
11652
+ let t_max = 1.0;
11653
+
11654
+ // If either point is outside the view frustum, clip the line segment
11655
+
11656
+ for (let i = 0; i < 2; ++i) {
11657
+ const denom = p1[i] - p0[i];
11658
+
11659
+ const l = (-p0[3] - p0[i]) / denom;
11660
+ const r = ( p0[3] - p0[i]) / denom;
11661
+
11662
+ if (denom > 0) {
11663
+ t_min = Math.max(t_min, l);
11664
+ t_max = Math.min(t_max, r);
11665
+ } else {
11666
+ t_min = Math.max(t_min, r);
11667
+ t_max = Math.min(t_max, l);
11668
+ }
11669
+ }
11670
+
11671
+ if (t_min >= t_max) {
11672
+ return false;
11673
+ }
11674
+
11675
+ // Calculate the clipped start and end points
11676
+ const ndcDelta = math.subVec4(p1, p0, tmpVec4c);
11677
+ math.addVec4(p0, math.mulVec4Scalar(ndcDelta, t_max, tmpVec4d), p1);
11678
+ math.addVec4(p0, math.mulVec4Scalar(ndcDelta, t_min, tmpVec4d), p0);
11679
+
11680
+ math.mulVec4Scalar(p0, 1 / p0[3]);
11681
+ math.mulVec4Scalar(p1, 1 / p1[3]);
11682
+
11683
+ toCanvasSpace(canvas, parentElement, p0, canvasStart);
11684
+ toCanvasSpace(canvas, parentElement, p1, canvasEnd);
11685
+
11686
+ return true;
11687
+ };
11688
+
11106
11689
  class Dot3D extends Marker {
11107
11690
  constructor(scene, markerCfg, parentElement, cfg = {}) {
11691
+ const camera = scene.camera;
11692
+
11108
11693
  super(scene, markerCfg);
11109
11694
 
11695
+ this.__visible = true; // "__" to not interfere with Marker::_visible
11696
+
11110
11697
  const handler = (cfgEvent, componentEvent) => {
11111
11698
  return event => {
11112
11699
  if (cfgEvent) {
@@ -11116,6 +11703,7 @@ class Dot3D extends Marker {
11116
11703
  };
11117
11704
  };
11118
11705
  this._dot = new Dot(parentElement, {
11706
+ borderColor: cfg.borderColor,
11119
11707
  fillColor: cfg.fillColor,
11120
11708
  zIndex: cfg.zIndex,
11121
11709
  onMouseOver: handler(cfg.onMouseOver, "mouseover"),
@@ -11130,19 +11718,62 @@ class Dot3D extends Marker {
11130
11718
  onContextMenu: handler(cfg.onContextMenu, "contextmenu")
11131
11719
  });
11132
11720
 
11721
+ const toClipSpace = (worldPos, p) => {
11722
+ // to homogeneous coords
11723
+ p.set(worldPos);
11724
+ p[3] = 1;
11725
+
11726
+ // to clip space
11727
+ math.mulMat4v4(camera.viewMatrix, p, p);
11728
+ math.mulMat4v4(camera.projMatrix, p, p);
11729
+ };
11730
+
11731
+ const toCanvasSpace = ndc => {
11732
+ const canvas = scene.canvas.canvas;
11733
+ ndc[0] = (1 + ndc[0]) * 0.5 * canvas.offsetWidth;
11734
+ ndc[1] = (1 - ndc[1]) * 0.5 * canvas.offsetHeight;
11735
+ transformToNode(canvas, parentElement, ndc);
11736
+ };
11737
+
11133
11738
  const updateDotPos = () => {
11134
- const pos = this.canvasPos.slice();
11135
- transformToNode(scene.canvas.canvas, parentElement, pos);
11136
- this._dot.setPos(pos[0], pos[1]);
11739
+ if (! this.__visible) {
11740
+ return;
11741
+ }
11742
+ const p0 = tmpVec4c;
11743
+ toClipSpace(this.worldPos, p0);
11744
+ math.mulVec3Scalar(p0, 1.0 / p0[3]);
11745
+
11746
+ const outsideFrustum = ((p0[3] < 0)
11747
+ ||
11748
+ (p0[0] < -1) || (p0[0] > 1)
11749
+ ||
11750
+ (p0[1] < -1) || (p0[1] > 1)
11751
+ ||
11752
+ (p0[2] < -1) || (p0[2] > 1));
11753
+ const culled = outsideFrustum || scene._sectionPlanesState.sectionPlanes.some(
11754
+ plane => (math.dotVec3(plane.dir, math.subVec3(plane.pos, this.worldPos, tmpVec3a$2)) > 0));
11755
+
11756
+ this._dot.setCulled(culled);
11757
+ if (!culled) {
11758
+ toCanvasSpace(p0);
11759
+ this._dot.setPos(p0[0], p0[1]);
11760
+ }
11137
11761
  };
11138
11762
 
11139
11763
  this.on("worldPos", updateDotPos);
11140
11764
 
11141
- const onViewMatrix = scene.camera.on("viewMatrix", updateDotPos);
11142
- const onProjMatrix = scene.camera.on("projMatrix", updateDotPos);
11765
+ const onViewMatrix = camera.on("viewMatrix", updateDotPos);
11766
+ const onProjMatrix = camera.on("projMatrix", updateDotPos);
11767
+ const onCanvasBnd = scene.canvas.on("boundary", updateDotPos);
11768
+ const planesUpdate = scene.on("sectionPlaneUpdated", updateDotPos);
11769
+
11770
+ this._updatePosition = updateDotPos;
11771
+
11143
11772
  this._cleanup = () => {
11144
- scene.camera.off(onViewMatrix);
11145
- scene.camera.off(onProjMatrix);
11773
+ camera.off(onViewMatrix);
11774
+ camera.off(onProjMatrix);
11775
+ scene.canvas.off(onCanvasBnd);
11776
+ scene.off(planesUpdate);
11146
11777
  this._dot.destroy();
11147
11778
  };
11148
11779
  }
@@ -11151,14 +11782,14 @@ class Dot3D extends Marker {
11151
11782
  this._dot.setClickable(value);
11152
11783
  }
11153
11784
 
11154
- setCulled(value) {
11155
- this._dot.setCulled(value);
11156
- }
11157
-
11158
11785
  setFillColor(value) {
11159
11786
  this._dot.setFillColor(value);
11160
11787
  }
11161
11788
 
11789
+ setBorderColor(value) {
11790
+ this._dot.setBorderColor(value);
11791
+ }
11792
+
11162
11793
  setHighlighted(value) {
11163
11794
  this._dot.setHighlighted(value);
11164
11795
  }
@@ -11168,7 +11799,11 @@ class Dot3D extends Marker {
11168
11799
  }
11169
11800
 
11170
11801
  setVisible(value) {
11171
- this._dot.setVisible(value);
11802
+ if (this.__visible != value) {
11803
+ this.__visible = value;
11804
+ this._updatePosition();
11805
+ this._dot.setVisible(value);
11806
+ }
11172
11807
  }
11173
11808
 
11174
11809
  destroy() {
@@ -11178,6 +11813,189 @@ class Dot3D extends Marker {
11178
11813
 
11179
11814
  }
11180
11815
 
11816
+ class Label3D {
11817
+ constructor(scene, parentElement, cfg) {
11818
+ const camera = scene.camera;
11819
+
11820
+ this._label = new Label(parentElement, cfg);
11821
+ this._start = math.vec3();
11822
+ this._mid = math.vec3();
11823
+ this._end = math.vec3();
11824
+ this._yOff = 0;
11825
+ this._betweenWires = false;
11826
+ this.__visible = true;
11827
+
11828
+ const setPosOnWire = (p0, p1, yOff) => {
11829
+ p0[0] += p1[0];
11830
+ p0[1] += p1[1];
11831
+ math.mulVec2Scalar(p0, .5);
11832
+ this._label.setPos(p0[0], p0[1] + yOff);
11833
+ };
11834
+
11835
+ this._updatePositions = () => {
11836
+ if (! this.__visible) {
11837
+ return;
11838
+ }
11839
+ if (this._betweenWires) {
11840
+ const visibleA = clipSegment(scene, parentElement, this._start, this._mid, tmpVec2a, tmpVec2b);
11841
+ const visibleB = clipSegment(scene, parentElement, this._end, this._mid, tmpVec2c, tmpVec2d);
11842
+ this._label.setCulled(! (visibleA || visibleB));
11843
+ if (visibleA && visibleB) {
11844
+ tmpVec2b[0] += tmpVec2d[0];
11845
+ tmpVec2b[1] += tmpVec2d[1];
11846
+ math.mulVec2Scalar(tmpVec2b, .5);
11847
+
11848
+ tmpVec2b[0] += tmpVec2a[0] + tmpVec2c[0];
11849
+ tmpVec2b[1] += tmpVec2a[1] + tmpVec2c[1];
11850
+ math.mulVec2Scalar(tmpVec2b, 1/3);
11851
+ this._label.setPos(tmpVec2b[0], tmpVec2b[1]);
11852
+ } else if (visibleA) {
11853
+ setPosOnWire(tmpVec2a, tmpVec2b, 0);
11854
+ } else if (visibleB) {
11855
+ setPosOnWire(tmpVec2c, tmpVec2d, 0);
11856
+ }
11857
+ } else {
11858
+ const visible = (clipSegment(scene, parentElement, this._start, this._end, tmpVec2a, tmpVec2b)
11859
+ &&
11860
+ (math.distVec2(tmpVec2a, tmpVec2b) >= this._labelMinAxisLength));
11861
+ this._label.setCulled(!visible);
11862
+ if (visible) {
11863
+ setPosOnWire(tmpVec2a, tmpVec2b, this._yOff);
11864
+ }
11865
+ }
11866
+ };
11867
+
11868
+ const onViewMatrix = camera.on("viewMatrix", this._updatePositions);
11869
+ const onProjMatrix = camera.on("projMatrix", this._updatePositions);
11870
+ const onCanvasBnd = scene.canvas.on("boundary", this._updatePositions);
11871
+ const planesUpdate = scene.on("sectionPlaneUpdated", this._updatePositions);
11872
+
11873
+ this._cleanup = () => {
11874
+ camera.off(onViewMatrix);
11875
+ camera.off(onProjMatrix);
11876
+ scene.canvas.off(onCanvasBnd);
11877
+ scene.off(planesUpdate);
11878
+ this._label.destroy();
11879
+ };
11880
+ }
11881
+
11882
+ setPosOnWire(p0, p1, yOff, labelMinAxisLength) {
11883
+ this._start.set(p0);
11884
+ this._end.set(p1);
11885
+ this._yOff = yOff;
11886
+ this._labelMinAxisLength = labelMinAxisLength;
11887
+ this._betweenWires = false;
11888
+ this._updatePositions();
11889
+ }
11890
+
11891
+ setPosBetween(p0, p1, p2) {
11892
+ this._start.set(p0);
11893
+ this._mid.set(p1);
11894
+ this._end.set(p2);
11895
+ this._betweenWires = true;
11896
+ this._updatePositions();
11897
+ }
11898
+
11899
+ setFillColor(value) {
11900
+ this._label.setFillColor(value);
11901
+ }
11902
+
11903
+ setHighlighted(value) {
11904
+ this._label.setHighlighted(value);
11905
+ }
11906
+
11907
+ setText(value) {
11908
+ this._label.setText(value);
11909
+ }
11910
+
11911
+ setClickable(value) {
11912
+ this._label.setClickable(value);
11913
+ }
11914
+
11915
+ setVisible(value) {
11916
+ if (this.__visible != value) {
11917
+ this.__visible = value;
11918
+ this._updatePositions();
11919
+ this._label.setVisible(value);
11920
+ }
11921
+ }
11922
+
11923
+ destroy() {
11924
+ this._cleanup();
11925
+ }
11926
+
11927
+ }
11928
+
11929
+ class Wire3D {
11930
+ constructor(scene, parentElement, cfg) {
11931
+ const camera = scene.camera;
11932
+
11933
+ this._wire = new Wire(parentElement, cfg);
11934
+ this._start = math.vec3();
11935
+ this._end = math.vec3();
11936
+ this.__visible = true;
11937
+
11938
+ this._updatePositions = () => {
11939
+ if (! this.__visible) {
11940
+ return;
11941
+ }
11942
+ const visible = clipSegment(scene, parentElement, this._start, this._end, tmpVec2a, tmpVec2b);
11943
+ this._wire.setCulled(! visible);
11944
+ if (visible) {
11945
+ this._wire.setStartAndEnd(tmpVec2a[0], tmpVec2a[1], tmpVec2b[0], tmpVec2b[1]);
11946
+ }
11947
+ };
11948
+
11949
+ const onViewMatrix = camera.on("viewMatrix", this._updatePositions);
11950
+ const onProjMatrix = camera.on("projMatrix", this._updatePositions);
11951
+ const onCanvasBnd = scene.canvas.on("boundary", this._updatePositions);
11952
+ const planesUpdate = scene.on("sectionPlaneUpdated", this._updatePositions);
11953
+
11954
+ this._cleanup = () => {
11955
+ camera.off(onViewMatrix);
11956
+ camera.off(onProjMatrix);
11957
+ scene.canvas.off(onCanvasBnd);
11958
+ scene.off(planesUpdate);
11959
+ this._wire.destroy();
11960
+ };
11961
+ }
11962
+
11963
+ setEnds(start, end) {
11964
+ this._start.set(start);
11965
+ this._end.set(end);
11966
+ this._updatePositions();
11967
+ }
11968
+
11969
+ setClickable(value) {
11970
+ this._wire.setClickable(value);
11971
+ }
11972
+
11973
+ setColor(value) {
11974
+ this._wire.setColor(value);
11975
+ }
11976
+
11977
+ setHighlighted(value) {
11978
+ this._wire.setHighlighted(value);
11979
+ }
11980
+
11981
+ setOpacity(value) {
11982
+ this._wire.setOpacity(value);
11983
+ }
11984
+
11985
+ setVisible(value) {
11986
+ if (this.__visible != value) {
11987
+ this.__visible = value;
11988
+ this._updatePositions();
11989
+ this._wire.setVisible(value);
11990
+ }
11991
+ }
11992
+
11993
+ destroy() {
11994
+ this._cleanup();
11995
+ }
11996
+
11997
+ }
11998
+
11181
11999
  function activateDraggableDot(dot, cfg) {
11182
12000
  const extractCFG = function(propName, defaultValue) {
11183
12001
  if (propName in cfg) {
@@ -11492,469 +12310,8 @@ const touchPointSelector = function(viewer, pointerCircle, ray2WorldPos) {
11492
12310
  };
11493
12311
  };
11494
12312
 
11495
- /** @private */
11496
- class Wire {
11497
-
11498
- constructor(parentElement, cfg = {}) {
11499
-
11500
- this._color = cfg.color || "black";
11501
- this._highlightClass = "viewer-ruler-wire-highlighted";
11502
-
11503
- this._wire = document.createElement('div');
11504
- this._wire.className += this._wire.className ? ' viewer-ruler-wire' : 'viewer-ruler-wire';
11505
-
11506
- this._wireClickable = document.createElement('div');
11507
- this._wireClickable.className += this._wireClickable.className ? ' viewer-ruler-wire-clickable' : 'viewer-ruler-wire-clickable';
11508
-
11509
- this._thickness = cfg.thickness || 1.0;
11510
- this._thicknessClickable = cfg.thicknessClickable || 6.0;
11511
-
11512
- this._visible = true;
11513
- this._culled = false;
11514
-
11515
- var wire = this._wire;
11516
- var wireStyle = wire.style;
11517
-
11518
- wireStyle.border = "solid " + this._thickness + "px " + this._color;
11519
- wireStyle.position = "absolute";
11520
- wireStyle["z-index"] = cfg.zIndex === undefined ? "2000001" : cfg.zIndex;
11521
- wireStyle.width = 0 + "px";
11522
- wireStyle.height = 0 + "px";
11523
- wireStyle.visibility = "visible";
11524
- wireStyle.top = 0 + "px";
11525
- wireStyle.left = 0 + "px";
11526
- wireStyle['-webkit-transform-origin'] = "0 0";
11527
- wireStyle['-moz-transform-origin'] = "0 0";
11528
- wireStyle['-ms-transform-origin'] = "0 0";
11529
- wireStyle['-o-transform-origin'] = "0 0";
11530
- wireStyle['transform-origin'] = "0 0";
11531
- wireStyle['-webkit-transform'] = 'rotate(0deg)';
11532
- wireStyle['-moz-transform'] = 'rotate(0deg)';
11533
- wireStyle['-ms-transform'] = 'rotate(0deg)';
11534
- wireStyle['-o-transform'] = 'rotate(0deg)';
11535
- wireStyle['transform'] = 'rotate(0deg)';
11536
- wireStyle["opacity"] = 1.0;
11537
- wireStyle["pointer-events"] = "none";
11538
- if (cfg.onContextMenu) ;
11539
-
11540
- parentElement.appendChild(wire);
11541
-
11542
- var wireClickable = this._wireClickable;
11543
- var wireClickableStyle = wireClickable.style;
11544
-
11545
- wireClickableStyle.border = "solid " + this._thicknessClickable + "px " + this._color;
11546
- wireClickableStyle.position = "absolute";
11547
- wireClickableStyle["z-index"] = cfg.zIndex === undefined ? "2000002" : (cfg.zIndex + 1);
11548
- wireClickableStyle.width = 0 + "px";
11549
- wireClickableStyle.height = 0 + "px";
11550
- wireClickableStyle.visibility = "visible";
11551
- wireClickableStyle.top = 0 + "px";
11552
- wireClickableStyle.left = 0 + "px";
11553
- // wireClickableStyle["pointer-events"] = "none";
11554
- wireClickableStyle['-webkit-transform-origin'] = "0 0";
11555
- wireClickableStyle['-moz-transform-origin'] = "0 0";
11556
- wireClickableStyle['-ms-transform-origin'] = "0 0";
11557
- wireClickableStyle['-o-transform-origin'] = "0 0";
11558
- wireClickableStyle['transform-origin'] = "0 0";
11559
- wireClickableStyle['-webkit-transform'] = 'rotate(0deg)';
11560
- wireClickableStyle['-moz-transform'] = 'rotate(0deg)';
11561
- wireClickableStyle['-ms-transform'] = 'rotate(0deg)';
11562
- wireClickableStyle['-o-transform'] = 'rotate(0deg)';
11563
- wireClickableStyle['transform'] = 'rotate(0deg)';
11564
- wireClickableStyle["opacity"] = 0.0;
11565
- wireClickableStyle["pointer-events"] = "none";
11566
- if (cfg.onContextMenu) ;
11567
-
11568
- parentElement.appendChild(wireClickable);
11569
-
11570
- if (cfg.onMouseOver) {
11571
- wireClickable.addEventListener('mouseover', (event) => {
11572
- cfg.onMouseOver(event, this);
11573
- });
11574
- }
11575
-
11576
- if (cfg.onMouseLeave) {
11577
- wireClickable.addEventListener('mouseleave', (event) => {
11578
- cfg.onMouseLeave(event, this);
11579
- });
11580
- }
11581
-
11582
- if (cfg.onMouseWheel) {
11583
- wireClickable.addEventListener('wheel', (event) => {
11584
- cfg.onMouseWheel(event, this);
11585
- });
11586
- }
11587
-
11588
- if (cfg.onMouseDown) {
11589
- wireClickable.addEventListener('mousedown', (event) => {
11590
- cfg.onMouseDown(event, this);
11591
- });
11592
- }
11593
-
11594
- if (cfg.onMouseUp) {
11595
- wireClickable.addEventListener('mouseup', (event) => {
11596
- cfg.onMouseUp(event, this);
11597
- });
11598
- }
11599
-
11600
- if (cfg.onMouseMove) {
11601
- wireClickable.addEventListener('mousemove', (event) => {
11602
- cfg.onMouseMove(event, this);
11603
- });
11604
- }
11605
-
11606
- if (cfg.onContextMenu) {
11607
- if(os.isIphoneSafari()){
11608
- wireClickable.addEventListener('touchstart', (event) => {
11609
- event.preventDefault();
11610
- if(this._timeout){
11611
- clearTimeout(this._timeout);
11612
- this._timeout = null;
11613
- }
11614
- this._timeout = setTimeout(() => {
11615
- event.clientX = event.touches[0].clientX;
11616
- event.clientY = event.touches[0].clientY;
11617
- cfg.onContextMenu(event, this);
11618
- clearTimeout(this._timeout);
11619
- this._timeout = null;
11620
- }, 500);
11621
- });
11622
-
11623
- wireClickable.addEventListener('touchend', (event) => {
11624
- event.preventDefault();
11625
- //stops short touches from calling the timeout
11626
- if(this._timeout) {
11627
- clearTimeout(this._timeout);
11628
- this._timeout = null;
11629
- }
11630
- } );
11631
-
11632
- }
11633
- else {
11634
- wireClickable.addEventListener('contextmenu', (event) => {
11635
- console.log(event);
11636
- cfg.onContextMenu(event, this);
11637
- event.preventDefault();
11638
- event.stopPropagation();
11639
- console.log("Label context menu");
11640
- });
11641
- }
11642
-
11643
- }
11644
-
11645
- this._x1 = 0;
11646
- this._y1 = 0;
11647
- this._x2 = 0;
11648
- this._y2 = 0;
11649
-
11650
- this._update();
11651
- }
11652
-
11653
- get visible() {
11654
- return this._wire.style.visibility === "visible";
11655
- }
11656
-
11657
- _update() {
11658
-
11659
- var length = Math.abs(Math.sqrt((this._x1 - this._x2) * (this._x1 - this._x2) + (this._y1 - this._y2) * (this._y1 - this._y2)));
11660
- var angle = Math.atan2(this._y2 - this._y1, this._x2 - this._x1) * 180.0 / Math.PI;
11661
-
11662
- var wireStyle = this._wire.style;
11663
- wireStyle["width"] = Math.round(length) + 'px';
11664
- wireStyle["left"] = Math.round(this._x1) + 'px';
11665
- wireStyle["top"] = Math.round(this._y1) + 'px';
11666
- wireStyle['-webkit-transform'] = 'rotate(' + angle + 'deg)';
11667
- wireStyle['-moz-transform'] = 'rotate(' + angle + 'deg)';
11668
- wireStyle['-ms-transform'] = 'rotate(' + angle + 'deg)';
11669
- wireStyle['-o-transform'] = 'rotate(' + angle + 'deg)';
11670
- wireStyle['transform'] = 'rotate(' + angle + 'deg)';
11671
-
11672
- var wireClickableStyle = this._wireClickable.style;
11673
- wireClickableStyle["width"] = Math.round(length) + 'px';
11674
- wireClickableStyle["left"] = Math.round(this._x1) + 'px';
11675
- wireClickableStyle["top"] = Math.round(this._y1) + 'px';
11676
- wireClickableStyle['-webkit-transform'] = 'rotate(' + angle + 'deg)';
11677
- wireClickableStyle['-moz-transform'] = 'rotate(' + angle + 'deg)';
11678
- wireClickableStyle['-ms-transform'] = 'rotate(' + angle + 'deg)';
11679
- wireClickableStyle['-o-transform'] = 'rotate(' + angle + 'deg)';
11680
- wireClickableStyle['transform'] = 'rotate(' + angle + 'deg)';
11681
- }
11682
-
11683
- setStartAndEnd(x1, y1, x2, y2) {
11684
- this._x1 = x1;
11685
- this._y1 = y1;
11686
- this._x2 = x2;
11687
- this._y2 = y2;
11688
- this._update();
11689
- }
11690
-
11691
- setColor(color) {
11692
- this._color = color || "black";
11693
- this._wire.style.border = "solid " + this._thickness + "px " + this._color;
11694
- }
11695
-
11696
- setOpacity(opacity) {
11697
- this._wire.style.opacity = opacity;
11698
- }
11699
-
11700
- setVisible(visible) {
11701
- if (this._visible === visible) {
11702
- return;
11703
- }
11704
- this._visible = !!visible;
11705
- this._wire.style.visibility = this._visible && !this._culled ? "visible" : "hidden";
11706
- }
11707
-
11708
- setCulled(culled) {
11709
- if (this._culled === culled) {
11710
- return;
11711
- }
11712
- this._culled = !!culled;
11713
- this._wire.style.visibility = this._visible && !this._culled ? "visible" : "hidden";
11714
- }
11715
-
11716
- setClickable(clickable) {
11717
- this._wireClickable.style["pointer-events"] = (clickable) ? "all" : "none";
11718
- }
11719
-
11720
- setHighlighted(highlighted) {
11721
- if (this._highlighted === highlighted) {
11722
- return;
11723
- }
11724
- this._highlighted = !!highlighted;
11725
- if (this._highlighted) {
11726
- this._wire.classList.add(this._highlightClass);
11727
- } else {
11728
- this._wire.classList.remove(this._highlightClass);
11729
- }
11730
- }
11731
-
11732
- destroy(visible) {
11733
- if (this._wire.parentElement) {
11734
- this._wire.parentElement.removeChild(this._wire);
11735
- }
11736
- if (this._wireClickable.parentElement) {
11737
- this._wireClickable.parentElement.removeChild(this._wireClickable);
11738
- }
11739
- }
11740
- }
11741
-
11742
- /** @private */
11743
- class Label {
11744
-
11745
- constructor(parentElement, cfg = {}) {
11746
-
11747
- this._highlightClass = "viewer-ruler-label-highlighted";
11748
-
11749
- this._prefix = cfg.prefix || "";
11750
- this._x = 0;
11751
- this._y = 0;
11752
- this._visible = true;
11753
- this._culled = false;
11754
-
11755
- this._label = document.createElement('div');
11756
- this._label.className += this._label.className ? ' viewer-ruler-label' : 'viewer-ruler-label';
11757
- this._timeout = null;
11758
-
11759
- var label = this._label;
11760
- var style = label.style;
11761
-
11762
- style["border-radius"] = 5 + "px";
11763
- style.color = "white";
11764
- style.padding = "4px";
11765
- style.border = "solid 1px";
11766
- style.background = "lightgreen";
11767
- style.position = "absolute";
11768
- style["z-index"] = cfg.zIndex === undefined ? "5000005" : cfg.zIndex;
11769
- style.width = "auto";
11770
- style.height = "auto";
11771
- style.visibility = "visible";
11772
- style.top = 0 + "px";
11773
- style.left = 0 + "px";
11774
- style["pointer-events"] = "all";
11775
- style["opacity"] = 1.0;
11776
- if (cfg.onContextMenu) ;
11777
- label.innerText = "";
11778
-
11779
- parentElement.appendChild(label);
11780
-
11781
- this.setPos(cfg.x || 0, cfg.y || 0);
11782
- this.setFillColor(cfg.fillColor);
11783
- this.setBorderColor(cfg.fillColor);
11784
- this.setText(cfg.text);
11785
-
11786
- if (cfg.onMouseOver) {
11787
- label.addEventListener('mouseover', (event) => {
11788
- cfg.onMouseOver(event, this);
11789
- event.preventDefault();
11790
- });
11791
- }
11792
-
11793
- if (cfg.onMouseLeave) {
11794
- label.addEventListener('mouseleave', (event) => {
11795
- cfg.onMouseLeave(event, this);
11796
- event.preventDefault();
11797
- });
11798
- }
11799
-
11800
- if (cfg.onMouseWheel) {
11801
- label.addEventListener('wheel', (event) => {
11802
- cfg.onMouseWheel(event, this);
11803
- });
11804
- }
11805
-
11806
- if (cfg.onMouseDown) {
11807
- label.addEventListener('mousedown', (event) => {
11808
- cfg.onMouseDown(event, this);
11809
- event.stopPropagation();
11810
- });
11811
- }
11812
-
11813
- if (cfg.onMouseUp) {
11814
- label.addEventListener('mouseup', (event) => {
11815
- cfg.onMouseUp(event, this);
11816
- event.stopPropagation();
11817
- });
11818
- }
11819
-
11820
- if (cfg.onMouseMove) {
11821
- label.addEventListener('mousemove', (event) => {
11822
- cfg.onMouseMove(event, this);
11823
- });
11824
- }
11825
-
11826
- if (cfg.onContextMenu) {
11827
- if(os.isIphoneSafari()){
11828
- label.addEventListener('touchstart', (event) => {
11829
- event.preventDefault();
11830
- if(this._timeout){
11831
- clearTimeout(this._timeout);
11832
- this._timeout = null;
11833
- }
11834
- this._timeout = setTimeout(() => {
11835
- event.clientX = event.touches[0].clientX;
11836
- event.clientY = event.touches[0].clientY;
11837
- cfg.onContextMenu(event, this);
11838
- clearTimeout(this._timeout);
11839
- this._timeout = null;
11840
- }, 500);
11841
- });
11842
-
11843
- label.addEventListener('touchend', (event) => {
11844
- event.preventDefault();
11845
- //stops short touches from calling the timeout
11846
- if(this._timeout) {
11847
- clearTimeout(this._timeout);
11848
- this._timeout = null;
11849
- }
11850
- } );
11851
-
11852
- }
11853
- else {
11854
- label.addEventListener('contextmenu', (event) => {
11855
- console.log(event);
11856
- cfg.onContextMenu(event, this);
11857
- event.preventDefault();
11858
- event.stopPropagation();
11859
- console.log("Label context menu");
11860
- });
11861
- }
11862
-
11863
- }
11864
- }
11865
-
11866
- setPos(x, y) {
11867
- this._x = x;
11868
- this._y = y;
11869
- var style = this._label.style;
11870
- style["left"] = (Math.round(x) - 20) + 'px';
11871
- style["top"] = (Math.round(y) - 12) + 'px';
11872
- }
11873
-
11874
- setPosOnWire(x1, y1, x2, y2) {
11875
- var x = x1 + ((x2 - x1) * 0.5);
11876
- var y = y1 + ((y2 - y1) * 0.5);
11877
- var style = this._label.style;
11878
- style["left"] = (Math.round(x) - 20) + 'px';
11879
- style["top"] = (Math.round(y) - 12) + 'px';
11880
- }
11881
-
11882
- setPosBetweenWires(x1, y1, x2, y2, x3, y3) {
11883
- var x = (x1 + x2 + x3) / 3;
11884
- var y = (y1 + y2 + y3) / 3;
11885
- var style = this._label.style;
11886
- style["left"] = (Math.round(x) - 20) + 'px';
11887
- style["top"] = (Math.round(y) - 12) + 'px';
11888
- }
11889
-
11890
- setText(text) {
11891
- this._label.innerHTML = this._prefix + (text || "");
11892
- }
11893
-
11894
- setFillColor(color) {
11895
- this._fillColor = color || "lightgreen";
11896
- this._label.style.background =this._fillColor;
11897
- }
11898
-
11899
- setBorderColor(color) {
11900
- this._borderColor = color || "black";
11901
- this._label.style.border = "solid 1px " + this._borderColor;
11902
- }
11903
-
11904
- setOpacity(opacity) {
11905
- this._label.style.opacity = opacity;
11906
- }
11907
-
11908
- setVisible(visible) {
11909
- if (this._visible === visible) {
11910
- return;
11911
- }
11912
- this._visible = !!visible;
11913
- this._label.style.visibility = this._visible && !this._culled ? "visible" : "hidden";
11914
- }
11915
-
11916
- setCulled(culled) {
11917
- if (this._culled === culled) {
11918
- return;
11919
- }
11920
- this._culled = !!culled;
11921
- this._label.style.visibility = this._visible && !this._culled ? "visible" : "hidden";
11922
- }
11923
-
11924
- setHighlighted(highlighted) {
11925
- if (this._highlighted === highlighted) {
11926
- return;
11927
- }
11928
- this._highlighted = !!highlighted;
11929
- if (this._highlighted) {
11930
- this._label.classList.add(this._highlightClass);
11931
- } else {
11932
- this._label.classList.remove(this._highlightClass);
11933
- }
11934
- }
11935
-
11936
- setClickable(clickable) {
11937
- this._label.style["pointer-events"] = (clickable) ? "all" : "none";
11938
- }
11939
-
11940
- setPrefix(prefix) {
11941
- if(this._prefix === prefix){
11942
- return;
11943
- }
11944
- this._prefix = prefix;
11945
- }
11946
-
11947
- destroy() {
11948
- if (this._label.parentElement) {
11949
- this._label.parentElement.removeChild(this._label);
11950
- }
11951
- }
11952
-
11953
-
11954
- }
11955
-
11956
- var originVec = math.vec3();
11957
- var targetVec = math.vec3();
12313
+ const tmpVec3a$1 = math.vec3();
12314
+ const tmpVec3b$1 = math.vec3();
11958
12315
 
11959
12316
  /**
11960
12317
  * @desc Measures the angle indicated by three 3D points.
@@ -11968,7 +12325,9 @@ class AngleMeasurement extends Component {
11968
12325
  */
11969
12326
  constructor(plugin, cfg = {}) {
11970
12327
 
11971
- super(plugin.viewer.scene, cfg);
12328
+ const scene = plugin.viewer.scene;
12329
+
12330
+ super(scene, cfg);
11972
12331
 
11973
12332
  /**
11974
12333
  * The {@link AngleMeasurementsPlugin} that owns this AngleMeasurement.
@@ -11976,349 +12335,165 @@ class AngleMeasurement extends Component {
11976
12335
  */
11977
12336
  this.plugin = plugin;
11978
12337
 
11979
- this._container = cfg.container;
11980
- if (!this._container) {
12338
+ const container = cfg.container;
12339
+ if (!container) {
11981
12340
  throw "config missing: container";
11982
12341
  }
11983
12342
 
11984
12343
  this._color = cfg.color || plugin.defaultColor;
11985
12344
 
11986
- var scene = this.plugin.viewer.scene;
12345
+ const channel = function(v) {
12346
+ const listeners = [ ];
12347
+ let value = v !== false;
12348
+ return {
12349
+ reg: (l) => listeners.push(l),
12350
+ get: () => value,
12351
+ set: (v) => {
12352
+ value = v !== false;
12353
+ listeners.forEach(l => l(value));
12354
+ }
12355
+ };
12356
+ };
11987
12357
 
11988
- this._originWorld = math.vec3();
11989
- this._cornerWorld = math.vec3();
11990
- this._targetWorld = math.vec3();
12358
+ this._visible = channel(cfg.visible);
12359
+ this._originVisible = channel(cfg.originVisible);
12360
+ this._cornerVisible = channel(cfg.cornerVisible);
12361
+ this._targetVisible = channel(cfg.targetVisible);
12362
+ this._originWireVisible = channel(cfg.originWireVisible);
12363
+ this._targetWireVisible = channel(cfg.targetWireVisible);
12364
+ this._angleVisible = channel(cfg.angleVisible);
12365
+ this._labelsVisible = channel();
12366
+ this.labelsVisible = cfg.labelsVisible;
12367
+ this._clickable = channel(false);
11991
12368
 
11992
- this._wp = new Float64Array(12);
11993
- this._vp = new Float64Array(12);
11994
- this._pp = new Float64Array(12);
11995
- this._cp = new Int16Array(6);
12369
+ this.approximate = cfg.approximate;
12370
+
12371
+
12372
+ const canvas = scene.canvas.canvas;
11996
12373
 
11997
12374
  const onMouseOver = cfg.onMouseOver ? (event) => {
11998
12375
  cfg.onMouseOver(event, this);
11999
- this.plugin.viewer.scene.canvas.canvas.dispatchEvent(new MouseEvent('mouseover', event));
12376
+ canvas.dispatchEvent(new MouseEvent('mouseover', event));
12000
12377
  } : null;
12001
12378
 
12002
12379
  const onMouseLeave = cfg.onMouseLeave ? (event) => {
12003
12380
  cfg.onMouseLeave(event, this);
12004
- this.plugin.viewer.scene.canvas.canvas.dispatchEvent(new MouseEvent('mouseleave', event));
12381
+ canvas.dispatchEvent(new MouseEvent('mouseleave', event));
12005
12382
  } : null;
12006
12383
 
12007
12384
  const onContextMenu = cfg.onContextMenu ? (event) => {
12008
12385
  cfg.onContextMenu(event, this);
12009
12386
  } : null;
12010
12387
 
12011
- const onMouseWheel = (event) => {
12012
- this.plugin.viewer.scene.canvas.canvas.dispatchEvent(new WheelEvent('wheel', event));
12013
- };
12388
+ const onMouseDown = (event) => canvas.dispatchEvent(new MouseEvent('mousedown', event));
12389
+ const onMouseUp = (event) => canvas.dispatchEvent(new MouseEvent('mouseup', event));
12390
+ const onMouseMove = (event) => canvas.dispatchEvent(new MouseEvent('mousemove', event));
12391
+ const onMouseWheel = (event) => canvas.dispatchEvent(new WheelEvent('wheel', event));
12014
12392
 
12015
- const onMouseDown = (event) => {
12016
- this.plugin.viewer.scene.canvas.canvas.dispatchEvent(new MouseEvent('mousedown', event));
12017
- } ;
12018
12393
 
12019
- const onMouseUp = (event) => {
12020
- this.plugin.viewer.scene.canvas.canvas.dispatchEvent(new MouseEvent('mouseup', event));
12021
- };
12394
+ this._cleanups = [ ];
12395
+ this._drawables = [ ];
12022
12396
 
12023
- const onMouseMove = (event) => {
12024
- this.plugin.viewer.scene.canvas.canvas.dispatchEvent(new MouseEvent('mousemove', event));
12397
+ const registerDrawable = (drawable, visibilityChannels) => {
12398
+ const updateVisibility = () => drawable.setVisible(visibilityChannels.every(ch => ch.get()));
12399
+ visibilityChannels.forEach(ch => ch.reg(updateVisibility));
12400
+ this._drawables.push(drawable);
12401
+ this._cleanups.push(() => drawable.destroy());
12025
12402
  };
12026
12403
 
12027
- this._originDot = new Dot3D(scene, cfg.origin, this._container, {
12028
- fillColor: this._color,
12029
- zIndex: plugin.zIndex !== undefined ? plugin.zIndex + 2 : undefined,
12030
- onMouseOver,
12031
- onMouseLeave,
12032
- onMouseWheel,
12033
- onMouseDown,
12034
- onMouseUp,
12035
- onMouseMove,
12036
- onContextMenu
12037
- });
12038
- this._cornerDot = new Dot3D(scene, cfg.corner, this._container, {
12039
- fillColor: this._color,
12040
- zIndex: plugin.zIndex !== undefined ? plugin.zIndex + 2 : undefined,
12041
- onMouseOver,
12042
- onMouseLeave,
12043
- onMouseWheel,
12044
- onMouseDown,
12045
- onMouseUp,
12046
- onMouseMove,
12047
- onContextMenu
12048
- });
12049
- this._targetDot = new Dot3D(scene, cfg.target, this._container, {
12050
- fillColor: this._color,
12051
- zIndex: plugin.zIndex !== undefined ? plugin.zIndex + 2 : undefined,
12052
- onMouseOver,
12053
- onMouseLeave,
12054
- onMouseWheel,
12055
- onMouseDown,
12056
- onMouseUp,
12057
- onMouseMove,
12058
- onContextMenu
12059
- });
12060
-
12061
- this._originWire = new Wire(this._container, {
12062
- color: this._color || "blue",
12063
- thickness: 1,
12064
- zIndex: plugin.zIndex,
12065
- onMouseOver,
12066
- onMouseLeave,
12067
- onMouseWheel,
12068
- onMouseDown,
12069
- onMouseUp,
12070
- onMouseMove,
12071
- onContextMenu
12072
- });
12073
- this._targetWire = new Wire(this._container, {
12074
- color: this._color || "red",
12075
- thickness: 1,
12076
- zIndex: plugin.zIndex !== undefined ? plugin.zIndex + 1 : undefined,
12077
- onMouseOver,
12078
- onMouseLeave,
12079
- onMouseWheel,
12080
- onMouseDown,
12081
- onMouseUp,
12082
- onMouseMove,
12083
- onContextMenu
12084
- });
12085
-
12086
- this._angleLabel = new Label(this._container, {
12087
- fillColor: this._color || "#00BBFF",
12088
- prefix: "",
12089
- text: "",
12090
- zIndex: plugin.zIndex + 2,
12091
- onMouseOver,
12092
- onMouseLeave,
12093
- onMouseWheel,
12094
- onMouseDown,
12095
- onMouseUp,
12096
- onMouseMove,
12097
- onContextMenu
12098
- });
12099
-
12100
- this._wpDirty = false;
12101
- this._vpDirty = false;
12102
- this._cpDirty = false;
12103
-
12104
- this._visible = false;
12105
- this._originVisible = false;
12106
- this._cornerVisible = false;
12107
- this._targetVisible = false;
12108
-
12109
- this._originWireVisible = false;
12110
- this._targetWireVisible = false;
12111
-
12112
- this._angleVisible = false;
12113
- this._labelsVisible = false;
12114
- this._clickable = false;
12115
-
12116
- this._originDot.on("worldPos", (value) => {
12117
- this._originWorld.set(value || [0, 0, 0]);
12118
- this._wpDirty = true;
12119
- this._needUpdate(0); // No lag
12120
- });
12121
-
12122
- this._cornerDot.on("worldPos", (value) => {
12123
- this._cornerWorld.set(value || [0, 0, 0]);
12124
- this._wpDirty = true;
12125
- this._needUpdate(0); // No lag
12126
- });
12127
-
12128
- this._targetDot.on("worldPos", (value) => {
12129
- this._targetWorld.set(value || [0, 0, 0]);
12130
- this._wpDirty = true;
12131
- this._needUpdate(0); // No lag
12132
- });
12133
-
12134
- this._onViewMatrix = scene.camera.on("viewMatrix", () => {
12135
- this._vpDirty = true;
12136
- this._needUpdate(0); // No lag
12137
- });
12138
-
12139
- this._onProjMatrix = scene.camera.on("projMatrix", () => {
12140
- this._cpDirty = true;
12141
- this._needUpdate();
12142
- });
12143
-
12144
- this._onCanvasBoundary = scene.canvas.on("boundary", () => {
12145
- this._cpDirty = true;
12146
- this._needUpdate(0); // No lag
12147
- });
12148
-
12149
- this._onSectionPlaneUpdated = scene.on("sectionPlaneUpdated", () => {
12150
- this._sectionPlanesDirty = true;
12151
- this._needUpdate();
12152
- });
12153
-
12154
- this.approximate = cfg.approximate;
12155
- this.visible = cfg.visible;
12156
-
12157
- this.originVisible = cfg.originVisible;
12158
- this.cornerVisible = cfg.cornerVisible;
12159
- this.targetVisible = cfg.targetVisible;
12160
-
12161
- this.originWireVisible = cfg.originWireVisible;
12162
- this.targetWireVisible = cfg.targetWireVisible;
12404
+ const makeWire = (color, thickness, visibilityChannels) => {
12405
+ const wire = new Wire3D(scene, container, {
12406
+ color: color,
12407
+ thickness: thickness,
12408
+ thicknessClickable: 6,
12409
+ zIndex: plugin.zIndex !== undefined ? plugin.zIndex + 1 : undefined,
12410
+ onMouseOver,
12411
+ onMouseLeave,
12412
+ onMouseWheel,
12413
+ onMouseDown,
12414
+ onMouseUp,
12415
+ onMouseMove,
12416
+ onContextMenu
12417
+ });
12418
+ registerDrawable(wire, visibilityChannels);
12419
+ return {
12420
+ setEnds: (p0, p1) => wire.setEnds(p0, p1),
12421
+ setColor: value => wire.setColor(value)
12422
+ };
12423
+ };
12424
+ this._originWire = makeWire(this._color || "blue", 1, [ this._visible, this._originWireVisible ]);
12425
+ this._targetWire = makeWire(this._color || "red", 1, [ this._visible, this._targetWireVisible ]);
12426
+
12427
+ const makeLabel = (color, zIndexOffset, visibilityChannels) => {
12428
+ const label = new Label3D(scene, container, {
12429
+ fillColor: color,
12430
+ zIndex: plugin.zIndex + zIndexOffset,
12431
+ onMouseOver,
12432
+ onMouseLeave,
12433
+ onMouseWheel,
12434
+ onMouseDown,
12435
+ onMouseUp,
12436
+ onMouseMove,
12437
+ onContextMenu
12438
+ });
12439
+ registerDrawable(label, visibilityChannels);
12440
+ return {
12441
+ setFillColor: value => label.setFillColor(value),
12442
+ setPosOnWire: (p0, p1, offset) => label.setPosOnWire(p0, p1, offset),
12443
+ setPosBetween: (p0, p1, p2) => label.setPosBetween(p0, p1, p2),
12444
+ setText: str => label.setText(str)
12445
+ };
12446
+ };
12447
+ this._angleLabel = makeLabel(this._color || "#00BBFF", 2, [ this._visible, this._angleVisible, this._labelsVisible ]);
12448
+
12449
+ const makeDot = (cfg, visibilityChannels) => {
12450
+ const dot = new Dot3D(scene, cfg, container, {
12451
+ fillColor: this._color,
12452
+ zIndex: plugin.zIndex !== undefined ? plugin.zIndex + 2 : undefined,
12453
+ onMouseOver,
12454
+ onMouseLeave,
12455
+ onMouseWheel,
12456
+ onMouseDown,
12457
+ onMouseUp,
12458
+ onMouseMove,
12459
+ onContextMenu
12460
+ });
12461
+ dot.on("worldPos", () => this._update());
12462
+ registerDrawable(dot, visibilityChannels);
12463
+ return dot;
12464
+ };
12465
+ this._originDot = makeDot(cfg.origin, [ this._visible, this._originVisible ]);
12466
+ this._cornerDot = makeDot(cfg.corner, [ this._visible, this._cornerVisible ]);
12467
+ this._targetDot = makeDot(cfg.target, [ this._visible, this._targetVisible ]);
12163
12468
 
12164
- this.angleVisible = cfg.angleVisible;
12165
- this.labelsVisible = cfg.labelsVisible;
12469
+ this._update();
12166
12470
  }
12167
12471
 
12168
12472
  _update() {
12169
-
12170
- if (!this._visible) {
12473
+ if (! this._targetDot) {
12171
12474
  return;
12172
12475
  }
12173
12476
 
12174
- const scene = this.plugin.viewer.scene;
12175
-
12176
- if (this._wpDirty) {
12177
-
12178
- this._wp[0] = this._originWorld[0];
12179
- this._wp[1] = this._originWorld[1];
12180
- this._wp[2] = this._originWorld[2];
12181
- this._wp[3] = 1.0;
12182
-
12183
- this._wp[4] = this._cornerWorld[0];
12184
- this._wp[5] = this._cornerWorld[1];
12185
- this._wp[6] = this._cornerWorld[2];
12186
- this._wp[7] = 1.0;
12187
-
12188
- this._wp[8] = this._targetWorld[0];
12189
- this._wp[9] = this._targetWorld[1];
12190
- this._wp[10] = this._targetWorld[2];
12191
- this._wp[11] = 1.0;
12192
-
12193
- this._wpDirty = false;
12194
- this._vpDirty = true;
12195
- }
12196
-
12197
- if (this._vpDirty) {
12198
-
12199
- math.transformPositions4(scene.camera.viewMatrix, this._wp, this._vp);
12200
-
12201
- this._vp[3] = 1.0;
12202
- this._vp[7] = 1.0;
12203
- this._vp[11] = 1.0;
12204
-
12205
- this._vpDirty = false;
12206
- this._cpDirty = true;
12207
- }
12208
-
12209
- if (this._sectionPlanesDirty) {
12210
-
12211
- if (this._isSliced(this._wp)) {
12212
- this._angleLabel.setCulled(true);
12213
- this._originWire.setCulled(true);
12214
- this._targetWire.setCulled(true);
12215
- this._originDot.setCulled(true);
12216
- this._cornerDot.setCulled(true);
12217
- this._targetDot.setCulled(true);
12218
- return;
12219
- } else {
12220
- this._angleLabel.setCulled(false);
12221
- this._originWire.setCulled(false);
12222
- this._targetWire.setCulled(false);
12223
- this._originDot.setCulled(false);
12224
- this._cornerDot.setCulled(false);
12225
- this._targetDot.setCulled(false);
12226
- }
12227
-
12228
- this._sectionPlanesDirty = true;
12229
- }
12230
-
12231
- if (this._cpDirty) {
12232
-
12233
- const near = -0.3;
12234
- const zOrigin = this._originDot.viewPos[2];
12235
- const zCorner = this._cornerDot.viewPos[2];
12236
- const zTarget = this._targetDot.viewPos[2];
12237
-
12238
- if (zOrigin > near || zCorner > near || zTarget > near) {
12239
-
12240
- this._originDot.setVisible(false);
12241
- this._cornerDot.setVisible(false);
12242
- this._targetDot.setVisible(false);
12243
-
12244
- this._originWire.setVisible(false);
12245
- this._targetWire.setVisible(false);
12246
-
12247
- this._angleLabel.setCulled(true);
12248
-
12249
- return;
12250
- }
12251
-
12252
- math.transformPositions4(scene.camera.project.matrix, this._vp, this._pp);
12253
-
12254
- var pp = this._pp;
12255
- var cp = this._cp;
12256
-
12257
- var canvas = scene.canvas.canvas;
12258
- var offsets = canvas.getBoundingClientRect();
12259
- const containerOffsets = this._container.getBoundingClientRect();
12260
- var top = offsets.top - containerOffsets.top;
12261
- var left = offsets.left - containerOffsets.left;
12262
- var aabb = scene.canvas.boundary;
12263
- var canvasWidth = aabb[2];
12264
- var canvasHeight = aabb[3];
12265
- var j = 0;
12266
-
12267
- for (var i = 0, len = pp.length; i < len; i += 4) {
12268
- cp[j] = left + Math.floor((1 + pp[i + 0] / pp[i + 3]) * canvasWidth / 2);
12269
- cp[j + 1] = top + Math.floor((1 - pp[i + 1] / pp[i + 3]) * canvasHeight / 2);
12270
- j += 2;
12271
- }
12272
-
12273
- this._originWire.setStartAndEnd(cp[0], cp[1], cp[2], cp[3]);
12274
- this._targetWire.setStartAndEnd(cp[2], cp[3], cp[4], cp[5]);
12275
-
12276
- this._angleLabel.setPosBetweenWires(cp[0], cp[1], cp[2], cp[3], cp[4], cp[5]);
12277
-
12278
- math.subVec3(this._originWorld, this._cornerWorld, originVec);
12279
- math.subVec3(this._targetWorld, this._cornerWorld, targetVec);
12280
-
12281
- var validVecs =
12282
- (originVec[0] !== 0 || originVec[1] !== 0 || originVec[2] !== 0) &&
12283
- (targetVec[0] !== 0 || targetVec[1] !== 0 || targetVec[2] !== 0);
12284
-
12285
- if (validVecs) {
12286
-
12287
- const tilde = this._approximate ? " ~ " : " = ";
12288
-
12289
- math.normalizeVec3(originVec);
12290
- math.normalizeVec3(targetVec);
12291
- const angle = Math.abs(math.angleVec3(originVec, targetVec));
12292
- this._angle = angle / math.DEGTORAD;
12293
- this._angleLabel.setText(tilde + this._angle.toFixed(2) + "°");
12294
- } else {
12295
- this._angleLabel.setText("");
12296
- }
12477
+ const p0 = this._originDot.worldPos;
12478
+ const p1 = this._cornerDot.worldPos;
12479
+ const p2 = this._targetDot.worldPos;
12297
12480
 
12298
- // this._angleLabel.setText((Math.abs(math.lenVec3(math.subVec3(this._targetWorld, this._originWorld, distVec3)) * scale).toFixed(2)) + unitAbbrev);
12481
+ this._originWire.setEnds(p0, p1);
12482
+ this._targetWire.setEnds(p1, p2);
12483
+ this._angleLabel.setPosBetween(p0, p1, p2);
12299
12484
 
12300
- this._originDot.setVisible(this._visible && this._originVisible);
12301
- this._cornerDot.setVisible(this._visible && this._cornerVisible);
12302
- this._targetDot.setVisible(this._visible && this._targetVisible);
12485
+ math.subVec3(p0, p1, tmpVec3a$1);
12486
+ math.subVec3(p2, p1, tmpVec3b$1);
12303
12487
 
12304
- this._originWire.setVisible(this._visible && this._originWireVisible);
12305
- this._targetWire.setVisible(this._visible && this._targetWireVisible);
12306
-
12307
- this._angleLabel.setCulled(!(this._visible && this._angleVisible && this.labelsVisible));
12308
-
12309
- this._cpDirty = false;
12310
- }
12311
- }
12312
-
12313
- _isSliced(positions) {
12314
- const sectionPlanes = this.scene._sectionPlanesState.sectionPlanes;
12315
- for (let i = 0, len = sectionPlanes.length; i < len; i++) {
12316
- const sectionPlane = sectionPlanes[i];
12317
- if (math.planeClipsPositions3(sectionPlane.pos, sectionPlane.dir, positions, 4)) {
12318
- return true
12319
- }
12488
+ if ((math.lenVec3(tmpVec3a$1) > 0) && (math.lenVec3(tmpVec3b$1) > 0)) {
12489
+ math.normalizeVec3(tmpVec3a$1);
12490
+ math.normalizeVec3(tmpVec3b$1);
12491
+ this._angle = Math.abs(math.angleVec3(tmpVec3a$1, tmpVec3b$1)) * math.RADTODEG;
12492
+ this._angleLabel.setText((this._approximate ? " ~ " : " = ") + this._angle.toFixed(2) + "°");
12493
+ } else {
12494
+ this._angle = undefined;
12495
+ this._angleLabel.setText("");
12320
12496
  }
12321
- return false;
12322
12497
  }
12323
12498
 
12324
12499
  /**
@@ -12334,8 +12509,7 @@ class AngleMeasurement extends Component {
12334
12509
  return;
12335
12510
  }
12336
12511
  this._approximate = approximate;
12337
- this._cpDirty = true;
12338
- this._needUpdate(0);
12512
+ this._update();
12339
12513
  }
12340
12514
 
12341
12515
  /**
@@ -12383,7 +12557,6 @@ class AngleMeasurement extends Component {
12383
12557
  * @type {Number}
12384
12558
  */
12385
12559
  get angle() {
12386
- this._update();
12387
12560
  return this._angle;
12388
12561
  }
12389
12562
 
@@ -12405,14 +12578,13 @@ class AngleMeasurement extends Component {
12405
12578
  * @type {String}
12406
12579
  */
12407
12580
  set color(value) {
12581
+ this._color = value;
12408
12582
  this._originDot.setFillColor(value);
12409
12583
  this._cornerDot.setFillColor(value);
12410
12584
  this._targetDot.setFillColor(value);
12411
12585
  this._originWire.setColor(value || "blue");
12412
12586
  this._targetWire.setColor(value || "red");
12413
12587
  this._angleLabel.setFillColor(value || "#00BBFF");
12414
-
12415
- this._color = value;
12416
12588
  }
12417
12589
 
12418
12590
  /**
@@ -12421,16 +12593,7 @@ class AngleMeasurement extends Component {
12421
12593
  * @type {Boolean}
12422
12594
  */
12423
12595
  set visible(value) {
12424
- value = value !== false;
12425
- this._visible = value;
12426
- this._originDot.setVisible(this._visible && this._originVisible);
12427
- this._cornerDot.setVisible(this._visible && this._cornerVisible);
12428
- this._targetDot.setVisible(this._visible && this._targetVisible);
12429
- this._originWire.setVisible(this._visible && this._originWireVisible);
12430
- this._targetWire.setVisible(this._visible && this._targetWireVisible);
12431
- this._angleLabel.setVisible(this._visible && this._angleVisible);
12432
- this._cpDirty = true;
12433
- this._needUpdate();
12596
+ this._visible.set(value);
12434
12597
  }
12435
12598
 
12436
12599
  /**
@@ -12439,7 +12602,7 @@ class AngleMeasurement extends Component {
12439
12602
  * @type {Boolean}
12440
12603
  */
12441
12604
  get visible() {
12442
- return this._visible;
12605
+ return this._visible.get();
12443
12606
  }
12444
12607
 
12445
12608
  /**
@@ -12448,11 +12611,7 @@ class AngleMeasurement extends Component {
12448
12611
  * @type {Boolean}
12449
12612
  */
12450
12613
  set originVisible(value) {
12451
- value = value !== false;
12452
- this._originVisible = value;
12453
- this._originDot.setVisible(this._visible && this._originVisible);
12454
- this._cpDirty = true;
12455
- this._needUpdate();
12614
+ this._originVisible.set(value);
12456
12615
  }
12457
12616
 
12458
12617
  /**
@@ -12461,7 +12620,7 @@ class AngleMeasurement extends Component {
12461
12620
  * @type {Boolean}
12462
12621
  */
12463
12622
  get originVisible() {
12464
- return this._originVisible;
12623
+ return this._originVisible.get();
12465
12624
  }
12466
12625
 
12467
12626
  /**
@@ -12470,11 +12629,7 @@ class AngleMeasurement extends Component {
12470
12629
  * @type {Boolean}
12471
12630
  */
12472
12631
  set cornerVisible(value) {
12473
- value = value !== false;
12474
- this._cornerVisible = value;
12475
- this._cornerDot.setVisible(this._visible && this._cornerVisible);
12476
- this._cpDirty = true;
12477
- this._needUpdate();
12632
+ this._cornerVisible.set(value);
12478
12633
  }
12479
12634
 
12480
12635
  /**
@@ -12483,7 +12638,7 @@ class AngleMeasurement extends Component {
12483
12638
  * @type {Boolean}
12484
12639
  */
12485
12640
  get cornerVisible() {
12486
- return this._cornerVisible;
12641
+ return this._cornerVisible.get();
12487
12642
  }
12488
12643
 
12489
12644
  /**
@@ -12492,11 +12647,7 @@ class AngleMeasurement extends Component {
12492
12647
  * @type {Boolean}
12493
12648
  */
12494
12649
  set targetVisible(value) {
12495
- value = value !== false;
12496
- this._targetVisible = value;
12497
- this._targetDot.setVisible(this._visible && this._targetVisible);
12498
- this._cpDirty = true;
12499
- this._needUpdate();
12650
+ this._targetVisible.set(value);
12500
12651
  }
12501
12652
 
12502
12653
  /**
@@ -12505,7 +12656,7 @@ class AngleMeasurement extends Component {
12505
12656
  * @type {Boolean}
12506
12657
  */
12507
12658
  get targetVisible() {
12508
- return this._targetVisible;
12659
+ return this._targetVisible.get();
12509
12660
  }
12510
12661
 
12511
12662
  /**
@@ -12514,11 +12665,7 @@ class AngleMeasurement extends Component {
12514
12665
  * @type {Boolean}
12515
12666
  */
12516
12667
  set originWireVisible(value) {
12517
- value = value !== false;
12518
- this._originWireVisible = value;
12519
- this._originWire.setVisible(this._visible && this._originWireVisible);
12520
- this._cpDirty = true;
12521
- this._needUpdate();
12668
+ this._originWireVisible.set(value);
12522
12669
  }
12523
12670
 
12524
12671
  /**
@@ -12527,7 +12674,7 @@ class AngleMeasurement extends Component {
12527
12674
  * @type {Boolean}
12528
12675
  */
12529
12676
  get originWireVisible() {
12530
- return this._originWireVisible;
12677
+ return this._originWireVisible.get();
12531
12678
  }
12532
12679
 
12533
12680
  /**
@@ -12536,11 +12683,7 @@ class AngleMeasurement extends Component {
12536
12683
  * @type {Boolean}
12537
12684
  */
12538
12685
  set targetWireVisible(value) {
12539
- value = value !== false;
12540
- this._targetWireVisible = value;
12541
- this._targetWire.setVisible(this._visible && this._targetWireVisible);
12542
- this._cpDirty = true;
12543
- this._needUpdate();
12686
+ this._targetWireVisible.set(value);
12544
12687
  }
12545
12688
 
12546
12689
  /**
@@ -12549,7 +12692,7 @@ class AngleMeasurement extends Component {
12549
12692
  * @type {Boolean}
12550
12693
  */
12551
12694
  get targetWireVisible() {
12552
- return this._targetWireVisible;
12695
+ return this._targetWireVisible.get();
12553
12696
  }
12554
12697
 
12555
12698
  /**
@@ -12558,11 +12701,7 @@ class AngleMeasurement extends Component {
12558
12701
  * @type {Boolean}
12559
12702
  */
12560
12703
  set angleVisible(value) {
12561
- value = value !== false;
12562
- this._angleVisible = value;
12563
- this._angleLabel.setVisible(this._visible && this._angleVisible);
12564
- this._cpDirty = true;
12565
- this._needUpdate();
12704
+ this._angleVisible.set(value);
12566
12705
  }
12567
12706
 
12568
12707
  /**
@@ -12571,7 +12710,7 @@ class AngleMeasurement extends Component {
12571
12710
  * @type {Boolean}
12572
12711
  */
12573
12712
  get angleVisible() {
12574
- return this._angleVisible;
12713
+ return this._angleVisible.get();
12575
12714
  }
12576
12715
 
12577
12716
  /**
@@ -12580,12 +12719,7 @@ class AngleMeasurement extends Component {
12580
12719
  * @type {Boolean}
12581
12720
  */
12582
12721
  set labelsVisible(value) {
12583
- value = value !== undefined ? Boolean(value) : this.plugin.defaultLabelsVisible;
12584
- this._labelsVisible = value;
12585
- var labelsVisible = this._visible && this._labelsVisible;
12586
- this._angleLabel.setVisible(labelsVisible);
12587
- this._cpDirty = true;
12588
- this._needUpdate();
12722
+ this._labelsVisible.set(value !== undefined ? Boolean(value) : this.plugin.defaultLabelsVisible);
12589
12723
  }
12590
12724
 
12591
12725
  /**
@@ -12594,7 +12728,7 @@ class AngleMeasurement extends Component {
12594
12728
  * @type {Boolean}
12595
12729
  */
12596
12730
  get labelsVisible() {
12597
- return this._labelsVisible;
12731
+ return this._labelsVisible.get();
12598
12732
  }
12599
12733
 
12600
12734
  /**
@@ -12602,12 +12736,7 @@ class AngleMeasurement extends Component {
12602
12736
  * @param highlighted
12603
12737
  */
12604
12738
  setHighlighted(highlighted) {
12605
- this._originDot.setHighlighted(highlighted);
12606
- this._cornerDot.setHighlighted(highlighted);
12607
- this._targetDot.setHighlighted(highlighted);
12608
- this._originWire.setHighlighted(highlighted);
12609
- this._targetWire.setHighlighted(highlighted);
12610
- this._angleLabel.setHighlighted(highlighted);
12739
+ this._drawables.forEach(d => d.setHighlighted(highlighted));
12611
12740
  }
12612
12741
 
12613
12742
  /**
@@ -12616,14 +12745,8 @@ class AngleMeasurement extends Component {
12616
12745
  * @type {Boolean}
12617
12746
  */
12618
12747
  set clickable(value) {
12619
- value = !!value;
12620
- this._clickable = value;
12621
- this._originDot.setClickable(this._clickable);
12622
- this._cornerDot.setClickable(this._clickable);
12623
- this._targetDot.setClickable(this._clickable);
12624
- this._originWire.setClickable(this._clickable);
12625
- this._targetWire.setClickable(this._clickable);
12626
- this._angleLabel.setClickable(this._clickable);
12748
+ this._clickable.set(!!value);
12749
+ this._drawables.forEach(d => d.setClickable(this._clickable.get()));
12627
12750
  }
12628
12751
 
12629
12752
  /**
@@ -12632,38 +12755,14 @@ class AngleMeasurement extends Component {
12632
12755
  * @type {Boolean}
12633
12756
  */
12634
12757
  get clickable() {
12635
- return this._clickable;
12758
+ return this._clickable.get();
12636
12759
  }
12637
12760
 
12638
12761
  /**
12639
12762
  * @private
12640
12763
  */
12641
12764
  destroy() {
12642
-
12643
- const scene = this.plugin.viewer.scene;
12644
-
12645
- if (this._onViewMatrix) {
12646
- scene.camera.off(this._onViewMatrix);
12647
- }
12648
- if (this._onProjMatrix) {
12649
- scene.camera.off(this._onProjMatrix);
12650
- }
12651
- if (this._onCanvasBoundary) {
12652
- scene.canvas.off(this._onCanvasBoundary);
12653
- }
12654
- if (this._onSectionPlaneUpdated) {
12655
- scene.off(this._onSectionPlaneUpdated);
12656
- }
12657
-
12658
- this._originDot.destroy();
12659
- this._cornerDot.destroy();
12660
- this._targetDot.destroy();
12661
-
12662
- this._originWire.destroy();
12663
- this._targetWire.destroy();
12664
-
12665
- this._angleLabel.destroy();
12666
-
12765
+ this._cleanups.forEach(cleanup => cleanup());
12667
12766
  super.destroy();
12668
12767
  }
12669
12768
  }
@@ -13094,7 +13193,7 @@ class AngleMeasurementsMouseControl extends AngleMeasurementsControl {
13094
13193
  mouseHovering = false;
13095
13194
  if (pointerLens) {
13096
13195
  pointerLens.visible = true;
13097
- pointerLens.pointerPos = event.canvasPos;
13196
+ pointerLens.canvasPos = event.canvasPos;
13098
13197
  pointerLens.snappedCanvasPos = event.snappedCanvasPos || event.canvasPos;
13099
13198
  pointerLens.snapped = false;
13100
13199
  }
@@ -14660,9 +14759,10 @@ class Annotation extends Marker {
14660
14759
  this._marker.addEventListener("click", this._onMouseClickedExternalMarker = () => {
14661
14760
  this.plugin.fire("markerClicked", this);
14662
14761
  });
14663
- this._marker.addEventListener("contextmenu", this._onContextMenuExtenalMarker = () => {
14762
+ this._onContextMenuExtenalMarker = () => {
14664
14763
  this.plugin.fire("contextmenu", this);
14665
- });
14764
+ };
14765
+ this._onContextMenuExtenalMarkerRemover = addContextMenuListener(this._markerHTML, this._onContextMenuExtenalMarker);
14666
14766
  this._marker.addEventListener("mouseenter", this._onMouseEnterExternalMarker = () => {
14667
14767
  this.plugin.fire("markerMouseEnter", this);
14668
14768
  });
@@ -14783,7 +14883,7 @@ class Annotation extends Marker {
14783
14883
  this._marker.addEventListener("click", () => {
14784
14884
  this.plugin.fire("markerClicked", this);
14785
14885
  });
14786
- this._marker.addEventListener("contextmenu", e => {
14886
+ addContextMenuListener(this._marker, e => {
14787
14887
  e.preventDefault();
14788
14888
  this.plugin.fire("contextmenu", this);
14789
14889
  });
@@ -15033,7 +15133,7 @@ class Annotation extends Marker {
15033
15133
  this._marker = null;
15034
15134
  } else {
15035
15135
  this._marker.removeEventListener("click", this._onMouseClickedExternalMarker);
15036
- this._marker.removeEventListener("contextmenu", this._onContextMenuExtenalMarker);
15136
+ this._onContextMenuExtenalMarkerRemover();
15037
15137
  this._marker.removeEventListener("mouseenter", this._onMouseEnterExternalMarker);
15038
15138
  this._marker.removeEventListener("mouseleave", this._onMouseLeaveExternalMarker);
15039
15139
  this._marker = null;
@@ -61847,7 +61947,7 @@ class VBOInstancingTrianglesLayer {
61847
61947
  state.indicesBuf = new ArrayBuf(gl, gl.ELEMENT_ARRAY_BUFFER, new Uint32Array(geometry.indices), geometry.indices.length, 1, gl.STATIC_DRAW);
61848
61948
  state.numIndices = geometry.indices.length;
61849
61949
  }
61850
- if (geometry.primitive === "triangles" || geometry.primitive === "solid" || geometry.primitive === "surface") {
61950
+ if (geometry.edgeIndices && geometry.edgeIndices.length > 0) {
61851
61951
  state.edgeIndicesBuf = new ArrayBuf(gl, gl.ELEMENT_ARRAY_BUFFER, new Uint32Array(geometry.edgeIndices), geometry.edgeIndices.length, 1, gl.STATIC_DRAW);
61852
61952
  }
61853
61953
 
@@ -87928,22 +88028,12 @@ function colorizeToRGB(color) {
87928
88028
  return rgb;
87929
88029
  }
87930
88030
 
87931
- const distVec3 = math.vec3();
87932
- const tmpVec3 = math.vec3();
87933
-
87934
- const lengthWire = (x1, y1, x2, y2) => {
87935
- var a = x1 - x2;
87936
- var b = y1 - y2;
87937
- return Math.sqrt(a * a + b * b);
87938
- };
87939
-
87940
- function determineMeasurementOrientation(A, B, distance) {
87941
- const yDiff = Math.abs(B[1] - A[1]);
87942
-
87943
- return yDiff > distance ? 'Vertical' : 'Horizontal';
87944
- }
87945
-
87946
- // function findDistance
88031
+ const tmpVec3a = math.vec3();
88032
+ const tmpVec3b = math.vec3();
88033
+ const tmpVec3c = math.vec3();
88034
+ math.vec4();
88035
+ math.vec4();
88036
+ math.vec4();
87947
88037
 
87948
88038
  /**
87949
88039
  * @desc Measures the distance between two 3D points.
@@ -87957,7 +88047,9 @@ class DistanceMeasurement extends Component {
87957
88047
  */
87958
88048
  constructor(plugin, cfg = {}) {
87959
88049
 
87960
- super(plugin.viewer.scene, cfg);
88050
+ const scene = plugin.viewer.scene;
88051
+
88052
+ super(scene, cfg);
87961
88053
 
87962
88054
  /**
87963
88055
  * The {@link DistanceMeasurementsPlugin} that owns this DistanceMeasurement.
@@ -87965,597 +88057,251 @@ class DistanceMeasurement extends Component {
87965
88057
  */
87966
88058
  this.plugin = plugin;
87967
88059
 
87968
- this._container = cfg.container;
87969
- if (!this._container) {
88060
+ const container = cfg.container;
88061
+ if (!container) {
87970
88062
  throw "config missing: container";
87971
88063
  }
87972
88064
 
87973
- this._eventSubs = {};
87974
-
87975
- var scene = this.plugin.viewer.scene;
88065
+ this._color = cfg.color || plugin.defaultColor;
87976
88066
 
87977
- this._originWorld = math.vec3();
87978
- this._targetWorld = math.vec3();
88067
+ const channel = function(v, defaultIfUndefined) {
88068
+ const listeners = [ ];
88069
+ let value = v !== undefined ? Boolean(v) : defaultIfUndefined;
88070
+ return {
88071
+ reg: (l) => listeners.push(l),
88072
+ get: () => value,
88073
+ set: (v) => {
88074
+ value = v !== undefined ? Boolean(v) : defaultIfUndefined;
88075
+ listeners.forEach(l => l(value));
88076
+ }
88077
+ };
88078
+ };
87979
88079
 
87980
- this._wp = new Float64Array(24); //world position
87981
- this._vp = new Float64Array(24); //view position
87982
- this._pp = new Float64Array(24);
87983
- this._cp = new Float64Array(8); //canvas position
88080
+ this._visible = channel(cfg.visible, plugin.defaultVisible);
88081
+ this._originVisible = channel(cfg.originVisible, plugin.defaultOriginVisible);
88082
+ this._targetVisible = channel(cfg.targetVisible, plugin.defaultTargetVisible);
88083
+ this._axisVisible = channel(cfg.axisVisible, plugin.defaultAxisVisible);
88084
+ this._xAxisVisible = channel(cfg.xAxisVisible, plugin.defaultAxisVisible);
88085
+ this._yAxisVisible = channel(cfg.yAxisVisible, plugin.defaultAxisVisible);
88086
+ this._zAxisVisible = channel(cfg.zAxisVisible, plugin.defaultAxisVisible);
88087
+ this._axisEnabled = channel(true, plugin.defaultAxisVisible);
88088
+ this._wireVisible = channel(cfg.wireVisible, plugin.defaultWireVisible);
88089
+ this._xLabelEnabled = channel(cfg.xLabelEnabled, plugin.defaultXLabelEnabled);
88090
+ this._yLabelEnabled = channel(cfg.yLabelEnabled, plugin.defaultYLabelEnabled);
88091
+ this._zLabelEnabled = channel(cfg.zLabelEnabled, plugin.defaultZLabelEnabled);
88092
+ this._lengthLabelEnabled = channel(cfg.lengthLabelEnabled, plugin.defaultLengthLabelEnabled);
88093
+ this._labelsVisible = channel(cfg.labelsVisible, plugin.defaultLabelsVisible);
88094
+ this._clickable = channel(false, false);
88095
+ this._labelsOnWires = channel(cfg.labelsOnWires, plugin.defaultLabelsOnWires);
88096
+ this._useRotationAdjustment = channel(cfg.useRotationAdjustment, plugin.useRotationAdjustment);
88097
+
88098
+ this._axesBasis = math.identityMat4();
88099
+ this.approximate = cfg.approximate;
87984
88100
 
87985
- this._xAxisLabelCulled = false;
87986
- this._yAxisLabelCulled = false;
87987
- this._zAxisLabelCulled = false;
87988
88101
 
87989
- this._color = cfg.color || this.plugin.defaultColor;
88102
+ const canvas = scene.canvas.canvas;
87990
88103
 
87991
88104
  const onMouseOver = cfg.onMouseOver ? (event) => {
87992
88105
  cfg.onMouseOver(event, this);
87993
- this.plugin.viewer.scene.canvas.canvas.dispatchEvent(new MouseEvent('mouseover', event));
88106
+ canvas.dispatchEvent(new MouseEvent('mouseover', event));
87994
88107
  } : null;
87995
88108
 
87996
88109
  const onMouseLeave = cfg.onMouseLeave ? (event) => {
87997
88110
  cfg.onMouseLeave(event, this);
87998
- this.plugin.viewer.scene.canvas.canvas.dispatchEvent(new MouseEvent('mouseleave', event));
88111
+ canvas.dispatchEvent(new MouseEvent('mouseleave', event));
87999
88112
  } : null;
88000
88113
 
88001
- const onMouseDown = (event) => {
88002
- this.plugin.viewer.scene.canvas.canvas.dispatchEvent(new MouseEvent('mousedown', event));
88003
- } ;
88004
-
88005
- const onMouseUp = (event) => {
88006
- this.plugin.viewer.scene.canvas.canvas.dispatchEvent(new MouseEvent('mouseup', event));
88007
- };
88008
-
88009
- const onMouseMove = (event) => {
88010
- this.plugin.viewer.scene.canvas.canvas.dispatchEvent(new MouseEvent('mousemove', event));
88011
- };
88012
-
88013
88114
  const onContextMenu = cfg.onContextMenu ? (event) => {
88014
88115
  cfg.onContextMenu(event, this);
88015
88116
  } : null;
88016
88117
 
88017
- const onMouseWheel = (event) => {
88018
- this.plugin.viewer.scene.canvas.canvas.dispatchEvent(new WheelEvent('wheel', event));
88019
- };
88118
+ const onMouseDown = (event) => canvas.dispatchEvent(new MouseEvent('mousedown', event));
88119
+ const onMouseUp = (event) => canvas.dispatchEvent(new MouseEvent('mouseup', event));
88120
+ const onMouseMove = (event) => canvas.dispatchEvent(new MouseEvent('mousemove', event));
88121
+ const onMouseWheel = (event) => canvas.dispatchEvent(new WheelEvent('wheel', event));
88020
88122
 
88021
- this._originDot = new Dot3D(scene, cfg.origin, this._container, {
88022
- fillColor: this._color,
88023
- zIndex: plugin.zIndex !== undefined ? plugin.zIndex + 2 : undefined,
88024
- onMouseOver,
88025
- onMouseLeave,
88026
- onMouseWheel,
88027
- onMouseDown,
88028
- onMouseUp,
88029
- onMouseMove,
88030
- onContextMenu
88031
- });
88032
88123
 
88033
- this._targetDot = new Dot3D(scene, cfg.target, this._container, {
88034
- fillColor: this._color,
88035
- zIndex: plugin.zIndex !== undefined ? plugin.zIndex + 2 : undefined,
88036
- onMouseOver,
88037
- onMouseLeave,
88038
- onMouseWheel,
88039
- onMouseDown,
88040
- onMouseUp,
88041
- onMouseMove,
88042
- onContextMenu
88043
- });
88124
+ this._cleanups = [ ];
88044
88125
 
88045
- this._lengthWire = new Wire(this._container, {
88046
- color: this._color,
88047
- thickness: 2,
88048
- thicknessClickable: 6,
88049
- zIndex: plugin.zIndex !== undefined ? plugin.zIndex + 1 : undefined,
88050
- onMouseOver,
88051
- onMouseLeave,
88052
- onMouseWheel,
88053
- onMouseDown,
88054
- onMouseUp,
88055
- onMouseMove,
88056
- onContextMenu
88126
+ [ "units", "scale" ].forEach(evt => {
88127
+ const handler = scene.metrics.on("units", () => this._update());
88128
+ this._cleanups.push(() => scene.metrics.off(handler));
88057
88129
  });
88058
88130
 
88059
- this._xAxisWire = new Wire(this._container, {
88060
- color: "#FF0000",
88061
- thickness: 1,
88062
- thicknessClickable: 6,
88063
- zIndex: plugin.zIndex !== undefined ? plugin.zIndex + 1 : undefined,
88064
- onMouseOver,
88065
- onMouseLeave,
88066
- onMouseWheel,
88067
- onMouseDown,
88068
- onMouseUp,
88069
- onMouseMove,
88070
- onContextMenu
88071
- });
88131
+ this._drawables = [ ];
88072
88132
 
88073
- this._yAxisWire = new Wire(this._container, {
88074
- color: "green",
88075
- thickness: 1,
88076
- thicknessClickable: 6,
88077
- zIndex: plugin.zIndex !== undefined ? plugin.zIndex + 1 : undefined,
88078
- onMouseOver,
88079
- onMouseLeave,
88080
- onMouseWheel,
88081
- onMouseDown,
88082
- onMouseUp,
88083
- onMouseMove,
88084
- onContextMenu
88085
- });
88086
-
88087
- this._zAxisWire = new Wire(this._container, {
88088
- color: "blue",
88089
- thickness: 1,
88090
- thicknessClickable: 6,
88091
- zIndex: plugin.zIndex !== undefined ? plugin.zIndex + 1 : undefined,
88092
- onMouseOver,
88093
- onMouseLeave,
88094
- onMouseWheel,
88095
- onMouseDown,
88096
- onMouseUp,
88097
- onMouseMove,
88098
- onContextMenu
88099
- });
88133
+ const registerDrawable = (drawable, visibilityChannels) => {
88134
+ const updateVisibility = () => drawable.setVisible(visibilityChannels.every(ch => ch.get()));
88135
+ visibilityChannels.forEach(ch => ch.reg(updateVisibility));
88136
+ this._drawables.push(drawable);
88137
+ this._cleanups.push(() => drawable.destroy());
88138
+ };
88100
88139
 
88101
- this._lengthLabel = new Label(this._container, {
88102
- fillColor: this._color,
88103
- prefix: "",
88104
- text: "",
88105
- zIndex: plugin.zIndex !== undefined ? plugin.zIndex + 4 : undefined,
88106
- onMouseOver,
88107
- onMouseLeave,
88108
- onMouseWheel,
88109
- onMouseDown,
88110
- onMouseUp,
88111
- onMouseMove,
88112
- onContextMenu
88113
- });
88140
+ const makeWire = (color, thickness, visibilityChannels) => {
88141
+ const wire = new Wire3D(scene, container, {
88142
+ color: color,
88143
+ thickness: thickness,
88144
+ thicknessClickable: 6,
88145
+ zIndex: plugin.zIndex !== undefined ? plugin.zIndex + 1 : undefined,
88146
+ onMouseOver,
88147
+ onMouseLeave,
88148
+ onMouseWheel,
88149
+ onMouseDown,
88150
+ onMouseUp,
88151
+ onMouseMove,
88152
+ onContextMenu
88153
+ });
88154
+ registerDrawable(wire, visibilityChannels);
88155
+ return {
88156
+ setEnds: (p0, p1) => wire.setEnds(p0, p1),
88157
+ setColor: value => wire.setColor(value)
88158
+ };
88159
+ };
88160
+ this._lengthWire = makeWire(this._color, 2, [ this._visible, this._wireVisible ]);
88161
+ this._xAxisWire = makeWire("red", 1, [ this._visible, this._axisEnabled, this._axisVisible, this._xAxisVisible ]);
88162
+ this._yAxisWire = makeWire("green", 1, [ this._visible, this._axisEnabled, this._axisVisible, this._yAxisVisible ]);
88163
+ this._zAxisWire = makeWire("blue", 1, [ this._visible, this._axisEnabled, this._axisVisible, this._zAxisVisible ]);
88164
+
88165
+ const makeLabel = (color, zIndexOffset, visibilityChannels) => {
88166
+ const label = new Label3D(scene, container, {
88167
+ fillColor: color,
88168
+ zIndex: plugin.zIndex !== undefined ? plugin.zIndex + zIndexOffset : undefined,
88169
+ onMouseOver,
88170
+ onMouseLeave,
88171
+ onMouseWheel,
88172
+ onMouseDown,
88173
+ onMouseUp,
88174
+ onMouseMove,
88175
+ onContextMenu
88176
+ });
88177
+ registerDrawable(label, visibilityChannels);
88178
+ return {
88179
+ setFillColor: value => label.setFillColor(value),
88180
+ setPosOnWire: (p0, p1, offset, labelMinAxisLength) => label.setPosOnWire(p0, p1, offset, labelMinAxisLength),
88181
+ setPosBetween: (p0, p1, p2) => label.setPosBetween(p0, p1, p2),
88182
+ setText: str => label.setText(str.replace(/ /g, "&nbsp;"))
88183
+ };
88184
+ };
88185
+ this._lengthLabel = makeLabel(this._color, 4, [ this._visible, this._wireVisible, this._labelsVisible, this._clickable, this._axisEnabled, this._lengthLabelEnabled ]);
88186
+ this._xAxisLabel = makeLabel("red", 3, [ this._visible, this._axisEnabled, this._axisVisible, this._xAxisVisible, this._labelsVisible, this._clickable, this._xLabelEnabled ]);
88187
+ this._yAxisLabel = makeLabel("green", 3, [ this._visible, this._axisEnabled, this._axisVisible, this._yAxisVisible, this._labelsVisible, this._clickable, this._yLabelEnabled ]);
88188
+ this._zAxisLabel = makeLabel("blue", 3, [ this._visible, this._axisEnabled, this._axisVisible, this._zAxisVisible, this._labelsVisible, this._clickable, this._zLabelEnabled ]);
88189
+
88190
+ const makeDot = (cfg, visibilityChannels) => {
88191
+ const dot = new Dot3D(scene, cfg, container, {
88192
+ fillColor: this._color,
88193
+ zIndex: plugin.zIndex !== undefined ? plugin.zIndex + 2 : undefined,
88194
+ onMouseOver,
88195
+ onMouseLeave,
88196
+ onMouseWheel,
88197
+ onMouseDown,
88198
+ onMouseUp,
88199
+ onMouseMove,
88200
+ onContextMenu
88201
+ });
88202
+ dot.on("worldPos", () => this._update());
88203
+ registerDrawable(dot, visibilityChannels);
88204
+ return dot;
88205
+ };
88206
+ this._originDot = makeDot(cfg.origin, [ this._visible, this._originVisible ]);
88207
+ this._targetDot = makeDot(cfg.target, [ this._visible, this._targetVisible ]);
88114
88208
 
88115
- this._xAxisLabel = new Label(this._container, {
88116
- fillColor: "red",
88117
- prefix: "X",
88118
- text: "",
88119
- zIndex: plugin.zIndex !== undefined ? plugin.zIndex + 3 : undefined,
88120
- onMouseOver,
88121
- onMouseLeave,
88122
- onMouseWheel,
88123
- onMouseDown,
88124
- onMouseUp,
88125
- onMouseMove,
88126
- onContextMenu
88127
- });
88209
+ this._update();
88210
+ }
88128
88211
 
88129
- this._yAxisLabel = new Label(this._container, {
88130
- fillColor: "green",
88131
- prefix: "Y",
88132
- text: "",
88133
- zIndex: plugin.zIndex !== undefined ? plugin.zIndex + 3 : undefined,
88134
- onMouseOver,
88135
- onMouseLeave,
88136
- onMouseWheel,
88137
- onMouseDown,
88138
- onMouseUp,
88139
- onMouseMove,
88140
- onContextMenu
88141
- });
88212
+ _update() {
88213
+ if (! this._targetDot) {
88214
+ return;
88215
+ }
88142
88216
 
88143
- this._zAxisLabel = new Label(this._container, {
88144
- fillColor: "blue",
88145
- prefix: "Z",
88146
- text: "",
88147
- zIndex: plugin.zIndex !== undefined ? plugin.zIndex + 3 : undefined,
88148
- onMouseOver,
88149
- onMouseLeave,
88150
- onMouseWheel,
88151
- onMouseDown,
88152
- onMouseUp,
88153
- onMouseMove,
88154
- onContextMenu
88155
- });
88217
+ const p0 = this._originDot.worldPos;
88218
+ const p1 = this._targetDot.worldPos;
88219
+ const axesBasis = this._axesBasis;
88220
+ const delta = math.subVec3(p1, p0, tmpVec3a);
88221
+ const factors = math.transformVec3(axesBasis, delta, delta);
88156
88222
 
88157
- this._measurementOrientation = 'Horizontal';
88158
- this._wpDirty = false;
88159
- this._vpDirty = false;
88160
- this._cpDirty = false;
88161
- this._sectionPlanesDirty = true;
88223
+ const measurementOrientationVertical = this._useRotationAdjustment.get() && Math.abs(delta[1]) > 0;
88162
88224
 
88163
- this._visible = false;
88164
- this._originVisible = false;
88165
- this._targetVisible = false;
88166
- this._useRotationAdjustment = false;
88167
- this._wireVisible = false;
88168
- this._axisVisible = false;
88169
- this._xAxisVisible = false;
88170
- this._yAxisVisible = false;
88171
- this._zAxisVisible = false;
88172
- this._axisEnabled = true;
88173
- this._xLabelEnabled = false;
88174
- this._yLabelEnabled = false;
88175
- this._zLabelEnabled = false;
88176
- this._lengthLabelEnabled = false;
88177
- this._labelsVisible = false;
88178
- this._labelsOnWires = false;
88179
- this._clickable = false;
88180
-
88181
- this._originDot.on("worldPos", (value) => {
88182
- this._originWorld.set(value || [0,0,0]);
88183
- this._wpDirty = true;
88184
- this._needUpdate(0); // No lag
88185
- });
88225
+ const setWireCoordinates = (xEnd, zStart) => {
88186
88226
 
88187
- this._targetDot.on("worldPos", (value) => {
88188
- this._targetWorld.set(value || [0,0,0]);
88189
- this._wpDirty = true;
88190
- this._needUpdate(0); // No lag
88191
- });
88227
+ const metrics = this.plugin.viewer.scene.metrics;
88228
+ const scale = metrics.scale;
88229
+ const unit = metrics.unitsInfo[metrics.units].abbrev;
88192
88230
 
88193
- this._onViewMatrix = scene.camera.on("viewMatrix", () => {
88194
- this._vpDirty = true;
88195
- this._needUpdate(0); // No lag
88196
- });
88231
+ const setAxisLabelCoords = (label, a, b, offsetIdx) => {
88232
+ if (this._labelsOnWires.get()) {
88233
+ label.setPosOnWire(a, b, 0, this.plugin.labelMinAxisLength);
88234
+ } else {
88235
+ label.setPosOnWire(p0, p1, offsetIdx * 35, 0);
88236
+ }
88237
+ };
88238
+ const unitStr = len => (this._approximate ? " ~ " : " = ") + len.toFixed(2) + unit;
88197
88239
 
88198
- this._onProjMatrix = scene.camera.on("projMatrix", () => {
88199
- this._cpDirty = true;
88200
- this._needUpdate();
88201
- });
88240
+ this._xAxisWire.setEnds(p0, xEnd);
88241
+ setAxisLabelCoords(this._xAxisLabel, p0, xEnd, 1);
88242
+ this._xAxisLabel.setText("X" + unitStr(math.distVec3(p0, xEnd) * scale));
88202
88243
 
88203
- this._onCanvasBoundary = scene.canvas.on("boundary", () => {
88204
- this._cpDirty = true;
88205
- this._needUpdate(0); // No lag
88206
- });
88244
+ this._yAxisWire.setEnds(xEnd, zStart);
88245
+ setAxisLabelCoords(this._yAxisLabel, xEnd, zStart, 2);
88246
+ this._yAxisLabel.setText("Y" + unitStr(math.distVec3(xEnd, zStart) * scale));
88207
88247
 
88208
- this._onMetricsUnits = scene.metrics.on("units", () => {
88209
- this._cpDirty = true;
88210
- this._needUpdate();
88211
- });
88248
+ this._zAxisWire.setEnds(zStart, p1);
88249
+ setAxisLabelCoords(this._zAxisLabel, zStart, p1, 3);
88250
+ this._zAxisLabel.setText((measurementOrientationVertical ? "" : "Z") + unitStr(math.distVec3(zStart, p1) * scale));
88212
88251
 
88213
- this._onMetricsScale = scene.metrics.on("scale", () => {
88214
- this._cpDirty = true;
88215
- this._needUpdate();
88216
- });
88252
+ this._lengthWire.setEnds(p0, p1);
88253
+ setAxisLabelCoords(this._lengthLabel, p0, p1, 0);
88254
+ this._length = math.distVec3(p0, p1) * scale;
88255
+ this._lengthLabel.setText(unitStr(this._length));
88256
+ };
88217
88257
 
88218
- this._onMetricsOrigin = scene.metrics.on("origin", () => {
88219
- this._cpDirty = true;
88220
- this._needUpdate();
88221
- });
88258
+ if (measurementOrientationVertical) {
88259
+ tmpVec3c[0] = p0[0];
88260
+ tmpVec3c[1] = p1[1];
88261
+ tmpVec3c[2] = p0[2];
88222
88262
 
88223
- this._onSectionPlaneUpdated = scene.on("sectionPlaneUpdated", () =>{
88224
- this._sectionPlanesDirty = true;
88225
- this._needUpdate();
88226
- });
88263
+ setWireCoordinates(p0, tmpVec3c);
88264
+ }
88265
+ else {
88266
+ tmpVec3b[0] = p0[0] + axesBasis[0] * factors[0];
88267
+ tmpVec3b[1] = p0[1] + axesBasis[4] * factors[0];
88268
+ tmpVec3b[2] = p0[2] + axesBasis[8] * factors[0];
88227
88269
 
88228
- this.approximate = cfg.approximate;
88229
- this.visible = cfg.visible;
88230
- this.originVisible = cfg.originVisible;
88231
- this.targetVisible = cfg.targetVisible;
88232
- this.wireVisible = cfg.wireVisible;
88233
- this.axisVisible = cfg.axisVisible;
88234
- this.xAxisVisible = cfg.xAxisVisible;
88235
- this.yAxisVisible = cfg.yAxisVisible;
88236
- this.zAxisVisible = cfg.zAxisVisible;
88237
- this.xLabelEnabled = cfg.xLabelEnabled;
88238
- this.yLabelEnabled = cfg.yLabelEnabled;
88239
- this.zLabelEnabled = cfg.zLabelEnabled;
88240
- this.lengthLabelEnabled = cfg.lengthLabelEnabled;
88241
- this.labelsVisible = cfg.labelsVisible;
88242
- this.labelsOnWires = cfg.labelsOnWires;
88243
- this._useRotationAdjustment = cfg.useRotationAdjustment;
88270
+ tmpVec3c[0] = tmpVec3b[0] + axesBasis[1] * factors[1];
88271
+ tmpVec3c[1] = tmpVec3b[1] + axesBasis[5] * factors[1];
88272
+ tmpVec3c[2] = tmpVec3b[2] + axesBasis[9] * factors[1];
88244
88273
 
88245
- /**
88246
- * @type {number[]}
88247
- */
88248
- this._axesBasis = [
88249
- 1, 0, 0, 0,
88250
- 0, 1, 0, 0,
88251
- 0, 0, 1, 0,
88252
- 0, 0, 0, 1,
88253
- ];
88274
+ setWireCoordinates(tmpVec3b, tmpVec3c);
88275
+ }
88254
88276
  }
88255
88277
 
88256
88278
  /**
88257
88279
  * Sets the axes basis for the measurement.
88258
- *
88280
+ *
88259
88281
  * The value is a 4x4 matrix where each column-vector defines an axis and must have unit length.
88260
- *
88282
+ *
88261
88283
  * This is the ```identity``` matrix by default, meaning the measurement axes are the same as the world axes.
88262
- *
88263
- * @param {number[]} value
88284
+ *
88285
+ * @param {number[]} value
88264
88286
  */
88265
88287
  set axesBasis(value) {
88266
- this._axesBasis = value.slice();
88267
- this._wpDirty = true;
88268
- this._needUpdate(0); // No lag
88288
+ this._axesBasis.set(value);
88289
+ this._update();
88269
88290
  }
88270
88291
 
88271
88292
  /**
88272
88293
  * Gets the axes basis for the measurement.
88273
- *
88294
+ *
88274
88295
  * The value is a 4x4 matrix where each column-vector defines an axis and must have unit length.
88275
- *
88296
+ *
88276
88297
  * This is the ```identity``` matrix by default, meaning the measurement axes are the same as the world axes.
88277
- *
88298
+ *
88278
88299
  * @type {number[]}
88279
88300
  */
88280
88301
  get axesBasis() {
88281
88302
  return this._axesBasis;
88282
88303
  }
88283
88304
 
88284
- _update() {
88285
-
88286
- if (!this._visible) {
88287
- return;
88288
- }
88289
-
88290
- const scene = this.plugin.viewer.scene;
88291
-
88292
- if (this._wpDirty) {
88293
- const delta = math.subVec3(
88294
- this._targetWorld,
88295
- this._originWorld,
88296
- tmpVec3
88297
- );
88298
-
88299
- /**
88300
- * The length detected for each measurement axis.
88301
- */
88302
- this._factors = math.transformVec3(this._axesBasis, delta);
88303
-
88304
- this._measurementOrientation = determineMeasurementOrientation(this._originWorld, this._targetWorld, 0);
88305
- if (this._measurementOrientation === 'Vertical' && this._useRotationAdjustment) {
88306
- this._wp[0] = this._originWorld[0];
88307
- this._wp[1] = this._originWorld[1];
88308
- this._wp[2] = this._originWorld[2];
88309
- this._wp[3] = 1.0;
88310
-
88311
- this._wp[4] = this._originWorld[0]; //x-axis
88312
- this._wp[5] = this._originWorld[1];
88313
- this._wp[6] = this._originWorld[2];
88314
- this._wp[7] = 1.0;
88315
-
88316
- this._wp[8] = this._originWorld[0]; //x-axis
88317
- this._wp[9] = this._targetWorld[1]; //y-axis
88318
- this._wp[10] = this._originWorld[2];
88319
- this._wp[11] = 1.0;
88320
-
88321
- this._wp[12] = this._targetWorld[0];
88322
- this._wp[13] = this._targetWorld[1];
88323
- this._wp[14] = this._targetWorld[2];
88324
- this._wp[15] = 1.0;
88325
- }
88326
- else {
88327
-
88328
- this._wp[0] = this._originWorld[0];
88329
- this._wp[1] = this._originWorld[1];
88330
- this._wp[2] = this._originWorld[2];
88331
- this._wp[3] = 1.0;
88332
-
88333
- this._wp[4] = this._originWorld[0] + this._axesBasis[0]*this._factors[0];
88334
- this._wp[5] = this._originWorld[1] + this._axesBasis[4]*this._factors[0];
88335
- this._wp[6] = this._originWorld[2] + this._axesBasis[8]*this._factors[0];
88336
- this._wp[7] = 1.0;
88337
-
88338
- this._wp[8] = this._originWorld[0] + this._axesBasis[0]*this._factors[0]+ this._axesBasis[1]*this._factors[1];
88339
- this._wp[9] = this._originWorld[1] + this._axesBasis[4]*this._factors[0]+ this._axesBasis[5]*this._factors[1];
88340
- this._wp[10] = this._originWorld[2] + this._axesBasis[8]*this._factors[0]+ this._axesBasis[9]*this._factors[1]; this._wp[11] = 1.0;
88341
-
88342
- this._wp[12] = this._targetWorld[0];
88343
- this._wp[13] = this._targetWorld[1];
88344
- this._wp[14] = this._targetWorld[2];
88345
- this._wp[15] = 1.0;
88346
- }
88347
-
88348
-
88349
- this._wpDirty = false;
88350
- this._vpDirty = true;
88351
- }
88352
-
88353
- if (this._vpDirty) {
88354
-
88355
- math.transformPositions4(scene.camera.viewMatrix, this._wp, this._vp);
88356
-
88357
- this._vp[3] = 1.0;
88358
- this._vp[7] = 1.0;
88359
- this._vp[11] = 1.0;
88360
- this._vp[15] = 1.0;
88361
-
88362
- this._vpDirty = false;
88363
- this._cpDirty = true;
88364
- }
88365
-
88366
- if (this._sectionPlanesDirty) {
88367
-
88368
- if (this._isSliced(this._originWorld) || this._isSliced(this._targetWorld)) {
88369
- this._xAxisLabel.setCulled(true);
88370
- this._yAxisLabel.setCulled(true);
88371
- this._zAxisLabel.setCulled(true);
88372
- this._lengthLabel.setCulled(true);
88373
- this._xAxisWire.setCulled(true);
88374
- this._yAxisWire.setCulled(true);
88375
- this._zAxisWire.setCulled(true);
88376
- this._lengthWire.setCulled(true);
88377
- this._originDot.setCulled(true);
88378
- this._targetDot.setCulled(true);
88379
- return;
88380
- } else {
88381
- this._xAxisLabel.setCulled(false);
88382
- this._yAxisLabel.setCulled(false);
88383
- this._zAxisLabel.setCulled(false);
88384
- this._lengthLabel.setCulled(false);
88385
- this._xAxisWire.setCulled(false);
88386
- this._yAxisWire.setCulled(false);
88387
- this._zAxisWire.setCulled(false);
88388
- this._lengthWire.setCulled(false);
88389
- this._originDot.setCulled(false);
88390
- this._targetDot.setCulled(false);
88391
- }
88392
-
88393
- this._sectionPlanesDirty = true;
88394
- }
88395
-
88396
- const near = -0.3;
88397
- const vpz1 = this._originDot.viewPos[2];
88398
- const vpz2 = this._targetDot.viewPos[2];
88399
-
88400
- if (vpz1 > near || vpz2 > near) {
88401
-
88402
- this._xAxisLabel.setCulled(true);
88403
- this._yAxisLabel.setCulled(true);
88404
- this._zAxisLabel.setCulled(true);
88405
- this._lengthLabel.setCulled(true);
88406
-
88407
- this._xAxisWire.setVisible(false);
88408
- this._yAxisWire.setVisible(false);
88409
- this._zAxisWire.setVisible(false);
88410
- this._lengthWire.setVisible(false);
88411
-
88412
- this._originDot.setVisible(false);
88413
- this._targetDot.setVisible(false);
88414
-
88415
- return;
88416
- }
88417
-
88418
- if (this._cpDirty) {
88419
-
88420
- math.transformPositions4(scene.camera.project.matrix, this._vp, this._pp);
88421
-
88422
- var pp = this._pp;
88423
- var cp = this._cp;
88424
-
88425
- var canvas = scene.canvas.canvas;
88426
- var offsets = canvas.getBoundingClientRect();
88427
- const containerOffsets = this._container.getBoundingClientRect();
88428
- var top = offsets.top - containerOffsets.top;
88429
- var left = offsets.left - containerOffsets.left;
88430
- var aabb = scene.canvas.boundary;
88431
- var canvasWidth = aabb[2];
88432
- var canvasHeight = aabb[3];
88433
- var j = 0;
88434
-
88435
- const metrics = this.plugin.viewer.scene.metrics;
88436
- const scale = metrics.scale;
88437
- const units = metrics.units;
88438
- const unitInfo = metrics.unitsInfo[units];
88439
- const unitAbbrev = unitInfo.abbrev;
88440
-
88441
- for (var i = 0, len = pp.length; i < len; i += 4) {
88442
- cp[j] = left + Math.floor((1 + pp[i + 0] / pp[i + 3]) * canvasWidth / 2);
88443
- cp[j + 1] = top + Math.floor((1 - pp[i + 1] / pp[i + 3]) * canvasHeight / 2);
88444
- j += 2;
88445
- }
88446
-
88447
- this._lengthWire.setStartAndEnd(cp[0], cp[1], cp[6], cp[7]);
88448
-
88449
- this._xAxisWire.setStartAndEnd(cp[0], cp[1], cp[2], cp[3]);
88450
- this._yAxisWire.setStartAndEnd(cp[2], cp[3], cp[4], cp[5]);
88451
- this._zAxisWire.setStartAndEnd(cp[4], cp[5], cp[6], cp[7]);
88452
-
88453
- if (!this.labelsVisible) {
88454
-
88455
- this._lengthLabel.setCulled(true);
88456
-
88457
- this._xAxisLabel.setCulled(true);
88458
- this._yAxisLabel.setCulled(true);
88459
- this._zAxisLabel.setCulled(true);
88460
-
88461
- } else {
88462
-
88463
- this._lengthLabel.setPosOnWire(cp[0], cp[1], cp[6], cp[7]);
88464
-
88465
- if (this.labelsOnWires) {
88466
- this._xAxisLabel.setPosOnWire(cp[0], cp[1], cp[2], cp[3]);
88467
- this._yAxisLabel.setPosOnWire(cp[2], cp[3], cp[4], cp[5]);
88468
- this._zAxisLabel.setPosOnWire(cp[4], cp[5], cp[6], cp[7]);
88469
- } else {
88470
- const labelOffset = 35;
88471
- let currentLabelOffset = labelOffset;
88472
- this._xAxisLabel.setPosOnWire(cp[0], cp[1] + currentLabelOffset, cp[6], cp[7] + currentLabelOffset);
88473
- currentLabelOffset += labelOffset;
88474
- this._yAxisLabel.setPosOnWire(cp[0], cp[1] + currentLabelOffset, cp[6], cp[7] + currentLabelOffset);
88475
- currentLabelOffset += labelOffset;
88476
- this._zAxisLabel.setPosOnWire(cp[0], cp[1] + currentLabelOffset, cp[6], cp[7] + currentLabelOffset);
88477
- }
88478
-
88479
- const tilde = this._approximate ? " ~ " : " = ";
88480
-
88481
- this._length = Math.abs(math.lenVec3(math.subVec3(this._targetWorld, this._originWorld, distVec3)));
88482
- this._lengthLabel.setText(tilde + (this._length * scale).toFixed(2) + unitAbbrev);
88483
-
88484
- const xAxisCanvasLength = Math.abs(lengthWire(cp[0], cp[1], cp[2], cp[3]));
88485
- const yAxisCanvasLength = Math.abs(lengthWire(cp[2], cp[3], cp[4], cp[5]));
88486
- const zAxisCanvasLength = Math.abs(lengthWire(cp[4], cp[5], cp[6], cp[7]));
88487
-
88488
- const labelMinAxisLength = this.plugin.labelMinAxisLength;
88489
-
88490
- if (this.labelsOnWires){
88491
- this._xAxisLabelCulled = (xAxisCanvasLength < labelMinAxisLength);
88492
- this._yAxisLabelCulled = (yAxisCanvasLength < labelMinAxisLength);
88493
- this._zAxisLabelCulled = (zAxisCanvasLength < labelMinAxisLength);
88494
- } else {
88495
- this._xAxisLabelCulled = false;
88496
- this._yAxisLabelCulled = false;
88497
- this._zAxisLabelCulled = false;
88498
- }
88499
-
88500
- if (!this._xAxisLabelCulled) {
88501
- this._xAxisLabel.setText(tilde + Math.abs(this._factors[0] * scale).toFixed(2) + unitAbbrev);
88502
- this._xAxisLabel.setCulled(!this.axisVisible);
88503
- } else {
88504
- this._xAxisLabel.setCulled(true);
88505
- }
88506
-
88507
- if (!this._yAxisLabelCulled) {
88508
- this._yAxisLabel.setText(tilde + Math.abs(this._factors[1] * scale).toFixed(2) + unitAbbrev);
88509
- this._yAxisLabel.setCulled(!this.axisVisible);
88510
- } else {
88511
- this._yAxisLabel.setCulled(true);
88512
- }
88513
-
88514
- if (!this._zAxisLabelCulled) {
88515
- if (this._measurementOrientation === 'Vertical' && this._useRotationAdjustment) {
88516
- this._zAxisLabel.setPrefix("");
88517
- this._zAxisLabel.setText(tilde + Math.abs(math.lenVec3(math.subVec3(this._targetWorld, [this._originWorld[0], this._targetWorld[1], this._originWorld[2]], distVec3)) * scale).toFixed(2) + unitAbbrev);
88518
- }
88519
- else {
88520
- this._zAxisLabel.setPrefix("Z");
88521
- this._zAxisLabel.setText(tilde + Math.abs(this._factors[2] * scale).toFixed(2) + unitAbbrev);
88522
- }
88523
- this._zAxisLabel.setCulled(!this.axisVisible);
88524
- } else {
88525
- this._zAxisLabel.setCulled(true);
88526
- }
88527
- }
88528
-
88529
- // this._xAxisLabel.setVisible(this.axisVisible && this.xAxisVisible);
88530
- // this._yAxisLabel.setVisible(this.axisVisible && this.yAxisVisible);
88531
- // this._zAxisLabel.setVisible(this.axisVisible && this.zAxisVisible);
88532
- // this._lengthLabel.setVisible(false);
88533
-
88534
- this._originDot.setVisible(this._visible && this._originVisible);
88535
- this._targetDot.setVisible(this._visible && this._targetVisible);
88536
-
88537
- this._xAxisWire.setVisible(this.axisVisible && this.xAxisVisible);
88538
- this._yAxisWire.setVisible(this.axisVisible && this.yAxisVisible);
88539
- this._zAxisWire.setVisible(this.axisVisible && this.zAxisVisible);
88540
-
88541
- this._lengthWire.setVisible(this.wireVisible);
88542
- this._lengthLabel.setCulled(!this.wireVisible);
88543
-
88544
- this._cpDirty = false;
88545
- }
88546
- }
88547
-
88548
- _isSliced(positions) {
88549
- const sectionPlanes = this.scene._sectionPlanesState.sectionPlanes;
88550
- for (let i = 0, len = sectionPlanes.length; i < len; i++) {
88551
- const sectionPlane = sectionPlanes[i];
88552
- if (math.planeClipsPositions3(sectionPlane.pos, sectionPlane.dir, positions, 4)) {
88553
- return true
88554
- }
88555
- }
88556
- return false;
88557
- }
88558
-
88559
88305
  /**
88560
88306
  * Sets whether this DistanceMeasurement indicates that its measurement is approximate.
88561
88307
  *
@@ -88569,8 +88315,7 @@ class DistanceMeasurement extends Component {
88569
88315
  return;
88570
88316
  }
88571
88317
  this._approximate = approximate;
88572
- this._cpDirty = true;
88573
- this._needUpdate(0);
88318
+ this._update();
88574
88319
  }
88575
88320
 
88576
88321
  /**
@@ -88608,9 +88353,7 @@ class DistanceMeasurement extends Component {
88608
88353
  * @type {Number}
88609
88354
  */
88610
88355
  get length() {
88611
- this._update();
88612
- const scale = this.plugin.viewer.scene.metrics.scale;
88613
- return this._length * scale;
88356
+ return this._length;
88614
88357
  }
88615
88358
 
88616
88359
  get color() {
@@ -88631,31 +88374,7 @@ class DistanceMeasurement extends Component {
88631
88374
  * @type {Boolean}
88632
88375
  */
88633
88376
  set visible(value) {
88634
-
88635
- value = value !== undefined ? Boolean(value) : this.plugin.defaultVisible;
88636
-
88637
- this._visible = value;
88638
-
88639
- this._originDot.setVisible(this._visible && this._originVisible);
88640
- this._targetDot.setVisible(this._visible && this._targetVisible);
88641
- this._lengthWire.setVisible(this._visible && this._wireVisible);
88642
- this._lengthLabel.setVisible(this._visible && this._wireVisible && this._lengthLabelEnabled);
88643
-
88644
- const xAxisVisible = this._visible && this._axisVisible && this._xAxisVisible;
88645
- const yAxisVisible = this._visible && this._axisVisible && this._yAxisVisible;
88646
- const zAxisVisible = this._visible && this._axisVisible && this._zAxisVisible;
88647
-
88648
- this._xAxisWire.setVisible(xAxisVisible);
88649
- this._yAxisWire.setVisible(yAxisVisible);
88650
- this._zAxisWire.setVisible(zAxisVisible);
88651
-
88652
- this._xAxisLabel.setVisible(xAxisVisible && !this._xAxisLabelCulled && this._EnabledVisible);
88653
- this._yAxisLabel.setVisible(yAxisVisible && !this._yAxisLabelCulled && this._yLabelEnabled);
88654
- this._zAxisLabel.setVisible(zAxisVisible && !this._zAxisLabelCulled && this._zLabelEnabled);
88655
-
88656
- this._cpDirty = true;
88657
-
88658
- this._needUpdate();
88377
+ this._visible.set(value);
88659
88378
  }
88660
88379
 
88661
88380
  /**
@@ -88664,7 +88383,7 @@ class DistanceMeasurement extends Component {
88664
88383
  * @type {Boolean}
88665
88384
  */
88666
88385
  get visible() {
88667
- return this._visible;
88386
+ return this._visible.get();
88668
88387
  }
88669
88388
 
88670
88389
  /**
@@ -88673,9 +88392,7 @@ class DistanceMeasurement extends Component {
88673
88392
  * @type {Boolean}
88674
88393
  */
88675
88394
  set originVisible(value) {
88676
- value = value !== undefined ? Boolean(value) : this.plugin.defaultOriginVisible;
88677
- this._originVisible = value;
88678
- this._originDot.setVisible(this._visible && this._originVisible);
88395
+ this._originVisible.set(value);
88679
88396
  }
88680
88397
 
88681
88398
  /**
@@ -88684,7 +88401,7 @@ class DistanceMeasurement extends Component {
88684
88401
  * @type {Boolean}
88685
88402
  */
88686
88403
  get originVisible() {
88687
- return this._originVisible;
88404
+ return this._originVisible.get();
88688
88405
  }
88689
88406
 
88690
88407
  /**
@@ -88693,9 +88410,7 @@ class DistanceMeasurement extends Component {
88693
88410
  * @type {Boolean}
88694
88411
  */
88695
88412
  set targetVisible(value) {
88696
- value = value !== undefined ? Boolean(value) : this.plugin.defaultTargetVisible;
88697
- this._targetVisible = value;
88698
- this._targetDot.setVisible(this._visible && this._targetVisible);
88413
+ this._targetVisible.set(value);
88699
88414
  }
88700
88415
 
88701
88416
  /**
@@ -88704,7 +88419,7 @@ class DistanceMeasurement extends Component {
88704
88419
  * @type {Boolean}
88705
88420
  */
88706
88421
  get targetVisible() {
88707
- return this._targetVisible;
88422
+ return this._targetVisible.get();
88708
88423
  }
88709
88424
 
88710
88425
  /**
@@ -88713,8 +88428,8 @@ class DistanceMeasurement extends Component {
88713
88428
  * @type {Boolean}
88714
88429
  */
88715
88430
  set useRotationAdjustment(value) {
88716
- value = value !== undefined ? Boolean(value) : this.plugin.useRotationAdjustment;
88717
- this._useRotationAdjustment = value;
88431
+ this._useRotationAdjustment.set(value);
88432
+ this._update();
88718
88433
  }
88719
88434
 
88720
88435
  /**
@@ -88723,7 +88438,7 @@ class DistanceMeasurement extends Component {
88723
88438
  * @type {Boolean}
88724
88439
  */
88725
88440
  get useRotationAdjustment() {
88726
- return this._useRotationAdjustment;
88441
+ return this._useRotationAdjustment.get();
88727
88442
  }
88728
88443
 
88729
88444
  /**
@@ -88734,17 +88449,7 @@ class DistanceMeasurement extends Component {
88734
88449
  * @type {Boolean}
88735
88450
  */
88736
88451
  set axisEnabled(value) {
88737
- value = value !== undefined ? Boolean(value) : this.plugin.defaultAxisVisible;
88738
- this._axisEnabled = value;
88739
- var axisVisible = this._visible && this._axisVisible && this._axisEnabled;
88740
- this._xAxisWire.setVisible(axisVisible && this._xAxisVisible);
88741
- this._yAxisWire.setVisible(axisVisible && this._yAxisVisible);
88742
- this._zAxisWire.setVisible(axisVisible && this._zAxisVisible);
88743
- this._xAxisLabel.setVisible(axisVisible && !this._xAxisLabelCulled&& this._xAxisVisible && this._xLabelEnabled);
88744
- this._yAxisLabel.setVisible(axisVisible && !this._yAxisLabelCulled&& this._xAxisVisible && this._yLabelEnabled);
88745
- this._zAxisLabel.setVisible(axisVisible && !this._zAxisLabelCulled&& this._xAxisVisible && this._zLabelEnabled);
88746
- this._cpDirty = true;
88747
- this._needUpdate();
88452
+ this._axisEnabled.set(value);
88748
88453
  }
88749
88454
 
88750
88455
  /**
@@ -88755,7 +88460,7 @@ class DistanceMeasurement extends Component {
88755
88460
  * @type {Boolean}
88756
88461
  */
88757
88462
  get axisEnabled() {
88758
- return this._axisEnabled;
88463
+ return this._axisEnabled.get();
88759
88464
  }
88760
88465
 
88761
88466
  /**
@@ -88766,17 +88471,7 @@ class DistanceMeasurement extends Component {
88766
88471
  * @type {Boolean}
88767
88472
  */
88768
88473
  set axisVisible(value) {
88769
- value = value !== undefined ? Boolean(value) : this.plugin.defaultAxisVisible;
88770
- this._axisVisible = value;
88771
- var axisVisible = this._visible && this._axisVisible && this._axisEnabled;
88772
- this._xAxisWire.setVisible(axisVisible && this._xAxisVisible);
88773
- this._yAxisWire.setVisible(axisVisible && this._yAxisVisible);
88774
- this._zAxisWire.setVisible(axisVisible && this._zAxisVisible);
88775
- this._xAxisLabel.setVisible(axisVisible && !this._xAxisLabelCulled&& this._xAxisVisible);
88776
- this._yAxisLabel.setVisible(axisVisible && !this._yAxisLabelCulled&& this._yAxisVisible);
88777
- this._zAxisLabel.setVisible(axisVisible && !this._zAxisLabelCulled&& this._zAxisVisible);
88778
- this._cpDirty = true;
88779
- this._needUpdate();
88474
+ this._axisVisible.set(value);
88780
88475
  }
88781
88476
 
88782
88477
  /**
@@ -88787,7 +88482,7 @@ class DistanceMeasurement extends Component {
88787
88482
  * @type {Boolean}
88788
88483
  */
88789
88484
  get axisVisible() {
88790
- return this._axisVisible;
88485
+ return this._axisVisible.get();
88791
88486
  }
88792
88487
 
88793
88488
  /**
@@ -88798,13 +88493,7 @@ class DistanceMeasurement extends Component {
88798
88493
  * @type {Boolean}
88799
88494
  */
88800
88495
  set xAxisVisible(value) {
88801
- value = value !== undefined ? Boolean(value) : this.plugin.defaultAxisVisible;
88802
- this._xAxisVisible = value;
88803
- const axisVisible = this._visible && this._axisVisible && this._xAxisVisible && this._axisEnabled;
88804
- this._xAxisWire.setVisible(axisVisible);
88805
- this._xAxisLabel.setVisible(axisVisible && !this._xAxisLabelCulled && this._xLabelEnabled);
88806
- this._cpDirty = true;
88807
- this._needUpdate();
88496
+ this._xAxisVisible.set(value);
88808
88497
  }
88809
88498
 
88810
88499
  /**
@@ -88815,7 +88504,7 @@ class DistanceMeasurement extends Component {
88815
88504
  * @type {Boolean}
88816
88505
  */
88817
88506
  get xAxisVisible() {
88818
- return this._xAxisVisible;
88507
+ return this._xAxisVisible.get();
88819
88508
  }
88820
88509
 
88821
88510
  /**
@@ -88826,13 +88515,7 @@ class DistanceMeasurement extends Component {
88826
88515
  * @type {Boolean}
88827
88516
  */
88828
88517
  set yAxisVisible(value) {
88829
- value = value !== undefined ? Boolean(value) : this.plugin.defaultAxisVisible;
88830
- this._yAxisVisible = value;
88831
- const axisVisible = this._visible && this._axisVisible && this._yAxisVisible && this._axisEnabled;
88832
- this._yAxisWire.setVisible(axisVisible);
88833
- this._yAxisLabel.setVisible(axisVisible && !this._yAxisLabelCulled && this._yLabelEnabled);
88834
- this._cpDirty = true;
88835
- this._needUpdate();
88518
+ this._yAxisVisible.set(value);
88836
88519
  }
88837
88520
 
88838
88521
  /**
@@ -88843,7 +88526,7 @@ class DistanceMeasurement extends Component {
88843
88526
  * @type {Boolean}
88844
88527
  */
88845
88528
  get yAxisVisible() {
88846
- return this._yAxisVisible;
88529
+ return this._yAxisVisible.get();
88847
88530
  }
88848
88531
 
88849
88532
  /**
@@ -88854,13 +88537,7 @@ class DistanceMeasurement extends Component {
88854
88537
  * @type {Boolean}
88855
88538
  */
88856
88539
  set zAxisVisible(value) {
88857
- value = value !== undefined ? Boolean(value) : this.plugin.defaultAxisVisible;
88858
- this._zAxisVisible = value;
88859
- const axisVisible = this._visible && this._axisVisible && this._zAxisVisible && this._axisEnabled;
88860
- this._zAxisWire.setVisible(axisVisible);
88861
- this._zAxisLabel.setVisible(axisVisible && !this._zAxisLabelCulled && this._zLabelEnabled);
88862
- this._cpDirty = true;
88863
- this._needUpdate();
88540
+ this._zAxisVisible.set(value);
88864
88541
  }
88865
88542
 
88866
88543
  /**
@@ -88871,7 +88548,7 @@ class DistanceMeasurement extends Component {
88871
88548
  * @type {Boolean}
88872
88549
  */
88873
88550
  get zAxisVisible() {
88874
- return this._zAxisVisible;
88551
+ return this._zAxisVisible.get();
88875
88552
  }
88876
88553
 
88877
88554
  /**
@@ -88880,11 +88557,7 @@ class DistanceMeasurement extends Component {
88880
88557
  * @type {Boolean}
88881
88558
  */
88882
88559
  set wireVisible(value) {
88883
- value = value !== undefined ? Boolean(value) : this.plugin.defaultWireVisible;
88884
- this._wireVisible = value;
88885
- var wireVisible = this._visible && this._wireVisible;
88886
- this._lengthLabel.setVisible(wireVisible && this._lengthLabelEnabled);
88887
- this._lengthWire.setVisible(wireVisible);
88560
+ this._wireVisible.set(value);
88888
88561
  }
88889
88562
 
88890
88563
  /**
@@ -88893,7 +88566,7 @@ class DistanceMeasurement extends Component {
88893
88566
  * @type {Boolean}
88894
88567
  */
88895
88568
  get wireVisible() {
88896
- return this._wireVisible;
88569
+ return this._wireVisible.get();
88897
88570
  }
88898
88571
 
88899
88572
  /**
@@ -88902,15 +88575,7 @@ class DistanceMeasurement extends Component {
88902
88575
  * @type {Boolean}
88903
88576
  */
88904
88577
  set labelsVisible(value) {
88905
- value = value !== undefined ? Boolean(value) : this.plugin.defaultLabelsVisible;
88906
- this._labelsVisible = value;
88907
- var labelsVisible = this._visible && this._labelsVisible;
88908
- this._xAxisLabel.setVisible(labelsVisible && !this._xAxisLabelCulled && this._clickable && this._axisEnabled && this._xLabelEnabled);
88909
- this._yAxisLabel.setVisible(labelsVisible && !this._yAxisLabelCulled && this._clickable && this._axisEnabled && this._yLabelEnabled);
88910
- this._zAxisLabel.setVisible(labelsVisible && !this._zAxisLabelCulled && this._clickable && this._axisEnabled && this._zLabelEnabled);
88911
- this._lengthLabel.setVisible(labelsVisible && this._lengthLabelEnabled);
88912
- this._cpDirty = true;
88913
- this._needUpdate();
88578
+ this._labelsVisible.set(value);
88914
88579
  }
88915
88580
 
88916
88581
  /**
@@ -88919,7 +88584,7 @@ class DistanceMeasurement extends Component {
88919
88584
  * @type {Boolean}
88920
88585
  */
88921
88586
  get labelsVisible() {
88922
- return this._labelsVisible;
88587
+ return this._labelsVisible.get();
88923
88588
  }
88924
88589
 
88925
88590
  /**
@@ -88928,12 +88593,7 @@ class DistanceMeasurement extends Component {
88928
88593
  * @type {Boolean}
88929
88594
  */
88930
88595
  set xLabelEnabled(value) {
88931
- value = value !== undefined ? Boolean(value) : this.plugin.defaultXLabelEnabled;
88932
- this._xLabelEnabled = value;
88933
- var labelsVisible = this._visible && this._labelsVisible;
88934
- this._xAxisLabel.setVisible(labelsVisible && !this._xAxisLabelCulled && this._clickable && this._axisEnabled && this._xLabelEnabled);
88935
- this._cpDirty = true;
88936
- this._needUpdate();
88596
+ this._xLabelEnabled.set(value);
88937
88597
  }
88938
88598
 
88939
88599
  /**
@@ -88942,7 +88602,7 @@ class DistanceMeasurement extends Component {
88942
88602
  * @type {Boolean}
88943
88603
  */
88944
88604
  get xLabelEnabled(){
88945
- return this._xLabelEnabled;
88605
+ return this._xLabelEnabled.get();
88946
88606
  }
88947
88607
 
88948
88608
  /**
@@ -88951,12 +88611,7 @@ class DistanceMeasurement extends Component {
88951
88611
  * @type {Boolean}
88952
88612
  */
88953
88613
  set yLabelEnabled(value) {
88954
- value = value !== undefined ? Boolean(value) : this.plugin.defaultYLabelEnabled;
88955
- this._yLabelEnabled = value;
88956
- var labelsVisible = this._visible && this._labelsVisible;
88957
- this._yAxisLabel.setVisible(labelsVisible && !this._yAxisLabelCulled && this._clickable && this._axisEnabled && this._yLabelEnabled);
88958
- this._cpDirty = true;
88959
- this._needUpdate();
88614
+ this._yLabelEnabled.set(value);
88960
88615
  }
88961
88616
 
88962
88617
  /**
@@ -88965,7 +88620,7 @@ class DistanceMeasurement extends Component {
88965
88620
  * @type {Boolean}
88966
88621
  */
88967
88622
  get yLabelEnabled(){
88968
- return this._yLabelEnabled;
88623
+ return this._yLabelEnabled.get();
88969
88624
  }
88970
88625
 
88971
88626
  /**
@@ -88974,12 +88629,7 @@ class DistanceMeasurement extends Component {
88974
88629
  * @type {Boolean}
88975
88630
  */
88976
88631
  set zLabelEnabled(value) {
88977
- value = value !== undefined ? Boolean(value) : this.plugin.defaultZLabelEnabled;
88978
- this._zLabelEnabled = value;
88979
- var labelsVisible = this._visible && this._labelsVisible;
88980
- this._zAxisLabel.setVisible(labelsVisible && !this._zAxisLabelCulled && this._clickable && this._axisEnabled && this._zLabelEnabled);
88981
- this._cpDirty = true;
88982
- this._needUpdate();
88632
+ this._zLabelEnabled.set(value);
88983
88633
  }
88984
88634
 
88985
88635
  /**
@@ -88988,7 +88638,7 @@ class DistanceMeasurement extends Component {
88988
88638
  * @type {Boolean}
88989
88639
  */
88990
88640
  get zLabelEnabled(){
88991
- return this._zLabelEnabled;
88641
+ return this._zLabelEnabled.get();
88992
88642
  }
88993
88643
 
88994
88644
  /**
@@ -88997,12 +88647,7 @@ class DistanceMeasurement extends Component {
88997
88647
  * @type {Boolean}
88998
88648
  */
88999
88649
  set lengthLabelEnabled(value) {
89000
- value = value !== undefined ? Boolean(value) : this.plugin.defaultLengthLabelEnabled;
89001
- this._lengthLabelEnabled = value;
89002
- var labelsVisible = this._visible && this._labelsVisible;
89003
- this._lengthLabel.setVisible(labelsVisible && !this._lengthAxisLabelCulled && this._clickable && this._axisEnabled && this._lengthLabelEnabled);
89004
- this._cpDirty = true;
89005
- this._needUpdate();
88650
+ this._lengthLabelEnabled.set(value);
89006
88651
  }
89007
88652
 
89008
88653
  /**
@@ -89011,7 +88656,7 @@ class DistanceMeasurement extends Component {
89011
88656
  * @type {Boolean}
89012
88657
  */
89013
88658
  get lengthLabelEnabled(){
89014
- return this._lengthLabelEnabled;
88659
+ return this._lengthLabelEnabled.get();
89015
88660
  }
89016
88661
 
89017
88662
  /**
@@ -89020,8 +88665,8 @@ class DistanceMeasurement extends Component {
89020
88665
  * @type {Boolean}
89021
88666
  */
89022
88667
  set labelsOnWires(value) {
89023
- value = value !== undefined ? Boolean(value) : this.plugin.defaultLabelsOnWires;
89024
- this._labelsOnWires = value;
88668
+ this._labelsOnWires.set(value);
88669
+ this._update();
89025
88670
  }
89026
88671
 
89027
88672
  /**
@@ -89030,7 +88675,7 @@ class DistanceMeasurement extends Component {
89030
88675
  * @type {Boolean}
89031
88676
  */
89032
88677
  get labelsOnWires() {
89033
- return this._labelsOnWires;
88678
+ return this._labelsOnWires.get();
89034
88679
  }
89035
88680
 
89036
88681
  /**
@@ -89038,16 +88683,7 @@ class DistanceMeasurement extends Component {
89038
88683
  * @param highlighted
89039
88684
  */
89040
88685
  setHighlighted(highlighted) {
89041
- this._originDot.setHighlighted(highlighted);
89042
- this._targetDot.setHighlighted(highlighted);
89043
- this._xAxisWire.setHighlighted(highlighted);
89044
- this._yAxisWire.setHighlighted(highlighted);
89045
- this._zAxisWire.setHighlighted(highlighted);
89046
- this._xAxisLabel.setHighlighted(highlighted);
89047
- this._yAxisLabel.setHighlighted(highlighted);
89048
- this._zAxisLabel.setHighlighted(highlighted);
89049
- this._lengthWire.setHighlighted(highlighted);
89050
- this._lengthLabel.setHighlighted(highlighted);
88686
+ this._drawables.forEach(d => d.setHighlighted(highlighted));
89051
88687
  }
89052
88688
 
89053
88689
  /**
@@ -89056,18 +88692,8 @@ class DistanceMeasurement extends Component {
89056
88692
  * @type {Boolean}
89057
88693
  */
89058
88694
  set clickable(value) {
89059
- value = !!value;
89060
- this._clickable = value;
89061
- this._originDot.setClickable(this._clickable);
89062
- this._targetDot.setClickable(this._clickable);
89063
- this._xAxisWire.setClickable(this._clickable);
89064
- this._yAxisWire.setClickable(this._clickable);
89065
- this._zAxisWire.setClickable(this._clickable);
89066
- this._lengthWire.setClickable(this._clickable);
89067
- this._xAxisLabel.setClickable(this._clickable);
89068
- this._yAxisLabel.setClickable(this._clickable);
89069
- this._zAxisLabel.setClickable(this._clickable);
89070
- this._lengthLabel.setClickable(this._clickable);
88695
+ this._clickable.set(!!value);
88696
+ this._drawables.forEach(d => d.setClickable(this._clickable.get()));
89071
88697
  }
89072
88698
 
89073
88699
  /**
@@ -89076,50 +88702,14 @@ class DistanceMeasurement extends Component {
89076
88702
  * @type {Boolean}
89077
88703
  */
89078
88704
  get clickable() {
89079
- return this._clickable;
88705
+ return this._clickable.get();
89080
88706
  }
89081
88707
 
89082
88708
  /**
89083
88709
  * @private
89084
88710
  */
89085
88711
  destroy() {
89086
-
89087
- const scene = this.plugin.viewer.scene;
89088
- const metrics = scene.metrics;
89089
-
89090
- if (this._onViewMatrix) {
89091
- scene.camera.off(this._onViewMatrix);
89092
- }
89093
- if (this._onProjMatrix) {
89094
- scene.camera.off(this._onProjMatrix);
89095
- }
89096
- if (this._onCanvasBoundary) {
89097
- scene.canvas.off(this._onCanvasBoundary);
89098
- }
89099
- if (this._onMetricsUnits) {
89100
- metrics.off(this._onMetricsUnits);
89101
- }
89102
- if (this._onMetricsScale) {
89103
- metrics.off(this._onMetricsScale);
89104
- }
89105
- if (this._onMetricsOrigin) {
89106
- metrics.off(this._onMetricsOrigin);
89107
- }
89108
- if (this._onSectionPlaneUpdated) {
89109
- scene.off(this._onSectionPlaneUpdated);
89110
- }
89111
-
89112
- this._originDot.destroy();
89113
- this._targetDot.destroy();
89114
- this._xAxisWire.destroy();
89115
- this._yAxisWire.destroy();
89116
- this._zAxisWire.destroy();
89117
- this._lengthLabel.destroy();
89118
- this._xAxisLabel.destroy();
89119
- this._yAxisLabel.destroy();
89120
- this._zAxisLabel.destroy();
89121
- this._lengthWire.destroy();
89122
-
88712
+ this._cleanups.forEach(cleanup => cleanup());
89123
88713
  super.destroy();
89124
88714
  }
89125
88715
  }
@@ -97463,7 +97053,6 @@ class MousePanRotateDollyHandler {
97463
97053
  });
97464
97054
 
97465
97055
  function setMousedownState(pick = true) {
97466
- canvas.style.cursor = "move";
97467
97056
  setMousedownPositions();
97468
97057
  if (pick) {
97469
97058
  setMousedownPick();
@@ -97492,7 +97081,7 @@ class MousePanRotateDollyHandler {
97492
97081
  }
97493
97082
 
97494
97083
  function isPanning() {
97495
- return cameraControl._isKeyDownForAction(cameraControl.MOUSE_PAN, keyDown);
97084
+ return configs.planView || cameraControl._isKeyDownForAction(cameraControl.MOUSE_PAN, keyDown);
97496
97085
  }
97497
97086
 
97498
97087
  function isRotating() {
@@ -98254,7 +97843,7 @@ class KeyboardPanRotateDollyHandler {
98254
97843
 
98255
97844
  const keyDownMap = [];
98256
97845
 
98257
- const canvas = scene.canvas.canvas;
97846
+ scene.canvas.canvas;
98258
97847
 
98259
97848
  let mouseMovedSinceLastKeyboardDolly = true;
98260
97849
 
@@ -98270,10 +97859,6 @@ class KeyboardPanRotateDollyHandler {
98270
97859
  return;
98271
97860
  }
98272
97861
  keyDownMap[keyCode] = true;
98273
-
98274
- if (keyCode === input.KEY_SHIFT) {
98275
- canvas.style.cursor = "move";
98276
- }
98277
97862
  });
98278
97863
 
98279
97864
  this._onSceneKeyUp = input.on("keyup", (keyCode) => {
@@ -98282,10 +97867,6 @@ class KeyboardPanRotateDollyHandler {
98282
97867
  }
98283
97868
  keyDownMap[keyCode] = false;
98284
97869
 
98285
- if (keyCode === input.KEY_SHIFT) {
98286
- canvas.style.cursor = null;
98287
- }
98288
-
98289
97870
  if (controllers.pivotController.getPivoting()) {
98290
97871
  controllers.pivotController.endPivot();
98291
97872
  }
@@ -98442,6 +98023,7 @@ class CameraUpdater {
98442
98023
  const pickController = controllers.pickController;
98443
98024
  const pivotController = controllers.pivotController;
98444
98025
  const panController = controllers.panController;
98026
+ const cameraControl = controllers.cameraControl;
98445
98027
 
98446
98028
  let countDown = SCALE_DOLLY_EACH_FRAME; // Decrements on each tick
98447
98029
  let dollyDistFactor = 1.0; // Calculated when countDown is zero
@@ -98566,7 +98148,7 @@ class CameraUpdater {
98566
98148
  updates.rotateDeltaX *= configs.rotationInertia;
98567
98149
  updates.rotateDeltaY *= configs.rotationInertia;
98568
98150
 
98569
- cursorType = "grabbing";
98151
+ cursorType = cameraControl._cursors.rotate;
98570
98152
  }
98571
98153
 
98572
98154
  //----------------------------------------------------------------------------------------------------------
@@ -98632,7 +98214,7 @@ class CameraUpdater {
98632
98214
  camera.pan(vec);
98633
98215
  }
98634
98216
 
98635
- cursorType = "grabbing";
98217
+ cursorType = cameraControl._cursors.pan;
98636
98218
  }
98637
98219
 
98638
98220
  updates.panDeltaX *= configs.panInertia;
@@ -98646,9 +98228,9 @@ class CameraUpdater {
98646
98228
  if (dollyDeltaForDist !== 0) {
98647
98229
 
98648
98230
  if (dollyDeltaForDist < 0) {
98649
- cursorType = "zoom-in";
98231
+ cursorType = cameraControl._cursors.dollyForward;
98650
98232
  } else {
98651
- cursorType = "zoom-out";
98233
+ cursorType = cameraControl._cursors.dollyBackward;
98652
98234
  }
98653
98235
 
98654
98236
  if (configs.firstPerson) {
@@ -98914,6 +98496,7 @@ class TouchPanRotateAndDollyHandler {
98914
98496
  canvas.addEventListener("touchend", this._canvasTouchEndHandler = () => {
98915
98497
  if (pivotController.getPivoting()) {
98916
98498
  pivotController.endPivot();
98499
+ pivotController.hidePivot();
98917
98500
  }
98918
98501
  });
98919
98502
 
@@ -100109,6 +99692,13 @@ class CameraControl extends Component {
100109
99692
  new KeyboardPanRotateDollyHandler(this.scene, this._controllers, this._configs, this._states, this._updates)
100110
99693
  ];
100111
99694
 
99695
+ this._cursors = {
99696
+ dollyForward: "zoom-in",
99697
+ dollyBackward: "zoom-out",
99698
+ rotate: 'grabbing',
99699
+ pan: 'move',
99700
+ };
99701
+
100112
99702
  // Applies scheduled updates to the Camera on each Scene "tick" event
100113
99703
 
100114
99704
  this._cameraUpdater = new CameraUpdater(this.scene, this._controllers, this._configs, this._states, this._updates);
@@ -100470,6 +100060,37 @@ class CameraControl extends Component {
100470
100060
  this._configs.pointerEnabled = !!value;
100471
100061
  }
100472
100062
 
100063
+ /**
100064
+ * Sets the cursor to be used when a particular action is being performed.
100065
+ *
100066
+ * Accepted actions are:
100067
+ *
100068
+ * * "dollyForward" - when the camera is dollying in the forward direction
100069
+ * * "dollyBackward" - when the camera is dollying in the backward direction
100070
+ * * "pan" - when the camera is being panned
100071
+ * * "rotate" - when the camera is being rotated
100072
+ *
100073
+ * @param {String} action
100074
+ * @param {String} style
100075
+ */
100076
+ setCursorStyle(action, style) {
100077
+ if (Object.prototype.hasOwnProperty.call(this._cursors, action)) {
100078
+ this._cursors = { ...this._cursors, [action]: style };
100079
+ }
100080
+ else
100081
+ console.warn(`Action '${action}' is not valid for cursor styles.`);
100082
+ }
100083
+
100084
+ /**
100085
+ * Gets the current style for a particular action.
100086
+ *
100087
+ * @param {String} action To get the style for
100088
+ * @returns {String} style set on the cursor for action
100089
+ */
100090
+ getCursorStyle(action) {
100091
+ return this._cursors[action] || null;
100092
+ }
100093
+
100473
100094
  _reset() {
100474
100095
  for (let i = 0, len = this._handlers.length; i < len; i++) {
100475
100096
  const handler = this._handlers[i];
@@ -110675,6 +110296,12 @@ class Viewer {
110675
110296
  }
110676
110297
  }
110677
110298
 
110299
+ // Added to fix label's text offset in an html2canvas capture (See XEOK-151)
110300
+ // based on https://github.com/niklasvh/html2canvas/issues/2775#issuecomment-1316356991
110301
+ const style = document.createElement('style');
110302
+ document.head.appendChild(style);
110303
+ style.sheet?.insertRule('body > div:last-child img { display: inline-block; }');
110304
+
110678
110305
  for (let i = 0, len = pluginContainerElements.length; i < len; i++) {
110679
110306
  const containerElement = pluginContainerElements[i];
110680
110307
  await html2canvas(containerElement, {
@@ -110687,6 +110314,9 @@ class Viewer {
110687
110314
  // (implemented to compensate XCD-153 issue)
110688
110315
  snapshotCanvas.getContext("2d").resetTransform();
110689
110316
  }
110317
+
110318
+ style.remove();
110319
+
110690
110320
  if (!params.includeGizmos) {
110691
110321
  this.sendToPlugins("snapshotFinished");
110692
110322
  }
@@ -123561,6 +123191,43 @@ class StoreyViewsPlugin extends Plugin {
123561
123191
  this.modelStoreys[modelId][storeyId] = storey;
123562
123192
  }
123563
123193
  }
123194
+ this._clipBoundingBoxes();
123195
+ }
123196
+
123197
+ _clipBoundingBoxes() {
123198
+ const storeysList = this.storeysList;
123199
+ const metaScene = this.viewer.metaScene;
123200
+ const camera = this.viewer.camera;
123201
+ const worldUp = camera.worldUp;
123202
+ const xUp = worldUp[0] > worldUp[1] && worldUp[0] > worldUp[2];
123203
+ const yUp = !xUp && worldUp[1] > worldUp[0] && worldUp[1] > worldUp[2];
123204
+ !xUp && !yUp && worldUp[2] > worldUp[0] && worldUp[2] > worldUp[1];
123205
+
123206
+ let bbIndex;
123207
+
123208
+ if(xUp) bbIndex = 0;
123209
+ else if(yUp) bbIndex = 1;
123210
+ else bbIndex = 2;
123211
+
123212
+ for (let i = 0, len = storeysList.length; i < len; i++) {
123213
+
123214
+ const storeyMetaObjectCur = metaScene.metaObjects[storeysList[i].storeyId];
123215
+ const elevationCur = storeyMetaObjectCur.attributes.elevation;
123216
+
123217
+ if(isNaN(elevationCur)) return;
123218
+
123219
+ const bb = storeysList[i].storeyAABB;
123220
+ bb[bbIndex] = Math.max(bb[1], parseFloat(elevationCur));
123221
+
123222
+ if (i > 0) {
123223
+ const storeyMetaObjectNext = metaScene.metaObjects[storeysList[i - 1].storeyId];
123224
+ const elevationNext = storeyMetaObjectNext.attributes.elevation;
123225
+ bb[4] = Math.min(bb[bbIndex + 3], parseFloat(elevationNext));
123226
+ }
123227
+
123228
+ this.storeys[storeysList[i].storeyId].storeyAABB = bb;
123229
+ }
123230
+
123564
123231
  }
123565
123232
 
123566
123233
  _deregisterModelStoreys(modelId) {
@@ -123757,6 +123424,7 @@ class StoreyViewsPlugin extends Plugin {
123757
123424
  * @param {Number} [options.width=300] Image width in pixels. Height will be automatically determined from this, if not given.
123758
123425
  * @param {Number} [options.height=300] Image height in pixels, as an alternative to width. Width will be automatically determined from this, if not given.
123759
123426
  * @param {String} [options.format="png"] Image format. Accepted values are "png" and "jpeg".
123427
+ * @param {Boolean} [options.captureSectionPlanes=false] Whether the storey map is sliced or not.
123760
123428
  * @returns {StoreyMap} The StoreyMap.
123761
123429
  */
123762
123430
  createStoreyMap(storeyId, options = {}) {
@@ -123773,6 +123441,7 @@ class StoreyViewsPlugin extends Plugin {
123773
123441
  const aabb = (this._fitStoreyMaps) ? storey.storeyAABB : storey.modelAABB;
123774
123442
  const aspect = Math.abs((aabb[5] - aabb[2]) / (aabb[3] - aabb[0]));
123775
123443
  const padding = options.padding || 0;
123444
+ const captureSectionPlanes = !!options.captureSectionPlanes;
123776
123445
 
123777
123446
  let width;
123778
123447
  let height;
@@ -123804,6 +123473,9 @@ class StoreyViewsPlugin extends Plugin {
123804
123473
  this.showStoreyObjects(storeyId, utils.apply(options, {
123805
123474
  hideOthers: true
123806
123475
  }));
123476
+
123477
+ if (captureSectionPlanes)
123478
+ this._toggleSectionPlanes(false);
123807
123479
 
123808
123480
  this._arrangeStoreyMapCamera(storey);
123809
123481
 
@@ -123815,10 +123487,19 @@ class StoreyViewsPlugin extends Plugin {
123815
123487
 
123816
123488
  this._objectsMemento.restoreObjects(scene, mask);
123817
123489
  this._cameraMemento.restoreCamera(scene);
123490
+ if (captureSectionPlanes)
123491
+ this._toggleSectionPlanes(true);
123818
123492
 
123819
123493
  return new StoreyMap(storeyId, src, format, width, height, padding);
123820
123494
  }
123821
123495
 
123496
+ _toggleSectionPlanes(visible) {
123497
+ const planes = this.viewer.scene.sectionPlanes;
123498
+ for (const key in planes) {
123499
+ planes[key].active = visible;
123500
+ }
123501
+ }
123502
+
123822
123503
  _arrangeStoreyMapCamera(storey) {
123823
123504
  const viewer = this.viewer;
123824
123505
  const scene = viewer.scene;
@@ -126362,7 +126043,7 @@ class RenderService {
126362
126043
  nodeElement.appendChild(span);
126363
126044
 
126364
126045
  if (contextmenuHandler) {
126365
- span.oncontextmenu = contextmenuHandler;
126046
+ addContextMenuListener(span, contextmenuHandler);
126366
126047
  }
126367
126048
 
126368
126049
  if (titleClickHandler) {
@@ -133067,7 +132748,7 @@ parsers[ParserV11.version] = ParserV11;
133067
132748
  *
133068
132749
  * ````javascript
133069
132750
  * const sceneModel = xktLoader.load({
133070
- * manifestSrc: "https://xeokit.github.io/xeokit-sdk/assets/models/models/xkt/Schependomlaan.xkt",
132751
+ * src: "https://xeokit.github.io/xeokit-sdk/assets/models/models/xkt/Schependomlaan.xkt",
133071
132752
  * id: "myModel",
133072
132753
  * });
133073
132754
  * ````
@@ -133805,6 +133486,10 @@ class XKTLoaderPlugin extends Plugin {
133805
133486
  }
133806
133487
 
133807
133488
  function getBaseDirectory(filePath) {
133489
+ if (filePath.indexOf('?') > -1) {
133490
+ filePath = filePath.split('?')[0];
133491
+ }
133492
+
133808
133493
  const pathArray = filePath.split('/');
133809
133494
  pathArray.pop(); // Remove the file name or the last segment of the path
133810
133495
  return pathArray.join('/') + '/';
@@ -140781,105 +140466,45 @@ const triangulateEarClipping = function(planeCoords) {
140781
140466
  };
140782
140467
 
140783
140468
  const marker3D = function(scene, color) {
140784
- const canvas = scene.canvas.canvas;
140785
-
140786
- const markerParent = canvas.parentNode;
140787
- const markerDiv = document.createElement("div");
140788
- markerParent.insertBefore(markerDiv, canvas);
140789
-
140790
- let size = 5;
140791
- markerDiv.style.background = color;
140792
- markerDiv.style.border = "2px solid white";
140793
- markerDiv.style.margin = "0 0";
140794
- markerDiv.style.zIndex = "100";
140795
- markerDiv.style.position = "absolute";
140796
- markerDiv.style.pointerEvents = "none";
140797
- markerDiv.style.display = "none";
140798
-
140799
- const marker = new Marker(scene, {});
140800
-
140801
- const px = x => x + "px";
140802
- const update = function() {
140803
- const pos = marker.canvasPos.slice();
140804
- transformToNode(canvas, markerParent, pos);
140805
- markerDiv.style.left = px(pos[0] - 3 - size / 2);
140806
- markerDiv.style.top = px(pos[1] - 3 - size / 2);
140807
- markerDiv.style.borderRadius = px(size * 2);
140808
- markerDiv.style.width = px(size);
140809
- markerDiv.style.height = px(size);
140810
- };
140811
- const onViewMatrix = scene.camera.on("viewMatrix", update);
140812
- const onProjMatrix = scene.camera.on("projMatrix", update);
140469
+ const marker = new Dot3D(scene, {}, scene.canvas.canvas.parentNode, {
140470
+ borderColor: "white",
140471
+ fillColor: color,
140472
+ zIndex: 100
140473
+ });
140813
140474
 
140814
140475
  return {
140815
140476
  update: function(worldPos) {
140816
140477
  if (worldPos)
140817
140478
  {
140818
140479
  marker.worldPos = worldPos;
140819
- update();
140820
140480
  }
140821
- markerDiv.style.display = worldPos ? "" : "none";
140822
- },
140823
-
140824
- setHighlighted: function(h) {
140825
- size = h ? 10 : 5;
140826
- update();
140481
+ marker.setVisible(!!worldPos);
140827
140482
  },
140828
140483
 
140829
- getCanvasPos: () => marker.canvasPos,
140830
-
140831
- getWorldPos: () => marker.worldPos,
140832
-
140833
- destroy: function() {
140834
- markerDiv.parentNode.removeChild(markerDiv);
140835
- scene.camera.off(onViewMatrix);
140836
- scene.camera.off(onProjMatrix);
140837
- marker.destroy();
140838
- }
140484
+ setHighlighted: h => marker.setHighlighted(h),
140485
+ getCanvasPos: () => marker.canvasPos,
140486
+ getWorldPos: () => marker.worldPos,
140487
+ destroy: () => marker.destroy()
140839
140488
  };
140840
140489
  };
140841
140490
 
140842
140491
  const wire3D = function(scene, color, startWorldPos) {
140843
- const canvas = scene.canvas.canvas;
140844
-
140845
- const startMarker = new Marker(scene, {});
140846
- startMarker.worldPos = startWorldPos;
140847
- const endMarker = new Marker(scene, {});
140848
- const wireParent = canvas.ownerDocument.body;
140849
- const wire = new Wire(wireParent, {
140492
+ const wire = new Wire3D(scene, scene.canvas.canvas.ownerDocument.body, {
140850
140493
  color: color,
140851
140494
  thickness: 1,
140852
140495
  thicknessClickable: 6
140853
140496
  });
140854
140497
  wire.setVisible(false);
140855
-
140856
- const updatePos = function() {
140857
- const p0 = startMarker.canvasPos.slice();
140858
- const p1 = endMarker.canvasPos.slice();
140859
- transformToNode(canvas, wireParent, p0);
140860
- transformToNode(canvas, wireParent, p1);
140861
- wire.setStartAndEnd(p0[0], p0[1], p1[0], p1[1]);
140862
- };
140863
- const onViewMatrix = scene.camera.on("viewMatrix", updatePos);
140864
- const onProjMatrix = scene.camera.on("projMatrix", updatePos);
140865
-
140866
140498
  return {
140867
- update: function(endWorldPos) {
140499
+ update: endWorldPos => {
140868
140500
  if (endWorldPos)
140869
140501
  {
140870
- endMarker.worldPos = endWorldPos;
140871
- updatePos();
140502
+ wire.setEnds(startWorldPos, endWorldPos);
140872
140503
  }
140873
140504
  wire.setVisible(!!endWorldPos);
140874
140505
  },
140875
140506
 
140876
- destroy: function() {
140877
- scene.camera.off(onViewMatrix);
140878
- scene.camera.off(onProjMatrix);
140879
- startMarker.destroy();
140880
- endMarker.destroy();
140881
- wire.destroy();
140882
- }
140507
+ destroy: () => wire.destroy()
140883
140508
  };
140884
140509
  };
140885
140510
 
@@ -142409,4 +142034,4 @@ class ZoneTranslateTouchControl extends ZoneTranslateControl {
142409
142034
  }
142410
142035
  }
142411
142036
 
142412
- 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, Dot3D, 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, activateDraggableDot, activateDraggableDots, 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, touchPointSelector, transformToNode, utils, worldToRTCPos, worldToRTCPositions };
142037
+ 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, Dot3D, DotBIMDefaultDataSource, DotBIMLoaderPlugin, EdgeMaterial, EmphasisMaterial, FaceAlignedSectionPlanesPlugin, FastNavPlugin, FloatType, Fresnel, Frustum$1 as Frustum, FrustumPlane, GIFMediaType, GLTFDefaultDataSource, GLTFLoaderPlugin, HalfFloatType, ImagePlane, IntType, JPEGMediaType, KTX2TextureTranscoder, LASLoaderPlugin, Label3D, 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, Wire3D, WorkerPool$1 as WorkerPool, XKTDefaultDataSource, XKTLoaderPlugin, XML3DLoaderPlugin, ZoneEditControl, ZoneEditMouseControl, ZoneEditTouchControl, ZoneTranslateControl, ZoneTranslateMouseControl, ZoneTranslateTouchControl, ZonesMouseControl, ZonesPlugin, ZonesPolysurfaceMouseControl, ZonesPolysurfaceTouchControl, ZonesTouchControl, activateDraggableDot, activateDraggableDots, buildBoxGeometry, buildBoxLinesGeometry, buildBoxLinesGeometryFromAABB, buildCylinderGeometry, buildGridGeometry, buildLineGeometry, buildPlaneGeometry, buildPolylineGeometry, buildPolylineGeometryFromCurve, buildSphereGeometry, buildTorusGeometry, buildVectorTextGeometry, createRTCViewMat, frustumIntersectsAABB3, getKTX2TextureTranscoder, getPlaneRTCPos, isTriangleMeshSolid, load3DSGeometry, loadOBJGeometry, math, meshSurfaceArea, meshVolume, os, rtcToWorldPos, sRGBEncoding, setFrustum, stats, touchPointSelector, transformToNode, utils, worldToRTCPos, worldToRTCPositions };