@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/package.json
CHANGED
|
@@ -4,6 +4,87 @@ import {Frustum, frustumIntersectsAABB3, setFrustum} from "../../viewer/scene/ma
|
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Picks a {@link Viewer}'s {@link Entity}s with a canvas-space 2D marquee box.
|
|
7
|
+
*
|
|
8
|
+
* [<img src="https://xeokit.github.io/xeokit-sdk/assets/images/MarqueeSelect.gif">](https://xeokit.github.io/xeokit-sdk/examples/picking/#marqueePick_select)
|
|
9
|
+
*
|
|
10
|
+
* * [[Example 1: Select Objects with Marquee](https://xeokit.github.io/xeokit-sdk/examples/picking/#marqueePick_select)]
|
|
11
|
+
* * [[Example 2: View-Fit Objects with Marquee](https://xeokit.github.io/xeokit-sdk/examples/picking/#marqueePick_viewFit)]
|
|
12
|
+
*
|
|
13
|
+
* # Usage
|
|
14
|
+
*
|
|
15
|
+
* In the example below, we
|
|
16
|
+
*
|
|
17
|
+
* 1. Create a {@link Viewer}, arrange the {@link Camera}
|
|
18
|
+
* 2. Use an {@link XKTLoaderPlugin} to load a BIM model,
|
|
19
|
+
* 3. Create a {@link ObjectsKdTree3} to automatically index the `Viewer's` {@link Entity}s for fast spatial lookup,
|
|
20
|
+
* 4. Create a `MarqueePicker` to pick {@link Entity}s in the {@link Viewer}, using the {@link ObjectsKdTree3} to accelerate picking
|
|
21
|
+
* 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.
|
|
22
|
+
*
|
|
23
|
+
* When the {@link MarqueePickerMouseControl} is active:
|
|
24
|
+
*
|
|
25
|
+
* * Long-click, drag and release on the canvas to define a marque box that picks {@link Entity}s.
|
|
26
|
+
* * Drag left-to-right to pick {@link Entity}s that intersect the box.
|
|
27
|
+
* * Drag right-to-left to pick {@link Entity}s that are fully inside the box.
|
|
28
|
+
* * On release, the `MarqueePicker` will fire a "picked" event with IDs of the picked {@link Entity}s, if any.
|
|
29
|
+
* * Handling that event, we mark the {@link Entity}s as selected.
|
|
30
|
+
* * Hold down CTRL to multi-pick.
|
|
31
|
+
*
|
|
32
|
+
* ````javascript
|
|
33
|
+
* import {
|
|
34
|
+
* Viewer,
|
|
35
|
+
* XKTLoaderPlugin,
|
|
36
|
+
* ObjectsKdTree3,
|
|
37
|
+
* MarqueePicker,
|
|
38
|
+
* MarqueePickerMouseControl
|
|
39
|
+
* } from "xeokit-sdk.es.js";
|
|
40
|
+
*
|
|
41
|
+
* // 1
|
|
42
|
+
*
|
|
43
|
+
* const viewer = new Viewer({
|
|
44
|
+
* canvasId: "myCanvas"
|
|
45
|
+
* });
|
|
46
|
+
*
|
|
47
|
+
* viewer.scene.camera.eye = [14.9, 14.3, 5.4];
|
|
48
|
+
* viewer.scene.camera.look = [6.5, 8.3, -4.1];
|
|
49
|
+
* viewer.scene.camera.up = [-0.28, 0.9, -0.3];
|
|
50
|
+
*
|
|
51
|
+
* // 2
|
|
52
|
+
*
|
|
53
|
+
* const xktLoader = new XKTLoaderPlugin(viewer);
|
|
54
|
+
*
|
|
55
|
+
* const sceneModel = xktLoader.load({
|
|
56
|
+
* id: "myModel",
|
|
57
|
+
* src: "../../assets/models/xkt/v8/ifc/HolterTower.ifc.xkt"
|
|
58
|
+
* });
|
|
59
|
+
*
|
|
60
|
+
* // 3
|
|
61
|
+
*
|
|
62
|
+
* const objectsKdTree3 = new ObjectsKdTree3({viewer});
|
|
63
|
+
*
|
|
64
|
+
* // 4
|
|
65
|
+
*
|
|
66
|
+
* const marqueePicker = new MarqueePicker({viewer, objectsKdTree3});
|
|
67
|
+
*
|
|
68
|
+
* // 5
|
|
69
|
+
*
|
|
70
|
+
* const marqueePickerMouseControl = new MarqueePickerMouseControl({marqueePicker});
|
|
71
|
+
*
|
|
72
|
+
* marqueePicker.on("clear", () => {
|
|
73
|
+
* viewer.scene.setObjectsSelected(viewer.scene.selectedObjectIds, false);
|
|
74
|
+
* });
|
|
75
|
+
*
|
|
76
|
+
* marqueePicker.on("picked", (objectIds) => {
|
|
77
|
+
* viewer.scene.setObjectsSelected(objectIds, true);
|
|
78
|
+
* });
|
|
79
|
+
*
|
|
80
|
+
* marqueePickerMouseControl.setActive(true);
|
|
81
|
+
* ````
|
|
82
|
+
*
|
|
83
|
+
* # Design Notes
|
|
84
|
+
*
|
|
85
|
+
* * The {@link ObjectsKdTree3} can be shared with any other components that want to use it to spatially search for {@link Entity}s.
|
|
86
|
+
* * The {@link MarqueePickerMouseControl} can be replaced with other types of controllers (i.e. touch), or used alongside them.
|
|
87
|
+
* * 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*.
|
|
7
88
|
*/
|
|
8
89
|
export class MarqueePicker extends Component {
|
|
9
90
|
|
|
@@ -4,6 +4,8 @@ import {MarqueePicker} from "./MarqueePicker";
|
|
|
4
4
|
/**
|
|
5
5
|
* Controls a {@link MarqueePicker} with mouse input.
|
|
6
6
|
*
|
|
7
|
+
* See {@link MarqueePicker} for usage example.
|
|
8
|
+
*
|
|
7
9
|
* When the MarqueePickerMouseControl is active:
|
|
8
10
|
*
|
|
9
11
|
* * Long-click, drag and release on the canvas to define a marque box that picks {@link Entity}s.
|
|
@@ -93,8 +93,8 @@ export class PointerLens {
|
|
|
93
93
|
this._lensCanvasContext = this._lensCanvas.getContext('2d');
|
|
94
94
|
this._canvasElement = this.viewer.scene.canvas.canvas;
|
|
95
95
|
|
|
96
|
-
this.
|
|
97
|
-
this.
|
|
96
|
+
this._canvasPos = null;
|
|
97
|
+
this._snappedCanvasPos = null;
|
|
98
98
|
this._lensPosToggle = true;
|
|
99
99
|
|
|
100
100
|
this._zoomLevel = cfg.zoomLevel || 2;
|
|
@@ -117,14 +117,14 @@ export class PointerLens {
|
|
|
117
117
|
if (!this._active || !this._visible) {
|
|
118
118
|
return;
|
|
119
119
|
}
|
|
120
|
-
if (!this.
|
|
120
|
+
if (!this._canvasPos) {
|
|
121
121
|
return;
|
|
122
122
|
}
|
|
123
123
|
const lensRect = this._lensContainer.getBoundingClientRect();
|
|
124
124
|
const canvasRect = this._canvasElement.getBoundingClientRect();
|
|
125
125
|
const pointerOnLens =
|
|
126
|
-
this.
|
|
127
|
-
this.
|
|
126
|
+
this._canvasPos[0] < lensRect.right && this._canvasPos[0] > lensRect.left &&
|
|
127
|
+
this._canvasPos[1] < lensRect.bottom && this._canvasPos[1] > lensRect.top;
|
|
128
128
|
this._lensContainer.style.marginLeft = `25px`;
|
|
129
129
|
if (pointerOnLens) {
|
|
130
130
|
if (this._lensPosToggle) {
|
|
@@ -138,8 +138,8 @@ export class PointerLens {
|
|
|
138
138
|
const size = Math.max(this._lensCanvas.width, this._lensCanvas.height) / this._zoomLevel;
|
|
139
139
|
this._lensCanvasContext.drawImage(
|
|
140
140
|
this._canvasElement, // source canvas
|
|
141
|
-
this.
|
|
142
|
-
this.
|
|
141
|
+
this._canvasPos[0] - size / 2, // source x (zoom center)
|
|
142
|
+
this._canvasPos[1] - size / 2, // source y (zoom center)
|
|
143
143
|
size, // source width
|
|
144
144
|
size, // source height
|
|
145
145
|
0, // destination x
|
|
@@ -153,9 +153,9 @@ export class PointerLens {
|
|
|
153
153
|
(lensRect.top + lensRect.bottom) / 2
|
|
154
154
|
];
|
|
155
155
|
|
|
156
|
-
if (this.
|
|
157
|
-
const deltaX = this.
|
|
158
|
-
const deltaY = this.
|
|
156
|
+
if (this._snappedCanvasPos) {
|
|
157
|
+
const deltaX = this._snappedCanvasPos[0] - this._canvasPos[0];
|
|
158
|
+
const deltaY = this._snappedCanvasPos[1] - this._canvasPos[1];
|
|
159
159
|
|
|
160
160
|
this._lensCursorDiv.style.marginLeft = `${centerLensCanvas[0] + deltaX * this._zoomLevel - 10}px`;
|
|
161
161
|
this._lensCursorDiv.style.marginTop = `${centerLensCanvas[1] + deltaY * this._zoomLevel - 10}px`;
|
|
@@ -191,10 +191,10 @@ export class PointerLens {
|
|
|
191
191
|
|
|
192
192
|
/**
|
|
193
193
|
* Sets the canvas central position of the lens.
|
|
194
|
-
* @param
|
|
194
|
+
* @param canvasPos
|
|
195
195
|
*/
|
|
196
|
-
set
|
|
197
|
-
this.
|
|
196
|
+
set canvasPos(canvasPos) {
|
|
197
|
+
this._canvasPos = canvasPos;
|
|
198
198
|
this.update();
|
|
199
199
|
}
|
|
200
200
|
|
|
@@ -202,25 +202,25 @@ export class PointerLens {
|
|
|
202
202
|
* Gets the canvas central position of the lens.
|
|
203
203
|
* @returns {Number[]}
|
|
204
204
|
*/
|
|
205
|
-
get
|
|
206
|
-
return this.
|
|
205
|
+
get canvasPos() {
|
|
206
|
+
return this._canvasPos;
|
|
207
207
|
}
|
|
208
208
|
|
|
209
209
|
/**
|
|
210
210
|
* Sets the canvas coordinates of the pointer.
|
|
211
|
-
* @param
|
|
211
|
+
* @param snappedCanvasPos
|
|
212
212
|
*/
|
|
213
|
-
set
|
|
214
|
-
this.
|
|
213
|
+
set snappedCanvasPos(snappedCanvasPos) {
|
|
214
|
+
this._snappedCanvasPos = snappedCanvasPos;
|
|
215
215
|
this.update();
|
|
216
216
|
}
|
|
217
217
|
|
|
218
218
|
/**
|
|
219
|
-
* Gets the canvas coordinates of the pointer.
|
|
219
|
+
* Gets the canvas coordinates of the snapped pointer.
|
|
220
220
|
* @returns {Number[]}
|
|
221
221
|
*/
|
|
222
|
-
get
|
|
223
|
-
return this.
|
|
222
|
+
get snappedCanvasPos() {
|
|
223
|
+
return this._snappedCanvasPos;
|
|
224
224
|
}
|
|
225
225
|
|
|
226
226
|
/**
|
|
@@ -7,6 +7,8 @@ const kdTreeDimLength = new Float32Array(3);
|
|
|
7
7
|
* Automatically indexes a {@link Viewer}'s {@link Entity}s in a 3D k-d tree
|
|
8
8
|
* to support fast collision detection with 3D World-space axis-aligned boundaries (AABBs) and frustums.
|
|
9
9
|
*
|
|
10
|
+
* See {@link MarqueePicker} for usage example.
|
|
11
|
+
*
|
|
10
12
|
* An ObjectsKdTree3 is configured with a Viewer, and will then automatically
|
|
11
13
|
* keep itself populated with k-d nodes that contain the Viewer's Entitys.
|
|
12
14
|
*
|
|
@@ -177,8 +177,8 @@ export class AngleMeasurementsMouseControl extends AngleMeasurementsControl {
|
|
|
177
177
|
if (event.snappedToVertex || event.snappedToEdge) {
|
|
178
178
|
if (pointerLens) {
|
|
179
179
|
pointerLens.visible = true;
|
|
180
|
-
pointerLens.
|
|
181
|
-
pointerLens.
|
|
180
|
+
pointerLens.canvasPos = event.canvasPos;
|
|
181
|
+
pointerLens.snappedCanvasPos = event.snappedCanvasPos || event.canvasPos;
|
|
182
182
|
pointerLens.snapped = true;
|
|
183
183
|
}
|
|
184
184
|
this.markerDiv.style.background = "greenyellow";
|
|
@@ -186,21 +186,22 @@ export class AngleMeasurementsMouseControl extends AngleMeasurementsControl {
|
|
|
186
186
|
} else {
|
|
187
187
|
if (pointerLens) {
|
|
188
188
|
pointerLens.visible = true;
|
|
189
|
-
pointerLens.
|
|
190
|
-
pointerLens.
|
|
189
|
+
pointerLens.canvasPos = event.canvasPos;
|
|
190
|
+
pointerLens.snappedCanvasPos = event.canvasPos;
|
|
191
191
|
pointerLens.snapped = false;
|
|
192
192
|
}
|
|
193
193
|
this.markerDiv.style.background = "pink";
|
|
194
194
|
this.markerDiv.style.border = "2px solid red";
|
|
195
195
|
}
|
|
196
|
+
const canvasPos = event.snappedCanvasPos || event.canvasPos;
|
|
196
197
|
mouseHovering = true;
|
|
197
198
|
mouseHoverEntity = event.entity;
|
|
198
199
|
mouseWorldPos.set(event.worldPos);
|
|
199
|
-
mouseHoverCanvasPos.set(
|
|
200
|
+
mouseHoverCanvasPos.set(canvasPos);
|
|
200
201
|
switch (this._mouseState) {
|
|
201
202
|
case MOUSE_FINDING_ORIGIN:
|
|
202
|
-
this.markerDiv.style.marginLeft = `${
|
|
203
|
-
this.markerDiv.style.marginTop = `${
|
|
203
|
+
this.markerDiv.style.marginLeft = `${canvasPos[0] - 5}px`;
|
|
204
|
+
this.markerDiv.style.marginTop = `${canvasPos[1] - 5}px`;
|
|
204
205
|
break;
|
|
205
206
|
case MOUSE_FINDING_CORNER:
|
|
206
207
|
if (this._currentAngleMeasurement) {
|
|
@@ -316,8 +317,8 @@ export class AngleMeasurementsMouseControl extends AngleMeasurementsControl {
|
|
|
316
317
|
mouseHovering = false;
|
|
317
318
|
if (pointerLens) {
|
|
318
319
|
pointerLens.visible = true;
|
|
319
|
-
pointerLens.
|
|
320
|
-
pointerLens.
|
|
320
|
+
pointerLens.pointerPos = event.canvasPos;
|
|
321
|
+
pointerLens.snappedCanvasPos = event.snappedCanvasPos || event.canvasPos;
|
|
321
322
|
pointerLens.snapped = false;
|
|
322
323
|
}
|
|
323
324
|
this.markerDiv.style.marginLeft = `-100px`;
|
|
@@ -181,18 +181,19 @@ export class DistanceMeasurementsMouseControl extends DistanceMeasurementsContro
|
|
|
181
181
|
this._snapping
|
|
182
182
|
? "hoverSnapOrSurface"
|
|
183
183
|
: "hoverSurface", event => {
|
|
184
|
+
const canvasPos = event.snappedCanvasPos || event.canvasPos;
|
|
184
185
|
mouseHovering = true;
|
|
185
186
|
pointerWorldPos.set(event.worldPos);
|
|
186
187
|
pointerCanvasPos.set(event.canvasPos);
|
|
187
188
|
if (this._mouseState === MOUSE_FIRST_CLICK_EXPECTED) {
|
|
188
|
-
this._markerDiv.style.marginLeft = `${
|
|
189
|
-
this._markerDiv.style.marginTop = `${
|
|
189
|
+
this._markerDiv.style.marginLeft = `${canvasPos[0] - 5}px`;
|
|
190
|
+
this._markerDiv.style.marginTop = `${canvasPos[1] - 5}px`;
|
|
190
191
|
this._markerDiv.style.background = "pink";
|
|
191
192
|
if (event.snappedToVertex || event.snappedToEdge) {
|
|
192
193
|
if (this.pointerLens) {
|
|
193
194
|
this.pointerLens.visible = true;
|
|
194
|
-
this.pointerLens.
|
|
195
|
-
this.pointerLens.
|
|
195
|
+
this.pointerLens.canvasPos = event.canvasPos;
|
|
196
|
+
this.pointerLens.snappedCanvasPos = event.snappedCanvasPos || event.canvasPos;
|
|
196
197
|
this.pointerLens.snapped = true;
|
|
197
198
|
}
|
|
198
199
|
this._markerDiv.style.background = "greenyellow";
|
|
@@ -200,8 +201,8 @@ export class DistanceMeasurementsMouseControl extends DistanceMeasurementsContro
|
|
|
200
201
|
} else {
|
|
201
202
|
if (this.pointerLens) {
|
|
202
203
|
this.pointerLens.visible = true;
|
|
203
|
-
this.pointerLens.
|
|
204
|
-
this.pointerLens.
|
|
204
|
+
this.pointerLens.canvasPos = event.canvasPos;
|
|
205
|
+
this.pointerLens.snappedCanvasPos = event.canvasPos;
|
|
205
206
|
this.pointerLens.snapped = false;
|
|
206
207
|
}
|
|
207
208
|
this._markerDiv.style.background = "pink";
|
|
@@ -283,8 +284,8 @@ export class DistanceMeasurementsMouseControl extends DistanceMeasurementsContro
|
|
|
283
284
|
: "hoverOff", event => {
|
|
284
285
|
if (this.pointerLens) {
|
|
285
286
|
this.pointerLens.visible = true;
|
|
286
|
-
this.pointerLens.
|
|
287
|
-
this.pointerLens.
|
|
287
|
+
this.pointerLens.canvasPos = event.canvasPos;
|
|
288
|
+
this.pointerLens.snappedCanvasPos = event.snappedCanvasPos || event.canvasPos;
|
|
288
289
|
}
|
|
289
290
|
mouseHovering = false;
|
|
290
291
|
this._markerDiv.style.marginLeft = `-100px`;
|
|
@@ -70,29 +70,12 @@ class PickController {
|
|
|
70
70
|
this._lastPickedEntityId = null;
|
|
71
71
|
|
|
72
72
|
this._needFireEvents = 0;
|
|
73
|
-
|
|
74
|
-
this._needToUpdate = false;
|
|
75
|
-
|
|
76
|
-
this._tickSub = this._scene.on("tick", () => {
|
|
77
|
-
this.runUpdate();
|
|
78
|
-
});
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
update() {
|
|
82
|
-
this._needToUpdate = true;
|
|
83
73
|
}
|
|
84
74
|
|
|
85
75
|
/**
|
|
86
76
|
* Immediately attempts a pick, if scheduled.
|
|
87
77
|
*/
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
if (!this._needToUpdate) {
|
|
91
|
-
return;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
this._needToUpdate = false;
|
|
95
|
-
|
|
78
|
+
update() {
|
|
96
79
|
if (!this._configs.pointerEnabled) {
|
|
97
80
|
return;
|
|
98
81
|
}
|
|
@@ -109,13 +92,13 @@ class PickController {
|
|
|
109
92
|
const hasHoverSurfaceSubs = this._cameraControl.hasSubs("hoverSurface");
|
|
110
93
|
|
|
111
94
|
if (this.scheduleSnapOrPick) {
|
|
112
|
-
const snapPickResult = this._scene.
|
|
95
|
+
const snapPickResult = this._scene.pick({
|
|
113
96
|
canvasPos: this.pickCursorPos,
|
|
114
97
|
snapRadius: this._configs.snapRadius,
|
|
115
98
|
snapToVertex: this._configs.snapToVertex,
|
|
116
99
|
snapToEdge: this._configs.snapToEdge,
|
|
117
100
|
});
|
|
118
|
-
if (snapPickResult && snapPickResult.
|
|
101
|
+
if (snapPickResult && (snapPickResult.snappedToEdge || snapPickResult.snappedToVertex)) {
|
|
119
102
|
this.snapPickResult = snapPickResult;
|
|
120
103
|
this.snappedOrPicked = true;
|
|
121
104
|
this._needFireEvents++;
|
|
@@ -197,14 +180,14 @@ class PickController {
|
|
|
197
180
|
|
|
198
181
|
fireEvents() {
|
|
199
182
|
|
|
200
|
-
if (this._needFireEvents
|
|
183
|
+
if (this._needFireEvents === 0) {
|
|
201
184
|
return;
|
|
202
185
|
}
|
|
203
186
|
|
|
204
187
|
if (this.hoveredSnappedOrSurfaceOff) {
|
|
205
188
|
this._cameraControl.fire("hoverSnapOrSurfaceOff", {
|
|
206
189
|
canvasPos: this.pickCursorPos,
|
|
207
|
-
|
|
190
|
+
pointerPos : this.pickCursorPos
|
|
208
191
|
}, true);
|
|
209
192
|
}
|
|
210
193
|
|
|
@@ -213,9 +196,9 @@ class PickController {
|
|
|
213
196
|
const pickResult = new PickResult();
|
|
214
197
|
pickResult.snappedToVertex = this.snapPickResult.snappedToVertex;
|
|
215
198
|
pickResult.snappedToEdge = this.snapPickResult.snappedToEdge;
|
|
216
|
-
pickResult.worldPos = this.snapPickResult.
|
|
217
|
-
pickResult.
|
|
218
|
-
pickResult.
|
|
199
|
+
pickResult.worldPos = this.snapPickResult.worldPos;
|
|
200
|
+
pickResult.canvasPos = this.pickCursorPos
|
|
201
|
+
pickResult.snappedCanvasPos = this.snapPickResult.snappedCanvasPos;
|
|
219
202
|
this._cameraControl.fire("hoverSnapOrSurface", pickResult, true);
|
|
220
203
|
this.snapPickResult = null;
|
|
221
204
|
} else {
|
|
@@ -269,10 +252,6 @@ class PickController {
|
|
|
269
252
|
|
|
270
253
|
this._needFireEvents = 0;
|
|
271
254
|
}
|
|
272
|
-
|
|
273
|
-
destroy() {
|
|
274
|
-
this._scene.off(this._tickSub);
|
|
275
|
-
}
|
|
276
255
|
}
|
|
277
256
|
|
|
278
257
|
export {PickController};
|
|
@@ -45,75 +45,78 @@ class MousePickHandler {
|
|
|
45
45
|
}
|
|
46
46
|
};
|
|
47
47
|
|
|
48
|
-
|
|
48
|
+
const tickifiedMouseMoveFn = scene.tickify (
|
|
49
|
+
this._canvasMouseMoveHandler = (e) => {
|
|
50
|
+
if (!(configs.active && configs.pointerEnabled)) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
49
53
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
54
|
+
if (leftDown || rightDown) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
53
57
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
58
|
+
const hoverSubs = cameraControl.hasSubs("hover");
|
|
59
|
+
const hoverEnterSubs = cameraControl.hasSubs("hoverEnter");
|
|
60
|
+
const hoverOutSubs = cameraControl.hasSubs("hoverOut");
|
|
61
|
+
const hoverOffSubs = cameraControl.hasSubs("hoverOff");
|
|
62
|
+
const hoverSurfaceSubs = cameraControl.hasSubs("hoverSurface");
|
|
63
|
+
const hoverSnapOrSurfaceSubs = cameraControl.hasSubs("hoverSnapOrSurface");
|
|
57
64
|
|
|
58
|
-
|
|
59
|
-
const hoverEnterSubs = cameraControl.hasSubs("hoverEnter");
|
|
60
|
-
const hoverOutSubs = cameraControl.hasSubs("hoverOut");
|
|
61
|
-
const hoverOffSubs = cameraControl.hasSubs("hoverOff");
|
|
62
|
-
const hoverSurfaceSubs = cameraControl.hasSubs("hoverSurface");
|
|
63
|
-
const hoverSnapOrSurfaceSubs = cameraControl.hasSubs("hoverSnapOrSurface");
|
|
65
|
+
if (hoverSubs || hoverEnterSubs || hoverOutSubs || hoverOffSubs || hoverSurfaceSubs || hoverSnapOrSurfaceSubs) {
|
|
64
66
|
|
|
65
|
-
|
|
67
|
+
pickController.pickCursorPos = states.pointerCanvasPos;
|
|
68
|
+
pickController.schedulePickEntity = true;
|
|
69
|
+
pickController.schedulePickSurface = hoverSurfaceSubs;
|
|
70
|
+
pickController.scheduleSnapOrPick = hoverSnapOrSurfaceSubs
|
|
66
71
|
|
|
67
|
-
|
|
68
|
-
pickController.schedulePickEntity = true;
|
|
69
|
-
pickController.schedulePickSurface = hoverSurfaceSubs;
|
|
70
|
-
pickController.scheduleSnapOrPick = hoverSnapOrSurfaceSubs
|
|
72
|
+
pickController.update();
|
|
71
73
|
|
|
72
|
-
|
|
74
|
+
if (pickController.pickResult) {
|
|
73
75
|
|
|
74
|
-
|
|
76
|
+
if (pickController.pickResult.entity) {
|
|
77
|
+
const pickedEntityId = pickController.pickResult.entity.id;
|
|
75
78
|
|
|
76
|
-
|
|
77
|
-
const pickedEntityId = pickController.pickResult.entity.id;
|
|
79
|
+
if (this._lastPickedEntityId !== pickedEntityId) {
|
|
78
80
|
|
|
79
|
-
|
|
81
|
+
if (this._lastPickedEntityId !== undefined) {
|
|
80
82
|
|
|
81
|
-
|
|
83
|
+
cameraControl.fire("hoverOut", { // Hovered off an entity
|
|
84
|
+
entity: scene.objects[this._lastPickedEntityId]
|
|
85
|
+
}, true);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
cameraControl.fire("hoverEnter", pickController.pickResult, true); // Hovering over a new entity
|
|
82
89
|
|
|
83
|
-
|
|
84
|
-
entity: scene.objects[this._lastPickedEntityId]
|
|
85
|
-
}, true);
|
|
90
|
+
this._lastPickedEntityId = pickedEntityId;
|
|
86
91
|
}
|
|
92
|
+
}
|
|
87
93
|
|
|
88
|
-
|
|
94
|
+
cameraControl.fire("hover", pickController.pickResult, true);
|
|
89
95
|
|
|
90
|
-
|
|
96
|
+
if (pickController.pickResult.worldPos || pickController.pickResult.snappedWorldPos) { // Hovering the surface of an entity
|
|
97
|
+
cameraControl.fire("hoverSurface", pickController.pickResult, true);
|
|
91
98
|
}
|
|
92
|
-
}
|
|
93
99
|
|
|
94
|
-
|
|
100
|
+
} else {
|
|
95
101
|
|
|
96
|
-
|
|
97
|
-
cameraControl.fire("hoverSurface", pickController.pickResult, true);
|
|
98
|
-
}
|
|
102
|
+
if (this._lastPickedEntityId !== undefined) {
|
|
99
103
|
|
|
100
|
-
|
|
104
|
+
cameraControl.fire("hoverOut", { // Hovered off an entity
|
|
105
|
+
entity: scene.objects[this._lastPickedEntityId]
|
|
106
|
+
}, true);
|
|
101
107
|
|
|
102
|
-
|
|
108
|
+
this._lastPickedEntityId = undefined;
|
|
109
|
+
}
|
|
103
110
|
|
|
104
|
-
cameraControl.fire("
|
|
105
|
-
|
|
111
|
+
cameraControl.fire("hoverOff", { // Not hovering on any entity
|
|
112
|
+
canvasPos: pickController.pickCursorPos
|
|
106
113
|
}, true);
|
|
107
|
-
|
|
108
|
-
this._lastPickedEntityId = undefined;
|
|
109
114
|
}
|
|
110
|
-
|
|
111
|
-
cameraControl.fire("hoverOff", { // Not hovering on any entity
|
|
112
|
-
canvasPos: pickController.pickCursorPos
|
|
113
|
-
}, true);
|
|
114
115
|
}
|
|
115
116
|
}
|
|
116
|
-
|
|
117
|
+
);
|
|
118
|
+
|
|
119
|
+
canvas.addEventListener("mousemove", tickifiedMouseMoveFn);
|
|
117
120
|
|
|
118
121
|
canvas.addEventListener('mousedown', this._canvasMouseDownHandler = (e) => {
|
|
119
122
|
|
|
@@ -1175,23 +1175,31 @@ class Input extends Component {
|
|
|
1175
1175
|
}
|
|
1176
1176
|
});
|
|
1177
1177
|
|
|
1178
|
+
const tickifedMouseMoveFn = this.scene.tickify(
|
|
1179
|
+
() => this.fire("mousemove", this.mouseCanvasPos, true)
|
|
1180
|
+
);
|
|
1181
|
+
|
|
1178
1182
|
this.element.addEventListener("mousemove", this._mouseMoveListener = (e) => {
|
|
1179
1183
|
if (!this.enabled) {
|
|
1180
1184
|
return;
|
|
1181
1185
|
}
|
|
1182
1186
|
this._getMouseCanvasPos(e);
|
|
1183
|
-
|
|
1187
|
+
tickifedMouseMoveFn();
|
|
1184
1188
|
if (this.mouseover) {
|
|
1185
1189
|
e.preventDefault();
|
|
1186
1190
|
}
|
|
1187
1191
|
});
|
|
1188
1192
|
|
|
1193
|
+
const tickifiedMouseWheelFn = this.scene.tickify(
|
|
1194
|
+
(delta) => { this.fire("mousewheel", delta, true); }
|
|
1195
|
+
);
|
|
1196
|
+
|
|
1189
1197
|
this.element.addEventListener("wheel", this._mouseWheelListener = (e, d) => {
|
|
1190
1198
|
if (!this.enabled) {
|
|
1191
1199
|
return;
|
|
1192
1200
|
}
|
|
1193
1201
|
const delta = Math.max(-1, Math.min(1, -e.deltaY * 40));
|
|
1194
|
-
|
|
1202
|
+
tickifiedMouseWheelFn(delta);
|
|
1195
1203
|
}, {passive: true});
|
|
1196
1204
|
|
|
1197
1205
|
// mouseclicked
|