瀏覽代碼

fix: 定点缩放 触屏基本可以

xzw 3 年之前
父節點
當前提交
059da1e918

+ 21 - 3
note笔记笔记笔记.txt

@@ -133,13 +133,31 @@ Bug	|
 漫游飞行的时候增加点云pointBudget, 或者创建少量的鳞片矩形(但非朝向相机,而是使用normal)
 
 
+
+
+
+
+
+导航距离很短时,只得到一个点时,地图上的箭头好像偏离了起点终点?  
+导航地图上的margin再检查下 似乎没问题
+
+
+
+
+
 触屏的设备还不支持。macbook触摸板的也没有检查。 还不知道navvis的表现如何
 
+根据鼠标所在位置来放大。 触屏时根据双指位置来缩放(缩放就是定点平移),全景图也要放大
+
+
+为了适应触屏,测量估计要改成和navvis一样,没完成前不闭合,点击到开始点时才闭合。
+测量的在点击时也要计算,而非dragChange
+
+
+
+ 
 
 
-根据鼠标所在位置来放大
 
 
 
-导航距离很短时,只得到一个点时,地图上的箭头好像偏离了起点终点?  
-导航地图上的margin再检查下 似乎没问题

+ 1 - 1
src/defines.js

@@ -26,7 +26,7 @@ export const ElevationGradientRepeat = {
 	MIRRORED_REPEAT: 2,
 };
 
-export const MOUSE = {// MouseEvent.buttons
+export const Buttons = {// MouseEvent.buttons
     //buttons,设置按下了鼠标哪些键,是一个3个比特位的二进制值,默认为0。1表示按下主键(通常是左键),2表示按下次要键(通常是右键),4表示按下辅助键(通常是中间的键)。
 	NONE:0,//add
     

+ 37 - 16
src/modules/Images360/Images360.js

@@ -114,15 +114,14 @@ export class Images360 extends EventDispatcher{
                 }else{
                     zoom = 1 - this.scrollZoomSpeed
                 }
-                e.delta != 0 && this.zoomBy(zoom)
+                e.delta != 0 && this.zoomBy(zoom, e.pointer)
             }
         }
         viewer.addEventListener('global_mousewheel', scroll);
 
 
