@inweb/viewer-three 26.11.0 → 26.11.1

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 (113) hide show
  1. package/README.md +4 -7
  2. package/dist/plugins/components/AxesHelperComponent.js.map +1 -0
  3. package/dist/plugins/components/AxesHelperComponent.module.js.map +1 -0
  4. package/dist/plugins/components/ExtentsHelperComponent.js.map +1 -0
  5. package/dist/plugins/components/ExtentsHelperComponent.module.js.map +1 -0
  6. package/dist/plugins/components/GridHelperComponent.js.map +1 -0
  7. package/dist/plugins/components/GridHelperComponent.module.js.map +1 -0
  8. package/dist/plugins/components/LightHelperComponent.js.map +1 -0
  9. package/dist/plugins/components/LightHelperComponent.module.js.map +1 -0
  10. package/dist/plugins/components/RoomEnvironmentComponent.js.map +1 -0
  11. package/dist/plugins/components/RoomEnvironmentComponent.module.js.map +1 -0
  12. package/dist/plugins/components/StatsPanelComponent.js.map +1 -0
  13. package/dist/plugins/components/StatsPanelComponent.module.js.map +1 -0
  14. package/dist/plugins/loaders/GLTFCloudLoader.js.map +1 -0
  15. package/dist/plugins/loaders/GLTFCloudLoader.module.js.map +1 -0
  16. package/dist/{extensions → plugins}/loaders/GLTFFileLoader.js +1 -1
  17. package/dist/plugins/loaders/GLTFFileLoader.js.map +1 -0
  18. package/dist/plugins/loaders/GLTFFileLoader.min.js +24 -0
  19. package/dist/plugins/loaders/GLTFFileLoader.module.js.map +1 -0
  20. package/dist/plugins/loaders/IFCXLoader.js.map +1 -0
  21. package/dist/plugins/loaders/IFCXLoader.module.js.map +1 -0
  22. package/dist/plugins/loaders/PotreeLoader.js.map +1 -0
  23. package/dist/plugins/loaders/PotreeLoader.module.js.map +1 -0
  24. package/dist/viewer-three.js +153 -249
  25. package/dist/viewer-three.js.map +1 -1
  26. package/dist/viewer-three.min.js +3 -3
  27. package/dist/viewer-three.module.js +155 -243
  28. package/dist/viewer-three.module.js.map +1 -1
  29. package/lib/Viewer/Viewer.d.ts +1 -1
  30. package/lib/Viewer/components/SelectionComponent.d.ts +3 -1
  31. package/lib/Viewer/draggers/MeasureLineDragger.d.ts +1 -7
  32. package/lib/Viewer/models/IModelImpl.d.ts +0 -4
  33. package/lib/Viewer/models/ModelImpl.d.ts +0 -4
  34. package/package.json +11 -11
  35. package/src/Viewer/Viewer.ts +1 -1
  36. package/src/Viewer/components/SelectionComponent.ts +30 -5
  37. package/src/Viewer/draggers/MeasureLineDragger.ts +226 -84
  38. package/src/Viewer/loaders/DynamicGltfLoader/DynamicGltfLoader.js +16 -14
  39. package/src/Viewer/loaders/DynamicGltfLoader/GltfStructure.js +0 -1
  40. package/src/Viewer/models/IModelImpl.ts +0 -8
  41. package/src/Viewer/models/ModelImpl.ts +0 -18
  42. package/src/index-umd.ts +1 -1
  43. package/dist/extensions/components/AxesHelperComponent.js.map +0 -1
  44. package/dist/extensions/components/AxesHelperComponent.module.js.map +0 -1
  45. package/dist/extensions/components/ExtentsHelperComponent.js.map +0 -1
  46. package/dist/extensions/components/ExtentsHelperComponent.module.js.map +0 -1
  47. package/dist/extensions/components/GridHelperComponent.js.map +0 -1
  48. package/dist/extensions/components/GridHelperComponent.module.js.map +0 -1
  49. package/dist/extensions/components/LightHelperComponent.js.map +0 -1
  50. package/dist/extensions/components/LightHelperComponent.module.js.map +0 -1
  51. package/dist/extensions/components/RoomEnvironmentComponent.js.map +0 -1
  52. package/dist/extensions/components/RoomEnvironmentComponent.module.js.map +0 -1
  53. package/dist/extensions/components/StatsPanelComponent.js.map +0 -1
  54. package/dist/extensions/components/StatsPanelComponent.module.js.map +0 -1
  55. package/dist/extensions/loaders/GLTFCloudLoader.js.map +0 -1
  56. package/dist/extensions/loaders/GLTFCloudLoader.module.js.map +0 -1
  57. package/dist/extensions/loaders/GLTFFileLoader.js.map +0 -1
  58. package/dist/extensions/loaders/GLTFFileLoader.min.js +0 -24
  59. package/dist/extensions/loaders/GLTFFileLoader.module.js.map +0 -1
  60. package/dist/extensions/loaders/IFCXLoader.js.map +0 -1
  61. package/dist/extensions/loaders/IFCXLoader.module.js.map +0 -1
  62. package/dist/extensions/loaders/PotreeLoader.js.map +0 -1
  63. package/dist/extensions/loaders/PotreeLoader.module.js.map +0 -1
  64. package/lib/Viewer/measurement/Snapper.d.ts +0 -15
  65. package/lib/Viewer/measurement/UnitConverter.d.ts +0 -63
  66. package/lib/Viewer/measurement/UnitFormatter.d.ts +0 -4
  67. package/src/Viewer/measurement/Snapper.ts +0 -208
  68. package/src/Viewer/measurement/UnitConverter.ts +0 -47
  69. package/src/Viewer/measurement/UnitFormatter.ts +0 -95
  70. /package/dist/{extensions → plugins}/components/AxesHelperComponent.js +0 -0
  71. /package/dist/{extensions → plugins}/components/AxesHelperComponent.min.js +0 -0
  72. /package/dist/{extensions → plugins}/components/AxesHelperComponent.module.js +0 -0
  73. /package/dist/{extensions → plugins}/components/ExtentsHelperComponent.js +0 -0
  74. /package/dist/{extensions → plugins}/components/ExtentsHelperComponent.min.js +0 -0
  75. /package/dist/{extensions → plugins}/components/ExtentsHelperComponent.module.js +0 -0
  76. /package/dist/{extensions → plugins}/components/GridHelperComponent.js +0 -0
  77. /package/dist/{extensions → plugins}/components/GridHelperComponent.min.js +0 -0
  78. /package/dist/{extensions → plugins}/components/GridHelperComponent.module.js +0 -0
  79. /package/dist/{extensions → plugins}/components/LightHelperComponent.js +0 -0
  80. /package/dist/{extensions → plugins}/components/LightHelperComponent.min.js +0 -0
  81. /package/dist/{extensions → plugins}/components/LightHelperComponent.module.js +0 -0
  82. /package/dist/{extensions → plugins}/components/RoomEnvironmentComponent.js +0 -0
  83. /package/dist/{extensions → plugins}/components/RoomEnvironmentComponent.min.js +0 -0
  84. /package/dist/{extensions → plugins}/components/RoomEnvironmentComponent.module.js +0 -0
  85. /package/dist/{extensions → plugins}/components/StatsPanelComponent.js +0 -0
  86. /package/dist/{extensions → plugins}/components/StatsPanelComponent.min.js +0 -0
  87. /package/dist/{extensions → plugins}/components/StatsPanelComponent.module.js +0 -0
  88. /package/dist/{extensions → plugins}/loaders/GLTFCloudLoader.js +0 -0
  89. /package/dist/{extensions → plugins}/loaders/GLTFCloudLoader.min.js +0 -0
  90. /package/dist/{extensions → plugins}/loaders/GLTFCloudLoader.module.js +0 -0
  91. /package/dist/{extensions → plugins}/loaders/GLTFFileLoader.module.js +0 -0
  92. /package/dist/{extensions → plugins}/loaders/IFCXLoader.js +0 -0
  93. /package/dist/{extensions → plugins}/loaders/IFCXLoader.min.js +0 -0
  94. /package/dist/{extensions → plugins}/loaders/IFCXLoader.module.js +0 -0
  95. /package/dist/{extensions → plugins}/loaders/PotreeLoader.js +0 -0
  96. /package/dist/{extensions → plugins}/loaders/PotreeLoader.min.js +0 -0
  97. /package/dist/{extensions → plugins}/loaders/PotreeLoader.module.js +0 -0
  98. /package/{extensions → plugins}/components/AxesHelperComponent.ts +0 -0
  99. /package/{extensions → plugins}/components/ExtentsHelperComponent.ts +0 -0
  100. /package/{extensions → plugins}/components/GridHelperComponent.ts +0 -0
  101. /package/{extensions → plugins}/components/LightHelperComponent.ts +0 -0
  102. /package/{extensions → plugins}/components/RoomEnvironmentComponent.ts +0 -0
  103. /package/{extensions → plugins}/components/StatsPanelComponent.ts +0 -0
  104. /package/{extensions → plugins}/loaders/GLTFCloudLoader.ts +0 -0
  105. /package/{extensions → plugins}/loaders/GLTFFileLoader.ts +0 -0
  106. /package/{extensions → plugins}/loaders/IFCX/IFCXCloudLoader.ts +0 -0
  107. /package/{extensions → plugins}/loaders/IFCX/IFCXFileLoader.ts +0 -0
  108. /package/{extensions → plugins}/loaders/IFCX/IFCXLoader.ts +0 -0
  109. /package/{extensions → plugins}/loaders/IFCX/index.ts +0 -0
  110. /package/{extensions → plugins}/loaders/IFCX/render.js +0 -0
  111. /package/{extensions → plugins}/loaders/Potree/PotreeFileLoader.ts +0 -0
  112. /package/{extensions → plugins}/loaders/Potree/PotreeModelImpl.ts +0 -0
  113. /package/{extensions → plugins}/loaders/Potree/index.ts +0 -0
