@xeokit/xeokit-sdk 2.6.61 → 2.6.63

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 (25) hide show
  1. package/dist/xeokit-sdk.cjs.js +123 -51
  2. package/dist/xeokit-sdk.es.js +123 -51
  3. package/dist/xeokit-sdk.es5.js +89 -87
  4. package/dist/xeokit-sdk.min.cjs.js +5 -5
  5. package/dist/xeokit-sdk.min.es.js +5 -5
  6. package/dist/xeokit-sdk.min.es5.js +4 -4
  7. package/package.json +2 -1
  8. package/src/extras/ContextMenu/ContextMenu.js +11 -4
  9. package/src/plugins/AnnotationsPlugin/Annotation.js +3 -3
  10. package/src/plugins/ZonesPlugin/ZonesPlugin.js +14 -14
  11. package/src/plugins/lib/html/MenuEvent.js +17 -4
  12. package/src/viewer/metadata/MetaScene.js +2 -2
  13. package/src/viewer/scene/CameraControl/lib/handlers/KeyboardPanRotateDollyHandler.js +10 -0
  14. package/src/viewer/scene/CameraControl/lib/handlers/MousePanRotateDollyHandler.js +10 -0
  15. package/src/viewer/scene/CameraControl/lib/handlers/MousePickHandler.js +1 -1
  16. package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesColorRenderer.js +19 -4
  17. package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesEdgesColorRenderer.js +11 -2
  18. package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesEdgesRenderer.js +11 -2
  19. package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesSilhouetteRenderer.js +9 -2
  20. package/src/viewer/scene/model/vbo/VBORenderer.js +2 -2
  21. package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesBatchingRenderer.js +3 -1
  22. package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesSnapRenderer.js +5 -3
  23. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesInstancingRenderer.js +3 -1
  24. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesSnapRenderer.js +6 -4
  25. package/src/viewer/scene/webgl/Renderer.js +6 -2
@@ -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
 
@@ -52150,7 +52174,7 @@ class VBORenderer {
52150
52174
  }
52151
52175
 
