@inweb/viewer-three 26.10.1 → 26.10.3

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 (36) hide show
  1. package/dist/plugins/components/AxesHelperComponent.js +5 -9
  2. package/dist/plugins/components/AxesHelperComponent.js.map +1 -1
  3. package/dist/plugins/components/AxesHelperComponent.min.js +1 -1
  4. package/dist/plugins/components/AxesHelperComponent.module.js +5 -9
  5. package/dist/plugins/components/AxesHelperComponent.module.js.map +1 -1
  6. package/dist/plugins/components/GridHelperComponent.js +62 -0
  7. package/dist/plugins/components/GridHelperComponent.js.map +1 -0
  8. package/dist/plugins/components/GridHelperComponent.min.js +24 -0
  9. package/dist/plugins/components/GridHelperComponent.module.js +57 -0
  10. package/dist/plugins/components/GridHelperComponent.module.js.map +1 -0
  11. package/dist/plugins/loaders/IFCXLoader.js.map +1 -1
  12. package/dist/plugins/loaders/IFCXLoader.module.js.map +1 -1
  13. package/dist/viewer-three.js +163 -59
  14. package/dist/viewer-three.js.map +1 -1
  15. package/dist/viewer-three.min.js +3 -3
  16. package/dist/viewer-three.module.js +151 -56
  17. package/dist/viewer-three.module.js.map +1 -1
  18. package/lib/Viewer/components/CameraComponent.d.ts +5 -1
  19. package/lib/Viewer/draggers/CuttingPlaneDragger.d.ts +1 -0
  20. package/lib/Viewer/draggers/FlyDragger.d.ts +1 -0
  21. package/lib/Viewer/draggers/MeasureLineDragger.d.ts +1 -0
  22. package/lib/Viewer/draggers/OrbitDragger.d.ts +1 -0
  23. package/lib/Viewer/draggers/WalkDragger.d.ts +1 -0
  24. package/package.json +5 -5
  25. package/plugins/components/AxesHelperComponent.ts +6 -11
  26. package/plugins/components/GridHelperComponent.ts +67 -0
  27. package/plugins/loaders/IFCX/render.js +2 -2
  28. package/src/Viewer/Viewer.ts +4 -0
  29. package/src/Viewer/components/CameraComponent.ts +86 -25
  30. package/src/Viewer/components/SelectionComponent.ts +7 -1
  31. package/src/Viewer/controls/WalkControls.ts +1 -1
  32. package/src/Viewer/draggers/CuttingPlaneDragger.ts +12 -6
  33. package/src/Viewer/draggers/FlyDragger.ts +10 -4
  34. package/src/Viewer/draggers/MeasureLineDragger.ts +50 -17
  35. package/src/Viewer/draggers/OrbitDragger.ts +7 -1
  36. package/src/Viewer/draggers/WalkDragger.ts +10 -4
@@ -23,7 +23,7 @@
23
23
 
24
24
  import { draggersRegistry, commandsRegistry, componentsRegistry, Loader, loadersRegistry, Options, CANVAS_EVENTS } from '@inweb/viewer-core';
25
25
  export * from '@inweb/viewer-core';
26
- import { Line, Vector3, BufferGeometry, Float32BufferAttribute, LineBasicMaterial, Mesh, MeshBasicMaterial, DoubleSide, EventDispatcher, MOUSE, TOUCH, Spherical, Quaternion, Vector2, Plane, Object3D, Line3, Matrix4, Vector4, MathUtils, Raycaster, EdgesGeometry, Controls, Clock, Sphere, Box3, Color, AmbientLight, DirectionalLight, HemisphereLight, MeshPhongMaterial, WebGLRenderTarget, UnsignedByteType, RGBAFormat, OrthographicCamera, CylinderGeometry, Sprite, CanvasTexture, SRGBColorSpace, SpriteMaterial, LoadingManager, LoaderUtils, TextureLoader, BufferAttribute, PointsMaterial, Points, TriangleStripDrawMode, TriangleFanDrawMode, LineSegments, LineLoop, Group, NormalBlending, PerspectiveCamera, UniformsUtils, ShaderMaterial, AdditiveBlending, HalfFloatType, Scene, WebGLRenderer, LinearSRGBColorSpace } from 'three';
26
+ import { Line, Vector3, BufferGeometry, Float32BufferAttribute, LineBasicMaterial, Mesh, MeshBasicMaterial, DoubleSide, EventDispatcher, MOUSE, TOUCH, Spherical, Quaternion, Vector2, Plane, Object3D, Line3, Matrix4, Vector4, MathUtils, Raycaster, EdgesGeometry, Controls, Clock, Sphere, Box3, Color, PerspectiveCamera, OrthographicCamera, AmbientLight, DirectionalLight, HemisphereLight, MeshPhongMaterial, WebGLRenderTarget, UnsignedByteType, RGBAFormat, CylinderGeometry, Sprite, CanvasTexture, SRGBColorSpace, SpriteMaterial, LoadingManager, LoaderUtils, TextureLoader, BufferAttribute, PointsMaterial, Points, TriangleStripDrawMode, TriangleFanDrawMode, LineSegments, LineLoop, Group, NormalBlending, UniformsUtils, ShaderMaterial, AdditiveBlending, HalfFloatType, Scene, WebGLRenderer, LinearSRGBColorSpace } from 'three';
27
27
  import { TransformControls } from 'three/examples/jsm/controls/TransformControls.js';
