@inweb/viewer-three 25.11.2 → 25.12.1
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 +17789 -15075
- package/dist/viewer-three.js.map +1 -1
- package/dist/viewer-three.min.js +3 -3
- package/dist/viewer-three.module.js +425 -964
- package/dist/viewer-three.module.js.map +1 -1
- package/lib/Viewer/Viewer.d.ts +6 -0
- package/lib/Viewer/controls/WalkControls.d.ts +12 -4
- package/lib/Viewer/draggers/MeasureLineDragger.d.ts +16 -0
- package/package.json +9 -9
- package/src/Viewer/Viewer.ts +9 -0
- package/src/Viewer/commands/ZoomToObjects.ts +1 -5
- package/src/Viewer/commands/ZoomToSelected.ts +1 -4
- package/src/Viewer/components/ExtentsComponent.ts +1 -4
- package/src/Viewer/components/SelectionComponent.ts +9 -0
- package/src/Viewer/components/WCSHelperComponent.ts +4 -1
- package/src/Viewer/controls/WalkControls.ts +42 -59
- package/src/Viewer/draggers/CuttingPlaneDragger.ts +3 -2
- package/src/Viewer/draggers/MeasureLineDragger.ts +464 -0
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import { Vector2, Raycaster, MeshBasicMaterial, Box3, Vector3, Sphere, LoadingManager, LoaderUtils, EventDispatcher, MOUSE, TOUCH, Quaternion, Spherical,
|
|
1
|
+
import { Vector2, Raycaster, MeshBasicMaterial, Box3, Vector3, Sphere, LoadingManager, LoaderUtils, EventDispatcher, MOUSE, TOUCH, Quaternion, Spherical, Controls, Clock, Line, BufferGeometry, Float32BufferAttribute, LineBasicMaterial, Mesh, DoubleSide, Plane, Object3D, Matrix4, Vector4, AmbientLight, DirectionalLight, Color, PMREMGenerator, OrthographicCamera, CylinderGeometry, Sprite, CanvasTexture, SRGBColorSpace, SpriteMaterial, Scene, PerspectiveCamera, WebGLRenderer, LinearToneMapping } from "three";
|
|
2
2
|
|
|
3
3
|
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
|
|
4
4
|
|
|
5
5
|
import Konva from "konva";
|
|
6
6
|
|
|
7
|
+
import { TransformControls } from "three/examples/jsm/controls/TransformControls.js";
|
|
8
|
+
|
|
7
9
|
import { RoomEnvironment } from "three/examples/jsm/environments/RoomEnvironment.js";
|
|
8
10
|
|
|
9
11
|
class Commands {
|
|
@@ -459,6 +461,20 @@ class SelectionComponent {
|
|
|
459
461
|
this.raycaster.setFromCamera(coords, this.viewer.camera);
|
|
460
462
|
const objects = [];
|
|
461
463
|
this.viewer.scene.traverseVisible((child => objects.push(child)));
|
|
464
|
+
this.raycaster.params = this.raycaster.params = {
|
|
465
|
+
Mesh: {},
|
|
466
|
+
Line: {
|
|
467
|
+
threshold: .25
|
|
468
|
+
},
|
|
469
|
+
Line2: {
|
|
470
|
+
threshold: .25
|
|
471
|
+
},
|
|
472
|
+
LOD: {},
|
|
473
|
+
Points: {
|
|
474
|
+
threshold: .1
|
|
475
|
+
},
|
|
476
|
+
Sprite: {}
|
|
477
|
+
};
|
|
462
478
|
return this.raycaster.intersectObjects(objects, false);
|
|
463
479
|
}
|
|
464
480
|
select(object) {
|
|
@@ -786,10 +802,7 @@ function zoomToObjects(viewer, handles = []) {
|
|
|
786
802
|
var _a;
|
|
787
803
|
if (handleSet.has((_a = child.userData) === null || _a === void 0 ? void 0 : _a.handle)) objects.push(child);
|
|
788
804
|
}));
|
|
789
|
-
const extents = objects.reduce(((result, object) =>
|
|
790
|
-
const objectExtents = (new Box3).setFromObject(object);
|
|
791
|
-
return result.isEmpty() ? result.copy(objectExtents) : result.union(objectExtents);
|
|
792
|
-
}), new Box3);
|
|
805
|
+
const extents = objects.reduce(((result, object) => result.expandByObject(object)), new Box3);
|
|
793
806
|
const center = extents.getCenter(new Vector3);
|
|
794
807
|
const distance = extents.getBoundingSphere(new Sphere).radius;
|
|
795
808
|
const delta = new Vector3(0, 0, 1);
|
|
@@ -806,10 +819,7 @@ function zoomToObjects(viewer, handles = []) {
|
|
|
806
819
|
commands("ThreeJS").registerCommand("zoomToObjects", zoomToObjects);
|
|
807
820
|
|
|
808
821
|
function zoomToSelected(viewer) {
|
|
809
|
-
const extents = viewer.selected.reduce(((result, object) =>
|
|
810
|
-
const objectExtents = (new Box3).setFromObject(object);
|
|
811
|
-
return result.isEmpty() ? result.copy(objectExtents) : result.union(objectExtents);
|
|
812
|
-
}), new Box3);
|
|
822
|
+
const extents = viewer.selected.reduce(((result, object) => result.expandByObject(object)), new Box3);
|
|
813
823
|
if (extents.isEmpty()) extents.copy(viewer.extents);
|
|
814
824
|
const center = extents.getCenter(new Vector3);
|
|
815
825
|
const distance = extents.getBoundingSphere(new Sphere).radius;
|
|
@@ -2740,7 +2750,7 @@ class KonvaMarkup {
|
|
|
2740
2750
|
}
|
|
2741
2751
|
}
|
|
2742
2752
|
|
|
2743
|
-
const _changeEvent
|
|
2753
|
+
const _changeEvent = {
|
|
2744
2754
|
type: "change"
|
|
2745
2755
|
};
|
|
2746
2756
|
|
|
@@ -2837,7 +2847,7 @@ class OrbitControls extends EventDispatcher {
|
|
|
2837
2847
|
scope.object.position.copy(scope.position0);
|
|
2838
2848
|
scope.object.zoom = scope.zoom0;
|
|
2839
2849
|
scope.object.updateProjectionMatrix();
|
|
2840
|
-
scope.dispatchEvent(_changeEvent
|
|
2850
|
+
scope.dispatchEvent(_changeEvent);
|
|
2841
2851
|
scope.update();
|
|
2842
2852
|
scope.state = STATE.NONE;
|
|
2843
2853
|
};
|
|
@@ -2898,7 +2908,7 @@ class OrbitControls extends EventDispatcher {
|
|
|
2898
2908
|
}
|
|
2899
2909
|
scope.scale = 1;
|
|
2900
2910
|
if (scope.zoomChanged || lastPosition.distanceToSquared(scope.object.position) > EPS || 8 * (1 - lastQuaternion.dot(scope.object.quaternion)) > EPS || lastTargetPosition.distanceToSquared(scope.target) > 0) {
|
|
2901
|
-
scope.dispatchEvent(_changeEvent
|
|
2911
|
+
scope.dispatchEvent(_changeEvent);
|
|
2902
2912
|
lastPosition.copy(scope.object.position);
|
|
2903
2913
|
lastQuaternion.copy(scope.object.quaternion);
|
|
2904
2914
|
lastTargetPosition.copy(scope.target);
|
|
@@ -3069,7 +3079,7 @@ class OrbitControls extends EventDispatcher {
|
|
|
3069
3079
|
scope.update();
|
|
3070
3080
|
if (event.deltaY !== 0) {
|
|
3071
3081
|
scope.state = STATE.DOLLY;
|
|
3072
|
-
scope.dispatchEvent(_changeEvent
|
|
3082
|
+
scope.dispatchEvent(_changeEvent);
|
|
3073
3083
|
scope.state = STATE.NONE;
|
|
3074
3084
|
}
|
|
3075
3085
|
}
|
|
@@ -3528,40 +3538,37 @@ class ZoomDragger extends OrbitDragger {
|
|
|
3528
3538
|
}
|
|
3529
3539
|
}
|
|
3530
3540
|
|
|
3531
|
-
|
|
3532
|
-
type: "change"
|
|
3533
|
-
};
|
|
3534
|
-
|
|
3535
|
-
class WalkControls extends EventDispatcher {
|
|
3541
|
+
class WalkControls extends Controls {
|
|
3536
3542
|
constructor(camera, canvas) {
|
|
3537
|
-
super();
|
|
3543
|
+
super(camera, canvas);
|
|
3538
3544
|
this.movementSpeed = .2;
|
|
3539
3545
|
this.lookSpeed = 5;
|
|
3540
3546
|
this.multiplier = 5;
|
|
3541
3547
|
this.moveWheel = 0;
|
|
3542
3548
|
this.mouseDragOn = false;
|
|
3543
3549
|
this.onPointerDown = event => {
|
|
3544
|
-
if (
|
|
3545
|
-
this.
|
|
3550
|
+
if (event.button !== 0) return;
|
|
3551
|
+
this.domElement.setPointerCapture(event.pointerId);
|
|
3546
3552
|
this.downPosition.set(event.clientX, event.clientY);
|
|
3547
|
-
this.quaternion.copy(this.
|
|
3553
|
+
this.quaternion.copy(this.object.quaternion);
|
|
3548
3554
|
this.mouseDragOn = true;
|
|
3549
3555
|
};
|
|
3550
3556
|
this.onPointerMove = event => {
|
|
3551
|
-
if (!
|
|
3557
|
+
if (!this.mouseDragOn) return;
|
|
3552
3558
|
const movePosition = new Vector2(event.clientX, event.clientY);
|
|
3553
3559
|
if (this.downPosition.distanceTo(movePosition) === 0) return;
|
|
3554
3560
|
this.rotateDelta.copy(this.downPosition).sub(movePosition);
|
|
3555
3561
|
this.rotateCamera(this.rotateDelta);
|
|
3556
|
-
this.dispatchEvent(
|
|
3562
|
+
this.dispatchEvent({
|
|
3563
|
+
type: "change"
|
|
3564
|
+
});
|
|
3557
3565
|
};
|
|
3558
3566
|
this.onPointerUp = event => {
|
|
3559
|
-
|
|
3560
|
-
this.canvas.releasePointerCapture(event.pointerId);
|
|
3567
|
+
this.domElement.releasePointerCapture(event.pointerId);
|
|
3561
3568
|
this.mouseDragOn = false;
|
|
3562
3569
|
};
|
|
3563
3570
|
this.onPointerCancel = event => {
|
|
3564
|
-
this.
|
|
3571
|
+
this.domElement.dispatchEvent(new PointerEvent("pointerup", event));
|
|
3565
3572
|
};
|
|
3566
3573
|
this.onWheel = event => {
|
|
3567
3574
|
this.moveWheel = event.deltaY;
|
|
@@ -3607,69 +3614,58 @@ class WalkControls extends EventDispatcher {
|
|
|
3607
3614
|
}
|
|
3608
3615
|
};
|
|
3609
3616
|
this.onKeyUp = event => {
|
|
3610
|
-
|
|
3611
|
-
case "ArrowLeft":
|
|
3612
|
-
case "ArrowRight":
|
|
3613
|
-
case "ArrowUp":
|
|
3614
|
-
case "ArrowDown":
|
|
3615
|
-
case "KeyW":
|
|
3616
|
-
case "KeyS":
|
|
3617
|
-
case "KeyA":
|
|
3618
|
-
case "KeyD":
|
|
3619
|
-
case "KeyQ":
|
|
3620
|
-
case "KeyE":
|
|
3621
|
-
this.moveKeys.delete(event.code);
|
|
3622
|
-
this.update();
|
|
3623
|
-
break;
|
|
3624
|
-
}
|
|
3617
|
+
if (this.moveKeys.delete(event.code)) this.update();
|
|
3625
3618
|
};
|
|
3626
|
-
this.camera = camera;
|
|
3627
|
-
this.canvas = canvas;
|
|
3628
3619
|
this.moveKeys = new Set;
|
|
3629
3620
|
this.moveClock = new Clock;
|
|
3630
3621
|
this.quaternion = camera.quaternion.clone();
|
|
3631
3622
|
this.downPosition = new Vector2(0, 0);
|
|
3632
3623
|
this.rotateDelta = new Vector2(0, 0);
|
|
3633
|
-
this.
|
|
3634
|
-
this.
|
|
3635
|
-
this.
|
|
3636
|
-
this.
|
|
3637
|
-
this.
|
|
3624
|
+
this.domElement.addEventListener("pointerdown", this.onPointerDown);
|
|
3625
|
+
this.domElement.addEventListener("pointermove", this.onPointerMove);
|
|
3626
|
+
this.domElement.addEventListener("pointerup", this.onPointerUp);
|
|
3627
|
+
this.domElement.addEventListener("pointercancel", this.onPointerCancel);
|
|
3628
|
+
this.domElement.addEventListener("wheel", this.onWheel);
|
|
3638
3629
|
window.addEventListener("keydown", this.onKeyDown);
|
|
3639
3630
|
window.addEventListener("keyup", this.onKeyUp);
|
|
3640
3631
|
}
|
|
3641
3632
|
dispose() {
|
|
3642
|
-
this.
|
|
3643
|
-
this.
|
|
3644
|
-
this.
|
|
3645
|
-
this.
|
|
3646
|
-
this.
|
|
3633
|
+
this.domElement.removeEventListener("pointerdown", this.onPointerDown);
|
|
3634
|
+
this.domElement.removeEventListener("pointermove", this.onPointerMove);
|
|
3635
|
+
this.domElement.removeEventListener("pointerup", this.onPointerUp);
|
|
3636
|
+
this.domElement.removeEventListener("pointercancel", this.onPointerCancel);
|
|
3637
|
+
this.domElement.removeEventListener("wheel", this.onWheel);
|
|
3647
3638
|
window.removeEventListener("keydown", this.onKeyDown);
|
|
3648
3639
|
window.removeEventListener("keyup", this.onKeyUp);
|
|
3640
|
+
super.dispose();
|
|
3649
3641
|
}
|
|
3650
3642
|
update() {
|
|
3651
3643
|
if (this.moveKeys.size > 0) {
|
|
3652
3644
|
const timeDelta = this.moveClock.getDelta();
|
|
3653
3645
|
const moveDelta = timeDelta * this.movementSpeed * this.multiplier;
|
|
3654
|
-
if (this.moveKeys.has("KeyW")) this.
|
|
3655
|
-
if (this.moveKeys.has("KeyS")) this.
|
|
3656
|
-
if (this.moveKeys.has("KeyA")) this.
|
|
3657
|
-
if (this.moveKeys.has("KeyD")) this.
|
|
3658
|
-
if (this.moveKeys.has("KeyQ")) this.
|
|
3659
|
-
if (this.moveKeys.has("KeyE")) this.
|
|
3646
|
+
if (this.moveKeys.has("KeyW")) this.object.translateZ(-moveDelta);
|
|
3647
|
+
if (this.moveKeys.has("KeyS")) this.object.translateZ(moveDelta);
|
|
3648
|
+
if (this.moveKeys.has("KeyA")) this.object.translateX(-moveDelta);
|
|
3649
|
+
if (this.moveKeys.has("KeyD")) this.object.translateX(moveDelta);
|
|
3650
|
+
if (this.moveKeys.has("KeyQ")) this.object.translateY(moveDelta);
|
|
3651
|
+
if (this.moveKeys.has("KeyE")) this.object.translateY(-moveDelta);
|
|
3660
3652
|
const lookDelta = this.lookSpeed + (this.multiplier - 1);
|
|
3661
3653
|
if (this.moveKeys.has("ArrowUp")) this.rotateCamera(this.rotateDelta.add(new Vector2(0, -lookDelta / 2)));
|
|
3662
3654
|
if (this.moveKeys.has("ArrowDown")) this.rotateCamera(this.rotateDelta.add(new Vector2(0, lookDelta / 2)));
|
|
3663
3655
|
if (this.moveKeys.has("ArrowLeft")) this.rotateCamera(this.rotateDelta.add(new Vector2(lookDelta, 0)));
|
|
3664
3656
|
if (this.moveKeys.has("ArrowRight")) this.rotateCamera(this.rotateDelta.add(new Vector2(-lookDelta, 0)));
|
|
3665
3657
|
this.moveWheel = 0;
|
|
3666
|
-
this.dispatchEvent(
|
|
3658
|
+
this.dispatchEvent({
|
|
3659
|
+
type: "change"
|
|
3660
|
+
});
|
|
3667
3661
|
}
|
|
3668
3662
|
if (this.moveWheel !== 0) {
|
|
3669
3663
|
const moveDelta = this.moveWheel * 1e-4 * this.movementSpeed * this.multiplier;
|
|
3670
|
-
this.
|
|
3664
|
+
this.object.translateZ(-moveDelta);
|
|
3671
3665
|
this.moveWheel += -1 * Math.sign(this.moveWheel);
|
|
3672
|
-
this.dispatchEvent(
|
|
3666
|
+
this.dispatchEvent({
|
|
3667
|
+
type: "change"
|
|
3668
|
+
});
|
|
3673
3669
|
}
|
|
3674
3670
|
if (this.moveKeys.size === 0 && this.moveWheel === 0) {
|
|
3675
3671
|
this.moveClock.stop();
|
|
@@ -3677,15 +3673,15 @@ class WalkControls extends EventDispatcher {
|
|
|
3677
3673
|
}
|
|
3678
3674
|
}
|
|
3679
3675
|
rotateCamera(delta) {
|
|
3680
|
-
const rotateX = Math.PI * delta.x / this.
|
|
3681
|
-
const rotateY = Math.PI * delta.y / this.
|
|
3676
|
+
const rotateX = Math.PI * delta.x / this.domElement.clientWidth;
|
|
3677
|
+
const rotateY = Math.PI * delta.y / this.domElement.clientHeight;
|
|
3682
3678
|
const xRotation = new Quaternion;
|
|
3683
|
-
xRotation.setFromAxisAngle(this.
|
|
3679
|
+
xRotation.setFromAxisAngle(this.object.up, rotateX);
|
|
3684
3680
|
const yRotation = new Quaternion;
|
|
3685
3681
|
yRotation.setFromAxisAngle(new Vector3(1, 0, 0), rotateY);
|
|
3686
3682
|
const quaternion = this.quaternion.clone();
|
|
3687
3683
|
quaternion.premultiply(xRotation).multiply(yRotation).normalize();
|
|
3688
|
-
this.
|
|
3684
|
+
this.object.setRotationFromQuaternion(quaternion);
|
|
3689
3685
|
}
|
|
3690
3686
|
}
|
|
3691
3687
|
|
|
@@ -3724,895 +3720,6 @@ class WalkDragger {
|
|
|
3724
3720
|
}
|
|
3725
3721
|
}
|
|
3726
3722
|
|
|
3727
|
-
const _raycaster = new Raycaster;
|
|
3728
|
-
|
|
3729
|
-
const _tempVector = new Vector3;
|
|
3730
|
-
|
|
3731
|
-
const _tempVector2 = new Vector3;
|
|
3732
|
-
|
|
3733
|
-
const _tempQuaternion = new Quaternion;
|
|
3734
|
-
|
|
3735
|
-
const _unit = {
|
|
3736
|
-
X: new Vector3(1, 0, 0),
|
|
3737
|
-
Y: new Vector3(0, 1, 0),
|
|
3738
|
-
Z: new Vector3(0, 0, 1)
|
|
3739
|
-
};
|
|
3740
|
-
|
|
3741
|
-
const _changeEvent = {
|
|
3742
|
-
type: "change"
|
|
3743
|
-
};
|
|
3744
|
-
|
|
3745
|
-
const _mouseDownEvent = {
|
|
3746
|
-
type: "mouseDown"
|
|
3747
|
-
};
|
|
3748
|
-
|
|
3749
|
-
const _mouseUpEvent = {
|
|
3750
|
-
type: "mouseUp",
|
|
3751
|
-
mode: null
|
|
3752
|
-
};
|
|
3753
|
-
|
|
3754
|
-
const _objectChangeEvent = {
|
|
3755
|
-
type: "objectChange"
|
|
3756
|
-
};
|
|
3757
|
-
|
|
3758
|
-
class TransformControls extends Object3D {
|
|
3759
|
-
constructor(camera, domElement) {
|
|
3760
|
-
super();
|
|
3761
|
-
if (domElement === undefined) {
|
|
3762
|
-
console.warn('THREE.TransformControls: The second parameter "domElement" is now mandatory.');
|
|
3763
|
-
domElement = document;
|
|
3764
|
-
}
|
|
3765
|
-
this.isTransformControls = true;
|
|
3766
|
-
this.visible = false;
|
|
3767
|
-
this.domElement = domElement;
|
|
3768
|
-
this.domElement.style.touchAction = "none";
|
|
3769
|
-
const _gizmo = new TransformControlsGizmo;
|
|
3770
|
-
this._gizmo = _gizmo;
|
|
3771
|
-
this.add(_gizmo);
|
|
3772
|
-
const _plane = new TransformControlsPlane;
|
|
3773
|
-
this._plane = _plane;
|
|
3774
|
-
this.add(_plane);
|
|
3775
|
-
const scope = this;
|
|
3776
|
-
function defineProperty(propName, defaultValue) {
|
|
3777
|
-
let propValue = defaultValue;
|
|
3778
|
-
Object.defineProperty(scope, propName, {
|
|
3779
|
-
get: function() {
|
|
3780
|
-
return propValue !== undefined ? propValue : defaultValue;
|
|
3781
|
-
},
|
|
3782
|
-
set: function(value) {
|
|
3783
|
-
if (propValue !== value) {
|
|
3784
|
-
propValue = value;
|
|
3785
|
-
_plane[propName] = value;
|
|
3786
|
-
_gizmo[propName] = value;
|
|
3787
|
-
scope.dispatchEvent({
|
|
3788
|
-
type: propName + "-changed",
|
|
3789
|
-
value: value
|
|
3790
|
-
});
|
|
3791
|
-
scope.dispatchEvent(_changeEvent);
|
|
3792
|
-
}
|
|
3793
|
-
}
|
|
3794
|
-
});
|
|
3795
|
-
scope[propName] = defaultValue;
|
|
3796
|
-
_plane[propName] = defaultValue;
|
|
3797
|
-
_gizmo[propName] = defaultValue;
|
|
3798
|
-
}
|
|
3799
|
-
defineProperty("camera", camera);
|
|
3800
|
-
defineProperty("object", undefined);
|
|
3801
|
-
defineProperty("enabled", true);
|
|
3802
|
-
defineProperty("axis", null);
|
|
3803
|
-
defineProperty("mode", "translate");
|
|
3804
|
-
defineProperty("translationSnap", null);
|
|
3805
|
-
defineProperty("rotationSnap", null);
|
|
3806
|
-
defineProperty("scaleSnap", null);
|
|
3807
|
-
defineProperty("space", "world");
|
|
3808
|
-
defineProperty("size", 1);
|
|
3809
|
-
defineProperty("dragging", false);
|
|
3810
|
-
defineProperty("showX", true);
|
|
3811
|
-
defineProperty("showY", true);
|
|
3812
|
-
defineProperty("showZ", true);
|
|
3813
|
-
const worldPosition = new Vector3;
|
|
3814
|
-
const worldPositionStart = new Vector3;
|
|
3815
|
-
const worldQuaternion = new Quaternion;
|
|
3816
|
-
const worldQuaternionStart = new Quaternion;
|
|
3817
|
-
const cameraPosition = new Vector3;
|
|
3818
|
-
const cameraQuaternion = new Quaternion;
|
|
3819
|
-
const pointStart = new Vector3;
|
|
3820
|
-
const pointEnd = new Vector3;
|
|
3821
|
-
const rotationAxis = new Vector3;
|
|
3822
|
-
const rotationAngle = 0;
|
|
3823
|
-
const eye = new Vector3;
|
|
3824
|
-
defineProperty("worldPosition", worldPosition);
|
|
3825
|
-
defineProperty("worldPositionStart", worldPositionStart);
|
|
3826
|
-
defineProperty("worldQuaternion", worldQuaternion);
|
|
3827
|
-
defineProperty("worldQuaternionStart", worldQuaternionStart);
|
|
3828
|
-
defineProperty("cameraPosition", cameraPosition);
|
|
3829
|
-
defineProperty("cameraQuaternion", cameraQuaternion);
|
|
3830
|
-
defineProperty("pointStart", pointStart);
|
|
3831
|
-
defineProperty("pointEnd", pointEnd);
|
|
3832
|
-
defineProperty("rotationAxis", rotationAxis);
|
|
3833
|
-
defineProperty("rotationAngle", rotationAngle);
|
|
3834
|
-
defineProperty("eye", eye);
|
|
3835
|
-
this._offset = new Vector3;
|
|
3836
|
-
this._startNorm = new Vector3;
|
|
3837
|
-
this._endNorm = new Vector3;
|
|
3838
|
-
this._cameraScale = new Vector3;
|
|
3839
|
-
this._parentPosition = new Vector3;
|
|
3840
|
-
this._parentQuaternion = new Quaternion;
|
|
3841
|
-
this._parentQuaternionInv = new Quaternion;
|
|
3842
|
-
this._parentScale = new Vector3;
|
|
3843
|
-
this._worldScaleStart = new Vector3;
|
|
3844
|
-
this._worldQuaternionInv = new Quaternion;
|
|
3845
|
-
this._worldScale = new Vector3;
|
|
3846
|
-
this._positionStart = new Vector3;
|
|
3847
|
-
this._quaternionStart = new Quaternion;
|
|
3848
|
-
this._scaleStart = new Vector3;
|
|
3849
|
-
this._getPointer = getPointer.bind(this);
|
|
3850
|
-
this._onPointerDown = onPointerDown.bind(this);
|
|
3851
|
-
this._onPointerHover = onPointerHover.bind(this);
|
|
3852
|
-
this._onPointerMove = onPointerMove.bind(this);
|
|
3853
|
-
this._onPointerUp = onPointerUp.bind(this);
|
|
3854
|
-
this.domElement.addEventListener("pointerdown", this._onPointerDown);
|
|
3855
|
-
this.domElement.addEventListener("pointermove", this._onPointerHover);
|
|
3856
|
-
this.domElement.addEventListener("pointerup", this._onPointerUp);
|
|
3857
|
-
}
|
|
3858
|
-
updateMatrixWorld() {
|
|
3859
|
-
if (this.object !== undefined) {
|
|
3860
|
-
this.object.updateMatrixWorld();
|
|
3861
|
-
if (this.object.parent === null) {
|
|
3862
|
-
console.error("TransformControls: The attached 3D object must be a part of the scene graph.");
|
|
3863
|
-
} else {
|
|
3864
|
-
this.object.parent.matrixWorld.decompose(this._parentPosition, this._parentQuaternion, this._parentScale);
|
|
3865
|
-
}
|
|
3866
|
-
this.object.matrixWorld.decompose(this.worldPosition, this.worldQuaternion, this._worldScale);
|
|
3867
|
-
this._parentQuaternionInv.copy(this._parentQuaternion).invert();
|
|
3868
|
-
this._worldQuaternionInv.copy(this.worldQuaternion).invert();
|
|
3869
|
-
}
|
|
3870
|
-
this.camera.updateMatrixWorld();
|
|
3871
|
-
this.camera.matrixWorld.decompose(this.cameraPosition, this.cameraQuaternion, this._cameraScale);
|
|
3872
|
-
if (this.camera.isOrthographicCamera) {
|
|
3873
|
-
this.camera.getWorldDirection(this.eye).negate();
|
|
3874
|
-
} else {
|
|
3875
|
-
this.eye.copy(this.cameraPosition).sub(this.worldPosition).normalize();
|
|
3876
|
-
}
|
|
3877
|
-
super.updateMatrixWorld(this);
|
|
3878
|
-
}
|
|
3879
|
-
pointerHover(pointer) {
|
|
3880
|
-
if (this.object === undefined || this.dragging === true) return;
|
|
3881
|
-
_raycaster.setFromCamera(pointer, this.camera);
|
|
3882
|
-
const intersect = intersectObjectWithRay(this._gizmo.picker[this.mode], _raycaster);
|
|
3883
|
-
if (intersect) {
|
|
3884
|
-
this.axis = intersect.object.name;
|
|
3885
|
-
} else {
|
|
3886
|
-
this.axis = null;
|
|
3887
|
-
}
|
|
3888
|
-
}
|
|
3889
|
-
pointerDown(pointer) {
|
|
3890
|
-
if (this.object === undefined || this.dragging === true || pointer.button !== 0) return;
|
|
3891
|
-
if (this.axis !== null) {
|
|
3892
|
-
_raycaster.setFromCamera(pointer, this.camera);
|
|
3893
|
-
const planeIntersect = intersectObjectWithRay(this._plane, _raycaster, true);
|
|
3894
|
-
if (planeIntersect) {
|
|
3895
|
-
this.object.updateMatrixWorld();
|
|
3896
|
-
this.object.parent.updateMatrixWorld();
|
|
3897
|
-
this._positionStart.copy(this.object.position);
|
|
3898
|
-
this._quaternionStart.copy(this.object.quaternion);
|
|
3899
|
-
this._scaleStart.copy(this.object.scale);
|
|
3900
|
-
this.object.matrixWorld.decompose(this.worldPositionStart, this.worldQuaternionStart, this._worldScaleStart);
|
|
3901
|
-
this.pointStart.copy(planeIntersect.point).sub(this.worldPositionStart);
|
|
3902
|
-
}
|
|
3903
|
-
this.dragging = true;
|
|
3904
|
-
_mouseDownEvent.mode = this.mode;
|
|
3905
|
-
this.dispatchEvent(_mouseDownEvent);
|
|
3906
|
-
}
|
|
3907
|
-
}
|
|
3908
|
-
pointerMove(pointer) {
|
|
3909
|
-
const axis = this.axis;
|
|
3910
|
-
const mode = this.mode;
|
|
3911
|
-
const object = this.object;
|
|
3912
|
-
let space = this.space;
|
|
3913
|
-
if (mode === "scale") {
|
|
3914
|
-
space = "local";
|
|
3915
|
-
} else if (axis === "E" || axis === "XYZE" || axis === "XYZ") {
|
|
3916
|
-
space = "world";
|
|
3917
|
-
}
|
|
3918
|
-
if (object === undefined || axis === null || this.dragging === false || pointer.button !== -1) return;
|
|
3919
|
-
_raycaster.setFromCamera(pointer, this.camera);
|
|
3920
|
-
const planeIntersect = intersectObjectWithRay(this._plane, _raycaster, true);
|
|
3921
|
-
if (!planeIntersect) return;
|
|
3922
|
-
this.pointEnd.copy(planeIntersect.point).sub(this.worldPositionStart);
|
|
3923
|
-
if (mode === "translate") {
|
|
3924
|
-
this._offset.copy(this.pointEnd).sub(this.pointStart);
|
|
3925
|
-
if (space === "local" && axis !== "XYZ") {
|
|
3926
|
-
this._offset.applyQuaternion(this._worldQuaternionInv);
|
|
3927
|
-
}
|
|
3928
|
-
if (axis.indexOf("X") === -1) this._offset.x = 0;
|
|
3929
|
-
if (axis.indexOf("Y") === -1) this._offset.y = 0;
|
|
3930
|
-
if (axis.indexOf("Z") === -1) this._offset.z = 0;
|
|
3931
|
-
if (space === "local" && axis !== "XYZ") {
|
|
3932
|
-
this._offset.applyQuaternion(this._quaternionStart).divide(this._parentScale);
|
|
3933
|
-
} else {
|
|
3934
|
-
this._offset.applyQuaternion(this._parentQuaternionInv).divide(this._parentScale);
|
|
3935
|
-
}
|
|
3936
|
-
object.position.copy(this._offset).add(this._positionStart);
|
|
3937
|
-
if (this.translationSnap) {
|
|
3938
|
-
if (space === "local") {
|
|
3939
|
-
object.position.applyQuaternion(_tempQuaternion.copy(this._quaternionStart).invert());
|
|
3940
|
-
if (axis.search("X") !== -1) {
|
|
3941
|
-
object.position.x = Math.round(object.position.x / this.translationSnap) * this.translationSnap;
|
|
3942
|
-
}
|
|
3943
|
-
if (axis.search("Y") !== -1) {
|
|
3944
|
-
object.position.y = Math.round(object.position.y / this.translationSnap) * this.translationSnap;
|
|
3945
|
-
}
|
|
3946
|
-
if (axis.search("Z") !== -1) {
|
|
3947
|
-
object.position.z = Math.round(object.position.z / this.translationSnap) * this.translationSnap;
|
|
3948
|
-
}
|
|
3949
|
-
object.position.applyQuaternion(this._quaternionStart);
|
|
3950
|
-
}
|
|
3951
|
-
if (space === "world") {
|
|
3952
|
-
if (object.parent) {
|
|
3953
|
-
object.position.add(_tempVector.setFromMatrixPosition(object.parent.matrixWorld));
|
|
3954
|
-
}
|
|
3955
|
-
if (axis.search("X") !== -1) {
|
|
3956
|
-
object.position.x = Math.round(object.position.x / this.translationSnap) * this.translationSnap;
|
|
3957
|
-
}
|
|
3958
|
-
if (axis.search("Y") !== -1) {
|
|
3959
|
-
object.position.y = Math.round(object.position.y / this.translationSnap) * this.translationSnap;
|
|
3960
|
-
}
|
|
3961
|
-
if (axis.search("Z") !== -1) {
|
|
3962
|
-
object.position.z = Math.round(object.position.z / this.translationSnap) * this.translationSnap;
|
|
3963
|
-
}
|
|
3964
|
-
if (object.parent) {
|
|
3965
|
-
object.position.sub(_tempVector.setFromMatrixPosition(object.parent.matrixWorld));
|
|
3966
|
-
}
|
|
3967
|
-
}
|
|
3968
|
-
}
|
|
3969
|
-
} else if (mode === "scale") {
|
|
3970
|
-
if (axis.search("XYZ") !== -1) {
|
|
3971
|
-
let d = this.pointEnd.length() / this.pointStart.length();
|
|
3972
|
-
if (this.pointEnd.dot(this.pointStart) < 0) d *= -1;
|
|
3973
|
-
_tempVector2.set(d, d, d);
|
|
3974
|
-
} else {
|
|
3975
|
-
_tempVector.copy(this.pointStart);
|
|
3976
|
-
_tempVector2.copy(this.pointEnd);
|
|
3977
|
-
_tempVector.applyQuaternion(this._worldQuaternionInv);
|
|
3978
|
-
_tempVector2.applyQuaternion(this._worldQuaternionInv);
|
|
3979
|
-
_tempVector2.divide(_tempVector);
|
|
3980
|
-
if (axis.search("X") === -1) {
|
|
3981
|
-
_tempVector2.x = 1;
|
|
3982
|
-
}
|
|
3983
|
-
if (axis.search("Y") === -1) {
|
|
3984
|
-
_tempVector2.y = 1;
|
|
3985
|
-
}
|
|
3986
|
-
if (axis.search("Z") === -1) {
|
|
3987
|
-
_tempVector2.z = 1;
|
|
3988
|
-
}
|
|
3989
|
-
}
|
|
3990
|
-
object.scale.copy(this._scaleStart).multiply(_tempVector2);
|
|
3991
|
-
if (this.scaleSnap) {
|
|
3992
|
-
if (axis.search("X") !== -1) {
|
|
3993
|
-
object.scale.x = Math.round(object.scale.x / this.scaleSnap) * this.scaleSnap || this.scaleSnap;
|
|
3994
|
-
}
|
|
3995
|
-
if (axis.search("Y") !== -1) {
|
|
3996
|
-
object.scale.y = Math.round(object.scale.y / this.scaleSnap) * this.scaleSnap || this.scaleSnap;
|
|
3997
|
-
}
|
|
3998
|
-
if (axis.search("Z") !== -1) {
|
|
3999
|
-
object.scale.z = Math.round(object.scale.z / this.scaleSnap) * this.scaleSnap || this.scaleSnap;
|
|
4000
|
-
}
|
|
4001
|
-
}
|
|
4002
|
-
} else if (mode === "rotate") {
|
|
4003
|
-
this._offset.copy(this.pointEnd).sub(this.pointStart);
|
|
4004
|
-
const ROTATION_SPEED = 20 / this.worldPosition.distanceTo(_tempVector.setFromMatrixPosition(this.camera.matrixWorld));
|
|
4005
|
-
if (axis === "E") {
|
|
4006
|
-
this.rotationAxis.copy(this.eye);
|
|
4007
|
-
this.rotationAngle = this.pointEnd.angleTo(this.pointStart);
|
|
4008
|
-
this._startNorm.copy(this.pointStart).normalize();
|
|
4009
|
-
this._endNorm.copy(this.pointEnd).normalize();
|
|
4010
|
-
this.rotationAngle *= this._endNorm.cross(this._startNorm).dot(this.eye) < 0 ? 1 : -1;
|
|
4011
|
-
} else if (axis === "XYZE") {
|
|
4012
|
-
this.rotationAxis.copy(this._offset).cross(this.eye).normalize();
|
|
4013
|
-
this.rotationAngle = this._offset.dot(_tempVector.copy(this.rotationAxis).cross(this.eye)) * ROTATION_SPEED;
|
|
4014
|
-
} else if (axis === "X" || axis === "Y" || axis === "Z") {
|
|
4015
|
-
this.rotationAxis.copy(_unit[axis]);
|
|
4016
|
-
_tempVector.copy(_unit[axis]);
|
|
4017
|
-
if (space === "local") {
|
|
4018
|
-
_tempVector.applyQuaternion(this.worldQuaternion);
|
|
4019
|
-
}
|
|
4020
|
-
this.rotationAngle = this._offset.dot(_tempVector.cross(this.eye).normalize()) * ROTATION_SPEED;
|
|
4021
|
-
}
|
|
4022
|
-
if (this.rotationSnap) this.rotationAngle = Math.round(this.rotationAngle / this.rotationSnap) * this.rotationSnap;
|
|
4023
|
-
if (space === "local" && axis !== "E" && axis !== "XYZE") {
|
|
4024
|
-
object.quaternion.copy(this._quaternionStart);
|
|
4025
|
-
object.quaternion.multiply(_tempQuaternion.setFromAxisAngle(this.rotationAxis, this.rotationAngle)).normalize();
|
|
4026
|
-
} else {
|
|
4027
|
-
this.rotationAxis.applyQuaternion(this._parentQuaternionInv);
|
|
4028
|
-
object.quaternion.copy(_tempQuaternion.setFromAxisAngle(this.rotationAxis, this.rotationAngle));
|
|
4029
|
-
object.quaternion.multiply(this._quaternionStart).normalize();
|
|
4030
|
-
}
|
|
4031
|
-
}
|
|
4032
|
-
this.dispatchEvent(_changeEvent);
|
|
4033
|
-
this.dispatchEvent(_objectChangeEvent);
|
|
4034
|
-
}
|
|
4035
|
-
pointerUp(pointer) {
|
|
4036
|
-
if (pointer.button !== 0) return;
|
|
4037
|
-
if (this.dragging && this.axis !== null) {
|
|
4038
|
-
_mouseUpEvent.mode = this.mode;
|
|
4039
|
-
this.dispatchEvent(_mouseUpEvent);
|
|
4040
|
-
}
|
|
4041
|
-
this.dragging = false;
|
|
4042
|
-
this.axis = null;
|
|
4043
|
-
}
|
|
4044
|
-
dispose() {
|
|
4045
|
-
this.domElement.removeEventListener("pointerdown", this._onPointerDown);
|
|
4046
|
-
this.domElement.removeEventListener("pointermove", this._onPointerHover);
|
|
4047
|
-
this.domElement.removeEventListener("pointermove", this._onPointerMove);
|
|
4048
|
-
this.domElement.removeEventListener("pointerup", this._onPointerUp);
|
|
4049
|
-
this.traverse((function(child) {
|
|
4050
|
-
if (child.geometry) child.geometry.dispose();
|
|
4051
|
-
if (child.material) child.material.dispose();
|
|
4052
|
-
}));
|
|
4053
|
-
}
|
|
4054
|
-
attach(object) {
|
|
4055
|
-
this.object = object;
|
|
4056
|
-
this.visible = true;
|
|
4057
|
-
return this;
|
|
4058
|
-
}
|
|
4059
|
-
detach() {
|
|
4060
|
-
this.object = undefined;
|
|
4061
|
-
this.visible = false;
|
|
4062
|
-
this.axis = null;
|
|
4063
|
-
return this;
|
|
4064
|
-
}
|
|
4065
|
-
reset() {
|
|
4066
|
-
if (!this.enabled) return;
|
|
4067
|
-
if (this.dragging) {
|
|
4068
|
-
this.object.position.copy(this._positionStart);
|
|
4069
|
-
this.object.quaternion.copy(this._quaternionStart);
|
|
4070
|
-
this.object.scale.copy(this._scaleStart);
|
|
4071
|
-
this.dispatchEvent(_changeEvent);
|
|
4072
|
-
this.dispatchEvent(_objectChangeEvent);
|
|
4073
|
-
this.pointStart.copy(this.pointEnd);
|
|
4074
|
-
}
|
|
4075
|
-
}
|
|
4076
|
-
getRaycaster() {
|
|
4077
|
-
return _raycaster;
|
|
4078
|
-
}
|
|
4079
|
-
getMode() {
|
|
4080
|
-
return this.mode;
|
|
4081
|
-
}
|
|
4082
|
-
setMode(mode) {
|
|
4083
|
-
this.mode = mode;
|
|
4084
|
-
}
|
|
4085
|
-
setTranslationSnap(translationSnap) {
|
|
4086
|
-
this.translationSnap = translationSnap;
|
|
4087
|
-
}
|
|
4088
|
-
setRotationSnap(rotationSnap) {
|
|
4089
|
-
this.rotationSnap = rotationSnap;
|
|
4090
|
-
}
|
|
4091
|
-
setScaleSnap(scaleSnap) {
|
|
4092
|
-
this.scaleSnap = scaleSnap;
|
|
4093
|
-
}
|
|
4094
|
-
setSize(size) {
|
|
4095
|
-
this.size = size;
|
|
4096
|
-
}
|
|
4097
|
-
setSpace(space) {
|
|
4098
|
-
this.space = space;
|
|
4099
|
-
}
|
|
4100
|
-
}
|
|
4101
|
-
|
|
4102
|
-
function getPointer(event) {
|
|
4103
|
-
if (this.domElement.ownerDocument.pointerLockElement) {
|
|
4104
|
-
return {
|
|
4105
|
-
x: 0,
|
|
4106
|
-
y: 0,
|
|
4107
|
-
button: event.button
|
|
4108
|
-
};
|
|
4109
|
-
} else {
|
|
4110
|
-
const rect = this.domElement.getBoundingClientRect();
|
|
4111
|
-
return {
|
|
4112
|
-
x: (event.clientX - rect.left) / rect.width * 2 - 1,
|
|
4113
|
-
y: -(event.clientY - rect.top) / rect.height * 2 + 1,
|
|
4114
|
-
button: event.button
|
|
4115
|
-
};
|
|
4116
|
-
}
|
|
4117
|
-
}
|
|
4118
|
-
|
|
4119
|
-
function onPointerHover(event) {
|
|
4120
|
-
if (!this.enabled) return;
|
|
4121
|
-
switch (event.pointerType) {
|
|
4122
|
-
case "mouse":
|
|
4123
|
-
case "pen":
|
|
4124
|
-
this.pointerHover(this._getPointer(event));
|
|
4125
|
-
break;
|
|
4126
|
-
}
|
|
4127
|
-
}
|
|
4128
|
-
|
|
4129
|
-
function onPointerDown(event) {
|
|
4130
|
-
if (!this.enabled) return;
|
|
4131
|
-
if (!document.pointerLockElement) {
|
|
4132
|
-
this.domElement.setPointerCapture(event.pointerId);
|
|
4133
|
-
}
|
|
4134
|
-
this.domElement.addEventListener("pointermove", this._onPointerMove);
|
|
4135
|
-
this.pointerHover(this._getPointer(event));
|
|
4136
|
-
this.pointerDown(this._getPointer(event));
|
|
4137
|
-
}
|
|
4138
|
-
|
|
4139
|
-
function onPointerMove(event) {
|
|
4140
|
-
if (!this.enabled) return;
|
|
4141
|
-
this.pointerMove(this._getPointer(event));
|
|
4142
|
-
}
|
|
4143
|
-
|
|
4144
|
-
function onPointerUp(event) {
|
|
4145
|
-
if (!this.enabled) return;
|
|
4146
|
-
this.domElement.releasePointerCapture(event.pointerId);
|
|
4147
|
-
this.domElement.removeEventListener("pointermove", this._onPointerMove);
|
|
4148
|
-
this.pointerUp(this._getPointer(event));
|
|
4149
|
-
}
|
|
4150
|
-
|
|
4151
|
-
function intersectObjectWithRay(object, raycaster, includeInvisible) {
|
|
4152
|
-
const allIntersections = raycaster.intersectObject(object, true);
|
|
4153
|
-
for (let i = 0; i < allIntersections.length; i++) {
|
|
4154
|
-
if (allIntersections[i].object.visible || includeInvisible) {
|
|
4155
|
-
return allIntersections[i];
|
|
4156
|
-
}
|
|
4157
|
-
}
|
|
4158
|
-
return false;
|
|
4159
|
-
}
|
|
4160
|
-
|
|
4161
|
-
const _tempEuler = new Euler;
|
|
4162
|
-
|
|
4163
|
-
const _alignVector = new Vector3(0, 1, 0);
|
|
4164
|
-
|
|
4165
|
-
const _zeroVector = new Vector3(0, 0, 0);
|
|
4166
|
-
|
|
4167
|
-
const _lookAtMatrix = new Matrix4;
|
|
4168
|
-
|
|
4169
|
-
const _tempQuaternion2 = new Quaternion;
|
|
4170
|
-
|
|
4171
|
-
const _identityQuaternion = new Quaternion;
|
|
4172
|
-
|
|
4173
|
-
const _dirVector = new Vector3;
|
|
4174
|
-
|
|
4175
|
-
const _tempMatrix = new Matrix4;
|
|
4176
|
-
|
|
4177
|
-
const _unitX = new Vector3(1, 0, 0);
|
|
4178
|
-
|
|
4179
|
-
const _unitY = new Vector3(0, 1, 0);
|
|
4180
|
-
|
|
4181
|
-
const _unitZ = new Vector3(0, 0, 1);
|
|
4182
|
-
|
|
4183
|
-
const _v1 = new Vector3;
|
|
4184
|
-
|
|
4185
|
-
const _v2 = new Vector3;
|
|
4186
|
-
|
|
4187
|
-
const _v3 = new Vector3;
|
|
4188
|
-
|
|
4189
|
-
class TransformControlsGizmo extends Object3D {
|
|
4190
|
-
constructor() {
|
|
4191
|
-
super();
|
|
4192
|
-
this.isTransformControlsGizmo = true;
|
|
4193
|
-
this.type = "TransformControlsGizmo";
|
|
4194
|
-
const gizmoMaterial = new MeshBasicMaterial({
|
|
4195
|
-
depthTest: false,
|
|
4196
|
-
depthWrite: false,
|
|
4197
|
-
fog: false,
|
|
4198
|
-
toneMapped: false,
|
|
4199
|
-
transparent: true
|
|
4200
|
-
});
|
|
4201
|
-
const gizmoLineMaterial = new LineBasicMaterial({
|
|
4202
|
-
depthTest: false,
|
|
4203
|
-
depthWrite: false,
|
|
4204
|
-
fog: false,
|
|
4205
|
-
toneMapped: false,
|
|
4206
|
-
transparent: true
|
|
4207
|
-
});
|
|
4208
|
-
const matInvisible = gizmoMaterial.clone();
|
|
4209
|
-
matInvisible.opacity = .15;
|
|
4210
|
-
const matHelper = gizmoLineMaterial.clone();
|
|
4211
|
-
matHelper.opacity = .5;
|
|
4212
|
-
const matRed = gizmoMaterial.clone();
|
|
4213
|
-
matRed.color.setHex(16711680);
|
|
4214
|
-
const matGreen = gizmoMaterial.clone();
|
|
4215
|
-
matGreen.color.setHex(65280);
|
|
4216
|
-
const matBlue = gizmoMaterial.clone();
|
|
4217
|
-
matBlue.color.setHex(255);
|
|
4218
|
-
const matRedTransparent = gizmoMaterial.clone();
|
|
4219
|
-
matRedTransparent.color.setHex(16711680);
|
|
4220
|
-
matRedTransparent.opacity = .5;
|
|
4221
|
-
const matGreenTransparent = gizmoMaterial.clone();
|
|
4222
|
-
matGreenTransparent.color.setHex(65280);
|
|
4223
|
-
matGreenTransparent.opacity = .5;
|
|
4224
|
-
const matBlueTransparent = gizmoMaterial.clone();
|
|
4225
|
-
matBlueTransparent.color.setHex(255);
|
|
4226
|
-
matBlueTransparent.opacity = .5;
|
|
4227
|
-
const matWhiteTransparent = gizmoMaterial.clone();
|
|
4228
|
-
matWhiteTransparent.opacity = .25;
|
|
4229
|
-
const matYellowTransparent = gizmoMaterial.clone();
|
|
4230
|
-
matYellowTransparent.color.setHex(16776960);
|
|
4231
|
-
matYellowTransparent.opacity = .25;
|
|
4232
|
-
const matYellow = gizmoMaterial.clone();
|
|
4233
|
-
matYellow.color.setHex(16776960);
|
|
4234
|
-
const matGray = gizmoMaterial.clone();
|
|
4235
|
-
matGray.color.setHex(7895160);
|
|
4236
|
-
const arrowGeometry = new CylinderGeometry(0, .04, .1, 12);
|
|
4237
|
-
arrowGeometry.translate(0, .05, 0);
|
|
4238
|
-
const scaleHandleGeometry = new BoxGeometry(.08, .08, .08);
|
|
4239
|
-
scaleHandleGeometry.translate(0, .04, 0);
|
|
4240
|
-
const lineGeometry = new BufferGeometry;
|
|
4241
|
-
lineGeometry.setAttribute("position", new Float32BufferAttribute([ 0, 0, 0, 1, 0, 0 ], 3));
|
|
4242
|
-
const lineGeometry2 = new CylinderGeometry(.0075, .0075, .5, 3);
|
|
4243
|
-
lineGeometry2.translate(0, .25, 0);
|
|
4244
|
-
function CircleGeometry(radius, arc) {
|
|
4245
|
-
const geometry = new TorusGeometry(radius, .0075, 3, 64, arc * Math.PI * 2);
|
|
4246
|
-
geometry.rotateY(Math.PI / 2);
|
|
4247
|
-
geometry.rotateX(Math.PI / 2);
|
|
4248
|
-
return geometry;
|
|
4249
|
-
}
|
|
4250
|
-
function TranslateHelperGeometry() {
|
|
4251
|
-
const geometry = new BufferGeometry;
|
|
4252
|
-
geometry.setAttribute("position", new Float32BufferAttribute([ 0, 0, 0, 1, 1, 1 ], 3));
|
|
4253
|
-
return geometry;
|
|
4254
|
-
}
|
|
4255
|
-
const gizmoTranslate = {
|
|
4256
|
-
X: [ [ new Mesh(arrowGeometry, matRed), [ .5, 0, 0 ], [ 0, 0, -Math.PI / 2 ] ], [ new Mesh(arrowGeometry, matRed), [ -.5, 0, 0 ], [ 0, 0, Math.PI / 2 ] ], [ new Mesh(lineGeometry2, matRed), [ 0, 0, 0 ], [ 0, 0, -Math.PI / 2 ] ] ],
|
|
4257
|
-
Y: [ [ new Mesh(arrowGeometry, matGreen), [ 0, .5, 0 ] ], [ new Mesh(arrowGeometry, matGreen), [ 0, -.5, 0 ], [ Math.PI, 0, 0 ] ], [ new Mesh(lineGeometry2, matGreen) ] ],
|
|
4258
|
-
Z: [ [ new Mesh(arrowGeometry, matBlue), [ 0, 0, .5 ], [ Math.PI / 2, 0, 0 ] ], [ new Mesh(arrowGeometry, matBlue), [ 0, 0, -.5 ], [ -Math.PI / 2, 0, 0 ] ], [ new Mesh(lineGeometry2, matBlue), null, [ Math.PI / 2, 0, 0 ] ] ],
|
|
4259
|
-
XYZ: [ [ new Mesh(new OctahedronGeometry(.1, 0), matWhiteTransparent.clone()), [ 0, 0, 0 ] ] ],
|
|
4260
|
-
XY: [ [ new Mesh(new BoxGeometry(.15, .15, .01), matBlueTransparent.clone()), [ .15, .15, 0 ] ] ],
|
|
4261
|
-
YZ: [ [ new Mesh(new BoxGeometry(.15, .15, .01), matRedTransparent.clone()), [ 0, .15, .15 ], [ 0, Math.PI / 2, 0 ] ] ],
|
|
4262
|
-
XZ: [ [ new Mesh(new BoxGeometry(.15, .15, .01), matGreenTransparent.clone()), [ .15, 0, .15 ], [ -Math.PI / 2, 0, 0 ] ] ]
|
|
4263
|
-
};
|
|
4264
|
-
const pickerTranslate = {
|
|
4265
|
-
X: [ [ new Mesh(new CylinderGeometry(.2, 0, .6, 4), matInvisible), [ .3, 0, 0 ], [ 0, 0, -Math.PI / 2 ] ], [ new Mesh(new CylinderGeometry(.2, 0, .6, 4), matInvisible), [ -.3, 0, 0 ], [ 0, 0, Math.PI / 2 ] ] ],
|
|
4266
|
-
Y: [ [ new Mesh(new CylinderGeometry(.2, 0, .6, 4), matInvisible), [ 0, .3, 0 ] ], [ new Mesh(new CylinderGeometry(.2, 0, .6, 4), matInvisible), [ 0, -.3, 0 ], [ 0, 0, Math.PI ] ] ],
|
|
4267
|
-
Z: [ [ new Mesh(new CylinderGeometry(.2, 0, .6, 4), matInvisible), [ 0, 0, .3 ], [ Math.PI / 2, 0, 0 ] ], [ new Mesh(new CylinderGeometry(.2, 0, .6, 4), matInvisible), [ 0, 0, -.3 ], [ -Math.PI / 2, 0, 0 ] ] ],
|
|
4268
|
-
XYZ: [ [ new Mesh(new OctahedronGeometry(.2, 0), matInvisible) ] ],
|
|
4269
|
-
XY: [ [ new Mesh(new BoxGeometry(.2, .2, .01), matInvisible), [ .15, .15, 0 ] ] ],
|
|
4270
|
-
YZ: [ [ new Mesh(new BoxGeometry(.2, .2, .01), matInvisible), [ 0, .15, .15 ], [ 0, Math.PI / 2, 0 ] ] ],
|
|
4271
|
-
XZ: [ [ new Mesh(new BoxGeometry(.2, .2, .01), matInvisible), [ .15, 0, .15 ], [ -Math.PI / 2, 0, 0 ] ] ]
|
|
4272
|
-
};
|
|
4273
|
-
const helperTranslate = {
|
|
4274
|
-
START: [ [ new Mesh(new OctahedronGeometry(.01, 2), matHelper), null, null, null, "helper" ] ],
|
|
4275
|
-
END: [ [ new Mesh(new OctahedronGeometry(.01, 2), matHelper), null, null, null, "helper" ] ],
|
|
4276
|
-
DELTA: [ [ new Line(TranslateHelperGeometry(), matHelper), null, null, null, "helper" ] ],
|
|
4277
|
-
X: [ [ new Line(lineGeometry, matHelper.clone()), [ -1e3, 0, 0 ], null, [ 1e6, 1, 1 ], "helper" ] ],
|
|
4278
|
-
Y: [ [ new Line(lineGeometry, matHelper.clone()), [ 0, -1e3, 0 ], [ 0, 0, Math.PI / 2 ], [ 1e6, 1, 1 ], "helper" ] ],
|
|
4279
|
-
Z: [ [ new Line(lineGeometry, matHelper.clone()), [ 0, 0, -1e3 ], [ 0, -Math.PI / 2, 0 ], [ 1e6, 1, 1 ], "helper" ] ]
|
|
4280
|
-
};
|
|
4281
|
-
const gizmoRotate = {
|
|
4282
|
-
XYZE: [ [ new Mesh(CircleGeometry(.5, 1), matGray), null, [ 0, Math.PI / 2, 0 ] ] ],
|
|
4283
|
-
X: [ [ new Mesh(CircleGeometry(.5, .5), matRed) ] ],
|
|
4284
|
-
Y: [ [ new Mesh(CircleGeometry(.5, .5), matGreen), null, [ 0, 0, -Math.PI / 2 ] ] ],
|
|
4285
|
-
Z: [ [ new Mesh(CircleGeometry(.5, .5), matBlue), null, [ 0, Math.PI / 2, 0 ] ] ],
|
|
4286
|
-
E: [ [ new Mesh(CircleGeometry(.75, 1), matYellowTransparent), null, [ 0, Math.PI / 2, 0 ] ] ]
|
|
4287
|
-
};
|
|
4288
|
-
const helperRotate = {
|
|
4289
|
-
AXIS: [ [ new Line(lineGeometry, matHelper.clone()), [ -1e3, 0, 0 ], null, [ 1e6, 1, 1 ], "helper" ] ]
|
|
4290
|
-
};
|
|
4291
|
-
const pickerRotate = {
|
|
4292
|
-
XYZE: [ [ new Mesh(new SphereGeometry(.25, 10, 8), matInvisible) ] ],
|
|
4293
|
-
X: [ [ new Mesh(new TorusGeometry(.5, .1, 4, 24), matInvisible), [ 0, 0, 0 ], [ 0, -Math.PI / 2, -Math.PI / 2 ] ] ],
|
|
4294
|
-
Y: [ [ new Mesh(new TorusGeometry(.5, .1, 4, 24), matInvisible), [ 0, 0, 0 ], [ Math.PI / 2, 0, 0 ] ] ],
|
|
4295
|
-
Z: [ [ new Mesh(new TorusGeometry(.5, .1, 4, 24), matInvisible), [ 0, 0, 0 ], [ 0, 0, -Math.PI / 2 ] ] ],
|
|
4296
|
-
E: [ [ new Mesh(new TorusGeometry(.75, .1, 2, 24), matInvisible) ] ]
|
|
4297
|
-
};
|
|
4298
|
-
const gizmoScale = {
|
|
4299
|
-
X: [ [ new Mesh(scaleHandleGeometry, matRed), [ .5, 0, 0 ], [ 0, 0, -Math.PI / 2 ] ], [ new Mesh(lineGeometry2, matRed), [ 0, 0, 0 ], [ 0, 0, -Math.PI / 2 ] ], [ new Mesh(scaleHandleGeometry, matRed), [ -.5, 0, 0 ], [ 0, 0, Math.PI / 2 ] ] ],
|
|
4300
|
-
Y: [ [ new Mesh(scaleHandleGeometry, matGreen), [ 0, .5, 0 ] ], [ new Mesh(lineGeometry2, matGreen) ], [ new Mesh(scaleHandleGeometry, matGreen), [ 0, -.5, 0 ], [ 0, 0, Math.PI ] ] ],
|
|
4301
|
-
Z: [ [ new Mesh(scaleHandleGeometry, matBlue), [ 0, 0, .5 ], [ Math.PI / 2, 0, 0 ] ], [ new Mesh(lineGeometry2, matBlue), [ 0, 0, 0 ], [ Math.PI / 2, 0, 0 ] ], [ new Mesh(scaleHandleGeometry, matBlue), [ 0, 0, -.5 ], [ -Math.PI / 2, 0, 0 ] ] ],
|
|
4302
|
-
XY: [ [ new Mesh(new BoxGeometry(.15, .15, .01), matBlueTransparent), [ .15, .15, 0 ] ] ],
|
|
4303
|
-
YZ: [ [ new Mesh(new BoxGeometry(.15, .15, .01), matRedTransparent), [ 0, .15, .15 ], [ 0, Math.PI / 2, 0 ] ] ],
|
|
4304
|
-
XZ: [ [ new Mesh(new BoxGeometry(.15, .15, .01), matGreenTransparent), [ .15, 0, .15 ], [ -Math.PI / 2, 0, 0 ] ] ],
|
|
4305
|
-
XYZ: [ [ new Mesh(new BoxGeometry(.1, .1, .1), matWhiteTransparent.clone()) ] ]
|
|
4306
|
-
};
|
|
4307
|
-
const pickerScale = {
|
|
4308
|
-
X: [ [ new Mesh(new CylinderGeometry(.2, 0, .6, 4), matInvisible), [ .3, 0, 0 ], [ 0, 0, -Math.PI / 2 ] ], [ new Mesh(new CylinderGeometry(.2, 0, .6, 4), matInvisible), [ -.3, 0, 0 ], [ 0, 0, Math.PI / 2 ] ] ],
|
|
4309
|
-
Y: [ [ new Mesh(new CylinderGeometry(.2, 0, .6, 4), matInvisible), [ 0, .3, 0 ] ], [ new Mesh(new CylinderGeometry(.2, 0, .6, 4), matInvisible), [ 0, -.3, 0 ], [ 0, 0, Math.PI ] ] ],
|
|
4310
|
-
Z: [ [ new Mesh(new CylinderGeometry(.2, 0, .6, 4), matInvisible), [ 0, 0, .3 ], [ Math.PI / 2, 0, 0 ] ], [ new Mesh(new CylinderGeometry(.2, 0, .6, 4), matInvisible), [ 0, 0, -.3 ], [ -Math.PI / 2, 0, 0 ] ] ],
|
|
4311
|
-
XY: [ [ new Mesh(new BoxGeometry(.2, .2, .01), matInvisible), [ .15, .15, 0 ] ] ],
|
|
4312
|
-
YZ: [ [ new Mesh(new BoxGeometry(.2, .2, .01), matInvisible), [ 0, .15, .15 ], [ 0, Math.PI / 2, 0 ] ] ],
|
|
4313
|
-
XZ: [ [ new Mesh(new BoxGeometry(.2, .2, .01), matInvisible), [ .15, 0, .15 ], [ -Math.PI / 2, 0, 0 ] ] ],
|
|
4314
|
-
XYZ: [ [ new Mesh(new BoxGeometry(.2, .2, .2), matInvisible), [ 0, 0, 0 ] ] ]
|
|
4315
|
-
};
|
|
4316
|
-
const helperScale = {
|
|
4317
|
-
X: [ [ new Line(lineGeometry, matHelper.clone()), [ -1e3, 0, 0 ], null, [ 1e6, 1, 1 ], "helper" ] ],
|
|
4318
|
-
Y: [ [ new Line(lineGeometry, matHelper.clone()), [ 0, -1e3, 0 ], [ 0, 0, Math.PI / 2 ], [ 1e6, 1, 1 ], "helper" ] ],
|
|
4319
|
-
Z: [ [ new Line(lineGeometry, matHelper.clone()), [ 0, 0, -1e3 ], [ 0, -Math.PI / 2, 0 ], [ 1e6, 1, 1 ], "helper" ] ]
|
|
4320
|
-
};
|
|
4321
|
-
function setupGizmo(gizmoMap) {
|
|
4322
|
-
const gizmo = new Object3D;
|
|
4323
|
-
for (const name in gizmoMap) {
|
|
4324
|
-
for (let i = gizmoMap[name].length; i--; ) {
|
|
4325
|
-
const object = gizmoMap[name][i][0].clone();
|
|
4326
|
-
const position = gizmoMap[name][i][1];
|
|
4327
|
-
const rotation = gizmoMap[name][i][2];
|
|
4328
|
-
const scale = gizmoMap[name][i][3];
|
|
4329
|
-
const tag = gizmoMap[name][i][4];
|
|
4330
|
-
object.name = name;
|
|
4331
|
-
object.tag = tag;
|
|
4332
|
-
if (position) {
|
|
4333
|
-
object.position.set(position[0], position[1], position[2]);
|
|
4334
|
-
}
|
|
4335
|
-
if (rotation) {
|
|
4336
|
-
object.rotation.set(rotation[0], rotation[1], rotation[2]);
|
|
4337
|
-
}
|
|
4338
|
-
if (scale) {
|
|
4339
|
-
object.scale.set(scale[0], scale[1], scale[2]);
|
|
4340
|
-
}
|
|
4341
|
-
object.updateMatrix();
|
|
4342
|
-
const tempGeometry = object.geometry.clone();
|
|
4343
|
-
tempGeometry.applyMatrix4(object.matrix);
|
|
4344
|
-
object.geometry = tempGeometry;
|
|
4345
|
-
object.renderOrder = Infinity;
|
|
4346
|
-
object.position.set(0, 0, 0);
|
|
4347
|
-
object.rotation.set(0, 0, 0);
|
|
4348
|
-
object.scale.set(1, 1, 1);
|
|
4349
|
-
gizmo.add(object);
|
|
4350
|
-
}
|
|
4351
|
-
}
|
|
4352
|
-
return gizmo;
|
|
4353
|
-
}
|
|
4354
|
-
this.gizmo = {};
|
|
4355
|
-
this.picker = {};
|
|
4356
|
-
this.helper = {};
|
|
4357
|
-
this.add(this.gizmo["translate"] = setupGizmo(gizmoTranslate));
|
|
4358
|
-
this.add(this.gizmo["rotate"] = setupGizmo(gizmoRotate));
|
|
4359
|
-
this.add(this.gizmo["scale"] = setupGizmo(gizmoScale));
|
|
4360
|
-
this.add(this.picker["translate"] = setupGizmo(pickerTranslate));
|
|
4361
|
-
this.add(this.picker["rotate"] = setupGizmo(pickerRotate));
|
|
4362
|
-
this.add(this.picker["scale"] = setupGizmo(pickerScale));
|
|
4363
|
-
this.add(this.helper["translate"] = setupGizmo(helperTranslate));
|
|
4364
|
-
this.add(this.helper["rotate"] = setupGizmo(helperRotate));
|
|
4365
|
-
this.add(this.helper["scale"] = setupGizmo(helperScale));
|
|
4366
|
-
this.picker["translate"].visible = false;
|
|
4367
|
-
this.picker["rotate"].visible = false;
|
|
4368
|
-
this.picker["scale"].visible = false;
|
|
4369
|
-
}
|
|
4370
|
-
updateMatrixWorld(force) {
|
|
4371
|
-
const space = this.mode === "scale" ? "local" : this.space;
|
|
4372
|
-
const quaternion = space === "local" ? this.worldQuaternion : _identityQuaternion;
|
|
4373
|
-
this.gizmo["translate"].visible = this.mode === "translate";
|
|
4374
|
-
this.gizmo["rotate"].visible = this.mode === "rotate";
|
|
4375
|
-
this.gizmo["scale"].visible = this.mode === "scale";
|
|
4376
|
-
this.helper["translate"].visible = this.mode === "translate";
|
|
4377
|
-
this.helper["rotate"].visible = this.mode === "rotate";
|
|
4378
|
-
this.helper["scale"].visible = this.mode === "scale";
|
|
4379
|
-
let handles = [];
|
|
4380
|
-
handles = handles.concat(this.picker[this.mode].children);
|
|
4381
|
-
handles = handles.concat(this.gizmo[this.mode].children);
|
|
4382
|
-
handles = handles.concat(this.helper[this.mode].children);
|
|
4383
|
-
for (let i = 0; i < handles.length; i++) {
|
|
4384
|
-
const handle = handles[i];
|
|
4385
|
-
handle.visible = true;
|
|
4386
|
-
handle.rotation.set(0, 0, 0);
|
|
4387
|
-
handle.position.copy(this.worldPosition);
|
|
4388
|
-
let factor;
|
|
4389
|
-
if (this.camera.isOrthographicCamera) {
|
|
4390
|
-
factor = (this.camera.top - this.camera.bottom) / this.camera.zoom;
|
|
4391
|
-
} else {
|
|
4392
|
-
factor = this.worldPosition.distanceTo(this.cameraPosition) * Math.min(1.9 * Math.tan(Math.PI * this.camera.fov / 360) / this.camera.zoom, 7);
|
|
4393
|
-
}
|
|
4394
|
-
handle.scale.set(1, 1, 1).multiplyScalar(factor * this.size / 4);
|
|
4395
|
-
if (handle.tag === "helper") {
|
|
4396
|
-
handle.visible = false;
|
|
4397
|
-
if (handle.name === "AXIS") {
|
|
4398
|
-
handle.visible = !!this.axis;
|
|
4399
|
-
if (this.axis === "X") {
|
|
4400
|
-
_tempQuaternion.setFromEuler(_tempEuler.set(0, 0, 0));
|
|
4401
|
-
handle.quaternion.copy(quaternion).multiply(_tempQuaternion);
|
|
4402
|
-
if (Math.abs(_alignVector.copy(_unitX).applyQuaternion(quaternion).dot(this.eye)) > .9) {
|
|
4403
|
-
handle.visible = false;
|
|
4404
|
-
}
|
|
4405
|
-
}
|
|
4406
|
-
if (this.axis === "Y") {
|
|
4407
|
-
_tempQuaternion.setFromEuler(_tempEuler.set(0, 0, Math.PI / 2));
|
|
4408
|
-
handle.quaternion.copy(quaternion).multiply(_tempQuaternion);
|
|
4409
|
-
if (Math.abs(_alignVector.copy(_unitY).applyQuaternion(quaternion).dot(this.eye)) > .9) {
|
|
4410
|
-
handle.visible = false;
|
|
4411
|
-
}
|
|
4412
|
-
}
|
|
4413
|
-
if (this.axis === "Z") {
|
|
4414
|
-
_tempQuaternion.setFromEuler(_tempEuler.set(0, Math.PI / 2, 0));
|
|
4415
|
-
handle.quaternion.copy(quaternion).multiply(_tempQuaternion);
|
|
4416
|
-
if (Math.abs(_alignVector.copy(_unitZ).applyQuaternion(quaternion).dot(this.eye)) > .9) {
|
|
4417
|
-
handle.visible = false;
|
|
4418
|
-
}
|
|
4419
|
-
}
|
|
4420
|
-
if (this.axis === "XYZE") {
|
|
4421
|
-
_tempQuaternion.setFromEuler(_tempEuler.set(0, Math.PI / 2, 0));
|
|
4422
|
-
_alignVector.copy(this.rotationAxis);
|
|
4423
|
-
handle.quaternion.setFromRotationMatrix(_lookAtMatrix.lookAt(_zeroVector, _alignVector, _unitY));
|
|
4424
|
-
handle.quaternion.multiply(_tempQuaternion);
|
|
4425
|
-
handle.visible = this.dragging;
|
|
4426
|
-
}
|
|
4427
|
-
if (this.axis === "E") {
|
|
4428
|
-
handle.visible = false;
|
|
4429
|
-
}
|
|
4430
|
-
} else if (handle.name === "START") {
|
|
4431
|
-
handle.position.copy(this.worldPositionStart);
|
|
4432
|
-
handle.visible = this.dragging;
|
|
4433
|
-
} else if (handle.name === "END") {
|
|
4434
|
-
handle.position.copy(this.worldPosition);
|
|
4435
|
-
handle.visible = this.dragging;
|
|
4436
|
-
} else if (handle.name === "DELTA") {
|
|
4437
|
-
handle.position.copy(this.worldPositionStart);
|
|
4438
|
-
handle.quaternion.copy(this.worldQuaternionStart);
|
|
4439
|
-
_tempVector.set(1e-10, 1e-10, 1e-10).add(this.worldPositionStart).sub(this.worldPosition).multiplyScalar(-1);
|
|
4440
|
-
_tempVector.applyQuaternion(this.worldQuaternionStart.clone().invert());
|
|
4441
|
-
handle.scale.copy(_tempVector);
|
|
4442
|
-
handle.visible = this.dragging;
|
|
4443
|
-
} else {
|
|
4444
|
-
handle.quaternion.copy(quaternion);
|
|
4445
|
-
if (this.dragging) {
|
|
4446
|
-
handle.position.copy(this.worldPositionStart);
|
|
4447
|
-
} else {
|
|
4448
|
-
handle.position.copy(this.worldPosition);
|
|
4449
|
-
}
|
|
4450
|
-
if (this.axis) {
|
|
4451
|
-
handle.visible = this.axis.search(handle.name) !== -1;
|
|
4452
|
-
}
|
|
4453
|
-
}
|
|
4454
|
-
continue;
|
|
4455
|
-
}
|
|
4456
|
-
handle.quaternion.copy(quaternion);
|
|
4457
|
-
if (this.mode === "translate" || this.mode === "scale") {
|
|
4458
|
-
const AXIS_HIDE_THRESHOLD = .99;
|
|
4459
|
-
const PLANE_HIDE_THRESHOLD = .2;
|
|
4460
|
-
if (handle.name === "X") {
|
|
4461
|
-
if (Math.abs(_alignVector.copy(_unitX).applyQuaternion(quaternion).dot(this.eye)) > AXIS_HIDE_THRESHOLD) {
|
|
4462
|
-
handle.scale.set(1e-10, 1e-10, 1e-10);
|
|
4463
|
-
handle.visible = false;
|
|
4464
|
-
}
|
|
4465
|
-
}
|
|
4466
|
-
if (handle.name === "Y") {
|
|
4467
|
-
if (Math.abs(_alignVector.copy(_unitY).applyQuaternion(quaternion).dot(this.eye)) > AXIS_HIDE_THRESHOLD) {
|
|
4468
|
-
handle.scale.set(1e-10, 1e-10, 1e-10);
|
|
4469
|
-
handle.visible = false;
|
|
4470
|
-
}
|
|
4471
|
-
}
|
|
4472
|
-
if (handle.name === "Z") {
|
|
4473
|
-
if (Math.abs(_alignVector.copy(_unitZ).applyQuaternion(quaternion).dot(this.eye)) > AXIS_HIDE_THRESHOLD) {
|
|
4474
|
-
handle.scale.set(1e-10, 1e-10, 1e-10);
|
|
4475
|
-
handle.visible = false;
|
|
4476
|
-
}
|
|
4477
|
-
}
|
|
4478
|
-
if (handle.name === "XY") {
|
|
4479
|
-
if (Math.abs(_alignVector.copy(_unitZ).applyQuaternion(quaternion).dot(this.eye)) < PLANE_HIDE_THRESHOLD) {
|
|
4480
|
-
handle.scale.set(1e-10, 1e-10, 1e-10);
|
|
4481
|
-
handle.visible = false;
|
|
4482
|
-
}
|
|
4483
|
-
}
|
|
4484
|
-
if (handle.name === "YZ") {
|
|
4485
|
-
if (Math.abs(_alignVector.copy(_unitX).applyQuaternion(quaternion).dot(this.eye)) < PLANE_HIDE_THRESHOLD) {
|
|
4486
|
-
handle.scale.set(1e-10, 1e-10, 1e-10);
|
|
4487
|
-
handle.visible = false;
|
|
4488
|
-
}
|
|
4489
|
-
}
|
|
4490
|
-
if (handle.name === "XZ") {
|
|
4491
|
-
if (Math.abs(_alignVector.copy(_unitY).applyQuaternion(quaternion).dot(this.eye)) < PLANE_HIDE_THRESHOLD) {
|
|
4492
|
-
handle.scale.set(1e-10, 1e-10, 1e-10);
|
|
4493
|
-
handle.visible = false;
|
|
4494
|
-
}
|
|
4495
|
-
}
|
|
4496
|
-
} else if (this.mode === "rotate") {
|
|
4497
|
-
_tempQuaternion2.copy(quaternion);
|
|
4498
|
-
_alignVector.copy(this.eye).applyQuaternion(_tempQuaternion.copy(quaternion).invert());
|
|
4499
|
-
if (handle.name.search("E") !== -1) {
|
|
4500
|
-
handle.quaternion.setFromRotationMatrix(_lookAtMatrix.lookAt(this.eye, _zeroVector, _unitY));
|
|
4501
|
-
}
|
|
4502
|
-
if (handle.name === "X") {
|
|
4503
|
-
_tempQuaternion.setFromAxisAngle(_unitX, Math.atan2(-_alignVector.y, _alignVector.z));
|
|
4504
|
-
_tempQuaternion.multiplyQuaternions(_tempQuaternion2, _tempQuaternion);
|
|
4505
|
-
handle.quaternion.copy(_tempQuaternion);
|
|
4506
|
-
}
|
|
4507
|
-
if (handle.name === "Y") {
|
|
4508
|
-
_tempQuaternion.setFromAxisAngle(_unitY, Math.atan2(_alignVector.x, _alignVector.z));
|
|
4509
|
-
_tempQuaternion.multiplyQuaternions(_tempQuaternion2, _tempQuaternion);
|
|
4510
|
-
handle.quaternion.copy(_tempQuaternion);
|
|
4511
|
-
}
|
|
4512
|
-
if (handle.name === "Z") {
|
|
4513
|
-
_tempQuaternion.setFromAxisAngle(_unitZ, Math.atan2(_alignVector.y, _alignVector.x));
|
|
4514
|
-
_tempQuaternion.multiplyQuaternions(_tempQuaternion2, _tempQuaternion);
|
|
4515
|
-
handle.quaternion.copy(_tempQuaternion);
|
|
4516
|
-
}
|
|
4517
|
-
}
|
|
4518
|
-
handle.visible = handle.visible && (handle.name.indexOf("X") === -1 || this.showX);
|
|
4519
|
-
handle.visible = handle.visible && (handle.name.indexOf("Y") === -1 || this.showY);
|
|
4520
|
-
handle.visible = handle.visible && (handle.name.indexOf("Z") === -1 || this.showZ);
|
|
4521
|
-
handle.visible = handle.visible && (handle.name.indexOf("E") === -1 || this.showX && this.showY && this.showZ);
|
|
4522
|
-
handle.material._color = handle.material._color || handle.material.color.clone();
|
|
4523
|
-
handle.material._opacity = handle.material._opacity || handle.material.opacity;
|
|
4524
|
-
handle.material.color.copy(handle.material._color);
|
|
4525
|
-
handle.material.opacity = handle.material._opacity;
|
|
4526
|
-
if (this.enabled && this.axis) {
|
|
4527
|
-
if (handle.name === this.axis) {
|
|
4528
|
-
handle.material.color.setHex(16776960);
|
|
4529
|
-
handle.material.opacity = 1;
|
|
4530
|
-
} else if (this.axis.split("").some((function(a) {
|
|
4531
|
-
return handle.name === a;
|
|
4532
|
-
}))) {
|
|
4533
|
-
handle.material.color.setHex(16776960);
|
|
4534
|
-
handle.material.opacity = 1;
|
|
4535
|
-
}
|
|
4536
|
-
}
|
|
4537
|
-
}
|
|
4538
|
-
super.updateMatrixWorld(force);
|
|
4539
|
-
}
|
|
4540
|
-
}
|
|
4541
|
-
|
|
4542
|
-
class TransformControlsPlane extends Mesh {
|
|
4543
|
-
constructor() {
|
|
4544
|
-
super(new PlaneGeometry(1e5, 1e5, 2, 2), new MeshBasicMaterial({
|
|
4545
|
-
visible: false,
|
|
4546
|
-
wireframe: true,
|
|
4547
|
-
side: DoubleSide,
|
|
4548
|
-
transparent: true,
|
|
4549
|
-
opacity: .1,
|
|
4550
|
-
toneMapped: false
|
|
4551
|
-
}));
|
|
4552
|
-
this.isTransformControlsPlane = true;
|
|
4553
|
-
this.type = "TransformControlsPlane";
|
|
4554
|
-
}
|
|
4555
|
-
updateMatrixWorld(force) {
|
|
4556
|
-
let space = this.space;
|
|
4557
|
-
this.position.copy(this.worldPosition);
|
|
4558
|
-
if (this.mode === "scale") space = "local";
|
|
4559
|
-
_v1.copy(_unitX).applyQuaternion(space === "local" ? this.worldQuaternion : _identityQuaternion);
|
|
4560
|
-
_v2.copy(_unitY).applyQuaternion(space === "local" ? this.worldQuaternion : _identityQuaternion);
|
|
4561
|
-
_v3.copy(_unitZ).applyQuaternion(space === "local" ? this.worldQuaternion : _identityQuaternion);
|
|
4562
|
-
_alignVector.copy(_v2);
|
|
4563
|
-
switch (this.mode) {
|
|
4564
|
-
case "translate":
|
|
4565
|
-
case "scale":
|
|
4566
|
-
switch (this.axis) {
|
|
4567
|
-
case "X":
|
|
4568
|
-
_alignVector.copy(this.eye).cross(_v1);
|
|
4569
|
-
_dirVector.copy(_v1).cross(_alignVector);
|
|
4570
|
-
break;
|
|
4571
|
-
|
|
4572
|
-
case "Y":
|
|
4573
|
-
_alignVector.copy(this.eye).cross(_v2);
|
|
4574
|
-
_dirVector.copy(_v2).cross(_alignVector);
|
|
4575
|
-
break;
|
|
4576
|
-
|
|
4577
|
-
case "Z":
|
|
4578
|
-
_alignVector.copy(this.eye).cross(_v3);
|
|
4579
|
-
_dirVector.copy(_v3).cross(_alignVector);
|
|
4580
|
-
break;
|
|
4581
|
-
|
|
4582
|
-
case "XY":
|
|
4583
|
-
_dirVector.copy(_v3);
|
|
4584
|
-
break;
|
|
4585
|
-
|
|
4586
|
-
case "YZ":
|
|
4587
|
-
_dirVector.copy(_v1);
|
|
4588
|
-
break;
|
|
4589
|
-
|
|
4590
|
-
case "XZ":
|
|
4591
|
-
_alignVector.copy(_v3);
|
|
4592
|
-
_dirVector.copy(_v2);
|
|
4593
|
-
break;
|
|
4594
|
-
|
|
4595
|
-
case "XYZ":
|
|
4596
|
-
case "E":
|
|
4597
|
-
_dirVector.set(0, 0, 0);
|
|
4598
|
-
break;
|
|
4599
|
-
}
|
|
4600
|
-
break;
|
|
4601
|
-
|
|
4602
|
-
case "rotate":
|
|
4603
|
-
default:
|
|
4604
|
-
_dirVector.set(0, 0, 0);
|
|
4605
|
-
}
|
|
4606
|
-
if (_dirVector.length() === 0) {
|
|
4607
|
-
this.quaternion.copy(this.cameraQuaternion);
|
|
4608
|
-
} else {
|
|
4609
|
-
_tempMatrix.lookAt(_tempVector.set(0, 0, 0), _dirVector, _alignVector);
|
|
4610
|
-
this.quaternion.setFromRotationMatrix(_tempMatrix);
|
|
4611
|
-
}
|
|
4612
|
-
super.updateMatrixWorld(force);
|
|
4613
|
-
}
|
|
4614
|
-
}
|
|
4615
|
-
|
|
4616
3723
|
class PlaneHelper extends Line {
|
|
4617
3724
|
constructor(plane, size = 1, color = 16776960, offset = new Vector3) {
|
|
4618
3725
|
const positions = [ 1, 1, 0, -1, 1, 0, -1, -1, 0, 1, -1, 0, 1, 1, 0 ];
|
|
@@ -4694,7 +3801,7 @@ class CuttingPlaneDragger extends OrbitDragger {
|
|
|
4694
3801
|
this.transform.attach(this.planeCenter);
|
|
4695
3802
|
this.transform.addEventListener("change", this.transformChange);
|
|
4696
3803
|
this.transform.addEventListener("dragging-changed", this.transformDrag);
|
|
4697
|
-
this.viewer.helpers.add(this.transform);
|
|
3804
|
+
this.viewer.helpers.add(this.transform.getHelper());
|
|
4698
3805
|
this.viewer.on("explode", this.viewerExplode);
|
|
4699
3806
|
this.viewer.canvas.addEventListener("dblclick", this.onDoubleClick, true);
|
|
4700
3807
|
this.viewer.update();
|
|
@@ -4704,7 +3811,8 @@ class CuttingPlaneDragger extends OrbitDragger {
|
|
|
4704
3811
|
this.viewer.canvas.removeEventListener("dblclick", this.onDoubleClick, true);
|
|
4705
3812
|
this.transform.removeEventListener("change", this.transformChange);
|
|
4706
3813
|
this.transform.removeEventListener("dragging-changed", this.transformDrag);
|
|
4707
|
-
this.transform.removeFromParent();
|
|
3814
|
+
this.transform.getHelper().removeFromParent();
|
|
3815
|
+
this.transform.detach();
|
|
4708
3816
|
this.transform.dispose();
|
|
4709
3817
|
this.planeHelper.removeFromParent();
|
|
4710
3818
|
this.planeHelper.dispose();
|
|
@@ -4731,13 +3839,362 @@ class CuttingPlaneZAxisDragger extends CuttingPlaneDragger {
|
|
|
4731
3839
|
}
|
|
4732
3840
|
}
|
|
4733
3841
|
|
|
3842
|
+
const PRECISION = .01;
|
|
3843
|
+
|
|
3844
|
+
class MeasureLineDragger extends OrbitDragger {
|
|
3845
|
+
constructor(viewer) {
|
|
3846
|
+
super(viewer);
|
|
3847
|
+
this.onPointerDown = event => {
|
|
3848
|
+
if (event.button !== 0) return;
|
|
3849
|
+
this.line.startPoint = this.snapper.getSnapPoint(event);
|
|
3850
|
+
this.line.render();
|
|
3851
|
+
this.viewer.canvas.setPointerCapture(event.pointerId);
|
|
3852
|
+
this.orbit.enabled = !this.line.startPoint;
|
|
3853
|
+
};
|
|
3854
|
+
this.onPointerMove = event => {
|
|
3855
|
+
if (this.orbit.enabled && this.orbit.state !== -1) return;
|
|
3856
|
+
this.line.endPoint = this.snapper.getSnapPoint(event);
|
|
3857
|
+
this.line.render();
|
|
3858
|
+
if (this.line.startPoint) this.changed = true;
|
|
3859
|
+
};
|
|
3860
|
+
this.onPointerUp = event => {
|
|
3861
|
+
if (this.line.startPoint && this.line.endPoint && this.line.getDistance() >= PRECISION) {
|
|
3862
|
+
this.line = new MeasureLine(this.overlay);
|
|
3863
|
+
this.overlay.addLine(this.line);
|
|
3864
|
+
} else {
|
|
3865
|
+
this.line.startPoint = undefined;
|
|
3866
|
+
this.line.endPoint = undefined;
|
|
3867
|
+
this.line.render();
|
|
3868
|
+
}
|
|
3869
|
+
this.viewer.canvas.releasePointerCapture(event.pointerId);
|
|
3870
|
+
this.orbit.enabled = true;
|
|
3871
|
+
};
|
|
3872
|
+
this.onPointerCancel = event => {
|
|
3873
|
+
this.viewer.canvas.dispatchEvent(new PointerEvent("pointerup", event));
|
|
3874
|
+
};
|
|
3875
|
+
this.onPointerLeave = () => {
|
|
3876
|
+
this.line.endPoint = undefined;
|
|
3877
|
+
this.line.render();
|
|
3878
|
+
};
|
|
3879
|
+
this.renderOverlay = () => {
|
|
3880
|
+
this.overlay.render();
|
|
3881
|
+
};
|
|
3882
|
+
this.updateSnapper = () => {
|
|
3883
|
+
this.snapper.update(this.viewer.scene);
|
|
3884
|
+
};
|
|
3885
|
+
this.overlay = new MeasureOverlay(viewer.camera, viewer.canvas);
|
|
3886
|
+
this.overlay.attach();
|
|
3887
|
+
this.line = new MeasureLine(this.overlay);
|
|
3888
|
+
this.overlay.addLine(this.line);
|
|
3889
|
+
this.snapper = new MeasureSnapper(viewer.camera, viewer.canvas);
|
|
3890
|
+
this.snapper.update(viewer.scene);
|
|
3891
|
+
this.viewer.canvas.addEventListener("pointerdown", this.onPointerDown);
|
|
3892
|
+
this.viewer.canvas.addEventListener("pointermove", this.onPointerMove);
|
|
3893
|
+
this.viewer.canvas.addEventListener("pointerup", this.onPointerUp);
|
|
3894
|
+
this.viewer.canvas.addEventListener("pointercancel", this.onPointerCancel);
|
|
3895
|
+
this.viewer.canvas.addEventListener("pointerleave", this.onPointerLeave);
|
|
3896
|
+
this.viewer.addEventListener("render", this.renderOverlay);
|
|
3897
|
+
this.viewer.addEventListener("hide", this.updateSnapper);
|
|
3898
|
+
this.viewer.addEventListener("isolate", this.updateSnapper);
|
|
3899
|
+
this.viewer.addEventListener("showall", this.updateSnapper);
|
|
3900
|
+
}
|
|
3901
|
+
dispose() {
|
|
3902
|
+
this.viewer.canvas.removeEventListener("pointerdown", this.onPointerDown);
|
|
3903
|
+
this.viewer.canvas.removeEventListener("pointermove", this.onPointerMove);
|
|
3904
|
+
this.viewer.canvas.removeEventListener("pointerup", this.onPointerUp);
|
|
3905
|
+
this.viewer.canvas.removeEventListener("pointercancel", this.onPointerCancel);
|
|
3906
|
+
this.viewer.canvas.removeEventListener("pointerleave", this.onPointerLeave);
|
|
3907
|
+
this.viewer.removeEventListener("render", this.renderOverlay);
|
|
3908
|
+
this.viewer.removeEventListener("hide", this.updateSnapper);
|
|
3909
|
+
this.viewer.removeEventListener("isolate", this.updateSnapper);
|
|
3910
|
+
this.viewer.removeEventListener("showall", this.updateSnapper);
|
|
3911
|
+
this.overlay.detach();
|
|
3912
|
+
this.overlay.dispose();
|
|
3913
|
+
super.dispose();
|
|
3914
|
+
}
|
|
3915
|
+
}
|
|
3916
|
+
|
|
3917
|
+
class MeasureSnapper {
|
|
3918
|
+
constructor(camera, canvas) {
|
|
3919
|
+
this.objects = [];
|
|
3920
|
+
this.camera = camera;
|
|
3921
|
+
this.canvas = canvas;
|
|
3922
|
+
this.raycaster = new Raycaster;
|
|
3923
|
+
}
|
|
3924
|
+
getSnapPoint(event) {
|
|
3925
|
+
const mouse = new Vector2(event.clientX, event.clientY);
|
|
3926
|
+
const rect = this.canvas.getBoundingClientRect();
|
|
3927
|
+
const x = (mouse.x - rect.left) / rect.width * 2 - 1;
|
|
3928
|
+
const y = -(mouse.y - rect.top) / rect.height * 2 + 1;
|
|
3929
|
+
const coords = new Vector2(x, y);
|
|
3930
|
+
this.raycaster.setFromCamera(coords, this.camera);
|
|
3931
|
+
this.raycaster.params = {
|
|
3932
|
+
Mesh: {},
|
|
3933
|
+
Line: {
|
|
3934
|
+
threshold: .25
|
|
3935
|
+
},
|
|
3936
|
+
Line2: {
|
|
3937
|
+
threshold: .25
|
|
3938
|
+
},
|
|
3939
|
+
LOD: {},
|
|
3940
|
+
Points: {
|
|
3941
|
+
threshold: .1
|
|
3942
|
+
},
|
|
3943
|
+
Sprite: {}
|
|
3944
|
+
};
|
|
3945
|
+
const intersects = this.raycaster.intersectObjects(this.objects, false);
|
|
3946
|
+
if (intersects.length === 0) return undefined;
|
|
3947
|
+
return intersects[0].point;
|
|
3948
|
+
}
|
|
3949
|
+
update(scene) {
|
|
3950
|
+
this.objects = [];
|
|
3951
|
+
scene.traverseVisible((child => this.objects.push(child)));
|
|
3952
|
+
}
|
|
3953
|
+
}
|
|
3954
|
+
|
|
3955
|
+
class MeasureOverlay {
|
|
3956
|
+
constructor(camera, canvas) {
|
|
3957
|
+
this.lines = [];
|
|
3958
|
+
this.camera = camera;
|
|
3959
|
+
this.canvas = canvas;
|
|
3960
|
+
this.projector = new MeasureProjector(camera, canvas);
|
|
3961
|
+
}
|
|
3962
|
+
attach() {
|
|
3963
|
+
this.container = document.createElement("div");
|
|
3964
|
+
this.container.id = "measure-container";
|
|
3965
|
+
this.container.style.background = "rgba(0,0,0,0)";
|
|
3966
|
+
this.container.style.position = "absolute";
|
|
3967
|
+
this.container.style.top = "0px";
|
|
3968
|
+
this.container.style.left = "0px";
|
|
3969
|
+
this.container.style.width = "100%";
|
|
3970
|
+
this.container.style.height = "100%";
|
|
3971
|
+
this.container.style.outline = "none";
|
|
3972
|
+
this.container.style.pointerEvents = "none";
|
|
3973
|
+
this.container.style.overflow = "hidden";
|
|
3974
|
+
this.canvas.parentElement.appendChild(this.container);
|
|
3975
|
+
}
|
|
3976
|
+
dispose() {
|
|
3977
|
+
this.clear();
|
|
3978
|
+
}
|
|
3979
|
+
detach() {
|
|
3980
|
+
this.container.remove();
|
|
3981
|
+
this.container = undefined;
|
|
3982
|
+
}
|
|
3983
|
+
clear() {
|
|
3984
|
+
this.lines.forEach((line => line.dispose()));
|
|
3985
|
+
this.lines = [];
|
|
3986
|
+
}
|
|
3987
|
+
render() {
|
|
3988
|
+
this.projector.updateProjectionMatrix();
|
|
3989
|
+
this.lines.forEach((line => line.render()));
|
|
3990
|
+
}
|
|
3991
|
+
update() {
|
|
3992
|
+
this.lines.forEach((line => line.update()));
|
|
3993
|
+
}
|
|
3994
|
+
addLine(line) {
|
|
3995
|
+
this.lines.push(line);
|
|
3996
|
+
}
|
|
3997
|
+
removeLine(line) {
|
|
3998
|
+
this.lines = this.lines.filter((x => x !== line));
|
|
3999
|
+
}
|
|
4000
|
+
}
|
|
4001
|
+
|
|
4002
|
+
const _middlePoint = new Vector3;
|
|
4003
|
+
|
|
4004
|
+
class MeasureLine {
|
|
4005
|
+
constructor(overlay) {
|
|
4006
|
+
this.id = Date.now();
|
|
4007
|
+
this.unit = "";
|
|
4008
|
+
this.scale = 1;
|
|
4009
|
+
this.size = 10;
|
|
4010
|
+
this.lineWidth = 2;
|
|
4011
|
+
this.style = {
|
|
4012
|
+
border: "2px solid #FFFFFF",
|
|
4013
|
+
background: "#009bff",
|
|
4014
|
+
boxShadow: "0 0 10px rgba(0,0,0,0.5)",
|
|
4015
|
+
color: "white",
|
|
4016
|
+
font: "1rem system-ui"
|
|
4017
|
+
};
|
|
4018
|
+
this.overlay = overlay;
|
|
4019
|
+
this.elementStartPoint = overlay.container.appendChild(document.createElement("div"));
|
|
4020
|
+
this.elementEndPoint = overlay.container.appendChild(document.createElement("div"));
|
|
4021
|
+
this.elementLine = overlay.container.appendChild(document.createElement("div"));
|
|
4022
|
+
this.elementLabel = overlay.container.appendChild(document.createElement("div"));
|
|
4023
|
+
this.update();
|
|
4024
|
+
}
|
|
4025
|
+
dispose() {
|
|
4026
|
+
this.elementStartPoint.remove();
|
|
4027
|
+
this.elementEndPoint.remove();
|
|
4028
|
+
this.elementLine.remove();
|
|
4029
|
+
this.elementLabel.remove();
|
|
4030
|
+
}
|
|
4031
|
+
render() {
|
|
4032
|
+
const projector = this.overlay.projector;
|
|
4033
|
+
if (this.startPoint) {
|
|
4034
|
+
const {point: point, visible: visible} = projector.projectPoint(this.startPoint);
|
|
4035
|
+
this.elementStartPoint.style.display = visible ? "block" : "none";
|
|
4036
|
+
this.elementStartPoint.style.left = `${point.x}px`;
|
|
4037
|
+
this.elementStartPoint.style.top = `${point.y}px`;
|
|
4038
|
+
} else {
|
|
4039
|
+
this.elementStartPoint.style.display = "none";
|
|
4040
|
+
}
|
|
4041
|
+
if (this.endPoint) {
|
|
4042
|
+
const {point: point, visible: visible} = projector.projectPoint(this.endPoint);
|
|
4043
|
+
this.elementEndPoint.style.display = visible ? "block" : "none";
|
|
4044
|
+
this.elementEndPoint.style.left = `${point.x}px`;
|
|
4045
|
+
this.elementEndPoint.style.top = `${point.y}px`;
|
|
4046
|
+
} else {
|
|
4047
|
+
this.elementEndPoint.style.display = "none";
|
|
4048
|
+
}
|
|
4049
|
+
if (this.startPoint && this.endPoint) {
|
|
4050
|
+
const {point1: point1, point2: point2, visible: visible} = projector.projectLine(this.startPoint, this.endPoint);
|
|
4051
|
+
point2.sub(point1);
|
|
4052
|
+
const angle = point2.angle();
|
|
4053
|
+
const width = point2.length();
|
|
4054
|
+
this.elementLine.style.display = visible ? "block" : "none";
|
|
4055
|
+
this.elementLine.style.left = `${point1.x}px`;
|
|
4056
|
+
this.elementLine.style.top = `${point1.y}px`;
|
|
4057
|
+
this.elementLine.style.width = `${width}px`;
|
|
4058
|
+
this.elementLine.style.transform = `translate(0px, ${-this.lineWidth / 2}px) rotate(${angle}rad)`;
|
|
4059
|
+
} else {
|
|
4060
|
+
this.elementLine.style.display = "none";
|
|
4061
|
+
}
|
|
4062
|
+
if (this.startPoint && this.endPoint) {
|
|
4063
|
+
_middlePoint.lerpVectors(this.startPoint, this.endPoint, .5);
|
|
4064
|
+
const {point: point, visible: visible} = projector.projectPoint(_middlePoint);
|
|
4065
|
+
const distance = this.getDistance();
|
|
4066
|
+
this.elementLabel.style.display = visible && distance >= PRECISION ? "block" : "none";
|
|
4067
|
+
this.elementLabel.style.left = `${point.x}px`;
|
|
4068
|
+
this.elementLabel.style.top = `${point.y}px`;
|
|
4069
|
+
this.elementLabel.innerHTML = `${distance.toFixed(2)} ${this.unit}`;
|
|
4070
|
+
} else {
|
|
4071
|
+
this.elementLabel.style.display = "none";
|
|
4072
|
+
}
|
|
4073
|
+
}
|
|
4074
|
+
update() {
|
|
4075
|
+
this.elementStartPoint.id = `markup-dot-start-${this.id}`;
|
|
4076
|
+
this.elementStartPoint.style.position = "absolute";
|
|
4077
|
+
this.elementStartPoint.style.zIndex = "2";
|
|
4078
|
+
this.elementStartPoint.style.width = `${this.size}px`;
|
|
4079
|
+
this.elementStartPoint.style.height = `${this.size}px`;
|
|
4080
|
+
this.elementStartPoint.style.border = this.style.border;
|
|
4081
|
+
this.elementStartPoint.style.borderRadius = `${this.size}px`;
|
|
4082
|
+
this.elementStartPoint.style.background = this.style.background;
|
|
4083
|
+
this.elementStartPoint.style.boxShadow = this.style.boxShadow;
|
|
4084
|
+
this.elementStartPoint.style.transform = "translate(-50%, -50%)";
|
|
4085
|
+
this.elementEndPoint.id = `markup-dot-end-${this.id}`;
|
|
4086
|
+
this.elementEndPoint.style.position = "absolute";
|
|
4087
|
+
this.elementEndPoint.style.zIndex = "2";
|
|
4088
|
+
this.elementEndPoint.style.width = `${this.size}px`;
|
|
4089
|
+
this.elementEndPoint.style.height = `${this.size}px`;
|
|
4090
|
+
this.elementEndPoint.style.border = this.style.border;
|
|
4091
|
+
this.elementEndPoint.style.borderRadius = `${this.size}px`;
|
|
4092
|
+
this.elementEndPoint.style.background = this.style.background;
|
|
4093
|
+
this.elementEndPoint.style.boxShadow = this.style.boxShadow;
|
|
4094
|
+
this.elementEndPoint.style.transform = "translate(-50%, -50%)";
|
|
4095
|
+
this.elementLine.id = `markup-line-${this.id}`;
|
|
4096
|
+
this.elementLine.style.position = "absolute";
|
|
4097
|
+
this.elementLine.style.zIndex = "1";
|
|
4098
|
+
this.elementLine.style.height = `${this.lineWidth}px`;
|
|
4099
|
+
this.elementLine.style.background = this.style.background;
|
|
4100
|
+
this.elementLine.style.boxShadow = this.style.boxShadow;
|
|
4101
|
+
this.elementLine.style.transformOrigin = `0px ${this.lineWidth / 2}px`;
|
|
4102
|
+
this.elementLabel.id = `markup-label-${this.id}`;
|
|
4103
|
+
this.elementLabel.style.position = "absolute";
|
|
4104
|
+
this.elementLabel.style.zIndex = "3";
|
|
4105
|
+
this.elementLabel.style.padding = "2px";
|
|
4106
|
+
this.elementLabel.style.paddingInline = "5px";
|
|
4107
|
+
this.elementLabel.style.borderRadius = "5px";
|
|
4108
|
+
this.elementLabel.style.background = this.style.background;
|
|
4109
|
+
this.elementLabel.style.boxShadow = this.style.boxShadow;
|
|
4110
|
+
this.elementLabel.style.color = this.style.color;
|
|
4111
|
+
this.elementLabel.style.font = this.style.font;
|
|
4112
|
+
this.elementLabel.style.transform = "translate(-50%, -50%)";
|
|
4113
|
+
}
|
|
4114
|
+
getDistance() {
|
|
4115
|
+
return this.startPoint.distanceTo(this.endPoint) / this.scale;
|
|
4116
|
+
}
|
|
4117
|
+
}
|
|
4118
|
+
|
|
4119
|
+
let _widthHalf;
|
|
4120
|
+
|
|
4121
|
+
let _heightHalf;
|
|
4122
|
+
|
|
4123
|
+
const _viewMatrix = new Matrix4;
|
|
4124
|
+
|
|
4125
|
+
const _viewProjectionMatrix = new Matrix4;
|
|
4126
|
+
|
|
4127
|
+
const _vector = new Vector3;
|
|
4128
|
+
|
|
4129
|
+
const _vector1 = new Vector4;
|
|
4130
|
+
|
|
4131
|
+
const _vector2 = new Vector4;
|
|
4132
|
+
|
|
4133
|
+
const point = new Vector2;
|
|
4134
|
+
|
|
4135
|
+
const point1 = new Vector2;
|
|
4136
|
+
|
|
4137
|
+
const point2 = new Vector2;
|
|
4138
|
+
|
|
4139
|
+
class MeasureProjector {
|
|
4140
|
+
constructor(camera, canvas) {
|
|
4141
|
+
this.camera = camera;
|
|
4142
|
+
this.canvas = canvas;
|
|
4143
|
+
}
|
|
4144
|
+
updateProjectionMatrix() {
|
|
4145
|
+
const rect = this.canvas.getBoundingClientRect();
|
|
4146
|
+
_widthHalf = rect.width / 2;
|
|
4147
|
+
_heightHalf = rect.height / 2;
|
|
4148
|
+
_viewMatrix.copy(this.camera.matrixWorldInverse);
|
|
4149
|
+
_viewProjectionMatrix.multiplyMatrices(this.camera.projectionMatrix, _viewMatrix);
|
|
4150
|
+
}
|
|
4151
|
+
projectPoint(p) {
|
|
4152
|
+
_vector.copy(p).applyMatrix4(_viewProjectionMatrix);
|
|
4153
|
+
const visible = _vector.z >= -1 && _vector.z <= 1;
|
|
4154
|
+
point.x = (_vector.x + 1) * _widthHalf;
|
|
4155
|
+
point.y = (-_vector.y + 1) * _heightHalf;
|
|
4156
|
+
return {
|
|
4157
|
+
point: point,
|
|
4158
|
+
visible: visible
|
|
4159
|
+
};
|
|
4160
|
+
}
|
|
4161
|
+
projectLine(p1, p2) {
|
|
4162
|
+
let visible;
|
|
4163
|
+
_vector1.copy(p1).applyMatrix4(_viewProjectionMatrix);
|
|
4164
|
+
_vector2.copy(p2).applyMatrix4(_viewProjectionMatrix);
|
|
4165
|
+
const bc1near = _vector1.z + _vector1.w;
|
|
4166
|
+
const bc2near = _vector2.z + _vector2.w;
|
|
4167
|
+
const bc1far = -_vector1.z + _vector1.w;
|
|
4168
|
+
const bc2far = -_vector2.z + _vector2.w;
|
|
4169
|
+
if (bc1near >= 0 && bc2near >= 0 && bc1far >= 0 && bc2far >= 0) visible = true; else if (bc1near < 0 && bc2near < 0 || bc1far < 0 && bc2far < 0) visible = false; else {
|
|
4170
|
+
let alpha1 = 0;
|
|
4171
|
+
let alpha2 = 1;
|
|
4172
|
+
if (bc1near < 0) alpha1 = Math.max(alpha1, bc1near / (bc1near - bc2near)); else if (bc2near < 0) alpha2 = Math.min(alpha2, bc1near / (bc1near - bc2near));
|
|
4173
|
+
if (bc1far < 0) alpha1 = Math.max(alpha1, bc1far / (bc1far - bc2far)); else if (bc2far < 0) alpha2 = Math.min(alpha2, bc1far / (bc1far - bc2far));
|
|
4174
|
+
visible = alpha2 >= alpha1;
|
|
4175
|
+
if (visible) {
|
|
4176
|
+
_vector1.lerp(_vector2, alpha1);
|
|
4177
|
+
_vector2.lerp(_vector1, 1 - alpha2);
|
|
4178
|
+
}
|
|
4179
|
+
}
|
|
4180
|
+
_vector1.multiplyScalar(1 / _vector1.w);
|
|
4181
|
+
_vector2.multiplyScalar(1 / _vector2.w);
|
|
4182
|
+
point1.x = (_vector1.x + 1) * _widthHalf;
|
|
4183
|
+
point1.y = (-_vector1.y + 1) * _heightHalf;
|
|
4184
|
+
point2.x = (_vector2.x + 1) * _widthHalf;
|
|
4185
|
+
point2.y = (-_vector2.y + 1) * _heightHalf;
|
|
4186
|
+
return {
|
|
4187
|
+
point1: point1,
|
|
4188
|
+
point2: point2,
|
|
4189
|
+
visible: visible
|
|
4190
|
+
};
|
|
4191
|
+
}
|
|
4192
|
+
}
|
|
4193
|
+
|
|
4734
4194
|
class ExtentsComponent {
|
|
4735
4195
|
constructor(viewer) {
|
|
4736
4196
|
this.syncExtents = () => {
|
|
4737
|
-
const extents = this.viewer.models.reduce(((result, gltf) =>
|
|
4738
|
-
const modelExtents = (new Box3).setFromObject(gltf.scene);
|
|
4739
|
-
return result.isEmpty() ? result.copy(modelExtents) : result.union(modelExtents);
|
|
4740
|
-
}), new Box3);
|
|
4197
|
+
const extents = this.viewer.models.reduce(((result, gltf) => result.expandByObject(gltf.scene)), new Box3);
|
|
4741
4198
|
this.viewer.extents.copy(extents);
|
|
4742
4199
|
this.viewer.target.copy(extents.getCenter(new Vector3));
|
|
4743
4200
|
};
|
|
@@ -4934,7 +4391,9 @@ class WCSHelper extends Object3D {
|
|
|
4934
4391
|
class WCSHelperComponent {
|
|
4935
4392
|
constructor(viewer) {
|
|
4936
4393
|
this.viewerRender = () => {
|
|
4937
|
-
if (!this.viewer.
|
|
4394
|
+
if (!this.viewer.options.showWCS) return;
|
|
4395
|
+
if (this.viewer.extents.isEmpty()) return;
|
|
4396
|
+
this.wcsHelper.render(this.viewer.renderer);
|
|
4938
4397
|
};
|
|
4939
4398
|
this.wcsHelper = new WCSHelper(viewer.camera);
|
|
4940
4399
|
this.viewer = viewer;
|
|
@@ -4962,7 +4421,8 @@ class Viewer extends EventEmitter2 {
|
|
|
4962
4421
|
Walk: WalkDragger,
|
|
4963
4422
|
CuttingPlaneXAxis: CuttingPlaneXAxisDragger,
|
|
4964
4423
|
CuttingPlaneYAxis: CuttingPlaneYAxisDragger,
|
|
4965
|
-
CuttingPlaneZAxis: CuttingPlaneZAxisDragger
|
|
4424
|
+
CuttingPlaneZAxis: CuttingPlaneZAxisDragger,
|
|
4425
|
+
MeasureLine: MeasureLineDragger
|
|
4966
4426
|
};
|
|
4967
4427
|
this._activeDragger = null;
|
|
4968
4428
|
this.models = [];
|
|
@@ -5186,6 +4646,7 @@ class Viewer extends EventEmitter2 {
|
|
|
5186
4646
|
this.setActiveDragger();
|
|
5187
4647
|
this.clearSlices();
|
|
5188
4648
|
this.clearOverlay();
|
|
4649
|
+
this.clearSelected();
|
|
5189
4650
|
this.helpers.traverse(disposeObject);
|
|
5190
4651
|
this.helpers.clear();
|
|
5191
4652
|
this.models.forEach((gltf => gltf.scene.traverse(disposeObject)));
|