@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
|
@@ -352,6 +352,11 @@ class Scene extends Component {
|
|
|
352
352
|
throw "Mandatory config expected: valid canvasId or canvasElement";
|
|
353
353
|
}
|
|
354
354
|
|
|
355
|
+
/**
|
|
356
|
+
* @type {{[key: string]: {wrapperFunc: Function, tickSubId: string}}}
|
|
357
|
+
*/
|
|
358
|
+
this._tickifiedFunctions = {};
|
|
359
|
+
|
|
355
360
|
const transparent = (!!cfg.transparent);
|
|
356
361
|
const alphaDepthMask = (!!cfg.alphaDepthMask);
|
|
357
362
|
|
|
@@ -2149,6 +2154,9 @@ class Scene extends Component {
|
|
|
2149
2154
|
* @param {Number[]} [params.matrix] 4x4 transformation matrix to define the World-space ray origin and direction, as an alternative to ````origin```` and ````direction````.
|
|
2150
2155
|
* @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.
|
|
2151
2156
|
* @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.
|
|
2157
|
+
* @param {Number} [params.snapRadius=30] The snap radius, in canvas pixels
|
|
2158
|
+
* @param {boolean} [params.snapToVertex=true] Whether to snap to vertex.
|
|
2159
|
+
* @param {boolean} [params.snapToEdge=true] Whether to snap to edge.
|
|
2152
2160
|
* @param {PickResult} [pickResult] Holds the results of the pick attempt. Will use the Scene's singleton PickResult if you don't supply your own.
|
|
2153
2161
|
* @returns {PickResult} Holds results of the pick attempt, returned when an {@link Entity} is picked, else null. See method comments for description.
|
|
2154
2162
|
*/
|
|
@@ -2183,14 +2191,25 @@ class Scene extends Component {
|
|
|
2183
2191
|
this._needRecompile = false;
|
|
2184
2192
|
}
|
|
2185
2193
|
|
|
2186
|
-
|
|
2194
|
+
if (params.snapToEdge || params.snapToVertex) {
|
|
2195
|
+
pickResult = this._renderer.snapPick(
|
|
2196
|
+
params.canvasPos,
|
|
2197
|
+
params.snapRadius || 30,
|
|
2198
|
+
params.snapToVertex,
|
|
2199
|
+
params.snapToEdge,
|
|
2200
|
+
pickResult
|
|
2201
|
+
);
|
|
2202
|
+
} else {
|
|
2203
|
+
pickResult = this._renderer.pick(params, pickResult);
|
|
2204
|
+
}
|
|
2187
2205
|
|
|
2188
2206
|
if (pickResult) {
|
|
2189
2207
|
if (pickResult.entity && pickResult.entity.fire) {
|
|
2190
|
-
pickResult.entity.fire("picked", pickResult); // TODO:
|
|
2208
|
+
pickResult.entity.fire("picked", pickResult); // TODO: SceneModelEntity doesn't fire events
|
|
2191
2209
|
}
|
|
2192
|
-
return pickResult;
|
|
2193
2210
|
}
|
|
2211
|
+
|
|
2212
|
+
return pickResult;
|
|
2194
2213
|
}
|
|
2195
2214
|
|
|
2196
2215
|
/**
|
|
@@ -2199,8 +2218,13 @@ class Scene extends Component {
|
|
|
2199
2218
|
* @param {Number} [params.snapRadius=30] The snap radius, in canvas pixels
|
|
2200
2219
|
* @param {boolean} [params.snapToVertex=true] Whether to snap to vertex.
|
|
2201
2220
|
* @param {boolean} [params.snapToEdge=true] Whether to snap to edge.
|
|
2221
|
+
* @deprecated
|
|
2202
2222
|
*/
|
|
2203
2223
|
snapPick(params) {
|
|
2224
|
+
if (undefined === this._warnSnapPickDeprecated) {
|
|
2225
|
+
this._warnSnapPickDeprecated = true;
|
|
2226
|
+
this.warn("Scene.snapPick() is deprecated since v2.4.2 - use Scene.pick() instead")
|
|
2227
|
+
}
|
|
2204
2228
|
return this._renderer.snapPick(
|
|
2205
2229
|
params.canvasPos,
|
|
2206
2230
|
params.snapRadius || 30,
|
|
@@ -2562,6 +2586,63 @@ class Scene extends Component {
|
|
|
2562
2586
|
return changed;
|
|
2563
2587
|
}
|
|
2564
2588
|
|
|
2589
|
+
/**
|
|
2590
|
+
* This method will "tickify" the provided `cb` function.
|
|
2591
|
+
*
|
|
2592
|
+
* This means, the function will be wrapped so:
|
|
2593
|
+
*
|
|
2594
|
+
* - it runs time-aligned to scene ticks
|
|
2595
|
+
* - it runs maximum once per scene-tick
|
|
2596
|
+
*
|
|
2597
|
+
* @param {Function} cb The function to tickify
|
|
2598
|
+
* @returns {Function)}
|
|
2599
|
+
*/
|
|
2600
|
+
tickify(cb) {
|
|
2601
|
+
const cbString = cb.toString();
|
|
2602
|
+
|
|
2603
|
+
/**
|
|
2604
|
+
* Check if the function is already tickified, and if so return the cached one.
|
|
2605
|
+
*/
|
|
2606
|
+
if (cbString in this._tickifiedFunctions) {
|
|
2607
|
+
return this._tickifiedFunctions[cbString].wrapperFunc;
|
|
2608
|
+
}
|
|
2609
|
+
|
|
2610
|
+
let alreadyRun = 0;
|
|
2611
|
+
let needToRun = 0;
|
|
2612
|
+
|
|
2613
|
+
let lastArgs;
|
|
2614
|
+
|
|
2615
|
+
/**
|
|
2616
|
+
* The provided `cb` function is replaced with a "set-dirty" function
|
|
2617
|
+
*
|
|
2618
|
+
* @type {Function}
|
|
2619
|
+
*/
|
|
2620
|
+
const wrapperFunc = function (...args) {
|
|
2621
|
+
lastArgs = args;
|
|
2622
|
+
needToRun++;
|
|
2623
|
+
};
|
|
2624
|
+
|
|
2625
|
+
/**
|
|
2626
|
+
* An each scene tick, if the "dirty-flag" is set, run the `cb` function.
|
|
2627
|
+
*
|
|
2628
|
+
* This will make it run time-aligned to the scene tick.
|
|
2629
|
+
*/
|
|
2630
|
+
const tickSubId = this.on("tick", () => {
|
|
2631
|
+
const tmp = needToRun;
|
|
2632
|
+
if (tmp > alreadyRun) {
|
|
2633
|
+
alreadyRun = tmp;
|
|
2634
|
+
cb(...lastArgs);
|
|
2635
|
+
}
|
|
2636
|
+
});
|
|
2637
|
+
|
|
2638
|
+
/**
|
|
2639
|
+
* And, store the list of subscribers.
|
|
2640
|
+
*/
|
|
2641
|
+
this._tickifiedFunctions[cbString] = { tickSubId, wrapperFunc };
|
|
2642
|
+
|
|
2643
|
+
return wrapperFunc;
|
|
2644
|
+
}
|
|
2645
|
+
|
|
2565
2646
|
/**
|
|
2566
2647
|
* Destroys this Scene.
|
|
2567
2648
|
*/
|
|
@@ -60,13 +60,14 @@ class PickResult {
|
|
|
60
60
|
*/
|
|
61
61
|
this.snappedToVertex = false;
|
|
62
62
|
|
|
63
|
-
this._canvasPos = new Int16Array([0, 0]);
|
|
64
63
|
this._origin = new Float64Array([0, 0, 0]);
|
|
65
64
|
this._direction = new Float64Array([0, 0, 0]);
|
|
66
65
|
this._indices = new Int32Array(3);
|
|
67
66
|
this._localPos = new Float64Array([0, 0, 0]);
|
|
68
67
|
this._worldPos = new Float64Array([0, 0, 0]);
|
|
69
68
|
this._viewPos = new Float64Array([0, 0, 0]);
|
|
69
|
+
this._canvasPos = new Int16Array([0, 0]);
|
|
70
|
+
this._snappedCanvasPos = new Int16Array([0, 0]);
|
|
70
71
|
this._bary = new Float64Array([0, 0, 0]);
|
|
71
72
|
this._worldNormal = new Float64Array([0, 0, 0]);
|
|
72
73
|
this._uv = new Float64Array([0, 0]);
|
|
@@ -75,7 +76,7 @@ class PickResult {
|
|
|
75
76
|
}
|
|
76
77
|
|
|
77
78
|
/**
|
|
78
|
-
* Canvas coordinates
|
|
79
|
+
* Canvas pick coordinates.
|
|
79
80
|
* @property canvasPos
|
|
80
81
|
* @type {Number[]}
|
|
81
82
|
*/
|
|
@@ -193,6 +194,29 @@ class PickResult {
|
|
|
193
194
|
}
|
|
194
195
|
}
|
|
195
196
|
|
|
197
|
+
/**
|
|
198
|
+
* Canvas cursor coordinates, snapped when snap picking, otherwise same as {@link PickResult#pointerPos}.
|
|
199
|
+
* @property snappedCanvasPos
|
|
200
|
+
* @type {Number[]}
|
|
201
|
+
*/
|
|
202
|
+
get snappedCanvasPos() {
|
|
203
|
+
return this._gotSnappedCanvasPos ? this._snappedCanvasPos : null;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* @private
|
|
208
|
+
* @param value
|
|
209
|
+
*/
|
|
210
|
+
set snappedCanvasPos(value) {
|
|
211
|
+
if (value) {
|
|
212
|
+
this._snappedCanvasPos[0] = value[0];
|
|
213
|
+
this._snappedCanvasPos[1] = value[1];
|
|
214
|
+
this._gotSnappedCanvasPos = true;
|
|
215
|
+
} else {
|
|
216
|
+
this._gotSnappedCanvasPos = false;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
196
220
|
/**
|
|
197
221
|
* Picked World-space point.
|
|
198
222
|
* @property worldPos
|
|
@@ -321,6 +345,7 @@ class PickResult {
|
|
|
321
345
|
this.primitive = null;
|
|
322
346
|
this.pickSurfacePrecision = false;
|
|
323
347
|
this._gotCanvasPos = false;
|
|
348
|
+
this._gotSnappedCanvasPos = false;
|
|
324
349
|
this._gotOrigin = false;
|
|
325
350
|
this._gotDirection = false;
|
|
326
351
|
this._gotIndices = false;
|
|
@@ -1283,255 +1283,260 @@ const Renderer = function (scene, options) {
|
|
|
1283
1283
|
* @param {number} [snapRadiusInPixels=30]
|
|
1284
1284
|
* @param {boolean} [snapToVertex=true]
|
|
1285
1285
|
* @param {boolean} [snapToEdge=true]
|
|
1286
|
-
*
|
|
1287
|
-
* @returns {
|
|
1286
|
+
* @param pickResult
|
|
1287
|
+
* @returns {PickResult}
|
|
1288
1288
|
*/
|
|
1289
|
-
this.snapPick = function (
|
|
1290
|
-
|
|
1291
|
-
if (!snapToVertex && !snapToEdge) {
|
|
1292
|
-
return this.pick({canvasPos, pickSurface: true});
|
|
1293
|
-
}
|
|
1289
|
+
this.snapPick = (function () {
|
|
1294
1290
|
|
|
1295
|
-
const
|
|
1296
|
-
|
|
1297
|
-
frameCtx.reset();
|
|
1298
|
-
frameCtx.backfaces = true;
|
|
1299
|
-
frameCtx.frontface = true; // "ccw"
|
|
1300
|
-
frameCtx.pickZNear = scene.camera.project.near;
|
|
1301
|
-
frameCtx.pickZFar = scene.camera.project.far;
|
|
1302
|
-
|
|
1303
|
-
const vertexPickBuffer = renderBufferManager.getRenderBuffer("uniquePickColors-aabs", {
|
|
1304
|
-
depthTexture: true,
|
|
1305
|
-
size: [
|
|
1306
|
-
2 * snapRadiusInPixels + 1,
|
|
1307
|
-
2 * snapRadiusInPixels + 1,
|
|
1308
|
-
]
|
|
1309
|
-
});
|
|
1291
|
+
const _pickResult = new PickResult();
|
|
1310
1292
|
|
|
1311
|
-
|
|
1312
|
-
getClipPosX(canvasPos[0] * resolutionScale, gl.drawingBufferWidth),
|
|
1313
|
-
getClipPosY(canvasPos[1] * resolutionScale, gl.drawingBufferHeight),
|
|
1314
|
-
];
|
|
1293
|
+
return function (canvasPos, snapRadiusInPixels, snapToVertex, snapToEdge, pickResult = _pickResult) {
|
|
1315
1294
|
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
];
|
|
1295
|
+
if (!snapToVertex && !snapToEdge) {
|
|
1296
|
+
return this.pick({canvasPos, pickSurface: true});
|
|
1297
|
+
}
|
|
1320
1298
|
|
|
1321
|
-
|
|
1299
|
+
const resolutionScale = scene.canvas.resolutionScale;
|
|
1322
1300
|
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
gl.depthMask(true);
|
|
1329
|
-
gl.disable(gl.BLEND);
|
|
1330
|
-
gl.depthFunc(gl.LEQUAL);
|
|
1331
|
-
gl.clear(gl.DEPTH_BUFFER_BIT);
|
|
1332
|
-
gl.clearBufferiv(gl.COLOR, 0, new Int32Array([0, 0, 0, 0]));
|
|
1333
|
-
gl.clearBufferiv(gl.COLOR, 1, new Int32Array([0, 0, 0, 0]));
|
|
1334
|
-
gl.clearBufferuiv(gl.COLOR, 2, new Uint32Array([0, 0, 0, 0]));
|
|
1301
|
+
frameCtx.reset();
|
|
1302
|
+
frameCtx.backfaces = true;
|
|
1303
|
+
frameCtx.frontface = true; // "ccw"
|
|
1304
|
+
frameCtx.pickZNear = scene.camera.project.near;
|
|
1305
|
+
frameCtx.pickZFar = scene.camera.project.far;
|
|
1335
1306
|
|
|
1336
|
-
|
|
1337
|
-
// Set view and proj mats for VBO renderers
|
|
1338
|
-
///////////////////////////////////////
|
|
1307
|
+
snapRadiusInPixels = snapRadiusInPixels || 30;
|
|
1339
1308
|
|
|
1340
|
-
|
|
1341
|
-
|
|
1309
|
+
const vertexPickBuffer = renderBufferManager.getRenderBuffer("uniquePickColors-aabs", {
|
|
1310
|
+
depthTexture: true,
|
|
1311
|
+
size: [
|
|
1312
|
+
2 * snapRadiusInPixels + 1,
|
|
1313
|
+
2 * snapRadiusInPixels + 1,
|
|
1314
|
+
]
|
|
1315
|
+
});
|
|
1342
1316
|
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
const drawable = drawableList[i];
|
|
1348
|
-
if (drawable.setPickMatrices) { // Eg. SceneModel, which needs pre-loading into texture
|
|
1349
|
-
drawable.setPickMatrices(pickViewMatrix, pickProjMatrix);
|
|
1350
|
-
}
|
|
1351
|
-
}
|
|
1352
|
-
}
|
|
1353
|
-
}
|
|
1317
|
+
frameCtx.snapVectorA = [
|
|
1318
|
+
getClipPosX(canvasPos[0] * resolutionScale, gl.drawingBufferWidth),
|
|
1319
|
+
getClipPosY(canvasPos[1] * resolutionScale, gl.drawingBufferHeight),
|
|
1320
|
+
];
|
|
1354
1321
|
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1322
|
+
frameCtx.snapInvVectorAB = [
|
|
1323
|
+
gl.drawingBufferWidth / (2 * snapRadiusInPixels),
|
|
1324
|
+
gl.drawingBufferHeight / (2 * snapRadiusInPixels),
|
|
1325
|
+
];
|
|
1358
1326
|
|
|
1359
|
-
|
|
1360
|
-
const layerParamsSnap = []
|
|
1361
|
-
frameCtx.snapPickLayerParams = layerParamsSnap;
|
|
1327
|
+
// Bind and clear the snap render target
|
|
1362
1328
|
|
|
1363
|
-
|
|
1364
|
-
|
|
1329
|
+
vertexPickBuffer.bind(gl.RGBA32I, gl.RGBA32I, gl.RGBA8UI);
|
|
1330
|
+
gl.viewport(0, 0, vertexPickBuffer.size[0], vertexPickBuffer.size[1]);
|
|
1331
|
+
gl.enable(gl.DEPTH_TEST);
|
|
1332
|
+
gl.frontFace(gl.CCW);
|
|
1333
|
+
gl.disable(gl.CULL_FACE);
|
|
1334
|
+
gl.depthMask(true);
|
|
1335
|
+
gl.disable(gl.BLEND);
|
|
1336
|
+
gl.depthFunc(gl.LEQUAL);
|
|
1337
|
+
gl.clear(gl.DEPTH_BUFFER_BIT);
|
|
1338
|
+
gl.clearBufferiv(gl.COLOR, 0, new Int32Array([0, 0, 0, 0]));
|
|
1339
|
+
gl.clearBufferiv(gl.COLOR, 1, new Int32Array([0, 0, 0, 0]));
|
|
1340
|
+
gl.clearBufferuiv(gl.COLOR, 2, new Uint32Array([0, 0, 0, 0]));
|
|
1365
1341
|
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1342
|
+
//////////////////////////////////
|
|
1343
|
+
// Set view and proj mats for VBO renderers
|
|
1344
|
+
///////////////////////////////////////
|
|
1369
1345
|
|
|
1370
|
-
|
|
1371
|
-
|
|
1346
|
+
const pickViewMatrix = scene.camera.viewMatrix;
|
|
1347
|
+
const pickProjMatrix = scene.camera.projMatrix;
|
|
1372
1348
|
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1349
|
+
for (let type in drawableTypeInfo) {
|
|
1350
|
+
if (drawableTypeInfo.hasOwnProperty(type)) {
|
|
1351
|
+
const drawableList = drawableTypeInfo[type].drawableList;
|
|
1352
|
+
for (let i = 0, len = drawableList.length; i < len; i++) {
|
|
1353
|
+
const drawable = drawableList[i];
|
|
1354
|
+
if (drawable.setPickMatrices) { // Eg. SceneModel, which needs pre-loading into texture
|
|
1355
|
+
drawable.setPickMatrices(pickViewMatrix, pickProjMatrix);
|
|
1356
|
+
}
|
|
1357
|
+
}
|
|
1358
|
+
}
|
|
1359
|
+
}
|
|
1379
1360
|
|
|
1380
|
-
|
|
1361
|
+
// a) init z-buffer
|
|
1362
|
+
gl.drawBuffers([gl.COLOR_ATTACHMENT0, gl.COLOR_ATTACHMENT1, gl.COLOR_ATTACHMENT2]);
|
|
1363
|
+
const layerParamsSurface = snapInitDepthBuf(frameCtx);
|
|
1381
1364
|
|
|
1382
|
-
|
|
1365
|
+
// b) snap-pick
|
|
1366
|
+
const layerParamsSnap = []
|
|
1367
|
+
frameCtx.snapPickLayerParams = layerParamsSnap;
|
|
1383
1368
|
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
const snapPickIdResultArray = vertexPickBuffer.readArray(gl.RGBA_INTEGER, gl.UNSIGNED_INT, Uint32Array, 4, 2);
|
|
1369
|
+
gl.depthMask(false);
|
|
1370
|
+
gl.drawBuffers([gl.COLOR_ATTACHMENT0]);
|
|
1387
1371
|
|
|
1388
|
-
|
|
1372
|
+
if (snapToVertex && snapToEdge) {
|
|
1373
|
+
frameCtx.snapMode = "edge";
|
|
1374
|
+
snapPickDrawSnapDepths(frameCtx);
|
|
1389
1375
|
|
|
1390
|
-
|
|
1376
|
+
frameCtx.snapMode = "vertex";
|
|
1377
|
+
frameCtx.snapPickLayerNumber++;
|
|
1391
1378
|
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1379
|
+
snapPickDrawSnapDepths(frameCtx);
|
|
1380
|
+
} else {
|
|
1381
|
+
frameCtx.snapMode = snapToVertex ? "vertex" : "edge";
|
|
1395
1382
|
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
const middleIndex = (middleX * 4) + (middleY * vertexPickBuffer.size[0] * 4);
|
|
1399
|
-
const pickResultMiddleXY = snapPickResultArray.slice(middleIndex, middleIndex + 4);
|
|
1400
|
-
const pickNormalResultMiddleXY = snapPickNormalResultArray.slice(middleIndex, middleIndex + 4);
|
|
1401
|
-
const pickPickableResultMiddleXY = snapPickIdResultArray.slice(middleIndex, middleIndex + 4);
|
|
1383
|
+
snapPickDrawSnapDepths(frameCtx);
|
|
1384
|
+
}
|
|
1402
1385
|
|
|
1403
|
-
|
|
1404
|
-
const pickedLayerParmasSurface = layerParamsSurface[Math.abs(pickResultMiddleXY[3]) % layerParamsSurface.length];
|
|
1405
|
-
const origin = pickedLayerParmasSurface.origin;
|
|
1406
|
-
const scale = pickedLayerParmasSurface.coordinateScale;
|
|
1407
|
-
worldPos = [
|
|
1408
|
-
pickResultMiddleXY[0] * scale[0] + origin[0],
|
|
1409
|
-
pickResultMiddleXY[1] * scale[1] + origin[1],
|
|
1410
|
-
pickResultMiddleXY[2] * scale[2] + origin[2],
|
|
1411
|
-
];
|
|
1412
|
-
worldNormal = math.normalizeVec3([
|
|
1413
|
-
pickNormalResultMiddleXY[0] / math.MAX_INT,
|
|
1414
|
-
pickNormalResultMiddleXY[1] / math.MAX_INT,
|
|
1415
|
-
pickNormalResultMiddleXY[2] / math.MAX_INT,
|
|
1416
|
-
]);
|
|
1417
|
-
|
|
1418
|
-
const pickID =
|
|
1419
|
-
pickPickableResultMiddleXY[0]
|
|
1420
|
-
+ (pickPickableResultMiddleXY[1] << 8)
|
|
1421
|
-
+ (pickPickableResultMiddleXY[2] << 16)
|
|
1422
|
-
+ (pickPickableResultMiddleXY[3] << 24);
|
|
1423
|
-
|
|
1424
|
-
pickable = pickIDs.items[pickID];
|
|
1425
|
-
}
|
|
1386
|
+
gl.depthMask(true);
|
|
1426
1387
|
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
],
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
]
|
|
1461
|
-
|
|
1388
|
+
// Read and decode the snapped coordinates
|
|
1389
|
+
|
|
1390
|
+
const snapPickResultArray = vertexPickBuffer.readArray(gl.RGBA_INTEGER, gl.INT, Int32Array, 4);
|
|
1391
|
+
const snapPickNormalResultArray = vertexPickBuffer.readArray(gl.RGBA_INTEGER, gl.INT, Int32Array, 4, 1);
|
|
1392
|
+
const snapPickIdResultArray = vertexPickBuffer.readArray(gl.RGBA_INTEGER, gl.UNSIGNED_INT, Uint32Array, 4, 2);
|
|
1393
|
+
|
|
1394
|
+
vertexPickBuffer.unbind();
|
|
1395
|
+
|
|
1396
|
+
// result 1) regular hi-precision world position
|
|
1397
|
+
|
|
1398
|
+
let worldPos = null;
|
|
1399
|
+
let worldNormal = null;
|
|
1400
|
+
let pickable = null;
|
|
1401
|
+
|
|
1402
|
+
const middleX = snapRadiusInPixels;
|
|
1403
|
+
const middleY = snapRadiusInPixels;
|
|
1404
|
+
const middleIndex = (middleX * 4) + (middleY * vertexPickBuffer.size[0] * 4);
|
|
1405
|
+
const pickResultMiddleXY = snapPickResultArray.slice(middleIndex, middleIndex + 4);
|
|
1406
|
+
const pickNormalResultMiddleXY = snapPickNormalResultArray.slice(middleIndex, middleIndex + 4);
|
|
1407
|
+
const pickPickableResultMiddleXY = snapPickIdResultArray.slice(middleIndex, middleIndex + 4);
|
|
1408
|
+
|
|
1409
|
+
if (pickResultMiddleXY[3] !== 0) {
|
|
1410
|
+
const pickedLayerParmasSurface = layerParamsSurface[Math.abs(pickResultMiddleXY[3]) % layerParamsSurface.length];
|
|
1411
|
+
const origin = pickedLayerParmasSurface.origin;
|
|
1412
|
+
const scale = pickedLayerParmasSurface.coordinateScale;
|
|
1413
|
+
worldPos = [
|
|
1414
|
+
pickResultMiddleXY[0] * scale[0] + origin[0],
|
|
1415
|
+
pickResultMiddleXY[1] * scale[1] + origin[1],
|
|
1416
|
+
pickResultMiddleXY[2] * scale[2] + origin[2],
|
|
1417
|
+
];
|
|
1418
|
+
worldNormal = math.normalizeVec3([
|
|
1419
|
+
pickNormalResultMiddleXY[0] / math.MAX_INT,
|
|
1420
|
+
pickNormalResultMiddleXY[1] / math.MAX_INT,
|
|
1421
|
+
pickNormalResultMiddleXY[2] / math.MAX_INT,
|
|
1422
|
+
]);
|
|
1423
|
+
|
|
1424
|
+
const pickID =
|
|
1425
|
+
pickPickableResultMiddleXY[0]
|
|
1426
|
+
+ (pickPickableResultMiddleXY[1] << 8)
|
|
1427
|
+
+ (pickPickableResultMiddleXY[2] << 16)
|
|
1428
|
+
+ (pickPickableResultMiddleXY[3] << 24);
|
|
1429
|
+
|
|
1430
|
+
pickable = pickIDs.items[pickID];
|
|
1462
1431
|
}
|
|
1463
|
-
}
|
|
1464
|
-
|
|
1465
|
-
let snappedWorldPos = null;
|
|
1466
|
-
let snappedWorldNormal = null;
|
|
1467
|
-
let snappedPickable = null;
|
|
1468
|
-
let snapType = null;
|
|
1469
1432
|
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
snapPickResult
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1433
|
+
// result 2) hi-precision snapped (to vertex/edge) world position
|
|
1434
|
+
|
|
1435
|
+
let snapPickResult = [];
|
|
1436
|
+
|
|
1437
|
+
for (let i = 0; i < snapPickResultArray.length; i += 4) {
|
|
1438
|
+
if (snapPickResultArray[i + 3] > 0) {
|
|
1439
|
+
const pixelNumber = Math.floor(i / 4);
|
|
1440
|
+
const w = vertexPickBuffer.size[0];
|
|
1441
|
+
const x = pixelNumber % w - Math.floor(w / 2);
|
|
1442
|
+
const y = Math.floor(pixelNumber / w) - Math.floor(w / 2);
|
|
1443
|
+
const dist = (Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)));
|
|
1444
|
+
snapPickResult.push({
|
|
1445
|
+
x,
|
|
1446
|
+
y,
|
|
1447
|
+
dist,
|
|
1448
|
+
isVertex: snapToVertex && snapToEdge ? snapPickResultArray[i + 3] > layerParamsSnap.length / 2 : snapToVertex,
|
|
1449
|
+
result: [
|
|
1450
|
+
snapPickResultArray[i + 0],
|
|
1451
|
+
snapPickResultArray[i + 1],
|
|
1452
|
+
snapPickResultArray[i + 2],
|
|
1453
|
+
snapPickResultArray[i + 3],
|
|
1454
|
+
],
|
|
1455
|
+
normal: [
|
|
1456
|
+
snapPickNormalResultArray[i + 0],
|
|
1457
|
+
snapPickNormalResultArray[i + 1],
|
|
1458
|
+
snapPickNormalResultArray[i + 2],
|
|
1459
|
+
snapPickNormalResultArray[i + 3],
|
|
1460
|
+
],
|
|
1461
|
+
id: [
|
|
1462
|
+
snapPickIdResultArray[i + 0],
|
|
1463
|
+
snapPickIdResultArray[i + 1],
|
|
1464
|
+
snapPickIdResultArray[i + 2],
|
|
1465
|
+
snapPickIdResultArray[i + 3],
|
|
1466
|
+
]
|
|
1467
|
+
});
|
|
1477
1468
|
}
|
|
1478
|
-
}
|
|
1469
|
+
}
|
|
1479
1470
|
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1471
|
+
let snappedWorldPos = null;
|
|
1472
|
+
let snappedWorldNormal = null;
|
|
1473
|
+
let snappedPickable = null;
|
|
1474
|
+
let snapType = null;
|
|
1475
|
+
|
|
1476
|
+
if (snapPickResult.length > 0) {
|
|
1477
|
+
// vertex snap first, then edge snap
|
|
1478
|
+
snapPickResult.sort((a, b) => {
|
|
1479
|
+
if (a.isVertex !== b.isVertex) {
|
|
1480
|
+
return a.isVertex ? -1 : 1;
|
|
1481
|
+
} else {
|
|
1482
|
+
return a.dist - b.dist;
|
|
1483
|
+
}
|
|
1484
|
+
});
|
|
1484
1485
|
|
|
1485
|
-
|
|
1486
|
+
snapType = snapPickResult[0].isVertex ? "vertex" : "edge";
|
|
1487
|
+
const snapPick = snapPickResult[0].result;
|
|
1488
|
+
const snapPickNormal = snapPickResult[0].normal;
|
|
1489
|
+
const snapPickId = snapPickResult[0].id;
|
|
1486
1490
|
|
|
1487
|
-
|
|
1488
|
-
const scale = pickedLayerParmas.coordinateScale;
|
|
1491
|
+
const pickedLayerParmas = layerParamsSnap[snapPick[3]];
|
|
1489
1492
|
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
snapPickNormal[1] / math.MAX_INT,
|
|
1493
|
-
snapPickNormal[2] / math.MAX_INT,
|
|
1494
|
-
]);
|
|
1493
|
+
const origin = pickedLayerParmas.origin;
|
|
1494
|
+
const scale = pickedLayerParmas.coordinateScale;
|
|
1495
1495
|
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1496
|
+
snappedWorldNormal = math.normalizeVec3([
|
|
1497
|
+
snapPickNormal[0] / math.MAX_INT,
|
|
1498
|
+
snapPickNormal[1] / math.MAX_INT,
|
|
1499
|
+
snapPickNormal[2] / math.MAX_INT,
|
|
1500
|
+
]);
|
|
1501
1501
|
|
|
1502
|
-
|
|
1502
|
+
snappedWorldPos = [
|
|
1503
|
+
snapPick[0] * scale[0] + origin[0],
|
|
1504
|
+
snapPick[1] * scale[1] + origin[1],
|
|
1505
|
+
snapPick[2] * scale[2] + origin[2],
|
|
1506
|
+
];
|
|
1507
|
+
|
|
1508
|
+
snappedPickable = pickIDs.items[
|
|
1503
1509
|
snapPickId[0]
|
|
1504
1510
|
+ (snapPickId[1] << 8)
|
|
1505
1511
|
+ (snapPickId[2] << 16)
|
|
1506
1512
|
+ (snapPickId[3] << 24)
|
|
1507
|
-
|
|
1508
|
-
|
|
1513
|
+
];
|
|
1514
|
+
}
|
|
1509
1515
|
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1516
|
+
if (null === worldPos && null == snappedWorldPos) { // If neither regular pick or snap pick, return null
|
|
1517
|
+
return null;
|
|
1518
|
+
}
|
|
1513
1519
|
|
|
1514
|
-
|
|
1520
|
+
let snappedCanvasPos = null;
|
|
1515
1521
|
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1522
|
+
if (null !== snappedWorldPos) {
|
|
1523
|
+
snappedCanvasPos = scene.camera.projectWorldPos(snappedWorldPos);
|
|
1524
|
+
}
|
|
1525
|
+
|
|
1526
|
+
const snappedEntity = (snappedPickable && snappedPickable.delegatePickedEntity) ? snappedPickable.delegatePickedEntity() : snappedPickable;
|
|
1519
1527
|
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
snappedCanvasPos,
|
|
1531
|
-
snappedEntity,
|
|
1532
|
-
entity: snappedEntity
|
|
1528
|
+
pickResult.reset();
|
|
1529
|
+
pickResult.snappedToEdge = (snapType === "edge");
|
|
1530
|
+
pickResult.snappedToVertex = (snapType === "vertex");
|
|
1531
|
+
pickResult.worldPos = snappedWorldPos;
|
|
1532
|
+
pickResult.worldNormal = snappedWorldNormal;
|
|
1533
|
+
pickResult.entity = snappedEntity;
|
|
1534
|
+
pickResult.canvasPos = canvasPos;
|
|
1535
|
+
pickResult.snappedCanvasPos = snappedCanvasPos || canvasPos;
|
|
1536
|
+
|
|
1537
|
+
return pickResult;
|
|
1533
1538
|
};
|
|
1534
|
-
};
|
|
1539
|
+
})();
|
|
1535
1540
|
|
|
1536
1541
|
function unpackDepth(depthZ) {
|
|
1537
1542
|
const vec = [depthZ[0] / 256.0, depthZ[1] / 256.0, depthZ[2] / 256.0, depthZ[3] / 256.0];
|