@xeokit/xeokit-sdk 2.6.64 → 2.6.66

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.
Files changed (36) hide show
  1. package/dist/xeokit-sdk.cjs.js +277 -272
  2. package/dist/xeokit-sdk.es.js +277 -272
  3. package/dist/xeokit-sdk.es5.js +132 -119
  4. package/dist/xeokit-sdk.min.cjs.js +5 -5
  5. package/dist/xeokit-sdk.min.es.js +5 -5
  6. package/dist/xeokit-sdk.min.es5.js +4 -4
  7. package/package.json +1 -1
  8. package/src/extras/PointerCircle/PointerCircle.js +1 -1
  9. package/src/extras/PointerLens/PointerLens.js +27 -46
  10. package/src/plugins/AngleMeasurementsPlugin/AngleMeasurementsTouchControl.js +29 -20
  11. package/src/plugins/AnnotationsPlugin/Annotation.js +3 -0
  12. package/src/plugins/DistanceMeasurementsPlugin/DistanceMeasurementsTouchControl.js +27 -33
  13. package/src/plugins/SectionPlanesPlugin/Control.js +36 -126
  14. package/src/plugins/TreeViewPlugin/TreeViewPlugin.js +10 -4
  15. package/src/plugins/lib/html/MenuEvent.js +3 -1
  16. package/src/viewer/scene/model/SceneModel.js +1 -0
  17. package/src/viewer/scene/model/dtx/triangles/DTXTrianglesLayer.js +1 -2
  18. package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesColorRenderer.js +4 -1
  19. package/src/viewer/scene/model/vbo/instancing/lines/VBOInstancingLinesLayer.js +1 -1
  20. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesColorRenderer.js +4 -1
  21. package/src/viewer/scene/sectionPlane/SectionPlane.js +79 -1
  22. package/src/viewer/scene/webgl/Renderer.js +9 -3
  23. package/types/extras/PointerCircle/PointerCircle.d.ts +50 -0
  24. package/types/extras/PointerCircle/index.d.ts +1 -0
  25. package/types/plugins/AngleMeasurementsPlugin/index.d.ts +2 -1
  26. package/types/plugins/CityJSONLoaderPlugin/CityJSONLoaderPlugin.d.ts +4 -0
  27. package/types/plugins/DotBIMLoaderPlugin/DotBIMLoaderPlugin.d.ts +121 -0
  28. package/types/plugins/DotBIMLoaderPlugin/index.d.ts +1 -0
  29. package/types/plugins/GLTFLoaderPlugin/GLTFLoaderPlugin.d.ts +4 -0
  30. package/types/plugins/LASLoaderPlugin/LASLoaderPlugin.d.ts +4 -0
  31. package/types/plugins/STLLoaderPlugin/STLLoaderPlugin.d.ts +4 -0
  32. package/types/plugins/TreeViewPlugin/TreeViewPlugin.d.ts +4 -0
  33. package/types/plugins/WebIFCLoaderPlugin/WebIFCLoaderPlugin.d.ts +4 -0
  34. package/types/plugins/XKTLoaderPlugin/XKTLoaderPlugin.d.ts +19 -1
  35. package/types/plugins/index.d.ts +2 -0
  36. package/types/plugins/lib/ui/index.d.ts +12 -0
@@ -132,15 +132,13 @@ class Control {
132
132
  });
133
133
 
134
134
  const handlers = { };