@@ -23,7 +23,7 @@
23
23
 
24
24
  import { draggersRegistry, commandsRegistry, Options, componentsRegistry, Loader, loadersRegistry, 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, Raycaster, MathUtils, EdgesGeometry, Matrix4, Vector4, Controls, Clock, Sphere, Box3, Color, PerspectiveCamera, OrthographicCamera, AmbientLight, DirectionalLight, HemisphereLight, MeshPhongMaterial, WebGLRenderTarget, UnsignedByteType, RGBAFormat, CylinderGeometry, Sprite, CanvasTexture, SRGBColorSpace, SpriteMaterial, TextureLoader, BufferAttribute, PointsMaterial, Points, TriangleStripDrawMode, TriangleFanDrawMode, LineSegments, LineLoop, Group, NormalBlending, LoadingManager, LoaderUtils, FileLoader, 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, TextureLoader, BufferAttribute, PointsMaterial, Points, TriangleStripDrawMode, TriangleFanDrawMode, LineSegments, LineLoop, Group, NormalBlending, LoadingManager, LoaderUtils, FileLoader, 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';
@@ -913,91 +913,116 @@ class CuttingPlaneZAxisDragger extends CuttingPlaneDragger {
913
913
  }
914
914
  }
915
915
 
916
- const ModelUnits = {
917
- Meters: { name: "Meters", type: "m", scale: 1.0 },
918
- Centimeters: { name: "Centimeters", type: "cm", scale: 0.01 },
919
- Millimeters: { name: "Millimeters", type: "mm", scale: 0.001 },
920
- Feet: { name: "Feet", type: "ft", scale: 0.3048 },
921
- Inches: { name: "Inches", type: "in", scale: 0.0254 },
922
- Yards: { name: "Yards", type: "yd", scale: 0.9144 },
923
- Kilometers: { name: "Kilometers", type: "km", scale: 1000.0 },
924
- Miles: { name: "Miles", type: "mi", scale: 1609.344 },
925
- Micrometers: { name: "Micrometers", type: "µm", scale: 0.000001 },
926
- Mils: { name: "Mils", type: "mil", scale: 0.0000254 },
927
- MicroInches: { name: "Micro-inches", type: "µin", scale: 0.0000000254 },
928
- Default: { name: "File units", type: "unit", scale: 1.0 },
929
- };
930
- function convertUnits(fromUnits, toUnits, distance) {
931
- const fromFactor = 1 / (ModelUnits[fromUnits] || ModelUnits.Default).scale;
932
- const toFactor = (ModelUnits[toUnits] || ModelUnits.Default).scale || 1;
933
- return distance * fromFactor * toFactor;
934
- }
935
-
936
- function getDisplayUnit(units) {
937
- return (ModelUnits[units] || ModelUnits.Default).type;
938
- }
939
- function calculatePrecision(value) {
940
- const distance = Math.abs(value);
941
- if (distance >= 1000)
942
- return 0;
943
- if (distance >= 10)
944
- return 1;
945
- if (distance >= 0.1)
946
- return 2;
947
- if (distance >= 0.001)
948
- return 3;
949
- return distance > 0 ? Math.floor(-Math.log10(distance)) + 1 : 2;
950
- }
951
- function formatNumber(distance, digits, precision) {
952
- let result = distance.toFixed(digits);
953
- if (precision === "Auto")
954
- result = result.replace(/\.0+$/, "").replace(/\.$/, "");
955
- if (+result !== distance)
956
- result = "~ " + result;
957
- return result;
958
- }
959
- function formatDistance(distance, units, precision = 2) {
960
- let digits;
961
- if (precision === "Auto")
962
- digits = calculatePrecision(distance);
963
- else if (Number.isFinite(precision))
964
- digits = precision;
965
- else
966
- digits = parseFloat(precision);
967
- if (!Number.isFinite(digits))
968
- digits = 2;
969
- else if (digits < 0)
970
- digits = 0;
971
- else if (digits > 10)
972
- digits = 10;
973
- if (ModelUnits[units]) {
974
- return formatNumber(distance, digits, precision) + " " + ModelUnits[units].type;
975
- }
976
- else if (units) {
977
- return formatNumber(distance, digits, precision) + " " + units;
978
- }
979
- else {
980
- return formatNumber(distance, digits, precision);
981
- }
982
- }
983
-
916
+ const PRECISION = 0.01;
984
917
  const DESKTOP_SNAP_DISTANCE = 10;
