@xeokit/xeokit-sdk 2.6.73 → 2.6.77-slim-rc1

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 (77) hide show
  1. package/dist/xeokit-sdk.cjs.js +246 -126
  2. package/dist/xeokit-sdk.es.js +246 -126
  3. package/dist/xeokit-sdk.es5.js +316 -306
  4. package/dist/xeokit-sdk.min.cjs.js +8 -8
  5. package/dist/xeokit-sdk.min.es.js +8 -8
  6. package/dist/xeokit-sdk.min.es5.js +7 -7
  7. package/package.json +2 -1
  8. package/src/extras/ContextMenu/ContextMenu.js +25 -16
  9. package/src/extras/Skybox/Skybox.js +139 -0
  10. package/src/extras/index.js +2 -1
  11. package/src/plugins/CxConverterIFCLoaderPlugin/CxConverterIFCLoaderPlugin.js +81 -81
  12. package/src/plugins/CxConverterIFCLoaderPlugin/index.js +1 -1
  13. package/src/plugins/FastNavPlugin/FastNavPlugin.js +10 -18
  14. package/src/plugins/SectionPlanesPlugin/Control.js +1 -1
  15. package/src/plugins/TreeViewPlugin/RenderService.js +13 -4
  16. package/src/plugins/TreeViewPlugin/TreeViewPlugin.js +1 -1
  17. package/src/plugins/index.js +0 -1
  18. package/src/viewer/Viewer.js +0 -16
  19. package/src/viewer/scene/CameraControl/lib/controllers/PivotController.js +29 -8
  20. package/src/viewer/scene/LineSet/LineSet.js +7 -2
  21. package/src/viewer/scene/camera/CameraFlightAnimation.js +2 -2
  22. package/src/viewer/scene/canvas/Canvas.js +7 -4
  23. package/src/viewer/scene/index.js +0 -1
  24. package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesColorRenderer.js +5 -0
  25. package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesColorRenderer.js +5 -0
  26. package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesFlatColorRenderer.js +5 -0
  27. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesColorRenderer.js +5 -0
  28. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesFlatColorRenderer.js +5 -0
  29. package/types/plugins/FastNavPlugin/FastNavPlugin.d.ts +5 -0
  30. package/types/plugins/index.d.ts +0 -1
  31. package/types/viewer/scene/CameraControl/CameraControl.d.ts +168 -0
  32. package/types/viewer/scene/LineSet/LineSet.d.ts +1 -1
  33. package/types/viewer/scene/camera/CameraPath.d.ts +86 -6
  34. package/types/viewer/scene/camera/CameraPathAnimation.d.ts +2 -0
  35. package/types/viewer/scene/geometry/ReadableGeometry.d.ts +14 -0
  36. package/types/viewer/scene/geometry/VBOGeometry.d.ts +2 -0
  37. package/types/viewer/scene/geometry/index.d.ts +2 -1
  38. package/types/viewer/scene/geometry/loaders/index.d.ts +2 -0
  39. package/types/viewer/scene/geometry/loaders/load3DSGeometry.d.ts +17 -0
  40. package/types/viewer/scene/geometry/loaders/loadOBJGeometry.d.ts +18 -0
  41. package/types/viewer/scene/index.d.ts +1 -0
  42. package/types/viewer/scene/input/input.d.ts +117 -0
  43. package/types/viewer/scene/lights/AmbientLight.d.ts +41 -0
  44. package/types/viewer/scene/lights/CubeTexture.d.ts +27 -0
  45. package/types/viewer/scene/lights/DirLight.d.ts +77 -0
  46. package/types/viewer/scene/lights/LightMap.d.ts +27 -0
  47. package/types/viewer/scene/lights/PointLight.d.ts +135 -0
  48. package/types/viewer/scene/lights/ReflectionMap.d.ts +26 -0
  49. package/types/viewer/scene/lights/index.d.ts +4 -1
  50. package/types/viewer/scene/marker/Marker.d.ts +5 -0
  51. package/types/viewer/scene/materials/EmphasisMaterial.d.ts +5 -0
  52. package/types/viewer/scene/materials/Fresnel.d.ts +25 -62
  53. package/types/viewer/scene/materials/LambertMaterial.d.ts +192 -0
  54. package/types/viewer/scene/materials/MetallicMaterial.d.ts +359 -0
  55. package/types/viewer/scene/materials/PhongMaterial.d.ts +5 -0
  56. package/types/viewer/scene/materials/PointsMaterial.d.ts +5 -0
  57. package/types/viewer/scene/materials/SpecularMaterial.d.ts +342 -0
  58. package/types/viewer/scene/materials/Texture.d.ts +36 -78
  59. package/types/viewer/scene/materials/index.d.ts +2 -0
  60. package/types/viewer/scene/models/SceneModel.d.ts +134 -7
  61. package/types/viewer/scene/models/SceneModelEntity.d.ts +65 -0
  62. package/types/viewer/scene/models/SceneModelMesh.d.ts +12 -0
  63. package/types/viewer/scene/paths/CubicBezierCurve.d.ts +146 -0
  64. package/types/viewer/scene/paths/Curve.d.ts +75 -0
  65. package/types/viewer/scene/paths/Path.d.ts +119 -0
  66. package/types/viewer/scene/paths/QuadraticBezierCurve.d.ts +124 -0
  67. package/types/viewer/scene/paths/SplineCurve.d.ts +84 -0
  68. package/types/viewer/scene/paths/index.d.ts +5 -0
  69. package/types/viewer/scene/scene/Scene.d.ts +102 -0
  70. package/types/viewer/scene/sectionPlane/SectionPlane.d.ts +41 -0
  71. package/types/viewer/scene/webgl/PickResult.d.ts +19 -0
  72. package/src/plugins/SkyboxesPlugin/SkyboxesPlugin.js +0 -134
  73. package/src/plugins/SkyboxesPlugin/index.js +0 -1
  74. package/src/viewer/scene/skybox/Skybox.js +0 -123
  75. package/types/plugins/SkyboxesPlugin/SkyboxesPlugin.d.ts +0 -34
  76. package/types/plugins/SkyboxesPlugin/index.d.ts +0 -1
  77. /package/src/{viewer/scene/skybox → extras/Skybox}/index.js +0 -0