52152
52176
  if (this._instancing) {
52153
- if (this._edges) {
52177
+ if (this._edges && state.edgeIndicesBuf) {
52154
52178
  state.edgeIndicesBuf.bind();
52155
52179
  } else {
52156
52180
  if (state.indicesBuf) {
@@ -52158,7 +52182,7 @@ class VBORenderer {
52158
52182
  }
52159
52183
  }
52160
52184
  } else {
52161
- if (this._edges) {
52185
+ if (this._edges && state.edgeIndicesBuf) {
52162
52186
  state.edgeIndicesBuf.bind();
52163
52187
  } else {
52164
52188
  if (state.indicesBuf) {
@@ -52425,7 +52449,9 @@ class TrianglesBatchingRenderer extends VBORenderer {
52425
52449
  } = drawCfg;
52426
52450
 
52427
52451
  if (this._edges) {
52428
- gl.drawElements(gl.LINES, state.edgeIndicesBuf.numItems, state.edgeIndicesBuf.itemType, 0);
52452
+ if (state.edgeIndicesBuf) {
52453
+ gl.drawElements(gl.LINES, state.edgeIndicesBuf.numItems, state.edgeIndicesBuf.itemType, 0);
52454
+ }
52429
52455
  } else {
52430
52456
  const count = frameCtx.pickElementsCount || state.indicesBuf.numItems;
52431
52457
  const offset = frameCtx.pickElementsOffset ? frameCtx.pickElementsOffset * state.indicesBuf.itemByteSize : 0;
@@ -55590,9 +55616,11 @@ class TrianglesSnapRenderer$1 extends VBORenderer{
55590
55616
  //=============================================================
55591
55617
 
55592
55618
  if (frameCtx.snapMode === "edge") {
55593
- state.edgeIndicesBuf.bind();
55594
- gl.drawElements(gl.LINES, state.edgeIndicesBuf.numItems, state.edgeIndicesBuf.itemType, 0);
55595
- state.edgeIndicesBuf.unbind(); // needed?
55619
+ if (state.edgeIndicesBuf) {
55620
+ state.edgeIndicesBuf.bind();
55621
+ gl.drawElements(gl.LINES, state.edgeIndicesBuf.numItems, state.edgeIndicesBuf.itemType, 0);
55622
+ state.edgeIndicesBuf.unbind(); // needed?
55623
+ }
55596
55624
  } else {
55597
55625
  gl.drawArrays(gl.POINTS, 0, state.positionsBuf.numItems);
55598
55626
  }
@@ -57761,7 +57789,9 @@ class TrianglesInstancingRenderer extends VBORenderer {
57761
57789
  } = drawCfg;
57762
57790
 
57763
57791
  if (this._edges) {
57764
- gl.drawElementsInstanced(gl.LINES, state.edgeIndicesBuf.numItems, state.edgeIndicesBuf.itemType, 0, state.numInstances);
57792
+ if (state.edgeIndicesBuf) {
57793
+ gl.drawElementsInstanced(gl.LINES, state.edgeIndicesBuf.numItems, state.edgeIndicesBuf.itemType, 0, state.numInstances);
57794
+ }
57765
57795
  } else {
57766
57796
  gl.drawElementsInstanced(gl.TRIANGLES, state.indicesBuf.numItems, state.indicesBuf.itemType, 0, state.numInstances);
57767
57797
 
@@ -61053,10 +61083,12 @@ class TrianglesSnapRenderer extends VBORenderer {
61053
61083
  this._aFlags.bindArrayBuffer(state.flagsBuf);
61054
61084
  gl.vertexAttribDivisor(this._aFlags.location, 1);
61055
61085
 
61056
- if (frameCtx.snapMode === "edge") {
61057
- state.edgeIndicesBuf.bind();
61058
- gl.drawElementsInstanced(gl.LINES, state.edgeIndicesBuf.numItems, state.edgeIndicesBuf.itemType, 0, state.numInstances);
61059
- state.edgeIndicesBuf.unbind(); // needed?
61086
+ if (frameCtx.snapMode === "edge" ) {
61087
+ if (state.edgeIndicesBuf) {
61088
+ state.edgeIndicesBuf.bind();
61089
+ gl.drawElementsInstanced(gl.LINES, state.edgeIndicesBuf.numItems, state.edgeIndicesBuf.itemType, 0, state.numInstances);
61090
+ state.edgeIndicesBuf.unbind(); // needed?
61091
+ }
61060
61092
  } else {
61061
61093
  gl.drawArraysInstanced(gl.POINTS, 0, state.positionsBuf.numItems, state.numInstances);
61062
61094
  }
@@ -73103,6 +73135,10 @@ class DTXTrianglesColorRenderer {
73103
73135
  const sectionPlanes = scene._sectionPlanesState.sectionPlanes;
73104
73136
  const baseIndex = dataTextureLayer.layerIndex * numSectionPlanes;
73105
73137
  const renderFlags = model.renderFlags;
73138
+ if (scene.crossSections) {
73139
+ gl.uniform4fv(this._uSliceColor, scene.crossSections.sliceColor);
73140
+ gl.uniform1f(this._uSliceThickness, scene.crossSections.sliceThickness);
73141
+ }
73106
73142
  for (let sectionPlaneIndex = 0; sectionPlaneIndex < numAllocatedSectionPlanes; sectionPlaneIndex++) {
73107
73143
  const sectionPlaneUniforms = this._uSectionPlanes[sectionPlaneIndex];
73108
73144
  if (sectionPlaneUniforms) {
@@ -73240,6 +73276,11 @@ class DTXTrianglesColorRenderer {
73240
73276
  this._uTexturePerPolygonIdPortionIds = "uTexturePerPolygonIdPortionIds";
73241
73277
  this._uTexturePerObjectMatrix= "uTexturePerObjectMatrix";
73242
73278
  this._uCameraEyeRtc = program.getLocation("uCameraEyeRtc");
73279
+
73280
+ if (scene.crossSections) {
73281
+ this._uSliceColor = program.getLocation("sliceColor");
73282
+ this._uSliceThickness = program.getLocation("sliceThickness");
73283
+ }
73243
73284
  }
73244
73285
 
73245
73286
  _bindProgram(frameCtx) {
@@ -73556,11 +73597,14 @@ class DTXTrianglesColorRenderer {
73556
73597
  src.push("uniform vec3 sectionPlanePos" + i + ";");
73557
73598
  src.push("uniform vec3 sectionPlaneDir" + i + ";");
73558
73599
  }
73600
+ src.push("uniform float sliceThickness;");
73601
+ src.push("uniform vec4 sliceColor;");
73559
73602
  }
73560
73603
  src.push("in vec4 vColor;");
73561
73604
  src.push("out vec4 outColor;");
73562
73605
  src.push("void main(void) {");
73563
-
73606
+ src.push(" vec4 newColor;");
73607
+ src.push(" newColor = vColor;");
73564
73608
  if (clipping) {
73565
73609
  src.push(" bool clippable = vFlags2 > 0u;");
73566
73610
  src.push(" if (clippable) {");
@@ -73570,9 +73614,12 @@ class DTXTrianglesColorRenderer {
73570
73614
  src.push(" dist += clamp(dot(-sectionPlaneDir" + i + ".xyz, vWorldPosition.xyz - sectionPlanePos" + i + ".xyz), 0.0, 1000.0);");
73571
73615
  src.push("}");
73572
73616
  }
73573
- src.push(" if (dist > 0.0) { ");
73617
+ src.push(" if (dist > sliceThickness) { ");
73574
73618
  src.push(" discard;");
73575
73619
  src.push(" }");
73620
+ src.push(" if (dist > 0.0) { ");
73621
+ src.push(" newColor = sliceColor;");
73622
+ src.push(" }");
73576
73623
  src.push("}");
73577
73624
  }
73578
73625
 
@@ -73590,9 +73637,9 @@ class DTXTrianglesColorRenderer {
73590
73637
  src.push(" float blendFactor = uSAOParams[3];");
73591
73638
  src.push(" vec2 uv = vec2(gl_FragCoord.x / viewportWidth, gl_FragCoord.y / viewportHeight);");
73592
73639
  src.push(" float ambient = smoothstep(blendCutoff, 1.0, unpackRGBToFloat(texture(uOcclusionTexture, uv))) * blendFactor;");
73593
- src.push(" outColor = vec4(vColor.rgb * ambient, 1.0);");
73640
+ src.push(" outColor = vec4(newColor.rgb * ambient, 1.0);");
73594
73641
  } else {
73595
- src.push(" outColor = vColor;");
73642
+ src.push(" outColor = newColor;");
73596
73643
  }
73597
73644
 
73598
73645
  src.push("}");
@@ -74034,10 +74081,14 @@ class DTXTrianglesSilhouetteRenderer {
74034
74081
  src.push("uniform vec3 sectionPlanePos" + i + ";");
74035
74082
  src.push("uniform vec3 sectionPlaneDir" + i + ";");
74036
74083
  }
74084
+ src.push("uniform float sliceThickness;");
74085
+ src.push("uniform vec4 sliceColor;");
74037
74086
  }
74038
74087
  src.push("uniform vec4 color;");
74039
74088
  src.push("out vec4 outColor;");
74040
74089
  src.push("void main(void) {");
74090
+ src.push(" vec4 newColor;");
74091
+ src.push(" newColor = color;");
74041
74092
  if (clipping) {
74042
74093
  src.push(" bool clippable = vFlags2 > 0u;");
74043
74094
  src.push(" if (clippable) {");
@@ -74047,15 +74098,18 @@ class DTXTrianglesSilhouetteRenderer {
74047
74098
  src.push(" dist += clamp(dot(-sectionPlaneDir" + i + ".xyz, vWorldPosition.xyz - sectionPlanePos" + i + ".xyz), 0.0, 1000.0);");
74048
74099
  src.push("}");
74049
74100
  }
74050
- src.push(" if (dist > 0.0) { ");
74101
+ src.push(" if (dist > sliceThickness) { ");
74051
74102
  src.push(" discard;");
74052
74103
  src.push(" }");
74104
+ src.push(" if (dist > 0.0) { ");
74105
+ src.push(" newColor = sliceColor;");
74106
+ src.push(" }");
74053
74107
  src.push("}");
74054
74108
  }
74055
74109
  if (scene.logarithmicDepthBufferEnabled) {
74056
74110
  src.push(" gl_FragDepth = isPerspective == 0.0 ? gl_FragCoord.z : log2( vFragDepth ) * logDepthBufFC * 0.5;");
74057
74111
  }
74058
- src.push(" outColor = color;");
74112
+ src.push(" outColor = newColor;");
74059
74113
  src.push("}");
74060
74114
  return src;
74061
74115
  }
@@ -74454,10 +74508,14 @@ class DTXTrianglesEdgesRenderer {
74454
74508
  src.push("uniform vec3 sectionPlanePos" + i + ";");
74455
74509
  src.push("uniform vec3 sectionPlaneDir" + i + ";");
74456
74510
  }
74511
+ src.push("uniform float sliceThickness;");
74512
+ src.push("uniform vec4 sliceColor;");
74457
74513
  }
74458
74514
  src.push("in vec4 vColor;");
74459
74515
  src.push("out vec4 outColor;");
74460
74516
  src.push("void main(void) {");
74517
+ src.push(" vec4 newColor;");
74518
+ src.push(" newColor = vColor;");
74461
74519
  if (clipping) {
74462
74520
  src.push(" bool clippable = vFlags2 > 0u;");
74463
74521
  src.push(" if (clippable) {");
@@ -74467,13 +74525,18 @@ class DTXTrianglesEdgesRenderer {
74467
74525
  src.push(" dist += clamp(dot(-sectionPlaneDir" + i + ".xyz, vWorldPosition.xyz - sectionPlanePos" + i + ".xyz), 0.0, 1000.0);");
74468
74526
  src.push("}");
74469
74527
  }
74470
- src.push(" if (dist > 0.0) { discard; }");
74528
+ src.push(" if (dist > sliceThickness) { ");
74529
+ src.push(" discard;");
74530
+ src.push(" }");
74531
+ src.push(" if (dist > 0.0) { ");
74532
+ src.push(" newColor = sliceColor;");
74533
+ src.push(" }");
74471
74534
  src.push("}");
74472
74535
  }
74473
74536
  if (scene.logarithmicDepthBufferEnabled) {
74474
74537
  src.push(" gl_FragDepth = isPerspective == 0.0 ? gl_FragCoord.z : log2( vFragDepth ) * logDepthBufFC * 0.5;");
74475
74538
  }
74476
- src.push(" outColor = vColor;");
74539
+ src.push(" outColor = newColor;");
74477
74540
  src.push("}");
74478
74541
  return src;
74479
74542
  }
@@ -74863,10 +74926,14 @@ class DTXTrianglesEdgesColorRenderer {
74863
74926
  src.push("uniform vec3 sectionPlanePos" + i + ";");
74864
74927
  src.push("uniform vec3 sectionPlaneDir" + i + ";");
74865
74928
  }
74929
+ src.push("uniform float sliceThickness;");
74930
+ src.push("uniform vec4 sliceColor;");
74866
74931
  }
74867
74932
  src.push("in vec4 vColor;");
74868
74933
  src.push("out vec4 outColor;");
74869
74934
  src.push("void main(void) {");
74935
+ src.push(" vec4 newColor;");
74936
+ src.push(" newColor = vColor;");
74870
74937
  if (clipping) {
74871
74938
  src.push(" bool clippable = vFlags2 > 0u;");
74872
74939
  src.push(" if (clippable) {");
@@ -74876,13 +74943,18 @@ class DTXTrianglesEdgesColorRenderer {
74876
74943
  src.push(" dist += clamp(dot(-sectionPlaneDir" + i + ".xyz, vWorldPosition.xyz - sectionPlanePos" + i + ".xyz), 0.0, 1000.0);");
74877
74944
  src.push("}");
74878
74945
  }
74879
- src.push(" if (dist > 0.0) { discard; }");
74946
+ src.push(" if (dist > sliceThickness) { ");
74947
+ src.push(" discard;");
74948
+ src.push(" }");
74949
+ src.push(" if (dist > 0.0) { ");
74950
+ src.push(" newColor = sliceColor;");
74951
+ src.push(" }");
74880
74952
  src.push("}");
74881
74953
  }
74882
74954
  if (scene.logarithmicDepthBufferEnabled) {
74883
74955
  src.push(" gl_FragDepth = isPerspective == 0.0 ? gl_FragCoord.z : log2( vFragDepth ) * logDepthBufFC * 0.5;");
74884
74956
  }
74885
- src.push(" outColor = vColor;");
74957
+ src.push(" outColor = newColor;");
74886
74958
  src.push("}");
74887
74959
  return src;
74888
74960
  }
@@ -97729,7 +97801,7 @@ class MousePickHandler {
97729
97801
 
97730
97802
  this._timeout = setTimeout(() => {
97731
97803
 
97732
- if (firstClickPickResult && firstClickPickResult.worldPos) {
97804
+ if (firstClickPickResult) {
97733
97805
 
97734
97806
  cameraControl.fire("picked", firstClickPickResult, true);
97735
97807
 
@@ -101921,8 +101993,8 @@ class MetaScene {
101921
101993
 
101922
101994
  for (let modelId in this.metaModels) {
101923
101995
  const metaModel = this.metaModels[modelId];
101924
- for (let i = 0, len = metaModel.metaObjects.length; i < len; i++) {
101925
- const metaObject = metaModel.metaObjects[i];
101996
+ for (let objectId in metaModel.metaObjects) {
101997
+ const metaObject = metaModel.metaObjects[objectId];
101926
101998
  metaObject.metaModels.push(metaModel);
101927
101999
  }
101928
102000
  }
@@ -140846,8 +140918,21 @@ class Zone extends Component {
140846
140918
  }
140847
140919
 
140848
140920
 
140849
- const positions = [].concat(...pos);
140921
+ const min = idx => Math.min(...pos.map(p => p[idx]));
140922
+ const max = idx => Math.max(...pos.map(p => p[idx]));
140923
+
140924
+ const xmin = min(0);
140925
+ const ymin = min(1);
140926
+ const zmin = min(2);
140927
+ const xmax = max(0);
140928
+ const ymax = max(1);
140929
+ const zmax = max(2);
140930
+
140931
+ this._center = math.vec3([ (xmin + xmax) / 2, (ymin + ymax) / 2, (zmin + zmax) / 2 ]);
140932
+
140933
+ const positions = [].concat(...pos.map(p => math.subVec3(p, this._center, p)));
140850
140934
  this._zoneMesh = new Mesh(scene, {
140935
+ origin: this._center,
140851
140936
  edges: this._edges,
140852
140937
  geometry: new ReadableGeometry(
140853
140938
  scene,
@@ -140888,19 +140973,6 @@ class Zone extends Component {
140888
140973
  }
140889
140974
 
140890
140975
  this._metrics = null;
140891
-
140892
-
140893
- const min = idx => Math.min(...pos.map(p => p[idx]));
140894
- const max = idx => Math.max(...pos.map(p => p[idx]));
140895
-
140896
- const xmin = min(0);
140897
- const ymin = min(1);
140898
- const zmin = min(2);
140899
- const xmax = max(0);
140900
- const ymax = max(1);
140901
- const zmax = max(2);
140902
-
140903
- this._center = math.vec3([ (xmin + xmax) / 2, (ymin + ymax) / 2, (zmin + zmax) / 2 ]);
140904
140976
  }
140905
140977
 
140906
140978
  get baseArea() {