985
918
  const MOBILE_SNAP_DISTANCE = 50;
919
+ class MeasureLineDragger extends OrbitDragger {
920
+ constructor(viewer) {
921
+ super(viewer);
922
+ this.onPointerDown = (event) => {
923
+ if (event.button !== 0)
924
+ return;
925
+ this.line.startPoint = this.snapper.getSnapPoint(event);
926
+ this.line.render();
927
+ this.viewer.canvas.setPointerCapture(event.pointerId);
928
+ this.orbit.enabled = !this.line.startPoint;
929
+ };
930
+ this.onPointerMove = (event) => {
931
+ if (this.orbit.enabled && this.orbit.state !== -1)
932
+ return;
933
+ const snapPoint = this.snapper.getSnapPoint(event);
934
+ if (snapPoint && this.line.endPoint && snapPoint.equals(this.line.endPoint))
935
+ return;
936
+ this.line.endPoint = snapPoint;
937
+ this.line.render();
938
+ if (this.line.startPoint)
939
+ this.changed = true;
940
+ };
941
+ this.onPointerUp = (event) => {
942
+ if (this.line.startPoint && this.line.endPoint && this.line.getDistance() >= PRECISION) {
943
+ this.line = new MeasureLine(this.overlay);
944
+ this.overlay.addLine(this.line);
945
+ }
946
+ else {
947
+ this.line.startPoint = undefined;
948
+ this.line.endPoint = undefined;
949
+ this.line.render();
950
+ }
951
+ this.viewer.canvas.releasePointerCapture(event.pointerId);
952
+ this.orbit.enabled = true;
953
+ };
954
+ this.onPointerCancel = (event) => {
955
+ this.viewer.canvas.dispatchEvent(new PointerEvent("pointerup", event));
956
+ };
957
+ this.onPointerLeave = () => {
958
+ this.line.endPoint = undefined;
959
+ this.line.render();
960
+ };
961
+ this.renderOverlay = () => {
962
+ this.overlay.render();
963
+ };
964
+ this.updateSnapper = () => {
965
+ this.snapper.setFromViewer(this.viewer);
966
+ };
967
+ this.updateSnapperCamera = () => {
968
+ this.snapper.camera = this.viewer.camera;
969
+ this.overlay.camera = this.viewer.camera;
970
+ };
971
+ this.overlay = new MeasureOverlay(viewer.camera, viewer.canvas);
972
+ this.overlay.attach();
973
+ this.line = new MeasureLine(this.overlay);
974
+ this.overlay.addLine(this.line);
975
+ this.snapper = new MeasureSnapper(viewer.camera, viewer.canvas);
976
+ this.updateSnapper();
977
+ this.viewer.canvas.addEventListener("pointerdown", this.onPointerDown);
978
+ this.viewer.canvas.addEventListener("pointermove", this.onPointerMove);
979
+ this.viewer.canvas.addEventListener("pointerup", this.onPointerUp);
980
+ this.viewer.canvas.addEventListener("pointercancel", this.onPointerCancel);
981
+ this.viewer.canvas.addEventListener("pointerleave", this.onPointerLeave);
982
+ this.viewer.addEventListener("render", this.renderOverlay);
983
+ this.viewer.addEventListener("hide", this.updateSnapper);
984
+ this.viewer.addEventListener("isolate", this.updateSnapper);
985
+ this.viewer.addEventListener("show", this.updateSnapper);
986
+ this.viewer.addEventListener("showall", this.updateSnapper);
987
+ this.viewer.addEventListener("changecameramode", this.updateSnapperCamera);
988
+ }
989
+ dispose() {
990
+ this.viewer.canvas.removeEventListener("pointerdown", this.onPointerDown);
991
+ this.viewer.canvas.removeEventListener("pointermove", this.onPointerMove);
992
+ this.viewer.canvas.removeEventListener("pointerup", this.onPointerUp);
993
+ this.viewer.canvas.removeEventListener("pointercancel", this.onPointerCancel);
994
+ this.viewer.canvas.removeEventListener("pointerleave", this.onPointerLeave);
995
+ this.viewer.removeEventListener("render", this.renderOverlay);
996
+ this.viewer.removeEventListener("hide", this.updateSnapper);
997
+ this.viewer.removeEventListener("isolate", this.updateSnapper);
998
+ this.viewer.removeEventListener("show", this.updateSnapper);
999
+ this.viewer.removeEventListener("showall", this.updateSnapper);
1000
+ this.viewer.removeEventListener("changecameramode", this.updateSnapperCamera);
1001
+ this.snapper.dispose();
1002
+ this.overlay.detach();
1003
+ this.overlay.dispose();
1004
+ super.dispose();
1005
+ }
1006
+ }
986
1007
  const _vertex = new Vector3();
