@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.
@@ -780,12 +780,19 @@ class ContextMenu {
780
780
  subMenuElement.getBoundingClientRect();
781
781
 
782
782
  const subMenuWidth = 200; // TODO
783
- const showOnLeft = ((itemRect.right + subMenuWidth) > window.innerWidth);
783
+ const showOnRight = (itemRect.right + subMenuWidth) < window.innerWidth;
784
+ const showOnLeft = (itemRect.left - subMenuWidth) > 0;
784
785
 
785
- if (showOnLeft) {
786
- self._showMenu(subMenu.id, itemRect.left - subMenuWidth, itemRect.top - 1);
787
- } else {
786
+ if(showOnRight)
788
787
  self._showMenu(subMenu.id, itemRect.right - 5, itemRect.top - 1);
788
+ else if (showOnLeft)
789
+ self._showMenu(subMenu.id, itemRect.left - subMenuWidth, itemRect.top - 1);
790
+ else {
791
+ const spaceOnLeft = itemRect.left, spaceOnRight = window.innerWidth - itemRect.right;
792
+ if(spaceOnRight > spaceOnLeft)
793
+ self._showMenu(subMenu.id, itemRect.right - 5 - (subMenuWidth - spaceOnRight), itemRect.top - 1);
794
+ else
795
+ self._showMenu(subMenu.id, itemRect.left - spaceOnLeft, itemRect.top - 1);
789
796
  }
790
797
 
791
798
  lastSubMenu = subMenu;
@@ -9589,14 +9596,17 @@ function addContextMenuListener(elem, callback) {
9589
9596
 
9590
9597
  const touchStartHandler = (event) => {
9591
9598
  event.preventDefault();
9592
- const touch = event.touches[0];
9593
- startX = touch.clientX;
9594
- startY = touch.clientY;
9595
-
9599
+
9596
9600
  if (timeout) {
9597
9601
  clearTimeout(timeout);
9598
9602
  timeout = null;
9599
9603
  }
9604
+ // If more than one finger touches the screen, cancel the timeout
9605
+ if (event.touches.length > 1) return;
9606
+
9607
+ const touch = event.touches[0];
9608
+ startX = touch.clientX;
9609
+ startY = touch.clientY;
9600
9610
 
9601
9611
  timeout = setTimeout(() => {
9602
9612
  event.clientX = touch.clientX;
@@ -9607,6 +9617,14 @@ function addContextMenuListener(elem, callback) {
9607
9617
  }, longPressTimer);
9608
9618
  };
9609
9619
 
9620
+ const globalTouchStartHandler = (event) => {
9621
+ // Cancel timeout if multiple touches are detected anywhere on the screen
9622
+ if (event.touches.length > 1 && timeout) {
9623
+ clearTimeout(timeout);
9624
+ timeout = null;
9625
+ }
9626
+ };
9627
+
9610
9628
  const touchMoveHandler = (event) => {
9611
9629
  if (!timeout) return;
9612
9630
  const touch = event.touches[0];
@@ -9637,6 +9655,7 @@ function addContextMenuListener(elem, callback) {
9637
9655
  elem.addEventListener('touchstart', touchStartHandler);
9638
9656
  elem.addEventListener('touchmove', touchMoveHandler);
9639
9657
  elem.addEventListener('touchend', touchEndHandler);
9658
+ window.addEventListener('touchstart', globalTouchStartHandler);
9640
9659
  } else {
9641
9660
  elem.addEventListener('contextmenu', contextMenuHandler);
9642
9661
  }
@@ -9646,6 +9665,7 @@ function addContextMenuListener(elem, callback) {
9646
9665
  elem.removeEventListener('touchstart', touchStartHandler);
9647
9666
  elem.removeEventListener('touchmove', touchMoveHandler);
9648
9667
  elem.removeEventListener('touchend', touchEndHandler);
9668
+ window.removeEventListener('touchstart', globalTouchStartHandler);
9649
9669
  } else {
9650
9670
  elem.removeEventListener('contextmenu', contextMenuHandler);
9651
9671
  }
@@ -14769,10 +14789,10 @@ class Annotation extends Marker {
14769
14789
  this._marker.addEventListener("click", this._onMouseClickedExternalMarker = () => {
14770
14790
  this.plugin.fire("markerClicked", this);
14771
14791
  });
14772
- this._onContextMenuExtenalMarker = () => {
14792
+ this._onContextMenuExternalMarker = () => {
14773
14793
  this.plugin.fire("contextmenu", this);
14774
14794
  };
14775
- this._onContextMenuExtenalMarkerRemover = addContextMenuListener(this._markerHTML, this._onContextMenuExtenalMarker);
14795
+ this._onContextMenuExternalMarkerRemover = addContextMenuListener(this._marker, this._onContextMenuExternalMarker);
14776
14796
  this._marker.addEventListener("mouseenter", this._onMouseEnterExternalMarker = () => {
14777
14797
  this.plugin.fire("markerMouseEnter", this);
14778
14798
  });
@@ -15143,7 +15163,7 @@ class Annotation extends Marker {
15143
15163
  this._marker = null;
15144
15164
  } else {
15145
15165
  this._marker.removeEventListener("click", this._onMouseClickedExternalMarker);
15146
- this._onContextMenuExtenalMarkerRemover();
15166
+ this._onContextMenuExternalMarkerRemover();
15147
15167
  this._marker.removeEventListener("mouseenter", this._onMouseEnterExternalMarker);
15148
15168
  this._marker.removeEventListener("mouseleave", this._onMouseLeaveExternalMarker);
15149
15169
  this._marker = null;
@@ -19388,6 +19408,8 @@ function getExtension (gl, name) {
19388
19408
  return extension;
19389
19409
  }
19390
19410
 
19411
+ const vec3_0 = math.vec3([0,0,0]);
19412
+
19391
19413
  /**
19392
19414
  * @private
19393
19415
  */
@@ -20066,9 +20088,11 @@ const Renderer$1 = function (scene, options) {
20066
20088
  // Transparent color fill
20067
20089
 
20068
20090
  if (normalFillTransparentBinLen > 0) {
20091
+ const eye = frameCtx.pickOrigin || scene.camera.eye;
20092
+ const byDist = normalFillTransparentBin.map(d => ({ drawable: d, distSq: math.distVec3(d.origin || vec3_0, eye) }));
20093
+ byDist.sort((a, b) => b.distSq - a.distSq);
20069
20094
  for (i = 0; i < normalFillTransparentBinLen; i++) {
20070
- drawable = normalFillTransparentBin[i];
20071
- drawable.drawColorTransparent(frameCtx);
20095
+ byDist[i].drawable.drawColorTransparent(frameCtx);
20072
20096
  }
20073
20097
  }
20074
20098
 
@@ -73103,6 +73127,10 @@ class DTXTrianglesColorRenderer {
73103
73127
  const sectionPlanes = scene._sectionPlanesState.sectionPlanes;
73104
73128
  const baseIndex = dataTextureLayer.layerIndex * numSectionPlanes;
73105
73129
  const renderFlags = model.renderFlags;
73130
+ if (scene.crossSections) {
73131
+ gl.uniform4fv(this._uSliceColor, scene.crossSections.sliceColor);
73132
+ gl.uniform1f(this._uSliceThickness, scene.crossSections.sliceThickness);
73133
+ }
73106
73134
  for (let sectionPlaneIndex = 0; sectionPlaneIndex < numAllocatedSectionPlanes; sectionPlaneIndex++) {
73107
73135
  const sectionPlaneUniforms = this._uSectionPlanes[sectionPlaneIndex];
73108
73136
  if (sectionPlaneUniforms) {
@@ -73240,6 +73268,11 @@ class DTXTrianglesColorRenderer {
73240
73268
  this._uTexturePerPolygonIdPortionIds = "uTexturePerPolygonIdPortionIds";
73241
73269
  this._uTexturePerObjectMatrix= "uTexturePerObjectMatrix";
73242
73270
  this._uCameraEyeRtc = program.getLocation("uCameraEyeRtc");
73271
+
73272
+ if (scene.crossSections) {
73273
+ this._uSliceColor = program.getLocation("sliceColor");
73274
+ this._uSliceThickness = program.getLocation("sliceThickness");
73275
+ }
73243
73276
  }
73244
73277
 
73245
73278
  _bindProgram(frameCtx) {
@@ -73556,11 +73589,14 @@ class DTXTrianglesColorRenderer {
73556
73589
  src.push("uniform vec3 sectionPlanePos" + i + ";");
73557
73590
  src.push("uniform vec3 sectionPlaneDir" + i + ";");
73558
73591
  }
73592
+ src.push("uniform float sliceThickness;");
73593
+ src.push("uniform vec4 sliceColor;");
73559
73594
  }
73560
73595
  src.push("in vec4 vColor;");
73561
73596
  src.push("out vec4 outColor;");
73562
73597
  src.push("void main(void) {");
73563
-
73598
+ src.push(" vec4 newColor;");
73599
+ src.push(" newColor = vColor;");
73564
73600
  if (clipping) {
73565
73601
  src.push(" bool clippable = vFlags2 > 0u;");
73566
73602
  src.push(" if (clippable) {");
@@ -73570,9 +73606,12 @@ class DTXTrianglesColorRenderer {
73570
73606
  src.push(" dist += clamp(dot(-sectionPlaneDir" + i + ".xyz, vWorldPosition.xyz - sectionPlanePos" + i + ".xyz), 0.0, 1000.0);");
73571
73607
  src.push("}");
73572
73608
  }
73573
- src.push(" if (dist > 0.0) { ");
73609
+ src.push(" if (dist > sliceThickness) { ");
73574
73610
  src.push(" discard;");
73575
73611
  src.push(" }");
73612
+ src.push(" if (dist > 0.0) { ");
73613
+ src.push(" newColor = sliceColor;");
73614
+ src.push(" }");
73576
73615
  src.push("}");
73577
73616
  }
73578
73617
 
@@ -73590,9 +73629,9 @@ class DTXTrianglesColorRenderer {
73590
73629
  src.push(" float blendFactor = uSAOParams[3];");
73591
73630
  src.push(" vec2 uv = vec2(gl_FragCoord.x / viewportWidth, gl_FragCoord.y / viewportHeight);");
73592
73631
  src.push(" float ambient = smoothstep(blendCutoff, 1.0, unpackRGBToFloat(texture(uOcclusionTexture, uv))) * blendFactor;");
73593
- src.push(" outColor = vec4(vColor.rgb * ambient, 1.0);");
73632
+ src.push(" outColor = vec4(newColor.rgb * ambient, 1.0);");
73594
73633
  } else {
73595
- src.push(" outColor = vColor;");
73634
+ src.push(" outColor = newColor;");
73596
73635
  }
73597
73636
 
73598
73637
  src.push("}");
@@ -74034,10 +74073,14 @@ class DTXTrianglesSilhouetteRenderer {
74034
74073
  src.push("uniform vec3 sectionPlanePos" + i + ";");
74035
74074
  src.push("uniform vec3 sectionPlaneDir" + i + ";");
74036
74075
  }
74076
+ src.push("uniform float sliceThickness;");
74077
+ src.push("uniform vec4 sliceColor;");
74037
74078
  }
74038
74079
  src.push("uniform vec4 color;");
74039
74080
  src.push("out vec4 outColor;");
74040
74081
  src.push("void main(void) {");
74082
+ src.push(" vec4 newColor;");
74083
+ src.push(" newColor = color;");
74041
74084
  if (clipping) {
74042
74085
  src.push(" bool clippable = vFlags2 > 0u;");
74043
74086
  src.push(" if (clippable) {");
@@ -74047,15 +74090,18 @@ class DTXTrianglesSilhouetteRenderer {
74047
74090
  src.push(" dist += clamp(dot(-sectionPlaneDir" + i + ".xyz, vWorldPosition.xyz - sectionPlanePos" + i + ".xyz), 0.0, 1000.0);");
74048
74091
  src.push("}");
74049
74092
  }
74050
- src.push(" if (dist > 0.0) { ");
74093
+ src.push(" if (dist > sliceThickness) { ");
74051
74094
  src.push(" discard;");
74052
74095
  src.push(" }");
74096
+ src.push(" if (dist > 0.0) { ");
74097
+ src.push(" newColor = sliceColor;");
74098
+ src.push(" }");
74053
74099
  src.push("}");
74054
74100
  }
74055
74101
  if (scene.logarithmicDepthBufferEnabled) {
74056
74102
  src.push(" gl_FragDepth = isPerspective == 0.0 ? gl_FragCoord.z : log2( vFragDepth ) * logDepthBufFC * 0.5;");
74057
74103
  }
74058
- src.push(" outColor = color;");
74104
+ src.push(" outColor = newColor;");
74059
74105
  src.push("}");
74060
74106
  return src;
74061
74107
  }
@@ -74454,10 +74500,14 @@ class DTXTrianglesEdgesRenderer {
74454
74500
  src.push("uniform vec3 sectionPlanePos" + i + ";");
74455
74501
  src.push("uniform vec3 sectionPlaneDir" + i + ";");
74456
74502
  }
74503
+ src.push("uniform float sliceThickness;");
74504
+ src.push("uniform vec4 sliceColor;");
74457
74505
  }
74458
74506
  src.push("in vec4 vColor;");
74459
74507
  src.push("out vec4 outColor;");
74460
74508
  src.push("void main(void) {");
74509
+ src.push(" vec4 newColor;");
74510
+ src.push(" newColor = vColor;");
74461
74511
  if (clipping) {
74462
74512
  src.push(" bool clippable = vFlags2 > 0u;");
74463
74513
  src.push(" if (clippable) {");
@@ -74467,13 +74517,18 @@ class DTXTrianglesEdgesRenderer {
74467
74517
  src.push(" dist += clamp(dot(-sectionPlaneDir" + i + ".xyz, vWorldPosition.xyz - sectionPlanePos" + i + ".xyz), 0.0, 1000.0);");
74468
74518
  src.push("}");
74469
74519
  }
74470
- src.push(" if (dist > 0.0) { discard; }");
74520
+ src.push(" if (dist > sliceThickness) { ");
74521
+ src.push(" discard;");
74522
+ src.push(" }");
74523
+ src.push(" if (dist > 0.0) { ");
74524
+ src.push(" newColor = sliceColor;");
74525
+ src.push(" }");
74471
74526
  src.push("}");
74472
74527
  }
74473
74528
  if (scene.logarithmicDepthBufferEnabled) {
74474
74529
  src.push(" gl_FragDepth = isPerspective == 0.0 ? gl_FragCoord.z : log2( vFragDepth ) * logDepthBufFC * 0.5;");
74475
74530
  }
74476
- src.push(" outColor = vColor;");
74531
+ src.push(" outColor = newColor;");
74477
74532
  src.push("}");
74478
74533
  return src;
74479
74534
  }
@@ -74863,10 +74918,14 @@ class DTXTrianglesEdgesColorRenderer {
74863
74918
  src.push("uniform vec3 sectionPlanePos" + i + ";");
74864
74919
  src.push("uniform vec3 sectionPlaneDir" + i + ";");
74865
74920
  }
74921
+ src.push("uniform float sliceThickness;");
74922
+ src.push("uniform vec4 sliceColor;");
74866
74923
  }
74867
74924
  src.push("in vec4 vColor;");
74868
74925
  src.push("out vec4 outColor;");
74869
74926
  src.push("void main(void) {");
74927
+ src.push(" vec4 newColor;");
74928
+ src.push(" newColor = vColor;");
74870
74929
  if (clipping) {
74871
74930
  src.push(" bool clippable = vFlags2 > 0u;");
74872
74931
  src.push(" if (clippable) {");
@@ -74876,13 +74935,18 @@ class DTXTrianglesEdgesColorRenderer {
74876
74935
  src.push(" dist += clamp(dot(-sectionPlaneDir" + i + ".xyz, vWorldPosition.xyz - sectionPlanePos" + i + ".xyz), 0.0, 1000.0);");
74877
74936
  src.push("}");
74878
74937
  }
74879
- src.push(" if (dist > 0.0) { discard; }");
74938
+ src.push(" if (dist > sliceThickness) { ");
74939
+ src.push(" discard;");
74940
+ src.push(" }");
74941
+ src.push(" if (dist > 0.0) { ");
74942
+ src.push(" newColor = sliceColor;");
74943
+ src.push(" }");
74880
74944
  src.push("}");
74881
74945
  }
74882
74946
  if (scene.logarithmicDepthBufferEnabled) {
74883
74947
  src.push(" gl_FragDepth = isPerspective == 0.0 ? gl_FragCoord.z : log2( vFragDepth ) * logDepthBufFC * 0.5;");
74884
74948
  }
74885
- src.push(" outColor = vColor;");
74949
+ src.push(" outColor = newColor;");
74886
74950
  src.push("}");
74887
74951
  return src;
74888
74952
  }
@@ -90752,7 +90816,7 @@ class FastNavPlugin extends Plugin {
90752
90816
  this._hideEdges = cfg.hideEdges !== false;
90753
90817
  this._hideTransparentObjects = !!cfg.hideTransparentObjects;
90754
90818
  this._scaleCanvasResolution = !!cfg.scaleCanvasResolution;
90755
- this._defaultScaleCanvasResolutionFactor = cfg.defaultScaleCanvasResolutionFactor || 1.0;
90819
+ this._defaultScaleCanvasResolutionFactor = cfg.defaultScaleCanvasResolutionFactor;
90756
90820
  this._scaleCanvasResolutionFactor = cfg.scaleCanvasResolutionFactor || 0.6;
90757
90821
  this._delayBeforeRestore = (cfg.delayBeforeRestore !== false);
90758
90822
  this._delayBeforeRestoreSeconds = cfg.delayBeforeRestoreSeconds || 0.5;
@@ -90768,6 +90832,7 @@ class FastNavPlugin extends Plugin {
90768
90832
  viewer.scene._renderer.setSAOEnabled(!this._hideSAO);
90769
90833
  viewer.scene._renderer.setTransparentEnabled(!this._hideTransparentObjects);
90770
90834
  viewer.scene._renderer.setEdgesEnabled(!this._hideEdges);
90835
+ this._originalCanvasResolutionScale = viewer.scene.canvas.resolutionScale;
90771
90836
  if (this._scaleCanvasResolution) {
90772
90837
  viewer.scene.canvas.resolutionScale = this._scaleCanvasResolutionFactor;
90773
90838
  } else {
@@ -90778,7 +90843,7 @@ class FastNavPlugin extends Plugin {
90778
90843
  };
90779
90844
 
90780
90845
  const switchToHighQuality = () => {
90781
- viewer.scene.canvas.resolutionScale = this._defaultScaleCanvasResolutionFactor;
90846
+ viewer.scene.canvas.resolutionScale = this._defaultScaleCanvasResolutionFactor || this._originalCanvasResolutionScale || 1.0;
90782
90847
  viewer.scene._renderer.setEdgesEnabled(true);
90783
90848
  viewer.scene._renderer.setColorTextureEnabled(true);
90784
90849
  viewer.scene._renderer.setPBREnabled(true);
@@ -90983,7 +91048,7 @@ class FastNavPlugin extends Plugin {
90983
91048
  * @param {Number} defaultScaleCanvasResolutionFactor Factor by scale canvas resolution when we stop interacting with the viewer.
90984
91049
  */
90985
91050
  set defaultScaleCanvasResolutionFactor(defaultScaleCanvasResolutionFactor) {
90986
- this._defaultScaleCanvasResolutionFactor = defaultScaleCanvasResolutionFactor || 1.0;
91051
+ this._defaultScaleCanvasResolutionFactor = defaultScaleCanvasResolutionFactor;
90987
91052
  }
90988
91053
 
90989
91054
  /**
@@ -97728,7 +97793,7 @@ class MousePickHandler {
97728
97793
 
97729
97794
  this._timeout = setTimeout(() => {
97730
97795
 
97731
- if (firstClickPickResult && firstClickPickResult.worldPos) {
97796
+ if (firstClickPickResult) {
97732
97797
 
97733
97798
  cameraControl.fire("picked", firstClickPickResult, true);
97734
97799
 
@@ -101920,8 +101985,8 @@ class MetaScene {
101920
101985
 
101921
101986
  for (let modelId in this.metaModels) {
101922
101987
  const metaModel = this.metaModels[modelId];
101923
- for (let i = 0, len = metaModel.metaObjects.length; i < len; i++) {
101924
- const metaObject = metaModel.metaObjects[i];
101988
+ for (let objectId in metaModel.metaObjects) {
101989
+ const metaObject = metaModel.metaObjects[objectId];
101925
101990
  metaObject.metaModels.push(metaModel);
101926
101991
  }
101927
101992
  }
@@ -126540,6 +126605,7 @@ class TreeViewPlugin extends Plugin {
126540
126605
  * @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.
126541
126606
  * @param {RenderService} [cfg.renderService] Optional {@link RenderService} to use. Defaults to the {@link TreeViewPlugin}'s default {@link RenderService}.
126542
126607
  * @param {Boolean} [cfg.showIndeterminate=false] When true, will show indeterminate state for checkboxes when some but not all child nodes are checked
126608
+ * @param {Boolean} [cfg.showProjectNode=false] When true, will show top level project node when hierarchy is set to "storeys"
126543
126609
  */
126544
126610
  constructor(viewer, cfg = {}) {
126545
126611
 
@@ -126592,6 +126658,7 @@ class TreeViewPlugin extends Plugin {
126592
126658
  this._showListItemElementId = null;
126593
126659
  this._renderService = cfg.renderService || new RenderService();
126594
126660
  this._showIndeterminate = cfg.showIndeterminate ?? false;
126661
+ this._showProjectNode = cfg.showProjectNode ?? false;
126595
126662
 
126596
126663
  if (!this._renderService) {
126597
126664
  throw new Error('TreeViewPlugin: no render service set');
@@ -127146,11 +127213,11 @@ class TreeViewPlugin extends Plugin {
127146
127213
  _createStoreysNodes() {
127147
127214
  const rootMetaObjects = this._viewer.metaScene.rootMetaObjects;
127148
127215
  for (let id in rootMetaObjects) {
127149
- this._createStoreysNodes2(rootMetaObjects[id], null, null, null);
127216
+ this._createStoreysNodes2(rootMetaObjects[id], null, null, null, null);
127150
127217
  }
127151
127218
  }
127152
127219
 
127153
- _createStoreysNodes2(metaObject, buildingNode, storeyNode, typeNodes) {
127220
+ _createStoreysNodes2(metaObject, projectNode, buildingNode, storeyNode, typeNodes) {
127154
127221
  if (this._pruneEmptyNodes && (metaObject._countEntities === 0)) {
127155
127222
  return;
127156
127223
  }
@@ -127158,20 +127225,41 @@ class TreeViewPlugin extends Plugin {
127158
127225
  const metaObjectName = metaObject.name;
127159
127226
  const children = metaObject.children;
127160
127227
  const objectId = metaObject.id;
127161
- if (metaObjectType === "IfcBuilding") {
127228
+
127229
+ if (this._showProjectNode && metaObjectType === 'IfcProject') {
127230
+ projectNode = {
127231
+ nodeId: `${this._id}-${objectId}`,
127232
+ objectId,
127233
+ title: (metaObject.metaModels.length === 0) ? metaObjectName : this._rootNames[metaObject.metaModels[0].id] || ((metaObjectName && metaObjectName !== "" && metaObjectName !== "Undefined" && metaObjectName !== "Default") ? metaObjectName : metaObjectType),
127234
+ type: metaObjectType,
127235
+ parent: null,
127236
+ numEntities: 0,
127237
+ numVisibleEntities: 0,
127238
+ checked: false,
127239
+ xrayed: false,
127240
+ children: [],
127241
+ };
127242
+ this._rootNodes.push(projectNode);
127243
+ this._objectNodes[projectNode.objectId] = projectNode;
127244
+ this._nodeNodes[projectNode.nodeId] = projectNode;
127245
+ } else if (metaObjectType === "IfcBuilding") {
127162
127246
  buildingNode = {
127163
127247
  nodeId: `${this._id}-${objectId}`,
127164
127248
  objectId: objectId,
127165
127249
  title: (metaObject.metaModels.length === 0) ? metaObjectName : this._rootNames[metaObject.metaModels[0].id] || ((metaObjectName && metaObjectName !== "" && metaObjectName !== "Undefined" && metaObjectName !== "Default") ? metaObjectName : metaObjectType),
127166
127250
  type: metaObjectType,
127167
- parent: null,
127251
+ parent: projectNode,
127168
127252
  numEntities: 0,
127169
127253
  numVisibleEntities: 0,
127170
127254
  checked: false,
127171
127255
  xrayed: false,
127172
127256
  children: []
127173
127257
  };
127174
- this._rootNodes.push(buildingNode);
127258
+ if (projectNode) {
127259
+ projectNode.children.push(buildingNode);
127260
+ } else {
127261
+ this._rootNodes.push(buildingNode);
127262
+ }
127175
127263
  this._objectNodes[buildingNode.objectId] = buildingNode;
127176
127264
  this._nodeNodes[buildingNode.nodeId] = buildingNode;
127177
127265
  } else if (metaObjectType === "IfcBuildingStorey") {
@@ -127241,7 +127329,7 @@ class TreeViewPlugin extends Plugin {
127241
127329
  if (children) {
127242
127330
  for (let i = 0, len = children.length; i < len; i++) {
127243
127331
  const childMetaObject = children[i];
127244
- this._createStoreysNodes2(childMetaObject, buildingNode, storeyNode, typeNodes);
127332
+ this._createStoreysNodes2(childMetaObject, projectNode, buildingNode, storeyNode, typeNodes);
127245
127333
  }
127246
127334
  }
127247
127335
  }
@@ -140822,8 +140910,21 @@ class Zone extends Component {
140822
140910
  }
140823
140911
 
140824
140912
 
140825
- const positions = [].concat(...pos);
140913
+ const min = idx => Math.min(...pos.map(p => p[idx]));
140914
+ const max = idx => Math.max(...pos.map(p => p[idx]));
140915
+
140916
+ const xmin = min(0);
140917
+ const ymin = min(1);
140918
+ const zmin = min(2);
140919
+ const xmax = max(0);
140920
+ const ymax = max(1);
140921
+ const zmax = max(2);
140922
+
140923
+ this._center = math.vec3([ (xmin + xmax) / 2, (ymin + ymax) / 2, (zmin + zmax) / 2 ]);
140924
+
140925
+ const positions = [].concat(...pos.map(p => math.subVec3(p, this._center, p)));
140826
140926
  this._zoneMesh = new Mesh(scene, {
140927
+ origin: this._center,
140827
140928
  edges: this._edges,
140828
140929
  geometry: new ReadableGeometry(
140829
140930
  scene,
@@ -140864,19 +140965,6 @@ class Zone extends Component {
140864
140965
  }
140865
140966
 
140866
140967
  this._metrics = null;
140867
-
140868
-
140869
- const min = idx => Math.min(...pos.map(p => p[idx]));
140870
- const max = idx => Math.max(...pos.map(p => p[idx]));
140871
-
140872
- const xmin = min(0);
140873
- const ymin = min(1);
140874
- const zmin = min(2);
140875
- const xmax = max(0);
140876
- const ymax = max(1);
140877
- const zmax = max(2);
140878
-
140879
- this._center = math.vec3([ (xmin + xmax) / 2, (ymin + ymax) / 2, (zmin + zmax) / 2 ]);
140880
140968
  }
140881
140969
 
140882
140970
  get baseArea() {