Browse Source

fix: 正在飞向某点或转向某点 可被其他操作立即中断,如鼠标拖拽画面 view

xzw 2 years ago
parent
commit
2d4f4e1857

+ 17 - 17
src/custom/modules/panos/Images360.js

@@ -598,19 +598,18 @@ export class Images360 extends THREE.EventDispatcher{
             })
         }
         
-        //console.warn('setProjectedPanos  ', o.pano0.id , o.pano1.id)
+        console.warn('setProjectedPanos  ', o.pano0.id , o.pano1.id)
         this.projectedPano0 = o.pano0    
         this.projectedPano1 = o.pano1
         
     }
 
 
-	cancelFlyToPano(){//取消当前已有的飞行准备,前提是相机还未移动
-        //Potree.Log('cancelFlyToPano')
-        if(viewer.mainViewport.view.isFlying())return
+	cancelFlyToPano(toPano){//取消当前已有的飞行准备,前提是相机还未移动 
+        if(viewer.mainViewport.view.isFlying() || toPano && this.latestToPano != toPano)return
+        Potree.Log('cancelFlyToPano', this.latestToPano && this.latestToPano.pano.id)
         this.nextPano = null 
-        this.latestToPano = null
-        //this.flying = false
+        this.latestToPano = null 
     }
 
 
@@ -622,14 +621,13 @@ export class Images360 extends THREE.EventDispatcher{
         
        
         let done = (makeIt, disturb)=>{
-            //console.log('flyToPano done ', toPano.pano.id, makeIt ) 
+            //console.log('flyToPano done ', toPano.pano.id, makeIt, disturb ) 
             if(makeIt || disturb) { // disturb已经开始飞行但中途取消
                 toPano.callback && toPano.callback(makeIt) 
                 //this.flying = false
-                this.cancelFlyToPano()
+                this.cancelFlyToPano(toPano)
                 this.updateClosestPano(this.closestPano,false) //飞行结束后取消点击漫游点时得到的closestPano
-            }else{
-                /* console.log('makeit fail') */
+            }else{ 
             }
            
             this.dispatchEvent({type:'flyToPanoDone', makeIt})
@@ -638,12 +636,13 @@ export class Images360 extends THREE.EventDispatcher{
         }
         
         if(!toPano.pano.enabled)return done(false,true);
+        //Potree.Log('hope flyToPano: '+toPano.pano.id )
         
-                 
-        if(this.latestToPano && this.latestToPano != toPano && !this.latestToPano.pano.position.equals(this.position)){//还在飞//如果旧的toPano只是旋转镜头,就直接取消旧的
-            return done(false)
-        }
         
+        if(this.latestToPano && this.latestToPano != toPano && this.latestToPano.pano != this.currentPano){//还在飞//如果旧的toPano只是旋转镜头,就直接取消旧的
+            return done(false) 
+        }
+        //Potree.Log('flyToPano: '+toPano.pano.id,  this.latestToPano && this.latestToPano.pano.id )
         if(this.currentPano == toPano.pano && this.isAtPano() && !toPano.target && !toPano.quaternion  ){
             this.dispatchEvent({type:'flyToPano', toPano})
             return done(true);
@@ -666,7 +665,7 @@ export class Images360 extends THREE.EventDispatcher{
         this.nextPano = pano 
         this.latestToPano = toPano
         //this.flying = true  //防止新的请求
-        /* Potree.Log('flyToPano:'+pano.id + ' , duration:'+toPano.duration, null, 12) */
+        //Potree.Log('flyToPano:'+pano.id + ' , duration:'+toPano.duration, null, 12)  
         
         
         {//不飞的话是否不要执行这段?
@@ -754,7 +753,8 @@ export class Images360 extends THREE.EventDispatcher{
                     
                     
                     
-                }, onUpdate:(progress)=>{ 
+                }, onUpdate:(progress)=>{
+                    //console.log('uniforms progress',progress)                    
                     this.cube.material.uniforms.progress.value = progress 
                     
                     viewer.scene.pointclouds.forEach(e=>{
@@ -1994,7 +1994,7 @@ export class Images360 extends THREE.EventDispatcher{
                 //let result = (- dis1  - Math.pow(dis2 , 1.5)) / (cos + 2)  // cos+2是为了调整到1-3, 
                 
                 let result =  (dis1 + dis2*0.3) * ( -1 + cos*0.9 ) //尽量贴近最佳位置的角度, 或贴近相机原来的角度 。尽量靠近最佳观测点,并且优先选择靠近目标点的位置.(注意cos的乘数不能太接近1,否则容易只考虑角度)
-                Potree.Log(pano.id, dis1, dis2,  cos,  result,{font:{toFixed:2,fontSize:10}}) 
+                //Potree.Log(pano.id, dis1, dis2,  cos,  result,{font:{toFixed:2,fontSize:10}}) 
                 
                 if(maxDisSquared && dis2 > maxDisSquared){
                     result -= maxDisSquared*3 ;//尽量不要超过可视距离

+ 2 - 3
src/custom/settings.js

@@ -430,13 +430,12 @@ let settings = {//设置   可修改
     useRTskybox:true,  //直接使用rtEDL绘制到屏幕,当是全景模式时. 在降4倍时能给render节省1毫秒,gpu时间未测
     useRTPoint:true,    //直接使用rtEDL绘制到屏幕,当是点云模式时。可以大大节省gpu时间
     pointEnableRT:false,//点云是否允许绘制到rtEDL。只在有需要时使用
-    
+    cloudSameMat:true,  //因为点云个数较多,就使用相同的材质,可见降低绘制速度(要保证所有点云的maxNodelevel一样,且要算出 material.spacing的平均值)
     
     showCompass : isTest,
     showAxis : isTest,
-    //testCube : true,
+    testCube : true,
     
-    cloudSameMat:true,  //因为点云个数较多,就使用相同的材质,可见降低绘制速度(要保证所有点云的maxNodelevel一样,且要算出 material.spacing的平均值)
 }
   
  

+ 10 - 11
src/custom/three.shim.js

@@ -124,17 +124,16 @@ THREE.EventDispatcher.prototype.addEventListener = function(type, listener, {imp
 
 		const listeners = this._listeners;
 
-		if ( listeners[ type ] === undefined ) {
-
-			listeners[ type ] = [];
-
+		if ( listeners[ type ] === undefined ) { 
+			listeners[ type ] = []; 
 		}
-
-		if ( !listeners[ type ].some(e=>e.listener == listener )  ) { 
-			//listeners[ type ].push( listener );
+        if(type == 'flyingDone'){
+            console.log('addEventListener flyingDone')
+        }
+		if ( !listeners[ type ].some(e=>e.listener == listener )  ) {  
             listeners[type].push({ listener, importance, once});
             listeners[type] = listeners[type].sort((e,a)=> a.importance - e.importance)//add
-		}
+		} 
 }
 
 THREE.EventDispatcher.prototype.hasEventListener = function(type, listener){
@@ -190,13 +189,13 @@ THREE.EventDispatcher.prototype.dispatchEvent = function(event){
 
         event.target = this;
 
-        // Make a copy, in case listeners are removed while iterating.
-         
+        // Make a copy, in case listeners are removed while iterating. 
         for(let {listener, once} of listenerArray.slice(0)){
-            let result = listener.call(this, event);   //add stopContinue
             if(once){
                 this.removeEventListener(event.type,listener)
             }
+            let result = listener.call(this, event);   //add stopContinue
+            
             if(result && result.stopContinue){
                 break
             }

+ 10 - 5
src/custom/utils/Common.js

@@ -158,21 +158,26 @@ var Common = {
         return result;
     }
     ,
-    CloneClassObject :function(copyObj ){//复杂类对象
+    CloneClassObject :function(copyObj, {ignoreList=[],simpleCopyList=[]}={}){//复杂类对象
         var newobj = new copyObj.constructor();
-        this.CopyClassObject(newobj, copyObj) 
+        this.CopyClassObject(newobj, copyObj, {ignoreList,simpleCopyList}) 
         
         return newobj
     }
     
     ,
      
-    CopyClassObject :function(targetObj,  copyObj){//复杂类对象
+    CopyClassObject :function(targetObj,  copyObj, {ignoreList=[],simpleCopyList=[]}={}){//复杂类对象
         for(let i in copyObj){
             if(i in copyObj.__proto__)break; //到函数了跳出 
-              
-            targetObj[i] = this.CloneObject(copyObj[i], null )  
             
+            if(ignoreList.includes(i)){
+                continue;
+            }else if(simpleCopyList.includes(i)){
+                targetObj[i] = copyObj[i]
+            }else{
+                targetObj[i] = this.CloneObject(copyObj[i], null, false, simpleCopyList )  
+            }
                 
             
             /* else if(copyObj[i].clone instanceof Function ){

+ 4 - 4
src/custom/viewer/ViewerNew.js

@@ -3084,13 +3084,13 @@ export class Viewer extends ViewerBase{
         let useMap = info.type == 'measure' || info.map
         
         
-        if(this.images360.flying){//如果在飞,飞完再截图
+        if(Potree.settings.displayMode == 'showPanos' && viewer.scene.view.isFlying('pos')){//如果在飞,飞完再截图
             info.getImageDeferred = getImageDeferred , info.finishDeferred = finishDeferred
             let f = ()=>{
-                this.startScreenshot(info,  width, height, compressRatio)
-                this.images360.removeEventListener('cameraMoveDone', f)
+                this.startScreenshot(info,  width, height, compressRatio)  
             } 
-            this.images360.addEventListener('cameraMoveDone', f) //once 
+            viewer.scene.view.addEventListener('flyingDone', f, {once:true}) 
+          
             return {getImagePromise:getImageDeferred.promise(), finishPromise:finishDeferred.promise()}
         }
         

+ 7 - 6
src/navigation/FirstPersonControlsNew.js

@@ -75,7 +75,7 @@ export class FirstPersonControls extends THREE.EventDispatcher {
         })
         
 
-		let drag = (e) => {
+		let drag = (e) => {  
             if(!this.enabled)return 
             let viewport = e.dragViewport;
             if(!viewport)return
@@ -101,7 +101,7 @@ export class FirstPersonControls extends THREE.EventDispatcher {
 				this.dispatchEvent({type: 'start'});
 			}
             
-                
+            
             if (mode.includes('rotate')) {//旋转 
 				
                 //来自panoramaControl updateRotation
@@ -249,7 +249,7 @@ export class FirstPersonControls extends THREE.EventDispatcher {
                         this.translationWorldDelta.add(moveVec.negate())  
                     }
                      
-                }else{ //perspectiveCamera:
+                }else{ //perspectiveCamera: 
                     if(e.drag.intersectStart){//如果拖拽着点云 
                         let ifInit = e.drag.z == void 0
                         let pointerStartPos2d = e.drag.intersectStart.location.clone().project(camera);//识别到的点云点的位置
@@ -277,9 +277,7 @@ export class FirstPersonControls extends THREE.EventDispatcher {
                         camera.projectionMatrixInverse = _projectionMatrixInverse
                         this.translationWorldDelta.copy(moveVec.negate())  //这里没法用add,原因未知,打开console时会跳动
                         //console.log('pan 1', this.translationWorldDelta.clone())   
-                        
                          
-                        
                         //四指松开剩三指时会偏移一下,暂不知道哪里的问题,或许跟开头防止点云吸附有关?
                          
                     }else{ //如果鼠标没有找到和点云的交点,就假设移动整个模型(也可以去扩大范围寻找最近点云)
@@ -301,10 +299,13 @@ export class FirstPersonControls extends THREE.EventDispatcher {
                         let ratio = speed  * Math.tan(fov/2) 
                         this.translationDelta.x -= e.drag.pointerDelta.x  * ratio
                         this.translationDelta.z -= e.drag.pointerDelta.y  * ratio 
-                         //console.log('pan2', e.drag.pointerDelta)
+                        //console.log('pan2', e.drag.pointerDelta)
                     }
                 } 
                 this.useAttenuation = false
+                
+                
+                
 			}
             
             

+ 83 - 62
src/viewer/ExtendView.js

@@ -48,17 +48,45 @@ class ExtendView extends View {
     
     
     copy(a){
-        Common.CopyClassObject(this, a)
+        Common.CopyClassObject(this, a, {ignoreList: ['_listeners']})
     }
     
 	clone () {  
-        return Common.CloneClassObject(this)
+        return Common.CloneClassObject(this, {ignoreList: ['_listeners']}) 
 	}
     
     //----------  
     
     
-    
+    setCubeView(dir) {
+		 
+		switch(dir) {
+			case "front":
+				this.yaw = 0;
+                this.pitch = 0;
+				break;
+			case "back":
+				this.yaw =  Math.PI;  
+                this.pitch = 0;
+				break;
+			case "left":
+				this.yaw = -Math.PI / 2;
+                this.pitch = 0;
+				break;
+			case "right":
+				this.yaw = Math.PI / 2;
+                this.pitch = 0;
+				break;
+			case "top":
+				this.yaw = 0;
+                this.pitch = -Math.PI / 2;
+				break;
+			case "bottom":
+				this.yaw = -Math.PI;
+                this.pitch = Math.PI / 2;
+				break;
+		}
+	}
  
  
 
@@ -102,7 +130,9 @@ class ExtendView extends View {
         
 		this.position = this.position.add(t);
          
-        x != 0 && y != 0 && z != 0 &&  /* t.lengthSq()!=0  && */Potree.settings.displayMode != 'showPanos' && this.cancelFlying('pos')
+        if((!math.closeTo(x, 0, 1e-4) || !math.closeTo(y, 0, 1e-4) || !math.closeTo(z, 0, 1e-4)) && Potree.settings.displayMode != 'showPanos'){
+            this.cancelFlying('pos')
+        }
         
         this.restrictPos()
 	}
@@ -110,7 +140,10 @@ class ExtendView extends View {
 	translateWorld (x, y, z) { 
 		super.translateWorld(x, y, z)
         
-        x != 0 && y != 0 && z != 0 && Potree.settings.displayMode != 'showPanos' && this.cancelFlying('pos')
+        if((!math.closeTo(x, 0, 1e-4) || !math.closeTo(y, 0, 1e-4) || !math.closeTo(z, 0, 1e-4)) && Potree.settings.displayMode != 'showPanos'){
+            this.cancelFlying('pos')
+        }
+           
         this.restrictPos()
 	}
 
@@ -120,53 +153,19 @@ class ExtendView extends View {
             (position || this.position).clamp(this.limitBound.min, this.limitBound.max)
         }
     }
-
-
-
-    setCubeView(dir) {
-		 
-		switch(dir) {
-			case "front":
-				this.yaw = 0;
-                this.pitch = 0;
-				break;
-			case "back":
-				this.yaw =  Math.PI;  
-                this.pitch = 0;
-				break;
-			case "left":
-				this.yaw = -Math.PI / 2;
-                this.pitch = 0;
-				break;
-			case "right":
-				this.yaw = Math.PI / 2;
-                this.pitch = 0;
-				break;
-			case "top":
-				this.yaw = 0;
-                this.pitch = -Math.PI / 2;
-				break;
-			case "bottom":
-				this.yaw = -Math.PI;
-                this.pitch = Math.PI / 2;
-				break;
-		}
-	}
-    
-    
-    
+ 
     isFlying(type='all'){
         let a = transitions.getById(this.FlyTransition).length > 0
         let b = transitions.getById(this.LookTransition).length > 0 
        
-        return type == 'pos' ? a : type == 'rotate' ? b :  a && b
+        return type == 'pos' ? a : type == 'rotate' ? b :  (a || b)
     }
     
     cancelFlying(type='all'){//外界只能通过这个来cancel
         type == 'pos' ? transitions.cancelById(this.FlyTransition, true )
          : type == 'rotate' ? transitions.cancelById(this.LookTransition, true )    
          : (transitions.cancelById(this.FlyTransition, true ), transitions.cancelById(this.LookTransition, true ))
-        
+        //console.log('cancelFlying ' , this.sid,  type)
     }
     
     
@@ -175,9 +174,11 @@ class ExtendView extends View {
     setView( info = {}){
         // position, target, duration = 0, callback = null, onUpdate = null, Easing='', cancelFun
         this.cancelFlying()
-        let finished
+        let posWaitDone,  rotWaitDone 
+        
         let posDone = ()=>{
-            done()
+            rotWaitDone || done()
+            posWaitDone = false
         }
         let rotDone = ()=>{
             if(endTarget){
@@ -185,10 +186,12 @@ class ExtendView extends View {
             }else if(endQuaternion){
                 this.rotation = new THREE.Euler().setFromQuaternion(endQuaternion)
             }
-            done()
+            posWaitDone || done()
+            rotWaitDone = false 
         }
-        let done = ()=>{ 
-            if(finished)return
+        
+        let done = ()=>{ //一定要旋转和位移都结束了才能执行
+            
             let f = ()=>{
                 info.callback && info.callback()     
                 this.dispatchEvent('flyingDone')  
@@ -198,7 +201,7 @@ class ExtendView extends View {
             }else{
                 f()  //有的需要迅速执行回调
             }
-            finished = true
+            
         }
         
         let endPosition = new THREE.Vector3().copy(info.position)
@@ -213,7 +216,7 @@ class ExtendView extends View {
             endQuaternion = info.quaternion.clone()
         }
          
-        if(endQuaternion){
+        if(endQuaternion){ 
             startQuaternion = new THREE.Quaternion().setFromEuler(this.rotation)
             /*  const startTarget = this.getPivot();
             let startQuaternion = math.getQuaFromPosAim(startPosition,startTarget) */
@@ -224,32 +227,50 @@ class ExtendView extends View {
 		if(!info.duration){
 			this.position.copy(endPosition);
             this.restrictPos()
-			
+			posWaitDone = true, rotWaitDone = true 
             info.onUpdate && info.onUpdate(1)
             posDone()
             rotDone()
 		}else{
+            info.onUpdate && info.onUpdate(0) //初始化progress
+            
             let posChange = !this.position.equals(endPosition)
             if(posChange){
+                posWaitDone = true 
                 transitions.start(lerp.vector(this.position, endPosition, (pos, progress)=>{
                     
                     info.onUpdate && info.onUpdate(progress) 
                     
-                }), info.duration, posDone/* done */, 0, info.Easing ? easing[info.Easing] : easing.easeInOutSine /*easeInOutQuad */,null, this.FlyTransition, info.cancelFun); 
-                 
+                }), info.duration, posDone , 0, info.Easing ? easing[info.Easing] : easing.easeInOutSine ,null, this.FlyTransition, ()=>{
+                    //中途取消 
+                    if(endTarget ){
+                        /* endPosition = new THREE.Vector3().copy(this.position)//更改旋转的endQuaternion 
+                        endQuaternion = math.getQuaFromPosAim(endPosition,endTarget)  */
+                        //直接改变endQuaternion会突变,所以还是cancel吧
+                        this.cancelFlying('rotate')
+                    } 
+                    posWaitDone = false 
+                    info.cancelFun && info.cancelFun()
+                });  
             } 
             
-            
-            endQuaternion && transitions.start( (progress)=>{
-                
-                let quaternion = (new THREE.Quaternion()).copy(startQuaternion) 
-                lerp.quaternion(quaternion, endQuaternion)(progress),
-                this.rotation = new THREE.Euler().setFromQuaternion(quaternion)
-                
-                posChange || info.onUpdate && info.onUpdate(progress) 
+            if(endQuaternion){
+                rotWaitDone = true 
+                transitions.start( (progress)=>{
                 
-            }, info.duration, rotDone/* posChange?done:null */, 0, info.Easing ? easing[info.Easing] : easing.easeInOutSine ,null, this.LookTransition, info.cancelFun); 
-                   
+                    let quaternion = (new THREE.Quaternion()).copy(startQuaternion) 
+                    lerp.quaternion(quaternion, endQuaternion)(progress),
+                    this.rotation = new THREE.Euler().setFromQuaternion(quaternion)
+                    
+                    //posChange || info.onUpdate && info.onUpdate(progress)  //位置没变化uniforms不需要变progress
+                    
+                }, info.duration, rotDone , 0, info.Easing ? easing[info.Easing] : easing.easeInOutSine ,null, this.LookTransition, ()=>{
+                    //中途取消
+                    rotWaitDone = false
+                    info.cancelFun && info.cancelFun()
+                }); 
+                  
+            }