987
1008
  const _start = new Vector3();
988
1009
  const _end = new Vector3();
989
1010
  const _line = new Line3();
990
1011
  const _center = new Vector3();
991
1012
  const _projection = new Vector3();
992
- class Snapper {
993
- constructor(camera, renderer, canvas) {
1013
+ class MeasureSnapper {
1014
+ constructor(camera, canvas) {
994
1015
  this.camera = camera;
995
- this.renderer = renderer;
996
1016
  this.canvas = canvas;
1017
+ this.objects = [];
1018
+ this.clippingPlanes = [];
997
1019
  this.raycaster = new Raycaster();
998
1020
  this.detectRadiusInPixels = this.isMobile() ? MOBILE_SNAP_DISTANCE : DESKTOP_SNAP_DISTANCE;
999
1021
  this.edgesCache = new WeakMap();
1000
1022
  }
1023
+ dispose() {
1024
+ this.objects = [];
1025
+ }
1001
1026
  isMobile() {
1002
1027
  if (typeof navigator === "undefined")
1003
1028
  return false;
@@ -1006,7 +1031,7 @@ class Snapper {
1006
1031
  getMousePosition(event, target) {
1007
1032
  return target.set(event.clientX, event.clientY);
1008
1033
  }
1009
- getPointerIntersects(mouse, objects) {
1034
+ getPointerIntersects(mouse) {
1010
1035
  const rect = this.canvas.getBoundingClientRect();
1011
1036
  const x = ((mouse.x - rect.left) / rect.width) * 2 - 1;
1012
1037
  const y = (-(mouse.y - rect.top) / rect.height) * 2 + 1;
@@ -1020,8 +1045,8 @@ class Snapper {
1020
1045
  Points: { threshold: 0.01 },
1021
1046
  Sprite: {},
1022
1047
  };
1023
- let intersects = this.raycaster.intersectObjects(objects, false);
1024
- (this.renderer.clippingPlanes || []).forEach((plane) => {
1048
+ let intersects = this.raycaster.intersectObjects(this.objects, false);
1049
+ this.clippingPlanes.forEach((plane) => {
1025
1050
  intersects = intersects.filter((intersect) => plane.distanceToPoint(intersect.point) >= 0);
1026
1051
  });
1027
1052
  return intersects;
@@ -1043,8 +1068,9 @@ class Snapper {
1043
1068
  }
1044
1069
  return 0.1;
1045
1070
  }
1046
- getSnapPoint(mouse, objects) {
1047
- const intersections = this.getPointerIntersects(mouse, objects);
1071
+ getSnapPoint(event) {
1072
+ const mouse = this.getMousePosition(event, new Vector2());
1073
+ const intersections = this.getPointerIntersects(mouse);
1048
1074
  if (intersections.length === 0)
1049
1075
  return undefined;
1050
1076
  const object = intersections[0].object;
@@ -1092,133 +1118,13 @@ class Snapper {
1092
1118
  return object.localToWorld(snapPoint);
1093
1119
  return intersectionPoint.clone();
1094
1120
  }
1095
- }
1096
-
1097
- const _downPoint = new Vector2();
1098
- class MeasureLineDragger extends OrbitDragger {
1099
- constructor(viewer) {
1100
- super(viewer);
1101
- this.scale = 1.0;
1102
- this.units = "";
1103
- this.precision = 2;
1104
- this.onPointerDown = (event) => {
1105
- if (event.button !== 0)
1106
- return;
1107
- const mouse = this.snapper.getMousePosition(event, _downPoint);
1108
- this.line.startPoint = this.snapper.getSnapPoint(mouse, this.objects);
1109
- this.line.render();
1110
- this.viewer.canvas.setPointerCapture(event.pointerId);
1111
- this.orbit.enabled = !this.line.startPoint;
1112
- };
1113
- this.onPointerMove = (event) => {
1114
- if (this.orbit.enabled && this.orbit.state !== -1)
1115
- return;
1116
- const mouse = this.snapper.getMousePosition(event, _downPoint);
1117
- const snapPoint = this.snapper.getSnapPoint(mouse, this.objects);
1118
- if (snapPoint && this.line.endPoint && snapPoint.equals(this.line.endPoint))
1119
- return;
1120
- this.line.endPoint = snapPoint;
1121
- this.line.render();
1122
- if (this.line.startPoint)
1123
- this.changed = true;
1124
- };
1125
- this.onPointerUp = (event) => {
1126
- if (this.line.startPoint && this.line.endPoint && this.line.getDistance() > 0) {
1127
- this.line = new MeasureLine(this.overlay, this.scale, this.units, this.precision);
1128
- this.overlay.addLine(this.line);
1129
- }
1130
- else {
1131
- this.line.startPoint = undefined;
1132
- this.line.endPoint = undefined;
1133
- this.line.render();
1134
- }
1135
- this.viewer.canvas.releasePointerCapture(event.pointerId);
1136
- this.orbit.enabled = true;
1137
- };
1138
- this.onPointerCancel = (event) => {
1139
- this.viewer.canvas.dispatchEvent(new PointerEvent("pointerup", event));
1140
- };
1141
- this.onPointerLeave = () => {
1142
- this.line.endPoint = undefined;
1143
- this.line.render();
1144
- };
1145
- this.clearOverlay = () => {
1146
- this.overlay.clear();
1147
- this.line = new MeasureLine(this.overlay, this.scale, this.units, this.precision);
1148
- this.overlay.addLine(this.line);
1149
- };
1150
- this.renderOverlay = () => {
1151
- this.overlay.render();
1152
- };
1153
- this.updateObjects = () => {
1154
- this.objects.length = 0;
1155
- this.viewer.models.forEach((model) => {
1156
- model.getVisibleObjects().forEach((object) => this.objects.push(object));
1157
- });
1158
- };
1159
- this.updateSnapperCamera = () => {
1160
- this.snapper.camera = this.viewer.camera;
1161
- this.overlay.camera = this.viewer.camera;
1162
- };
1163
- this.updateUnits = () => {
1164
- var _a, _b;
1165
- const model = this.viewer.models[0];
1166
- const units = (_a = this.viewer.options.rulerUnit) !== null && _a !== void 0 ? _a : "Default";
1167
- const precision = (_b = this.viewer.options.rulerPrecision) !== null && _b !== void 0 ? _b : "Default";
1168
- if (units === "Default") {
1169
- this.scale = model.getUnitScale();
1170
- this.units = model.getUnitString();
1171
- }
1172
- else {
1173
- this.scale = convertUnits(model.getUnits(), units, 1);
1174
- this.units = units;
1175
- }
1176
- if (precision === "Default") {
1177
- this.precision = model.getPrecision();
1178
- }
1179
- else {
1180
- this.precision = precision;
1181
- }
1182
- this.overlay.updateLineUnits(this.scale, this.units, this.precision);
1183
- };
1184
- this.overlay = new MeasureOverlay(viewer.camera, viewer.canvas);
1185
- this.overlay.attach();
1186
- this.line = new MeasureLine(this.overlay, this.scale, this.units, this.precision);
1187
- this.overlay.addLine(this.line);
1188
- this.snapper = new Snapper(viewer.camera, viewer.renderer, viewer.canvas);
1189
- this.objects = [];
1190
- this.updateObjects();
1191
- this.updateUnits();
1192
- this.viewer.canvas.addEventListener("pointerdown", this.onPointerDown);
1193
- this.viewer.canvas.addEventListener("pointermove", this.onPointerMove);
1194
- this.viewer.canvas.addEventListener("pointerup", this.onPointerUp);
1195
- this.viewer.canvas.addEventListener("pointercancel", this.onPointerCancel);
1196
- this.viewer.canvas.addEventListener("pointerleave", this.onPointerLeave);
1197
- this.viewer.addEventListener("render", this.renderOverlay);
1198
- this.viewer.addEventListener("hide", this.updateObjects);
1199
- this.viewer.addEventListener("isolate", this.updateObjects);
1200
- this.viewer.addEventListener("show", this.updateObjects);
1201
- this.viewer.addEventListener("showall", this.updateObjects);
1202
- this.viewer.addEventListener("changecameramode", this.updateSnapperCamera);
1203
- this.viewer.addEventListener("optionschange", this.updateUnits);
1204
- }
1205
- dispose() {
1206
- this.viewer.canvas.removeEventListener("pointerdown", this.onPointerDown);
1207
- this.viewer.canvas.removeEventListener("pointermove", this.onPointerMove);
1208
- this.viewer.canvas.removeEventListener("pointerup", this.onPointerUp);
1209
- this.viewer.canvas.removeEventListener("pointercancel", this.onPointerCancel);
1210
- this.viewer.canvas.removeEventListener("pointerleave", this.onPointerLeave);
1211
- this.viewer.removeEventListener("render", this.renderOverlay);
1212
- this.viewer.removeEventListener("hide", this.updateObjects);
1213
- this.viewer.removeEventListener("isolate", this.updateObjects);
1214
- this.viewer.removeEventListener("show", this.updateObjects);
1215
- this.viewer.removeEventListener("showall", this.updateObjects);
1216
- this.viewer.removeEventListener("changecameramode", this.updateSnapperCamera);
1217
- this.viewer.removeEventListener("optionschange", this.updateUnits);
1121
+ setFromViewer(viewer) {
1218
1122
  this.objects.length = 0;
1219
- this.overlay.detach();
1220
- this.overlay.dispose();
1221
- super.dispose();
1123
+ viewer.models.forEach((model) => {
1124
+ model.getVisibleObjects().forEach((object) => this.objects.push(object));
1125
+ });
1126
+ this.camera = viewer.camera;
1127
+ this.clippingPlanes = viewer.renderer.clippingPlanes || [];
1222
1128
  }
1223
1129
  }
1224
1130
  class MeasureOverlay {
@@ -1238,9 +1144,6 @@ class MeasureOverlay {
1238
1144
  this.projector = new MeasureProjector(camera, canvas);
1239
1145
  this.resizeObserver = new ResizeObserver(this.resizeContainer);
1240
1146
  }
1241
- dispose() {
1242
- this.clear();
1243
- }
1244
1147
  attach() {
1245
1148
  this.container = document.createElement("div");
1246
1149
  this.container.id = "measure-container";
@@ -1253,6 +1156,9 @@ class MeasureOverlay {
1253
1156
  this.canvas.parentElement.appendChild(this.container);
1254
1157
  this.resizeObserver.observe(this.canvas);
1255
1158
  }
1159
+ dispose() {
1160
+ this.clear();
1161
+ }
1256
1162
  detach() {
1257
1163
  this.resizeObserver.disconnect();
1258
1164
  this.container.remove();
@@ -1260,7 +1166,7 @@ class MeasureOverlay {
1260
1166
  }
1261
1167
  clear() {
1262
1168
  this.lines.forEach((line) => line.dispose());
1263
- this.lines.length = 0;
1169
+ this.lines = [];
1264
1170
  }
1265
1171
  render() {
1266
1172
  this.projector.setFromCamera(this.camera);
@@ -1275,18 +1181,13 @@ class MeasureOverlay {
1275
1181
  removeLine(line) {
1276
1182
  this.lines = this.lines.filter((x) => x !== line);
1277
1183
  }
1278
- updateLineUnits(scale, units, precision) {
1279
- this.lines.forEach((line) => {
1280
- line.scale = scale;
1281
- line.units = units;
1282
- line.precision = precision;
1283
- });
1284
- }
1285
1184
  }
1286
1185
  const _middlePoint = new Vector3();
1287
1186
  class MeasureLine {
1288
- constructor(overlay, scale, units, precision) {
1187
+ constructor(overlay) {
1289
1188
  this.id = MathUtils.generateUUID();
1189
+ this.unit = "";
1190
+ this.scale = 1.0;
1290
1191
  this.size = 10.0;
1291
1192
  this.lineWidth = 2;
1292
1193
  this.style = {
@@ -1297,9 +1198,6 @@ class MeasureLine {
1297
1198
  font: "1rem system-ui",
1298
1199
  };
1299
1200
  this.overlay = overlay;
1300
- this.scale = scale;
1301
- this.units = units;
1302
- this.precision = precision;
1303
1201
  this.elementStartPoint = overlay.container.appendChild(document.createElement("div"));
1304
1202
  this.elementEndPoint = overlay.container.appendChild(document.createElement("div"));
1305
1203
  this.elementLine = overlay.container.appendChild(document.createElement("div"));
@@ -1354,10 +1252,10 @@ class MeasureLine {
1354
1252
  _middlePoint.lerpVectors(this.startPoint, this.endPoint, 0.5);
1355
1253
  const { point, visible } = projector.projectPoint(_middlePoint);
1356
1254
  const distance = this.getDistance();
1357
- this.elementLabel.style.display = visible && distance > 0 ? "block" : "none";
1255
+ this.elementLabel.style.display = visible && distance >= PRECISION ? "block" : "none";
1358
1256
  this.elementLabel.style.left = `${point.x}px`;
1359
1257
  this.elementLabel.style.top = `${point.y}px`;
1360
- this.elementLabel.innerHTML = formatDistance(distance, this.units, this.precision);
1258
+ this.elementLabel.innerHTML = `${distance.toFixed(2)} ${this.unit}`;
1361
1259
  }
1362
1260
  else {
1363
1261
  this.elementLabel.style.display = "none";
@@ -2880,11 +2778,10 @@ class SelectionComponent {
2880
2778
  const upPosition = this.getMousePosition(event, new Vector2());
2881
2779
  if (upPosition.distanceTo(this.downPosition) !== 0)
2882
2780
  return;
2883
- const snapper = new Snapper(this.viewer.camera, this.viewer.renderer, this.viewer.canvas);
2884
2781
  let intersections = [];
2885
2782
  this.viewer.models.forEach((model) => {
2886
2783
  const objects = model.getVisibleObjects();
2887
- const intersects = snapper.getPointerIntersects(upPosition, objects);
2784
+ const intersects = this.getPointerIntersects(upPosition, objects);
2888
2785
  if (intersects.length > 0)
2889
2786
  intersections.push({ ...intersects[0], model });
2890
2787
  });
@@ -2913,6 +2810,7 @@ class SelectionComponent {
2913
2810
  this.highlighter = this.viewer.getComponent("HighlighterComponent");
2914
2811
  };
2915
2812
  this.viewer = viewer;
2813
+ this.raycaster = new Raycaster();
2916
2814
  this.downPosition = new Vector2();
2917
2815
  this.viewer.addEventListener("pointerdown", this.onPointerDown);
2918
2816
  this.viewer.addEventListener("pointerup", this.onPointerUp);
@@ -2928,6 +2826,26 @@ class SelectionComponent {
2928
2826
  getMousePosition(event, target) {
2929
2827
  return target.set(event.clientX, event.clientY);
2930
2828
  }
2829
+ getPointerIntersects(mouse, objects) {
2830
+ const rect = this.viewer.canvas.getBoundingClientRect();
2831
+ const x = ((mouse.x - rect.left) / rect.width) * 2 - 1;
2832
+ const y = (-(mouse.y - rect.top) / rect.height) * 2 + 1;
2833
+ const coords = new Vector2(x, y);
2834
+ this.raycaster.setFromCamera(coords, this.viewer.camera);
2835
+ this.raycaster.params = {
2836
+ Mesh: {},
2837
+ Line: { threshold: 0.05 },
2838
+ Line2: { threshold: 0.05 },
2839
+ LOD: {},
2840
+ Points: { threshold: 0.01 },
2841
+ Sprite: {},
2842
+ };
2843
+ let intersects = this.raycaster.intersectObjects(objects, false);
2844
+ (this.viewer.renderer.clippingPlanes || []).forEach((plane) => {
2845
+ intersects = intersects.filter((intersect) => plane.distanceToPoint(intersect.point) >= 0);
2846
+ });
2847
+ return intersects;
2848
+ }
2931
2849
  select(objects, model) {
2932
2850
  if (!model) {
2933
2851
  this.viewer.models.forEach((model) => this.select(objects, model));
@@ -3147,18 +3065,6 @@ class ModelImpl {
3147
3065
  this.scene.traverse(disposeObject);
3148
3066
  this.scene.clear();
3149
3067
  }
3150
- getUnits() {
3151
- return "Meters";
3152
- }
3153
- getUnitScale() {
3154
- return convertUnits(this.getUnits(), "Meters", 1);
3155
- }
3156
- getUnitString() {
3157
- return getDisplayUnit(this.getUnits());
3158
- }
3159
- getPrecision() {
3160
- return 2;
3161
- }
3162
3068
  getExtents(target) {
3163
3069
  this.scene.traverseVisible((object) => !object.children.length && target.expandByObject(object));
3164
3070
  return target;
@@ -3406,7 +3312,6 @@ class GltfStructure {
3406
3312
  this.textureCache = new Map();
3407
3313
  this.materialCache = new Map();
3408
3314
  this.uri = "";
3409
- this._nextObjectId = 0;
3410
3315
  }
3411
3316
  async initialize(loader) {
3412
3317
  this.json = await this.loadController.loadJson();
@@ -4277,7 +4182,7 @@ class DynamicGltfLoader {
4277
4182
  if (node.handle) {
4278
4183
  mesh.userData.handle = node.handle;
4279
4184
  } else {
4280
- mesh.userData.handle = this.getFullHandle(node.structure.id, mesh.userData.handle);
4185
+ mesh.userData.handle = `${node.structure.id}${STRUCTURE_ID_SEPARATOR}${mesh.userData.handle}`;
4281
4186
  }
4282
4187
  if (mesh.material.name === "edges") {
4283
4188
  mesh.userData.isEdge = true;
@@ -4418,15 +4323,12 @@ class DynamicGltfLoader {
4418
4323
  })),
4419
4324
  });
4420
4325
  }
4421
- getFullHandle(structureId, originalHandle) {
4422
- return `${structureId}${STRUCTURE_ID_SEPARATOR}${originalHandle}`;
4423
- }
4424
4326
  async processNodeHierarchy(structure, nodeId, parentGroup) {
4425
4327
  const nodeDef = structure.json.nodes[nodeId];
4426
4328
  let nodeGroup = null;
4427
4329
  let handle = null;
4428
4330
  if (nodeDef.extras?.handle) {
4429
- handle = this.getFullHandle(structure.id, nodeDef.extras.handle);
4331
+ handle = `${structure.id}${STRUCTURE_ID_SEPARATOR}${nodeDef.extras.handle}`;
4430
4332
  }
4431
4333
  if (nodeDef.camera !== undefined) {
4432
4334
  const camera = this.loadCamera(structure, nodeDef.camera, nodeDef);
@@ -4443,7 +4345,7 @@ class DynamicGltfLoader {
4443
4345
  if (nodeDef.extras) {
4444
4346
  nodeGroup.userData = { ...nodeDef.extras };
4445
4347
  if (nodeGroup.userData.handle) {
4446
- nodeGroup.userData.handle = this.getFullHandle(structure.id, nodeGroup.userData.handle);
4348
+ nodeGroup.userData.handle = `${structure.id}${STRUCTURE_ID_SEPARATOR}${nodeGroup.userData.handle}`;
4447
4349
  }
4448
4350
  }
4449
4351
  if (nodeDef.matrix) {
@@ -4488,7 +4390,7 @@ class DynamicGltfLoader {
4488
4390
  this.edgeNodes.push(uniqueNodeId);
4489
4391
  }
4490
4392
  if (meshDef.extras && meshDef.extras.handle) {
4491
- handle = this.getFullHandle(structure.id, meshDef.extras.handle);
4393
+ handle = `${structure.id}${STRUCTURE_ID_SEPARATOR}${meshDef.extras.handle}`;
4492
4394
  }
4493
4395
  this.nodes.set(uniqueNodeId, {
4494
4396
  position: nodeGroup ? nodeGroup.position.clone() : new Vector3().setFromMatrixPosition(nodeMatrix),
@@ -4501,7 +4403,7 @@ class DynamicGltfLoader {
4501
4403
  structure,
4502
4404
  extras: nodeDef.extras,
4503
4405
  geometryExtents,
4504
- handle: handle || this.getFullHandle(structure.id, structure._nextObjectId++),
4406
+ handle,
4505
4407
  });
4506
4408
  }
4507
4409
  if (nodeDef.children) {
@@ -5084,6 +4986,8 @@ class DynamicGltfLoader {
5084
4986
  let currentVertexOffset = 0;
5085
4987
  for (const mesh of group.objects) {
5086
4988
  const geometry = mesh.geometry.clone();
4989
+ mesh.updateWorldMatrix(true, false);
4990
+ geometry.applyMatrix4(mesh.matrixWorld);
5087
4991
  const handle = mesh.userData.handle;
5088
4992
  if (!this.objectIdToIndex.has(handle)) {
5089
4993
  this.objectIdToIndex.set(handle, this.maxObjectId++);
@@ -5189,9 +5093,12 @@ class DynamicGltfLoader {
5189
5093
  vertexCount,
5190
5094
  });
5191
5095
  currentVertexOffset += vertexCount;
5096
+ line.updateWorldMatrix(true, false);
5097
+ const matrix = line.matrixWorld;
5192
5098
  const vector = new Vector3();
5193
5099
  for (let i = 0; i < vertexCount; i++) {
5194
5100
  vector.fromBufferAttribute(positionAttr, i);
5101
+ vector.applyMatrix4(matrix);
5195
5102
  positions[posOffset++] = vector.x;
5196
5103
  positions[posOffset++] = vector.y;
5197
5104
  positions[posOffset++] = vector.z;
@@ -5270,6 +5177,8 @@ class DynamicGltfLoader {
5270
5177
  for (const line of group.objects) {
5271
5178
  isEdge = line.userData.isEdge;
5272
5179
  const geometry = line.geometry.clone();
5180
+ line.updateWorldMatrix(true, false);
5181
+ geometry.applyMatrix4(line.matrixWorld);
5273
5182
  const handle = line.userData.handle;
5274
5183
  if (!this.objectIdToIndex.has(handle)) {
5275
5184
  this.objectIdToIndex.set(handle, this.maxObjectId++);
@@ -5354,6 +5263,8 @@ class DynamicGltfLoader {
5354
5263
  const handles = new Set();
5355
5264
  for (const points of group.objects) {
5356
5265
  const geometry = points.geometry.clone();
5266
+ points.updateWorldMatrix(true, false);
5267
+ geometry.applyMatrix4(points.matrixWorld);
5357
5268
  geometries.push(geometry);
5358
5269
  optimizedObjects.push(points);
5359
5270
  handles.add(points.userData.handle);
@@ -5404,6 +5315,7 @@ class DynamicGltfLoader {
5404
5315
  const hasNormals = lineSegmentsArray.some((segment) => segment.geometry.attributes.normal !== undefined);
5405
5316
  lineSegmentsArray.forEach((segment) => {
5406
5317
  const clonedGeometry = segment.geometry.clone();
5318
+ segment.updateWorldMatrix(true, false);
5407
5319
  clonedGeometry.applyMatrix4(segment.matrixWorld);
5408
5320
  if (hasNormals && !clonedGeometry.attributes.normal) {
5409
5321
  clonedGeometry.computeVertexNormals();