135
- const addAxis = (rgb, axisDirection, hoopDirection) => {
135
+ const addAxis = (rgb, hoopRot) => {
136
+ const axisDirection = math.mulVec3Scalar(rgb, -1, math.vec3());
136
137
  const material = colorMaterial(rgb);
137
138
 
138
- const rotateToHorizontal = math.rotationMat4v(270 * math.DEGTORAD, [1, 0, 0], math.identityMat4());
139
- const hoopRotation = math.quaternionToRotationMat4(math.vec3PairToQuaternion([ 0, 1, 0 ], hoopDirection), math.identityMat4());
140
- const hoopMatrix = math.mulMat4(hoopRotation, rotateToHorizontal, math.identityMat4());
141
-
139
+ const hoopMatrix = math.quaternionToRotationMat4(hoopRot, math.identityMat4());
140
+ math.mulMat4(math.rotationMat4v(Math.PI, [0,1,0], math.mat4()), hoopMatrix, hoopMatrix);
142
141
  const scale = math.scaleMat4v([0.6, 0.6, 0.6], math.identityMat4());
143
-
144
142
  const scaledArrowMatrix = (t, matR) => {
145
143
  const matT = math.translateMat4v(t, math.identityMat4());
146
144
  const ret = math.identityMat4();
@@ -209,7 +207,8 @@ class Control {
209
207
  }), NO_STATE_INHERIT);
210
208
 
211
209
 
212
- const axisRotation = math.quaternionToRotationMat4(math.vec3PairToQuaternion([ 0, 1, 0 ], axisDirection), math.identityMat4());
210
+ const axisRotation = math.quaternionToRotationMat4(math.vec3PairToQuaternion([ 0, 1, 0 ], rgb), math.identityMat4());
211
+ math.mulMat4(math.rotationMat4v(Math.PI, [0,1,0], math.mat4()), axisRotation, axisRotation);
213
212
 
214
213
  const translatedAxisMatrix = (yOffset) => math.mulMat4(axisRotation, math.translateMat4c(0, yOffset, 0, math.identityMat4()), math.identityMat4());
215
214
  const arrowMatrix = translatedAxisMatrix(arrowLength + .1);
@@ -270,8 +269,10 @@ class Control {
270
269
  isObject: false
271
270
  }), NO_STATE_INHERIT);
272
271
 
