@xeokit/xeokit-sdk 2.6.31 → 2.6.33

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.
@@ -1038,20 +1038,23 @@ class PointerLens {
1038
1038
  this._lensCursorDiv.style.pointerEvents = "none";
1039
1039
 
1040
1040
  this._lensContainer = document.createElement('div');
1041
+ this._lensContainerId = cfg.containerId || 'xeokit-lens';
1042
+ this._lensContainer.setAttribute("id", this._lensContainerId);
1043
+
1041
1044
  this._lensContainer.style.border = "1px solid black";
1042
1045
  this._lensContainer.style.background = "white";
1043
1046
  // this._lensContainer.style.opacity = "0";
1044
1047
  this._lensContainer.style.borderRadius = "50%";
1045
1048
  this._lensContainer.style.width = "300px";
1046
1049
  this._lensContainer.style.height = "300px";
1047
- this._lensContainer.style.marginTop = "85px";
1048
- this._lensContainer.style.marginLeft = "25px";
1050
+
1049
1051
  this._lensContainer.style.zIndex = "15000";
1050
1052
  this._lensContainer.style.position = "absolute";
1051
1053
  this._lensContainer.style.pointerEvents = "none";
1052
1054
  this._lensContainer.style.visibility = "hidden";
1053
1055
 
1054
1056
  this._lensCanvas = document.createElement('canvas');
1057
+ this._lensCanvas.id = `${this._lensContainerId}-canvas`;
1055
1058
  // this._lensCanvas.style.background = "darkblue";
1056
1059
  this._lensCanvas.style.borderRadius = "50%";
1057
1060
 
@@ -1068,7 +1071,12 @@ class PointerLens {
1068
1071
 
1069
1072
  this._canvasPos = null;
1070
1073
  this._snappedCanvasPos = null;
1071
- this._lensPosToggle = true;
1074
+ this._lensPosToggle = cfg.lensPosToggle || true;
1075
+ this._lensPosToggleAmount = cfg.lensPosToggleAmount || 85;
1076
+ this._lensPosMarginLeft = cfg.lensPosMarginLeft || 85;
1077
+ this._lensPosMarginTop = cfg.lensPosMarginTop || 25;
1078
+ this._lensContainer.style.marginTop = `${this._lensPosMarginTop}px`;
1079
+ this._lensContainer.style.marginLeft = `${this._lensPosMarginLeft}px`;
1072
1080
 
1073
1081
  this._zoomLevel = cfg.zoomLevel || 2;
1074
1082
 
@@ -1098,12 +1106,12 @@ class PointerLens {
1098
1106
  const pointerOnLens =
1099
1107
  this._canvasPos[0] < lensRect.right && this._canvasPos[0] > lensRect.left &&
1100
1108
  this._canvasPos[1] < lensRect.bottom && this._canvasPos[1] > lensRect.top;
1101
- this._lensContainer.style.marginLeft = `25px`;
1109
+ this._lensContainer.style.marginLeft = `${this._lensPosMarginLeft}px`;
1102
1110
  if (pointerOnLens) {
1103
1111
  if (this._lensPosToggle) {
1104
- this._lensContainer.style.marginTop = `${canvasRect.bottom - canvasRect.top - this._lensCanvas.height - 85}px`;
1112
+ this._lensContainer.style.marginTop = `${canvasRect.bottom - canvasRect.top - this._lensCanvas.height - this._lensPosToggleAmount}px`;
1105
1113
  } else {
1106
- this._lensContainer.style.marginTop = `85px`;
1114
+ this._lensContainer.style.marginTop = `${this._lensPosMarginTop}px`;
1107
1115
  }
1108
1116
  this._lensPosToggle = !this._lensPosToggle;
1109
1117
  }
@@ -9558,7 +9566,7 @@ class Dot {
9558
9566
  this._dotClickable = document.createElement('div');
9559
9567
  this._dotClickable.className += this._dotClickable.className ? ' viewer-ruler-dot-clickable' : 'viewer-ruler-dot-clickable';
9560
9568
 
9561
- this._visible = !!cfg.visible;
9569
+ this._visible = cfg.visible !== false;
9562
9570
  this._culled = false;
9563
9571
 
9564
9572
  var dot = this._dot;
@@ -9570,7 +9578,7 @@ class Dot {
9570
9578
  dotStyle["z-index"] = cfg.zIndex === undefined ? "40000005" : cfg.zIndex ;
9571
9579
  dotStyle.width = 8 + "px";
9572
9580
  dotStyle.height = 8 + "px";
9573
- dotStyle.visibility = cfg.visible !== false ? "visible" : "hidden";
9581
+ dotStyle.visibility = this._visible ? "visible" : "hidden";
9574
9582
  dotStyle.top = 0 + "px";
9575
9583
  dotStyle.left = 0 + "px";
9576
9584
  dotStyle["box-shadow"] = "0 2px 5px 0 #182A3D;";
@@ -19152,6 +19160,9 @@ const Renderer$1 = function (scene, options) {
19152
19160
  let drawableTypeInfo = {};
19153
19161
  let drawables = {};
19154
19162
 
19163
+ let postSortDrawableList = [];
19164
+ let postCullDrawableList = [];
19165
+
19155
19166
  let drawableListDirty = true;
19156
19167
  let stateSortDirty = true;
19157
19168
  let imageDirty = true;
@@ -19372,33 +19383,33 @@ const Renderer$1 = function (scene, options) {
19372
19383
  }
19373
19384
 
19374
19385
  function sortDrawableList() {
19386
+ let lenDrawableList = 0;
19375
19387
  for (let type in drawableTypeInfo) {
19376
19388
  if (drawableTypeInfo.hasOwnProperty(type)) {
19377
19389
  const drawableInfo = drawableTypeInfo[type];
19378
- if (drawableInfo.isStateSortable) {
19379
- drawableInfo.drawableListPreCull.sort(drawableInfo.stateSortCompare);
19390
+ const drawableListPreCull = drawableInfo.drawableListPreCull;
19391
+ for (let i = 0, len = drawableListPreCull.length; i < len; i++) {
19392
+ const drawable = drawableListPreCull[i];
19393
+ postSortDrawableList[lenDrawableList++] = drawable;
19380
19394
  }
19381
19395
  }
19382
19396
  }
19397
+ postSortDrawableList.length = lenDrawableList;
19398
+ postSortDrawableList.sort((a, b) => {
19399
+ return a.renderOrder - b.renderOrder;
19400
+ });
19383
19401
  }
19384
19402
 
19385
19403
  function cullDrawableList() {
19386
- for (let type in drawableTypeInfo) {
19387
- if (drawableTypeInfo.hasOwnProperty(type)) {
19388
- const drawableInfo = drawableTypeInfo[type];
19389
- const drawableListPreCull = drawableInfo.drawableListPreCull;
19390
- const drawableList = drawableInfo.drawableList;
19391
- let lenDrawableList = 0;
19392
- for (let i = 0, len = drawableListPreCull.length; i < len; i++) {
19393
- const drawable = drawableListPreCull[i];
19394
- drawable.rebuildRenderFlags();
19395
- if (!drawable.renderFlags.culled) {
19396
- drawableList[lenDrawableList++] = drawable;
19397
- }
19398
- }
19399
- drawableList.length = lenDrawableList;
19404
+ let lenDrawableList = 0;
19405
+ for (let i = 0, len = postSortDrawableList.length; i < len; i++) {
19406
+ const drawable = postSortDrawableList[i];
19407
+ drawable.rebuildRenderFlags();
19408
+ if (!drawable.renderFlags.culled) {
19409
+ postCullDrawableList[lenDrawableList++] = drawable;
19400
19410
  }
19401
19411
  }
19412
+ postCullDrawableList.length = lenDrawableList;
19402
19413
  }
19403
19414
 
19404
19415
  function draw(params) {
@@ -19474,25 +19485,16 @@ const Renderer$1 = function (scene, options) {
19474
19485
  if (params.clear !== false) {
19475
19486
  gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
19476
19487
  }
19488
+ for (let i = 0, len = postCullDrawableList.length; i < len; i++) {
19477
19489
 
19478
- for (let type in drawableTypeInfo) {
19479
- if (drawableTypeInfo.hasOwnProperty(type)) {
19480
-
19481
- const drawableInfo = drawableTypeInfo[type];
19482
- const drawableList = drawableInfo.drawableList;
19483
-
19484
- for (let i = 0, len = drawableList.length; i < len; i++) {
19485
-
19486
- const drawable = drawableList[i];
19490
+ const drawable = postCullDrawableList[i];
19487
19491
 
19488
- if (drawable.culled === true || drawable.visible === false || !drawable.drawDepth || !drawable.saoEnabled) {
19489
- continue;
19490
- }
19492
+ if (drawable.culled === true || drawable.visible === false || !drawable.drawDepth || !drawable.saoEnabled) {
19493
+ continue;
19494
+ }
19491
19495
 
19492
- if (drawable.renderFlags.colorOpaque) {
19493
- drawable.drawDepth(frameCtx);
19494
- }
19495
- }
19496
+ if (drawable.renderFlags.colorOpaque) {
19497
+ drawable.drawDepth(frameCtx);
19496
19498
  }
19497
19499
  }
19498
19500
 
@@ -19631,7 +19633,6 @@ const Renderer$1 = function (scene, options) {
19631
19633
  }
19632
19634
 
19633
19635
  let i;
19634
- let len;
19635
19636
  let drawable;
19636
19637
 
19637
19638
  const startTime = Date.now();
@@ -19664,93 +19665,85 @@ const Renderer$1 = function (scene, options) {
19664
19665
  // Render normal opaque solids, defer others to bins to render after
19665
19666
  //------------------------------------------------------------------------------------------------------
19666
19667
 
19667
- for (let type in drawableTypeInfo) {
19668
- if (drawableTypeInfo.hasOwnProperty(type)) {
19669
-
19670
- const drawableInfo = drawableTypeInfo[type];
19671
- const drawableList = drawableInfo.drawableList;
19668
+ for (let i = 0, len = postCullDrawableList.length; i < len; i++) {
19672
19669
 
19673
- for (i = 0, len = drawableList.length; i < len; i++) {
19670
+ drawable = postCullDrawableList[i];
19674
19671
 
19675
- drawable = drawableList[i];
19676
-
19677
- if (drawable.culled === true || drawable.visible === false) {
19678
- continue;
19679
- }
19672
+ if (drawable.culled === true || drawable.visible === false) {
19673
+ continue;
19674
+ }
19680
19675
 
19681
- const renderFlags = drawable.renderFlags;
19676
+ const renderFlags = drawable.renderFlags;
19682
19677
 
19683
- if (renderFlags.colorOpaque) {
19684
- if (saoEnabled && saoPossible && drawable.saoEnabled) {
19685
- normalDrawSAOBin[normalDrawSAOBinLen++] = drawable;
19686
- } else {
19687
- drawable.drawColorOpaque(frameCtx);
19688
- }
19689
- }
19678
+ if (renderFlags.colorOpaque) {
19679
+ if (saoEnabled && saoPossible && drawable.saoEnabled) {
19680
+ normalDrawSAOBin[normalDrawSAOBinLen++] = drawable;
19681
+ } else {
19682
+ drawable.drawColorOpaque(frameCtx);
19683
+ }
19684
+ }
19690
19685
 
19691
- if (transparentEnabled) {
19692
- if (renderFlags.colorTransparent) {
19693
- normalFillTransparentBin[normalFillTransparentBinLen++] = drawable;
19694
- }
19695
- }
19686
+ if (transparentEnabled) {
19687
+ if (renderFlags.colorTransparent) {
19688
+ normalFillTransparentBin[normalFillTransparentBinLen++] = drawable;
19689
+ }
19690
+ }
19696
19691
 
19697
- if (renderFlags.xrayedSilhouetteTransparent) {
19698
- xrayedFillTransparentBin[xrayedFillTransparentBinLen++] = drawable;
19699
- }
19692
+ if (renderFlags.xrayedSilhouetteTransparent) {
19693
+ xrayedFillTransparentBin[xrayedFillTransparentBinLen++] = drawable;
19694
+ }
19700
19695
 
19701
- if (renderFlags.xrayedSilhouetteOpaque) {
19702
- xrayedFillOpaqueBin[xrayedFillOpaqueBinLen++] = drawable;
19703
- }
19696
+ if (renderFlags.xrayedSilhouetteOpaque) {
19697
+ xrayedFillOpaqueBin[xrayedFillOpaqueBinLen++] = drawable;
19698
+ }
19704
19699
 
19705
- if (renderFlags.highlightedSilhouetteTransparent) {
19706
- highlightedFillTransparentBin[highlightedFillTransparentBinLen++] = drawable;
19707
- }
19700
+ if (renderFlags.highlightedSilhouetteTransparent) {
19701
+ highlightedFillTransparentBin[highlightedFillTransparentBinLen++] = drawable;
19702
+ }
19708
19703
 
19709
- if (renderFlags.highlightedSilhouetteOpaque) {
19710
- highlightedFillOpaqueBin[highlightedFillOpaqueBinLen++] = drawable;
19711
- }
19704
+ if (renderFlags.highlightedSilhouetteOpaque) {
19705
+ highlightedFillOpaqueBin[highlightedFillOpaqueBinLen++] = drawable;
19706
+ }
19712
19707
 
19713
- if (renderFlags.selectedSilhouetteTransparent) {
19714
- selectedFillTransparentBin[selectedFillTransparentBinLen++] = drawable;
19715
- }
19708
+ if (renderFlags.selectedSilhouetteTransparent) {
19709
+ selectedFillTransparentBin[selectedFillTransparentBinLen++] = drawable;
19710
+ }
19716
19711
 
19717
- if (renderFlags.selectedSilhouetteOpaque) {
19718
- selectedFillOpaqueBin[selectedFillOpaqueBinLen++] = drawable;
19719
- }
19712
+ if (renderFlags.selectedSilhouetteOpaque) {
19713
+ selectedFillOpaqueBin[selectedFillOpaqueBinLen++] = drawable;
19714
+ }
19720
19715
 
19721
- if (drawable.edges && edgesEnabled) {
19722
- if (renderFlags.edgesOpaque) {
19723
- normalEdgesOpaqueBin[normalEdgesOpaqueBinLen++] = drawable;
19724
- }
19716
+ if (drawable.edges && edgesEnabled) {
19717
+ if (renderFlags.edgesOpaque) {
19718
+ normalEdgesOpaqueBin[normalEdgesOpaqueBinLen++] = drawable;
19719
+ }
19725
19720
 
19726
- if (renderFlags.edgesTransparent) {
19727
- normalEdgesTransparentBin[normalEdgesTransparentBinLen++] = drawable;
19728
- }
19721
+ if (renderFlags.edgesTransparent) {
19722
+ normalEdgesTransparentBin[normalEdgesTransparentBinLen++] = drawable;
19723
+ }
19729
19724
 
19730
- if (renderFlags.selectedEdgesTransparent) {
19731
- selectedEdgesTransparentBin[selectedEdgesTransparentBinLen++] = drawable;
19732
- }
19725
+ if (renderFlags.selectedEdgesTransparent) {
19726
+ selectedEdgesTransparentBin[selectedEdgesTransparentBinLen++] = drawable;
19727
+ }
19733
19728
 
19734
- if (renderFlags.selectedEdgesOpaque) {
19735
- selectedEdgesOpaqueBin[selectedEdgesOpaqueBinLen++] = drawable;
19736
- }
19729
+ if (renderFlags.selectedEdgesOpaque) {
19730
+ selectedEdgesOpaqueBin[selectedEdgesOpaqueBinLen++] = drawable;
19731
+ }
19737
19732
 
19738
- if (renderFlags.xrayedEdgesTransparent) {
19739
- xrayEdgesTransparentBin[xrayEdgesTransparentBinLen++] = drawable;
19740
- }
19733
+ if (renderFlags.xrayedEdgesTransparent) {
19734
+ xrayEdgesTransparentBin[xrayEdgesTransparentBinLen++] = drawable;
19735
+ }
19741
19736
 
19742
- if (renderFlags.xrayedEdgesOpaque) {
19743
- xrayEdgesOpaqueBin[xrayEdgesOpaqueBinLen++] = drawable;
19744
- }
19737
+ if (renderFlags.xrayedEdgesOpaque) {
19738
+ xrayEdgesOpaqueBin[xrayEdgesOpaqueBinLen++] = drawable;
19739
+ }
19745
19740
 
19746
- if (renderFlags.highlightedEdgesTransparent) {
19747
- highlightedEdgesTransparentBin[highlightedEdgesTransparentBinLen++] = drawable;
19748
- }
19741
+ if (renderFlags.highlightedEdgesTransparent) {
19742
+ highlightedEdgesTransparentBin[highlightedEdgesTransparentBinLen++] = drawable;
19743
+ }
19749
19744
 
19750
- if (renderFlags.highlightedEdgesOpaque) {
19751
- highlightedEdgesOpaqueBin[highlightedEdgesOpaqueBinLen++] = drawable;
19752
- }
19753
- }
19745
+ if (renderFlags.highlightedEdgesOpaque) {
19746
+ highlightedEdgesOpaqueBin[highlightedEdgesOpaqueBinLen++] = drawable;
19754
19747
  }
19755
19748
  }
19756
19749
  }
@@ -20156,7 +20149,7 @@ const Renderer$1 = function (scene, options) {
20156
20149
  frameCtx.pickInvisible = !!params.pickInvisible;
20157
20150
  frameCtx.pickClipPos = [
20158
20151
  getClipPosX(canvasPos[0] * resolutionScale, gl.drawingBufferWidth),
20159
- getClipPosY(canvasPos[1] * resolutionScale, gl.drawingBufferHeight),
20152
+ getClipPosY(canvasPos[1] * resolutionScale, gl.drawingBufferHeight)
20160
20153
  ];
20161
20154
 
20162
20155
  gl.viewport(0, 0, 1, 1);
@@ -20169,30 +20162,23 @@ const Renderer$1 = function (scene, options) {
20169
20162
  const includeEntityIds = params.includeEntityIds;
20170
20163
  const excludeEntityIds = params.excludeEntityIds;
20171
20164
 
20172
- for (let type in drawableTypeInfo) {
20173
- if (drawableTypeInfo.hasOwnProperty(type)) {
20174
-
20175
- const drawableInfo = drawableTypeInfo[type];
20176
- const drawableList = drawableInfo.drawableList;
20177
-
20178
- for (let i = 0, len = drawableList.length; i < len; i++) {
20179
-
20180
- const drawable = drawableList[i];
20181
-
20182
- if (!drawable.drawPickMesh || (params.pickInvisible !== true && drawable.visible === false) || drawable.pickable === false) {
20183
- continue;
20184
- }
20185
- if (includeEntityIds && !includeEntityIds[drawable.id]) { // TODO: push this logic into drawable
20186
- continue;
20187
- }
20188
- if (excludeEntityIds && excludeEntityIds[drawable.id]) {
20189
- continue;
20190
- }
20191
-
20192
- drawable.drawPickMesh(frameCtx);
20193
- }
20165
+ for (let i = 0, len = postCullDrawableList.length; i < len; i++) {
20166
+ const drawable = postCullDrawableList[i];
20167
+ if (drawable.culled === true || drawable.visible === false) {
20168
+ continue;
20169
+ }
20170
+ if (!drawable.drawPickMesh || (params.pickInvisible !== true && drawable.visible === false) || drawable.pickable === false) {
20171
+ continue;
20172
+ }
20173
+ if (includeEntityIds && !includeEntityIds[drawable.id]) { // TODO: push this logic into drawable
20174
+ continue;
20194
20175
  }
20176
+ if (excludeEntityIds && excludeEntityIds[drawable.id]) {
20177
+ continue;
20178
+ }
20179
+ drawable.drawPickMesh(frameCtx);
20195
20180
  }
20181
+
20196
20182
  const pix = pickBuffer.read(0, 0);
20197
20183
  const pickID = pix[0] + (pix[1] << 8) + (pix[2] << 16) + (pix[3] << 24);
20198
20184
 
@@ -20222,7 +20208,7 @@ const Renderer$1 = function (scene, options) {
20222
20208
  // frameCtx.pickInvisible = !!params.pickInvisible;
20223
20209
  frameCtx.pickClipPos = [
20224
20210
  getClipPosX(canvasPos[0] * resolutionScale, gl.drawingBufferWidth),
20225
- getClipPosY(canvasPos[1] * resolutionScale, gl.drawingBufferHeight),
20211
+ getClipPosY(canvasPos[1] * resolutionScale, gl.drawingBufferHeight)
20226
20212
  ];
20227
20213
 
20228
20214
  gl.viewport(0, 0, 1, 1);
@@ -20271,7 +20257,7 @@ const Renderer$1 = function (scene, options) {
20271
20257
  frameCtx.pickElementsOffset = pickable.pickElementsOffset;
20272
20258
  frameCtx.pickClipPos = [
20273
20259
  getClipPosX(canvasPos[0] * resolutionScale, gl.drawingBufferWidth),
20274
- getClipPosY(canvasPos[1] * resolutionScale, gl.drawingBufferHeight),
20260
+ getClipPosY(canvasPos[1] * resolutionScale, gl.drawingBufferHeight)
20275
20261
  ];
20276
20262
 
20277
20263
  gl.viewport(0, 0, 1, 1);
@@ -20336,15 +20322,14 @@ const Renderer$1 = function (scene, options) {
20336
20322
  function drawSnapInit(frameCtx) {
20337
20323
  frameCtx.snapPickLayerParams = [];
20338
20324
  frameCtx.snapPickLayerNumber = 0;
20339
- for (let type in drawableTypeInfo) {
20340
- const drawableInfo = drawableTypeInfo[type];
20341
- const drawableList = drawableInfo.drawableList;
20342
- for (let i = 0, len = drawableList.length; i < len; i++) {
20343
- const drawable = drawableList[i];
20344
- if (drawable.drawSnapInit) {
20345
- if (!drawable.culled && drawable.visible && drawable.pickable) {
20346
- drawable.drawSnapInit(frameCtx);
20347
- }
20325
+
20326
+ for (let i = 0, len = postCullDrawableList.length; i < len; i++) {
20327
+
20328
+ const drawable = postCullDrawableList[i];
20329
+
20330
+ if (drawable.drawSnapInit) {
20331
+ if (!drawable.culled && drawable.visible && drawable.pickable) {
20332
+ drawable.drawSnapInit(frameCtx);
20348
20333
  }
20349
20334
  }
20350
20335
  }
@@ -20354,11 +20339,11 @@ const Renderer$1 = function (scene, options) {
20354
20339
  function drawSnap(frameCtx) {
20355
20340
  frameCtx.snapPickLayerParams = frameCtx.snapPickLayerParams || [];
20356
20341
  frameCtx.snapPickLayerNumber = frameCtx.snapPickLayerParams.length;
20357
- for (let type in drawableTypeInfo) {
20358
- const drawableInfo = drawableTypeInfo[type];
20359
- const drawableList = drawableInfo.drawableList;
20360
- for (let i = 0, len = drawableList.length; i < len; i++) {
20361
- const drawable = drawableList[i];
20342
+ for (let i = 0, len = postCullDrawableList.length; i < len; i++) {
20343
+
20344
+ const drawable = postCullDrawableList[i];
20345
+
20346
+ if (drawable.drawSnapInit) {
20362
20347
  if (drawable.drawSnap) {
20363
20348
  if (!drawable.culled && drawable.visible && drawable.pickable) {
20364
20349
  drawable.drawSnap(frameCtx);
@@ -20748,19 +20733,16 @@ const Renderer$1 = function (scene, options) {
20748
20733
  gl.disable(gl.BLEND);
20749
20734
  gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
20750
20735
 
20751
- for (let type in drawableTypeInfo) {
20752
- if (drawableTypeInfo.hasOwnProperty(type)) {
20753
- const drawableInfo = drawableTypeInfo[type];
20754
- const drawableList = drawableInfo.drawableList;
20755
- for (let i = 0, len = drawableList.length; i < len; i++) {
20756
- const drawable = drawableList[i];
20757
- if (!drawable.drawOcclusion || drawable.culled === true || drawable.visible === false || drawable.pickable === false) { // TODO: Option to exclude transparent?
20758
- continue;
20759
- }
20760
20736
 
20761
- drawable.drawOcclusion(frameCtx);
20762
- }
20737
+ for (let i = 0, len = postCullDrawableList.length; i < len; i++) {
20738
+
20739
+ const drawable = postCullDrawableList[i];
20740
+
20741
+ if (!drawable.drawOcclusion || drawable.culled === true || drawable.visible === false || drawable.pickable === false) { // TODO: Option to exclude transparent?
20742
+ continue;
20763
20743
  }
20744
+
20745
+ drawable.drawOcclusion(frameCtx);
20764
20746
  }
20765
20747
 
20766
20748
  this._occlusionTester.drawMarkers(frameCtx);
@@ -50890,7 +50872,7 @@ class MeshVolume {
50890
50872
  volume += math.dotVec3(v1$1, v3$1);
50891
50873
  }
50892
50874
 
50893
- return volume;
50875
+ return volume / 6;
50894
50876
  }
50895
50877
  }
50896
50878
 
@@ -61414,7 +61396,7 @@ class VBOInstancingTrianglesLayer {
61414
61396
  */
61415
61397
  constructor(cfg) {
61416
61398
 
61417
- // console.info("Creating VBOInstancingTrianglesLayer");
61399
+ // console.info("Creating VBOInstancingTrianglesLayer");
61418
61400
 
61419
61401
  /**
61420
61402
  * Owner model
@@ -61756,7 +61738,9 @@ class VBOInstancingTrianglesLayer {
61756
61738
  && !!textureSet
61757
61739
  && !!textureSet.colorTexture;
61758
61740
 
61759
- this._state.geometry = null;
61741
+ if (!this.model.scene.readableGeometryEnabled) {
61742
+ this._state.geometry = null;
61743
+ }
61760
61744
 
61761
61745
  this._finalized = true;
61762
61746
  }
@@ -62083,11 +62067,11 @@ class VBOInstancingTrianglesLayer {
62083
62067
  this.model.error("portion not found: " + portionId);
62084
62068
  return;
62085
62069
  }
62086
- const positions = geometry.quantizedPositions;
62070
+ const positions = geometry.positionsCompressed;
62087
62071
  const origin = state.origin;
62088
- const offsetX = origin[0] ;
62089
- const offsetY = origin[1] ;
62090
- const offsetZ = origin[2] ;
62072
+ const offsetX = origin[0];
62073
+ const offsetY = origin[1];
62074
+ const offsetZ = origin[2];
62091
62075
  const worldPos = tempVec4a$7;
62092
62076
  const portionMatrix = portion.matrix;
62093
62077
  const sceneModelMatrix = this.model.matrix;
@@ -62163,7 +62147,7 @@ class VBOInstancingTrianglesLayer {
62163
62147
  return;
62164
62148
  }
62165
62149
  this._updateBackfaceCull(renderFlags, frameCtx);
62166
- const useAlphaCutoff = this._state.textureSet && (typeof(this._state.textureSet.alphaCutoff) === "number");
62150
+ const useAlphaCutoff = this._state.textureSet && (typeof (this._state.textureSet.alphaCutoff) === "number");
62167
62151
  if (frameCtx.withSAO && this.model.saoEnabled) {
62168
62152
  if (frameCtx.pbrEnabled && this.model.pbrEnabled && this._state.pbrSupported) {
62169
62153
  if (this._renderers.pbrRendererWithSAO) {
@@ -65583,7 +65567,9 @@ class VBOInstancingLinesLayer {
65583
65567
  this._modelMatrixCol1 = [];
65584
65568
  this._modelMatrixCol2 = [];
65585
65569
  }
65586
- this._state.geometry = null;
65570
+ if (!this.model.scene.readableGeometryEnabled) {
65571
+ this._state.geometry = null;
65572
+ }
65587
65573
  this._finalized = true;
65588
65574
  }
65589
65575
 
@@ -87819,6 +87805,7 @@ function colorizeToRGB(color) {
87819
87805
  }
87820
87806
 
87821
87807
  const distVec3 = math.vec3();
87808
+ const tmpVec3 = math.vec3();
87822
87809
 
87823
87810
  const lengthWire = (x1, y1, x2, y2) => {
87824
87811
  var a = x1 - x2;
@@ -88129,6 +88116,44 @@ class DistanceMeasurement extends Component {
88129
88116
  this.labelsVisible = cfg.labelsVisible;
88130
88117
  this.labelsOnWires = cfg.labelsOnWires;
88131
88118
  this.useRotationAdjustment = cfg.useRotationAdjustment;
88119
+
88120
+ /**
88121
+ * @type {number[]}
88122
+ */
88123
+ this._axesBasis = [
88124
+ 1, 0, 0, 0,
88125
+ 0, 1, 0, 0,
88126
+ 0, 0, 1, 0,
88127
+ 0, 0, 0, 1,
88128
+ ];
88129
+ }
88130
+
88131
+ /**
88132
+ * Sets the axes basis for the measurement.
88133
+ *
88134
+ * The value is a 4x4 matrix where each column-vector defines an axis and must have unit length.
88135
+ *
88136
+ * This is the ```identity``` matrix by default, meaning the measurement axes are the same as the world axes.
88137
+ *
88138
+ * @param {number[]} value
88139
+ */
88140
+ set axesBasis(value) {
88141
+ this._axesBasis = value.slice();
88142
+ this._wpDirty = true;
88143
+ this._needUpdate(0); // No lag
88144
+ }
88145
+
88146
+ /**
88147
+ * Gets the axes basis for the measurement.
88148
+ *
88149
+ * The value is a 4x4 matrix where each column-vector defines an axis and must have unit length.
88150
+ *
88151
+ * This is the ```identity``` matrix by default, meaning the measurement axes are the same as the world axes.
88152
+ *
88153
+ * @type {number[]}
88154
+ */
88155
+ get axesBasis() {
88156
+ return this._axesBasis;
88132
88157
  }
88133
88158
 
88134
88159
  _update() {
@@ -88164,20 +88189,30 @@ class DistanceMeasurement extends Component {
88164
88189
  this._wp[15] = 1.0;
88165
88190
  }
88166
88191
  else {
88192
+ const delta = math.subVec3(
88193
+ this._targetWorld,
88194
+ this._originWorld,
88195
+ tmpVec3
88196
+ );
88197
+
88198
+ /**
88199
+ * The length detected for each measurement axis.
88200
+ */
88201
+ this._factors = math.transformVec3(this._axesBasis, delta);
88202
+
88167
88203
  this._wp[0] = this._originWorld[0];
88168
88204
  this._wp[1] = this._originWorld[1];
88169
88205
  this._wp[2] = this._originWorld[2];
88170
88206
  this._wp[3] = 1.0;
88171
88207
 
88172
- this._wp[4] = this._targetWorld[0];
88173
- this._wp[5] = this._originWorld[1];
88174
- this._wp[6] = this._originWorld[2];
88208
+ this._wp[4] = this._originWorld[0] + this._axesBasis[0]*this._factors[0];
88209
+ this._wp[5] = this._originWorld[1] + this._axesBasis[4]*this._factors[0];
88210
+ this._wp[6] = this._originWorld[2] + this._axesBasis[8]*this._factors[0];
88175
88211
  this._wp[7] = 1.0;
88176
88212
 
88177
- this._wp[8] = this._targetWorld[0];
88178
- this._wp[9] = this._targetWorld[1];
88179
- this._wp[10] = this._originWorld[2];
88180
- this._wp[11] = 1.0;
88213
+ this._wp[8] = this._originWorld[0] + this._axesBasis[0]*this._factors[0]+ this._axesBasis[1]*this._factors[1];
88214
+ this._wp[9] = this._originWorld[1] + this._axesBasis[4]*this._factors[0]+ this._axesBasis[5]*this._factors[1];
88215
+ this._wp[10] = this._originWorld[2] + this._axesBasis[8]*this._factors[0]+ this._axesBasis[9]*this._factors[1]; this._wp[11] = 1.0;
88181
88216
 
88182
88217
  this._wp[12] = this._targetWorld[0];
88183
88218
  this._wp[13] = this._targetWorld[1];
@@ -88338,14 +88373,14 @@ class DistanceMeasurement extends Component {
88338
88373
  }
88339
88374
 
88340
88375
  if (!this._xAxisLabelCulled) {
88341
- this._xAxisLabel.setText(tilde + Math.abs((this._targetWorld[0] - this._originWorld[0]) * scale).toFixed(2) + unitAbbrev);
88376
+ this._xAxisLabel.setText(tilde + Math.abs(this._factors[0] * scale).toFixed(2) + unitAbbrev);
88342
88377
  this._xAxisLabel.setCulled(!this.axisVisible);
88343
88378
  } else {
88344
88379
  this._xAxisLabel.setCulled(true);
88345
88380
  }
88346
88381
 
88347
88382
  if (!this._yAxisLabelCulled) {
88348
- this._yAxisLabel.setText(tilde + Math.abs((this._targetWorld[1] - this._originWorld[1]) * scale).toFixed(2) + unitAbbrev);
88383
+ this._yAxisLabel.setText(tilde + Math.abs(this._factors[1] * scale).toFixed(2) + unitAbbrev);
88349
88384
  this._yAxisLabel.setCulled(!this.axisVisible);
88350
88385
  } else {
88351
88386
  this._yAxisLabel.setCulled(true);
@@ -88358,7 +88393,7 @@ class DistanceMeasurement extends Component {
88358
88393
  }
88359
88394
  else {
88360
88395
  this._zAxisLabel.setPrefix("Z");
88361
- this._zAxisLabel.setText(tilde + Math.abs((this._targetWorld[2] - this._originWorld[2]) * scale).toFixed(2) + unitAbbrev);
88396
+ this._zAxisLabel.setText(tilde + Math.abs(this._factors[2] * scale).toFixed(2) + unitAbbrev);
88362
88397
  }
88363
88398
  this._zAxisLabel.setCulled(!this.axisVisible);
88364
88399
  } else {
@@ -132477,6 +132512,9 @@ class XKTLoaderPlugin extends Plugin {
132477
132512
  * represent the returned model. Set false to always use vertex buffer objects (VBOs). Note that DTX is only applicable
132478
132513
  * to non-textured triangle meshes, and that VBOs are always used for meshes that have textures, line segments, or point
132479
132514
  * primitives. Only works while {@link DTX#enabled} is also ````true````.
132515
+ * @param {Number} [params.renderOrder=0] Specifies the rendering order for the model. This is used to control the order in which
132516
+ * SceneModels are drawn when they have transparent objects, to give control over the order in which those objects are blended within the transparent
132517
+ * render pass.
132480
132518
  * @returns {Entity} Entity representing the model, which will have {@link Entity#isModel} set ````true```` and will be registered by {@link Entity#id} in {@link Scene#models}.
132481
132519
  */
132482
132520
  load(params = {}) {
@@ -132526,7 +132564,8 @@ class XKTLoaderPlugin extends Plugin {
132526
132564
  origin: params.origin,
132527
132565
  disableVertexWelding: params.disableVertexWelding || false,
132528
132566
  disableIndexRebucketing: params.disableIndexRebucketing || false,
132529
- dtxEnabled: params.dtxEnabled
132567
+ dtxEnabled: params.dtxEnabled,
132568
+ renderOrder: params.renderOrder
132530
132569
  }));
132531
132570
 
132532
132571
  const modelId = sceneModel.id; // In case ID was auto-generated
@@ -139732,10 +139771,9 @@ const basePolygon3D = function(scene, color, alpha) {
139732
139771
  };
139733
139772
  };
139734
139773
 
139735
- const startAAZoneCreateUI = function(scene, zoneAltitude, zoneHeight, zoneColor, zoneAlpha, pointerLens, zonesPlugin, select3dPoint, onZoneCreated) {
139736
- const marker1 = marker3D(scene, zoneColor);
139737
- const marker2 = marker3D(scene, zoneColor);
139738
- const basePolygon = basePolygon3D(scene, zoneColor, zoneAlpha);
139774
+ const startAARectCreateUI = function(scene, markersColor, pointerLens, select3dPoint, withPoints, onPointsSelected) {
139775
+ const marker1 = marker3D(scene, markersColor);
139776
+ const marker2 = marker3D(scene, markersColor);
139739
139777
 
139740
139778
  const updatePointerLens = (pointerLens
139741
139779
  ? function(canvasPos) {
@@ -139763,29 +139801,14 @@ const startAAZoneCreateUI = function(scene, zoneAltitude, zoneHeight, zoneColor,
139763
139801
  function() {
139764
139802
  updatePointerLens(null);
139765
139803
  marker2.update(null);
139766
- basePolygon.updateBase(null);
139804
+ withPoints(null);
139767
139805
  },
139768
139806
  function(canvasPos, point2WorldPos) {
139769
139807
  updatePointerLens(canvasPos);
139770
139808
  marker2.update(point2WorldPos);
139771
-
139772
- if (math.distVec3(point1WorldPos, point2WorldPos) > 0.01)
139773
- {
139774
- const min = (idx) => Math.min(point1WorldPos[idx], point2WorldPos[idx]);
139775
- const max = (idx) => Math.max(point1WorldPos[idx], point2WorldPos[idx]);
139776
-
139777
- const xmin = min(0);
139778
- const ymin = min(1);
139779
- const zmin = min(2);
139780
- const xmax = max(0);
139781
- max(1);
139782
- const zmax = max(2);
139783
-
139784
- basePolygon.updateBase([ [ xmin, ymin, zmax ], [ xmax, ymin, zmax ],
139785
- [ xmax, ymin, zmin ], [ xmin, ymin, zmin ] ]);
139786
- }
139787
- else
139788
- basePolygon.updateBase(null);
139809
+ withPoints((math.distVec3(point1WorldPos, point2WorldPos) > 0.01)
139810
+ &&
139811
+ [ point1WorldPos, point2WorldPos ]);
139789
139812
  },
139790
139813
  function(point2CanvasPos, point2WorldPos) {
139791
139814
  // `marker2.update' makes sure marker's position has been updated from its default [0,0,0]
@@ -139795,35 +139818,9 @@ const startAAZoneCreateUI = function(scene, zoneAltitude, zoneHeight, zoneColor,
139795
139818
 
139796
139819
  marker1.destroy();
139797
139820
  marker2.destroy();
139798
- basePolygon.destroy();
139799
139821
  updatePointerLens(null);
139800
139822
 
139801
- const min = (idx) => Math.min(point1WorldPos[idx], point2WorldPos[idx]);
139802
- const max = (idx) => Math.max(point1WorldPos[idx], point2WorldPos[idx]);
139803
-
139804
- const xmin = min(0);
139805
- const zmin = min(2);
139806
- const xmax = max(0);
139807
- const zmax = max(2);
139808
-
139809
- const zone = zonesPlugin.createZone(
139810
- {
139811
- id: math.createUUID(),
139812
- geometry: {
139813
- planeCoordinates: [
139814
- [ xmin, zmax ],
139815
- [ xmax, zmax ],
139816
- [ xmax, zmin ],
139817
- [ xmin, zmin ]
139818
- ],
139819
- altitude: zoneAltitude,
139820
- height: zoneHeight
139821
- },
139822
- alpha: zoneAlpha,
139823
- color: zoneColor
139824
- });
139825
-
139826
- onZoneCreated(zone);
139823
+ onPointsSelected([ point1WorldPos, point2WorldPos ]);
139827
139824
  });
139828
139825
  });
139829
139826
 
@@ -139832,7 +139829,6 @@ const startAAZoneCreateUI = function(scene, zoneAltitude, zoneHeight, zoneColor,
139832
139829
  deactivatePointSelection();
139833
139830
  marker1.destroy();
139834
139831
  marker2.destroy();
139835
- basePolygon.destroy();
139836
139832
  updatePointerLens(null);
139837
139833
  }
139838
139834
  };
@@ -140492,6 +140488,34 @@ class Zone extends Component {
140492
140488
  }
140493
140489
  }
140494
140490
 
140491
+ const createAAZoneFromPoints = function(pos1, pos2, zoneAltitude, zoneHeight, zoneColor, zoneAlpha, zonesPlugin) {
140492
+
140493
+ const min = (idx) => Math.min(pos1[idx], pos2[idx]);
140494
+ const max = (idx) => Math.max(pos1[idx], pos2[idx]);
140495
+
140496
+ const xmin = min(0);
140497
+ const zmin = min(2);
140498
+ const xmax = max(0);
140499
+ const zmax = max(2);
140500
+
140501
+ return zonesPlugin.createZone(
140502
+ {
140503
+ id: math.createUUID(),
140504
+ geometry: {
140505
+ planeCoordinates: [
140506
+ [ xmin, zmax ],
140507
+ [ xmax, zmax ],
140508
+ [ xmax, zmin ],
140509
+ [ xmin, zmin ]
140510
+ ],
140511
+ altitude: zoneAltitude,
140512
+ height: zoneHeight
140513
+ },
140514
+ alpha: zoneAlpha,
140515
+ color: zoneColor
140516
+ });
140517
+ };
140518
+
140495
140519
  /**
140496
140520
  * Creates {@link Zone}s in a {@link ZonesPlugin} from mouse input.
140497
140521
  *
@@ -140522,7 +140546,7 @@ class Zone extends Component {
140522
140546
  * const zonesControl = new ZonesMouseControl(Zones)
140523
140547
  * ````
140524
140548
  */
140525
- class ZonesMouseControl extends Component {
140549
+ class ZonesAAZoneControl extends Component {
140526
140550
 
140527
140551
  /**
140528
140552
  * Creates a ZonesMouseControl bound to the given ZonesPlugin.
@@ -140531,11 +140555,12 @@ class ZonesMouseControl extends Component {
140531
140555
  * @param [cfg] Configuration
140532
140556
  * @param {PointerLens} [cfg.pointerLens] A PointerLens to use to provide a magnified view of the cursor when snapping is enabled.
140533
140557
  */
140534
- constructor(zonesPlugin, cfg = {}) {
140558
+ constructor(zonesPlugin, cfg, createSelect3dPoint) {
140535
140559
  super(zonesPlugin.viewer.scene);
140536
140560
 
140537
140561
  this.zonesPlugin = zonesPlugin;
140538
140562
  this.pointerLens = cfg.pointerLens;
140563
+ this.createSelect3dPoint = createSelect3dPoint;
140539
140564
  this._deactivate = null;
140540
140565
  }
140541
140566
 
@@ -140572,16 +140597,35 @@ class ZonesMouseControl extends Component {
140572
140597
  const scene = viewer.scene;
140573
140598
  const self = this;
140574
140599
 
140575
- const select3dPoint = mousePointSelector(
140576
- viewer,
140577
- function(origin, direction) {
140578
- return planeIntersect(zoneAltitude, math.vec3([ 0, 1, 0 ]), origin, direction);
140579
- });
140600
+ const select3dPoint = this.createSelect3dPoint(viewer, (origin, direction) => planeIntersect(zoneAltitude, math.vec3([ 0, 1, 0 ]), origin, direction));
140580
140601
 
140581
140602
  (function rec() {
140582
- self._deactivate = startAAZoneCreateUI(
140583
- scene, zoneAltitude, zoneHeight, zoneColor, zoneAlpha, self.pointerLens, zonesPlugin, select3dPoint,
140584
- zone => {
140603
+ const basePolygon = basePolygon3D(scene, zoneColor, zoneAlpha);
140604
+ const deactivate = startAARectCreateUI(
140605
+ scene, zoneColor, self.pointerLens, select3dPoint,
140606
+ points => {
140607
+ if (points) {
140608
+ const p0 = points[0];
140609
+ const p1 = points[1];
140610
+ const min = (idx) => Math.min(p0[idx], p1[idx]);
140611
+ const max = (idx) => Math.max(p0[idx], p1[idx]);
140612
+
140613
+ const xmin = min(0);
140614
+ const ymin = min(1);
140615
+ const zmin = min(2);
140616
+ const xmax = max(0);
140617
+ max(1);
140618
+ const zmax = max(2);
140619
+
140620
+ basePolygon.updateBase([ [ xmin, ymin, zmax ], [ xmax, ymin, zmax ],
140621
+ [ xmax, ymin, zmin ], [ xmin, ymin, zmin ] ]);
140622
+ } else {
140623
+ basePolygon.updateBase(null);
140624
+ }
140625
+ },
140626
+ points => {
140627
+ basePolygon.destroy();
140628
+ const zone = createAAZoneFromPoints(points[0], points[1], zoneAltitude, zoneHeight, zoneColor, zoneAlpha, zonesPlugin);
140585
140629
  let reactivate = true;
140586
140630
  self._deactivate = () => { reactivate = false; };
140587
140631
  self.fire("zoneEnd", zone);
@@ -140590,6 +140634,10 @@ class ZonesMouseControl extends Component {
140590
140634
  rec();
140591
140635
  }
140592
140636
  }).deactivate;
140637
+ self._deactivate = () => {
140638
+ deactivate();
140639
+ basePolygon.destroy();
140640
+ };
140593
140641
  })();
140594
140642
  }
140595
140643
 
@@ -140612,6 +140660,30 @@ class ZonesMouseControl extends Component {
140612
140660
  }
140613
140661
  }
140614
140662
 
140663
+ class ZonesMouseControl extends ZonesAAZoneControl {
140664
+ constructor(zonesPlugin, cfg = {}) {
140665
+ super(
140666
+ zonesPlugin,
140667
+ cfg,
140668
+ (viewer, ray2WorldPos) => mousePointSelector(viewer, ray2WorldPos));
140669
+ }
140670
+ }
140671
+ class ZonesTouchControl extends ZonesAAZoneControl {
140672
+ constructor(zonesPlugin, cfg = {}) {
140673
+ const pointerCircle = new PointerCircle(zonesPlugin.viewer);
140674
+ super(
140675
+ zonesPlugin,
140676
+ cfg,
140677
+ (viewer, ray2WorldPos) => touchPointSelector(viewer, pointerCircle, ray2WorldPos));
140678
+ this.pointerCircle = pointerCircle;
140679
+ }
140680
+
140681
+ destroy() {
140682
+ this.pointerCircle.destroy();
140683
+ super.destroy();
140684
+ }
140685
+ }
140686
+
140615
140687
  /**
140616
140688
  * ZonesPlugin documentation to be added, mostly compatible with DistanceMeasurementsPlugin.
140617
140689
  */
@@ -140726,86 +140798,6 @@ class ZonesPlugin extends Plugin {
140726
140798
  }
140727
140799
  }
140728
140800
 
140729
- class ZonesTouchControl extends Component {
140730
-
140731
- constructor(zonesPlugin, cfg = {}) {
140732
- super(zonesPlugin.viewer.scene);
140733
-
140734
- this.zonesPlugin = zonesPlugin;
140735
- this.pointerLens = cfg.pointerLens;
140736
- this.pointerCircle = new PointerCircle(zonesPlugin.viewer);
140737
- this._deactivate = null;
140738
- }
140739
-
140740
- get active() {
140741
- return !! this._deactivate;
140742
- }
140743
-
140744
- activate(zoneAltitude, zoneHeight, zoneColor, zoneAlpha) {
140745
-
140746
- if (typeof(zoneAltitude) === "object" && (zoneAltitude !== null)) {
140747
- const params = zoneAltitude;
140748
- const param = (name, defaultValue) => {
140749
- if (name in params) {
140750
- return params[name];
140751
- } else if (defaultValue !== undefined) {
140752
- return defaultValue;
140753
- } else {
140754
- throw "config missing: " + name;
140755
- }
140756
- };
140757
-
140758
- zoneAltitude = param("altitude");
140759
- zoneHeight = param("height");
140760
- zoneColor = param("color", "#008000");
140761
- zoneAlpha = param("alpha", 0.5);
140762
- }
140763
-
140764
- if (this._deactivate) {
140765
- return;
140766
- }
140767
-
140768
- const zonesPlugin = this.zonesPlugin;
140769
- const viewer = zonesPlugin.viewer;
140770
- const scene = viewer.scene;
140771
- const self = this;
140772
-
140773
- const select3dPoint = touchPointSelector(
140774
- viewer,
140775
- this.pointerCircle,
140776
- function(origin, direction) {
140777
- return planeIntersect(zoneAltitude, math.vec3([ 0, 1, 0 ]), origin, direction);
140778
- });
140779
-
140780
- (function rec() {
140781
- self._deactivate = startAAZoneCreateUI(
140782
- scene, zoneAltitude, zoneHeight, zoneColor, zoneAlpha, self.pointerLens, zonesPlugin, select3dPoint,
140783
- zone => {
140784
- let reactivate = true;
140785
- self._deactivate = () => { reactivate = false; };
140786
- self.fire("zoneEnd", zone);
140787
- if (reactivate)
140788
- {
140789
- rec();
140790
- }
140791
- }).deactivate;
140792
- })();
140793
- }
140794
-
140795
- deactivate() {
140796
- if (this._deactivate)
140797
- {
140798
- this._deactivate();
140799
- this._deactivate = null;
140800
- }
140801
- }
140802
-
140803
- destroy() {
140804
- this.deactivate();
140805
- super.destroy();
140806
- }
140807
- }
140808
-
140809
140801
  const startPolysurfaceZoneCreateUI = function(scene, zoneAltitude, zoneHeight, zoneColor, zoneAlpha, pointerLens, zonesPlugin, select3dPoint, onZoneCreated) {
140810
140802
  const updatePointerLens = (pointerLens
140811
140803
  ? function(canvasPos) {