@xeokit/xeokit-sdk 2.6.60 → 2.6.62

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.
@@ -784,12 +784,19 @@ class ContextMenu {
784
784
  subMenuElement.getBoundingClientRect();
785
785
 
786
786
  const subMenuWidth = 200; // TODO
787
- const showOnLeft = ((itemRect.right + subMenuWidth) > window.innerWidth);
787
+ const showOnRight = (itemRect.right + subMenuWidth) < window.innerWidth;
788
+ const showOnLeft = (itemRect.left - subMenuWidth) > 0;
788
789
 
789
- if (showOnLeft) {
790
- self._showMenu(subMenu.id, itemRect.left - subMenuWidth, itemRect.top - 1);
791
- } else {
790
+ if(showOnRight)
792
791
  self._showMenu(subMenu.id, itemRect.right - 5, itemRect.top - 1);
792
+ else if (showOnLeft)
793
+ self._showMenu(subMenu.id, itemRect.left - subMenuWidth, itemRect.top - 1);
794
+ else {
795
+ const spaceOnLeft = itemRect.left, spaceOnRight = window.innerWidth - itemRect.right;
796
+ if(spaceOnRight > spaceOnLeft)
797
+ self._showMenu(subMenu.id, itemRect.right - 5 - (subMenuWidth - spaceOnRight), itemRect.top - 1);
798
+ else
799
+ self._showMenu(subMenu.id, itemRect.left - spaceOnLeft, itemRect.top - 1);
793
800
  }
794
801
 
795
802
  lastSubMenu = subMenu;
@@ -9593,14 +9600,17 @@ function addContextMenuListener(elem, callback) {
9593
9600
 
9594
9601
  const touchStartHandler = (event) => {
9595
9602
  event.preventDefault();
9596
- const touch = event.touches[0];
9597
- startX = touch.clientX;
9598
- startY = touch.clientY;
9599
-
9603
+
9600
9604
  if (timeout) {
9601
9605
  clearTimeout(timeout);
9602
9606
  timeout = null;
9603
9607
  }
9608
+ // If more than one finger touches the screen, cancel the timeout
9609
+ if (event.touches.length > 1) return;
9610
+
9611
+ const touch = event.touches[0];
9612
+ startX = touch.clientX;
9613
+ startY = touch.clientY;
9604
9614
 
9605
9615
  timeout = setTimeout(() => {
9606
9616
  event.clientX = touch.clientX;
@@ -9611,6 +9621,14 @@ function addContextMenuListener(elem, callback) {
9611
9621
  }, longPressTimer);
9612
9622
  };
9613
9623
 
9624
+ const globalTouchStartHandler = (event) => {
9625
+ // Cancel timeout if multiple touches are detected anywhere on the screen
9626
+ if (event.touches.length > 1 && timeout) {
9627
+ clearTimeout(timeout);
9628
+ timeout = null;
9629
+ }
9630
+ };
9631
+
9614
9632
  const touchMoveHandler = (event) => {
9615
9633
  if (!timeout) return;
9616
9634
  const touch = event.touches[0];
@@ -9641,6 +9659,7 @@ function addContextMenuListener(elem, callback) {
9641
9659
  elem.addEventListener('touchstart', touchStartHandler);
9642
9660
  elem.addEventListener('touchmove', touchMoveHandler);
9643
9661
  elem.addEventListener('touchend', touchEndHandler);
9662
+ window.addEventListener('touchstart', globalTouchStartHandler);
9644
9663
  } else {
9645
9664
  elem.addEventListener('contextmenu', contextMenuHandler);
9646
9665
  }
@@ -9650,6 +9669,7 @@ function addContextMenuListener(elem, callback) {
9650
9669
  elem.removeEventListener('touchstart', touchStartHandler);
9651
9670
  elem.removeEventListener('touchmove', touchMoveHandler);
9652
9671
  elem.removeEventListener('touchend', touchEndHandler);
9672
+ window.removeEventListener('touchstart', globalTouchStartHandler);
9653
9673
  } else {
9654
9674
  elem.removeEventListener('contextmenu', contextMenuHandler);
9655
9675
  }
@@ -14773,10 +14793,10 @@ class Annotation extends Marker {
14773
14793
  this._marker.addEventListener("click", this._onMouseClickedExternalMarker = () => {
14774
14794
  this.plugin.fire("markerClicked", this);
14775
14795
  });
14776
- this._onContextMenuExtenalMarker = () => {
14796
+ this._onContextMenuExternalMarker = () => {
14777
14797
  this.plugin.fire("contextmenu", this);
14778
14798
  };
14779
- this._onContextMenuExtenalMarkerRemover = addContextMenuListener(this._markerHTML, this._onContextMenuExtenalMarker);
14799
+ this._onContextMenuExternalMarkerRemover = addContextMenuListener(this._marker, this._onContextMenuExternalMarker);
14780
14800
  this._marker.addEventListener("mouseenter", this._onMouseEnterExternalMarker = () => {
14781
14801
  this.plugin.fire("markerMouseEnter", this);
14782
14802
  });
@@ -15147,7 +15167,7 @@ class Annotation extends Marker {
15147
15167
  this._marker = null;
15148
15168
  } else {
15149
15169
  this._marker.removeEventListener("click", this._onMouseClickedExternalMarker);
15150
- this._onContextMenuExtenalMarkerRemover();
15170
+ this._onContextMenuExternalMarkerRemover();
15151
15171
  this._marker.removeEventListener("mouseenter", this._onMouseEnterExternalMarker);
15152
15172
  this._marker.removeEventListener("mouseleave", this._onMouseLeaveExternalMarker);
15153
15173
  this._marker = null;
@@ -19392,6 +19412,8 @@ function getExtension (gl, name) {
19392
19412
  return extension;
19393
19413
  }
19394
19414
 
19415
+ const vec3_0 = math.vec3([0,0,0]);
19416
+
19395
19417
  /**
19396
19418
  * @private
19397
19419
  */
@@ -20070,9 +20092,11 @@ const Renderer$1 = function (scene, options) {
20070
20092
  // Transparent color fill
20071
20093
 
20072
20094
  if (normalFillTransparentBinLen > 0) {
20095
+ const eye = frameCtx.pickOrigin || scene.camera.eye;
20096
+ const byDist = normalFillTransparentBin.map(d => ({ drawable: d, distSq: math.distVec3(d.origin || vec3_0, eye) }));
20097
+ byDist.sort((a, b) => b.distSq - a.distSq);
20073
20098
  for (i = 0; i < normalFillTransparentBinLen; i++) {
20074
- drawable = normalFillTransparentBin[i];
20075
- drawable.drawColorTransparent(frameCtx);
20099
+ byDist[i].drawable.drawColorTransparent(frameCtx);
20076
20100
  }
20077
20101
  }
20078
20102
 
@@ -73107,6 +73131,10 @@ class DTXTrianglesColorRenderer {
73107
73131
  const sectionPlanes = scene._sectionPlanesState.sectionPlanes;
73108
73132
  const baseIndex = dataTextureLayer.layerIndex * numSectionPlanes;
73109
73133
  const renderFlags = model.renderFlags;
73134
+ if (scene.crossSections) {
73135
+ gl.uniform4fv(this._uSliceColor, scene.crossSections.sliceColor);
73136
+ gl.uniform1f(this._uSliceThickness, scene.crossSections.sliceThickness);
73137
+ }
73110
73138
  for (let sectionPlaneIndex = 0; sectionPlaneIndex < numAllocatedSectionPlanes; sectionPlaneIndex++) {
73111
73139
  const sectionPlaneUniforms = this._uSectionPlanes[sectionPlaneIndex];
73112
73140
  if (sectionPlaneUniforms) {
@@ -73244,6 +73272,11 @@ class DTXTrianglesColorRenderer {
73244
73272
  this._uTexturePerPolygonIdPortionIds = "uTexturePerPolygonIdPortionIds";
73245
73273
  this._uTexturePerObjectMatrix= "uTexturePerObjectMatrix";
73246
73274
  this._uCameraEyeRtc = program.getLocation("uCameraEyeRtc");
73275
+
73276
+ if (scene.crossSections) {
73277
+ this._uSliceColor = program.getLocation("sliceColor");
73278
+ this._uSliceThickness = program.getLocation("sliceThickness");
73279
+ }
73247
73280
  }
73248
73281
 
73249
73282
  _bindProgram(frameCtx) {
@@ -73560,11 +73593,14 @@ class DTXTrianglesColorRenderer {
73560
73593
  src.push("uniform vec3 sectionPlanePos" + i + ";");
73561
73594
  src.push("uniform vec3 sectionPlaneDir" + i + ";");
73562
73595
  }
73596
+ src.push("uniform float sliceThickness;");
73597
+ src.push("uniform vec4 sliceColor;");
73563
73598
  }
73564
73599
  src.push("in vec4 vColor;");
73565
73600
  src.push("out vec4 outColor;");
73566
73601
  src.push("void main(void) {");
73567
-
73602
+ src.push(" vec4 newColor;");
73603
+ src.push(" newColor = vColor;");
73568
73604
  if (clipping) {
73569
73605
  src.push(" bool clippable = vFlags2 > 0u;");
73570
73606
  src.push(" if (clippable) {");
@@ -73574,9 +73610,12 @@ class DTXTrianglesColorRenderer {
73574
73610
  src.push(" dist += clamp(dot(-sectionPlaneDir" + i + ".xyz, vWorldPosition.xyz - sectionPlanePos" + i + ".xyz), 0.0, 1000.0);");
73575
73611
  src.push("}");
73576
73612
  }
73577
- src.push(" if (dist > 0.0) { ");
73613
+ src.push(" if (dist > sliceThickness) { ");
73578
73614
  src.push(" discard;");
73579
73615
  src.push(" }");
73616
+ src.push(" if (dist > 0.0) { ");
73617
+ src.push(" newColor = sliceColor;");
73618
+ src.push(" }");
73580
73619
  src.push("}");
73581
73620
  }
73582
73621
 
@@ -73594,9 +73633,9 @@ class DTXTrianglesColorRenderer {
73594
73633
  src.push(" float blendFactor = uSAOParams[3];");
73595
73634
  src.push(" vec2 uv = vec2(gl_FragCoord.x / viewportWidth, gl_FragCoord.y / viewportHeight);");
73596
73635
  src.push(" float ambient = smoothstep(blendCutoff, 1.0, unpackRGBToFloat(texture(uOcclusionTexture, uv))) * blendFactor;");
73597
- src.push(" outColor = vec4(vColor.rgb * ambient, 1.0);");
73636
+ src.push(" outColor = vec4(newColor.rgb * ambient, 1.0);");
73598
73637
  } else {
73599
- src.push(" outColor = vColor;");
73638
+ src.push(" outColor = newColor;");
73600
73639
  }
73601
73640
 
73602
73641
  src.push("}");
@@ -74038,10 +74077,14 @@ class DTXTrianglesSilhouetteRenderer {
74038
74077
  src.push("uniform vec3 sectionPlanePos" + i + ";");
74039
74078
  src.push("uniform vec3 sectionPlaneDir" + i + ";");
74040
74079
  }
74080
+ src.push("uniform float sliceThickness;");
74081
+ src.push("uniform vec4 sliceColor;");
74041
74082
  }
74042
74083
  src.push("uniform vec4 color;");
74043
74084
  src.push("out vec4 outColor;");
74044
74085
  src.push("void main(void) {");
74086
+ src.push(" vec4 newColor;");
74087
+ src.push(" newColor = color;");
74045
74088
  if (clipping) {
74046
74089
  src.push(" bool clippable = vFlags2 > 0u;");
74047
74090
  src.push(" if (clippable) {");
@@ -74051,15 +74094,18 @@ class DTXTrianglesSilhouetteRenderer {
74051
74094
  src.push(" dist += clamp(dot(-sectionPlaneDir" + i + ".xyz, vWorldPosition.xyz - sectionPlanePos" + i + ".xyz), 0.0, 1000.0);");
74052
74095
  src.push("}");
74053
74096
  }
74054
- src.push(" if (dist > 0.0) { ");
74097
+ src.push(" if (dist > sliceThickness) { ");
74055
74098
  src.push(" discard;");
74056
74099
  src.push(" }");
74100
+ src.push(" if (dist > 0.0) { ");
74101
+ src.push(" newColor = sliceColor;");
74102
+ src.push(" }");
74057
74103
  src.push("}");
74058
74104
  }
74059
74105
  if (scene.logarithmicDepthBufferEnabled) {
74060
74106
  src.push(" gl_FragDepth = isPerspective == 0.0 ? gl_FragCoord.z : log2( vFragDepth ) * logDepthBufFC * 0.5;");
74061
74107
  }
74062
- src.push(" outColor = color;");
74108
+ src.push(" outColor = newColor;");
74063
74109
  src.push("}");
74064
74110
  return src;
74065
74111
  }
@@ -74458,10 +74504,14 @@ class DTXTrianglesEdgesRenderer {
74458
74504
  src.push("uniform vec3 sectionPlanePos" + i + ";");
74459
74505
  src.push("uniform vec3 sectionPlaneDir" + i + ";");
74460
74506
  }
74507
+ src.push("uniform float sliceThickness;");
74508
+ src.push("uniform vec4 sliceColor;");
74461
74509
  }
74462
74510
  src.push("in vec4 vColor;");
74463
74511
  src.push("out vec4 outColor;");
74464
74512
  src.push("void main(void) {");
74513
+ src.push(" vec4 newColor;");
74514
+ src.push(" newColor = vColor;");
74465
74515
  if (clipping) {
74466
74516
  src.push(" bool clippable = vFlags2 > 0u;");
74467
74517
  src.push(" if (clippable) {");
@@ -74471,13 +74521,18 @@ class DTXTrianglesEdgesRenderer {
74471
74521
  src.push(" dist += clamp(dot(-sectionPlaneDir" + i + ".xyz, vWorldPosition.xyz - sectionPlanePos" + i + ".xyz), 0.0, 1000.0);");
74472
74522
  src.push("}");
74473
74523
  }
74474
- src.push(" if (dist > 0.0) { discard; }");
74524
+ src.push(" if (dist > sliceThickness) { ");
74525
+ src.push(" discard;");
74526
+ src.push(" }");
74527
+ src.push(" if (dist > 0.0) { ");
74528
+ src.push(" newColor = sliceColor;");
74529
+ src.push(" }");
74475
74530
  src.push("}");
74476
74531
  }
74477
74532
  if (scene.logarithmicDepthBufferEnabled) {
74478
74533
  src.push(" gl_FragDepth = isPerspective == 0.0 ? gl_FragCoord.z : log2( vFragDepth ) * logDepthBufFC * 0.5;");
74479
74534
  }
74480
- src.push(" outColor = vColor;");
74535
+ src.push(" outColor = newColor;");
74481
74536
  src.push("}");
74482
74537
  return src;
74483
74538
  }
@@ -74867,10 +74922,14 @@ class DTXTrianglesEdgesColorRenderer {
74867
74922
  src.push("uniform vec3 sectionPlanePos" + i + ";");
74868
74923
  src.push("uniform vec3 sectionPlaneDir" + i + ";");
74869
74924
  }
74925
+ src.push("uniform float sliceThickness;");
74926
+ src.push("uniform vec4 sliceColor;");
74870
74927
  }
74871
74928
  src.push("in vec4 vColor;");
74872
74929
  src.push("out vec4 outColor;");
74873
74930
  src.push("void main(void) {");
74931
+ src.push(" vec4 newColor;");
74932
+ src.push(" newColor = vColor;");
74874
74933
  if (clipping) {
74875
74934
  src.push(" bool clippable = vFlags2 > 0u;");
74876
74935
  src.push(" if (clippable) {");
@@ -74880,13 +74939,18 @@ class DTXTrianglesEdgesColorRenderer {
74880
74939
  src.push(" dist += clamp(dot(-sectionPlaneDir" + i + ".xyz, vWorldPosition.xyz - sectionPlanePos" + i + ".xyz), 0.0, 1000.0);");
74881
74940
  src.push("}");
74882
74941
  }
74883
- src.push(" if (dist > 0.0) { discard; }");
74942
+ src.push(" if (dist > sliceThickness) { ");
74943
+ src.push(" discard;");
74944
+ src.push(" }");
74945
+ src.push(" if (dist > 0.0) { ");
74946
+ src.push(" newColor = sliceColor;");
74947
+ src.push(" }");
74884
74948
  src.push("}");
74885
74949
  }
74886
74950
  if (scene.logarithmicDepthBufferEnabled) {
74887
74951
  src.push(" gl_FragDepth = isPerspective == 0.0 ? gl_FragCoord.z : log2( vFragDepth ) * logDepthBufFC * 0.5;");
74888
74952
  }
74889
- src.push(" outColor = vColor;");
74953
+ src.push(" outColor = newColor;");
74890
74954
  src.push("}");
74891
74955
  return src;
74892
74956
  }
@@ -90756,7 +90820,7 @@ class FastNavPlugin extends Plugin {
90756
90820
  this._hideEdges = cfg.hideEdges !== false;
90757
90821
  this._hideTransparentObjects = !!cfg.hideTransparentObjects;
90758
90822
  this._scaleCanvasResolution = !!cfg.scaleCanvasResolution;
90759
- this._defaultScaleCanvasResolutionFactor = cfg.defaultScaleCanvasResolutionFactor || 1.0;
90823
+ this._defaultScaleCanvasResolutionFactor = cfg.defaultScaleCanvasResolutionFactor;
90760
90824
  this._scaleCanvasResolutionFactor = cfg.scaleCanvasResolutionFactor || 0.6;
90761
90825
  this._delayBeforeRestore = (cfg.delayBeforeRestore !== false);
90762
90826
  this._delayBeforeRestoreSeconds = cfg.delayBeforeRestoreSeconds || 0.5;
@@ -90772,6 +90836,7 @@ class FastNavPlugin extends Plugin {
90772
90836
  viewer.scene._renderer.setSAOEnabled(!this._hideSAO);
90773
90837
  viewer.scene._renderer.setTransparentEnabled(!this._hideTransparentObjects);
90774
90838
  viewer.scene._renderer.setEdgesEnabled(!this._hideEdges);
90839
+ this._originalCanvasResolutionScale = viewer.scene.canvas.resolutionScale;
90775
90840
  if (this._scaleCanvasResolution) {
90776
90841
  viewer.scene.canvas.resolutionScale = this._scaleCanvasResolutionFactor;
90777
90842
  } else {
@@ -90782,7 +90847,7 @@ class FastNavPlugin extends Plugin {
90782
90847
  };
90783
90848
 
90784
90849
  const switchToHighQuality = () => {
90785
- viewer.scene.canvas.resolutionScale = this._defaultScaleCanvasResolutionFactor;
90850
+ viewer.scene.canvas.resolutionScale = this._defaultScaleCanvasResolutionFactor || this._originalCanvasResolutionScale || 1.0;
90786
90851
  viewer.scene._renderer.setEdgesEnabled(true);
90787
90852
  viewer.scene._renderer.setColorTextureEnabled(true);
90788
90853
  viewer.scene._renderer.setPBREnabled(true);
@@ -90987,7 +91052,7 @@ class FastNavPlugin extends Plugin {
90987
91052
  * @param {Number} defaultScaleCanvasResolutionFactor Factor by scale canvas resolution when we stop interacting with the viewer.
90988
91053
  */
90989
91054
  set defaultScaleCanvasResolutionFactor(defaultScaleCanvasResolutionFactor) {
90990
- this._defaultScaleCanvasResolutionFactor = defaultScaleCanvasResolutionFactor || 1.0;
91055
+ this._defaultScaleCanvasResolutionFactor = defaultScaleCanvasResolutionFactor;
90991
91056
  }
90992
91057
 
90993
91058
  /**
@@ -97732,7 +97797,7 @@ class MousePickHandler {
97732
97797
 
97733
97798
  this._timeout = setTimeout(() => {
97734
97799
 
97735
- if (firstClickPickResult && firstClickPickResult.worldPos) {
97800
+ if (firstClickPickResult) {
97736
97801
 
97737
97802
  cameraControl.fire("picked", firstClickPickResult, true);
97738
97803
 
@@ -101924,8 +101989,8 @@ class MetaScene {
101924
101989
 
101925
101990
  for (let modelId in this.metaModels) {
101926
101991
  const metaModel = this.metaModels[modelId];
101927
- for (let i = 0, len = metaModel.metaObjects.length; i < len; i++) {
101928
- const metaObject = metaModel.metaObjects[i];
101992
+ for (let objectId in metaModel.metaObjects) {
101993
+ const metaObject = metaModel.metaObjects[objectId];
101929
101994
  metaObject.metaModels.push(metaModel);
101930
101995
  }
101931
101996
  }
@@ -126544,6 +126609,7 @@ class TreeViewPlugin extends Plugin {
126544
126609
  * @param {Boolean} [cfg.pruneEmptyNodes=true] When true, will not contain nodes that don't have content in the {@link Scene}. These are nodes whose {@link MetaObject}s don't have {@link Entity}s.
126545
126610
  * @param {RenderService} [cfg.renderService] Optional {@link RenderService} to use. Defaults to the {@link TreeViewPlugin}'s default {@link RenderService}.
126546
126611
  * @param {Boolean} [cfg.showIndeterminate=false] When true, will show indeterminate state for checkboxes when some but not all child nodes are checked
126612
+ * @param {Boolean} [cfg.showProjectNode=false] When true, will show top level project node when hierarchy is set to "storeys"
126547
126613
  */
126548
126614
  constructor(viewer, cfg = {}) {
126549
126615
 
@@ -126596,6 +126662,7 @@ class TreeViewPlugin extends Plugin {
126596
126662
  this._showListItemElementId = null;
126597
126663
  this._renderService = cfg.renderService || new RenderService();
126598
126664
  this._showIndeterminate = cfg.showIndeterminate ?? false;
126665
+ this._showProjectNode = cfg.showProjectNode ?? false;
126599
126666
 
126600
126667
  if (!this._renderService) {
126601
126668
  throw new Error('TreeViewPlugin: no render service set');
@@ -127150,11 +127217,11 @@ class TreeViewPlugin extends Plugin {
127150
127217
  _createStoreysNodes() {
127151
127218
  const rootMetaObjects = this._viewer.metaScene.rootMetaObjects;
127152
127219
  for (let id in rootMetaObjects) {
127153
- this._createStoreysNodes2(rootMetaObjects[id], null, null, null);
127220
+ this._createStoreysNodes2(rootMetaObjects[id], null, null, null, null);
127154
127221
  }
127155
127222
  }
127156
127223
 
127157
- _createStoreysNodes2(metaObject, buildingNode, storeyNode, typeNodes) {
127224
+ _createStoreysNodes2(metaObject, projectNode, buildingNode, storeyNode, typeNodes) {
127158
127225
  if (this._pruneEmptyNodes && (metaObject._countEntities === 0)) {
127159
127226
  return;
127160
127227
  }
@@ -127162,20 +127229,41 @@ class TreeViewPlugin extends Plugin {
127162
127229
  const metaObjectName = metaObject.name;
127163
127230
  const children = metaObject.children;
127164
127231
  const objectId = metaObject.id;
127165
- if (metaObjectType === "IfcBuilding") {
127232
+
127233
+ if (this._showProjectNode && metaObjectType === 'IfcProject') {
127234
+ projectNode = {
127235
+ nodeId: `${this._id}-${objectId}`,
127236
+ objectId,
127237
+ title: (metaObject.metaModels.length === 0) ? metaObjectName : this._rootNames[metaObject.metaModels[0].id] || ((metaObjectName && metaObjectName !== "" && metaObjectName !== "Undefined" && metaObjectName !== "Default") ? metaObjectName : metaObjectType),
127238
+ type: metaObjectType,
127239
+ parent: null,
127240
+ numEntities: 0,
127241
+ numVisibleEntities: 0,
127242
+ checked: false,
127243
+ xrayed: false,
127244
+ children: [],
127245
+ };
127246
+ this._rootNodes.push(projectNode);
127247
+ this._objectNodes[projectNode.objectId] = projectNode;
127248
+ this._nodeNodes[projectNode.nodeId] = projectNode;
127249
+ } else if (metaObjectType === "IfcBuilding") {
127166
127250
  buildingNode = {
127167
127251
  nodeId: `${this._id}-${objectId}`,
127168
127252
  objectId: objectId,
127169
127253
  title: (metaObject.metaModels.length === 0) ? metaObjectName : this._rootNames[metaObject.metaModels[0].id] || ((metaObjectName && metaObjectName !== "" && metaObjectName !== "Undefined" && metaObjectName !== "Default") ? metaObjectName : metaObjectType),
127170
127254
  type: metaObjectType,
127171
- parent: null,
127255
+ parent: projectNode,
127172
127256
  numEntities: 0,
127173
127257
  numVisibleEntities: 0,
127174
127258
  checked: false,
127175
127259
  xrayed: false,
127176
127260
  children: []
127177
127261
  };
127178
- this._rootNodes.push(buildingNode);
127262
+ if (projectNode) {
127263
+ projectNode.children.push(buildingNode);
127264
+ } else {
127265
+ this._rootNodes.push(buildingNode);
127266
+ }
127179
127267
  this._objectNodes[buildingNode.objectId] = buildingNode;
127180
127268
  this._nodeNodes[buildingNode.nodeId] = buildingNode;
127181
127269
  } else if (metaObjectType === "IfcBuildingStorey") {
@@ -127245,7 +127333,7 @@ class TreeViewPlugin extends Plugin {
127245
127333
  if (children) {
127246
127334
  for (let i = 0, len = children.length; i < len; i++) {
127247
127335
  const childMetaObject = children[i];
127248
- this._createStoreysNodes2(childMetaObject, buildingNode, storeyNode, typeNodes);
127336
+ this._createStoreysNodes2(childMetaObject, projectNode, buildingNode, storeyNode, typeNodes);
127249
127337
  }
127250
127338
  }
127251
127339
  }
@@ -140826,8 +140914,21 @@ class Zone extends Component {
140826
140914
  }
140827
140915
 
140828
140916
 
140829
- const positions = [].concat(...pos);
140917
+ const min = idx => Math.min(...pos.map(p => p[idx]));
140918
+ const max = idx => Math.max(...pos.map(p => p[idx]));
140919
+
140920
+ const xmin = min(0);
140921
+ const ymin = min(1);
140922
+ const zmin = min(2);
140923
+ const xmax = max(0);
140924
+ const ymax = max(1);
140925
+ const zmax = max(2);
140926
+
140927
+ this._center = math.vec3([ (xmin + xmax) / 2, (ymin + ymax) / 2, (zmin + zmax) / 2 ]);
140928
+
140929
+ const positions = [].concat(...pos.map(p => math.subVec3(p, this._center, p)));
140830
140930
  this._zoneMesh = new Mesh(scene, {
140931
+ origin: this._center,
140831
140932
  edges: this._edges,
140832
140933
  geometry: new ReadableGeometry(
140833
140934
  scene,
@@ -140868,19 +140969,6 @@ class Zone extends Component {
140868
140969
  }
140869
140970
 
140870
140971
  this._metrics = null;
140871
-
140872
-
140873
- const min = idx => Math.min(...pos.map(p => p[idx]));
140874
- const max = idx => Math.max(...pos.map(p => p[idx]));
140875
-
140876
- const xmin = min(0);
140877
- const ymin = min(1);
140878
- const zmin = min(2);
140879
- const xmax = max(0);
140880
- const ymax = max(1);
140881
- const zmax = max(2);
140882
-
140883
- this._center = math.vec3([ (xmin + xmax) / 2, (ymin + ymax) / 2, (zmin + zmax) / 2 ]);
140884
140972
  }
140885
140973
 
140886
140974
  get baseArea() {