@xeokit/xeokit-sdk 2.4.2-beta-15 → 2.4.2-beta-20

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.
@@ -1041,8 +1041,8 @@ class PointerLens {
1041
1041
  this._lensCanvasContext = this._lensCanvas.getContext('2d');
1042
1042
  this._canvasElement = this.viewer.scene.canvas.canvas;
1043
1043
 
1044
- this._centerPos = null;
1045
- this._cursorPos = null;
1044
+ this._canvasPos = null;
1045
+ this._snappedCanvasPos = null;
1046
1046
  this._lensPosToggle = true;
1047
1047
 
1048
1048
  this._zoomLevel = cfg.zoomLevel || 2;
@@ -1065,14 +1065,14 @@ class PointerLens {
1065
1065
  if (!this._active || !this._visible) {
1066
1066
  return;
1067
1067
  }
1068
- if (!this._centerPos) {
1068
+ if (!this._canvasPos) {
1069
1069
  return;
1070
1070
  }
1071
1071
  const lensRect = this._lensContainer.getBoundingClientRect();
1072
1072
  const canvasRect = this._canvasElement.getBoundingClientRect();
1073
1073
  const pointerOnLens =
1074
- this._centerPos[0] < lensRect.right && this._centerPos[0] > lensRect.left &&
1075
- this._centerPos[1] < lensRect.bottom && this._centerPos[1] > lensRect.top;
1074
+ this._canvasPos[0] < lensRect.right && this._canvasPos[0] > lensRect.left &&
1075
+ this._canvasPos[1] < lensRect.bottom && this._canvasPos[1] > lensRect.top;
1076
1076
  this._lensContainer.style.marginLeft = `25px`;
1077
1077
  if (pointerOnLens) {
1078
1078
  if (this._lensPosToggle) {
@@ -1086,8 +1086,8 @@ class PointerLens {
1086
1086
  const size = Math.max(this._lensCanvas.width, this._lensCanvas.height) / this._zoomLevel;
1087
1087
  this._lensCanvasContext.drawImage(
1088
1088
  this._canvasElement, // source canvas
1089
- this._centerPos[0] - size / 2, // source x (zoom center)
1090
- this._centerPos[1] - size / 2, // source y (zoom center)
1089
+ this._canvasPos[0] - size / 2, // source x (zoom center)
1090
+ this._canvasPos[1] - size / 2, // source y (zoom center)
1091
1091
  size, // source width
1092
1092
  size, // source height
1093
1093
  0, // destination x
@@ -1101,9 +1101,9 @@ class PointerLens {
1101
1101
  (lensRect.top + lensRect.bottom) / 2
1102
1102
  ];
1103
1103
 
1104
- if (this._cursorPos) {
1105
- const deltaX = this._cursorPos[0] - this._centerPos[0];
1106
- const deltaY = this._cursorPos[1] - this._centerPos[1];
1104
+ if (this._snappedCanvasPos) {
1105
+ const deltaX = this._snappedCanvasPos[0] - this._canvasPos[0];
1106
+ const deltaY = this._snappedCanvasPos[1] - this._canvasPos[1];
1107
1107
 
1108
1108
  this._lensCursorDiv.style.marginLeft = `${centerLensCanvas[0] + deltaX * this._zoomLevel - 10}px`;
1109
1109
  this._lensCursorDiv.style.marginTop = `${centerLensCanvas[1] + deltaY * this._zoomLevel - 10}px`;
@@ -1139,10 +1139,10 @@ class PointerLens {
1139
1139
 
1140
1140
  /**
1141
1141
  * Sets the canvas central position of the lens.
1142
- * @param centerPos
1142
+ * @param canvasPos
1143
1143
  */
1144
- set centerPos(centerPos) {
1145
- this._centerPos = centerPos;
1144
+ set canvasPos(canvasPos) {
1145
+ this._canvasPos = canvasPos;
1146
1146
  this.update();
1147
1147
  }
1148
1148
 
@@ -1150,25 +1150,25 @@ class PointerLens {
1150
1150
  * Gets the canvas central position of the lens.
1151
1151
  * @returns {Number[]}
1152
1152
  */
1153
- get centerPos() {
1154
- return this._centerPos;
1153
+ get canvasPos() {
1154
+ return this._canvasPos;
1155
1155
  }
1156
1156
 
1157
1157
  /**
1158
1158
  * Sets the canvas coordinates of the pointer.
1159
- * @param cursorPos
1159
+ * @param snappedCanvasPos
1160
1160
  */
1161
- set cursorPos(cursorPos) {
1162
- this._cursorPos = cursorPos;
1161
+ set snappedCanvasPos(snappedCanvasPos) {
1162
+ this._snappedCanvasPos = snappedCanvasPos;
1163
1163
  this.update();
1164
1164
  }
1165
1165
 
1166
1166
  /**
1167
- * Gets the canvas coordinates of the pointer.
1167
+ * Gets the canvas coordinates of the snapped pointer.
1168
1168
  * @returns {Number[]}
1169
1169
  */
1170
- get cursorPos() {
1171
- return this._cursorPos;
1170
+ get snappedCanvasPos() {
1171
+ return this._snappedCanvasPos;
1172
1172
  }
1173
1173
 
1174
1174
  /**
@@ -12009,8 +12009,8 @@ class AngleMeasurementsMouseControl extends AngleMeasurementsControl {
12009
12009
  if (event.snappedToVertex || event.snappedToEdge) {
12010
12010
  if (pointerLens) {
12011
12011
  pointerLens.visible = true;
12012
- pointerLens.centerPos = event.cursorPos || event.canvasPos;
12013
- pointerLens.cursorPos = event.canvasPos;
12012
+ pointerLens.canvasPos = event.canvasPos;
12013
+ pointerLens.snappedCanvasPos = event.snappedCanvasPos || event.canvasPos;
12014
12014
  pointerLens.snapped = true;
12015
12015
  }
12016
12016
  this.markerDiv.style.background = "greenyellow";
@@ -12018,21 +12018,22 @@ class AngleMeasurementsMouseControl extends AngleMeasurementsControl {
12018
12018
  } else {
12019
12019
  if (pointerLens) {
12020
12020
  pointerLens.visible = true;
12021
- pointerLens.centerPos = event.cursorPos || event.canvasPos;
12022
- pointerLens.cursorPos = event.canvasPos;
12021
+ pointerLens.canvasPos = event.canvasPos;
12022
+ pointerLens.snappedCanvasPos = event.canvasPos;
12023
12023
  pointerLens.snapped = false;
12024
12024
  }
12025
12025
  this.markerDiv.style.background = "pink";
12026
12026
  this.markerDiv.style.border = "2px solid red";
12027
12027
  }
12028
+ const canvasPos = event.snappedCanvasPos || event.canvasPos;
12028
12029
  mouseHovering = true;
12029
12030
  mouseHoverEntity = event.entity;
12030
12031
  mouseWorldPos.set(event.worldPos);
12031
- mouseHoverCanvasPos.set(event.canvasPos);
12032
+ mouseHoverCanvasPos.set(canvasPos);
12032
12033
  switch (this._mouseState) {
12033
12034
  case MOUSE_FINDING_ORIGIN:
12034
- this.markerDiv.style.marginLeft = `${event.canvasPos[0] - 5}px`;
12035
- this.markerDiv.style.marginTop = `${event.canvasPos[1] - 5}px`;
12035
+ this.markerDiv.style.marginLeft = `${canvasPos[0] - 5}px`;
12036
+ this.markerDiv.style.marginTop = `${canvasPos[1] - 5}px`;
12036
12037
  break;
12037
12038
  case MOUSE_FINDING_CORNER:
12038
12039
  if (this._currentAngleMeasurement) {
@@ -12148,8 +12149,8 @@ class AngleMeasurementsMouseControl extends AngleMeasurementsControl {
12148
12149
  mouseHovering = false;
12149
12150
  if (pointerLens) {
12150
12151
  pointerLens.visible = true;
12151
- pointerLens.centerPos = event.cursorPos;
12152
- pointerLens.cursorPos = event.cursorPos;
12152
+ pointerLens.pointerPos = event.canvasPos;
12153
+ pointerLens.snappedCanvasPos = event.snappedCanvasPos || event.canvasPos;
12153
12154
  pointerLens.snapped = false;
12154
12155
  }
12155
12156
  this.markerDiv.style.marginLeft = `-100px`;
@@ -14789,13 +14790,14 @@ class PickResult {
14789
14790
  */
14790
14791
  this.snappedToVertex = false;
14791
14792
 
14792
- this._canvasPos = new Int16Array([0, 0]);
14793
14793
  this._origin = new Float64Array([0, 0, 0]);
14794
14794
  this._direction = new Float64Array([0, 0, 0]);
14795
14795
  this._indices = new Int32Array(3);
14796
14796
  this._localPos = new Float64Array([0, 0, 0]);
14797
14797
  this._worldPos = new Float64Array([0, 0, 0]);
14798
14798
  this._viewPos = new Float64Array([0, 0, 0]);
14799
+ this._canvasPos = new Int16Array([0, 0]);
14800
+ this._snappedCanvasPos = new Int16Array([0, 0]);
14799
14801
  this._bary = new Float64Array([0, 0, 0]);
14800
14802
  this._worldNormal = new Float64Array([0, 0, 0]);
14801
14803
  this._uv = new Float64Array([0, 0]);
@@ -14804,7 +14806,7 @@ class PickResult {
14804
14806
  }
14805
14807
 
14806
14808
  /**
14807
- * Canvas coordinates when picking with a 2D pointer.
14809
+ * Canvas pick coordinates.
14808
14810
  * @property canvasPos
14809
14811
  * @type {Number[]}
14810
14812
  */
@@ -14922,6 +14924,29 @@ class PickResult {
14922
14924
  }
14923
14925
  }
14924
14926
 
14927
+ /**
14928
+ * Canvas cursor coordinates, snapped when snap picking, otherwise same as {@link PickResult#pointerPos}.
14929
+ * @property snappedCanvasPos
14930
+ * @type {Number[]}
14931
+ */
14932
+ get snappedCanvasPos() {
14933
+ return this._gotSnappedCanvasPos ? this._snappedCanvasPos : null;
14934
+ }
14935
+
14936
+ /**
14937
+ * @private
14938
+ * @param value
14939
+ */
14940
+ set snappedCanvasPos(value) {
14941
+ if (value) {
14942
+ this._snappedCanvasPos[0] = value[0];
14943
+ this._snappedCanvasPos[1] = value[1];
14944
+ this._gotSnappedCanvasPos = true;
14945
+ } else {
14946
+ this._gotSnappedCanvasPos = false;
14947
+ }
14948
+ }
14949
+
14925
14950
  /**
14926
14951
  * Picked World-space point.
14927
14952
  * @property worldPos
@@ -15050,6 +15075,7 @@ class PickResult {
15050
15075
  this.primitive = null;
15051
15076
  this.pickSurfacePrecision = false;
15052
15077
  this._gotCanvasPos = false;
15078
+ this._gotSnappedCanvasPos = false;
15053
15079
  this._gotOrigin = false;
15054
15080
  this._gotDirection = false;
15055
15081
  this._gotIndices = false;
@@ -18446,254 +18472,258 @@ const Renderer$1 = function (scene, options) {
18446
18472
  * @param {number} [snapRadiusInPixels=30]
18447
18473
  * @param {boolean} [snapToVertex=true]
18448
18474
  * @param {boolean} [snapToEdge=true]
18449
- *
18450
- * @returns {{worldPos:number[],snappedWorldPos:null|number[],snappedCanvasPos:null|number[], snapType:null|"vertex"|"edge"}}
18475
+ * @param pickResult
18476
+ * @returns {PickResult}
18451
18477
  */
18452
- this.snapPick = function (canvasPos, snapRadiusInPixels = 30, snapToVertex = true, snapToEdge = true) {
18478
+ this.snapPick = (function () {
18453
18479
 
18454
- if (!snapToVertex && !snapToEdge) {
18455
- return this.pick({canvasPos, pickSurface: true});
18456
- }
18480
+ const _pickResult = new PickResult();
18457
18481
 
18458
- const resolutionScale = scene.canvas.resolutionScale;
18482
+ return function (canvasPos, snapRadiusInPixels, snapToVertex, snapToEdge, pickResult = _pickResult) {
18459
18483
 
18460
- frameCtx.reset();
18461
- frameCtx.backfaces = true;
18462
- frameCtx.frontface = true; // "ccw"
18463
- frameCtx.pickZNear = scene.camera.project.near;
18464
- frameCtx.pickZFar = scene.camera.project.far;
18465
-
18466
- const vertexPickBuffer = renderBufferManager.getRenderBuffer("uniquePickColors-aabs", {
18467
- depthTexture: true,
18468
- size: [
18469
- 2 * snapRadiusInPixels + 1,
18470
- 2 * snapRadiusInPixels + 1,
18471
- ]
18472
- });
18484
+ if (!snapToVertex && !snapToEdge) {
18485
+ return this.pick({canvasPos, pickSurface: true});
18486
+ }
18473
18487
 
18474
- frameCtx.snapVectorA = [
18475
- getClipPosX(canvasPos[0] * resolutionScale, gl.drawingBufferWidth),
18476
- getClipPosY(canvasPos[1] * resolutionScale, gl.drawingBufferHeight),
18477
- ];
18488
+ const resolutionScale = scene.canvas.resolutionScale;
18478
18489
 
18479
- frameCtx.snapInvVectorAB = [
18480
- gl.drawingBufferWidth / (2 * snapRadiusInPixels),
18481
- gl.drawingBufferHeight / (2 * snapRadiusInPixels),
18482
- ];
18490
+ frameCtx.reset();
18491
+ frameCtx.backfaces = true;
18492
+ frameCtx.frontface = true; // "ccw"
18493
+ frameCtx.pickZNear = scene.camera.project.near;
18494
+ frameCtx.pickZFar = scene.camera.project.far;
18483
18495
 
18484
- // Bind and clear the snap render target
18496
+ snapRadiusInPixels = snapRadiusInPixels || 30;
18485
18497
 
18486
- vertexPickBuffer.bind(gl.RGBA32I, gl.RGBA32I, gl.RGBA8UI);
18487
- gl.viewport(0, 0, vertexPickBuffer.size[0], vertexPickBuffer.size[1]);
18488
- gl.enable(gl.DEPTH_TEST);
18489
- gl.frontFace(gl.CCW);
18490
- gl.disable(gl.CULL_FACE);
18491
- gl.depthMask(true);
18492
- gl.disable(gl.BLEND);
18493
- gl.depthFunc(gl.LEQUAL);
18494
- gl.clear(gl.DEPTH_BUFFER_BIT);
18495
- gl.clearBufferiv(gl.COLOR, 0, new Int32Array([0, 0, 0, 0]));
18496
- gl.clearBufferiv(gl.COLOR, 1, new Int32Array([0, 0, 0, 0]));
18497
- gl.clearBufferuiv(gl.COLOR, 2, new Uint32Array([0, 0, 0, 0]));
18498
+ const vertexPickBuffer = renderBufferManager.getRenderBuffer("uniquePickColors-aabs", {
18499
+ depthTexture: true,
18500
+ size: [
18501
+ 2 * snapRadiusInPixels + 1,
18502
+ 2 * snapRadiusInPixels + 1,
18503
+ ]
18504
+ });
18505
+
18506
+ frameCtx.snapVectorA = [
18507
+ getClipPosX(canvasPos[0] * resolutionScale, gl.drawingBufferWidth),
18508
+ getClipPosY(canvasPos[1] * resolutionScale, gl.drawingBufferHeight),
18509
+ ];
18498
18510
 
18499
- //////////////////////////////////
18500
- // Set view and proj mats for VBO renderers
18501
- ///////////////////////////////////////
18511
+ frameCtx.snapInvVectorAB = [
18512
+ gl.drawingBufferWidth / (2 * snapRadiusInPixels),
18513
+ gl.drawingBufferHeight / (2 * snapRadiusInPixels),
18514
+ ];
18502
18515
 
18503
- const pickViewMatrix = scene.camera.viewMatrix;
18504
- const pickProjMatrix = scene.camera.projMatrix;
18516
+ // Bind and clear the snap render target
18505
18517
 
18506
- for (let type in drawableTypeInfo) {
18507
- if (drawableTypeInfo.hasOwnProperty(type)) {
18508
- const drawableList = drawableTypeInfo[type].drawableList;
18509
- for (let i = 0, len = drawableList.length; i < len; i++) {
18510
- const drawable = drawableList[i];
18511
- if (drawable.setPickMatrices) { // Eg. SceneModel, which needs pre-loading into texture
18512
- drawable.setPickMatrices(pickViewMatrix, pickProjMatrix);
18518
+ vertexPickBuffer.bind(gl.RGBA32I, gl.RGBA32I, gl.RGBA8UI);
18519
+ gl.viewport(0, 0, vertexPickBuffer.size[0], vertexPickBuffer.size[1]);
18520
+ gl.enable(gl.DEPTH_TEST);
18521
+ gl.frontFace(gl.CCW);
18522
+ gl.disable(gl.CULL_FACE);
18523
+ gl.depthMask(true);
18524
+ gl.disable(gl.BLEND);
18525
+ gl.depthFunc(gl.LEQUAL);
18526
+ gl.clear(gl.DEPTH_BUFFER_BIT);
18527
+ gl.clearBufferiv(gl.COLOR, 0, new Int32Array([0, 0, 0, 0]));
18528
+ gl.clearBufferiv(gl.COLOR, 1, new Int32Array([0, 0, 0, 0]));
18529
+ gl.clearBufferuiv(gl.COLOR, 2, new Uint32Array([0, 0, 0, 0]));
18530
+
18531
+ //////////////////////////////////
18532
+ // Set view and proj mats for VBO renderers
18533
+ ///////////////////////////////////////
18534
+
18535
+ const pickViewMatrix = scene.camera.viewMatrix;
18536
+ const pickProjMatrix = scene.camera.projMatrix;
18537
+
18538
+ for (let type in drawableTypeInfo) {
18539
+ if (drawableTypeInfo.hasOwnProperty(type)) {
18540
+ const drawableList = drawableTypeInfo[type].drawableList;
18541
+ for (let i = 0, len = drawableList.length; i < len; i++) {
18542
+ const drawable = drawableList[i];
18543
+ if (drawable.setPickMatrices) { // Eg. SceneModel, which needs pre-loading into texture
18544
+ drawable.setPickMatrices(pickViewMatrix, pickProjMatrix);
18545
+ }
18513
18546
  }
18514
18547
  }
18515
18548
  }
18516
- }
18517
18549
 
18518
- // a) init z-buffer
18519
- gl.drawBuffers([gl.COLOR_ATTACHMENT0, gl.COLOR_ATTACHMENT1, gl.COLOR_ATTACHMENT2]);
18520
- const layerParamsSurface = snapInitDepthBuf(frameCtx);
18550
+ // a) init z-buffer
18551
+ gl.drawBuffers([gl.COLOR_ATTACHMENT0, gl.COLOR_ATTACHMENT1, gl.COLOR_ATTACHMENT2]);
18552
+ const layerParamsSurface = snapInitDepthBuf(frameCtx);
18521
18553
 
18522
- // b) snap-pick
18523
- const layerParamsSnap = [];
18524
- frameCtx.snapPickLayerParams = layerParamsSnap;
18554
+ // b) snap-pick
18555
+ const layerParamsSnap = [];
18556
+ frameCtx.snapPickLayerParams = layerParamsSnap;
18525
18557
 
18526
- gl.depthMask(false);
18527
- gl.drawBuffers([gl.COLOR_ATTACHMENT0]);
18558
+ gl.depthMask(false);
18559
+ gl.drawBuffers([gl.COLOR_ATTACHMENT0]);
18528
18560
 
18529
- if (snapToVertex && snapToEdge) {
18530
- frameCtx.snapMode = "edge";
18531
- snapPickDrawSnapDepths(frameCtx);
18561
+ if (snapToVertex && snapToEdge) {
18562
+ frameCtx.snapMode = "edge";
18563
+ snapPickDrawSnapDepths(frameCtx);
18532
18564
 
18533
- frameCtx.snapMode = "vertex";
18534
- frameCtx.snapPickLayerNumber++;
18565
+ frameCtx.snapMode = "vertex";
18566
+ frameCtx.snapPickLayerNumber++;
18535
18567
 
18536
- snapPickDrawSnapDepths(frameCtx);
18537
- } else {
18538
- frameCtx.snapMode = snapToVertex ? "vertex" : "edge";
18568
+ snapPickDrawSnapDepths(frameCtx);
18569
+ } else {
18570
+ frameCtx.snapMode = snapToVertex ? "vertex" : "edge";
18539
18571
 
18540
- snapPickDrawSnapDepths(frameCtx);
18541
- }
18572
+ snapPickDrawSnapDepths(frameCtx);
18573
+ }
18542
18574
 
18543
- gl.depthMask(true);
18575
+ gl.depthMask(true);
18544
18576
 
18545
- // Read and decode the snapped coordinates
18577
+ // Read and decode the snapped coordinates
18546
18578
 
18547
- const snapPickResultArray = vertexPickBuffer.readArray(gl.RGBA_INTEGER, gl.INT, Int32Array, 4);
18548
- const snapPickNormalResultArray = vertexPickBuffer.readArray(gl.RGBA_INTEGER, gl.INT, Int32Array, 4, 1);
18549
- const snapPickIdResultArray = vertexPickBuffer.readArray(gl.RGBA_INTEGER, gl.UNSIGNED_INT, Uint32Array, 4, 2);
18579
+ const snapPickResultArray = vertexPickBuffer.readArray(gl.RGBA_INTEGER, gl.INT, Int32Array, 4);
18580
+ const snapPickNormalResultArray = vertexPickBuffer.readArray(gl.RGBA_INTEGER, gl.INT, Int32Array, 4, 1);
18581
+ const snapPickIdResultArray = vertexPickBuffer.readArray(gl.RGBA_INTEGER, gl.UNSIGNED_INT, Uint32Array, 4, 2);
18550
18582
 
18551
- vertexPickBuffer.unbind();
18583
+ vertexPickBuffer.unbind();
18552
18584
 
18553
- // result 1) regular hi-precision world position
18585
+ // result 1) regular hi-precision world position
18554
18586
 
18555
- let worldPos = null;
18556
- let worldNormal = null;
18587
+ let worldPos = null;
18557
18588
 
18558
- const middleX = snapRadiusInPixels;
18559
- const middleY = snapRadiusInPixels;
18560
- const middleIndex = (middleX * 4) + (middleY * vertexPickBuffer.size[0] * 4);
18561
- const pickResultMiddleXY = snapPickResultArray.slice(middleIndex, middleIndex + 4);
18562
- const pickNormalResultMiddleXY = snapPickNormalResultArray.slice(middleIndex, middleIndex + 4);
18563
- const pickPickableResultMiddleXY = snapPickIdResultArray.slice(middleIndex, middleIndex + 4);
18589
+ const middleX = snapRadiusInPixels;
18590
+ const middleY = snapRadiusInPixels;
18591
+ const middleIndex = (middleX * 4) + (middleY * vertexPickBuffer.size[0] * 4);
18592
+ const pickResultMiddleXY = snapPickResultArray.slice(middleIndex, middleIndex + 4);
18593
+ const pickNormalResultMiddleXY = snapPickNormalResultArray.slice(middleIndex, middleIndex + 4);
18594
+ const pickPickableResultMiddleXY = snapPickIdResultArray.slice(middleIndex, middleIndex + 4);
18564
18595
 
18565
- if (pickResultMiddleXY[3] !== 0) {
18566
- const pickedLayerParmasSurface = layerParamsSurface[Math.abs(pickResultMiddleXY[3]) % layerParamsSurface.length];
18567
- const origin = pickedLayerParmasSurface.origin;
18568
- const scale = pickedLayerParmasSurface.coordinateScale;
18569
- worldPos = [
18570
- pickResultMiddleXY[0] * scale[0] + origin[0],
18571
- pickResultMiddleXY[1] * scale[1] + origin[1],
18572
- pickResultMiddleXY[2] * scale[2] + origin[2],
18573
- ];
18574
- worldNormal = math.normalizeVec3([
18575
- pickNormalResultMiddleXY[0] / math.MAX_INT,
18576
- pickNormalResultMiddleXY[1] / math.MAX_INT,
18577
- pickNormalResultMiddleXY[2] / math.MAX_INT,
18578
- ]);
18579
-
18580
- const pickID =
18581
- pickPickableResultMiddleXY[0]
18582
- + (pickPickableResultMiddleXY[1] << 8)
18583
- + (pickPickableResultMiddleXY[2] << 16)
18584
- + (pickPickableResultMiddleXY[3] << 24);
18585
-
18586
- pickIDs.items[pickID];
18587
- }
18588
-
18589
- // result 2) hi-precision snapped (to vertex/edge) world position
18590
-
18591
- let snapPickResult = [];
18592
-
18593
- for (let i = 0; i < snapPickResultArray.length; i += 4) {
18594
- if (snapPickResultArray[i + 3] > 0) {
18595
- const pixelNumber = Math.floor(i / 4);
18596
- const w = vertexPickBuffer.size[0];
18597
- const x = pixelNumber % w - Math.floor(w / 2);
18598
- const y = Math.floor(pixelNumber / w) - Math.floor(w / 2);
18599
- const dist = (Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)));
18600
- snapPickResult.push({
18601
- x,
18602
- y,
18603
- dist,
18604
- isVertex: snapToVertex && snapToEdge ? snapPickResultArray[i + 3] > layerParamsSnap.length / 2 : snapToVertex,
18605
- result: [
18606
- snapPickResultArray[i + 0],
18607
- snapPickResultArray[i + 1],
18608
- snapPickResultArray[i + 2],
18609
- snapPickResultArray[i + 3],
18610
- ],
18611
- normal: [
18612
- snapPickNormalResultArray[i + 0],
18613
- snapPickNormalResultArray[i + 1],
18614
- snapPickNormalResultArray[i + 2],
18615
- snapPickNormalResultArray[i + 3],
18616
- ],
18617
- id: [
18618
- snapPickIdResultArray[i + 0],
18619
- snapPickIdResultArray[i + 1],
18620
- snapPickIdResultArray[i + 2],
18621
- snapPickIdResultArray[i + 3],
18622
- ]
18623
- });
18596
+ if (pickResultMiddleXY[3] !== 0) {
18597
+ const pickedLayerParmasSurface = layerParamsSurface[Math.abs(pickResultMiddleXY[3]) % layerParamsSurface.length];
18598
+ const origin = pickedLayerParmasSurface.origin;
18599
+ const scale = pickedLayerParmasSurface.coordinateScale;
18600
+ worldPos = [
18601
+ pickResultMiddleXY[0] * scale[0] + origin[0],
18602
+ pickResultMiddleXY[1] * scale[1] + origin[1],
18603
+ pickResultMiddleXY[2] * scale[2] + origin[2],
18604
+ ];
18605
+ math.normalizeVec3([
18606
+ pickNormalResultMiddleXY[0] / math.MAX_INT,
18607
+ pickNormalResultMiddleXY[1] / math.MAX_INT,
18608
+ pickNormalResultMiddleXY[2] / math.MAX_INT,
18609
+ ]);
18610
+
18611
+ const pickID =
18612
+ pickPickableResultMiddleXY[0]
18613
+ + (pickPickableResultMiddleXY[1] << 8)
18614
+ + (pickPickableResultMiddleXY[2] << 16)
18615
+ + (pickPickableResultMiddleXY[3] << 24);
18616
+
18617
+ pickIDs.items[pickID];
18618
+ }
18619
+
18620
+ // result 2) hi-precision snapped (to vertex/edge) world position
18621
+
18622
+ let snapPickResult = [];
18623
+
18624
+ for (let i = 0; i < snapPickResultArray.length; i += 4) {
18625
+ if (snapPickResultArray[i + 3] > 0) {
18626
+ const pixelNumber = Math.floor(i / 4);
18627
+ const w = vertexPickBuffer.size[0];
18628
+ const x = pixelNumber % w - Math.floor(w / 2);
18629
+ const y = Math.floor(pixelNumber / w) - Math.floor(w / 2);
18630
+ const dist = (Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)));
18631
+ snapPickResult.push({
18632
+ x,
18633
+ y,
18634
+ dist,
18635
+ isVertex: snapToVertex && snapToEdge ? snapPickResultArray[i + 3] > layerParamsSnap.length / 2 : snapToVertex,
18636
+ result: [
18637
+ snapPickResultArray[i + 0],
18638
+ snapPickResultArray[i + 1],
18639
+ snapPickResultArray[i + 2],
18640
+ snapPickResultArray[i + 3],
18641
+ ],
18642
+ normal: [
18643
+ snapPickNormalResultArray[i + 0],
18644
+ snapPickNormalResultArray[i + 1],
18645
+ snapPickNormalResultArray[i + 2],
18646
+ snapPickNormalResultArray[i + 3],
18647
+ ],
18648
+ id: [
18649
+ snapPickIdResultArray[i + 0],
18650
+ snapPickIdResultArray[i + 1],
18651
+ snapPickIdResultArray[i + 2],
18652
+ snapPickIdResultArray[i + 3],
18653
+ ]
18654
+ });
18655
+ }
18624
18656
  }
18625
- }
18626
18657
 
18627
- let snappedWorldPos = null;
18628
- let snappedWorldNormal = null;
18629
- let snappedPickable = null;
18630
- let snapType = null;
18658
+ let snappedWorldPos = null;
18659
+ let snappedWorldNormal = null;
18660
+ let snappedPickable = null;
18661
+ let snapType = null;
18631
18662
 
18632
- if (snapPickResult.length > 0) {
18633
- // vertex snap first, then edge snap
18634
- snapPickResult.sort((a, b) => {
18635
- if (a.isVertex !== b.isVertex) {
18636
- return a.isVertex ? -1 : 1;
18637
- } else {
18638
- return a.dist - b.dist;
18639
- }
18640
- });
18663
+ if (snapPickResult.length > 0) {
18664
+ // vertex snap first, then edge snap
18665
+ snapPickResult.sort((a, b) => {
18666
+ if (a.isVertex !== b.isVertex) {
18667
+ return a.isVertex ? -1 : 1;
18668
+ } else {
18669
+ return a.dist - b.dist;
18670
+ }
18671
+ });
18641
18672
 
18642
- snapType = snapPickResult[0].isVertex ? "vertex" : "edge";
18643
- const snapPick = snapPickResult[0].result;
18644
- const snapPickNormal = snapPickResult[0].normal;
18645
- const snapPickId = snapPickResult[0].id;
18673
+ snapType = snapPickResult[0].isVertex ? "vertex" : "edge";
18674
+ const snapPick = snapPickResult[0].result;
18675
+ const snapPickNormal = snapPickResult[0].normal;
18676
+ const snapPickId = snapPickResult[0].id;
18646
18677
 
18647
- const pickedLayerParmas = layerParamsSnap[snapPick[3]];
18678
+ const pickedLayerParmas = layerParamsSnap[snapPick[3]];
18648
18679
 
18649
- const origin = pickedLayerParmas.origin;
18650
- const scale = pickedLayerParmas.coordinateScale;
18680
+ const origin = pickedLayerParmas.origin;
18681
+ const scale = pickedLayerParmas.coordinateScale;
18651
18682
 
18652
- snappedWorldNormal = math.normalizeVec3([
18653
- snapPickNormal[0] / math.MAX_INT,
18654
- snapPickNormal[1] / math.MAX_INT,
18655
- snapPickNormal[2] / math.MAX_INT,
18656
- ]);
18683
+ snappedWorldNormal = math.normalizeVec3([
18684
+ snapPickNormal[0] / math.MAX_INT,
18685
+ snapPickNormal[1] / math.MAX_INT,
18686
+ snapPickNormal[2] / math.MAX_INT,
18687
+ ]);
18657
18688
 
18658
- snappedWorldPos = [
18659
- snapPick[0] * scale[0] + origin[0],
18660
- snapPick[1] * scale[1] + origin[1],
18661
- snapPick[2] * scale[2] + origin[2],
18662
- ];
18689
+ snappedWorldPos = [
18690
+ snapPick[0] * scale[0] + origin[0],
18691
+ snapPick[1] * scale[1] + origin[1],
18692
+ snapPick[2] * scale[2] + origin[2],
18693
+ ];
18663
18694
 
18664
- snappedPickable = pickIDs.items[
18695
+ snappedPickable = pickIDs.items[
18665
18696
  snapPickId[0]
18666
18697
  + (snapPickId[1] << 8)
18667
18698
  + (snapPickId[2] << 16)
18668
18699
  + (snapPickId[3] << 24)
18669
- ];
18670
- }
18700
+ ];
18701
+ }
18671
18702
 
18672
- if (null === worldPos && null == snappedWorldPos) { // If neither regular pick or snap pick, return null
18673
- return null;
18674
- }
18703
+ if (null === worldPos && null == snappedWorldPos) { // If neither regular pick or snap pick, return null
18704
+ return null;
18705
+ }
18675
18706
 
18676
- let snappedCanvasPos = null;
18707
+ let snappedCanvasPos = null;
18677
18708
 
18678
- if (null !== snappedWorldPos) {
18679
- snappedCanvasPos = scene.camera.projectWorldPos(snappedWorldPos);
18680
- }
18709
+ if (null !== snappedWorldPos) {
18710
+ snappedCanvasPos = scene.camera.projectWorldPos(snappedWorldPos);
18711
+ }
18681
18712
 
18682
- const snappedEntity = (snappedPickable && snappedPickable.delegatePickedEntity) ? snappedPickable.delegatePickedEntity() : snappedPickable;
18713
+ const snappedEntity = (snappedPickable && snappedPickable.delegatePickedEntity) ? snappedPickable.delegatePickedEntity() : snappedPickable;
18683
18714
 
18684
- return {
18685
- snapType,
18686
- snappedToVertex: snapType === "vertex",
18687
- snappedToEdge: snapType === "edge",
18688
- worldPos,
18689
- worldNormal,
18690
- snappedWorldPos,
18691
- snappedWorldNormal,
18692
- snappedCanvasPos,
18693
- snappedEntity,
18694
- entity: snappedEntity
18715
+ pickResult.reset();
18716
+ pickResult.snappedToEdge = (snapType === "edge");
18717
+ pickResult.snappedToVertex = (snapType === "vertex");
18718
+ pickResult.worldPos = snappedWorldPos;
18719
+ pickResult.worldNormal = snappedWorldNormal;
18720
+ pickResult.entity = snappedEntity;
18721
+ pickResult.canvasPos = canvasPos;
18722
+ pickResult.snappedCanvasPos = snappedCanvasPos || canvasPos;
18723
+
18724
+ return pickResult;
18695
18725
  };
18696
- };
18726
+ })();
18697
18727
 
18698
18728
  function unpackDepth(depthZ) {
18699
18729
  const vec = [depthZ[0] / 256.0, depthZ[1] / 256.0, depthZ[2] / 256.0, depthZ[3] / 256.0];
@@ -29701,6 +29731,9 @@ class Scene extends Component {
29701
29731
  * @param {Number[]} [params.matrix] 4x4 transformation matrix to define the World-space ray origin and direction, as an alternative to ````origin```` and ````direction````.
29702
29732
  * @param {String[]} [params.includeEntities] IDs of {@link Entity}s to restrict picking to. When given, ignores {@link Entity}s whose IDs are not in this list.
29703
29733
  * @param {String[]} [params.excludeEntities] IDs of {@link Entity}s to ignore. When given, will pick *through* these {@link Entity}s, as if they were not there.
29734
+ * @param {Number} [params.snapRadius=30] The snap radius, in canvas pixels
29735
+ * @param {boolean} [params.snapToVertex=true] Whether to snap to vertex.
29736
+ * @param {boolean} [params.snapToEdge=true] Whether to snap to edge.
29704
29737
  * @param {PickResult} [pickResult] Holds the results of the pick attempt. Will use the Scene's singleton PickResult if you don't supply your own.
29705
29738
  * @returns {PickResult} Holds results of the pick attempt, returned when an {@link Entity} is picked, else null. See method comments for description.
29706
29739
  */
@@ -29735,14 +29768,25 @@ class Scene extends Component {
29735
29768
  this._needRecompile = false;
29736
29769
  }
29737
29770
 
29738
- pickResult = this._renderer.pick(params, pickResult);
29771
+ if (params.snapToEdge || params.snapToVertex) {
29772
+ pickResult = this._renderer.snapPick(
29773
+ params.canvasPos,
29774
+ params.snapRadius || 30,
29775
+ params.snapToVertex,
29776
+ params.snapToEdge,
29777
+ pickResult
29778
+ );
29779
+ } else {
29780
+ pickResult = this._renderer.pick(params, pickResult);
29781
+ }
29739
29782
 
29740
29783
  if (pickResult) {
29741
29784
  if (pickResult.entity && pickResult.entity.fire) {
29742
- pickResult.entity.fire("picked", pickResult); // TODO: PerformanceModelNode doesn't fire events
29785
+ pickResult.entity.fire("picked", pickResult); // TODO: SceneModelEntity doesn't fire events
29743
29786
  }
29744
- return pickResult;
29745
29787
  }
29788
+
29789
+ return pickResult;
29746
29790
  }
29747
29791
 
29748
29792
  /**
@@ -29751,8 +29795,13 @@ class Scene extends Component {
29751
29795
  * @param {Number} [params.snapRadius=30] The snap radius, in canvas pixels
29752
29796
  * @param {boolean} [params.snapToVertex=true] Whether to snap to vertex.
29753
29797
  * @param {boolean} [params.snapToEdge=true] Whether to snap to edge.
29798
+ * @deprecated
29754
29799
  */
29755
29800
  snapPick(params) {
29801
+ if (undefined === this._warnSnapPickDeprecated) {
29802
+ this._warnSnapPickDeprecated = true;
29803
+ this.warn("Scene.snapPick() is deprecated since v2.4.2 - use Scene.pick() instead");
29804
+ }
29756
29805
  return this._renderer.snapPick(
29757
29806
  params.canvasPos,
29758
29807
  params.snapRadius || 30,
@@ -49925,18 +49974,19 @@ class DistanceMeasurementsMouseControl extends DistanceMeasurementsControl {
49925
49974
  this._snapping
49926
49975
  ? "hoverSnapOrSurface"
49927
49976
  : "hoverSurface", event => {
49977
+ const canvasPos = event.snappedCanvasPos || event.canvasPos;
49928
49978
  mouseHovering = true;
49929
49979
  pointerWorldPos.set(event.worldPos);
49930
49980
  pointerCanvasPos.set(event.canvasPos);
49931
49981
  if (this._mouseState === MOUSE_FIRST_CLICK_EXPECTED) {
49932
- this._markerDiv.style.marginLeft = `${event.canvasPos[0] - 5}px`;
49933
- this._markerDiv.style.marginTop = `${event.canvasPos[1] - 5}px`;
49982
+ this._markerDiv.style.marginLeft = `${canvasPos[0] - 5}px`;
49983
+ this._markerDiv.style.marginTop = `${canvasPos[1] - 5}px`;
49934
49984
  this._markerDiv.style.background = "pink";
49935
49985
  if (event.snappedToVertex || event.snappedToEdge) {
49936
49986
  if (this.pointerLens) {
49937
49987
  this.pointerLens.visible = true;
49938
- this.pointerLens.centerPos = event.cursorPos || event.canvasPos;
49939
- this.pointerLens.cursorPos = event.canvasPos;
49988
+ this.pointerLens.canvasPos = event.canvasPos;
49989
+ this.pointerLens.snappedCanvasPos = event.snappedCanvasPos || event.canvasPos;
49940
49990
  this.pointerLens.snapped = true;
49941
49991
  }
49942
49992
  this._markerDiv.style.background = "greenyellow";
@@ -49944,8 +49994,8 @@ class DistanceMeasurementsMouseControl extends DistanceMeasurementsControl {
49944
49994
  } else {
49945
49995
  if (this.pointerLens) {
49946
49996
  this.pointerLens.visible = true;
49947
- this.pointerLens.centerPos = event.cursorPos || event.canvasPos;
49948
- this.pointerLens.cursorPos = event.canvasPos;
49997
+ this.pointerLens.canvasPos = event.canvasPos;
49998
+ this.pointerLens.snappedCanvasPos = event.canvasPos;
49949
49999
  this.pointerLens.snapped = false;
49950
50000
  }
49951
50001
  this._markerDiv.style.background = "pink";
@@ -50027,8 +50077,8 @@ class DistanceMeasurementsMouseControl extends DistanceMeasurementsControl {
50027
50077
  : "hoverOff", event => {
50028
50078
  if (this.pointerLens) {
50029
50079
  this.pointerLens.visible = true;
50030
- this.pointerLens.centerPos = event.cursorPos || event.canvasPos;
50031
- this.pointerLens.cursorPos = event.canvasPos;
50080
+ this.pointerLens.canvasPos = event.canvasPos;
50081
+ this.pointerLens.snappedCanvasPos = event.snappedCanvasPos || event.canvasPos;
50032
50082
  }
50033
50083
  mouseHovering = false;
50034
50084
  this._markerDiv.style.marginLeft = `-100px`;
@@ -87437,6 +87487,8 @@ class PickController {
87437
87487
 
87438
87488
  this._lastPickedEntityId = null;
87439
87489
 
87490
+ this._lastHash = null;
87491
+
87440
87492
  this._needFireEvents = 0;
87441
87493
  }
87442
87494
 
@@ -87444,6 +87496,7 @@ class PickController {
87444
87496
  * Immediately attempts a pick, if scheduled.
87445
87497
  */
87446
87498
  update() {
87499
+
87447
87500
  if (!this._configs.pointerEnabled) {
87448
87501
  return;
87449
87502
  }
@@ -87452,6 +87505,11 @@ class PickController {
87452
87505
  return;
87453
87506
  }
87454
87507
 
87508
+ const hash = `${~~this.pickCursorPos[0]}-${~~this.pickCursorPos[1]}-${this.scheduleSnapOrPick}-${this.schedulePickSurface}-${this.schedulePickEntity}`;
87509
+ if (this._lastHash === hash) {
87510
+ return;
87511
+ }
87512
+
87455
87513
  this.picked = false;
87456
87514
  this.pickedSurface = false;
87457
87515
  this.snappedOrPicked = false;
@@ -87460,13 +87518,13 @@ class PickController {
87460
87518
  const hasHoverSurfaceSubs = this._cameraControl.hasSubs("hoverSurface");
87461
87519
 
87462
87520
  if (this.scheduleSnapOrPick) {
87463
- const snapPickResult = this._scene.snapPick({
87521
+ const snapPickResult = this._scene.pick({
87464
87522
  canvasPos: this.pickCursorPos,
87465
87523
  snapRadius: this._configs.snapRadius,
87466
87524
  snapToVertex: this._configs.snapToVertex,
87467
87525
  snapToEdge: this._configs.snapToEdge,
87468
87526
  });
87469
- if (snapPickResult && snapPickResult.snappedWorldPos) {
87527
+ if (snapPickResult && (snapPickResult.snappedToEdge || snapPickResult.snappedToVertex)) {
87470
87528
  this.snapPickResult = snapPickResult;
87471
87529
  this.snappedOrPicked = true;
87472
87530
  this._needFireEvents++;
@@ -87548,14 +87606,14 @@ class PickController {
87548
87606
 
87549
87607
  fireEvents() {
87550
87608
 
87551
- if (this._needFireEvents == 0) {
87609
+ if (this._needFireEvents === 0) {
87552
87610
  return;
87553
87611
  }
87554
87612
 
87555
87613
  if (this.hoveredSnappedOrSurfaceOff) {
87556
87614
  this._cameraControl.fire("hoverSnapOrSurfaceOff", {
87557
87615
  canvasPos: this.pickCursorPos,
87558
- cursorPos : this.pickCursorPos
87616
+ pointerPos : this.pickCursorPos
87559
87617
  }, true);
87560
87618
  }
87561
87619
 
@@ -87564,9 +87622,9 @@ class PickController {
87564
87622
  const pickResult = new PickResult();
87565
87623
  pickResult.snappedToVertex = this.snapPickResult.snappedToVertex;
87566
87624
  pickResult.snappedToEdge = this.snapPickResult.snappedToEdge;
87567
- pickResult.worldPos = this.snapPickResult.snappedWorldPos;
87568
- pickResult.cursorPos = this.pickCursorPos;
87569
- pickResult.canvasPos = this.snapPickResult.snappedCanvasPos;
87625
+ pickResult.worldPos = this.snapPickResult.worldPos;
87626
+ pickResult.canvasPos = this.pickCursorPos;
87627
+ pickResult.snappedCanvasPos = this.snapPickResult.snappedCanvasPos;
87570
87628
  this._cameraControl.fire("hoverSnapOrSurface", pickResult, true);
87571
87629
  this.snapPickResult = null;
87572
87630
  } else {