@@ -1,7 +1,7 @@
1
1
  /**
2
- * xeokit-sdk v2.6.73
3
- * Commit: 3b3bb2ad8abfdf189cf4ba7f67d6798375772b7b
4
- * Built: 2025-04-10T16:46:49.684Z
2
+ * xeokit-sdk v2.6.76
3
+ * Commit: dd09d800ebb3a626d7767a83af023ed05e49f2fa
4
+ * Built: 2025-05-10T10:08:24.044Z
5
5
  */
6
6
 
7
7
  /** @private */
@@ -346,7 +346,8 @@ class ContextMenu {
346
346
  this._shown = false; // True when the ContextMenu is visible
347
347
  this._nextId = 0;
348
348
  this._parentNode = cfg.parentNode || document.body;
349
-
349
+ this._offsetParent = (this._parentNode instanceof ShadowRoot) ? this._parentNode.host : this._parentNode;
350
+
350
351
  /**
351
352
  * Subscriptions to events fired at this ContextMenu.
352
353
  * @private
@@ -558,7 +559,7 @@ class ContextMenu {
558
559
  for (let i = 0, len = this._menuList.length; i < len; i++) {
559
560
  const menu = this._menuList[i];
560
561
  const menuElement = menu.menuElement;
561
- menuElement.parentElement.removeChild(menuElement);
562
+ menuElement.remove();
562
563
  }
563
564
  this._itemsCfg = [];
564
565
  this._rootMenu = null;
@@ -786,21 +787,22 @@ class ContextMenu {
786
787
 
787
788
  const itemRect = itemElement.getBoundingClientRect();
788
789
  subMenuElement.getBoundingClientRect();
790
+ const offsetRect = self._offsetParent.getBoundingClientRect();
789
791
 
790
792
  const subMenuWidth = 200; // TODO
791
- const showOnRight = (itemRect.right + subMenuWidth) < window.innerWidth;
792
- const showOnLeft = (itemRect.left - subMenuWidth) > 0;
793
-
793
+ const showOnRight = (itemRect.right + subMenuWidth) < offsetRect.right;
794
+ const showOnLeft = (itemRect.left - subMenuWidth) > offsetRect.left;
795
+
794
796
  if(showOnRight)
795
- self._showMenu(subMenu.id, itemRect.right - 5, itemRect.top - 1);
797
+ self._showMenu(subMenu.id, itemRect.right + window.scrollX - 5, itemRect.top + window.scrollY - 1);
796
798
  else if (showOnLeft)
797
- self._showMenu(subMenu.id, itemRect.left - subMenuWidth, itemRect.top - 1);
799
+ self._showMenu(subMenu.id, itemRect.left - subMenuWidth + window.scrollX, itemRect.top + window.scrollY - 1);
798
800
  else {
799
- const spaceOnLeft = itemRect.left, spaceOnRight = window.innerWidth - itemRect.right;
801
+ const spaceOnLeft = itemRect.left - offsetRect.left, spaceOnRight = offsetRect.right - itemRect.right;
800
802
  if(spaceOnRight > spaceOnLeft)
801
- self._showMenu(subMenu.id, itemRect.right - 5 - (subMenuWidth - spaceOnRight), itemRect.top - 1);
803
+ self._showMenu(subMenu.id, itemRect.right - 5 - (subMenuWidth - spaceOnRight), itemRect.top + window.scrollY - 1);
802
804
  else
803
- self._showMenu(subMenu.id, itemRect.left - spaceOnLeft, itemRect.top - 1);
805
+ self._showMenu(subMenu.id, itemRect.left - spaceOnLeft, itemRect.top + window.scrollY - 1);
804
806
  }
805
807
 
806
808
  lastSubMenu = subMenu;
@@ -993,14 +995,21 @@ class ContextMenu {
993
995
  menuElement.style.display = 'block';
994
996
  const menuHeight = menuElement.offsetHeight;
995
997
  const menuWidth = menuElement.offsetWidth;
996
- if ((pageY + menuHeight) > window.innerHeight) {
997
- pageY = window.innerHeight - menuHeight;
998
+
999
+ const offsetRect = this._offsetParent.getBoundingClientRect();
1000
+
1001
+ const bottomContainerBorder = offsetRect.bottom + window.scrollY;
1002
+ const rightContainerBorder = offsetRect.right + window.scrollX;
1003
+ if ((pageY + menuHeight) > bottomContainerBorder) {
1004
+ pageY = bottomContainerBorder- menuHeight;
998
1005
  }
999
- if ((pageX + menuWidth) > window.innerWidth) {
1000
- pageX = window.innerWidth - menuWidth;
1006
+ if ((pageX + menuWidth) > rightContainerBorder) {
1007
+ pageX = rightContainerBorder - menuWidth;
1001
1008
  }
1002
- menuElement.style.left = pageX + 'px';
1003
- menuElement.style.top = pageY + 'px';
1009
+
1010
+
1011
+ menuElement.style.left = pageX - offsetRect.left - window.scrollX + 'px';
1012
+ menuElement.style.top = pageY - offsetRect.top - window.scrollY + 'px';
1004
1013
  }
1005
1014
 
1006
1015
  _hideMenuElement(menuElement) {
@@ -54926,6 +54935,11 @@ class TrianglesColorRenderer$1 extends TrianglesBatchingRenderer {
54926
54935
  src.push(" float dy = dFdy(vFragDepth);");
54927
54936
  src.push(" float diff = sqrt(dx*dx+dy*dy);");
54928
54937
  src.push(" gl_FragDepth = isPerspective == 0.0 ? gl_FragCoord.z : log2( vFragDepth + diff ) * logDepthBufFC * 0.5;");
54938
+ } else {
54939
+ src.push(" float dx = dFdx(gl_FragCoord.z);");
54940
+ src.push(" float dy = dFdy(gl_FragCoord.z);");
54941
+ src.push(" float diff = sqrt(dx*dx+dy*dy);");
54942
+ src.push(" gl_FragDepth = gl_FragCoord.z + diff;");
54929
54943
  }
54930
54944
 
54931
54945
  if (this._withSAO) {
@@ -55180,6 +55194,11 @@ class TrianglesFlatColorRenderer$1 extends TrianglesBatchingRenderer {
55180
55194
 
55181
55195
  if (scene.logarithmicDepthBufferEnabled) {
55182
55196
  src.push(" gl_FragDepth = isPerspective == 0.0 ? gl_FragCoord.z : log2( vFragDepth ) * logDepthBufFC * 0.5;");
55197
+ } else {
55198
+ src.push(" float dx = dFdx(gl_FragCoord.z);");
55199
+ src.push(" float dy = dFdy(gl_FragCoord.z);");
55200
+ src.push(" float diff = sqrt(dx*dx+dy*dy);");
55201
+ src.push(" gl_FragDepth = gl_FragCoord.z + diff;");
55183
55202
  }
55184
55203
 
55185
55204
  src.push("}");
@@ -60282,6 +60301,11 @@ class TrianglesColorRenderer extends TrianglesInstancingRenderer {
60282
60301
  src.push(" float dy = dFdy(vFragDepth);");
60283
60302
  src.push(" float diff = sqrt(dx*dx+dy*dy);");
60284
60303
  src.push(" gl_FragDepth = isPerspective == 0.0 ? gl_FragCoord.z : log2( vFragDepth + diff ) * logDepthBufFC * 0.5;");
60304
+ } else {
60305
+ src.push(" float dx = dFdx(gl_FragCoord.z);");
60306
+ src.push(" float dy = dFdy(gl_FragCoord.z);");
60307
+ src.push(" float diff = sqrt(dx*dx+dy*dy);");
60308
+ src.push(" gl_FragDepth = gl_FragCoord.z + diff;");
60285
60309
  }
60286
60310
 
60287
60311
  // Doing SAO blend in the main solid fill draw shader just so that edge lines can be drawn over the top
@@ -60545,6 +60569,11 @@ class TrianglesFlatColorRenderer extends TrianglesInstancingRenderer {
60545
60569
 
60546
60570
  if (scene.logarithmicDepthBufferEnabled) {
60547
60571
  src.push(" gl_FragDepth = isPerspective == 0.0 ? gl_FragCoord.z : log2( vFragDepth ) * logDepthBufFC * 0.5;");
60572
+ } else {
60573
+ src.push(" float dx = dFdx(gl_FragCoord.z);");
60574
+ src.push(" float dy = dFdy(gl_FragCoord.z);");
60575
+ src.push(" float diff = sqrt(dx*dx+dy*dy);");
60576
+ src.push(" gl_FragDepth = gl_FragCoord.z + diff;");
60548
60577
  }
60549
60578
 
60550
60579
  src.push("}");
@@ -75756,6 +75785,11 @@ class DTXTrianglesColorRenderer {
75756
75785
  if (scene.logarithmicDepthBufferEnabled) {
75757
75786
  src.push(" gl_FragDepth = isPerspective == 0.0 ? gl_FragCoord.z : log2( vFragDepth ) * logDepthBufFC * 0.5;");
75758
75787
  //src.push(" gl_FragDepth = log2( vFragDepth ) * logDepthBufFC * 0.5;");
75788
+ } else {
75789
+ src.push(" float dx = dFdx(gl_FragCoord.z);");
75790
+ src.push(" float dy = dFdy(gl_FragCoord.z);");
75791
+ src.push(" float diff = sqrt(dx*dx+dy*dy);");
75792
+ src.push(" gl_FragDepth = gl_FragCoord.z + diff;");
75759
75793
  }
75760
75794
 
75761
75795
  if (this._withSAO) {
@@ -89179,7 +89213,7 @@ class LineSet extends Component {
89179
89213
  * @param {String} [cfg.id] Optional ID, unique among all components in the parent {@link Scene}, generated automatically when omitted.
89180
89214
  * @param {Number[]} cfg.positions World-space 3D vertex positions.
89181
89215
  * @param {Number[]} [cfg.indices] Indices to connect ````positions```` into line segments. Note that these are separate line segments, not a polyline.
89182
- * @param {Number[]} [cfg.color=[0,0,0]] The color of this ````LineSet````. This is both emissive and diffuse.
89216
+ * @param {Number[]} [cfg.color=[1,1,1]] The color of this ````LineSet````. This is both emissive and diffuse.
89183
89217
  * @param {Boolean} [cfg.visible=true] Indicates whether or not this ````LineSet```` is visible.
89184
89218
  * @param {Number} [cfg.opacity=1.0] ````LineSet````'s initial opacity factor.
89185
89219
  */
@@ -89199,6 +89233,9 @@ class LineSet extends Component {
89199
89233
  }
89200
89234
  }