272
+ const localToWorldVec = (localVec, worldVec) => math.vec3ApplyQuaternion(rootNode.quaternion, localVec, worldVec);
273
+
273
274
  const closestPointOnAxis = (function() {
274
- const worldAxis = math.vec4();
275
+ const worldAxis = math.vec3();
275
276
  const org = math.vec3();
276
277
  const dir = math.vec3();
277
278
  return (canvasPos, dst) => {
@@ -306,22 +307,39 @@ class Control {
306
307
  if (closestPointOnAxis(canvasPos, tempVec3)) {
307
308
  math.subVec3(tempVec3, initOffset, tempVec3);
308
309
  setPos(tempVec3);
309
- if (self._sectionPlane) {
310
- self._sectionPlane.pos = tempVec3;
310
+ if (this._sectionPlane) {
311
+ this._sectionPlane.pos = tempVec3;
311
312
  }
312
313
  }
313
314
  });
314
315
  }
315
316
  };
316
317
 
317
- const lastCanvasPos = math.vec2();
318
318
  handlers[rotateHandle.id] = {
319
319
  setActivated: a => hoop.visible = a,
320
320
  initDragAction: (initCanvasPos) => {
321
- lastCanvasPos.set(initCanvasPos);
321
+ const rotationFromCanvasPos = (function() {
322
+ const planeCanvasPos = camera.projectWorldPos(pos);
323
+ localToWorldVec(rgb, tempVec3);
324
+ math.transformVec3(camera.normalMatrix, tempVec3, tempVec3);
325
+ const axisCoeff = Math.sign(tempVec3[2]);
326
+ return (canvasPos) => {
327
+ const dx = canvasPos[0] - planeCanvasPos[0];
328
+ const dy = canvasPos[1] - planeCanvasPos[1];
329
+ return axisCoeff * Math.atan2(-dy, dx);
330
+ };
331
+ })();
332
+
333
+ let lastRotation = rotationFromCanvasPos(initCanvasPos);
334
+
322
335
  return canvasPos => {
323
- dragRotateSectionPlane(rgb, lastCanvasPos, canvasPos);
324
- lastCanvasPos.set(canvasPos);
336
+ const rotation = rotationFromCanvasPos(canvasPos);
337
+ rootNode.rotate(rgb, (rotation - lastRotation) * 180 / Math.PI);
338
+ if (this._sectionPlane) {
339
+ ignoreNextSectionPlaneDirUpdate = true;
340
+ this._sectionPlane.quaternion = rootNode.quaternion;
341
+ }
342
+ lastRotation = rotation;
325
343
  };
326
344
  }
327
345
  };
@@ -433,9 +451,9 @@ class Control {
433
451
  //
434
452
  //----------------------------------------------------------------------------------------------------------
435
453
 
436
- addAxis([1,0,0], [ 1, 0, 0 ], [ 1, 0, 0 ]),
437
- addAxis([0,1,0], [ 0, -1, 0 ], [ 0, 1, 0 ]),
438
- addAxis([0,0,1], [ 0, 0, -1 ], [ 0, 0, -1 ])
454
+ addAxis([1,0,0], math.vec3PairToQuaternion([1,0,0], [0,0,1])),
455
+ addAxis([0,1,0], math.eulerToQuaternion([90,0,0], "XYZ")),
456
+ addAxis([0,0,1], math.identityQuaternion())
439
457
  ];
440
458
 
441
459
  const cleanups = [ ];
@@ -457,114 +475,6 @@ class Control {
457
475
  cleanups.push(() => scene.off(onSceneTick));
458
476
  }
459
477
 
460
- const getClickCoordsWithinElement = (event, canvasPos) => {
461
- if (!event) {
462
- event = window.event;
463
- canvasPos[0] = event.x;
464
- canvasPos[1] = event.y;
465
- } else {
466
- const element = event.target;
467
- const rect = element.getBoundingClientRect();
468
- canvasPos[0] = event.clientX - rect.left;
469
- canvasPos[1] = event.clientY - rect.top;
470
- }
471
- };
472
-
473
- const localToWorldVec = (function () {
474
- const mat = math.mat4();
475
- return function (localVec, worldVec) {
476
- math.quaternionToMat4(rootNode.quaternion, mat);
477
- math.transformVec3(mat, localVec, worldVec);
478
- math.normalizeVec3(worldVec);
479
- return worldVec;
480
- };
481
- })();
482
-
483
- const getTranslationPlane = (worldAxis, planeNormal) => {
484
- const absX = Math.abs(worldAxis[0]);
485
- if (absX > Math.abs(worldAxis[1]) && absX > Math.abs(worldAxis[2])) {
486
- math.cross3Vec3(worldAxis, [0, 1, 0], planeNormal);
487
- } else {
488
- math.cross3Vec3(worldAxis, [1, 0, 0], planeNormal);
489
- }
490
- math.cross3Vec3(planeNormal, worldAxis, planeNormal);
491
- math.normalizeVec3(planeNormal);
492
- };
493
-
494
- const self = this;
495
- var dragRotateSectionPlane = (function () {
496
- const p1 = math.vec4();
497
- const p2 = math.vec4();
498
- const c = math.vec4();
499
- const worldAxis = math.vec4();
500
- const dir = math.vec3();
501
- const mat = math.mat4();
502
- const planeNormal = math.vec3();
503
- return function (baseAxis, fromMouse, toMouse) {
504
- localToWorldVec(baseAxis, worldAxis);
505
- const hasData = getPointerPlaneIntersect(fromMouse, worldAxis, p1) && getPointerPlaneIntersect(toMouse, worldAxis, p2);
506
- if (!hasData) { // Find intersections with view plane and project down to origin
507
- getTranslationPlane(worldAxis, planeNormal);
508
- getPointerPlaneIntersect(fromMouse, planeNormal, p1, 1); // Ensure plane moves closer to camera so angles become workable
509
- getPointerPlaneIntersect(toMouse, planeNormal, p2, 1);
510
- var dot = math.dotVec3(p1, worldAxis);
511
- p1[0] -= dot * worldAxis[0];
512
- p1[1] -= dot * worldAxis[1];
513
- p1[2] -= dot * worldAxis[2];
514
- dot = math.dotVec3(p2, worldAxis);
515
- p2[0] -= dot * worldAxis[0];
516
- p2[1] -= dot * worldAxis[1];
517
- p2[2] -= dot * worldAxis[2];
518
- }
519
- math.normalizeVec3(p1);
520
- math.normalizeVec3(p2);
521
- dot = math.dotVec3(p1, p2);
522
- dot = math.clamp(dot, -1.0, 1.0); // Rounding errors cause dot to exceed allowed range
523
- var incDegrees = Math.acos(dot) * math.RADTODEG;
524
- math.cross3Vec3(p1, p2, c);
525
- if (math.dotVec3(c, worldAxis) < 0.0) {
526
- incDegrees = -incDegrees;
527
- }
528
- rootNode.rotate(baseAxis, incDegrees);
529
-
530
- if (self._sectionPlane) {
531
- math.quaternionToMat4(rootNode.quaternion, mat); // << ---
532
- math.transformVec3(mat, [0, 0, 1], dir);
533
- ignoreNextSectionPlaneDirUpdate = true;
534
- self._sectionPlane.dir = dir;
535
- }
536
- };
537
- })();
538
-
539
- var getPointerPlaneIntersect = (function () {
540
- const dir = math.vec4([0, 0, 0, 1]);
541
- const matrix = math.mat4();
542
- return function (mouse, axis, dest, offset) {
543
- offset = offset || 0;
544
- dir[0] = mouse[0] / canvas.width * 2.0 - 1.0;
545
- dir[1] = -(mouse[1] / canvas.height * 2.0 - 1.0);
546
- dir[2] = 0.0;
547
- dir[3] = 1.0;
548
- math.mulMat4(camera.projMatrix, camera.viewMatrix, matrix); // Unproject norm device coords to view coords
549
- math.inverseMat4(matrix);
550
- math.transformVec4(matrix, dir, dir);
551
- math.mulVec4Scalar(dir, 1.0 / dir[3]); // This is now point A on the ray in world space
552
- var rayO = camera.eye; // The direction
553
- math.subVec4(dir, rayO, dir);
554
- const origin = self._sectionPlane.pos; // Plane origin:
555
- var d = -math.dotVec3(origin, axis) - offset;
556
- var dot = math.dotVec3(axis, dir);
557
- if (Math.abs(dot) > 0.005) {
558
- var t = -(math.dotVec3(axis, rayO) + d) / dot;
559
- math.mulVec3Scalar(dir, t, dest);
560
- math.addVec3(dest, rayO);
561
- math.subVec3(dest, origin, dest);
562
- return true;
563
- }
564
- return false;
565
- };
566
- })();
567
-
568
478
  {
569
479
  let deactivateActive = null;
570
480
  let currentDrag = null;
@@ -681,7 +591,7 @@ class Control {
681
591
  this.id = sectionPlane.id;
682
592
  this._sectionPlane = sectionPlane;
683
593
  const setPosFromSectionPlane = () => setPos(sectionPlane.pos);
684
- const setDirFromSectionPlane = () => rootNode.quaternion = math.vec3PairToQuaternion(zeroVec, sectionPlane.dir, quat);
594
+ const setDirFromSectionPlane = () => rootNode.quaternion = sectionPlane.quaternion;
685
595
  setPosFromSectionPlane();
686
596
  setDirFromSectionPlane();
687
597
  const onSectionPlanePos = sectionPlane.on("pos", setPosFromSectionPlane);
@@ -1,5 +1,5 @@
1
- import {Plugin} from "../../viewer/Plugin.js";
2
- import {RenderService} from "./RenderService.js";
1
+ import { Plugin } from "../../viewer/Plugin.js";
2
+ import { RenderService } from "./RenderService.js";
3
3
 
4
4
  const treeViews = [];
5
5
 
@@ -363,6 +363,8 @@ export class TreeViewPlugin extends Plugin {
363
363
  * @param {RenderService} [cfg.renderService] Optional {@link RenderService} to use. Defaults to the {@link TreeViewPlugin}'s default {@link RenderService}.
364
364
  * @param {Boolean} [cfg.showIndeterminate=false] When true, will show indeterminate state for checkboxes when some but not all child nodes are checked
365
365
  * @param {Boolean} [cfg.showProjectNode=false] When true, will show top level project node when hierarchy is set to "storeys"
366
+ * @param {Function} [cfg.elevationSortFunction] Optional function to replace the default elevation sort function. The function should take two nodes and return -1, 0 or 1.
367
+ * @param {Function} [cfg.defaultSortFunction] Optional function to replace the default sort function. The function should take two nodes and return -1, 0 or 1.
366
368
  */
367
369
  constructor(viewer, cfg = {}) {
368
370
 
@@ -416,6 +418,8 @@ export class TreeViewPlugin extends Plugin {
416
418
  this._renderService = cfg.renderService || new RenderService();
417
419
  this._showIndeterminate = cfg.showIndeterminate ?? false;
418
420
  this._showProjectNode = cfg.showProjectNode ?? false;
421
+ this._elevationSortFunction = cfg.elevationSortFunction ?? undefined;
422
+ this._defaultSortFunction = cfg.defaultSortFunction ?? undefined;
419
423
 
420
424
  if (!this._renderService) {
421
425
  throw new Error('TreeViewPlugin: no render service set');
@@ -1229,9 +1233,11 @@ export class TreeViewPlugin extends Plugin {
1229
1233
  }
1230
1234
  const firstChild = children[0];
1231
1235
  if ((this._hierarchy === "storeys" || this._hierarchy === "containment") && firstChild.type === "IfcBuildingStorey") {
1232
- children.sort(this._getSpatialSortFunc());
1236
+ if (this._elevationSortFunction) children.sort(this._elevationSortFunction);
1237
+ else children.sort(this._getSpatialSortFunc());
1233
1238
  } else {
1234
- children.sort(this._alphaSortFunc);
1239
+ if (this._defaultSortFunction) children.sort(this._defaultSortFunction)
1240
+ else children.sort(this._alphaSortFunc);
1235
1241
  }
1236
1242
  for (let i = 0, len = children.length; i < len; i++) {
1237
1243
  const node = children[i];
@@ -1,6 +1,7 @@
1
1
  import { os } from "../../../viewer/utils/os.js";
2
2
 
3
- export function addContextMenuListener(elem, callback) {
3
+ //failCallback will be called when the press is not long enough to considered a long press
4
+ export function addContextMenuListener(elem, callback, failCallback = () => {}) {
4
5
  if (!elem || !callback) return;
5
6
 
6
7
  let timeout = null;
@@ -54,6 +55,7 @@ export function addContextMenuListener(elem, callback) {
54
55
  const touchEndHandler = (event) => {
55
56
  event.preventDefault();
56
57
  if (timeout) {
58
+ failCallback(event);
57
59
  clearTimeout(timeout);
58
60
  timeout = null;
59
61
  }
@@ -1563,6 +1563,7 @@ export class SceneModel extends Component {
1563
1563
  set matrix(value) {
1564
1564
  this._matrix.set(value || DEFAULT_MATRIX);
1565
1565
  math.decomposeMat4(this._matrix, this._position, this._quaternion, this._scale);
1566
+ math.quaternionToEuler(this._quaternion, "XYZ", this._rotation);
1566
1567
  this._matrixDirty = false;
1567
1568
  this._setWorldMatrixDirty();
1568
1569
  this._sceneModelDirty();
@@ -1122,8 +1122,7 @@ export class DTXTrianglesLayer {
1122
1122
  worldPos[2] = positions[i + 2];
1123
1123
  worldPos[3] = 1.0;
1124
1124
  math.decompressPosition(worldPos, positionsDecodeMatrix);
1125
- math.transformPoint4(this.model.worldMatrix, worldPos, worldPos);
1126
- math.transformPoint4(this.model.worldMatrix, worldPos, worldPos);
1125
+ math.mulMat4v4(this.model.worldMatrix, worldPos, worldPos);
1127
1126
  worldPos[0] += offsetX;
1128
1127
  worldPos[1] += offsetY;
1129
1128
  worldPos[2] += offsetZ;
@@ -221,7 +221,10 @@ export class TrianglesColorRenderer extends TrianglesBatchingRenderer {
221
221
  }
222
222
 
223
223
  if (scene.logarithmicDepthBufferEnabled) {
224
- src.push(" gl_FragDepth = isPerspective == 0.0 ? gl_FragCoord.z : log2( vFragDepth ) * logDepthBufFC * 0.5;");
224
+ src.push(" float dx = dFdx(vFragDepth);")
225
+ src.push(" float dy = dFdy(vFragDepth);")
226
+ src.push(" float diff = sqrt(dx*dx+dy*dy);");
227
+ src.push(" gl_FragDepth = isPerspective == 0.0 ? gl_FragCoord.z : log2( vFragDepth + diff ) * logDepthBufFC * 0.5;");
225
228
  }
226
229
 
227
230
  if (this._withSAO) {
@@ -497,7 +497,7 @@ class VBOInstancingLinesLayer {
497
497
 
498
498
  let pickFlag = (visible && !culled && pickable) ? RENDER_PASSES.PICK : RENDER_PASSES.NOT_RENDERED;
499
499
 
500
- const clippableFlag = !!(flags & ENTITY_FLAGS.CLIPPABLE) ? 255 : 0;
500
+ const clippableFlag = !!(flags & ENTITY_FLAGS.CLIPPABLE) ? 1 : 0;
501
501
 
502
502
  let vertFlag = 0;
503
503
  vertFlag |= colorFlag;
@@ -234,7 +234,10 @@ class TrianglesColorRenderer extends TrianglesInstancingRenderer {
234
234
  }
235
235
 
236
236
  if (scene.logarithmicDepthBufferEnabled) {
237
- src.push(" gl_FragDepth = isPerspective == 0.0 ? gl_FragCoord.z : log2( vFragDepth ) * logDepthBufFC * 0.5;");
237
+ src.push(" float dx = dFdx(vFragDepth);")
238
+ src.push(" float dy = dFdy(vFragDepth);")
239
+ src.push(" float diff = sqrt(dx*dx+dy*dy);");
240
+ src.push(" gl_FragDepth = isPerspective == 0.0 ? gl_FragCoord.z : log2( vFragDepth + diff ) * logDepthBufFC * 0.5;");
238
241
  }
239
242
 
240
243
  // Doing SAO blend in the main solid fill draw shader just so that edge lines can be drawn over the top
@@ -3,6 +3,11 @@ import {RenderState} from '../webgl/RenderState.js';
3
3
  import {math} from "../math/math.js";
4
4
 
5
5
  const tempVec3a = math.vec3();
6
+ const tempVec3b = math.vec3();
7
+ const tempVec4a = math.vec4();
8
+ const front = math.vec3([0, 0, -1]);
9
+ const back = math.vec3([0, 0, 1]);
10
+ const up = math.vec3([0, 1, 0]);
6
11
 
7
12
  /**
8
13
  * @desc An arbitrarily-aligned World-space clipping plane.
@@ -74,6 +79,8 @@ class SectionPlane extends Component {
74
79
  this._state = new RenderState({
75
80
  active: true,
76
81
  pos: math.vec3(),
82
+ quaternion: math.vec4(),
83
+ roll: 0,
77
84
  dir: math.vec3(),
78
85
  dist: 0
79
86
  });
@@ -135,6 +142,59 @@ class SectionPlane extends Component {
135
142
  return this._state.pos;
136
143
  }
137
144
 
145
+ /**
146
+ * Sets the quaternion of this SectionPlane's plane.
147
+ *
148
+ * Default value is ````[0, -1, 0, 0]````.
149
+ *
150
+ * @param {Number[]} value New quaternion.
151
+ */
152
+ set quaternion(value) {
153
+ this._state.quaternion.set(value || [0, 0, 0, -1]);
154
+ math.vec3ApplyQuaternion(this._state.quaternion, back, this._state.dir);
155
+ const quatUp = math.vec3ApplyQuaternion(this._state.quaternion, up, tempVec3a);
156
+ const dirOnlyQ = math.vec3PairToQuaternion(back, this._state.dir, tempVec4a);
157
+ const dirOnlyUp = math.vec3ApplyQuaternion(dirOnlyQ, up, tempVec3b);
158
+ const angle = Math.acos(Math.min(1, math.dotVec3(quatUp, dirOnlyUp)));
159
+ const sign = Math.sign(math.dotVec3(this._state.dir, math.cross3Vec3(quatUp, dirOnlyUp, tempVec3b)));
160
+ this._state.roll = sign * angle;
161
+ this._onDirUpdated();
162
+ }
163
+
164
+ /**
165
+ * Gets the quaternion of this SectionPlane's plane.
166
+ *
167
+ * Default value is ````[0, -1, 0, 0]````.
168
+ *
169
+ * @returns {Number[]} value Current quaternion.
170
+ */
171
+ get quaternion() {
172
+ return this._state.quaternion;
173
+ }
174
+
175
+ /**
176
+ * Sets the roll of this SectionPlane's plane.
177
+ *
178
+ * Default value is ````0````.
179
+ *
180
+ * @param {Number[]} value New roll.
181
+ */
182
+ set roll(value) {
183
+ this._state.roll = value || 0;
184
+ this._onDirRollUpdated();
185
+ }
186
+
187
+ /**
188
+ * Gets the roll of this SectionPlane's plane.
189
+ *
190
+ * Default value is ````0````.
191
+ *
192
+ * @returns {Number[]} value Current roll.
193
+ */
194
+ get roll() {
195
+ return this._state.roll;
196
+ }
197
+
138
198
  /**
139
199
  * Sets the direction of this SectionPlane's plane.
140
200
  *
@@ -143,7 +203,25 @@ class SectionPlane extends Component {
143
203
  * @param {Number[]} value New direction.
144
204
  */
145
205
  set dir(value) {
146
- this._state.dir.set(value || [0, 0, -1]);
206
+ this._state.dir.set(value || front);
207
+ this._onDirRollUpdated();
208
+ }
209
+
210
+ _onDirRollUpdated() {
211
+ math.vec3PairToQuaternion(back, this._state.dir, this._state.quaternion);
212
+
213
+ tempVec4a[0] = 0;
214
+ tempVec4a[1] = 0;
215
+ tempVec4a[2] = -1;
216
+ tempVec4a[3] = this._state.roll;
217
+ math.angleAxisToQuaternion(tempVec4a, tempVec4a);
218
+
219
+ math.mulQuaternions(this._state.quaternion, tempVec4a, this._state.quaternion);
220
+
221
+ this._onDirUpdated();
222
+ }
223
+
224
+ _onDirUpdated() {
147
225
  this._state.dist = (-math.dotVec3(this._state.pos, this._state.dir));
148
226
  this.glRedraw();
149
227
  this.fire("dir", this._state.dir);
@@ -935,6 +935,9 @@ const Renderer = function (scene, options) {
935
935
  pickProjMatrix = scene.camera.projMatrix;
936
936
  projection = scene.camera.projection;
937
937
 
938
+ nearAndFar[0] = scene.camera.project.near;
939
+ nearAndFar[1] = scene.camera.project.far;
940
+
938
941
  pickResult.canvasPos = params.canvasPos;
939
942
 
940
943
  } else {
@@ -948,6 +951,9 @@ const Renderer = function (scene, options) {
948
951
  pickProjMatrix = scene.camera.projMatrix;
949
952
  projection = scene.camera.projection;
950
953
 
954
+ nearAndFar[0] = scene.camera.project.near;
955
+ nearAndFar[1] = scene.camera.project.far;
956
+
951
957
  } else {
952
958
 
953
959
  worldRayOrigin.set(params.origin || [0, 0, 0]);
@@ -967,6 +973,9 @@ const Renderer = function (scene, options) {
967
973
  pickProjMatrix = scene.camera.ortho.matrix;
968
974
  projection = "ortho";
969
975
 
976
+ nearAndFar[0] = scene.camera.ortho.near;
977
+ nearAndFar[1] = scene.camera.ortho.far;
978
+
970
979
  pickResult.origin = worldRayOrigin;
971
980
  pickResult.direction = worldRayDir;
972
981
  }
@@ -1021,9 +1030,6 @@ const Renderer = function (scene, options) {
1021
1030
 
1022
1031
  if (pickable.canPickWorldPos && pickable.canPickWorldPos()) {
1023
1032
 
1024
- nearAndFar[0] = scene.camera.project.near;
1025
- nearAndFar[1] = scene.camera.project.far;
1026
-
1027
1033
  gpuPickWorldPos(pickBuffer, pickable, canvasPos, pickViewMatrix, pickProjMatrix, nearAndFar, pickResult);
1028
1034
 
1029
1035
  if (params.pickSurfaceNormal !== false) {
@@ -0,0 +1,50 @@
1
+ import {Viewer} from "../../viewer";
2
+
3
+ /**
4
+ * A PointerCircle shows a circle, centered at the position of the
5
+ * mouse or touch pointer.
6
+ */
7
+ export class PointerCircle {
8
+ /**
9
+ * Constructs a new PointerCircle.
10
+ * @param {Viewer} viewer The Viewer
11
+ * @param {Object} [cfg] PointerCircle configuration.
12
+ * @param {boolean} [cfg.active=true] Whether PointerCircle is active. The PointerCircle can only be shown when this is `true` (default).
13
+ */
14
+ constructor(viewer: Viewer, cfg?: {
15
+ active?: boolean;
16
+ });
17
+
18
+ /**
19
+ * Show the circle at the given canvas coordinates and begin shrinking it.
20
+ */
21
+ start(circlePos: number[]): void;
22
+
23
+ /**
24
+ * Stop the shrinking circle and hide it.
25
+ */
26
+ stop(): void;
27
+
28
+ /**
29
+ * Sets the zoom factor for the lens.
30
+ *
31
+ * This is `2` by default.
32
+ *
33
+ * @param {number} durationMs
34
+ */
35
+ set durationMs(durationMs: number);
36
+
37
+ /**
38
+ * Gets the zoom factor for the lens.
39
+ *
40
+ * This is `2` by default.
41
+ *
42
+ * @returns {number} Number
43
+ */
44
+ get durationMs(): number;
45
+
46
+ /**
47
+ * Destroys this PointerCircle.
48
+ */
49
+ destroy(): void;
50
+ }
@@ -0,0 +1 @@
1
+ export * from "./PointerCircle";
@@ -1,3 +1,4 @@
1
1
  export * from "./AngleMeasurementsPlugin";
2
2
  export * from "./AngleMeasurementsControl";
3
- export * from "./AngleMeasurementsMouseControl";
3
+ export * from "./AngleMeasurementsMouseControl";
4
+ export * from "./AngleMeasurementsTouchControl";
@@ -10,6 +10,10 @@ export declare interface ICityJSONDefaultDataSource {
10
10
  * @param {Function} error Callback fired on error.
11
11
  */
12
12
  getCityJSON(src: string | number, ok: (json: any)=> void, error: (e: Error)=> void): void;
13
+
14
+ get cacheBuster(): boolean;
15
+
16
+ set cacheBuster(value: boolean);
13
17
  }
14
18
 
15
19
  export declare type CityJSONLoaderPluginConfiguration = {