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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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 {{worldPos:number[],snappedWorldPos:null|number[],snappedCanvasPos:null|number[], snapType:null|"vertex"|"edge"}}
1286
+ * @param pickResult
1287
+ * @returns {PickResult}
1288
1288
  */
1289
- this.snapPick = function (canvasPos, snapRadiusInPixels = 30, snapToVertex = true, snapToEdge = true) {
1290
-
1291
- if (!snapToVertex && !snapToEdge) {
1292
- return this.pick({canvasPos, pickSurface: true});
1293
- }
1289
+ this.snapPick = (function () {
1294
1290
 
1295
- const resolutionScale = scene.canvas.resolutionScale;
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
- frameCtx.snapVectorA = [
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
- frameCtx.snapInvVectorAB = [
1317
- gl.drawingBufferWidth / (2 * snapRadiusInPixels),
1318
- gl.drawingBufferHeight / (2 * snapRadiusInPixels),
1319
- ];
1295
+ if (!snapToVertex && !snapToEdge) {
1296
+ return this.pick({canvasPos, pickSurface: true});
1297
+ }
1320
1298
 
1321
- // Bind and clear the snap render target
1299
+ const resolutionScale = scene.canvas.resolutionScale;
1322
1300
 
1323
- vertexPickBuffer.bind(gl.RGBA32I, gl.RGBA32I, gl.RGBA8UI);
1324
- gl.viewport(0, 0, vertexPickBuffer.size[0], vertexPickBuffer.size[1]);
1325
- gl.enable(gl.DEPTH_TEST);
1326
- gl.frontFace(gl.CCW);
1327
- gl.disable(gl.CULL_FACE);
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
- const pickViewMatrix = scene.camera.viewMatrix;
1341
- const pickProjMatrix = scene.camera.projMatrix;
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
- for (let type in drawableTypeInfo) {
1344
- if (drawableTypeInfo.hasOwnProperty(type)) {
1345
- const drawableList = drawableTypeInfo[type].drawableList;
1346
- for (let i = 0, len = drawableList.length; i < len; i++) {
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
- // a) init z-buffer
1356
- gl.drawBuffers([gl.COLOR_ATTACHMENT0, gl.COLOR_ATTACHMENT1, gl.COLOR_ATTACHMENT2]);
1357
- const layerParamsSurface = snapInitDepthBuf(frameCtx);
1322
+ frameCtx.snapInvVectorAB = [
1323
+ gl.drawingBufferWidth / (2 * snapRadiusInPixels),
1324
+ gl.drawingBufferHeight / (2 * snapRadiusInPixels),
1325
+ ];
1358
1326
 
1359
- // b) snap-pick
1360
- const layerParamsSnap = []
1361
- frameCtx.snapPickLayerParams = layerParamsSnap;
1327
+ // Bind and clear the snap render target
1362
1328
 
1363
- gl.depthMask(false);
1364
- gl.drawBuffers([gl.COLOR_ATTACHMENT0]);
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
- if (snapToVertex && snapToEdge) {
1367
- frameCtx.snapMode = "edge";
1368
- snapPickDrawSnapDepths(frameCtx);
1342
+ //////////////////////////////////
1343
+ // Set view and proj mats for VBO renderers
1344
+ ///////////////////////////////////////
1369
1345
 
1370
- frameCtx.snapMode = "vertex";
1371
- frameCtx.snapPickLayerNumber++;
1346
+ const pickViewMatrix = scene.camera.viewMatrix;
1347
+ const pickProjMatrix = scene.camera.projMatrix;
1372
1348
 
1373
- snapPickDrawSnapDepths(frameCtx);
1374
- } else {
1375
- frameCtx.snapMode = snapToVertex ? "vertex" : "edge";
1376
-
1377
- snapPickDrawSnapDepths(frameCtx);
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
- gl.depthMask(true);
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
- // Read and decode the snapped coordinates
1365
+ // b) snap-pick
1366
+ const layerParamsSnap = []
1367
+ frameCtx.snapPickLayerParams = layerParamsSnap;
1383
1368
 
1384
- const snapPickResultArray = vertexPickBuffer.readArray(gl.RGBA_INTEGER, gl.INT, Int32Array, 4);
1385
- const snapPickNormalResultArray = vertexPickBuffer.readArray(gl.RGBA_INTEGER, gl.INT, Int32Array, 4, 1);
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
- vertexPickBuffer.unbind();
1372
+ if (snapToVertex && snapToEdge) {
1373
+ frameCtx.snapMode = "edge";
1374
+ snapPickDrawSnapDepths(frameCtx);
1389
1375
 
1390
- // result 1) regular hi-precision world position
1376
+ frameCtx.snapMode = "vertex";
1377
+ frameCtx.snapPickLayerNumber++;
1391
1378
 
1392
- let worldPos = null;
1393
- let worldNormal = null;
1394
- let pickable = null;
1379
+ snapPickDrawSnapDepths(frameCtx);
1380
+ } else {
1381
+ frameCtx.snapMode = snapToVertex ? "vertex" : "edge";
1395
1382
 
1396
- const middleX = snapRadiusInPixels;
1397
- const middleY = snapRadiusInPixels;
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
- if (pickResultMiddleXY[3] !== 0) {
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
- // result 2) hi-precision snapped (to vertex/edge) world position
1428
-
1429
- let snapPickResult = [];
1430
-
1431
- for (let i = 0; i < snapPickResultArray.length; i += 4) {
1432
- if (snapPickResultArray[i + 3] > 0) {
1433
- const pixelNumber = Math.floor(i / 4);
1434
- const w = vertexPickBuffer.size[0];
1435
- const x = pixelNumber % w - Math.floor(w / 2);
1436
- const y = Math.floor(pixelNumber / w) - Math.floor(w / 2);
1437
- const dist = (Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)));
1438
- snapPickResult.push({
1439
- x,
1440
- y,
1441
- dist,
1442
- isVertex: snapToVertex && snapToEdge ? snapPickResultArray[i + 3] > layerParamsSnap.length / 2 : snapToVertex,
1443
- result: [
1444
- snapPickResultArray[i + 0],
1445
- snapPickResultArray[i + 1],
1446
- snapPickResultArray[i + 2],
1447
- snapPickResultArray[i + 3],
1448
- ],
1449
- normal: [
1450
- snapPickNormalResultArray[i + 0],
1451
- snapPickNormalResultArray[i + 1],
1452
- snapPickNormalResultArray[i + 2],
1453
- snapPickNormalResultArray[i + 3],
1454
- ],
1455
- id: [
1456
- snapPickIdResultArray[i + 0],
1457
- snapPickIdResultArray[i + 1],
1458
- snapPickIdResultArray[i + 2],
1459
- snapPickIdResultArray[i + 3],
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
- if (snapPickResult.length > 0) {
1471
- // vertex snap first, then edge snap
1472
- snapPickResult.sort((a, b) => {
1473
- if (a.isVertex !== b.isVertex) {
1474
- return a.isVertex ? -1 : 1;
1475
- } else {
1476
- return a.dist - b.dist;
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
- snapType = snapPickResult[0].isVertex ? "vertex" : "edge";
1481
- const snapPick = snapPickResult[0].result;
1482
- const snapPickNormal = snapPickResult[0].normal;
1483
- const snapPickId = snapPickResult[0].id;
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
- const pickedLayerParmas = layerParamsSnap[snapPick[3]];
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
- const origin = pickedLayerParmas.origin;
1488
- const scale = pickedLayerParmas.coordinateScale;
1491
+ const pickedLayerParmas = layerParamsSnap[snapPick[3]];
1489
1492
 
1490
- snappedWorldNormal = math.normalizeVec3([
1491
- snapPickNormal[0] / math.MAX_INT,
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
- snappedWorldPos = [
1497
- snapPick[0] * scale[0] + origin[0],
1498
- snapPick[1] * scale[1] + origin[1],
1499
- snapPick[2] * scale[2] + origin[2],
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
- snappedPickable = pickIDs.items[
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
- if (null === worldPos && null == snappedWorldPos) { // If neither regular pick or snap pick, return null
1511
- return null;
1512
- }
1516
+ if (null === worldPos && null == snappedWorldPos) { // If neither regular pick or snap pick, return null
1517
+ return null;
1518
+ }
1513
1519
 
1514
- let snappedCanvasPos = null;
1520
+ let snappedCanvasPos = null;
1515
1521
 
1516
- if (null !== snappedWorldPos) {
1517
- snappedCanvasPos = scene.camera.projectWorldPos(snappedWorldPos);
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
- const snappedEntity = (snappedPickable && snappedPickable.delegatePickedEntity) ? snappedPickable.delegatePickedEntity() : snappedPickable;
1521
-
1522
- return {
1523
- snapType,
1524
- snappedToVertex: snapType === "vertex",
1525
- snappedToEdge: snapType === "edge",
1526
- worldPos,
1527
- worldNormal,
1528
- snappedWorldPos,
1529
- snappedWorldNormal,
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];