89201
89235
 
89236
+ this._color = cfg.color || [1, 1, 1];
89237
+ this._opacity = cfg.opacity || 1.0;
89238
+
89202
89239
  this._sceneModel = new SceneModel(this, {
89203
89240
  isModel: false // Don't register in Scene.models
89204
89241
  });
@@ -89207,7 +89244,9 @@ class LineSet extends Component {
89207
89244
  id: "linesMesh",
89208
89245
  primitive: "lines",
89209
89246
  positions: this._positions,
89210
- indices: this._indices
89247
+ indices: this._indices,
89248
+ color: this._color,
89249
+ opacity: this._opacity,
89211
89250
  });
89212
89251
 
89213
89252
  this._sceneModel.createEntity({
@@ -92935,6 +92974,7 @@ class FastNavPlugin extends Plugin {
92935
92974
  * @param {Number} [cfg.scaleCanvasResolutionFactor=0.6] The factor by which we downscale the canvas resolution whenever we interact with the Viewer.
92936
92975
  * @param {Boolean} [cfg.delayBeforeRestore=true] Whether to temporarily have a delay before restoring normal rendering after we stop interacting with the Viewer.
92937
92976
  * @param {Number} [cfg.delayBeforeRestoreSeconds=0.5] Delay in seconds before restoring normal rendering after we stop interacting with the Viewer.
92977
+ * @param {Function} [cfg.onMoved] Optional callback function fired during moving mode, should return the callback function that will be fired when the interaction stops.
92938
92978
  */
92939
92979
  constructor(viewer, cfg = {}) {
92940
92980
 
@@ -92950,6 +92990,8 @@ class FastNavPlugin extends Plugin {
92950
92990
  this._scaleCanvasResolutionFactor = cfg.scaleCanvasResolutionFactor || 0.6;
92951
92991
  this._delayBeforeRestore = (cfg.delayBeforeRestore !== false);
92952
92992
  this._delayBeforeRestoreSeconds = cfg.delayBeforeRestoreSeconds || 0.5;
92993
+ this._onMoved = cfg.onMoved;
92994
+ this._onStopped = null;
92953
92995
 
92954
92996
  let timer = this._delayBeforeRestoreSeconds * 1000;
92955
92997
  let fastMode = false;
@@ -92968,6 +93010,10 @@ class FastNavPlugin extends Plugin {
92968
93010
  } else {
92969
93011
  viewer.scene.canvas.resolutionScale = this._defaultScaleCanvasResolutionFactor;
92970
93012
  }
93013
+ if (this._onMoved) {
93014
+ this._onStopped = this._onMoved();
93015
+ }
93016
+
92971
93017
  fastMode = true;
92972
93018
  }
92973
93019
  };
@@ -92979,10 +93025,12 @@ class FastNavPlugin extends Plugin {
92979
93025
  viewer.scene._renderer.setPBREnabled(true);
92980
93026
  viewer.scene._renderer.setSAOEnabled(true);
92981
93027
  viewer.scene._renderer.setTransparentEnabled(true);
93028
+ if (this._onStopped) {
93029
+ this._onStopped();
93030
+ }
92982
93031
  fastMode = false;
92983
93032
  };
92984
93033
 
92985
- this._onCanvasBoundary = viewer.scene.canvas.on("boundary", switchToLowQuality);
92986
93034
  this._onCameraMatrix = viewer.scene.camera.on("matrix", switchToLowQuality);
92987
93035
 
92988
93036
  this._onSceneTick = viewer.scene.on("tick", (tickEvent) => {
@@ -92994,23 +93042,6 @@ class FastNavPlugin extends Plugin {
92994
93042
  switchToHighQuality();
92995
93043
  }
92996
93044
  });
92997
-
92998
- let down = false;
92999
-
93000
- this._onSceneMouseDown = viewer.scene.input.on("mousedown", () => {
93001
- down = true;
93002
- });
93003
-
93004
- this._onSceneMouseUp = viewer.scene.input.on("mouseup", () => {
93005
- down = false;
93006
- });
93007
-
93008
- this._onSceneMouseMove = viewer.scene.input.on("mousemove", () => {
93009
- if (!down) {
93010
- return;
93011
- }
93012
- switchToLowQuality();
93013
- });
93014
93045
  }
93015
93046
 
93016
93047
  /**
@@ -98305,8 +98336,8 @@ class Skybox extends Component {
98305
98336
  * @param {Component} owner Owner component. When destroyed, the owner will destroy this PointLight as well.
98306
98337
  * @param {*} [cfg] Skybox configuration
98307
98338
  * @param {String} [cfg.id] Optional ID, unique among all components in the parent {Scene}, generated automatically when omitted.
98308
- * @param {String} [cfg.src=null] Path to skybox texture
98309
- * @param {String} [cfg.encoding="linear"] Texture encoding format. See the {@link Texture#encoding} property for more info.
98339
+ * @param {String | String[]} [cfg.src=null] Path to skybox texture
98340
+ * @param {Number} [cfg.encoding=LinearEncoding] Texture encoding format. See the {@link Texture#encoding} property for more info.
98310
98341
  * @param {Number} [cfg.size=1000] Size of this Skybox, given as the distance from the center at ````[0,0,0]```` to each face.
98311
98342
  * @param {Boolean} [cfg.active=true] True when this Skybox is visible.
98312
98343
  */
@@ -98314,6 +98345,32 @@ class Skybox extends Component {
98314
98345
 
98315
98346
  super(owner, cfg);
98316
98347
 
98348
+ const useMultipleTexture = typeof cfg.src === "object" && cfg.src !== null;
98349
+
98350
+ if (useMultipleTexture) {
98351
+ this._createCombinedTexture(cfg).then(combinedTexture => {
98352
+ this._createSkyboxMesh(cfg, combinedTexture);
98353
+ }).catch(e => this.error(e));
98354
+ } else {
98355
+ this._createSkyboxMesh(cfg);
98356
+ }
98357
+ }
98358
+
98359
+ /**
98360
+ *
98361
+ * @private
98362
+ * @param {*} cfg
98363
+ * @param {Texture} combinedTexture
98364
+ */
98365
+ _createSkyboxMesh(cfg, combinedTexture = null) {
98366
+ const texture = combinedTexture || new Texture(this, {
98367
+ src: cfg.src,
98368
+ flipY: true,
98369
+ wrapS: ClampToEdgeWrapping,
98370
+ wrapT: ClampToEdgeWrapping,
98371
+ encoding: cfg.encoding || LinearEncoding
98372
+ });
98373
+
98317
98374
  this._skyboxMesh = new Mesh(this, {
98318
98375
 
98319
98376
  geometry: new ReadableGeometry(this, { // Box-shaped geometry
@@ -98344,13 +98401,7 @@ class Skybox extends Component {
98344
98401
  diffuse: [0, 0, 0],
98345
98402
  specular: [0, 0, 0],
98346
98403
  emissive: [1, 1, 1],
98347
- emissiveMap: new Texture(this, {
98348
- src: cfg.src,
98349
- flipY: true,
98350
- wrapS: "clampToEdge",
98351
- wrapT: "clampToEdge",
98352
- encoding: cfg.encoding || "sRGB"
98353
- }),
98404
+ emissiveMap: texture,
98354
98405
  backfaces: true // Show interior faces of our skybox geometry
98355
98406
  }),
98356
98407
  // stationary: true,
@@ -98364,6 +98415,86 @@ class Skybox extends Component {
98364
98415
  this.active = cfg.active;
98365
98416
  }
98366
98417
 
98418
+ /**
98419
+ *
98420
+ * @private
98421
+ * @param {*} cfg
98422
+ * @returns {Texture}
98423
+ */
98424
+ async _createCombinedTexture(cfg) {
98425
+ const [
98426
+ posX,
98427
+ negX,
98428
+ posY,
98429
+ negY,
98430
+ posZ,
98431
+ negZ
98432
+ ] = cfg.src;
98433
+
98434
+ if (!posX || !negX || !posY || !negY || !posZ || !negZ) {
98435
+ throw new Error("All six skybox textures must be provided");
98436
+ }
98437
+
98438
+ const canvas = document.createElement('canvas');
98439
+ const ctx = canvas.getContext('2d');
98440
+
98441
+ const loadImage = src => {
98442
+ return new Promise((resolve, reject) => {
98443
+ const img = new Image();
98444
+ img.crossOrigin = "anonymous";
98445
+ img.onload = () => resolve(img);
98446
+ img.onerror = () => reject(new Error(`Failed to load image: ${src}`));
98447
+ img.src = src;
98448
+ });
98449
+ };
98450
+
98451
+ try {
98452
+ const [imgPosX, imgNegX, imgPosY, imgNegY, imgPosZ, imgNegZ] = await Promise.all([
98453
+ loadImage(posX),
98454
+ loadImage(negX),
98455
+ loadImage(posY),
98456
+ loadImage(negY),
98457
+ loadImage(posZ),
98458
+ loadImage(negZ)
98459
+ ]);
98460
+
98461
+ const imageSize = imgPosX.width;
98462
+ if (
98463
+ imgNegX.width !== imageSize || imgPosY.width !== imageSize ||
98464
+ imgNegY.width !== imageSize || imgPosZ.width !== imageSize ||
98465
+ imgNegZ.width !== imageSize
98466
+ ) {
98467
+ throw new Error("All skybox textures must have the same dimensions");
98468
+ }
98469
+
98470
+ // Set canvas size for the Christ cross layout (3×4 grid)
98471
+ canvas.width = imageSize * 4;
98472
+ canvas.height = imageSize * 3;
98473
+
98474
+ ctx.fillStyle = 'black';
98475
+ ctx.fillRect(0, 0, canvas.width, canvas.height);
98476
+
98477
+ ctx.drawImage(imgNegX, imageSize * 0, imageSize * 1, imageSize, imageSize); // -X (left)
98478
+ ctx.drawImage(imgPosX, imageSize * 2, imageSize * 1, imageSize, imageSize); // +X (right)
98479
+ ctx.drawImage(imgPosY, imageSize * 1, imageSize * 0, imageSize, imageSize); // +Y (top)
98480
+ ctx.drawImage(imgNegY, imageSize * 1, imageSize * 2, imageSize, imageSize); // -Y (bottom)
98481
+ ctx.drawImage(imgPosZ, imageSize * 1, imageSize * 1, imageSize, imageSize); // +Z (front)
98482
+ ctx.drawImage(imgNegZ, imageSize * 3, imageSize * 1, imageSize, imageSize); // -Z (back)
98483
+
98484
+ const combinedTexture = new Texture(this, {
98485
+ image: canvas,
98486
+ flipY: true,
98487
+ wrapS: ClampToEdgeWrapping,
98488
+ wrapT: ClampToEdgeWrapping,
98489
+ encoding: cfg.encoding || LinearEncoding
98490
+ });
98491
+
98492
+ return combinedTexture;
98493
+ } catch (error) {
98494
+ console.error("Error creating combined skybox texture:", error);
98495
+ throw error;
98496
+ }
98497
+ }
98367
98498
 
98368
98499
  /**
98369
98500
  * Sets the size of this Skybox, given as the distance from the center at [0,0,0] to each face.
@@ -98558,6 +98689,9 @@ const tempVec4a$5 = math.vec4();
98558
98689
  const tempVec4b$5 = math.vec4();
98559
98690
  const tempVec4c = math.vec4();
98560
98691
 
98692
+ const TOP_LIMIT = 0.001;
98693
+ const BOTTOM_LIMIT = Math.PI - 0.001;
98694
+
98561
98695
 
98562
98696
  /** @private */
98563
98697
  class PivotController {
@@ -98733,14 +98867,9 @@ class PivotController {
98733
98867
  */
98734
98868
  startPivot() {
98735
98869
 
98736
- if (this._cameraLookingDownwards()) {
98737
- this._pivoting = false;
98738
- return false;
98739
- }
98740
-
98741
98870
  const camera = this._scene.camera;
98742
98871
 
98743
- let lookat = math.lookAtMat4v(camera.eye, camera.look, camera.worldUp);
98872
+ let lookat = math.lookAtMat4v(camera.eye, camera.look, camera.up);
98744
98873
  math.transformPoint3(lookat, this.getPivotPos(), this._cameraOffset);
98745
98874
 
98746
98875
  const pivotPos = this.getPivotPos();
@@ -98843,8 +98972,31 @@ class PivotController {
98843
98972
  dx = -dx;
98844
98973
  }
98845
98974
  this._azimuth += -dx * .01;
98846
- this._polar += dy * .01;
98847
- this._polar = math.clamp(this._polar, .001, Math.PI - .001);
98975
+
98976
+ const isMovingUp = dy < 0;
98977
+ const isMovingDown = dy > 0;
98978
+
98979
+ // Track if we're at limits - only check if we're very close to the limit
98980
+ const atTopLimit = Math.abs(this._polar - TOP_LIMIT) < 0.005;
98981
+ const atBottomLimit = Math.abs(this._polar - BOTTOM_LIMIT) < 0.005;
98982
+
98983
+ let newPolar = this._polar + dy * .01;
98984
+
98985
+ // Case 1: At top limit and trying to go beyond
98986
+ if (atTopLimit && isMovingUp) {
98987
+ newPolar = TOP_LIMIT;
98988
+ }
98989
+ // Case 2: At bottom limit and trying to go beyond
98990
+ else if (atBottomLimit && isMovingDown) {
98991
+ newPolar = BOTTOM_LIMIT;
98992
+ }
98993
+ // Case 3: Normal rotation or moving away from a limit
98994
+ else {
98995
+ newPolar = math.clamp(newPolar, TOP_LIMIT, BOTTOM_LIMIT);
98996
+ }
98997
+
98998
+ this._polar = newPolar;
98999
+
98848
99000
  const pos = [
98849
99001
  this._radius * Math.sin(this._polar) * Math.sin(this._azimuth),
98850
99002
  this._radius * Math.cos(this._polar),
@@ -112394,22 +112546,6 @@ class Viewer {
112394
112546
  this.sendToPlugins("snapshotStarting"); // Tells plugins to hide things that shouldn't be in snapshot
112395
112547
  }
112396
112548
 
112397
- const captured = {};
112398
- for (let i = 0, len = this._plugins.length; i < len; i++) {
112399
- const plugin = this._plugins[i];
112400
- if (plugin.getContainerElement) {
112401
- const container = plugin.getContainerElement();
112402
- if (container !== document.body) {
112403
- if (!captured[container.id]) {
112404
- captured[container.id] = true;
112405
- html2canvas(container).then(function (canvas) {
112406
- document.body.appendChild(canvas);
112407
- });
112408
- }
112409
- }
112410
- }
112411
- }
112412
-
112413
112549
  // firing "rendering" is necessary to trigger DTX{Lines,Triangles}Layer::_uploadDeferredFlags
112414
112550
  this.scene.fire("rendering", { }, true);
112415
112551
 
@@ -130060,46 +130196,27 @@ class FaceAlignedSectionPlanesPlugin extends Plugin {
130060
130196
  * });
130061
130197
  *
130062
130198
  * // Add a GLTFModelsPlugin
130063
- * var gltfLoaderPlugin = new GLTFModelsPlugin(viewer, {
130064
- * id: "GLTFModels" // Default value
130065
- * });
130199
+ * var xktLoaderPlugin = new XKTLoaderPlugin(viewer);
130066
130200
  *
130067
130201
  * // Add a SkyboxesPlugin
130068
- * var skyboxesPlugin = new SkyboxesPlugin(viewer, {
130069
- * id: "Skyboxes" // Default value
130070
- * });
130202
+ * var skyboxesPlugin = new SkyboxesPlugin(viewer);
130203
+ *
130204
+ * // Create a skybox
130205
+ * skyBoxesPlugin.createSkybox({
130206
+ * src: [
130207
+ * "./assets/images/posx.jpg",
130208
+ * "./assets/images/negx.jpg",
130209
+ * "./assets/images/posy.jpg",
130210
+ * "./assets/images/negy.jpg",
130211
+ * "./assets/images/posz.jpg",
130212
+ * "./assets/images/negz.jpg"
130213
+ * ]
130214
+ * })
130071
130215
  *
130072
- * // Load a glTF model
130073
- * const model = gltfLoaderPlugin.load({
130216
+ * // Load an XKT model
130217
+ * const model = xktLoaderPlugin.load({
130074
130218
  * id: "myModel",
130075
- * src: "./models/gltf/mygltfmodel.gltf"
130076
- * });
130077
- *
130078
- * // Create three directional World-space lights. "World" means that they will appear as if part
130079
- * // of the world, instead of "View", where they move with the user's head.
130080
- *
130081
- * skyboxesPlugin.createLight({
130082
- * id: "keyLight",
130083
- * dir: [0.8, -0.6, -0.8],
130084
- * color: [1.0, 0.3, 0.3],
130085
- * intensity: 1.0,
130086
- * space: "world"
130087
- * });
130088
- *
130089
- * skyboxesPlugin.createLight({
130090
- * id: "fillLight",
130091
- * dir: [-0.8, -0.4, -0.4],
130092
- * color: [0.3, 1.0, 0.3],
130093
- * intensity: 1.0,
130094
- * space: "world"
130095
- * });
130096
- *
130097
- * skyboxesPlugin.createDirLight({
130098
- * id: "rimLight",
130099
- * dir: [0.2, -0.8, 0.8],
130100
- * color: [0.6, 0.6, 0.6],
130101
- * intensity: 1.0,
130102
- * space: "world"
130219
+ * src: "./models/xkt/myModel.xkt"
130103
130220
  * });
130104
130221
  *
130105
130222
  * @class SkyboxesPlugin
@@ -130125,23 +130242,17 @@ class SkyboxesPlugin extends Plugin {
130125
130242
  /**
130126
130243
  Creates a skybox.
130127
130244
 
130128
- @param {String} id Unique ID to assign to the skybox.
130129
130245
  @param {Object} params Skybox configuration.
130246
+ @param {String} [params.id] Optional ID, unique among all components in the parent {Scene}, generated automatically when omitted.
130247
+ @param {String | String[]} [params.src=null] Path to skybox texture
130248
+ @param {Number} [params.encoding=LinearEncoding] Texture encoding format. See the {@link Texture#encoding} property for more info.
130249
+ @param {Number} [params.size=1000] Size of this Skybox, given as the distance from the center at ````[0,0,0]```` to each face.
130130
130250
  @param {Boolean} [params.active=true] Whether the skybox plane is initially active. Only skyboxes while this is true.
130131
130251
  @returns {Skybox} The new skybox.
130132
130252
  */
130133
- createSkybox(id, params) {
130134
- if (this.viewer.scene.components[id]) {
130135
- this.error("Component with this ID already exists: " + id);
130136
- return this;
130137
- }
130138
- var skybox = new Skybox(this.viewer.scene, {
130139
- id: id,
130140
- pos: params.pos,
130141
- dir: params.dir,
130142
- active: true
130143
- });
130144
- this.skyboxes[id] = skybox;
130253
+ createSkybox(params) {
130254
+ const skybox = new Skybox(this.viewer.scene, params);
130255
+ this.skyboxes[skybox.id] = skybox;
130145
130256
  return skybox;
130146
130257
  }
130147
130258
 
@@ -130804,6 +130915,15 @@ class STLLoaderPlugin extends Plugin {
130804
130915
  */
130805
130916
  class RenderService {
130806
130917
 
130918
+ /**
130919
+ * @constructor
130920
+ *
130921
+ * @param {HTMLElement} treeViewContainer Container element for the tree which uses this render service.
130922
+ */
130923
+ constructor(treeViewContainer) {
130924
+ this._treeViewContainer = treeViewContainer;
130925
+ }
130926
+
130807
130927
  /*
130808
130928
  * Creates the root node of the tree.
130809
130929
  * @return {HTMLElement} The root node of the tree.
@@ -130928,7 +131048,7 @@ class RenderService {
130928
131048
  }
130929
131049
 
130930
131050
  getSwitchElement(nodeId) {
130931
- return document.getElementById(`switch-${nodeId}`);
131051
+ return this._treeViewContainer.querySelector(`[id="switch-${nodeId}"]`);
130932
131052
  }
130933
131053
 
130934
131054
  isChecked(element) {
@@ -130936,7 +131056,7 @@ class RenderService {
130936
131056
  }
130937
131057
 
130938
131058
  setCheckbox(nodeId, checked, indeterminate = false) {
130939
- const checkbox = document.getElementById(`checkbox-${nodeId}`);
131059
+ const checkbox = this._treeViewContainer.querySelector(`[id="checkbox-${nodeId}"]`);
130940
131060
  if (checkbox) {
130941
131061
  if (checked !== checkbox.checked) {
130942
131062
  checkbox.checked = checked;
@@ -130951,7 +131071,7 @@ class RenderService {
130951
131071
  }
130952
131072
 
130953
131073
  setXRayed(nodeId, xrayed) {
130954
- const treeNode = document.getElementById(nodeId);
131074
+ const treeNode = this._treeViewContainer.querySelector(`[id="${nodeId}"]`);
130955
131075
  if (treeNode) {
130956
131076
  if (xrayed) {
130957
131077
  treeNode.classList.add('xrayed-node');
@@ -130962,7 +131082,7 @@ class RenderService {
130962
131082
  }
130963
131083
 
130964
131084
  setHighlighted(nodeId, highlighted) {
130965
- const treeNode = document.getElementById(nodeId);
131085
+ const treeNode = this._treeViewContainer.querySelector(`[id="${nodeId}"]`);
130966
131086
  if (treeNode) {
130967
131087
  if (highlighted) {
130968
131088
  treeNode.scrollIntoView({block: "center"});
@@ -131388,7 +131508,7 @@ class TreeViewPlugin extends Plugin {
131388
131508
  this._sortNodes = cfg.sortNodes;
131389
131509
  this._pruneEmptyNodes = cfg.pruneEmptyNodes;
131390
131510
  this._showListItemElementId = null;
131391
- this._renderService = cfg.renderService || new RenderService();
131511
+ this._renderService = cfg.renderService || new RenderService(this._containerElement);
131392
131512
  this._showIndeterminate = cfg.showIndeterminate ?? false;
131393
131513
  this._showProjectNode = cfg.showProjectNode ?? false;
131394
131514
  this._elevationSortFunction = cfg.elevationSortFunction ?? undefined;