@inweb/viewer-three 25.10.0 → 25.11.0
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/viewer-three.js +1061 -1265
- package/dist/viewer-three.js.map +1 -1
- package/dist/viewer-three.min.js +2 -2
- package/dist/viewer-three.module.js +853 -117
- package/dist/viewer-three.module.js.map +1 -1
- package/lib/Viewer/Viewer.d.ts +8 -2
- package/lib/Viewer/commands/index.d.ts +1 -1
- package/lib/Viewer/draggers/OrbitDragger.d.ts +1 -1
- package/package.json +5 -5
- package/src/Viewer/Viewer.ts +36 -14
- package/src/Viewer/commands/{Unselect.ts → ClearSelected.ts} +4 -3
- package/src/Viewer/commands/Explode.ts +1 -1
- package/src/Viewer/commands/HideSelected.ts +2 -2
- package/src/Viewer/commands/IsolateSelected.ts +1 -1
- package/src/Viewer/commands/ResetView.ts +1 -1
- package/src/Viewer/commands/SetSelected.ts +1 -1
- package/src/Viewer/commands/ShowAll.ts +1 -1
- package/src/Viewer/commands/index.ts +1 -1
- package/src/Viewer/controls/OrbitControls.js +1007 -0
- package/src/Viewer/controls/WalkControls.ts +1 -0
- package/src/Viewer/draggers/OrbitDragger.ts +26 -4
- /package/lib/Viewer/commands/{Unselect.d.ts → ClearSelected.d.ts} +0 -0
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Vector2, Raycaster, MeshBasicMaterial, Box3, Vector3, Sphere, LoadingManager, LoaderUtils, EventDispatcher, MOUSE, TOUCH, Quaternion, Spherical, Clock, Object3D, Euler, Matrix4, LineBasicMaterial, CylinderGeometry, BoxGeometry, BufferGeometry, Float32BufferAttribute, Mesh, OctahedronGeometry, Line, SphereGeometry, TorusGeometry, PlaneGeometry, DoubleSide, Plane, AmbientLight, DirectionalLight, Color, PMREMGenerator, OrthographicCamera, Sprite, CanvasTexture, SRGBColorSpace, SpriteMaterial, Vector4, Scene, PerspectiveCamera, WebGLRenderer, LinearToneMapping } from "three";
|
|
2
2
|
|
|
3
3
|
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
|
|
4
4
|
|
|
5
|
-
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
|
|
6
|
-
|
|
7
5
|
import { RoomEnvironment } from "three/examples/jsm/environments/RoomEnvironment.js";
|
|
8
6
|
|
|
9
7
|
class Commands {
|
|
@@ -105,7 +103,8 @@ function defaultOptions() {
|
|
|
105
103
|
reverseZoomWheel: false,
|
|
106
104
|
enableZoomWheel: true,
|
|
107
105
|
enableGestures: true,
|
|
108
|
-
geometryType: "vsfx"
|
|
106
|
+
geometryType: "vsfx",
|
|
107
|
+
rulerUnit: "Default"
|
|
109
108
|
};
|
|
110
109
|
}
|
|
111
110
|
|
|
@@ -365,6 +364,13 @@ class Options {
|
|
|
365
364
|
this._data.geometryType = value;
|
|
366
365
|
this.change();
|
|
367
366
|
}
|
|
367
|
+
get rulerUnit() {
|
|
368
|
+
return this._data.rulerUnit;
|
|
369
|
+
}
|
|
370
|
+
set rulerUnit(value) {
|
|
371
|
+
this._data.rulerUnit = value;
|
|
372
|
+
this.change();
|
|
373
|
+
}
|
|
368
374
|
}
|
|
369
375
|
|
|
370
376
|
const CanvasEvents = [ "click", "contextmenu", "dblclick", "mousedown", "mouseleave", "mousemove", "mouseup", "pointercancel", "pointerdown", "pointerleave", "pointermove", "pointerup", "touchcancel", "touchend", "touchmove", "touchstart", "wheel" ];
|
|
@@ -390,6 +396,101 @@ commands("ThreeJS").registerCommand("clearMarkup", (viewer => console.warn("clea
|
|
|
390
396
|
|
|
391
397
|
commands("ThreeJS").registerCommandAlias("clearMarkup", "clearOverlay");
|
|
392
398
|
|
|
399
|
+
class SelectionComponent {
|
|
400
|
+
constructor(viewer) {
|
|
401
|
+
this.onPointerDown = event => {
|
|
402
|
+
if (!event.isPrimary || event.button !== 0) return;
|
|
403
|
+
this.getMousePosition(event, this.downPosition);
|
|
404
|
+
};
|
|
405
|
+
this.onPointerUp = event => {
|
|
406
|
+
if (!event.isPrimary) return;
|
|
407
|
+
const upPosition = this.getMousePosition(event, new Vector2);
|
|
408
|
+
if (this.downPosition.distanceTo(upPosition) !== 0) return;
|
|
409
|
+
const intersects = this.getPointerIntersects(upPosition);
|
|
410
|
+
this.clearSelection();
|
|
411
|
+
if (intersects.length > 0) this.select(intersects[0].object);
|
|
412
|
+
this.viewer.update();
|
|
413
|
+
this.viewer.emitEvent({
|
|
414
|
+
type: "select",
|
|
415
|
+
data: undefined,
|
|
416
|
+
handles: this.viewer.getSelected()
|
|
417
|
+
});
|
|
418
|
+
};
|
|
419
|
+
this.onDoubleClick = event => {
|
|
420
|
+
if (event.button !== 0) return;
|
|
421
|
+
this.viewer.executeCommand("zoomToSelected");
|
|
422
|
+
};
|
|
423
|
+
this.optionsChange = () => {
|
|
424
|
+
const {facesColor: facesColor, facesTransparancy: facesTransparancy} = this.viewer.options;
|
|
425
|
+
this.facesMaterial.color.setRGB(facesColor.r / 255, facesColor.g / 255, facesColor.b / 255);
|
|
426
|
+
this.facesMaterial.opacity = (255 - facesTransparancy) / 255;
|
|
427
|
+
this.viewer.update();
|
|
428
|
+
};
|
|
429
|
+
this.viewer = viewer;
|
|
430
|
+
this.raycaster = new Raycaster;
|
|
431
|
+
this.downPosition = new Vector2;
|
|
432
|
+
const {facesColor: facesColor, facesTransparancy: facesTransparancy} = this.viewer.options;
|
|
433
|
+
this.facesMaterial = new MeshBasicMaterial;
|
|
434
|
+
this.facesMaterial.color.setRGB(facesColor.r / 255, facesColor.g / 255, facesColor.b / 255);
|
|
435
|
+
this.facesMaterial.opacity = (255 - facesTransparancy) / 255;
|
|
436
|
+
this.facesMaterial.transparent = true;
|
|
437
|
+
this.viewer.addEventListener("pointerdown", this.onPointerDown);
|
|
438
|
+
this.viewer.addEventListener("pointerup", this.onPointerUp);
|
|
439
|
+
this.viewer.addEventListener("dblclick", this.onDoubleClick);
|
|
440
|
+
this.viewer.addEventListener("optionschange", this.optionsChange);
|
|
441
|
+
}
|
|
442
|
+
dispose() {
|
|
443
|
+
this.facesMaterial.dispose();
|
|
444
|
+
this.viewer.removeEventListener("pointerdown", this.onPointerDown);
|
|
445
|
+
this.viewer.removeEventListener("pointerup", this.onPointerUp);
|
|
446
|
+
this.viewer.removeEventListener("dblclick", this.onDoubleClick);
|
|
447
|
+
this.viewer.removeEventListener("optionschange", this.optionsChange);
|
|
448
|
+
}
|
|
449
|
+
getMousePosition(event, position) {
|
|
450
|
+
const rect = this.viewer.canvas.getBoundingClientRect();
|
|
451
|
+
position.setX((event.clientX - rect.left) / rect.width);
|
|
452
|
+
position.setY((event.clientY - rect.top) / rect.height);
|
|
453
|
+
return position;
|
|
454
|
+
}
|
|
455
|
+
getPointerIntersects(position) {
|
|
456
|
+
const mouse = new Vector2(position.x * 2 - 1, -(position.y * 2) + 1);
|
|
457
|
+
this.raycaster.setFromCamera(mouse, this.viewer.camera);
|
|
458
|
+
const objects = [];
|
|
459
|
+
this.viewer.scene.traverseVisible((child => objects.push(child)));
|
|
460
|
+
return this.raycaster.intersectObjects(objects, false);
|
|
461
|
+
}
|
|
462
|
+
select(object) {
|
|
463
|
+
if (object.isSelected) return;
|
|
464
|
+
object.isSelected = true;
|
|
465
|
+
object.originalMaterial = object.material;
|
|
466
|
+
object.material = this.facesMaterial;
|
|
467
|
+
this.viewer.selected.push(object);
|
|
468
|
+
}
|
|
469
|
+
clearSelection() {
|
|
470
|
+
this.viewer.selected.forEach((object => {
|
|
471
|
+
object.isSelected = false;
|
|
472
|
+
object.material = object.originalMaterial;
|
|
473
|
+
}));
|
|
474
|
+
this.viewer.selected.length = 0;
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
function clearSelected(viewer) {
|
|
479
|
+
const selection = new SelectionComponent(viewer);
|
|
480
|
+
selection.clearSelection();
|
|
481
|
+
selection.dispose();
|
|
482
|
+
viewer.update();
|
|
483
|
+
viewer.emitEvent({
|
|
484
|
+
type: "select",
|
|
485
|
+
data: undefined,
|
|
486
|
+
handles: []
|
|
487
|
+
});
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
commands("ThreeJS").registerCommand("clearSelected", clearSelected);
|
|
491
|
+
|
|
492
|
+
commands("ThreeJS").registerCommandAlias("clearSelected", "unselect");
|
|
493
|
+
|
|
393
494
|
function clearSlices(viewer) {
|
|
394
495
|
viewer.renderer.clippingPlanes = [];
|
|
395
496
|
viewer.update();
|
|
@@ -444,7 +545,7 @@ function explodeScene(scene, scale = 0) {
|
|
|
444
545
|
function explode(viewer, index = 0) {
|
|
445
546
|
viewer.models.forEach((gltf => explodeScene(gltf.scene, index)));
|
|
446
547
|
viewer.update();
|
|
447
|
-
viewer.
|
|
548
|
+
viewer.emitEvent({
|
|
448
549
|
type: "explode",
|
|
449
550
|
data: index
|
|
450
551
|
});
|
|
@@ -550,95 +651,16 @@ function getSelected(viewer) {
|
|
|
550
651
|
|
|
551
652
|
commands("ThreeJS").registerCommand("getSelected", getSelected);
|
|
552
653
|
|
|
553
|
-
class SelectionComponent {
|
|
554
|
-
constructor(viewer) {
|
|
555
|
-
this.onPointerDown = event => {
|
|
556
|
-
if (!event.isPrimary || event.button !== 0) return;
|
|
557
|
-
this.getMousePosition(event, this.downPosition);
|
|
558
|
-
};
|
|
559
|
-
this.onPointerUp = event => {
|
|
560
|
-
if (!event.isPrimary) return;
|
|
561
|
-
const upPosition = this.getMousePosition(event, new Vector2);
|
|
562
|
-
if (this.downPosition.distanceTo(upPosition) !== 0) return;
|
|
563
|
-
const intersects = this.getPointerIntersects(upPosition);
|
|
564
|
-
this.clearSelection();
|
|
565
|
-
if (intersects.length > 0) this.select(intersects[0].object);
|
|
566
|
-
this.viewer.update();
|
|
567
|
-
this.viewer.emitEvent({
|
|
568
|
-
type: "select",
|
|
569
|
-
data: undefined,
|
|
570
|
-
handles: this.viewer.getSelected()
|
|
571
|
-
});
|
|
572
|
-
};
|
|
573
|
-
this.onDoubleClick = event => {
|
|
574
|
-
if (event.button !== 0) return;
|
|
575
|
-
this.viewer.executeCommand("zoomToSelected");
|
|
576
|
-
};
|
|
577
|
-
this.optionsChange = () => {
|
|
578
|
-
const {facesColor: facesColor, facesTransparancy: facesTransparancy} = this.viewer.options;
|
|
579
|
-
this.facesMaterial.color.setRGB(facesColor.r / 255, facesColor.g / 255, facesColor.b / 255);
|
|
580
|
-
this.facesMaterial.opacity = (255 - facesTransparancy) / 255;
|
|
581
|
-
this.viewer.update();
|
|
582
|
-
};
|
|
583
|
-
this.viewer = viewer;
|
|
584
|
-
this.raycaster = new Raycaster;
|
|
585
|
-
this.downPosition = new Vector2;
|
|
586
|
-
const {facesColor: facesColor, facesTransparancy: facesTransparancy} = this.viewer.options;
|
|
587
|
-
this.facesMaterial = new MeshBasicMaterial;
|
|
588
|
-
this.facesMaterial.color.setRGB(facesColor.r / 255, facesColor.g / 255, facesColor.b / 255);
|
|
589
|
-
this.facesMaterial.opacity = (255 - facesTransparancy) / 255;
|
|
590
|
-
this.facesMaterial.transparent = true;
|
|
591
|
-
this.viewer.addEventListener("pointerdown", this.onPointerDown);
|
|
592
|
-
this.viewer.addEventListener("pointerup", this.onPointerUp);
|
|
593
|
-
this.viewer.addEventListener("dblclick", this.onDoubleClick);
|
|
594
|
-
this.viewer.addEventListener("optionschange", this.optionsChange);
|
|
595
|
-
}
|
|
596
|
-
dispose() {
|
|
597
|
-
this.facesMaterial.dispose();
|
|
598
|
-
this.viewer.removeEventListener("pointerdown", this.onPointerDown);
|
|
599
|
-
this.viewer.removeEventListener("pointerup", this.onPointerUp);
|
|
600
|
-
this.viewer.removeEventListener("dblclick", this.onDoubleClick);
|
|
601
|
-
this.viewer.removeEventListener("optionschange", this.optionsChange);
|
|
602
|
-
}
|
|
603
|
-
getMousePosition(event, position) {
|
|
604
|
-
const rect = this.viewer.canvas.getBoundingClientRect();
|
|
605
|
-
position.setX((event.clientX - rect.left) / rect.width);
|
|
606
|
-
position.setY((event.clientY - rect.top) / rect.height);
|
|
607
|
-
return position;
|
|
608
|
-
}
|
|
609
|
-
getPointerIntersects(position) {
|
|
610
|
-
const mouse = new Vector2(position.x * 2 - 1, -(position.y * 2) + 1);
|
|
611
|
-
this.raycaster.setFromCamera(mouse, this.viewer.camera);
|
|
612
|
-
const objects = [];
|
|
613
|
-
this.viewer.scene.traverseVisible((child => objects.push(child)));
|
|
614
|
-
return this.raycaster.intersectObjects(objects, false);
|
|
615
|
-
}
|
|
616
|
-
select(object) {
|
|
617
|
-
if (object.isSelected) return;
|
|
618
|
-
object.isSelected = true;
|
|
619
|
-
object.originalMaterial = object.material;
|
|
620
|
-
object.material = this.facesMaterial;
|
|
621
|
-
this.viewer.selected.push(object);
|
|
622
|
-
}
|
|
623
|
-
clearSelection() {
|
|
624
|
-
this.viewer.selected.forEach((object => {
|
|
625
|
-
object.isSelected = false;
|
|
626
|
-
object.material = object.originalMaterial;
|
|
627
|
-
}));
|
|
628
|
-
this.viewer.selected.length = 0;
|
|
629
|
-
}
|
|
630
|
-
}
|
|
631
|
-
|
|
632
654
|
function hideSelected(viewer) {
|
|
633
655
|
viewer.selected.forEach((object => object.visible = false));
|
|
634
656
|
const selection = new SelectionComponent(viewer);
|
|
635
657
|
selection.clearSelection();
|
|
636
658
|
selection.dispose();
|
|
637
659
|
viewer.update();
|
|
638
|
-
viewer.
|
|
660
|
+
viewer.emitEvent({
|
|
639
661
|
type: "hide"
|
|
640
662
|
});
|
|
641
|
-
viewer.
|
|
663
|
+
viewer.emitEvent({
|
|
642
664
|
type: "select",
|
|
643
665
|
data: undefined,
|
|
644
666
|
handles: []
|
|
@@ -659,7 +681,7 @@ function isolateSelected(viewer) {
|
|
|
659
681
|
}
|
|
660
682
|
isolateObject(viewer.scene, 0);
|
|
661
683
|
viewer.update();
|
|
662
|
-
viewer.
|
|
684
|
+
viewer.emitEvent({
|
|
663
685
|
type: "isolate"
|
|
664
686
|
});
|
|
665
687
|
}
|
|
@@ -680,7 +702,7 @@ function resetView(viewer) {
|
|
|
680
702
|
viewer.executeCommand("clearSlices");
|
|
681
703
|
viewer.executeCommand("clearOverlay");
|
|
682
704
|
viewer.executeCommand("setMarkupColor");
|
|
683
|
-
viewer.executeCommand("
|
|
705
|
+
viewer.executeCommand("clearSelected");
|
|
684
706
|
viewer.executeCommand("showAll");
|
|
685
707
|
viewer.executeCommand("explode", 0);
|
|
686
708
|
viewer.executeCommand("zoomToExtents", true);
|
|
@@ -722,7 +744,7 @@ function setSelected(viewer, handles = []) {
|
|
|
722
744
|
objects.forEach((object => selection.select(object)));
|
|
723
745
|
selection.dispose();
|
|
724
746
|
viewer.update();
|
|
725
|
-
viewer.
|
|
747
|
+
viewer.emitEvent({
|
|
726
748
|
type: "select",
|
|
727
749
|
data: undefined,
|
|
728
750
|
handles: handles
|
|
@@ -734,27 +756,13 @@ commands("ThreeJS").registerCommand("setSelected", setSelected);
|
|
|
734
756
|
function showAll(viewer) {
|
|
735
757
|
viewer.scene.traverse((object => object.visible = true));
|
|
736
758
|
viewer.update();
|
|
737
|
-
viewer.
|
|
759
|
+
viewer.emitEvent({
|
|
738
760
|
type: "showall"
|
|
739
761
|
});
|
|
740
762
|
}
|
|
741
763
|
|
|
742
764
|
commands("ThreeJS").registerCommand("showAll", showAll);
|
|
743
765
|
|
|
744
|
-
function unselect(viewer) {
|
|
745
|
-
const selection = new SelectionComponent(viewer);
|
|
746
|
-
selection.clearSelection();
|
|
747
|
-
selection.dispose();
|
|
748
|
-
viewer.update();
|
|
749
|
-
viewer.emit({
|
|
750
|
-
type: "select",
|
|
751
|
-
data: undefined,
|
|
752
|
-
handles: []
|
|
753
|
-
});
|
|
754
|
-
}
|
|
755
|
-
|
|
756
|
-
commands("ThreeJS").registerCommand("unselect", unselect);
|
|
757
|
-
|
|
758
766
|
function zoomToExtents(viewer) {
|
|
759
767
|
if (viewer.extents.isEmpty()) return;
|
|
760
768
|
const center = viewer.extents.getCenter(new Vector3);
|
|
@@ -891,6 +899,695 @@ class EventEmitter2 {
|
|
|
891
899
|
}
|
|
892
900
|
}
|
|
893
901
|
|
|
902
|
+
const _changeEvent$2 = {
|
|
903
|
+
type: "change"
|
|
904
|
+
};
|
|
905
|
+
|
|
906
|
+
const _startEvent = {
|
|
907
|
+
type: "start"
|
|
908
|
+
};
|
|
909
|
+
|
|
910
|
+
const _endEvent = {
|
|
911
|
+
type: "end"
|
|
912
|
+
};
|
|
913
|
+
|
|
914
|
+
const STATE = {
|
|
915
|
+
NONE: -1,
|
|
916
|
+
ROTATE: 0,
|
|
917
|
+
DOLLY: 1,
|
|
918
|
+
PAN: 2,
|
|
919
|
+
TOUCH_ROTATE: 3,
|
|
920
|
+
TOUCH_PAN: 4,
|
|
921
|
+
TOUCH_DOLLY_PAN: 5,
|
|
922
|
+
TOUCH_DOLLY_ROTATE: 6
|
|
923
|
+
};
|
|
924
|
+
|
|
925
|
+
class OrbitControls extends EventDispatcher {
|
|
926
|
+
constructor(object, domElement) {
|
|
927
|
+
super();
|
|
928
|
+
this.object = object;
|
|
929
|
+
this.domElement = domElement;
|
|
930
|
+
this.domElement.style.touchAction = "none";
|
|
931
|
+
this.enabled = true;
|
|
932
|
+
this.target = new Vector3;
|
|
933
|
+
this.minDistance = 0;
|
|
934
|
+
this.maxDistance = Infinity;
|
|
935
|
+
this.minZoom = 0;
|
|
936
|
+
this.maxZoom = Infinity;
|
|
937
|
+
this.minPolarAngle = 0;
|
|
938
|
+
this.maxPolarAngle = Math.PI;
|
|
939
|
+
this.minAzimuthAngle = -Infinity;
|
|
940
|
+
this.maxAzimuthAngle = Infinity;
|
|
941
|
+
this.enableDamping = false;
|
|
942
|
+
this.dampingFactor = .05;
|
|
943
|
+
this.enableZoom = true;
|
|
944
|
+
this.zoomSpeed = 1;
|
|
945
|
+
this.enableRotate = true;
|
|
946
|
+
this.rotateSpeed = 1;
|
|
947
|
+
this.enablePan = true;
|
|
948
|
+
this.panSpeed = 1;
|
|
949
|
+
this.screenSpacePanning = true;
|
|
950
|
+
this.keyPanSpeed = 7;
|
|
951
|
+
this.autoRotate = false;
|
|
952
|
+
this.autoRotateSpeed = 2;
|
|
953
|
+
this.keys = {
|
|
954
|
+
LEFT: "ArrowLeft",
|
|
955
|
+
UP: "ArrowUp",
|
|
956
|
+
RIGHT: "ArrowRight",
|
|
957
|
+
BOTTOM: "ArrowDown"
|
|
958
|
+
};
|
|
959
|
+
this.mouseButtons = {
|
|
960
|
+
LEFT: MOUSE.ROTATE,
|
|
961
|
+
MIDDLE: MOUSE.DOLLY,
|
|
962
|
+
RIGHT: MOUSE.PAN
|
|
963
|
+
};
|
|
964
|
+
this.touches = {
|
|
965
|
+
ONE: TOUCH.ROTATE,
|
|
966
|
+
TWO: TOUCH.DOLLY_PAN
|
|
967
|
+
};
|
|
968
|
+
this.target0 = this.target.clone();
|
|
969
|
+
this.position0 = this.object.position.clone();
|
|
970
|
+
this.zoom0 = this.object.zoom;
|
|
971
|
+
this._domElementKeyEvents = null;
|
|
972
|
+
this.getPolarAngle = function() {
|
|
973
|
+
return spherical.phi;
|
|
974
|
+
};
|
|
975
|
+
this.getAzimuthalAngle = function() {
|
|
976
|
+
return spherical.theta;
|
|
977
|
+
};
|
|
978
|
+
this.getDistance = function() {
|
|
979
|
+
return this.object.position.distanceTo(this.target);
|
|
980
|
+
};
|
|
981
|
+
this.listenToKeyEvents = function(domElement) {
|
|
982
|
+
domElement.addEventListener("keydown", onKeyDown);
|
|
983
|
+
this._domElementKeyEvents = domElement;
|
|
984
|
+
};
|
|
985
|
+
this.stopListenToKeyEvents = function() {
|
|
986
|
+
this._domElementKeyEvents.removeEventListener("keydown", onKeyDown);
|
|
987
|
+
this._domElementKeyEvents = null;
|
|
988
|
+
};
|
|
989
|
+
this.saveState = function() {
|
|
990
|
+
scope.target0.copy(scope.target);
|
|
991
|
+
scope.position0.copy(scope.object.position);
|
|
992
|
+
scope.zoom0 = scope.object.zoom;
|
|
993
|
+
};
|
|
994
|
+
this.reset = function() {
|
|
995
|
+
scope.target.copy(scope.target0);
|
|
996
|
+
scope.object.position.copy(scope.position0);
|
|
997
|
+
scope.object.zoom = scope.zoom0;
|
|
998
|
+
scope.object.updateProjectionMatrix();
|
|
999
|
+
scope.dispatchEvent(_changeEvent$2);
|
|
1000
|
+
scope.update();
|
|
1001
|
+
scope.state = STATE.NONE;
|
|
1002
|
+
};
|
|
1003
|
+
this.update = function() {
|
|
1004
|
+
const offset = new Vector3;
|
|
1005
|
+
const quat = (new Quaternion).setFromUnitVectors(object.up, new Vector3(0, 1, 0));
|
|
1006
|
+
const quatInverse = quat.clone().invert();
|
|
1007
|
+
const lastPosition = new Vector3;
|
|
1008
|
+
const lastQuaternion = new Quaternion;
|
|
1009
|
+
const lastTargetPosition = new Vector3;
|
|
1010
|
+
const twoPI = 2 * Math.PI;
|
|
1011
|
+
return function update() {
|
|
1012
|
+
const position = scope.object.position;
|
|
1013
|
+
offset.copy(position).sub(scope.target);
|
|
1014
|
+
offset.applyQuaternion(quat);
|
|
1015
|
+
spherical.setFromVector3(offset);
|
|
1016
|
+
if (scope.autoRotate && scope.state === STATE.NONE) {
|
|
1017
|
+
rotateLeft(getAutoRotationAngle());
|
|
1018
|
+
}
|
|
1019
|
+
if (scope.enableDamping) {
|
|
1020
|
+
spherical.theta += sphericalDelta.theta * scope.dampingFactor;
|
|
1021
|
+
spherical.phi += sphericalDelta.phi * scope.dampingFactor;
|
|
1022
|
+
} else {
|
|
1023
|
+
spherical.theta += sphericalDelta.theta;
|
|
1024
|
+
spherical.phi += sphericalDelta.phi;
|
|
1025
|
+
}
|
|
1026
|
+
let min = scope.minAzimuthAngle;
|
|
1027
|
+
let max = scope.maxAzimuthAngle;
|
|
1028
|
+
if (isFinite(min) && isFinite(max)) {
|
|
1029
|
+
if (min < -Math.PI) min += twoPI; else if (min > Math.PI) min -= twoPI;
|
|
1030
|
+
if (max < -Math.PI) max += twoPI; else if (max > Math.PI) max -= twoPI;
|
|
1031
|
+
if (min <= max) {
|
|
1032
|
+
spherical.theta = Math.max(min, Math.min(max, spherical.theta));
|
|
1033
|
+
} else {
|
|
1034
|
+
spherical.theta = spherical.theta > (min + max) / 2 ? Math.max(min, spherical.theta) : Math.min(max, spherical.theta);
|
|
1035
|
+
}
|
|
1036
|
+
}
|
|
1037
|
+
spherical.phi = Math.max(scope.minPolarAngle, Math.min(scope.maxPolarAngle, spherical.phi));
|
|
1038
|
+
spherical.makeSafe();
|
|
1039
|
+
spherical.radius *= scope.scale;
|
|
1040
|
+
spherical.radius = Math.max(scope.minDistance, Math.min(scope.maxDistance, spherical.radius));
|
|
1041
|
+
if (scope.enableDamping === true) {
|
|
1042
|
+
scope.target.addScaledVector(scope.panOffset, scope.dampingFactor);
|
|
1043
|
+
} else {
|
|
1044
|
+
scope.target.add(scope.panOffset);
|
|
1045
|
+
}
|
|
1046
|
+
offset.setFromSpherical(spherical);
|
|
1047
|
+
offset.applyQuaternion(quatInverse);
|
|
1048
|
+
position.copy(scope.target).add(offset);
|
|
1049
|
+
scope.object.lookAt(scope.target);
|
|
1050
|
+
if (scope.enableDamping === true) {
|
|
1051
|
+
sphericalDelta.theta *= 1 - scope.dampingFactor;
|
|
1052
|
+
sphericalDelta.phi *= 1 - scope.dampingFactor;
|
|
1053
|
+
scope.panOffset.multiplyScalar(1 - scope.dampingFactor);
|
|
1054
|
+
} else {
|
|
1055
|
+
sphericalDelta.set(0, 0, 0);
|
|
1056
|
+
scope.panOffset.set(0, 0, 0);
|
|
1057
|
+
}
|
|
1058
|
+
scope.scale = 1;
|
|
1059
|
+
if (scope.zoomChanged || lastPosition.distanceToSquared(scope.object.position) > EPS || 8 * (1 - lastQuaternion.dot(scope.object.quaternion)) > EPS || lastTargetPosition.distanceToSquared(scope.target) > 0) {
|
|
1060
|
+
scope.dispatchEvent(_changeEvent$2);
|
|
1061
|
+
lastPosition.copy(scope.object.position);
|
|
1062
|
+
lastQuaternion.copy(scope.object.quaternion);
|
|
1063
|
+
lastTargetPosition.copy(scope.target);
|
|
1064
|
+
scope.zoomChanged = false;
|
|
1065
|
+
return true;
|
|
1066
|
+
}
|
|
1067
|
+
return false;
|
|
1068
|
+
};
|
|
1069
|
+
}();
|
|
1070
|
+
this.dispose = function() {
|
|
1071
|
+
scope.domElement.removeEventListener("contextmenu", onContextMenu);
|
|
1072
|
+
scope.domElement.removeEventListener("pointerdown", onPointerDown);
|
|
1073
|
+
scope.domElement.removeEventListener("pointercancel", onPointerUp);
|
|
1074
|
+
scope.domElement.removeEventListener("wheel", onMouseWheel);
|
|
1075
|
+
scope.domElement.removeEventListener("pointermove", onPointerMove);
|
|
1076
|
+
scope.domElement.removeEventListener("pointerup", onPointerUp);
|
|
1077
|
+
if (scope._domElementKeyEvents !== null) {
|
|
1078
|
+
scope._domElementKeyEvents.removeEventListener("keydown", onKeyDown);
|
|
1079
|
+
scope._domElementKeyEvents = null;
|
|
1080
|
+
}
|
|
1081
|
+
};
|
|
1082
|
+
const scope = this;
|
|
1083
|
+
scope.state = STATE.NONE;
|
|
1084
|
+
const EPS = 1e-6;
|
|
1085
|
+
const spherical = new Spherical;
|
|
1086
|
+
const sphericalDelta = new Spherical;
|
|
1087
|
+
scope.scale = 1;
|
|
1088
|
+
scope.panOffset = new Vector3;
|
|
1089
|
+
scope.zoomChanged = false;
|
|
1090
|
+
scope.rotateStart = new Vector2;
|
|
1091
|
+
scope.rotateEnd = new Vector2;
|
|
1092
|
+
scope.rotateDelta = new Vector2;
|
|
1093
|
+
scope.panStart = new Vector2;
|
|
1094
|
+
scope.panEnd = new Vector2;
|
|
1095
|
+
scope.panDelta = new Vector2;
|
|
1096
|
+
scope.dollyStart = new Vector2;
|
|
1097
|
+
scope.dollyEnd = new Vector2;
|
|
1098
|
+
scope.dollyDelta = new Vector2;
|
|
1099
|
+
scope.dollyScale = 0;
|
|
1100
|
+
scope.pointers = [];
|
|
1101
|
+
scope.pointerPositions = {};
|
|
1102
|
+
function getAutoRotationAngle() {
|
|
1103
|
+
return 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;
|
|
1104
|
+
}
|
|
1105
|
+
function getZoomScale() {
|
|
1106
|
+
return Math.pow(.95, scope.zoomSpeed);
|
|
1107
|
+
}
|
|
1108
|
+
function rotateLeft(angle) {
|
|
1109
|
+
sphericalDelta.theta -= angle;
|
|
1110
|
+
}
|
|
1111
|
+
function rotateUp(angle) {
|
|
1112
|
+
sphericalDelta.phi -= angle;
|
|
1113
|
+
}
|
|
1114
|
+
const panLeft = function() {
|
|
1115
|
+
const v = new Vector3;
|
|
1116
|
+
return function panLeft(distance, objectMatrix) {
|
|
1117
|
+
v.setFromMatrixColumn(objectMatrix, 0);
|
|
1118
|
+
v.multiplyScalar(-distance);
|
|
1119
|
+
scope.panOffset.add(v);
|
|
1120
|
+
};
|
|
1121
|
+
}();
|
|
1122
|
+
const panUp = function() {
|
|
1123
|
+
const v = new Vector3;
|
|
1124
|
+
return function panUp(distance, objectMatrix) {
|
|
1125
|
+
if (scope.screenSpacePanning === true) {
|
|
1126
|
+
v.setFromMatrixColumn(objectMatrix, 1);
|
|
1127
|
+
} else {
|
|
1128
|
+
v.setFromMatrixColumn(objectMatrix, 0);
|
|
1129
|
+
v.crossVectors(scope.object.up, v);
|
|
1130
|
+
}
|
|
1131
|
+
v.multiplyScalar(distance);
|
|
1132
|
+
scope.panOffset.add(v);
|
|
1133
|
+
};
|
|
1134
|
+
}();
|
|
1135
|
+
const pan = function() {
|
|
1136
|
+
const offset = new Vector3;
|
|
1137
|
+
return function pan(deltaX, deltaY) {
|
|
1138
|
+
const element = scope.domElement;
|
|
1139
|
+
if (scope.object.isPerspectiveCamera) {
|
|
1140
|
+
const position = scope.object.position;
|
|
1141
|
+
offset.copy(position).sub(scope.target);
|
|
1142
|
+
let targetDistance = offset.length();
|
|
1143
|
+
targetDistance *= Math.tan(scope.object.fov / 2 * Math.PI / 180);
|
|
1144
|
+
panLeft(2 * deltaX * targetDistance / element.clientHeight, scope.object.matrix);
|
|
1145
|
+
panUp(2 * deltaY * targetDistance / element.clientHeight, scope.object.matrix);
|
|
1146
|
+
} else if (scope.object.isOrthographicCamera) {
|
|
1147
|
+
panLeft(deltaX * (scope.object.right - scope.object.left) / scope.object.zoom / element.clientWidth, scope.object.matrix);
|
|
1148
|
+
panUp(deltaY * (scope.object.top - scope.object.bottom) / scope.object.zoom / element.clientHeight, scope.object.matrix);
|
|
1149
|
+
} else {
|
|
1150
|
+
console.warn("WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.");
|
|
1151
|
+
scope.enablePan = false;
|
|
1152
|
+
}
|
|
1153
|
+
};
|
|
1154
|
+
}();
|
|
1155
|
+
function dollyOut(dollyScale) {
|
|
1156
|
+
if (scope.object.isPerspectiveCamera) {
|
|
1157
|
+
scope.scale /= dollyScale;
|
|
1158
|
+
} else if (scope.object.isOrthographicCamera) {
|
|
1159
|
+
scope.object.zoom = Math.max(scope.minZoom, Math.min(scope.maxZoom, scope.object.zoom * dollyScale));
|
|
1160
|
+
scope.object.updateProjectionMatrix();
|
|
1161
|
+
scope.zoomChanged = true;
|
|
1162
|
+
} else {
|
|
1163
|
+
console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.");
|
|
1164
|
+
scope.enableZoom = false;
|
|
1165
|
+
}
|
|
1166
|
+
}
|
|
1167
|
+
function dollyIn(dollyScale) {
|
|
1168
|
+
if (scope.object.isPerspectiveCamera) {
|
|
1169
|
+
scope.scale *= dollyScale;
|
|
1170
|
+
} else if (scope.object.isOrthographicCamera) {
|
|
1171
|
+
scope.object.zoom = Math.max(scope.minZoom, Math.min(scope.maxZoom, scope.object.zoom / dollyScale));
|
|
1172
|
+
scope.object.updateProjectionMatrix();
|
|
1173
|
+
scope.zoomChanged = true;
|
|
1174
|
+
} else {
|
|
1175
|
+
console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.");
|
|
1176
|
+
scope.enableZoom = false;
|
|
1177
|
+
}
|
|
1178
|
+
}
|
|
1179
|
+
function handleMouseDownRotate(event) {
|
|
1180
|
+
scope.rotateStart.set(event.clientX, event.clientY);
|
|
1181
|
+
}
|
|
1182
|
+
function handleMouseDownDolly(event) {
|
|
1183
|
+
scope.dollyStart.set(event.clientX, event.clientY);
|
|
1184
|
+
}
|
|
1185
|
+
function handleMouseDownPan(event) {
|
|
1186
|
+
scope.panStart.set(event.clientX, event.clientY);
|
|
1187
|
+
}
|
|
1188
|
+
function handleMouseMoveRotate(event) {
|
|
1189
|
+
scope.rotateEnd.set(event.clientX, event.clientY);
|
|
1190
|
+
scope.rotateDelta.subVectors(scope.rotateEnd, scope.rotateStart).multiplyScalar(scope.rotateSpeed);
|
|
1191
|
+
const element = scope.domElement;
|
|
1192
|
+
rotateLeft(2 * Math.PI * scope.rotateDelta.x / element.clientHeight);
|
|
1193
|
+
rotateUp(2 * Math.PI * scope.rotateDelta.y / element.clientHeight);
|
|
1194
|
+
scope.rotateStart.copy(scope.rotateEnd);
|
|
1195
|
+
scope.update();
|
|
1196
|
+
}
|
|
1197
|
+
function handleMouseMoveDolly(event) {
|
|
1198
|
+
scope.dollyEnd.set(event.clientX, event.clientY);
|
|
1199
|
+
scope.dollyDelta.subVectors(scope.dollyEnd, scope.dollyStart);
|
|
1200
|
+
if (scope.dollyDelta.y < 0) {
|
|
1201
|
+
scope.dollyScale = 1 / getZoomScale();
|
|
1202
|
+
dollyOut(getZoomScale());
|
|
1203
|
+
} else if (scope.dollyDelta.y > 0) {
|
|
1204
|
+
scope.dollyScale = getZoomScale();
|
|
1205
|
+
dollyIn(getZoomScale());
|
|
1206
|
+
}
|
|
1207
|
+
scope.dollyStart.copy(scope.dollyEnd);
|
|
1208
|
+
scope.update();
|
|
1209
|
+
}
|
|
1210
|
+
function handleMouseMovePan(event) {
|
|
1211
|
+
scope.panEnd.set(event.clientX, event.clientY);
|
|
1212
|
+
scope.panDelta.subVectors(scope.panEnd, scope.panStart).multiplyScalar(scope.panSpeed);
|
|
1213
|
+
pan(scope.panDelta.x, scope.panDelta.y);
|
|
1214
|
+
scope.panStart.copy(scope.panEnd);
|
|
1215
|
+
scope.update();
|
|
1216
|
+
}
|
|
1217
|
+
function handleMouseWheel(event) {
|
|
1218
|
+
scope.dollyEnd.set(scope.domElement.clientWidth / 2, scope.domElement.clientHeight / 2);
|
|
1219
|
+
scope.dollyDelta.set(event.deltaX, event.deltaY);
|
|
1220
|
+
if (event.deltaY < 0) {
|
|
1221
|
+
scope.dollyScale = 1 / getZoomScale();
|
|
1222
|
+
dollyIn(getZoomScale());
|
|
1223
|
+
} else if (event.deltaY > 0) {
|
|
1224
|
+
scope.dollyScale = getZoomScale();
|
|
1225
|
+
dollyOut(getZoomScale());
|
|
1226
|
+
}
|
|
1227
|
+
scope.dollyStart.copy(scope.dollyEnd);
|
|
1228
|
+
scope.update();
|
|
1229
|
+
if (event.deltaY !== 0) {
|
|
1230
|
+
scope.state = STATE.DOLLY;
|
|
1231
|
+
scope.dispatchEvent(_changeEvent$2);
|
|
1232
|
+
scope.state = STATE.NONE;
|
|
1233
|
+
}
|
|
1234
|
+
}
|
|
1235
|
+
function handleKeyDown(event) {
|
|
1236
|
+
let needsUpdate = false;
|
|
1237
|
+
switch (event.code) {
|
|
1238
|
+
case scope.keys.UP:
|
|
1239
|
+
if (event.ctrlKey || event.metaKey || event.shiftKey) {
|
|
1240
|
+
rotateUp(2 * Math.PI * scope.rotateSpeed / scope.domElement.clientHeight);
|
|
1241
|
+
} else {
|
|
1242
|
+
pan(0, scope.keyPanSpeed);
|
|
1243
|
+
}
|
|
1244
|
+
needsUpdate = true;
|
|
1245
|
+
break;
|
|
1246
|
+
|
|
1247
|
+
case scope.keys.BOTTOM:
|
|
1248
|
+
if (event.ctrlKey || event.metaKey || event.shiftKey) {
|
|
1249
|
+
rotateUp(-2 * Math.PI * scope.rotateSpeed / scope.domElement.clientHeight);
|
|
1250
|
+
} else {
|
|
1251
|
+
pan(0, -scope.keyPanSpeed);
|
|
1252
|
+
}
|
|
1253
|
+
needsUpdate = true;
|
|
1254
|
+
break;
|
|
1255
|
+
|
|
1256
|
+
case scope.keys.LEFT:
|
|
1257
|
+
if (event.ctrlKey || event.metaKey || event.shiftKey) {
|
|
1258
|
+
rotateLeft(2 * Math.PI * scope.rotateSpeed / scope.domElement.clientHeight);
|
|
1259
|
+
} else {
|
|
1260
|
+
pan(scope.keyPanSpeed, 0);
|
|
1261
|
+
}
|
|
1262
|
+
needsUpdate = true;
|
|
1263
|
+
break;
|
|
1264
|
+
|
|
1265
|
+
case scope.keys.RIGHT:
|
|
1266
|
+
if (event.ctrlKey || event.metaKey || event.shiftKey) {
|
|
1267
|
+
rotateLeft(-2 * Math.PI * scope.rotateSpeed / scope.domElement.clientHeight);
|
|
1268
|
+
} else {
|
|
1269
|
+
pan(-scope.keyPanSpeed, 0);
|
|
1270
|
+
}
|
|
1271
|
+
needsUpdate = true;
|
|
1272
|
+
break;
|
|
1273
|
+
}
|
|
1274
|
+
if (needsUpdate) {
|
|
1275
|
+
event.preventDefault();
|
|
1276
|
+
scope.update();
|
|
1277
|
+
}
|
|
1278
|
+
}
|
|
1279
|
+
function handleTouchStartRotate() {
|
|
1280
|
+
if (scope.pointers.length === 1) {
|
|
1281
|
+
scope.rotateStart.set(scope.pointers[0].pageX, scope.pointers[0].pageY);
|
|
1282
|
+
} else {
|
|
1283
|
+
const x = .5 * (scope.pointers[0].pageX + scope.pointers[1].pageX);
|
|
1284
|
+
const y = .5 * (scope.pointers[0].pageY + scope.pointers[1].pageY);
|
|
1285
|
+
scope.rotateStart.set(x, y);
|
|
1286
|
+
}
|
|
1287
|
+
}
|
|
1288
|
+
function handleTouchStartPan() {
|
|
1289
|
+
if (scope.pointers.length === 1) {
|
|
1290
|
+
scope.panStart.set(scope.pointers[0].pageX, scope.pointers[0].pageY);
|
|
1291
|
+
} else {
|
|
1292
|
+
const x = .5 * (scope.pointers[0].pageX + scope.pointers[1].pageX);
|
|
1293
|
+
const y = .5 * (scope.pointers[0].pageY + scope.pointers[1].pageY);
|
|
1294
|
+
scope.panStart.set(x, y);
|
|
1295
|
+
}
|
|
1296
|
+
}
|
|
1297
|
+
function handleTouchStartDolly() {
|
|
1298
|
+
const dx = scope.pointers[0].pageX - scope.pointers[1].pageX;
|
|
1299
|
+
const dy = scope.pointers[0].pageY - scope.pointers[1].pageY;
|
|
1300
|
+
const distance = Math.sqrt(dx * dx + dy * dy);
|
|
1301
|
+
scope.dollyStart.set(0, distance);
|
|
1302
|
+
}
|
|
1303
|
+
function handleTouchStartDollyPan() {
|
|
1304
|
+
if (scope.enableZoom) handleTouchStartDolly();
|
|
1305
|
+
if (scope.enablePan) handleTouchStartPan();
|
|
1306
|
+
}
|
|
1307
|
+
function handleTouchStartDollyRotate() {
|
|
1308
|
+
if (scope.enableZoom) handleTouchStartDolly();
|
|
1309
|
+
if (scope.enableRotate) handleTouchStartRotate();
|
|
1310
|
+
}
|
|
1311
|
+
function handleTouchMoveRotate(event) {
|
|
1312
|
+
if (scope.pointers.length == 1) {
|
|
1313
|
+
scope.rotateEnd.set(event.pageX, event.pageY);
|
|
1314
|
+
} else {
|
|
1315
|
+
const position = getSecondPointerPosition(event);
|
|
1316
|
+
const x = .5 * (event.pageX + position.x);
|
|
1317
|
+
const y = .5 * (event.pageY + position.y);
|
|
1318
|
+
scope.rotateEnd.set(x, y);
|
|
1319
|
+
}
|
|
1320
|
+
scope.rotateDelta.subVectors(scope.rotateEnd, scope.rotateStart).multiplyScalar(scope.rotateSpeed);
|
|
1321
|
+
const element = scope.domElement;
|
|
1322
|
+
rotateLeft(2 * Math.PI * scope.rotateDelta.x / element.clientHeight);
|
|
1323
|
+
rotateUp(2 * Math.PI * scope.rotateDelta.y / element.clientHeight);
|
|
1324
|
+
scope.rotateStart.copy(scope.rotateEnd);
|
|
1325
|
+
}
|
|
1326
|
+
function handleTouchMovePan(event) {
|
|
1327
|
+
if (scope.pointers.length === 1) {
|
|
1328
|
+
scope.panEnd.set(event.pageX, event.pageY);
|
|
1329
|
+
} else {
|
|
1330
|
+
const position = getSecondPointerPosition(event);
|
|
1331
|
+
const x = .5 * (event.pageX + position.x);
|
|
1332
|
+
const y = .5 * (event.pageY + position.y);
|
|
1333
|
+
scope.panEnd.set(x, y);
|
|
1334
|
+
}
|
|
1335
|
+
scope.panDelta.subVectors(scope.panEnd, scope.panStart).multiplyScalar(scope.panSpeed);
|
|
1336
|
+
pan(scope.panDelta.x, scope.panDelta.y);
|
|
1337
|
+
scope.panStart.copy(scope.panEnd);
|
|
1338
|
+
}
|
|
1339
|
+
function handleTouchMoveDolly(event) {
|
|
1340
|
+
const position = getSecondPointerPosition(event);
|
|
1341
|
+
const dx = event.pageX - position.x;
|
|
1342
|
+
const dy = event.pageY - position.y;
|
|
1343
|
+
const distance = Math.sqrt(dx * dx + dy * dy);
|
|
1344
|
+
scope.dollyEnd.set(0, distance);
|
|
1345
|
+
scope.dollyDelta.set(0, Math.pow(scope.dollyEnd.y / scope.dollyStart.y, scope.zoomSpeed));
|
|
1346
|
+
dollyOut(scope.dollyDelta.y);
|
|
1347
|
+
scope.dollyStart.copy(scope.dollyEnd);
|
|
1348
|
+
}
|
|
1349
|
+
function handleTouchMoveDollyPan(event) {
|
|
1350
|
+
if (scope.enableZoom) handleTouchMoveDolly(event);
|
|
1351
|
+
if (scope.enablePan) handleTouchMovePan(event);
|
|
1352
|
+
}
|
|
1353
|
+
function handleTouchMoveDollyRotate(event) {
|
|
1354
|
+
if (scope.enableZoom) handleTouchMoveDolly(event);
|
|
1355
|
+
if (scope.enableRotate) handleTouchMoveRotate(event);
|
|
1356
|
+
}
|
|
1357
|
+
function onPointerDown(event) {
|
|
1358
|
+
if (scope.enabled === false) return;
|
|
1359
|
+
if (scope.pointers.length === 0) {
|
|
1360
|
+
scope.domElement.setPointerCapture(event.pointerId);
|
|
1361
|
+
scope.domElement.addEventListener("pointermove", onPointerMove);
|
|
1362
|
+
scope.domElement.addEventListener("pointerup", onPointerUp);
|
|
1363
|
+
}
|
|
1364
|
+
addPointer(event);
|
|
1365
|
+
if (event.pointerType === "touch") {
|
|
1366
|
+
onTouchStart(event);
|
|
1367
|
+
} else {
|
|
1368
|
+
onMouseDown(event);
|
|
1369
|
+
}
|
|
1370
|
+
}
|
|
1371
|
+
function onPointerMove(event) {
|
|
1372
|
+
if (scope.enabled === false) return;
|
|
1373
|
+
if (event.pointerType === "touch") {
|
|
1374
|
+
onTouchMove(event);
|
|
1375
|
+
} else {
|
|
1376
|
+
onMouseMove(event);
|
|
1377
|
+
}
|
|
1378
|
+
}
|
|
1379
|
+
function onPointerUp(event) {
|
|
1380
|
+
removePointer(event);
|
|
1381
|
+
if (scope.pointers.length === 0) {
|
|
1382
|
+
scope.domElement.releasePointerCapture(event.pointerId);
|
|
1383
|
+
scope.domElement.removeEventListener("pointermove", onPointerMove);
|
|
1384
|
+
scope.domElement.removeEventListener("pointerup", onPointerUp);
|
|
1385
|
+
}
|
|
1386
|
+
scope.dispatchEvent(_endEvent);
|
|
1387
|
+
scope.state = STATE.NONE;
|
|
1388
|
+
}
|
|
1389
|
+
function onMouseDown(event) {
|
|
1390
|
+
let mouseAction;
|
|
1391
|
+
switch (event.button) {
|
|
1392
|
+
case 0:
|
|
1393
|
+
mouseAction = scope.mouseButtons.LEFT;
|
|
1394
|
+
break;
|
|
1395
|
+
|
|
1396
|
+
case 1:
|
|
1397
|
+
mouseAction = scope.mouseButtons.MIDDLE;
|
|
1398
|
+
break;
|
|
1399
|
+
|
|
1400
|
+
case 2:
|
|
1401
|
+
mouseAction = scope.mouseButtons.RIGHT;
|
|
1402
|
+
break;
|
|
1403
|
+
|
|
1404
|
+
default:
|
|
1405
|
+
mouseAction = -1;
|
|
1406
|
+
}
|
|
1407
|
+
switch (mouseAction) {
|
|
1408
|
+
case MOUSE.DOLLY:
|
|
1409
|
+
if (scope.enableZoom === false) return;
|
|
1410
|
+
handleMouseDownDolly(event);
|
|
1411
|
+
scope.state = STATE.DOLLY;
|
|
1412
|
+
break;
|
|
1413
|
+
|
|
1414
|
+
case MOUSE.ROTATE:
|
|
1415
|
+
if (event.ctrlKey || event.metaKey || event.shiftKey) {
|
|
1416
|
+
if (scope.enablePan === false) return;
|
|
1417
|
+
handleMouseDownPan(event);
|
|
1418
|
+
scope.state = STATE.PAN;
|
|
1419
|
+
} else {
|
|
1420
|
+
if (scope.enableRotate === false) return;
|
|
1421
|
+
handleMouseDownRotate(event);
|
|
1422
|
+
scope.state = STATE.ROTATE;
|
|
1423
|
+
}
|
|
1424
|
+
break;
|
|
1425
|
+
|
|
1426
|
+
case MOUSE.PAN:
|
|
1427
|
+
if (event.ctrlKey || event.metaKey || event.shiftKey) {
|
|
1428
|
+
if (scope.enableRotate === false) return;
|
|
1429
|
+
handleMouseDownRotate(event);
|
|
1430
|
+
scope.state = STATE.ROTATE;
|
|
1431
|
+
} else {
|
|
1432
|
+
if (scope.enablePan === false) return;
|
|
1433
|
+
handleMouseDownPan(event);
|
|
1434
|
+
scope.state = STATE.PAN;
|
|
1435
|
+
}
|
|
1436
|
+
break;
|
|
1437
|
+
|
|
1438
|
+
default:
|
|
1439
|
+
scope.state = STATE.NONE;
|
|
1440
|
+
}
|
|
1441
|
+
if (scope.state !== STATE.NONE) {
|
|
1442
|
+
scope.dispatchEvent(_startEvent);
|
|
1443
|
+
}
|
|
1444
|
+
}
|
|
1445
|
+
function onMouseMove(event) {
|
|
1446
|
+
switch (scope.state) {
|
|
1447
|
+
case STATE.ROTATE:
|
|
1448
|
+
if (scope.enableRotate === false) return;
|
|
1449
|
+
handleMouseMoveRotate(event);
|
|
1450
|
+
break;
|
|
1451
|
+
|
|
1452
|
+
case STATE.DOLLY:
|
|
1453
|
+
if (scope.enableZoom === false) return;
|
|
1454
|
+
handleMouseMoveDolly(event);
|
|
1455
|
+
break;
|
|
1456
|
+
|
|
1457
|
+
case STATE.PAN:
|
|
1458
|
+
if (scope.enablePan === false) return;
|
|
1459
|
+
handleMouseMovePan(event);
|
|
1460
|
+
break;
|
|
1461
|
+
}
|
|
1462
|
+
}
|
|
1463
|
+
function onMouseWheel(event) {
|
|
1464
|
+
if (scope.enabled === false || scope.enableZoom === false || scope.state !== STATE.NONE) return;
|
|
1465
|
+
event.preventDefault();
|
|
1466
|
+
scope.dispatchEvent(_startEvent);
|
|
1467
|
+
handleMouseWheel(event);
|
|
1468
|
+
scope.dispatchEvent(_endEvent);
|
|
1469
|
+
}
|
|
1470
|
+
function onKeyDown(event) {
|
|
1471
|
+
if (scope.enabled === false || scope.enablePan === false) return;
|
|
1472
|
+
handleKeyDown(event);
|
|
1473
|
+
}
|
|
1474
|
+
function onTouchStart(event) {
|
|
1475
|
+
trackPointer(event);
|
|
1476
|
+
switch (scope.pointers.length) {
|
|
1477
|
+
case 1:
|
|
1478
|
+
switch (scope.touches.ONE) {
|
|
1479
|
+
case TOUCH.ROTATE:
|
|
1480
|
+
if (scope.enableRotate === false) return;
|
|
1481
|
+
handleTouchStartRotate();
|
|
1482
|
+
scope.state = STATE.TOUCH_ROTATE;
|
|
1483
|
+
break;
|
|
1484
|
+
|
|
1485
|
+
case TOUCH.PAN:
|
|
1486
|
+
if (scope.enablePan === false) return;
|
|
1487
|
+
handleTouchStartPan();
|
|
1488
|
+
scope.state = STATE.TOUCH_PAN;
|
|
1489
|
+
break;
|
|
1490
|
+
|
|
1491
|
+
default:
|
|
1492
|
+
scope.state = STATE.NONE;
|
|
1493
|
+
}
|
|
1494
|
+
break;
|
|
1495
|
+
|
|
1496
|
+
case 2:
|
|
1497
|
+
switch (scope.touches.TWO) {
|
|
1498
|
+
case TOUCH.DOLLY_PAN:
|
|
1499
|
+
if (scope.enableZoom === false && scope.enablePan === false) return;
|
|
1500
|
+
handleTouchStartDollyPan();
|
|
1501
|
+
scope.state = STATE.TOUCH_DOLLY_PAN;
|
|
1502
|
+
break;
|
|
1503
|
+
|
|
1504
|
+
case TOUCH.DOLLY_ROTATE:
|
|
1505
|
+
if (scope.enableZoom === false && scope.enableRotate === false) return;
|
|
1506
|
+
handleTouchStartDollyRotate();
|
|
1507
|
+
scope.state = STATE.TOUCH_DOLLY_ROTATE;
|
|
1508
|
+
break;
|
|
1509
|
+
|
|
1510
|
+
default:
|
|
1511
|
+
scope.state = STATE.NONE;
|
|
1512
|
+
}
|
|
1513
|
+
break;
|
|
1514
|
+
|
|
1515
|
+
default:
|
|
1516
|
+
scope.state = STATE.NONE;
|
|
1517
|
+
}
|
|
1518
|
+
if (scope.state !== STATE.NONE) {
|
|
1519
|
+
scope.dispatchEvent(_startEvent);
|
|
1520
|
+
}
|
|
1521
|
+
}
|
|
1522
|
+
function onTouchMove(event) {
|
|
1523
|
+
trackPointer(event);
|
|
1524
|
+
switch (scope.state) {
|
|
1525
|
+
case STATE.TOUCH_ROTATE:
|
|
1526
|
+
if (scope.enableRotate === false) return;
|
|
1527
|
+
handleTouchMoveRotate(event);
|
|
1528
|
+
scope.update();
|
|
1529
|
+
break;
|
|
1530
|
+
|
|
1531
|
+
case STATE.TOUCH_PAN:
|
|
1532
|
+
if (scope.enablePan === false) return;
|
|
1533
|
+
handleTouchMovePan(event);
|
|
1534
|
+
scope.update();
|
|
1535
|
+
break;
|
|
1536
|
+
|
|
1537
|
+
case STATE.TOUCH_DOLLY_PAN:
|
|
1538
|
+
if (scope.enableZoom === false && scope.enablePan === false) return;
|
|
1539
|
+
handleTouchMoveDollyPan(event);
|
|
1540
|
+
scope.update();
|
|
1541
|
+
break;
|
|
1542
|
+
|
|
1543
|
+
case STATE.TOUCH_DOLLY_ROTATE:
|
|
1544
|
+
if (scope.enableZoom === false && scope.enableRotate === false) return;
|
|
1545
|
+
handleTouchMoveDollyRotate(event);
|
|
1546
|
+
scope.update();
|
|
1547
|
+
break;
|
|
1548
|
+
|
|
1549
|
+
default:
|
|
1550
|
+
scope.state = STATE.NONE;
|
|
1551
|
+
}
|
|
1552
|
+
}
|
|
1553
|
+
function onContextMenu(event) {
|
|
1554
|
+
if (scope.enabled === false) return;
|
|
1555
|
+
event.preventDefault();
|
|
1556
|
+
}
|
|
1557
|
+
function addPointer(event) {
|
|
1558
|
+
scope.pointers.push(event);
|
|
1559
|
+
}
|
|
1560
|
+
function removePointer(event) {
|
|
1561
|
+
delete scope.pointerPositions[event.pointerId];
|
|
1562
|
+
for (let i = 0; i < scope.pointers.length; i++) {
|
|
1563
|
+
if (scope.pointers[i].pointerId == event.pointerId) {
|
|
1564
|
+
scope.pointers.splice(i, 1);
|
|
1565
|
+
return;
|
|
1566
|
+
}
|
|
1567
|
+
}
|
|
1568
|
+
}
|
|
1569
|
+
function trackPointer(event) {
|
|
1570
|
+
let position = scope.pointerPositions[event.pointerId];
|
|
1571
|
+
if (position === undefined) {
|
|
1572
|
+
position = new Vector2;
|
|
1573
|
+
scope.pointerPositions[event.pointerId] = position;
|
|
1574
|
+
}
|
|
1575
|
+
position.set(event.pageX, event.pageY);
|
|
1576
|
+
}
|
|
1577
|
+
function getSecondPointerPosition(event) {
|
|
1578
|
+
const pointer = event.pointerId === scope.pointers[0].pointerId ? scope.pointers[1] : scope.pointers[0];
|
|
1579
|
+
return scope.pointerPositions[pointer.pointerId];
|
|
1580
|
+
}
|
|
1581
|
+
scope.domElement.addEventListener("contextmenu", onContextMenu);
|
|
1582
|
+
scope.domElement.addEventListener("pointerdown", onPointerDown);
|
|
1583
|
+
scope.domElement.addEventListener("pointercancel", onPointerUp);
|
|
1584
|
+
scope.domElement.addEventListener("wheel", onMouseWheel, {
|
|
1585
|
+
passive: false
|
|
1586
|
+
});
|
|
1587
|
+
this.update();
|
|
1588
|
+
}
|
|
1589
|
+
}
|
|
1590
|
+
|
|
894
1591
|
class OrbitDragger {
|
|
895
1592
|
constructor(viewer) {
|
|
896
1593
|
this.updateControls = () => {
|
|
@@ -905,6 +1602,27 @@ class OrbitDragger {
|
|
|
905
1602
|
this.controlsChange = () => {
|
|
906
1603
|
this.viewer.target.copy(this.orbit.target);
|
|
907
1604
|
this.viewer.update();
|
|
1605
|
+
switch (this.orbit.state) {
|
|
1606
|
+
case STATE.PAN:
|
|
1607
|
+
case STATE.TOUCH_PAN:
|
|
1608
|
+
this.viewer.emitEvent({
|
|
1609
|
+
type: "pan",
|
|
1610
|
+
x: this.orbit.panEnd.x,
|
|
1611
|
+
y: this.orbit.panEnd.y,
|
|
1612
|
+
dX: this.orbit.panDelta.x,
|
|
1613
|
+
dY: this.orbit.panDelta.y
|
|
1614
|
+
});
|
|
1615
|
+
break;
|
|
1616
|
+
|
|
1617
|
+
case STATE.DOLLY:
|
|
1618
|
+
this.viewer.emitEvent({
|
|
1619
|
+
type: "zoomat",
|
|
1620
|
+
data: this.orbit.dollyScale,
|
|
1621
|
+
x: this.orbit.dollyEnd.x,
|
|
1622
|
+
y: this.orbit.dollyEnd.y
|
|
1623
|
+
});
|
|
1624
|
+
break;
|
|
1625
|
+
}
|
|
908
1626
|
this.changed = true;
|
|
909
1627
|
};
|
|
910
1628
|
this.stopContextMenu = event => {
|
|
@@ -936,10 +1654,10 @@ class OrbitDragger {
|
|
|
936
1654
|
this.updateControls();
|
|
937
1655
|
}
|
|
938
1656
|
dispose() {
|
|
939
|
-
this.viewer.off("contextmenu", this.stopContextMenu);
|
|
940
|
-
this.viewer.off("zoom", this.updateControls);
|
|
941
|
-
this.viewer.off("viewposition", this.updateControls);
|
|
942
1657
|
this.viewer.off("geometryend", this.updateControls);
|
|
1658
|
+
this.viewer.off("viewposition", this.updateControls);
|
|
1659
|
+
this.viewer.off("zoom", this.updateControls);
|
|
1660
|
+
this.viewer.off("contextmenu", this.stopContextMenu);
|
|
943
1661
|
this.orbit.removeEventListener("change", this.controlsChange);
|
|
944
1662
|
this.orbit.dispose();
|
|
945
1663
|
}
|
|
@@ -2489,12 +3207,15 @@ class Viewer extends EventEmitter2 {
|
|
|
2489
3207
|
render(time) {
|
|
2490
3208
|
if (!this.renderNeeded) return;
|
|
2491
3209
|
if (!this.renderer) return;
|
|
2492
|
-
|
|
3210
|
+
this.renderNeeded = false;
|
|
2493
3211
|
this.renderer.setViewport(0, 0, this.canvas.offsetWidth, this.canvas.offsetHeight);
|
|
3212
|
+
this.renderer.autoClear = true;
|
|
2494
3213
|
this.renderer.render(this.scene, this.camera);
|
|
3214
|
+
const clippingPlanes = this.renderer.clippingPlanes;
|
|
2495
3215
|
this.renderer.clippingPlanes = [];
|
|
2496
3216
|
this.renderer.autoClear = false;
|
|
2497
3217
|
this.renderer.render(this.helpers, this.camera);
|
|
3218
|
+
this.renderer.clippingPlanes = clippingPlanes;
|
|
2498
3219
|
const deltaTime = (time - this.renderTime) / 1e3;
|
|
2499
3220
|
this.renderTime = time;
|
|
2500
3221
|
this.emitEvent({
|
|
@@ -2502,9 +3223,6 @@ class Viewer extends EventEmitter2 {
|
|
|
2502
3223
|
time: time,
|
|
2503
3224
|
deltaTime: deltaTime
|
|
2504
3225
|
});
|
|
2505
|
-
this.renderer.autoClear = true;
|
|
2506
|
-
this.renderer.clippingPlanes = clippingPlanes;
|
|
2507
|
-
this.renderNeeded = false;
|
|
2508
3226
|
}
|
|
2509
3227
|
update(force = false) {
|
|
2510
3228
|
this.renderNeeded = true;
|
|
@@ -2628,6 +3346,30 @@ class Viewer extends EventEmitter2 {
|
|
|
2628
3346
|
this.update(true);
|
|
2629
3347
|
return this;
|
|
2630
3348
|
}
|
|
3349
|
+
getSelected() {
|
|
3350
|
+
return this.executeCommand("getSelected");
|
|
3351
|
+
}
|
|
3352
|
+
setSelected(handles) {
|
|
3353
|
+
this.executeCommand("setSelected", handles);
|
|
3354
|
+
}
|
|
3355
|
+
clearSelected() {
|
|
3356
|
+
this.executeCommand("clearSelected");
|
|
3357
|
+
}
|
|
3358
|
+
hideSelected() {
|
|
3359
|
+
this.executeCommand("hideSelected");
|
|
3360
|
+
}
|
|
3361
|
+
isolateSelected() {
|
|
3362
|
+
this.executeCommand("isolateSelected");
|
|
3363
|
+
}
|
|
3364
|
+
showAll() {
|
|
3365
|
+
this.executeCommand("showAll");
|
|
3366
|
+
}
|
|
3367
|
+
explode(index = 0) {
|
|
3368
|
+
this.executeCommand("explode", index);
|
|
3369
|
+
}
|
|
3370
|
+
collect() {
|
|
3371
|
+
this.executeCommand("collect");
|
|
3372
|
+
}
|
|
2631
3373
|
activeDragger() {
|
|
2632
3374
|
return this._activeDragger;
|
|
2633
3375
|
}
|
|
@@ -2665,12 +3407,6 @@ class Viewer extends EventEmitter2 {
|
|
|
2665
3407
|
is3D() {
|
|
2666
3408
|
return true;
|
|
2667
3409
|
}
|
|
2668
|
-
getSelected() {
|
|
2669
|
-
return this.executeCommand("getSelected");
|
|
2670
|
-
}
|
|
2671
|
-
setSelected(handles) {
|
|
2672
|
-
this.executeCommand("setSelected", handles);
|
|
2673
|
-
}
|
|
2674
3410
|
executeCommand(id, ...args) {
|
|
2675
3411
|
return commands("ThreeJS").executeCommand(id, this, ...args);
|
|
2676
3412
|
}
|