-
-        viewer.addEventListener('global_click'/* "global_drop" */, (e) => {//不用"mouseup" 是因为 mouseup有drag object时也会触发
-            if(Potree.settings.unableNavigate || this.flying  || e.button != THREE.MOUSE.LEFT || e.viewport != viewer.mainViewport )return //
+        let click = (e) => {//不用"mouseup" 是因为 mouseup有drag object时也会触发
+            if(Potree.settings.unableNavigate || this.flying  || e.button != THREE.MOUSE.LEFT || e.hoverViewport != viewer.mainViewport )return //
             
             /* if(currentlyHovered && currentlyHovered.pano){
 				this.focusPano(currentlyHovered.pano);
@@ -131,9 +130,9 @@ export class Images360 extends EventDispatcher{
                     this.flyToPanoClosestToMouse()   
                 }
             //}  
-        })
-        
-
+        }
+        viewer.addEventListener('global_click' , click)
+      
 
         viewer.addEventListener("global_mousemove", (e) => { 
             if(!Potree.settings.unableNavigate && Potree.settings.ifShowMarker && e.hoverViewport == viewer.mainViewport){//如果不显示marker,就在点击时再更新
@@ -1093,7 +1092,7 @@ export class Images360 extends EventDispatcher{
         
             
             var fov = {//test for direction  预加载的边缘有一丢丢不准确,尤其在相机倾斜时(4dkk也是)。
-                hFov: cameraLight.getHFOVForCamera(viewer.scene.getActiveCamera(), viewer.mainViewport.resolution2.x,viewer.mainViewport.resolution2.y  /* viewer.renderArea.clientWidth, viewer.renderArea.clientHeight */),
+                hFov: cameraLight.getHFOVForCamera(viewer.scene.getActiveCamera()  ),
 				vFov: viewer.scene.getActiveCamera().fov
             }//原先是null,不要求方向
             
@@ -1158,10 +1157,16 @@ export class Images360 extends EventDispatcher{
             if(camera.aspect > aspect){//视野更宽则用bound的纵向来决定
                 dis = /* size.y */o.boundSphere.radius/* / 2  *// THREE.Math.degToRad(camera.fov / 2)
             }else{
-                let hfov = cameraLight.getHFOVForCamera(camera, camera.aspect, 1 );
-                dis = /* size.x */ o.boundSphere.radius /* / 2 */ / THREE.Math.degToRad(hfov / 2)
+                let hfov = cameraLight.getHFOVForCamera(camera , true  );
+                dis = /* size.x */ o.boundSphere.radius /* / 2 */ /  (hfov / 2) 
             }
-                
+             
+
+            
+
+
+
+             
             bestDistance = dis//*0.8 
             
         } 
@@ -1193,10 +1198,10 @@ export class Images360 extends EventDispatcher{
     zoomOut = function() {//缩小
         this.zoomBy(1 - this.zoomSpeed);
     } */
-    zoomBy(e) {//以倍数
-        this.zoomTo(this.zoomLevel * e);
+    zoomBy(e, pointer) {//以倍数
+        this.zoomTo(this.zoomLevel * e, pointer);
     } 
-    zoomTo(zoomLevel) {//缩放到某绝对zoomLevel
+    zoomTo(zoomLevel, pointer) {//缩放到某绝对zoomLevel
         let zoom = Potree.settings.zoom
         if (zoom.enabled) {
             
@@ -1215,11 +1220,27 @@ export class Images360 extends EventDispatcher{
             } */ 
             
             this.zoomLevel = zoomLevel;
-            viewer.setFOV(Potree.config.view.fov * (1 / this.zoomLevel))
-           
+            //定点缩放:使当前鼠标所在的位置缩放后不变
+            let view = viewer.scene.view 
+            let originDir = viewer.scene.view.direction;
+            let oldPointerDir = viewer.inputHandler.getMouseDirection().direction
+            viewer.setFOV(Potree.config.view.fov * (1 / this.zoomLevel)) 
+            let newPointerDir = viewer.inputHandler.getMouseDirection().direction
+              
+            view.direction = oldPointerDir; //获取一下鼠标所在位置的yaw 和 pitch
+            let oldPitch = view.pitch, oldYaw = view.yaw;
+            view.direction = newPointerDir;
+            let newPitch = view.pitch, newYaw = view.yaw;
+             
+            view.direction = originDir //还原
+            viewer.scene.view.pitch -= newPitch - oldPitch
+            viewer.scene.view.yaw -= newYaw - oldYaw
         }
     }
      
+     
+     
+     
 
     zoomFovTo( fov ) { //通过fov来算zoomLevel 
         let zoomLevel = this.baseFov / fov;

+ 21 - 21
src/navigation/EarthControls.js

@@ -1,6 +1,6 @@
 
 import * as THREE from "../../libs/three.js/build/three.module.js";
-import {MOUSE} from "../defines.js";
+import {Buttons} from "../defines.js";
 import {Utils} from "../utils.js";
 import {EventDispatcher} from "../EventDispatcher.js";
 
@@ -51,12 +51,12 @@ export class EarthControls extends EventDispatcher {
 			let view = this.viewer.scene.view;
 
 			// let camera = this.viewer.scene.camera;
-			let mouse = e.drag.end;
+			let Buttons = e.drag.end;
 			let domElement = this.viewer.renderer.domElement;
 
-			if (e.drag.mouse === MOUSE.LEFT) {
+			if (e.drag.Buttons === Buttons.LEFT) {
 
-				let ray = Utils.mouseToRay(this.viewer.inputHandler.pointer/* mouse */, camera, domElement.clientWidth, domElement.clientHeight);
+				let ray = Utils.ButtonsToRay(this.viewer.inputHandler.pointer/* Buttons */, camera, domElement.clientWidth, domElement.clientHeight);
 				let plane = new THREE.Plane().setFromNormalAndCoplanarPoint(
 					new THREE.Vector3(0, 0, 1),
 					this.pivot);
@@ -82,10 +82,10 @@ export class EarthControls extends EventDispatcher {
 						this.viewer.setMoveSpeed(speed);
 					}
 				}
-			} else if (e.drag.mouse === MOUSE.RIGHT) {
+			} else if (e.drag.Buttons === Buttons.RIGHT) {
 				let ndrag = {
-					x: e.drag.mouseDelta.x / this.renderer.domElement.clientWidth,
-					y: e.drag.mouseDelta.y / this.renderer.domElement.clientHeight
+					x: e.drag.ButtonsDelta.x / this.renderer.domElement.clientWidth,
+					y: e.drag.ButtonsDelta.y / this.renderer.domElement.clientHeight
 				};
 
 				let yawDelta = -ndrag.x * this.rotationSpeed * 0.5;
@@ -115,9 +115,9 @@ export class EarthControls extends EventDispatcher {
 			}
 		};
 
-		let onMouseDown = e => {
-			let I = Utils.getMousePointCloudIntersection(
-				e.mouse, 
+		let onButtonsDown = e => {
+			let I = Utils.getButtonsPointCloudIntersection(
+				e.Buttons, 
 				this.scene.getActiveCamera(), 
 				this.viewer, 
 				this.scene.pointclouds, 
@@ -135,7 +135,7 @@ export class EarthControls extends EventDispatcher {
 			this.dispatchEvent({type: 'end'});
 		};
 
-		let onMouseUp = e => {
+		let onButtonsUp = e => {
 			this.camStart = null;
 			this.pivot = null;
 			this.pivotIndicator.visible = false;
@@ -146,14 +146,14 @@ export class EarthControls extends EventDispatcher {
 		};
 
 		let dblclick = (e) => {
-			this.zoomToLocation(e.mouse);
+			this.zoomToLocation(e.Buttons);
 		};
 
 		this.addEventListener('drag', drag);
 		this.addEventListener('drop', drop);
-		this.addEventListener('mousewheel', scroll);
-		this.addEventListener('mousedown', onMouseDown);
-		this.addEventListener('mouseup', onMouseUp);
+		this.addEventListener('Buttonswheel', scroll);
+		this.addEventListener('Buttonsdown', onButtonsDown);
+		this.addEventListener('Buttonsup', onButtonsUp);
 		this.addEventListener('dblclick', dblclick);
 	}
 
@@ -166,11 +166,11 @@ export class EarthControls extends EventDispatcher {
 		this.zoomDelta.set(0, 0, 0);
 	}
 	
-	zoomToLocation(mouse){
+	zoomToLocation(Buttons){
 		let camera = this.scene.getActiveCamera();
 		
-		let I = Utils.getMousePointCloudIntersection(
-			mouse,
+		let I = Utils.getButtonsPointCloudIntersection(
+			Buttons,
 			camera,
 			this.viewer,
 			this.scene.pointclouds);
@@ -184,7 +184,7 @@ export class EarthControls extends EventDispatcher {
 			let minimumJumpDistance = 0.2;
 
 			let domElement = this.renderer.domElement;
-			let ray = Utils.mouseToRay(this.viewer.inputHandler.pointer, camera, domElement.clientWidth, domElement.clientHeight);
+			let ray = Utils.ButtonsToRay(this.viewer.inputHandler.pointer, camera, domElement.clientWidth, domElement.clientHeight);
 
 			let nodes = I.pointcloud.nodesOnRay(I.pointcloud.visibleNodes, ray);
 			let lastNode = nodes[nodes.length - 1];
@@ -237,8 +237,8 @@ export class EarthControls extends EventDispatcher {
 		
 		// compute zoom
 		if (this.wheelDelta !== 0) {
-			let I = Utils.getMousePointCloudIntersection(
-				this.viewer.inputHandler.mouse, 
+			let I = Utils.getButtonsPointCloudIntersection(
+				this.viewer.inputHandler.Buttons, 
 				this.scene.getActiveCamera(), 
 				this.viewer, 
 				this.scene.pointclouds);

+ 19 - 11
src/navigation/FirstPersonControls.js

@@ -14,7 +14,7 @@
  */
 
 import * as THREE from "../../libs/three.js/build/three.module.js";
-import {MOUSE} from "../defines.js";
+import {Buttons} from "../defines.js";
 import {Utils} from "../utils.js";
 import {EventDispatcher} from "../EventDispatcher.js";
 import cameraLight from "../utils/cameraLight.js";
@@ -79,7 +79,7 @@ export class FirstPersonControls extends EventDispatcher {
             let viewport = e.drag.dragViewport;
             if(!viewport)return
             let camera = viewport.camera 
-            let mode = e.drag.mouse === MOUSE.LEFT && (!e.drag.dragViewport || e.drag.dragViewport.name == 'MainView') ? 'rotate' : 'pan'
+            let mode = e.buttons === Buttons.LEFT && (!e.drag.dragViewport || e.drag.dragViewport.name == 'MainView') ? 'rotate' : 'pan'
             let moveSpeed = this.currentViewport.getMoveSpeed();
             if (e.drag.startHandled === undefined) {///???????
 				e.drag.startHandled = true;
@@ -190,13 +190,11 @@ export class FirstPersonControls extends EventDispatcher {
                         }  */
                         let lastIntersect = viewport.lastIntersect ? (viewport.lastIntersect.location || viewport.lastIntersect) : viewer.bound.center  //该viewport的最近一次鼠标和点云的交点
                         let speed = camera.position.distanceTo(lastIntersect)   
-                        let fov = cameraLight.getHFOVForCamera(camera, camera.aspect, 1)
-                        let ratio = speed  * Math.tan(THREE.Math.degToRad(fov)/2) 
+                        let fov = cameraLight.getHFOVForCamera(camera, true)
+                        let ratio = speed  * Math.tan(fov/2) 
                         this.translationDelta.x -= e.drag.pointerDelta.x  * ratio
                         this.translationDelta.z -= e.drag.pointerDelta.y  * ratio 
                          
-                         
-                    
                     }
                 } 
                 
@@ -212,7 +210,9 @@ export class FirstPersonControls extends EventDispatcher {
 		let scroll = (e) => {
             if(!this.enabled)return   
             this.setCurrentViewport(e)            
-            if(this.currentViewport.unableChangePos)return 
+            if(this.currentViewport.unableChangePos){//全景时 
+                return 
+            }
             let camera = e.hoverViewport.camera
             let speed = this.currentViewport.getMoveSpeed() || 1 
             if(camera.type == "OrthographicCamera"){
@@ -228,22 +228,30 @@ export class FirstPersonControls extends EventDispatcher {
                 let limit = Potree.config.OrthoCameraLimit.zoom
                 zoom = THREE.Math.clamp(zoom, limit.min,limit.max )
                 
+                
+                let pointerPos = new THREE.Vector3(e.pointer.x, e.pointer.y,0.5); 
+                let oldPos = pointerPos.clone().unproject(camera);
+                
                 if(camera.zoom != zoom){ 
                     camera.zoom = zoom
                     camera.updateProjectionMatrix()
                 }
+                let newPos = pointerPos.clone().unproject(camera);
                 
-               
+                //定点缩放, 恢复一下鼠标所在位置的位置改变量
+                let moveVec = new THREE.Vector3().subVectors(newPos,oldPos)
+                this.translationWorldDelta.add(moveVec.negate()) 
                 
             }else{
-                var direction = this.currentViewport.view.direction.clone();
-            
+                //var direction = this.currentViewport.view.direction.clone();
+                let direction = this.viewer.inputHandler.getMouseDirection().direction  //定点缩放
+                 
                 var vec = direction.multiplyScalar(speed * 7)
                 if (e.delta < 0) {
                     this.translationWorldDelta.copy(vec.negate())
                 } else if (e.delta > 0) {
                     this.translationWorldDelta.copy(vec)
-                }
+                } 
             }
             
             

+ 203 - 150
src/navigation/InputHandler.js

@@ -7,7 +7,7 @@
 import * as THREE from "../../libs/three.js/build/three.module.js";
 import {KeyCodes} from "../KeyCodes.js";
 import {Utils} from "../utils.js";
-import {MOUSE} from "../defines.js"; 
+import {Buttons} from "../defines.js"; 
 import {EventDispatcher} from "../EventDispatcher.js";
 
 
@@ -98,86 +98,105 @@ export class InputHandler extends EventDispatcher {
 	onTouchStart (e) {
 		if (this.logMessages) console.log(this.constructor.name + ': onTouchStart');
 
-		e.preventDefault();
-
-
-
-
+		e.preventDefault(); 
 
-		if (e.touches.length === 1) {
+		if (e.touches.length === 1) { //changedTouches?
 			let rect = this.domElement.getBoundingClientRect();
-			let x = e.touches[0].pageX - rect.left;
-			let y = e.touches[0].pageY - rect.top;
-			this.mouse.set(x, y);
-
-			this.startDragging(null);
+			let x = e.touches[0].pageX 
+			let y = e.touches[0].pageY  
+			 
+            this.dealPointerDown(x,y,e,true)
+          
 		}
 
 		
-		/* for (let inputListener of this.getSortedListeners()) {
-			inputListener */this.viewer.dispatchEvent({
-				type: /* "global_"+ */e.type, // global_ 是否加上
-				touches: e.touches,
-				changedTouches: e.changedTouches
-			});
-		//}
+		this.viewer.dispatchEvent({
+            type: /* "global_"+ */e.type, // global_ 是否加上
+            touches: e.touches,
+            changedTouches: e.changedTouches
+        });
+	
         
         //add
         this.mouseDownMouse = this.mouse.clone()
 	}
+    
+    
+    
+    
 
 	onTouchEnd (e) {
 		if (this.logMessages) console.log(this.constructor.name + ': onTouchEnd');
 
 		e.preventDefault();
 
-		/* for (let inputListener of this.getSortedListeners()) {
-			inputListener. */this.viewer.dispatchEvent({
+		/*  this.viewer.dispatchEvent({
 				type: 'global_drop',
 				drag: this.drag,
 				viewer: this.viewer
 			});
-		//}
+		 
 
 		this.drag = null;
 
-		/* for (let inputListener of this.getSortedListeners()) {
-			inputListener */this.viewer.dispatchEvent({
+		 this.viewer.dispatchEvent({
 				type: 'global_' + e.type,
 				touches: e.touches,
 				changedTouches: e.changedTouches
-			});
-		//}
+			}); */
+        if (e.touches.length === 0) {
+			let rect = this.domElement.getBoundingClientRect();
+			let x = e.changedTouches[0].pageX   //万一一次松开两个指头的怎么办
+			let y = e.changedTouches[0].pageY  
+			 
+            this.dealPointerUp(x,y,e,true)
+             
+		}  
+         
+		 
 	}
 
+
+    
+
+
+
 	onTouchMove (e) {
 		if (this.logMessages) console.log(this.constructor.name + ': onTouchMove');
 
 		e.preventDefault();
-
+    
 		if (e.touches.length === 1) {
 			let rect = this.domElement.getBoundingClientRect();
-			let x = e.touches[0].pageX - rect.left;
-			let y = e.touches[0].pageY - rect.top;
-			this.mouse.set(x, y);
-
+			let x = e.touches[0].pageX;
+			let y = e.touches[0].pageY;
+			//this.mouse.set(x, y);
+            
+            
+            this.dealPointerMove(x, y, e, true)
+            
+            
+            /* var  {  camera, viewport  } = this.getPointerInViewport(x, y ) 
+            this.hoverViewport = viewport
+            if(!viewport)return 
+            
+            
 			if (this.drag) {
 				this.drag.mouse = 1; //why??非左键也非右键的意思?
 
-				this.drag.mouseDelta.x = x - this.drag.end.x;
-				this.drag.mouseDelta.y = y - this.drag.end.y;
+				this.drag.pointerDelta.set(this.pointer.x - this.drag.end.x, this.pointer.y - this.drag.end.y  );
+				this.drag.end.set(this.pointer.x, this.pointer.y);
 
-				this.drag.end.set(x, y);
+				 
 
 				if (this.logMessages) console.log(this.constructor.name + ': drag: ');
-				/* for (let inputListener of this.getSortedListeners()) {
-					inputListener */this.viewer.dispatchEvent({
+				this.viewer.dispatchEvent({
 						type: 'global_drag',
 						drag: this.drag,
 						viewer: this.viewer
 					});
-				//}
-			}
+				
+			} */
 		}
 
 		/* for (let inputListener of this.getSortedListeners()) {
@@ -276,29 +295,28 @@ export class InputHandler extends EventDispatcher {
 		e.preventDefault();
 	}
 
-	onMouseDown (e) {
-         
-		if (this.logMessages) console.log(this.constructor.name + ': onMouseDown');
-        
+
+
+
+    dealPointerDown(x,y,e,isTouch){
         //重新获取一下pointer, 因点击了浏览器的按钮展开列表时 move回来不会触发onmousemove,所以pointer是旧的
-        var  {  camera, viewport  } = this.getPointerInViewport(e.clientX, e.clientY ) 
+        var  {  camera, viewport  } = this.getPointerInViewport(x, y ) 
 		this.hoverViewport = viewport
         if(!viewport)return 
     
 		e.preventDefault(); 
-        
+         
         //this.onMouseMove(e)//add 重新获取一下mouse, 因在此前canvas可能失去侦听(不记得是什么了。如果一定要的话再写个加侦听的函数,但是直接调用mousemove的话会发送drag,导致magnifier停止渲染)
         
 		let consumed = false;
 		let consume = () => { return consumed = true; };
 		if (this.hoveredElements.length === 0) {
-			/* for (let inputListener of this.getSortedListeners()) {
-				inputListener */this.viewer.dispatchEvent({
-					type: 'global_mousedown',
-					viewer: this.viewer,
-					mouse: this.mouse
-				});
-			//}
+			this.viewer.dispatchEvent({
+                type: 'global_mousedown',
+                viewer: this.viewer,
+                mouse: this.mouse
+            });
+			
 		}else{
 			for(let hovered of this.hoveredElements){
 				let object = hovered.object;
@@ -319,7 +337,7 @@ export class InputHandler extends EventDispatcher {
         
 
 		if (!this.drag) {
-			let target = e.button == THREE.MOUSE.LEFT && this.hoveredElements.find(el => (//只有左键能拖拽
+			let target = (isTouch||e.button == THREE.MOUSE.LEFT) && this.hoveredElements.find(el => (//只有左键能拖拽
 					el.object._listeners &&
 					el.object._listeners['drag'] &&
 					el.object._listeners['drag'].length > 0));
@@ -337,10 +355,40 @@ export class InputHandler extends EventDispatcher {
         this.drag.intersectStart = this.intersectPoint;
         this.mouseDownMouse = this.mouse.clone()
         this.dragViewport = this.hoverViewport;
+    }
+
+
+
+	onMouseDown (e) {
+         
+		if (this.logMessages) console.log(this.constructor.name + ': onMouseDown');
+        this.dealPointerDown(e.clientX, e.clientY,e)
 		 
 	}
 
-	onMouseUp (e) {
+
+
+
+    getEventDesc(e,isTouch){//搜集dispatchEvent要给的一般数据 
+        return {
+            viewer: this.viewer,
+            mouse: this.mouse, 
+            pointer:this.pointer,
+            drag :this.drag,
+            isAtDomElement: e.target == this.domElement,
+            dragViewport : this.dragViewport,
+            hoverViewport: this.hoverViewport,
+            button: isTouch ? 0 : e.button,
+            buttons: isTouch ? e.touches.length : e.buttons,
+            isTouch,
+        }
+        
+    }
+
+
+
+    dealPointerUp(x,y,e,isTouch){
+        
         if(!this.drag){// 在canvas外mousedown
             return 
         }
@@ -355,14 +403,14 @@ export class InputHandler extends EventDispatcher {
 		let consume = () => { return consumed = true; };
 		//if (this.hoveredElements.length === 0) {
 			/* for (let inputListener of this.getSortedListeners()) {
-				inputListener */this.viewer.dispatchEvent({
-					type: 'global_mouseup',
-					viewer: this.viewer,
-					mouse: this.mouse,
-					consume: consume,
-                    drag :this.drag,
-                    pressDistance 
-				});
+				inputListener */this.viewer.dispatchEvent($.extend(  
+					this.getEventDesc(e,isTouch),
+                    {
+                        type: 'global_mouseup',
+                        pressDistance,
+                        consume,
+                    }
+                ));
 
 				/* if(consumed){//??
 					break;
@@ -388,53 +436,48 @@ export class InputHandler extends EventDispatcher {
             //拖拽结束
 			if (this.drag.object/*  && e.button == THREE.MOUSE.LEFT */) {//add LEFT
 				if (this.logMessages) console.log(`${this.constructor.name}: drop ${this.drag.object.name}`);
-				this.drag.object.dispatchEvent({
-					type: 'drop',
-					drag: this.drag, 
-					viewer: this.viewer,
-                    pressDistance,
-                    button : e.button,//add 放开的鼠标按键
-                    isAtDomElement: e.target == this.domElement,
-                    viewport:this.dragViewport 
-                    
-				});
-			} else {
-				/* for (let inputListener of this.getSortedListeners()) {
-					inputListener. */this.viewer.dispatchEvent({
-						type: 'global_drop',
-						drag: this.drag,
-						viewer: this.viewer,
-                        pressDistance,
-                        isAtDomElement: e.target == this.domElement,
-                        button: e.button //add
-					});
-				//}
+				
+                this.drag.object.dispatchEvent($.extend(  
+					this.getEventDesc(e,isTouch),
+                    {
+                        type: 'drop',
+                        pressDistance, 
+                    }
+                ));
+                
                 
+			} else {
+				this.viewer.dispatchEvent($.extend(  
+					this.getEventDesc(e,isTouch),
+                    {
+                        type: 'global_drop', 
+                        pressDistance
+                    }
+                ));
+                 
+                 
                 
                 // check for a click 
                 if(pressDistance < Potree.config.clickMaxDragDis){
                     if(this.hoveredElements && this.hoveredElements[0]){
                         if (this.logMessages) console.log(`${this.constructor.name}: click ${clicked.name}`);
-                        this.hoveredElements[0].object.dispatchEvent({
-                            type: 'click',
-                            viewer: this.viewer,
-                            consume: consume,
-                            viewport: this.hoverViewport,
-                            isAtDomElement: e.target == this.domElement,
-                            button: e.button //add
-                        });
+                        this.hoveredElements[0].object.dispatchEvent($.extend(  
+                            this.getEventDesc(e,isTouch),
+                            {
+                                type: 'click',
+                                pressDistance     
+                            }
+                        )); 
+                      
                     }else{
-                        /* for (let inputListener of this.getSortedListeners()) {
-                            inputListener. */this.viewer.dispatchEvent({
-                                type: 'global_click',
-                                drag: this.drag,
-                                viewer: this.viewer,
-                                pressDistance,
-                                viewport: this.hoverViewport,
-                                isAtDomElement: e.target == this.domElement,
-                                button: e.button //add
-                            });
-                        //}
+                        this.viewer.dispatchEvent($.extend(  
+                            this.getEventDesc(e,isTouch),
+                            {
+                                type: 'global_click',  
+                                pressDistance
+                            }
+                        )); 
+                       
                     }
                      
                 }
@@ -483,6 +526,10 @@ export class InputHandler extends EventDispatcher {
 				this.deselectAll();
 			}
 		}
+    }
+    
+	onMouseUp (e) {
+        this.dealPointerUp(e.clientX, e.clientY, e )
 	}
 
 
@@ -546,12 +593,13 @@ export class InputHandler extends EventDispatcher {
     }
 
 
-    
-
+    onMouseMove (e) {
+        this.dealPointerMove(e.clientX, e.clientY, e )
+    }
 
-	onMouseMove (e) {
-          
-        var  {  camera, viewport  } = this.getPointerInViewport(e.clientX, e.clientY,  this.dragViewport) 
+    dealPointerMove(x, y, e, isTouch){ 
+    
+        var  {  camera, viewport  } = this.getPointerInViewport(x, y,  this.dragViewport) 
 		this.hoverViewport = viewport
         if(!viewport)return//刚变化viewport时会找不到
         
@@ -589,22 +637,24 @@ export class InputHandler extends EventDispatcher {
         
  
 		if (this.drag) {//有拖拽(不一定拖拽了物体, 也不一定按下了鼠标)
-			this.drag.mouse = e.buttons; 
+			this.drag.mouse = isTouch ? 1 : e.buttons; 
             this.drag.hoverViewport = this.hoverViewport
-			/* this.drag.mouseDelta.x = this.mouse.x - this.drag.end.x;
-			this.drag.mouseDelta.y = this.mouse.y - this.drag.end.y; */
             this.drag.pointerDelta.set(this.pointer.x - this.drag.end.x, this.pointer.y - this.drag.end.y  )
 			this.drag.end.set(this.pointer.x, this.pointer.y);
             
             
-			if (this.drag.object && (e.buttons == MOUSE.NONE || !this.drag.notPressMouse )){//add notPressMouse 如果标记是不需要按鼠标的拖拽,则一旦按下鼠标,就暂停拖拽物体(改为拖拽场景):(如添加测量时突然拖拽画面)
+			if (this.drag.object && (e.buttons == Buttons.NONE || !this.drag.notPressMouse )){//add notPressMouse 如果标记是不需要按鼠标的拖拽,则一旦按下鼠标,就暂停拖拽物体(改为拖拽场景):(如添加测量时突然拖拽画面)
 				if (this.logMessages) console.log(this.constructor.name + ': drag: ' + this.drag.object.name);
-				this.drag.object.dispatchEvent({
-					type: 'drag',
-					drag: this.drag,
-					viewer: this.viewer,
-                    intersectPoint
-				});
+				
+                this.drag.object.dispatchEvent($.extend(  
+					this.getEventDesc(e,isTouch),
+                    {
+                        type: 'drag',
+                        intersectPoint,
+                    }
+                ))
+                
+                
 			} else {
                 
                 //add:
@@ -613,19 +663,16 @@ export class InputHandler extends EventDispatcher {
 				if (this.logMessages) console.log(this.constructor.name + ': drag: ');
 
 				let dragConsumed = false; 
-				/* for (let inputListener of this.getSortedListeners()) {
-					inputListener. */this.viewer.dispatchEvent({
-						type: 'global_drag',
-						drag: this.drag,
-						viewer: this.viewer,
+				this.viewer.dispatchEvent($.extend(  
+					this.getEventDesc(e,isTouch),
+                    {
+                        type: 'global_drag',
                         intersectPoint,
-						consume: () => {dragConsumed = true;}
-					});
-
-					/* if(dragConsumed){
-						break;
-					} */
-				//}
+                        consume: () => {dragConsumed = true;}
+                    }
+                ))
+                 
+				
 			}
 		}else{
 			let curr = hoveredElements.map(a => a.object).find(a => true);
@@ -686,7 +733,7 @@ export class InputHandler extends EventDispatcher {
                             })
                         }
                     }  
-            }
+                }
             }
             
 
@@ -724,15 +771,18 @@ export class InputHandler extends EventDispatcher {
         
         intersectPoint && (this.hoverViewport.lastIntersect = intersectPoint)
         
-        /* for (let inputListener of this.getSortedListeners()) {
-            inputListener. */this.viewer.dispatchEvent({
+        
+        this.viewer.dispatchEvent($.extend(  
+            this.getEventDesc(e,isTouch),
+            {
                 type: 'global_mousemove',
                 intersectPoint,
-                hoverViewport:this.hoverViewport,
-                buttons: e.buttons,
-                drag:this.drag,
-            });
-        //}
+                
+            }
+        ))
+        
+        
+        
 		
 
 		this.hoveredElements = hoveredElements;
@@ -757,21 +807,24 @@ export class InputHandler extends EventDispatcher {
 		// this.wheelDelta += Math.sign(delta);
 
 		if (this.hoveredElement) {
-			this.hoveredElement.object.dispatchEvent({
-				type: 'mousewheel',
-				delta: ndelta,
-				object: this.hoveredElement.object
-			});
+			this.hoveredElement.object.dispatchEvent($.extend(  
+                this.getEventDesc(e,isTouch),
+                {
+                    type: 'mousewheel',
+                    delta: ndelta, 
+                    object: this.hoveredElement.object
+                }
+            )); 
+            
 		} else {
-			/* for (let inputListener of this.getSortedListeners()) {
-				inputListener. */this.viewer.dispatchEvent({
-					type: 'global_mousewheel',
-					delta: ndelta,
-					object: null,
-                    hoverViewport: this.hoverViewport
-                    
-				});
-			//}
+            this.viewer.dispatchEvent($.extend(  
+                this.getEventDesc(e),
+                {
+                    type: 'global_mousewheel',
+                    delta: ndelta, 
+                }
+            ));
+              
 		}
 	}
 

+ 3 - 3
src/navigation/OrbitControls.js

@@ -14,7 +14,7 @@
  */
 
 import * as THREE from "../../libs/three.js/build/three.module.js";
-import {MOUSE} from "../defines.js";
+import {Buttons} from "../defines.js";
 import {Utils} from "../utils.js";
 import {EventDispatcher} from "../EventDispatcher.js";
 
@@ -63,12 +63,12 @@ export class OrbitControls extends EventDispatcher{
             let ndrag = e.drag.pointerDelta.clone()//.add(new THREE.Vector2(1,1)).multiplyScalar(0.5)
             ndrag.y *= -1
 
-			if (e.drag.mouse === MOUSE.LEFT) {
+			if (e.buttons === Buttons.LEFT) {
 				this.yawDelta += ndrag.x * this.rotationSpeed;
 				this.pitchDelta += ndrag.y * this.rotationSpeed;
 
 				this.stopTweens();
-			} else /* if (e.drag.mouse === MOUSE.RIGHT)  */{
+			} else {
                
 				this.panDelta.x += ndrag.x;
 				this.panDelta.y += ndrag.y;

+ 2 - 2
src/navigation/Reticule.js

@@ -1,5 +1,5 @@
 import * as THREE from "../../libs/three.js/build/three.module.js";
-import {MOUSE} from '../defines.js'
+import {Buttons} from '../defines.js'
 import {transitions, easing, lerp} from '../utils/transitions.js'
 import math from '../utils/math.js'
 
@@ -48,7 +48,7 @@ export default class Reticule extends THREE.Mesh{
     }
 
     move(e){
-        if(e.buttons == MOUSE.NONE || this.state == 'crosshair' ){//按下时不更新,除非拖拽测量
+        if(e.buttons == Buttons.NONE || this.state == 'crosshair' ){//按下时不更新,除非拖拽测量
             this.hidden = false,
             this.mouseLastMoveTime = Date.now()
             

+ 1 - 2
src/utils/Measure.js

@@ -4,8 +4,7 @@ import {TextSprite} from "../TextSprite.js";
 import {Utils} from "../utils.js";
 import  Label  from "./Label.js";
 import {LineDraw} from "../utils/DrawUtil";
-import math from "./math.js";
-import {MOUSE} from "../defines.js"; 
+import math from "./math.js"; 
 import DepthBasicMaterial from "../materials/DepthBasicMaterial.js";
 import Sprite from '../viewer/Sprite'
 import {config} from '../settings'

+ 1 - 1
src/utils/MeasuringTool.js

@@ -3,7 +3,7 @@ import * as THREE from "../../libs/three.js/build/three.module.js";
 import {Measure} from "./Measure.js";
 import {Utils} from "../utils.js"; 
 import math from "./math.js";
-import {CameraMode,MOUSE} from "../defines.js";
+import {CameraMode} from "../defines.js";
 import { EventDispatcher } from "../EventDispatcher.js";
  
 function updateAzimuth(viewer, measure){

+ 8 - 10
src/utils/cameraLight.js

@@ -5,16 +5,14 @@ var cameraLight = {
         var r = cameraLight.getHFOVFromVFOV(currentFov, width, height);
         return r > maxHFov ? cameraLight.getVFOVFromHFOV(maxHFov, width, height) : currentFov
     },
-    getHFOVForCamera: function(camera, width, height) {
-        return cameraLight.getHFOVFromVFOV(camera.fov, width, height)
-    },
-    getHFOVFromVFOV: function(fov, width, height) { 
-        return 2 * Math.atan(Math.tan(fov * MathLight.RADIANS_PER_DEGREE / 2) * (width / height)) * MathLight.DEGREES_PER_RADIAN;
-          
-    },
-    getVFOVFromHFOV: function(fov, width, height) { 
-        return 2 * Math.atan(Math.tan(fov * MathLight.RADIANS_PER_DEGREE / 2) * (height / width)) * MathLight.DEGREES_PER_RADIAN;
-         
+    getHFOVForCamera: function(camera,  getRad) {
+        return cameraLight.getFOVByScreenPrecent(camera.fov, camera.aspect, getRad)
+    }, 
+    //add
+    getFOVByScreenPrecent: function(fov, percent, getRad) { //当fov为占比百分百时,percent代表在屏幕上从中心到边缘的占比
+        let rad = 2 * Math.atan(percent * Math.tan(fov * MathLight.RADIANS_PER_DEGREE / 2));
+        if(getRad)return rad 
+        else return rad * MathLight.DEGREES_PER_RADIAN;
     }
 };
 

+ 54 - 12
src/viewer/viewer.js

@@ -867,10 +867,11 @@ export class Viewer extends ViewerBase{
 
 	setFOV (value) {
 		if (this.fov !== value) {
+            let oldFov = this.fov
 			this.fov = value;
             this.scene.cameraP.fov = this.fov;
             this.scene.cameraP.updateProjectionMatrix()
-			this.dispatchEvent({'type': 'fov_changed', 'viewer': this});
+			this.dispatchEvent({'type': 'fov_changed', 'viewer': this,  oldFov, fov:this.fov});
 		}
 	};
 
@@ -2840,11 +2841,42 @@ export class Viewer extends ViewerBase{
             })
             return deferred.promise();//不能打扰 从点云转向全景图时 的飞行
         }
-        if (type == 'measure') {  
+        if (type == 'measure') { 
+
+        
+            
+                
             target.copy(object.getCenter()) 
        
             
             var cameraTemp = camera.clone()
+            
+             //试试改变位置,直视测量线。能避免倾斜角度造成的非常不居中、以及看不到面的情况,但镜头旋转幅度太大了
+            if(object.facePlane/*  && window.focusMeasureFaceToIt */){
+                let normal
+                if(object.facePlane){
+                    normal = object.facePlane.normal.clone()
+                }/* else{ 
+                    if(object.points.length>2){
+                        console.error('怎么有多个点却没有facePlane?')
+                    }else{
+                        normal = //以后再写
+                    }
+                }  */                 
+                let angle = this.scene.view.direction.angleTo(normal)
+                if(angle<Math.PI*0.7){//当几乎正对时就不执行
+                    if(angle<Math.PI/2){
+                        normal.negate()
+                    }
+                    let dir = new THREE.Vector3().subVectors(camera.position, target).normalize() 
+                    let newDir = new THREE.Vector3().addVectors(dir,normal)//两个角度的中间
+                    cameraTemp.position.copy(target.clone().add(newDir))
+                }
+                
+                
+            } 
+            
+            
             cameraTemp.lookAt(target);
             cameraTemp.updateMatrix();
             cameraTemp.updateMatrixWorld();
@@ -2875,21 +2907,31 @@ export class Viewer extends ViewerBase{
                 this.scene.scene.add(this.boundBox); 
             }
              
-            
+           
             this.boundBox.position.copy(target)
             this.boundBox.scale.copy(boundSize)
-            this.boundBox.lookAt(camera.position)
+            this.boundBox.lookAt(cameraTemp.position)
+            
+            
+            {
+                let scale = 1.1; //稍微放大一些,不然会靠到屏幕边缘
+                boundSize.x *= scale 
+                boundSize.y *= scale 
+                
+            }
+            
             
-             
             
             let aspect = boundSize.x / boundSize.y
             if(camera.aspect > aspect){//视野更宽则用bound的纵向来决定
-                dis = boundSize.y/2/ THREE.Math.degToRad(camera.fov / 2) + boundSize.z/2 
+                dis = boundSize.y/2/ Math.tan(THREE.Math.degToRad(camera.fov / 2)) + boundSize.z/2 
             }else{
-                let hfov = cameraLight.getHFOVForCamera(camera, camera.aspect, 1 );
-                dis = boundSize.x/2 / THREE.Math.degToRad(hfov / 2) + boundSize.z/2
-            }//为何在只有两点的情况下,依然不能使box的边界刚好对着屏幕边界? 会缩小一些。  而三点以上的中心在这个视角上也不准确,所以点会超出box范围。
-             
+                let hfov = cameraLight.getHFOVForCamera(camera, true);
+                dis = boundSize.x/2 / Math.tan(hfov / 2) + boundSize.z/2
+            }
+            
+            //三个顶点以上的由于measure的中心不等于bound的中心,所以点会超出bound外。 且由于视椎近大远小,即使是两个点的,bound居中后线看上去仍旧不居中.
+            
             
             if(this.mapViewer.attachedToViewer){ 
                 //console.log('mapFocusOn: '+target.toArray())
@@ -2901,8 +2943,8 @@ export class Viewer extends ViewerBase{
             }
             
             
-            if(Potree.settings.displayMode == 'showPointCloud'){  //点云
-                let dir = new THREE.Vector3().subVectors(camera.position, target).normalize() 
+            if(Potree.settings.displayMode == 'showPointCloud'){  //点云 
+                let dir = new THREE.Vector3().subVectors(cameraTemp.position, target).normalize()
                 position.copy(target).add(dir.multiplyScalar(dis))
                  
             }else if(Potree.settings.displayMode == 'showPanos'){//全景 (比较难校准)