@xeokit/xeokit-sdk 2.4.2-beta-14 → 2.4.2-beta-19
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.
- package/dist/xeokit-sdk.cjs.js +506 -319
- package/dist/xeokit-sdk.es.js +506 -319
- package/dist/xeokit-sdk.es5.js +356 -236
- package/dist/xeokit-sdk.min.cjs.js +3 -3
- package/dist/xeokit-sdk.min.es.js +2 -2
- package/dist/xeokit-sdk.min.es5.js +2 -2
- package/package.json +1 -1
- package/src/extras/MarqueePicker/MarqueePicker.js +81 -0
- package/src/extras/MarqueePicker/MarqueePickerMouseControl.js +2 -0
- package/src/extras/PointerLens/PointerLens.js +21 -21
- package/src/extras/collision/ObjectsKdTree3.js +2 -0
- package/src/plugins/AngleMeasurementsPlugin/AngleMeasurementsMouseControl.js +10 -9
- package/src/plugins/DistanceMeasurementsPlugin/DistanceMeasurementsMouseControl.js +9 -8
- package/src/viewer/scene/CameraControl/lib/controllers/PickController.js +8 -29
- package/src/viewer/scene/CameraControl/lib/handlers/MousePickHandler.js +48 -45
- package/src/viewer/scene/input/Input.js +10 -2
- package/src/viewer/scene/scene/Scene.js +84 -3
- package/src/viewer/scene/webgl/PickResult.js +27 -2
- package/src/viewer/scene/webgl/Renderer.js +212 -207
package/dist/xeokit-sdk.cjs.js
CHANGED
|
@@ -1045,8 +1045,8 @@ class PointerLens {
|
|
|
1045
1045
|
this._lensCanvasContext = this._lensCanvas.getContext('2d');
|
|
1046
1046
|
this._canvasElement = this.viewer.scene.canvas.canvas;
|
|
1047
1047
|
|
|
1048
|
-
this.
|
|
1049
|
-
this.
|
|
1048
|
+
this._canvasPos = null;
|
|
1049
|
+
this._snappedCanvasPos = null;
|
|
1050
1050
|
this._lensPosToggle = true;
|
|
1051
1051
|
|
|
1052
1052
|
this._zoomLevel = cfg.zoomLevel || 2;
|
|
@@ -1069,14 +1069,14 @@ class PointerLens {
|
|
|
1069
1069
|
if (!this._active || !this._visible) {
|
|
1070
1070
|
return;
|
|
1071
1071
|
}
|
|
1072
|
-
if (!this.
|
|
1072
|
+
if (!this._canvasPos) {
|
|
1073
1073
|
return;
|
|
1074
1074
|
}
|
|
1075
1075
|
const lensRect = this._lensContainer.getBoundingClientRect();
|
|
1076
1076
|
const canvasRect = this._canvasElement.getBoundingClientRect();
|
|
1077
1077
|
const pointerOnLens =
|
|
1078
|
-
this.
|
|
1079
|
-
this.
|
|
1078
|
+
this._canvasPos[0] < lensRect.right && this._canvasPos[0] > lensRect.left &&
|
|
1079
|
+
this._canvasPos[1] < lensRect.bottom && this._canvasPos[1] > lensRect.top;
|
|
1080
1080
|
this._lensContainer.style.marginLeft = `25px`;
|
|
1081
1081
|
if (pointerOnLens) {
|
|
1082
1082
|
if (this._lensPosToggle) {
|
|
@@ -1090,8 +1090,8 @@ class PointerLens {
|
|
|
1090
1090
|
const size = Math.max(this._lensCanvas.width, this._lensCanvas.height) / this._zoomLevel;
|
|
1091
1091
|
this._lensCanvasContext.drawImage(
|
|
1092
1092
|
this._canvasElement, // source canvas
|
|
1093
|
-
this.
|
|
1094
|
-
this.
|
|
1093
|
+
this._canvasPos[0] - size / 2, // source x (zoom center)
|
|
1094
|
+
this._canvasPos[1] - size / 2, // source y (zoom center)
|
|
1095
1095
|
size, // source width
|
|
1096
1096
|
size, // source height
|
|
1097
1097
|
0, // destination x
|
|
@@ -1105,9 +1105,9 @@ class PointerLens {
|
|
|
1105
1105
|
(lensRect.top + lensRect.bottom) / 2
|
|
1106
1106
|
];
|
|
1107
1107
|
|
|
1108
|
-
if (this.
|
|
1109
|
-
const deltaX = this.
|
|
1110
|
-
const deltaY = this.
|
|
1108
|
+
if (this._snappedCanvasPos) {
|
|
1109
|
+
const deltaX = this._snappedCanvasPos[0] - this._canvasPos[0];
|
|
1110
|
+
const deltaY = this._snappedCanvasPos[1] - this._canvasPos[1];
|
|
1111
1111
|
|
|
1112
1112
|
this._lensCursorDiv.style.marginLeft = `${centerLensCanvas[0] + deltaX * this._zoomLevel - 10}px`;
|
|
1113
1113
|
this._lensCursorDiv.style.marginTop = `${centerLensCanvas[1] + deltaY * this._zoomLevel - 10}px`;
|
|
@@ -1143,10 +1143,10 @@ class PointerLens {
|
|
|
1143
1143
|
|
|
1144
1144
|
/**
|
|
1145
1145
|
* Sets the canvas central position of the lens.
|
|
1146
|
-
* @param
|
|
1146
|
+
* @param canvasPos
|
|
1147
1147
|
*/
|
|
1148
|
-
set
|
|
1149
|
-
this.
|
|
1148
|
+
set canvasPos(canvasPos) {
|
|
1149
|
+
this._canvasPos = canvasPos;
|
|
1150
1150
|
this.update();
|
|
1151
1151
|
}
|
|
1152
1152
|
|
|
@@ -1154,25 +1154,25 @@ class PointerLens {
|
|
|
1154
1154
|
* Gets the canvas central position of the lens.
|
|
1155
1155
|
* @returns {Number[]}
|
|
1156
1156
|
*/
|
|
1157
|
-
get
|
|
1158
|
-
return this.
|
|
1157
|
+
get canvasPos() {
|
|
1158
|
+
return this._canvasPos;
|
|
1159
1159
|
}
|
|
1160
1160
|
|
|
1161
1161
|
/**
|
|
1162
1162
|
* Sets the canvas coordinates of the pointer.
|
|
1163
|
-
* @param
|
|
1163
|
+
* @param snappedCanvasPos
|
|
1164
1164
|
*/
|
|
1165
|
-
set
|
|
1166
|
-
this.
|
|
1165
|
+
set snappedCanvasPos(snappedCanvasPos) {
|
|
1166
|
+
this._snappedCanvasPos = snappedCanvasPos;
|
|
1167
1167
|
this.update();
|
|
1168
1168
|
}
|
|
1169
1169
|
|
|
1170
1170
|
/**
|
|
1171
|
-
* Gets the canvas coordinates of the pointer.
|
|
1171
|
+
* Gets the canvas coordinates of the snapped pointer.
|
|
1172
1172
|
* @returns {Number[]}
|
|
1173
1173
|
*/
|
|
1174
|
-
get
|
|
1175
|
-
return this.
|
|
1174
|
+
get snappedCanvasPos() {
|
|
1175
|
+
return this._snappedCanvasPos;
|
|
1176
1176
|
}
|
|
1177
1177
|
|
|
1178
1178
|
/**
|
|
@@ -6653,6 +6653,8 @@ const kdTreeDimLength$1 = new Float32Array(3);
|
|
|
6653
6653
|
* Automatically indexes a {@link Viewer}'s {@link Entity}s in a 3D k-d tree
|
|
6654
6654
|
* to support fast collision detection with 3D World-space axis-aligned boundaries (AABBs) and frustums.
|
|
6655
6655
|
*
|
|
6656
|
+
* See {@link MarqueePicker} for usage example.
|
|
6657
|
+
*
|
|
6656
6658
|
* An ObjectsKdTree3 is configured with a Viewer, and will then automatically
|
|
6657
6659
|
* keep itself populated with k-d nodes that contain the Viewer's Entitys.
|
|
6658
6660
|
*
|
|
@@ -8581,6 +8583,87 @@ function frustumIntersectsAABB3(frustum, aabb) {
|
|
|
8581
8583
|
|
|
8582
8584
|
/**
|
|
8583
8585
|
* Picks a {@link Viewer}'s {@link Entity}s with a canvas-space 2D marquee box.
|
|
8586
|
+
*
|
|
8587
|
+
* [<img src="https://xeokit.github.io/xeokit-sdk/assets/images/MarqueeSelect.gif">](https://xeokit.github.io/xeokit-sdk/examples/picking/#marqueePick_select)
|
|
8588
|
+
*
|
|
8589
|
+
* * [[Example 1: Select Objects with Marquee](https://xeokit.github.io/xeokit-sdk/examples/picking/#marqueePick_select)]
|
|
8590
|
+
* * [[Example 2: View-Fit Objects with Marquee](https://xeokit.github.io/xeokit-sdk/examples/picking/#marqueePick_viewFit)]
|
|
8591
|
+
*
|
|
8592
|
+
* # Usage
|
|
8593
|
+
*
|
|
8594
|
+
* In the example below, we
|
|
8595
|
+
*
|
|
8596
|
+
* 1. Create a {@link Viewer}, arrange the {@link Camera}
|
|
8597
|
+
* 2. Use an {@link XKTLoaderPlugin} to load a BIM model,
|
|
8598
|
+
* 3. Create a {@link ObjectsKdTree3} to automatically index the `Viewer's` {@link Entity}s for fast spatial lookup,
|
|
8599
|
+
* 4. Create a `MarqueePicker` to pick {@link Entity}s in the {@link Viewer}, using the {@link ObjectsKdTree3} to accelerate picking
|
|
8600
|
+
* 5. Create a {@link MarqueePickerMouseControl} to perform the marquee-picking with the `MarqueePicker`, using mouse input to draw the marquee box on the `Viewer's` canvas.
|
|
8601
|
+
*
|
|
8602
|
+
* When the {@link MarqueePickerMouseControl} is active:
|
|
8603
|
+
*
|
|
8604
|
+
* * Long-click, drag and release on the canvas to define a marque box that picks {@link Entity}s.
|
|
8605
|
+
* * Drag left-to-right to pick {@link Entity}s that intersect the box.
|
|
8606
|
+
* * Drag right-to-left to pick {@link Entity}s that are fully inside the box.
|
|
8607
|
+
* * On release, the `MarqueePicker` will fire a "picked" event with IDs of the picked {@link Entity}s, if any.
|
|
8608
|
+
* * Handling that event, we mark the {@link Entity}s as selected.
|
|
8609
|
+
* * Hold down CTRL to multi-pick.
|
|
8610
|
+
*
|
|
8611
|
+
* ````javascript
|
|
8612
|
+
* import {
|
|
8613
|
+
* Viewer,
|
|
8614
|
+
* XKTLoaderPlugin,
|
|
8615
|
+
* ObjectsKdTree3,
|
|
8616
|
+
* MarqueePicker,
|
|
8617
|
+
* MarqueePickerMouseControl
|
|
8618
|
+
* } from "xeokit-sdk.es.js";
|
|
8619
|
+
*
|
|
8620
|
+
* // 1
|
|
8621
|
+
*
|
|
8622
|
+
* const viewer = new Viewer({
|
|
8623
|
+
* canvasId: "myCanvas"
|
|
8624
|
+
* });
|
|
8625
|
+
*
|
|
8626
|
+
* viewer.scene.camera.eye = [14.9, 14.3, 5.4];
|
|
8627
|
+
* viewer.scene.camera.look = [6.5, 8.3, -4.1];
|
|
8628
|
+
* viewer.scene.camera.up = [-0.28, 0.9, -0.3];
|
|
8629
|
+
*
|
|
8630
|
+
* // 2
|
|
8631
|
+
*
|
|
8632
|
+
* const xktLoader = new XKTLoaderPlugin(viewer);
|
|
8633
|
+
*
|
|
8634
|
+
* const sceneModel = xktLoader.load({
|
|
8635
|
+
* id: "myModel",
|
|
8636
|
+
* src: "../../assets/models/xkt/v8/ifc/HolterTower.ifc.xkt"
|
|
8637
|
+
* });
|
|
8638
|
+
*
|
|
8639
|
+
* // 3
|
|
8640
|
+
*
|
|
8641
|
+
* const objectsKdTree3 = new ObjectsKdTree3({viewer});
|
|
8642
|
+
*
|
|
8643
|
+
* // 4
|
|
8644
|
+
*
|
|
8645
|
+
* const marqueePicker = new MarqueePicker({viewer, objectsKdTree3});
|
|
8646
|
+
*
|
|
8647
|
+
* // 5
|
|
8648
|
+
*
|
|
8649
|
+
* const marqueePickerMouseControl = new MarqueePickerMouseControl({marqueePicker});
|
|
8650
|
+
*
|
|
8651
|
+
* marqueePicker.on("clear", () => {
|
|
8652
|
+
* viewer.scene.setObjectsSelected(viewer.scene.selectedObjectIds, false);
|
|
8653
|
+
* });
|
|
8654
|
+
*
|
|
8655
|
+
* marqueePicker.on("picked", (objectIds) => {
|
|
8656
|
+
* viewer.scene.setObjectsSelected(objectIds, true);
|
|
8657
|
+
* });
|
|
8658
|
+
*
|
|
8659
|
+
* marqueePickerMouseControl.setActive(true);
|
|
8660
|
+
* ````
|
|
8661
|
+
*
|
|
8662
|
+
* # Design Notes
|
|
8663
|
+
*
|
|
8664
|
+
* * The {@link ObjectsKdTree3} can be shared with any other components that want to use it to spatially search for {@link Entity}s.
|
|
8665
|
+
* * The {@link MarqueePickerMouseControl} can be replaced with other types of controllers (i.e. touch), or used alongside them.
|
|
8666
|
+
* * The `MarqueePicker` has no input handlers of its own, and provides an API through which to programmatically control marquee picking. By firing the "picked" events, `MarqueePicker` implements the *Blackboard Pattern*.
|
|
8584
8667
|
*/
|
|
8585
8668
|
class MarqueePicker extends Component {
|
|
8586
8669
|
|
|
@@ -8850,6 +8933,8 @@ MarqueePicker.PICK_MODE_INSIDE = 1;
|
|
|
8850
8933
|
/**
|
|
8851
8934
|
* Controls a {@link MarqueePicker} with mouse input.
|
|
8852
8935
|
*
|
|
8936
|
+
* See {@link MarqueePicker} for usage example.
|
|
8937
|
+
*
|
|
8853
8938
|
* When the MarqueePickerMouseControl is active:
|
|
8854
8939
|
*
|
|
8855
8940
|
* * Long-click, drag and release on the canvas to define a marque box that picks {@link Entity}s.
|
|
@@ -11928,8 +12013,8 @@ class AngleMeasurementsMouseControl extends AngleMeasurementsControl {
|
|
|
11928
12013
|
if (event.snappedToVertex || event.snappedToEdge) {
|
|
11929
12014
|
if (pointerLens) {
|
|
11930
12015
|
pointerLens.visible = true;
|
|
11931
|
-
pointerLens.
|
|
11932
|
-
pointerLens.
|
|
12016
|
+
pointerLens.canvasPos = event.canvasPos;
|
|
12017
|
+
pointerLens.snappedCanvasPos = event.snappedCanvasPos || event.canvasPos;
|
|
11933
12018
|
pointerLens.snapped = true;
|
|
11934
12019
|
}
|
|
11935
12020
|
this.markerDiv.style.background = "greenyellow";
|
|
@@ -11937,21 +12022,22 @@ class AngleMeasurementsMouseControl extends AngleMeasurementsControl {
|
|
|
11937
12022
|
} else {
|
|
11938
12023
|
if (pointerLens) {
|
|
11939
12024
|
pointerLens.visible = true;
|
|
11940
|
-
pointerLens.
|
|
11941
|
-
pointerLens.
|
|
12025
|
+
pointerLens.canvasPos = event.canvasPos;
|
|
12026
|
+
pointerLens.snappedCanvasPos = event.canvasPos;
|
|
11942
12027
|
pointerLens.snapped = false;
|
|
11943
12028
|
}
|
|
11944
12029
|
this.markerDiv.style.background = "pink";
|
|
11945
12030
|
this.markerDiv.style.border = "2px solid red";
|
|
11946
12031
|
}
|
|
12032
|
+
const canvasPos = event.snappedCanvasPos || event.canvasPos;
|
|
11947
12033
|
mouseHovering = true;
|
|
11948
12034
|
mouseHoverEntity = event.entity;
|
|
11949
12035
|
mouseWorldPos.set(event.worldPos);
|
|
11950
|
-
mouseHoverCanvasPos.set(
|
|
12036
|
+
mouseHoverCanvasPos.set(canvasPos);
|
|
11951
12037
|
switch (this._mouseState) {
|
|
11952
12038
|
case MOUSE_FINDING_ORIGIN:
|
|
11953
|
-
this.markerDiv.style.marginLeft = `${
|
|
11954
|
-
this.markerDiv.style.marginTop = `${
|
|
12039
|
+
this.markerDiv.style.marginLeft = `${canvasPos[0] - 5}px`;
|
|
12040
|
+
this.markerDiv.style.marginTop = `${canvasPos[1] - 5}px`;
|
|
11955
12041
|
break;
|
|
11956
12042
|
case MOUSE_FINDING_CORNER:
|
|
11957
12043
|
if (this._currentAngleMeasurement) {
|
|
@@ -12067,8 +12153,8 @@ class AngleMeasurementsMouseControl extends AngleMeasurementsControl {
|
|
|
12067
12153
|
mouseHovering = false;
|
|
12068
12154
|
if (pointerLens) {
|
|
12069
12155
|
pointerLens.visible = true;
|
|
12070
|
-
pointerLens.
|
|
12071
|
-
pointerLens.
|
|
12156
|
+
pointerLens.pointerPos = event.canvasPos;
|
|
12157
|
+
pointerLens.snappedCanvasPos = event.snappedCanvasPos || event.canvasPos;
|
|
12072
12158
|
pointerLens.snapped = false;
|
|
12073
12159
|
}
|
|
12074
12160
|
this.markerDiv.style.marginLeft = `-100px`;
|
|
@@ -14708,13 +14794,14 @@ class PickResult {
|
|
|
14708
14794
|
*/
|
|
14709
14795
|
this.snappedToVertex = false;
|
|
14710
14796
|
|
|
14711
|
-
this._canvasPos = new Int16Array([0, 0]);
|
|
14712
14797
|
this._origin = new Float64Array([0, 0, 0]);
|
|
14713
14798
|
this._direction = new Float64Array([0, 0, 0]);
|
|
14714
14799
|
this._indices = new Int32Array(3);
|
|
14715
14800
|
this._localPos = new Float64Array([0, 0, 0]);
|
|
14716
14801
|
this._worldPos = new Float64Array([0, 0, 0]);
|
|
14717
14802
|
this._viewPos = new Float64Array([0, 0, 0]);
|
|
14803
|
+
this._canvasPos = new Int16Array([0, 0]);
|
|
14804
|
+
this._snappedCanvasPos = new Int16Array([0, 0]);
|
|
14718
14805
|
this._bary = new Float64Array([0, 0, 0]);
|
|
14719
14806
|
this._worldNormal = new Float64Array([0, 0, 0]);
|
|
14720
14807
|
this._uv = new Float64Array([0, 0]);
|
|
@@ -14723,7 +14810,7 @@ class PickResult {
|
|
|
14723
14810
|
}
|
|
14724
14811
|
|
|
14725
14812
|
/**
|
|
14726
|
-
* Canvas coordinates
|
|
14813
|
+
* Canvas pick coordinates.
|
|
14727
14814
|
* @property canvasPos
|
|
14728
14815
|
* @type {Number[]}
|
|
14729
14816
|
*/
|
|
@@ -14841,6 +14928,29 @@ class PickResult {
|
|
|
14841
14928
|
}
|
|
14842
14929
|
}
|
|
14843
14930
|
|
|
14931
|
+
/**
|
|
14932
|
+
* Canvas cursor coordinates, snapped when snap picking, otherwise same as {@link PickResult#pointerPos}.
|
|
14933
|
+
* @property snappedCanvasPos
|
|
14934
|
+
* @type {Number[]}
|
|
14935
|
+
*/
|
|
14936
|
+
get snappedCanvasPos() {
|
|
14937
|
+
return this._gotSnappedCanvasPos ? this._snappedCanvasPos : null;
|
|
14938
|
+
}
|
|
14939
|
+
|
|
14940
|
+
/**
|
|
14941
|
+
* @private
|
|
14942
|
+
* @param value
|
|
14943
|
+
*/
|
|
14944
|
+
set snappedCanvasPos(value) {
|
|
14945
|
+
if (value) {
|
|
14946
|
+
this._snappedCanvasPos[0] = value[0];
|
|
14947
|
+
this._snappedCanvasPos[1] = value[1];
|
|
14948
|
+
this._gotSnappedCanvasPos = true;
|
|
14949
|
+
} else {
|
|
14950
|
+
this._gotSnappedCanvasPos = false;
|
|
14951
|
+
}
|
|
14952
|
+
}
|
|
14953
|
+
|
|
14844
14954
|
/**
|
|
14845
14955
|
* Picked World-space point.
|
|
14846
14956
|
* @property worldPos
|
|
@@ -14969,6 +15079,7 @@ class PickResult {
|
|
|
14969
15079
|
this.primitive = null;
|
|
14970
15080
|
this.pickSurfacePrecision = false;
|
|
14971
15081
|
this._gotCanvasPos = false;
|
|
15082
|
+
this._gotSnappedCanvasPos = false;
|
|
14972
15083
|
this._gotOrigin = false;
|
|
14973
15084
|
this._gotDirection = false;
|
|
14974
15085
|
this._gotIndices = false;
|
|
@@ -18365,254 +18476,258 @@ const Renderer$1 = function (scene, options) {
|
|
|
18365
18476
|
* @param {number} [snapRadiusInPixels=30]
|
|
18366
18477
|
* @param {boolean} [snapToVertex=true]
|
|
18367
18478
|
* @param {boolean} [snapToEdge=true]
|
|
18368
|
-
*
|
|
18369
|
-
* @returns {
|
|
18479
|
+
* @param pickResult
|
|
18480
|
+
* @returns {PickResult}
|
|
18370
18481
|
*/
|
|
18371
|
-
this.snapPick = function (
|
|
18482
|
+
this.snapPick = (function () {
|
|
18372
18483
|
|
|
18373
|
-
|
|
18374
|
-
return this.pick({canvasPos, pickSurface: true});
|
|
18375
|
-
}
|
|
18484
|
+
const _pickResult = new PickResult();
|
|
18376
18485
|
|
|
18377
|
-
|
|
18486
|
+
return function (canvasPos, snapRadiusInPixels, snapToVertex, snapToEdge, pickResult = _pickResult) {
|
|
18378
18487
|
|
|
18379
|
-
|
|
18380
|
-
|
|
18381
|
-
|
|
18382
|
-
frameCtx.pickZNear = scene.camera.project.near;
|
|
18383
|
-
frameCtx.pickZFar = scene.camera.project.far;
|
|
18384
|
-
|
|
18385
|
-
const vertexPickBuffer = renderBufferManager.getRenderBuffer("uniquePickColors-aabs", {
|
|
18386
|
-
depthTexture: true,
|
|
18387
|
-
size: [
|
|
18388
|
-
2 * snapRadiusInPixels + 1,
|
|
18389
|
-
2 * snapRadiusInPixels + 1,
|
|
18390
|
-
]
|
|
18391
|
-
});
|
|
18488
|
+
if (!snapToVertex && !snapToEdge) {
|
|
18489
|
+
return this.pick({canvasPos, pickSurface: true});
|
|
18490
|
+
}
|
|
18392
18491
|
|
|
18393
|
-
|
|
18394
|
-
getClipPosX(canvasPos[0] * resolutionScale, gl.drawingBufferWidth),
|
|
18395
|
-
getClipPosY(canvasPos[1] * resolutionScale, gl.drawingBufferHeight),
|
|
18396
|
-
];
|
|
18492
|
+
const resolutionScale = scene.canvas.resolutionScale;
|
|
18397
18493
|
|
|
18398
|
-
|
|
18399
|
-
|
|
18400
|
-
|
|
18401
|
-
|
|
18494
|
+
frameCtx.reset();
|
|
18495
|
+
frameCtx.backfaces = true;
|
|
18496
|
+
frameCtx.frontface = true; // "ccw"
|
|
18497
|
+
frameCtx.pickZNear = scene.camera.project.near;
|
|
18498
|
+
frameCtx.pickZFar = scene.camera.project.far;
|
|
18402
18499
|
|
|
18403
|
-
|
|
18500
|
+
snapRadiusInPixels = snapRadiusInPixels || 30;
|
|
18404
18501
|
|
|
18405
|
-
|
|
18406
|
-
|
|
18407
|
-
|
|
18408
|
-
|
|
18409
|
-
|
|
18410
|
-
|
|
18411
|
-
|
|
18412
|
-
gl.depthFunc(gl.LEQUAL);
|
|
18413
|
-
gl.clear(gl.DEPTH_BUFFER_BIT);
|
|
18414
|
-
gl.clearBufferiv(gl.COLOR, 0, new Int32Array([0, 0, 0, 0]));
|
|
18415
|
-
gl.clearBufferiv(gl.COLOR, 1, new Int32Array([0, 0, 0, 0]));
|
|
18416
|
-
gl.clearBufferuiv(gl.COLOR, 2, new Uint32Array([0, 0, 0, 0]));
|
|
18502
|
+
const vertexPickBuffer = renderBufferManager.getRenderBuffer("uniquePickColors-aabs", {
|
|
18503
|
+
depthTexture: true,
|
|
18504
|
+
size: [
|
|
18505
|
+
2 * snapRadiusInPixels + 1,
|
|
18506
|
+
2 * snapRadiusInPixels + 1,
|
|
18507
|
+
]
|
|
18508
|
+
});
|
|
18417
18509
|
|
|
18418
|
-
|
|
18419
|
-
|
|
18420
|
-
|
|
18510
|
+
frameCtx.snapVectorA = [
|
|
18511
|
+
getClipPosX(canvasPos[0] * resolutionScale, gl.drawingBufferWidth),
|
|
18512
|
+
getClipPosY(canvasPos[1] * resolutionScale, gl.drawingBufferHeight),
|
|
18513
|
+
];
|
|
18421
18514
|
|
|
18422
|
-
|
|
18423
|
-
|
|
18515
|
+
frameCtx.snapInvVectorAB = [
|
|
18516
|
+
gl.drawingBufferWidth / (2 * snapRadiusInPixels),
|
|
18517
|
+
gl.drawingBufferHeight / (2 * snapRadiusInPixels),
|
|
18518
|
+
];
|
|
18424
18519
|
|
|
18425
|
-
|
|
18426
|
-
|
|
18427
|
-
|
|
18428
|
-
|
|
18429
|
-
|
|
18430
|
-
|
|
18431
|
-
|
|
18520
|
+
// Bind and clear the snap render target
|
|
18521
|
+
|
|
18522
|
+
vertexPickBuffer.bind(gl.RGBA32I, gl.RGBA32I, gl.RGBA8UI);
|
|
18523
|
+
gl.viewport(0, 0, vertexPickBuffer.size[0], vertexPickBuffer.size[1]);
|
|
18524
|
+
gl.enable(gl.DEPTH_TEST);
|
|
18525
|
+
gl.frontFace(gl.CCW);
|
|
18526
|
+
gl.disable(gl.CULL_FACE);
|
|
18527
|
+
gl.depthMask(true);
|
|
18528
|
+
gl.disable(gl.BLEND);
|
|
18529
|
+
gl.depthFunc(gl.LEQUAL);
|
|
18530
|
+
gl.clear(gl.DEPTH_BUFFER_BIT);
|
|
18531
|
+
gl.clearBufferiv(gl.COLOR, 0, new Int32Array([0, 0, 0, 0]));
|
|
18532
|
+
gl.clearBufferiv(gl.COLOR, 1, new Int32Array([0, 0, 0, 0]));
|
|
18533
|
+
gl.clearBufferuiv(gl.COLOR, 2, new Uint32Array([0, 0, 0, 0]));
|
|
18534
|
+
|
|
18535
|
+
//////////////////////////////////
|
|
18536
|
+
// Set view and proj mats for VBO renderers
|
|
18537
|
+
///////////////////////////////////////
|
|
18538
|
+
|
|
18539
|
+
const pickViewMatrix = scene.camera.viewMatrix;
|
|
18540
|
+
const pickProjMatrix = scene.camera.projMatrix;
|
|
18541
|
+
|
|
18542
|
+
for (let type in drawableTypeInfo) {
|
|
18543
|
+
if (drawableTypeInfo.hasOwnProperty(type)) {
|
|
18544
|
+
const drawableList = drawableTypeInfo[type].drawableList;
|
|
18545
|
+
for (let i = 0, len = drawableList.length; i < len; i++) {
|
|
18546
|
+
const drawable = drawableList[i];
|
|
18547
|
+
if (drawable.setPickMatrices) { // Eg. SceneModel, which needs pre-loading into texture
|
|
18548
|
+
drawable.setPickMatrices(pickViewMatrix, pickProjMatrix);
|
|
18549
|
+
}
|
|
18432
18550
|
}
|
|
18433
18551
|
}
|
|
18434
18552
|
}
|
|
18435
|
-
}
|
|
18436
18553
|
|
|
18437
|
-
|
|
18438
|
-
|
|
18439
|
-
|
|
18554
|
+
// a) init z-buffer
|
|
18555
|
+
gl.drawBuffers([gl.COLOR_ATTACHMENT0, gl.COLOR_ATTACHMENT1, gl.COLOR_ATTACHMENT2]);
|
|
18556
|
+
const layerParamsSurface = snapInitDepthBuf(frameCtx);
|
|
18440
18557
|
|
|
18441
|
-
|
|
18442
|
-
|
|
18443
|
-
|
|
18558
|
+
// b) snap-pick
|
|
18559
|
+
const layerParamsSnap = [];
|
|
18560
|
+
frameCtx.snapPickLayerParams = layerParamsSnap;
|
|
18444
18561
|
|
|
18445
|
-
|
|
18446
|
-
|
|
18562
|
+
gl.depthMask(false);
|
|
18563
|
+
gl.drawBuffers([gl.COLOR_ATTACHMENT0]);
|
|
18447
18564
|
|
|
18448
|
-
|
|
18449
|
-
|
|
18450
|
-
|
|
18565
|
+
if (snapToVertex && snapToEdge) {
|
|
18566
|
+
frameCtx.snapMode = "edge";
|
|
18567
|
+
snapPickDrawSnapDepths(frameCtx);
|
|
18451
18568
|
|
|
18452
|
-
|
|
18453
|
-
|
|
18569
|
+
frameCtx.snapMode = "vertex";
|
|
18570
|
+
frameCtx.snapPickLayerNumber++;
|
|
18454
18571
|
|
|
18455
|
-
|
|
18456
|
-
|
|
18457
|
-
|
|
18572
|
+
snapPickDrawSnapDepths(frameCtx);
|
|
18573
|
+
} else {
|
|
18574
|
+
frameCtx.snapMode = snapToVertex ? "vertex" : "edge";
|
|
18458
18575
|
|
|
18459
|
-
|
|
18460
|
-
|
|
18576
|
+
snapPickDrawSnapDepths(frameCtx);
|
|
18577
|
+
}
|
|
18461
18578
|
|
|
18462
|
-
|
|
18579
|
+
gl.depthMask(true);
|
|
18463
18580
|
|
|
18464
|
-
|
|
18581
|
+
// Read and decode the snapped coordinates
|
|
18465
18582
|
|
|
18466
|
-
|
|
18467
|
-
|
|
18468
|
-
|
|
18583
|
+
const snapPickResultArray = vertexPickBuffer.readArray(gl.RGBA_INTEGER, gl.INT, Int32Array, 4);
|
|
18584
|
+
const snapPickNormalResultArray = vertexPickBuffer.readArray(gl.RGBA_INTEGER, gl.INT, Int32Array, 4, 1);
|
|
18585
|
+
const snapPickIdResultArray = vertexPickBuffer.readArray(gl.RGBA_INTEGER, gl.UNSIGNED_INT, Uint32Array, 4, 2);
|
|
18469
18586
|
|
|
18470
|
-
|
|
18587
|
+
vertexPickBuffer.unbind();
|
|
18471
18588
|
|
|
18472
|
-
|
|
18589
|
+
// result 1) regular hi-precision world position
|
|
18473
18590
|
|
|
18474
|
-
|
|
18475
|
-
let worldNormal = null;
|
|
18591
|
+
let worldPos = null;
|
|
18476
18592
|
|
|
18477
|
-
|
|
18478
|
-
|
|
18479
|
-
|
|
18480
|
-
|
|
18481
|
-
|
|
18482
|
-
|
|
18593
|
+
const middleX = snapRadiusInPixels;
|
|
18594
|
+
const middleY = snapRadiusInPixels;
|
|
18595
|
+
const middleIndex = (middleX * 4) + (middleY * vertexPickBuffer.size[0] * 4);
|
|
18596
|
+
const pickResultMiddleXY = snapPickResultArray.slice(middleIndex, middleIndex + 4);
|
|
18597
|
+
const pickNormalResultMiddleXY = snapPickNormalResultArray.slice(middleIndex, middleIndex + 4);
|
|
18598
|
+
const pickPickableResultMiddleXY = snapPickIdResultArray.slice(middleIndex, middleIndex + 4);
|
|
18483
18599
|
|
|
18484
|
-
|
|
18485
|
-
|
|
18486
|
-
|
|
18487
|
-
|
|
18488
|
-
|
|
18489
|
-
|
|
18490
|
-
|
|
18491
|
-
|
|
18492
|
-
|
|
18493
|
-
|
|
18494
|
-
|
|
18495
|
-
|
|
18496
|
-
|
|
18497
|
-
|
|
18498
|
-
|
|
18499
|
-
|
|
18500
|
-
|
|
18501
|
-
|
|
18502
|
-
|
|
18503
|
-
|
|
18504
|
-
|
|
18505
|
-
|
|
18506
|
-
|
|
18507
|
-
|
|
18508
|
-
|
|
18509
|
-
|
|
18510
|
-
|
|
18511
|
-
|
|
18512
|
-
|
|
18513
|
-
|
|
18514
|
-
|
|
18515
|
-
|
|
18516
|
-
|
|
18517
|
-
|
|
18518
|
-
|
|
18519
|
-
|
|
18520
|
-
|
|
18521
|
-
|
|
18522
|
-
|
|
18523
|
-
|
|
18524
|
-
|
|
18525
|
-
|
|
18526
|
-
|
|
18527
|
-
|
|
18528
|
-
|
|
18529
|
-
|
|
18530
|
-
|
|
18531
|
-
|
|
18532
|
-
|
|
18533
|
-
|
|
18534
|
-
|
|
18535
|
-
|
|
18536
|
-
|
|
18537
|
-
|
|
18538
|
-
|
|
18539
|
-
|
|
18540
|
-
|
|
18541
|
-
|
|
18542
|
-
|
|
18600
|
+
if (pickResultMiddleXY[3] !== 0) {
|
|
18601
|
+
const pickedLayerParmasSurface = layerParamsSurface[Math.abs(pickResultMiddleXY[3]) % layerParamsSurface.length];
|
|
18602
|
+
const origin = pickedLayerParmasSurface.origin;
|
|
18603
|
+
const scale = pickedLayerParmasSurface.coordinateScale;
|
|
18604
|
+
worldPos = [
|
|
18605
|
+
pickResultMiddleXY[0] * scale[0] + origin[0],
|
|
18606
|
+
pickResultMiddleXY[1] * scale[1] + origin[1],
|
|
18607
|
+
pickResultMiddleXY[2] * scale[2] + origin[2],
|
|
18608
|
+
];
|
|
18609
|
+
math.normalizeVec3([
|
|
18610
|
+
pickNormalResultMiddleXY[0] / math.MAX_INT,
|
|
18611
|
+
pickNormalResultMiddleXY[1] / math.MAX_INT,
|
|
18612
|
+
pickNormalResultMiddleXY[2] / math.MAX_INT,
|
|
18613
|
+
]);
|
|
18614
|
+
|
|
18615
|
+
const pickID =
|
|
18616
|
+
pickPickableResultMiddleXY[0]
|
|
18617
|
+
+ (pickPickableResultMiddleXY[1] << 8)
|
|
18618
|
+
+ (pickPickableResultMiddleXY[2] << 16)
|
|
18619
|
+
+ (pickPickableResultMiddleXY[3] << 24);
|
|
18620
|
+
|
|
18621
|
+
pickIDs.items[pickID];
|
|
18622
|
+
}
|
|
18623
|
+
|
|
18624
|
+
// result 2) hi-precision snapped (to vertex/edge) world position
|
|
18625
|
+
|
|
18626
|
+
let snapPickResult = [];
|
|
18627
|
+
|
|
18628
|
+
for (let i = 0; i < snapPickResultArray.length; i += 4) {
|
|
18629
|
+
if (snapPickResultArray[i + 3] > 0) {
|
|
18630
|
+
const pixelNumber = Math.floor(i / 4);
|
|
18631
|
+
const w = vertexPickBuffer.size[0];
|
|
18632
|
+
const x = pixelNumber % w - Math.floor(w / 2);
|
|
18633
|
+
const y = Math.floor(pixelNumber / w) - Math.floor(w / 2);
|
|
18634
|
+
const dist = (Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)));
|
|
18635
|
+
snapPickResult.push({
|
|
18636
|
+
x,
|
|
18637
|
+
y,
|
|
18638
|
+
dist,
|
|
18639
|
+
isVertex: snapToVertex && snapToEdge ? snapPickResultArray[i + 3] > layerParamsSnap.length / 2 : snapToVertex,
|
|
18640
|
+
result: [
|
|
18641
|
+
snapPickResultArray[i + 0],
|
|
18642
|
+
snapPickResultArray[i + 1],
|
|
18643
|
+
snapPickResultArray[i + 2],
|
|
18644
|
+
snapPickResultArray[i + 3],
|
|
18645
|
+
],
|
|
18646
|
+
normal: [
|
|
18647
|
+
snapPickNormalResultArray[i + 0],
|
|
18648
|
+
snapPickNormalResultArray[i + 1],
|
|
18649
|
+
snapPickNormalResultArray[i + 2],
|
|
18650
|
+
snapPickNormalResultArray[i + 3],
|
|
18651
|
+
],
|
|
18652
|
+
id: [
|
|
18653
|
+
snapPickIdResultArray[i + 0],
|
|
18654
|
+
snapPickIdResultArray[i + 1],
|
|
18655
|
+
snapPickIdResultArray[i + 2],
|
|
18656
|
+
snapPickIdResultArray[i + 3],
|
|
18657
|
+
]
|
|
18658
|
+
});
|
|
18659
|
+
}
|
|
18543
18660
|
}
|
|
18544
|
-
}
|
|
18545
18661
|
|
|
18546
|
-
|
|
18547
|
-
|
|
18548
|
-
|
|
18549
|
-
|
|
18662
|
+
let snappedWorldPos = null;
|
|
18663
|
+
let snappedWorldNormal = null;
|
|
18664
|
+
let snappedPickable = null;
|
|
18665
|
+
let snapType = null;
|
|
18550
18666
|
|
|
18551
|
-
|
|
18552
|
-
|
|
18553
|
-
|
|
18554
|
-
|
|
18555
|
-
|
|
18556
|
-
|
|
18557
|
-
|
|
18558
|
-
|
|
18559
|
-
|
|
18667
|
+
if (snapPickResult.length > 0) {
|
|
18668
|
+
// vertex snap first, then edge snap
|
|
18669
|
+
snapPickResult.sort((a, b) => {
|
|
18670
|
+
if (a.isVertex !== b.isVertex) {
|
|
18671
|
+
return a.isVertex ? -1 : 1;
|
|
18672
|
+
} else {
|
|
18673
|
+
return a.dist - b.dist;
|
|
18674
|
+
}
|
|
18675
|
+
});
|
|
18560
18676
|
|
|
18561
|
-
|
|
18562
|
-
|
|
18563
|
-
|
|
18564
|
-
|
|
18677
|
+
snapType = snapPickResult[0].isVertex ? "vertex" : "edge";
|
|
18678
|
+
const snapPick = snapPickResult[0].result;
|
|
18679
|
+
const snapPickNormal = snapPickResult[0].normal;
|
|
18680
|
+
const snapPickId = snapPickResult[0].id;
|
|
18565
18681
|
|
|
18566
|
-
|
|
18682
|
+
const pickedLayerParmas = layerParamsSnap[snapPick[3]];
|
|
18567
18683
|
|
|
18568
|
-
|
|
18569
|
-
|
|
18684
|
+
const origin = pickedLayerParmas.origin;
|
|
18685
|
+
const scale = pickedLayerParmas.coordinateScale;
|
|
18570
18686
|
|
|
18571
|
-
|
|
18572
|
-
|
|
18573
|
-
|
|
18574
|
-
|
|
18575
|
-
|
|
18687
|
+
snappedWorldNormal = math.normalizeVec3([
|
|
18688
|
+
snapPickNormal[0] / math.MAX_INT,
|
|
18689
|
+
snapPickNormal[1] / math.MAX_INT,
|
|
18690
|
+
snapPickNormal[2] / math.MAX_INT,
|
|
18691
|
+
]);
|
|
18576
18692
|
|
|
18577
|
-
|
|
18578
|
-
|
|
18579
|
-
|
|
18580
|
-
|
|
18581
|
-
|
|
18693
|
+
snappedWorldPos = [
|
|
18694
|
+
snapPick[0] * scale[0] + origin[0],
|
|
18695
|
+
snapPick[1] * scale[1] + origin[1],
|
|
18696
|
+
snapPick[2] * scale[2] + origin[2],
|
|
18697
|
+
];
|
|
18582
18698
|
|
|
18583
|
-
|
|
18699
|
+
snappedPickable = pickIDs.items[
|
|
18584
18700
|
snapPickId[0]
|
|
18585
18701
|
+ (snapPickId[1] << 8)
|
|
18586
18702
|
+ (snapPickId[2] << 16)
|
|
18587
18703
|
+ (snapPickId[3] << 24)
|
|
18588
|
-
|
|
18589
|
-
|
|
18704
|
+
];
|
|
18705
|
+
}
|
|
18590
18706
|
|
|
18591
|
-
|
|
18592
|
-
|
|
18593
|
-
|
|
18707
|
+
if (null === worldPos && null == snappedWorldPos) { // If neither regular pick or snap pick, return null
|
|
18708
|
+
return null;
|
|
18709
|
+
}
|
|
18594
18710
|
|
|
18595
|
-
|
|
18711
|
+
let snappedCanvasPos = null;
|
|
18596
18712
|
|
|
18597
|
-
|
|
18598
|
-
|
|
18599
|
-
|
|
18713
|
+
if (null !== snappedWorldPos) {
|
|
18714
|
+
snappedCanvasPos = scene.camera.projectWorldPos(snappedWorldPos);
|
|
18715
|
+
}
|
|
18600
18716
|
|
|
18601
|
-
|
|
18717
|
+
const snappedEntity = (snappedPickable && snappedPickable.delegatePickedEntity) ? snappedPickable.delegatePickedEntity() : snappedPickable;
|
|
18602
18718
|
|
|
18603
|
-
|
|
18604
|
-
snapType
|
|
18605
|
-
snappedToVertex
|
|
18606
|
-
|
|
18607
|
-
|
|
18608
|
-
|
|
18609
|
-
|
|
18610
|
-
|
|
18611
|
-
|
|
18612
|
-
|
|
18613
|
-
entity: snappedEntity
|
|
18719
|
+
pickResult.reset();
|
|
18720
|
+
pickResult.snappedToEdge = (snapType === "edge");
|
|
18721
|
+
pickResult.snappedToVertex = (snapType === "vertex");
|
|
18722
|
+
pickResult.worldPos = snappedWorldPos;
|
|
18723
|
+
pickResult.worldNormal = snappedWorldNormal;
|
|
18724
|
+
pickResult.entity = snappedEntity;
|
|
18725
|
+
pickResult.canvasPos = canvasPos;
|
|
18726
|
+
pickResult.snappedCanvasPos = snappedCanvasPos || canvasPos;
|
|
18727
|
+
|
|
18728
|
+
return pickResult;
|
|
18614
18729
|
};
|
|
18615
|
-
};
|
|
18730
|
+
})();
|
|
18616
18731
|
|
|
18617
18732
|
function unpackDepth(depthZ) {
|
|
18618
18733
|
const vec = [depthZ[0] / 256.0, depthZ[1] / 256.0, depthZ[2] / 256.0, depthZ[3] / 256.0];
|
|
@@ -20018,23 +20133,31 @@ class Input extends Component {
|
|
|
20018
20133
|
}
|
|
20019
20134
|
});
|
|
20020
20135
|
|
|
20136
|
+
const tickifedMouseMoveFn = this.scene.tickify(
|
|
20137
|
+
() => this.fire("mousemove", this.mouseCanvasPos, true)
|
|
20138
|
+
);
|
|
20139
|
+
|
|
20021
20140
|
this.element.addEventListener("mousemove", this._mouseMoveListener = (e) => {
|
|
20022
20141
|
if (!this.enabled) {
|
|
20023
20142
|
return;
|
|
20024
20143
|
}
|
|
20025
20144
|
this._getMouseCanvasPos(e);
|
|
20026
|
-
|
|
20145
|
+
tickifedMouseMoveFn();
|
|
20027
20146
|
if (this.mouseover) {
|
|
20028
20147
|
e.preventDefault();
|
|
20029
20148
|
}
|
|
20030
20149
|
});
|
|
20031
20150
|
|
|
20151
|
+
const tickifiedMouseWheelFn = this.scene.tickify(
|
|
20152
|
+
(delta) => { this.fire("mousewheel", delta, true); }
|
|
20153
|
+
);
|
|
20154
|
+
|
|
20032
20155
|
this.element.addEventListener("wheel", this._mouseWheelListener = (e, d) => {
|
|
20033
20156
|
if (!this.enabled) {
|
|
20034
20157
|
return;
|
|
20035
20158
|
}
|
|
20036
20159
|
const delta = Math.max(-1, Math.min(1, -e.deltaY * 40));
|
|
20037
|
-
|
|
20160
|
+
tickifiedMouseWheelFn(delta);
|
|
20038
20161
|
}, {passive: true});
|
|
20039
20162
|
|
|
20040
20163
|
// mouseclicked
|
|
@@ -27858,6 +27981,11 @@ class Scene extends Component {
|
|
|
27858
27981
|
throw "Mandatory config expected: valid canvasId or canvasElement";
|
|
27859
27982
|
}
|
|
27860
27983
|
|
|
27984
|
+
/**
|
|
27985
|
+
* @type {{[key: string]: {wrapperFunc: Function, tickSubId: string}}}
|
|
27986
|
+
*/
|
|
27987
|
+
this._tickifiedFunctions = {};
|
|
27988
|
+
|
|
27861
27989
|
const transparent = (!!cfg.transparent);
|
|
27862
27990
|
const alphaDepthMask = (!!cfg.alphaDepthMask);
|
|
27863
27991
|
|
|
@@ -29607,6 +29735,9 @@ class Scene extends Component {
|
|
|
29607
29735
|
* @param {Number[]} [params.matrix] 4x4 transformation matrix to define the World-space ray origin and direction, as an alternative to ````origin```` and ````direction````.
|
|
29608
29736
|
* @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.
|
|
29609
29737
|
* @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.
|
|
29738
|
+
* @param {Number} [params.snapRadius=30] The snap radius, in canvas pixels
|
|
29739
|
+
* @param {boolean} [params.snapToVertex=true] Whether to snap to vertex.
|
|
29740
|
+
* @param {boolean} [params.snapToEdge=true] Whether to snap to edge.
|
|
29610
29741
|
* @param {PickResult} [pickResult] Holds the results of the pick attempt. Will use the Scene's singleton PickResult if you don't supply your own.
|
|
29611
29742
|
* @returns {PickResult} Holds results of the pick attempt, returned when an {@link Entity} is picked, else null. See method comments for description.
|
|
29612
29743
|
*/
|
|
@@ -29641,14 +29772,25 @@ class Scene extends Component {
|
|
|
29641
29772
|
this._needRecompile = false;
|
|
29642
29773
|
}
|
|
29643
29774
|
|
|
29644
|
-
|
|
29775
|
+
if (params.snapToEdge || params.snapToVertex) {
|
|
29776
|
+
pickResult = this._renderer.snapPick(
|
|
29777
|
+
params.canvasPos,
|
|
29778
|
+
params.snapRadius || 30,
|
|
29779
|
+
params.snapToVertex,
|
|
29780
|
+
params.snapToEdge,
|
|
29781
|
+
pickResult
|
|
29782
|
+
);
|
|
29783
|
+
} else {
|
|
29784
|
+
pickResult = this._renderer.pick(params, pickResult);
|
|
29785
|
+
}
|
|
29645
29786
|
|
|
29646
29787
|
if (pickResult) {
|
|
29647
29788
|
if (pickResult.entity && pickResult.entity.fire) {
|
|
29648
|
-
pickResult.entity.fire("picked", pickResult); // TODO:
|
|
29789
|
+
pickResult.entity.fire("picked", pickResult); // TODO: SceneModelEntity doesn't fire events
|
|
29649
29790
|
}
|
|
29650
|
-
return pickResult;
|
|
29651
29791
|
}
|
|
29792
|
+
|
|
29793
|
+
return pickResult;
|
|
29652
29794
|
}
|
|
29653
29795
|
|
|
29654
29796
|
/**
|
|
@@ -29657,8 +29799,13 @@ class Scene extends Component {
|
|
|
29657
29799
|
* @param {Number} [params.snapRadius=30] The snap radius, in canvas pixels
|
|
29658
29800
|
* @param {boolean} [params.snapToVertex=true] Whether to snap to vertex.
|
|
29659
29801
|
* @param {boolean} [params.snapToEdge=true] Whether to snap to edge.
|
|
29802
|
+
* @deprecated
|
|
29660
29803
|
*/
|
|
29661
29804
|
snapPick(params) {
|
|
29805
|
+
if (undefined === this._warnSnapPickDeprecated) {
|
|
29806
|
+
this._warnSnapPickDeprecated = true;
|
|
29807
|
+
this.warn("Scene.snapPick() is deprecated since v2.4.2 - use Scene.pick() instead");
|
|
29808
|
+
}
|
|
29662
29809
|
return this._renderer.snapPick(
|
|
29663
29810
|
params.canvasPos,
|
|
29664
29811
|
params.snapRadius || 30,
|
|
@@ -30020,6 +30167,63 @@ class Scene extends Component {
|
|
|
30020
30167
|
return changed;
|
|
30021
30168
|
}
|
|
30022
30169
|
|
|
30170
|
+
/**
|
|
30171
|
+
* This method will "tickify" the provided `cb` function.
|
|
30172
|
+
*
|
|
30173
|
+
* This means, the function will be wrapped so:
|
|
30174
|
+
*
|
|
30175
|
+
* - it runs time-aligned to scene ticks
|
|
30176
|
+
* - it runs maximum once per scene-tick
|
|
30177
|
+
*
|
|
30178
|
+
* @param {Function} cb The function to tickify
|
|
30179
|
+
* @returns {Function)}
|
|
30180
|
+
*/
|
|
30181
|
+
tickify(cb) {
|
|
30182
|
+
const cbString = cb.toString();
|
|
30183
|
+
|
|
30184
|
+
/**
|
|
30185
|
+
* Check if the function is already tickified, and if so return the cached one.
|
|
30186
|
+
*/
|
|
30187
|
+
if (cbString in this._tickifiedFunctions) {
|
|
30188
|
+
return this._tickifiedFunctions[cbString].wrapperFunc;
|
|
30189
|
+
}
|
|
30190
|
+
|
|
30191
|
+
let alreadyRun = 0;
|
|
30192
|
+
let needToRun = 0;
|
|
30193
|
+
|
|
30194
|
+
let lastArgs;
|
|
30195
|
+
|
|
30196
|
+
/**
|
|
30197
|
+
* The provided `cb` function is replaced with a "set-dirty" function
|
|
30198
|
+
*
|
|
30199
|
+
* @type {Function}
|
|
30200
|
+
*/
|
|
30201
|
+
const wrapperFunc = function (...args) {
|
|
30202
|
+
lastArgs = args;
|
|
30203
|
+
needToRun++;
|
|
30204
|
+
};
|
|
30205
|
+
|
|
30206
|
+
/**
|
|
30207
|
+
* An each scene tick, if the "dirty-flag" is set, run the `cb` function.
|
|
30208
|
+
*
|
|
30209
|
+
* This will make it run time-aligned to the scene tick.
|
|
30210
|
+
*/
|
|
30211
|
+
const tickSubId = this.on("tick", () => {
|
|
30212
|
+
const tmp = needToRun;
|
|
30213
|
+
if (tmp > alreadyRun) {
|
|
30214
|
+
alreadyRun = tmp;
|
|
30215
|
+
cb(...lastArgs);
|
|
30216
|
+
}
|
|
30217
|
+
});
|
|
30218
|
+
|
|
30219
|
+
/**
|
|
30220
|
+
* And, store the list of subscribers.
|
|
30221
|
+
*/
|
|
30222
|
+
this._tickifiedFunctions[cbString] = { tickSubId, wrapperFunc };
|
|
30223
|
+
|
|
30224
|
+
return wrapperFunc;
|
|
30225
|
+
}
|
|
30226
|
+
|
|
30023
30227
|
/**
|
|
30024
30228
|
* Destroys this Scene.
|
|
30025
30229
|
*/
|
|
@@ -49774,18 +49978,19 @@ class DistanceMeasurementsMouseControl extends DistanceMeasurementsControl {
|
|
|
49774
49978
|
this._snapping
|
|
49775
49979
|
? "hoverSnapOrSurface"
|
|
49776
49980
|
: "hoverSurface", event => {
|
|
49981
|
+
const canvasPos = event.snappedCanvasPos || event.canvasPos;
|
|
49777
49982
|
mouseHovering = true;
|
|
49778
49983
|
pointerWorldPos.set(event.worldPos);
|
|
49779
49984
|
pointerCanvasPos.set(event.canvasPos);
|
|
49780
49985
|
if (this._mouseState === MOUSE_FIRST_CLICK_EXPECTED) {
|
|
49781
|
-
this._markerDiv.style.marginLeft = `${
|
|
49782
|
-
this._markerDiv.style.marginTop = `${
|
|
49986
|
+
this._markerDiv.style.marginLeft = `${canvasPos[0] - 5}px`;
|
|
49987
|
+
this._markerDiv.style.marginTop = `${canvasPos[1] - 5}px`;
|
|
49783
49988
|
this._markerDiv.style.background = "pink";
|
|
49784
49989
|
if (event.snappedToVertex || event.snappedToEdge) {
|
|
49785
49990
|
if (this.pointerLens) {
|
|
49786
49991
|
this.pointerLens.visible = true;
|
|
49787
|
-
this.pointerLens.
|
|
49788
|
-
this.pointerLens.
|
|
49992
|
+
this.pointerLens.canvasPos = event.canvasPos;
|
|
49993
|
+
this.pointerLens.snappedCanvasPos = event.snappedCanvasPos || event.canvasPos;
|
|
49789
49994
|
this.pointerLens.snapped = true;
|
|
49790
49995
|
}
|
|
49791
49996
|
this._markerDiv.style.background = "greenyellow";
|
|
@@ -49793,8 +49998,8 @@ class DistanceMeasurementsMouseControl extends DistanceMeasurementsControl {
|
|
|
49793
49998
|
} else {
|
|
49794
49999
|
if (this.pointerLens) {
|
|
49795
50000
|
this.pointerLens.visible = true;
|
|
49796
|
-
this.pointerLens.
|
|
49797
|
-
this.pointerLens.
|
|
50001
|
+
this.pointerLens.canvasPos = event.canvasPos;
|
|
50002
|
+
this.pointerLens.snappedCanvasPos = event.canvasPos;
|
|
49798
50003
|
this.pointerLens.snapped = false;
|
|
49799
50004
|
}
|
|
49800
50005
|
this._markerDiv.style.background = "pink";
|
|
@@ -49876,8 +50081,8 @@ class DistanceMeasurementsMouseControl extends DistanceMeasurementsControl {
|
|
|
49876
50081
|
: "hoverOff", event => {
|
|
49877
50082
|
if (this.pointerLens) {
|
|
49878
50083
|
this.pointerLens.visible = true;
|
|
49879
|
-
this.pointerLens.
|
|
49880
|
-
this.pointerLens.
|
|
50084
|
+
this.pointerLens.canvasPos = event.canvasPos;
|
|
50085
|
+
this.pointerLens.snappedCanvasPos = event.snappedCanvasPos || event.canvasPos;
|
|
49881
50086
|
}
|
|
49882
50087
|
mouseHovering = false;
|
|
49883
50088
|
this._markerDiv.style.marginLeft = `-100px`;
|
|
@@ -87287,29 +87492,12 @@ class PickController {
|
|
|
87287
87492
|
this._lastPickedEntityId = null;
|
|
87288
87493
|
|
|
87289
87494
|
this._needFireEvents = 0;
|
|
87290
|
-
|
|
87291
|
-
this._needToUpdate = false;
|
|
87292
|
-
|
|
87293
|
-
this._tickSub = this._scene.on("tick", () => {
|
|
87294
|
-
this.runUpdate();
|
|
87295
|
-
});
|
|
87296
|
-
}
|
|
87297
|
-
|
|
87298
|
-
update() {
|
|
87299
|
-
this._needToUpdate = true;
|
|
87300
87495
|
}
|
|
87301
87496
|
|
|
87302
87497
|
/**
|
|
87303
87498
|
* Immediately attempts a pick, if scheduled.
|
|
87304
87499
|
*/
|
|
87305
|
-
|
|
87306
|
-
|
|
87307
|
-
if (!this._needToUpdate) {
|
|
87308
|
-
return;
|
|
87309
|
-
}
|
|
87310
|
-
|
|
87311
|
-
this._needToUpdate = false;
|
|
87312
|
-
|
|
87500
|
+
update() {
|
|
87313
87501
|
if (!this._configs.pointerEnabled) {
|
|
87314
87502
|
return;
|
|
87315
87503
|
}
|
|
@@ -87326,13 +87514,13 @@ class PickController {
|
|
|
87326
87514
|
const hasHoverSurfaceSubs = this._cameraControl.hasSubs("hoverSurface");
|
|
87327
87515
|
|
|
87328
87516
|
if (this.scheduleSnapOrPick) {
|
|
87329
|
-
const snapPickResult = this._scene.
|
|
87517
|
+
const snapPickResult = this._scene.pick({
|
|
87330
87518
|
canvasPos: this.pickCursorPos,
|
|
87331
87519
|
snapRadius: this._configs.snapRadius,
|
|
87332
87520
|
snapToVertex: this._configs.snapToVertex,
|
|
87333
87521
|
snapToEdge: this._configs.snapToEdge,
|
|
87334
87522
|
});
|
|
87335
|
-
if (snapPickResult && snapPickResult.
|
|
87523
|
+
if (snapPickResult && (snapPickResult.snappedToEdge || snapPickResult.snappedToVertex)) {
|
|
87336
87524
|
this.snapPickResult = snapPickResult;
|
|
87337
87525
|
this.snappedOrPicked = true;
|
|
87338
87526
|
this._needFireEvents++;
|
|
@@ -87414,14 +87602,14 @@ class PickController {
|
|
|
87414
87602
|
|
|
87415
87603
|
fireEvents() {
|
|
87416
87604
|
|
|
87417
|
-
if (this._needFireEvents
|
|
87605
|
+
if (this._needFireEvents === 0) {
|
|
87418
87606
|
return;
|
|
87419
87607
|
}
|
|
87420
87608
|
|
|
87421
87609
|
if (this.hoveredSnappedOrSurfaceOff) {
|
|
87422
87610
|
this._cameraControl.fire("hoverSnapOrSurfaceOff", {
|
|
87423
87611
|
canvasPos: this.pickCursorPos,
|
|
87424
|
-
|
|
87612
|
+
pointerPos : this.pickCursorPos
|
|
87425
87613
|
}, true);
|
|
87426
87614
|
}
|
|
87427
87615
|
|
|
@@ -87430,9 +87618,9 @@ class PickController {
|
|
|
87430
87618
|
const pickResult = new PickResult();
|
|
87431
87619
|
pickResult.snappedToVertex = this.snapPickResult.snappedToVertex;
|
|
87432
87620
|
pickResult.snappedToEdge = this.snapPickResult.snappedToEdge;
|
|
87433
|
-
pickResult.worldPos = this.snapPickResult.
|
|
87434
|
-
pickResult.
|
|
87435
|
-
pickResult.
|
|
87621
|
+
pickResult.worldPos = this.snapPickResult.worldPos;
|
|
87622
|
+
pickResult.canvasPos = this.pickCursorPos;
|
|
87623
|
+
pickResult.snappedCanvasPos = this.snapPickResult.snappedCanvasPos;
|
|
87436
87624
|
this._cameraControl.fire("hoverSnapOrSurface", pickResult, true);
|
|
87437
87625
|
this.snapPickResult = null;
|
|
87438
87626
|
} else {
|
|
@@ -87484,10 +87672,6 @@ class PickController {
|
|
|
87484
87672
|
|
|
87485
87673
|
this._needFireEvents = 0;
|
|
87486
87674
|
}
|
|
87487
|
-
|
|
87488
|
-
destroy() {
|
|
87489
|
-
this._scene.off(this._tickSub);
|
|
87490
|
-
}
|
|
87491
87675
|
}
|
|
87492
87676
|
|
|
87493
87677
|
/**
|
|
@@ -87982,75 +88166,78 @@ class MousePickHandler {
|
|
|
87982
88166
|
}
|
|
87983
88167
|
};
|
|
87984
88168
|
|
|
87985
|
-
|
|
88169
|
+
const tickifiedMouseMoveFn = scene.tickify (
|
|
88170
|
+
this._canvasMouseMoveHandler = (e) => {
|
|
88171
|
+
if (!(configs.active && configs.pointerEnabled)) {
|
|
88172
|
+
return;
|
|
88173
|
+
}
|
|
87986
88174
|
|
|
87987
|
-
|
|
87988
|
-
|
|
87989
|
-
|
|
88175
|
+
if (leftDown || rightDown) {
|
|
88176
|
+
return;
|
|
88177
|
+
}
|
|
87990
88178
|
|
|
87991
|
-
|
|
87992
|
-
|
|
87993
|
-
|
|
88179
|
+
const hoverSubs = cameraControl.hasSubs("hover");
|
|
88180
|
+
const hoverEnterSubs = cameraControl.hasSubs("hoverEnter");
|
|
88181
|
+
const hoverOutSubs = cameraControl.hasSubs("hoverOut");
|
|
88182
|
+
const hoverOffSubs = cameraControl.hasSubs("hoverOff");
|
|
88183
|
+
const hoverSurfaceSubs = cameraControl.hasSubs("hoverSurface");
|
|
88184
|
+
const hoverSnapOrSurfaceSubs = cameraControl.hasSubs("hoverSnapOrSurface");
|
|
87994
88185
|
|
|
87995
|
-
|
|
87996
|
-
const hoverEnterSubs = cameraControl.hasSubs("hoverEnter");
|
|
87997
|
-
const hoverOutSubs = cameraControl.hasSubs("hoverOut");
|
|
87998
|
-
const hoverOffSubs = cameraControl.hasSubs("hoverOff");
|
|
87999
|
-
const hoverSurfaceSubs = cameraControl.hasSubs("hoverSurface");
|
|
88000
|
-
const hoverSnapOrSurfaceSubs = cameraControl.hasSubs("hoverSnapOrSurface");
|
|
88186
|
+
if (hoverSubs || hoverEnterSubs || hoverOutSubs || hoverOffSubs || hoverSurfaceSubs || hoverSnapOrSurfaceSubs) {
|
|
88001
88187
|
|
|
88002
|
-
|
|
88188
|
+
pickController.pickCursorPos = states.pointerCanvasPos;
|
|
88189
|
+
pickController.schedulePickEntity = true;
|
|
88190
|
+
pickController.schedulePickSurface = hoverSurfaceSubs;
|
|
88191
|
+
pickController.scheduleSnapOrPick = hoverSnapOrSurfaceSubs;
|
|
88003
88192
|
|
|
88004
|
-
|
|
88005
|
-
pickController.schedulePickEntity = true;
|
|
88006
|
-
pickController.schedulePickSurface = hoverSurfaceSubs;
|
|
88007
|
-
pickController.scheduleSnapOrPick = hoverSnapOrSurfaceSubs;
|
|
88193
|
+
pickController.update();
|
|
88008
88194
|
|
|
88009
|
-
|
|
88195
|
+
if (pickController.pickResult) {
|
|
88010
88196
|
|
|
88011
|
-
|
|
88197
|
+
if (pickController.pickResult.entity) {
|
|
88198
|
+
const pickedEntityId = pickController.pickResult.entity.id;
|
|
88012
88199
|
|
|
88013
|
-
|
|
88014
|
-
const pickedEntityId = pickController.pickResult.entity.id;
|
|
88200
|
+
if (this._lastPickedEntityId !== pickedEntityId) {
|
|
88015
88201
|
|
|
88016
|
-
|
|
88202
|
+
if (this._lastPickedEntityId !== undefined) {
|
|
88017
88203
|
|
|
88018
|
-
|
|
88204
|
+
cameraControl.fire("hoverOut", { // Hovered off an entity
|
|
88205
|
+
entity: scene.objects[this._lastPickedEntityId]
|
|
88206
|
+
}, true);
|
|
88207
|
+
}
|
|
88208
|
+
|
|
88209
|
+
cameraControl.fire("hoverEnter", pickController.pickResult, true); // Hovering over a new entity
|
|
88019
88210
|
|
|
88020
|
-
|
|
88021
|
-
entity: scene.objects[this._lastPickedEntityId]
|
|
88022
|
-
}, true);
|
|
88211
|
+
this._lastPickedEntityId = pickedEntityId;
|
|
88023
88212
|
}
|
|
88213
|
+
}
|
|
88024
88214
|
|
|
88025
|
-
|
|
88215
|
+
cameraControl.fire("hover", pickController.pickResult, true);
|
|
88026
88216
|
|
|
88027
|
-
|
|
88217
|
+
if (pickController.pickResult.worldPos || pickController.pickResult.snappedWorldPos) { // Hovering the surface of an entity
|
|
88218
|
+
cameraControl.fire("hoverSurface", pickController.pickResult, true);
|
|
88028
88219
|
}
|
|
88029
|
-
}
|
|
88030
88220
|
|
|
88031
|
-
|
|
88221
|
+
} else {
|
|
88032
88222
|
|
|
88033
|
-
|
|
88034
|
-
cameraControl.fire("hoverSurface", pickController.pickResult, true);
|
|
88035
|
-
}
|
|
88223
|
+
if (this._lastPickedEntityId !== undefined) {
|
|
88036
88224
|
|
|
88037
|
-
|
|
88225
|
+
cameraControl.fire("hoverOut", { // Hovered off an entity
|
|
88226
|
+
entity: scene.objects[this._lastPickedEntityId]
|
|
88227
|
+
}, true);
|
|
88038
88228
|
|
|
88039
|
-
|
|
88229
|
+
this._lastPickedEntityId = undefined;
|
|
88230
|
+
}
|
|
88040
88231
|
|
|
88041
|
-
cameraControl.fire("
|
|
88042
|
-
|
|
88232
|
+
cameraControl.fire("hoverOff", { // Not hovering on any entity
|
|
88233
|
+
canvasPos: pickController.pickCursorPos
|
|
88043
88234
|
}, true);
|
|
88044
|
-
|
|
88045
|
-
this._lastPickedEntityId = undefined;
|
|
88046
88235
|
}
|
|
88047
|
-
|
|
88048
|
-
cameraControl.fire("hoverOff", { // Not hovering on any entity
|
|
88049
|
-
canvasPos: pickController.pickCursorPos
|
|
88050
|
-
}, true);
|
|
88051
88236
|
}
|
|
88052
88237
|
}
|
|
88053
|
-
|
|
88238
|
+
);
|
|
88239
|
+
|
|
88240
|
+
canvas.addEventListener("mousemove", tickifiedMouseMoveFn);
|
|
88054
88241
|
|
|
88055
88242
|
canvas.addEventListener('mousedown', this._canvasMouseDownHandler = (e) => {
|
|
88056
88243
|
|