28
28
  import { LineSegmentsGeometry } from 'three/examples/jsm/lines/LineSegmentsGeometry.js';
29
29
  import { Wireframe } from 'three/examples/jsm/lines/Wireframe.js';
@@ -743,10 +743,13 @@ class OrbitControls extends EventDispatcher {
743
743
  class OrbitDragger {
744
744
  constructor(viewer) {
745
745
  this.updateControls = () => {
746
+ this.orbit.target.copy(this.viewer.target);
747
+ this.orbit.update();
748
+ };
749
+ this.updateControlsCamera = () => {
746
750
  this.orbit.maxDistance = this.viewer.camera.far;
747
751
  this.orbit.minDistance = this.viewer.camera.near;
748
752
  this.orbit.object = this.viewer.camera;
749
- this.orbit.target.copy(this.viewer.target);
750
753
  this.orbit.update();
751
754
  };
752
755
  this.controlsStart = () => {
@@ -803,6 +806,7 @@ class OrbitDragger {
803
806
  this.viewer.on("viewposition", this.updateControls);
804
807
  this.viewer.addEventListener("zoom", this.updateControls);
805
808
  this.viewer.addEventListener("drawviewpoint", this.updateControls);
809
+ this.viewer.addEventListener("changecameramode", this.updateControlsCamera);
806
810
  this.viewer.addEventListener("contextmenu", this.stopContextMenu);
807
811
  this.updateControls();
808
812
  }
@@ -812,6 +816,7 @@ class OrbitDragger {
812
816
  this.viewer.off("viewposition", this.updateControls);
813
817
  this.viewer.removeEventListener("zoom", this.updateControls);
814
818
  this.viewer.removeEventListener("drawviewpoint", this.updateControls);
819
+ this.viewer.removeEventListener("changecameramode", this.updateControlsCamera);
815
820
  this.viewer.removeEventListener("contextmenu", this.stopContextMenu);
816
821
  this.orbit.removeEventListener("start", this.controlsStart);
817
822
  this.orbit.removeEventListener("change", this.controlsChange);
@@ -833,6 +838,9 @@ class CuttingPlaneDragger extends OrbitDragger {
833
838
  this.planeHelper.size = this.viewer.extents.getSize(new Vector3()).length();
834
839
  this.viewer.update();
835
840
  };
841
+ this.updateTransformCamera = () => {
842
+ this.transform.camera = this.viewer.camera;
843
+ };
836
844
  this.onDoubleClick = (event) => {
837
845
  event.stopPropagation();
838
846
  this.plane.negate();
@@ -858,16 +866,18 @@ class CuttingPlaneDragger extends OrbitDragger {
858
866
  this.transform.addEventListener("change", this.transformChange);
859
867
  this.transform.addEventListener("dragging-changed", this.transformDrag);
860
868
  this.viewer.helpers.add(this.transform.getHelper());
861
- this.viewer.on("explode", this.updatePlaneSize);
862
- this.viewer.on("show", this.updatePlaneSize);
863
- this.viewer.on("showall", this.updatePlaneSize);
869
+ this.viewer.addEventListener("explode", this.updatePlaneSize);
870
+ this.viewer.addEventListener("show", this.updatePlaneSize);
871
+ this.viewer.addEventListener("showall", this.updatePlaneSize);
872
+ this.viewer.addEventListener("changecameramode", this.updateTransformCamera);
864
873
  this.viewer.canvas.addEventListener("dblclick", this.onDoubleClick, true);
865
874
  this.viewer.update();
866
875
  }
867
876
  dispose() {
868
- this.viewer.off("explode", this.updatePlaneSize);
869
- this.viewer.off("show", this.updatePlaneSize);
870
- this.viewer.off("showAll", this.updatePlaneSize);
877
+ this.viewer.removeEventListener("explode", this.updatePlaneSize);
878
+ this.viewer.removeEventListener("show", this.updatePlaneSize);
879
+ this.viewer.removeEventListener("showall", this.updatePlaneSize);
880
+ this.viewer.removeEventListener("changecameramode", this.updateTransformCamera);
871
881
  this.viewer.canvas.removeEventListener("dblclick", this.onDoubleClick, true);
872
882
  this.transform.removeEventListener("change", this.transformChange);
873
883
  this.transform.removeEventListener("dragging-changed", this.transformDrag);
@@ -948,7 +958,11 @@ class MeasureLineDragger extends OrbitDragger {
948
958
  this.overlay.render();
949
959
  };
950
960
  this.updateSnapper = () => {
951
- this.snapper.update(this.viewer);
961
+ this.snapper.setFromViewer(this.viewer);
962
+ };
963
+ this.updateSnapperCamera = () => {
964
+ this.snapper.camera = this.viewer.camera;
965
+ this.overlay.camera = this.viewer.camera;
952
966
  };
953
967
  this.overlay = new MeasureOverlay(viewer.camera, viewer.canvas);
954
968
  this.overlay.attach();
@@ -966,6 +980,7 @@ class MeasureLineDragger extends OrbitDragger {
966
980
  this.viewer.addEventListener("isolate", this.updateSnapper);
967
981
  this.viewer.addEventListener("show", this.updateSnapper);
968
982
  this.viewer.addEventListener("showall", this.updateSnapper);
983
+ this.viewer.addEventListener("changecameramode", this.updateSnapperCamera);
969
984
  }
970
985
  dispose() {
971
986
  this.viewer.canvas.removeEventListener("pointerdown", this.onPointerDown);
@@ -978,6 +993,7 @@ class MeasureLineDragger extends OrbitDragger {
978
993
  this.viewer.removeEventListener("isolate", this.updateSnapper);
979
994
  this.viewer.removeEventListener("show", this.updateSnapper);
980
995
  this.viewer.removeEventListener("showall", this.updateSnapper);
996
+ this.viewer.removeEventListener("changecameramode", this.updateSnapperCamera);
981
997
  this.snapper.dispose();
982
998
  this.overlay.detach();
983
999
  this.overlay.dispose();
@@ -995,6 +1011,7 @@ class MeasureSnapper {
995
1011
  this.camera = camera;
996
1012
  this.canvas = canvas;
997
1013
  this.objects = [];
1014
+ this.clippingPlanes = [];
998
1015
  this.raycaster = new Raycaster();
999
1016
  this.detectRadiusInPixels = this.isMobile() ? MOBILE_SNAP_DISTANCE : DESKTOP_SNAP_DISTANCE;
1000
1017
  this.edgesCache = new WeakMap();
@@ -1010,7 +1027,7 @@ class MeasureSnapper {
1010
1027
  getMousePosition(event, target) {
1011
1028
  return target.set(event.clientX, event.clientY);
1012
1029
  }
1013
- getPointerIntersects(mouse, objects) {
1030
+ getPointerIntersects(mouse) {
1014
1031
  const rect = this.canvas.getBoundingClientRect();
1015
1032
  const x = ((mouse.x - rect.left) / rect.width) * 2 - 1;
1016
1033
  const y = (-(mouse.y - rect.top) / rect.height) * 2 + 1;
@@ -1024,28 +1041,32 @@ class MeasureSnapper {
1024
1041
  Points: { threshold: 0.01 },
1025
1042
  Sprite: {},
1026
1043
  };
1027
- return this.raycaster.intersectObjects(objects, false);
1044
+ let intersects = this.raycaster.intersectObjects(this.objects, false);
1045
+ this.clippingPlanes.forEach((plane) => {
1046
+ intersects = intersects.filter((intersect) => plane.distanceToPoint(intersect.point) >= 0);
1047
+ });
1048
+ return intersects;
1028
1049
  }
1029
1050
  getDetectRadius(point) {
1030
1051
  const camera = this.camera;
1031
1052
  if (camera.isOrthographicCamera) {
1032
- const worldHeight = camera.top - camera.bottom;
1053
+ const fieldHeight = (camera.top - camera.bottom) / camera.zoom;
1033
1054
  const canvasHeight = this.canvas.height;
1034
- const worldUnitsPerPixel = worldHeight / canvasHeight;
1055
+ const worldUnitsPerPixel = fieldHeight / canvasHeight;
1035
1056
  return this.detectRadiusInPixels * worldUnitsPerPixel;
1036
1057
  }
1037
1058
  if (camera.isPerspectiveCamera) {
1038
1059
  const distance = camera.position.distanceTo(point);
1039
- const worldHeight = 2 * Math.tan(MathUtils.degToRad(camera.fov * 0.5)) * distance;
1060
+ const fieldHeight = 2 * Math.tan(MathUtils.degToRad(camera.fov * 0.5)) * distance;
1040
1061
  const canvasHeight = this.canvas.height;
1041
- const worldUnitsPerPixel = worldHeight / canvasHeight;
1062
+ const worldUnitsPerPixel = fieldHeight / canvasHeight;
1042
1063
  return this.detectRadiusInPixels * worldUnitsPerPixel;
1043
1064
  }
1044
1065
  return 0.1;
1045
1066
  }
1046
1067
  getSnapPoint(event) {
1047
1068
  const mouse = this.getMousePosition(event, new Vector2());
1048
- const intersections = this.getPointerIntersects(mouse, this.objects);
1069
+ const intersections = this.getPointerIntersects(mouse);
1049
1070
  if (intersections.length === 0)
1050
1071
  return undefined;
1051
1072
  const object = intersections[0].object;
@@ -1093,40 +1114,47 @@ class MeasureSnapper {
1093
1114
  return object.localToWorld(snapPoint);
1094
1115
  return intersectionPoint.clone();
1095
1116
  }
1096
- update(viewer) {
1117
+ setFromViewer(viewer) {
1097
1118
  this.objects.length = 0;
1098
1119
  viewer.models.forEach((model) => {
1099
1120
  model.getVisibleObjects().forEach((object) => this.objects.push(object));
1100
1121
  });
1122
+ this.camera = viewer.camera;
1123
+ this.clippingPlanes = viewer.renderer.clippingPlanes || [];
1101
1124
  }
1102
1125
  }
1103
1126
  class MeasureOverlay {
1104
1127
  constructor(camera, canvas) {
1105
1128
  this.lines = [];
1129
+ this.resizeContainer = (entries) => {
1130
+ const { width, height } = entries[0].contentRect;
1131
+ if (!width || !height)
1132
+ return;
1133
+ this.container.style.width = `${width}px`;
1134
+ this.container.style.height = `${height}px`;
1135
+ };
1106
1136
  this.camera = camera;
1107
1137
  this.canvas = canvas;
1108
1138
  this.projector = new MeasureProjector(camera, canvas);
1139
+ this.resizeObserver = new ResizeObserver(this.resizeContainer);
1109
1140
  }
1110
1141
  attach() {
1111
1142
  this.container = document.createElement("div");
1112
1143
  this.container.id = "measure-container";
1113
- this.container.style.background = "rgba(0,0,0,0)";
1114
1144
  this.container.style.position = "absolute";
1115
- this.container.style.top = "0px";
1116
- this.container.style.left = "0px";
1117
- this.container.style.width = "100%";
1118
- this.container.style.height = "100%";
1119
1145
  this.container.style.outline = "none";
1120
1146
  this.container.style.pointerEvents = "none";
1121
1147
  this.container.style.overflow = "hidden";
1122
1148
  if (!this.canvas.parentElement)
1123
1149
  return;
1124
1150
  this.canvas.parentElement.appendChild(this.container);
1151
+ this.resizeObserver.observe(this.canvas.parentElement);
1125
1152
  }
1126
1153
  dispose() {
1127
1154
  this.clear();
1128
1155
  }
1129
1156
  detach() {
1157
+ this.resizeObserver.disconnect();
1130
1158
  this.container.remove();
1131
1159
  this.container = undefined;
1132
1160
  }
@@ -1135,7 +1163,7 @@ class MeasureOverlay {
1135
1163
  this.lines = [];
1136
1164
  }
1137
1165
  render() {
1138
- this.projector.updateProjectionMatrix();
1166
+ this.projector.setFromCamera(this.camera);
1139
1167
  this.lines.forEach((line) => line.render());
1140
1168
  }
1141
1169
  update() {
@@ -1286,6 +1314,10 @@ class MeasureProjector {
1286
1314
  this.camera = camera;
1287
1315
  this.canvas = canvas;
1288
1316
  }
1317
+ setFromCamera(camera) {
1318
+ this.camera = camera;
1319
+ this.updateProjectionMatrix();
1320
+ }
1289
1321
  updateProjectionMatrix() {
1290
1322
  const rect = this.canvas.getBoundingClientRect();
1291
1323
  _widthHalf = rect.width / 2;
@@ -1462,7 +1494,7 @@ class WalkControls extends Controls {
1462
1494
  Points: { threshold: 0 },
1463
1495
  Sprite: { threshold: 0 },
1464
1496
  };
1465
- let intersects = this.raycaster.intersectObjects(this.groundObjects, false);
1497
+ const intersects = this.raycaster.intersectObjects(this.groundObjects, false);
1466
1498
  if (intersects.length > 0) {
1467
1499
  const groundY = intersects[0].point.y;
1468
1500
  const targetY = groundY + this.EYE_HEIGHT;
@@ -1554,6 +1586,9 @@ class WalkDragger {
1554
1586
  const size = this.viewer.extents.getSize(new Vector3());
1555
1587
  this.controls.movementSpeed = Math.min(size.x, size.y, size.z) / 2;
1556
1588
  };
1589
+ this.updateControlsCamera = () => {
1590
+ this.controls.object = this.viewer.camera;
1591
+ };
1557
1592
  this.controlsChange = () => {
1558
1593
  this.viewer.update();
1559
1594
  this.viewer.emitEvent({ type: "changecamera" });
@@ -1577,13 +1612,15 @@ class WalkDragger {
1577
1612
  this.controls.addEventListener("change", this.controlsChange);
1578
1613
  this.controls.addEventListener("walkspeedchange", this.walkspeedChange);
1579
1614
  this.viewer = viewer;
1580
- this.viewer.on("render", this.viewerRender);
1581
- this.viewer.on("zoom", this.viewerZoom);
1615
+ this.viewer.addEventListener("render", this.viewerRender);
1616
+ this.viewer.addEventListener("zoom", this.viewerZoom);
1617
+ this.viewer.addEventListener("changecameramode", this.updateControlsCamera);
1582
1618
  this.updateControls();
1583
1619
  }
1584
1620
  dispose() {
1585
- this.viewer.off("render", this.viewerRender);
1586
- this.viewer.off("zoom", this.viewerZoom);
1621
+ this.viewer.removeEventListener("render", this.viewerRender);
1622
+ this.viewer.removeEventListener("zoom", this.viewerZoom);
1623
+ this.viewer.removeEventListener("changecameramode", this.updateControlsCamera);
1587
1624
  this.controls.removeEventListener("walkspeedchange", this.walkspeedChange);
1588
1625
  this.controls.removeEventListener("change", this.controlsChange);
1589
1626
  this.controls.dispose();
@@ -1743,6 +1780,9 @@ class FlyDragger {
1743
1780
  const size = this.viewer.extents.getSize(new Vector3());
1744
1781
  this.controls.movementSpeed = Math.min(size.x, size.y, size.z) / 2;
1745
1782
  };
1783
+ this.updateControlsCamera = () => {
1784
+ this.controls.object = this.viewer.camera;
1785
+ };
1746
1786
  this.controlsChange = () => {
1747
1787
  this.viewer.update();
1748
1788
  this.viewer.emitEvent({ type: "changecamera" });
@@ -1760,13 +1800,15 @@ class FlyDragger {
1760
1800
  this.controls.addEventListener("change", this.controlsChange);
1761
1801
  this.controls.addEventListener("flyspeedchange", this.flyspeedChange);
1762
1802
  this.viewer = viewer;
1763
- this.viewer.on("render", this.viewerRender);
1764
- this.viewer.on("zoom", this.viewerZoom);
1803
+ this.viewer.addEventListener("render", this.viewerRender);
1804
+ this.viewer.addEventListener("zoom", this.viewerZoom);
1805
+ this.viewer.addEventListener("changecameramode", this.updateControlsCamera);
1765
1806
  this.updateControls();
1766
1807
  }
1767
1808
  dispose() {
1768
- this.viewer.off("render", this.viewerRender);
1769
- this.viewer.off("zoom", this.viewerZoom);
1809
+ this.viewer.removeEventListener("render", this.viewerRender);
1810
+ this.viewer.removeEventListener("zoom", this.viewerZoom);
1811
+ this.viewer.removeEventListener("changecameramode", this.updateControlsCamera);
1770
1812
  this.controls.removeEventListener("flyspeedchange", this.flyspeedChange);
1771
1813
  this.controls.removeEventListener("change", this.controlsChange);
1772
1814
  this.controls.dispose();
@@ -2064,10 +2106,10 @@ class BackgroundComponent {
2064
2106
 
2065
2107
  class CameraComponent {
2066
2108
  constructor(viewer) {
2109
+ this.optionsChange = () => {
2110
+ this.switchCameraMode(this.viewer.options.cameraMode);
2111
+ };
2067
2112
  this.geometryEnd = () => {
2068
- const extentsSize = this.viewer.extents.getBoundingSphere(new Sphere()).radius * 2;
2069
- const rendererSize = this.viewer.renderer.getSize(new Vector2());
2070
- const aspect = rendererSize.x / rendererSize.y;
2071
2113
  let camera;
2072
2114
  this.viewer.scene.traverse((object) => {
2073
2115
  if (object.isCamera)
@@ -2079,36 +2121,83 @@ class CameraComponent {
2079
2121
  if (camera) {
2080
2122
  camera.isDefaultCamera = true;
2081
2123
  camera.scale.set(1, 1, 1);
2082
- this.viewer.camera = camera;
2083
- this.viewer.renderPass.camera = camera;
2084
- this.viewer.helpersPass.camera = camera;
2085
- this.viewer.ssaaRenderPass.camera = camera;
2124
+ this.switchCamera(camera);
2125
+ const mode = this.getCameraMode(camera);
2126
+ this.viewer.options.cameraMode = mode;
2127
+ this.viewer.emitEvent({ type: "changecameramode", mode });
2086
2128
  }
2087
2129
  else {
2088
- camera = this.viewer.camera;
2089
- }
2090
- if (camera.isPerspectiveCamera) {
2091
- camera.aspect = aspect;
2092
- camera.near = extentsSize / 1000;
2093
- camera.far = extentsSize * 1000;
2094
- camera.updateProjectionMatrix();
2095
- }
2096
- if (camera.isOrthographicCamera) {
2097
- camera.left = camera.bottom * aspect;
2098
- camera.right = camera.top * aspect;
2099
- camera.near = 0;
2100
- camera.far = extentsSize * 1000;
2101
- camera.updateProjectionMatrix();
2102
- }
2103
- if (!camera.isDefaultCamera) {
2130
+ this.switchCamera(this.viewer.camera);
2104
2131
  this.viewer.executeCommand("setDefaultViewPosition");
2105
2132
  }
2106
2133
  };
2107
2134
  this.viewer = viewer;
2108
2135
  this.viewer.addEventListener("databasechunk", this.geometryEnd);
2136
+ this.viewer.addEventListener("optionschange", this.optionsChange);
2137
+ this.viewer.addEventListener("initialize", this.optionsChange);
2109
2138
  }
2110
2139
  dispose() {
2111
2140
  this.viewer.removeEventListener("databasechunk", this.geometryEnd);
2141
+ this.viewer.removeEventListener("optionschange", this.optionsChange);
2142
+ this.viewer.removeEventListener("initialize", this.optionsChange);
2143
+ }
2144
+ getCameraMode(camera) {
2145
+ return camera.isOrthographicCamera ? "orthographic" : "perspective";
2146
+ }
2147
+ switchCamera(camera) {
2148
+ const extentsSize = this.viewer.extents.getBoundingSphere(new Sphere()).radius * 2 || 1;
2149
+ const rendererSize = this.viewer.renderer.getSize(new Vector2());
2150
+ const aspect = rendererSize.x / rendererSize.y;
2151
+ if (camera.isPerspectiveCamera) {
2152
+ camera.aspect = aspect;
2153
+ camera.near = extentsSize / 1000;
2154
+ camera.far = extentsSize * 1000;
2155
+ }
2156
+ if (camera.isOrthographicCamera) {
2157
+ camera.left = camera.bottom * aspect;
2158
+ camera.right = camera.top * aspect;
2159
+ camera.near = 0;
2160
+ camera.far = extentsSize * 1000;
2161
+ }
2162
+ camera.updateProjectionMatrix();
2163
+ this.viewer.camera = camera;
2164
+ this.viewer.renderPass.camera = camera;
2165
+ this.viewer.helpersPass.camera = camera;
2166
+ this.viewer.ssaaRenderPass.camera = camera;
2167
+ this.viewer.update();
2168
+ }
2169
+ switchCameraMode(mode) {
2170
+ if (!mode)
2171
+ return;
2172
+ const currentCamera = this.viewer.camera;
2173
+ if (mode === this.getCameraMode(currentCamera))
2174
+ return;
2175
+ const target = this.viewer.target.clone();
2176
+ let camera;
2177
+ if (currentCamera.isOrthographicCamera) {
2178
+ const fov = currentCamera.userData.fov || 45;
2179
+ const fieldHeight = (currentCamera.top - currentCamera.bottom) / currentCamera.zoom;
2180
+ const distance = fieldHeight / (2 * Math.tan(MathUtils.degToRad(fov) / 2));
2181
+ const direction = new Vector3().subVectors(currentCamera.position, target).normalize();
2182
+ camera = new PerspectiveCamera(fov);
2183
+ camera.position.copy(direction).multiplyScalar(distance).add(target);
2184
+ }
2185
+ if (currentCamera.isPerspectiveCamera) {
2186
+ const fov = currentCamera.fov;
2187
+ const distance = currentCamera.position.distanceTo(target);
2188
+ const fieldHeight = 2 * Math.tan(MathUtils.degToRad(fov) / 2) * distance;
2189
+ camera = new OrthographicCamera();
2190
+ camera.top = fieldHeight / 2;
2191
+ camera.bottom = -fieldHeight / 2;
2192
+ camera.position.copy(currentCamera.position);
2193
+ camera.userData.fov = fov;
2194
+ }
2195
+ if (!camera)
2196
+ return;
2197
+ camera.up.copy(currentCamera.up);
2198
+ camera.quaternion.copy(currentCamera.quaternion);
2199
+ this.switchCamera(camera);
2200
+ this.viewer.emitEvent({ type: "changecameramode", mode });
2112
2201
  }
2113
2202
  }
2114
2203
 
@@ -2505,7 +2594,11 @@ class SelectionComponent {
2505
2594
  Points: { threshold: 0.01 },
2506
2595
  Sprite: {},
2507
2596
  };
2508
- return this.raycaster.intersectObjects(objects, false);
2597
+ let intersects = this.raycaster.intersectObjects(objects, false);
2598
+ (this.viewer.renderer.clippingPlanes || []).forEach((plane) => {
2599
+ intersects = intersects.filter((intersect) => plane.distanceToPoint(intersect.point) >= 0);
2600
+ });
2601
+ return intersects;
2509
2602
  }
2510
2603
  select(objects, model) {
2511
2604
  if (!model) {
@@ -5728,6 +5821,7 @@ class Viewer extends EventEmitter2 {
5728
5821
  this.renderPass.camera = camera;
5729
5822
  this.helpersPass.camera = camera;
5730
5823
  this.ssaaRenderPass.camera = camera;
5824
+ this.emitEvent({ type: "changecameramode", mode: "orthographic" });
5731
5825
  }
5732
5826
  };
5733
5827
  const setPerspectiveCamera = (perspective_camera) => {
@@ -5749,6 +5843,7 @@ class Viewer extends EventEmitter2 {
5749
5843
  this.renderPass.camera = camera;
5750
5844
  this.helpersPass.camera = camera;
5751
5845
  this.ssaaRenderPass.camera = camera;
5846
+ this.emitEvent({ type: "changecameramode", mode: "perspective" });
5752
5847
  }
5753
5848
  };
5754
5849
  const setClippingPlanes = (clipping_planes) => {