浏览代码

fix: finish

xzw 2 年之前
父节点
当前提交
4c8beee399
共有 6 个文件被更改,包括 359 次插入372 次删除
  1. 2 2
      public/static/lib/potree/potree.js
  2. 1 1
      public/static/lib/potree/potree.js.map
  3. 8 2
      src/pages/SViewer.vue
  4. 1 1
      src/pages/Viewer.vue
  5. 338 361
      src/utils/ConvertViews.js
  6. 9 5
      src/utils/sync.js

+ 2 - 2
public/static/lib/potree/potree.js

@@ -91897,7 +91897,7 @@ void main() {
                     },
                     set:  (mode)=> {
                         latestRequestMode = mode;
-                        //console.warn('Request setMode: ' + mode)  
+                        console.warn('Request setMode: ' + mode);  
                                        
                         if(mode != displayMode){ 
                             let config = Potree.config.displayMode[mode];
@@ -92067,7 +92067,7 @@ void main() {
                              
                              
                             this.dispatchEvent({type:'endChangeMode',mode});  
-                            //console.log('setModeSuccess: ' + mode)       
+                            console.log('setModeSuccess: ' + mode);       
                         }else {
                             
                             //this.dispatchEvent({type:'endChangeMode',mode})    

文件差异内容过多而无法显示
+ 1 - 1
public/static/lib/potree/potree.js.map


+ 8 - 2
src/pages/SViewer.vue

@@ -119,8 +119,14 @@ const onLoadSource = () => {
     }else{ 
         win.sceneType = 'laser' 
         win.loaded.then(sdk => { 
-            loaded() 
-        }) 
+            win.viewer.images360.cancelFlyToPano() 
+            loaded();
+            
+            setTimeout(()=>{//laser的代码中莫名会请求showPointCloud,所以尽量晚一点覆盖它
+                win.Potree.settings.displayMode = mode.value == 0 ? "showPanos" : "showPointCloud"
+            },1000)
+            
+         }) 
     }
      
      

+ 1 - 1
src/pages/Viewer.vue

@@ -191,7 +191,7 @@ const onLoadSource = () => {
         return
     }
 
-    loadSourceScene(sourceFrame, source.value.type < 2 ? 'kankan' : 'laser')
+    loadSourceScene(sourceFrame, source.value.type < 2 ? 'kankan' : 'laser', mode.value)
 }
 const onLoadTarget = () => {
     if (bimChecked.value) {

+ 338 - 361
src/utils/ConvertViews.js

@@ -4,147 +4,10 @@ let bimViewer
 
 export default class ConvertViews extends THREE.EventDispatcher{
     constructor() {
-        super()
-        this.sourceApp = null
-        this.targetApp = null
-        this.sourceType = null
-        this.targetPano = null
-        
-         
+        super() 
     }
 
      
-    /* 
-        laser暂时做成这样: 全景模式时不跟踪pos,跟踪pano变化。点云模式时也跟踪pano变化,但移动时完全跟踪位置变化 ,所以会有左边marker在脚下,右边marker不在脚下的情况。
-        
-    */
-    
-    getCameraData(app){ 
-        if(app.sceneType == 'laser'){
-            let camera = app.viewer.mainViewport.camera
-            return {
-                position: camera.position.clone(),
-                quaternion: camera.quaternion.clone(),
-                fov: camera.fov,
-            }
-        }else if(app.sceneType == 'kankan'){
-            let player = app.app.core.get('Player')
-            return {
-                position: player.position.clone(),
-                quaternion: player.quaternion.clone(),
-                fov: player.zoomFov,
-            }
-        }else{
-            let bimViewer = app.viewer
-            let info = bimViewer.getCameraStatus();
-            return {
-                position: info.position,
-                target: info.target,
-                fov: info.fov,
-            }
-        }     
-    }
-    
-    
-    createTempApp(app, addsubInfo){//for mobile 
-          
-        let fakeApp = {
-            isFake : true, //标志是虚拟的app。每个真实的app都要带一个这个。在移动端如果大的销毁了还有小的
-            sceneType : app.sceneType 
-        }
-        if(app.sceneType != 'bim'){
-            function getPanos(panos){ // only data
-                return panos.map(e=>{return {id:e.id, position:e.position, quaternion:e.quaternion}})
-            }   
-            fakeApp.panos = app.sceneType == 'laser' ? getPanos(app.viewer.images360.panos) : getPanos(app.app.core.get('Player').model.panos.list) 
-        }
-         
-        app.fakeApp = fakeApp
-        
-        if(addsubInfo){
-            this.addViewInfo(app) 
-        } 
-        return fakeApp
-    }
-    
-    addViewInfo(app){
-        let viewInfo 
-        let cameraData = this.getCameraData(app)
-        if(app.sceneType == 'laser'){
-            let images360 = app.viewer.images360
-            viewInfo = {
-                displayMode : app.Potree.settings.displayMode,
-                currentPano :  images360.currentPano && images360.currentPano.id,
-                isAtPano : images360.isAtPano(),
-                quaternionChanged : true,
-                
-            } 
-        }else if(app.sceneType == 'kankan'){
-            let player = app.app.core.get('Player')
-            viewInfo = {
-                currentPano : player.currentPano.id,
-                lon : player.cameraControls.activeControl.lon,
-                lat : player.cameraControls.activeControl.lat,
-                zoomLevel : player.zoomLevel,
-            }
-        }else{
-            viewInfo = {}
-        }
-        
-        
-        for(let i in cameraData){
-            viewInfo[i] = cameraData[i]
-        }
-         
-        
-        app.fakeApp.viewInfo = viewInfo
-        
-    }
-    
-    
-    /* getPano(app){
-        return app.sceneType == 'laser' ? app.viewer.images360.getPano(id) : app.app.core.get('Player').panos.index[id]
-    } */
-    
-    syncView(master, customer, convertInfo ){//同类型 相当于moveCamera的函数 
-        let fakeApp = master.fakeApp;
-        convertInfo = convertInfo || this.convertInfo
-        if(fakeApp.sceneType == 'laser'){
-            customer.Potree.settings.displayMode = fakeApp.viewInfo.displayMode
-            if(fakeApp.viewInfo.isAtPano || fakeApp.viewInfo.displayMode == 'showPanos'){ //不改变漫游点,仅转换朝向 
-                if( fakeApp.viewInfo.quaternionChanged){
-             
-                    let diffQua = customer == this.targetApp ? convertInfo.diffQua : convertInfo.diffQuaInvert
-                    let quaternion = fakeApp.viewInfo.quaternion.clone().premultiply(diffQua)
-                    let rotation = new THREE.Euler().setFromQuaternion(quaternion)  
-                    customer.viewer.mainViewport.view.rotation = rotation
-                    //console.log('cameraMove',customer == this.targetApp) 
-                }
-                if(fakeApp.viewInfo.displayMode == 'showPanos' ){
-                    if(customer.viewer.mainViewport.camera.fov != fakeApp.viewInfo.fov){
-                        customer.viewer.mainViewport.camera.fov = fakeApp.viewInfo.fov
-                        customer.viewer.mainViewport.camera.updateProjectionMatrix()
-                    }
-                }
-            }else{//转换朝向和位置 
-                this.syncPosRot(fakeApp.viewInfo, customer ) 
-            } 
-        }else if(fakeApp.sceneType == 'kankan'){
-            let player = customer.app.core.get('Player')
-            let diffLon = THREE.Math.radToDeg(customer == this.sourceApp ? -convertInfo.diffLon : convertInfo.diffLon)
-            player.cameraControls.controls.panorama.lon = fakeApp.viewInfo.lon + diffLon
-            player.cameraControls.controls.panorama.lat = fakeApp.viewInfo.lat
-            
-            if(player.zoomLevel != fakeApp.viewInfo.zoomLevel){
-                player.zoomTo(fakeApp.viewInfo.zoomLevel)
-            }
-        }
-        
-        
-    }
-    
-    
-    
     
     bindWithSameFakeType(sourceFakeApp, targetApp){//for mobile 实际只有一个场景,未分屏,和上一个场景相比
         let sourceApp = {sceneType: sourceFakeApp.sceneType,  fakeApp:sourceFakeApp} 
@@ -158,12 +21,16 @@ export default class ConvertViews extends THREE.EventDispatcher{
          
         
         if(sourceApp.sceneType == 'laser'){
-            let data = this.computeShift({sourceApp,targetApp}) //因为有点云模式自由移动所以需要计算
+            let data = this.computeShift({sourceApp,targetApp, convertInfo}) //因为有点云模式自由移动所以需要计算
             convertInfo.convertMatrix = data.convertMatrix
             convertInfo.convertMatrixInvert = data.convertMatrixInvert
-        }
-        this.flyToPano(targetApp, sourceFakeApp.viewInfo.currentPano,{duration:0})
+        } 
+        
         this.syncView(sourceApp, targetApp, convertInfo)
+        if(sourceApp.sceneType == 'kankan' || sourceFakeApp.viewInfo.isAtPano){
+            this.flyToPano(targetApp, sourceFakeApp.viewInfo.currentPano,{duration:0})
+        }
+        
         
         if(sourceApp.sceneType == 'laser'){
             targetApp.viewer.mainViewport.view.applyToCamera(targetApp.viewer.mainViewport.camera)//使获得的cameraInfo正确
@@ -173,23 +40,11 @@ export default class ConvertViews extends THREE.EventDispatcher{
         }        
     }
     
-    flyToPano(app, panoId, o={}){
-        if(app.sceneType == 'laser'){
-            app.viewer.images360.flyToPano(Object.assign({},{ 
-                pano: app.viewer.images360.getPano(panoId)
-            },o)) 
-        }else{
-            let player = app.app.core.get('Player')
-            player.flyToPano(Object.assign({},{ 
-                pano: player.model.panos.index[panoId]
-            },o))
-             
-        }  
-    }
+    
+    
     
     bindWithSameType(sourceApp,targetApp, isSwitchScene){ 
-        
-        
+         
         this.sourceApp = sourceApp
         this.targetApp = targetApp
         this.createTempApp(sourceApp)
@@ -202,7 +57,7 @@ export default class ConvertViews extends THREE.EventDispatcher{
         
         if(sourceApp.sceneType == 'laser'){ 
             {
-                let data = this.computeShift({sourceApp,targetApp}) //因为有点云模式自由移动所以需要计算
+                let data = this.computeShift({sourceApp,targetApp, convertInfo:this.convertInfo}) //因为有点云模式自由移动所以需要计算
                 this.convertInfo.convertMatrix = data.convertMatrix
                 this.convertInfo.convertMatrixInvert = data.convertMatrixInvert
             }
@@ -321,83 +176,31 @@ export default class ConvertViews extends THREE.EventDispatcher{
                     
                  
                 if(master.sceneType == 'laser'){
-                    customer.Potree.settings.displayMode = master.Potree.settings.displayMode
+                    
                     let pano = master.viewer.images360.nextPano || master.viewer.images360.currentPano
-                    let pano2 = pano && customer.viewer.images360.getPano(pano.id)
-                    pano2 && customer.viewer.images360.flyToPano({pano : pano2, duration: 0 })
+                     
+                    pano && this.flyToPano(customer, pano.id,  { duration: 0, callback:()=>{
+                        customer.Potree.settings.displayMode = master.Potree.settings.displayMode
+                    }})
                     //master.viewer.dispatchEvent({type:'camera_changed',changeInfo:{quaternionChanged:true},viewport:master.viewer.mainViewport }) //朝向位置同步
                 }else{ 
                     //master.app.core.get('Player').emit("update",{ hasChanged:{cameraChanged:true}  })//朝向同步
                     let pano = master.app.core.get('Player').nextPano || master.app.core.get('Player').currentPano
-                    let pano2 = pano && customer.app.core.get('Player').model.panos.index[pano.id]
-                    pano2 && customer.app.core.get('Player').flyToPano({pano: pano2})
+                    
+                    pano && this.flyToPano(customer, pano.id,  { duration: 0 })
                 } 
             },1)//要延迟,否则角度和pano都不成功
         }
         
-        this.loaded = true
-        
-       
+        this.loaded = true 
     }
     
     
     
-    bimGetPanoData(sourceApp, targetApp, panoData){
-        if(panoData){
-            let sourcePano,targetPano 
-            let pano1 = [{position:new THREE.Vector3().copy(panoData.p1.position)},{position:new THREE.Vector3().copy(panoData.p2.position)}]
-            
-            let getPano2 = (app)=>{
-                return [app.fakeApp.panos.find(e=>e.id == panoData.p1.id), app.fakeApp.panos.find(e=>e.id == panoData.p2.id)] 
-            }
-            
-            if(targetApp.sceneType == 'bim'){ 
-                targetPano = pano1 
-                sourcePano = getPano2(sourceApp)
-            }else{ 
-                targetPano = getPano2(targetApp) 
-                sourcePano = pano1
-            }
-            return {sourcePano, targetPano} 
-        }else return {}
-    }
     
     
-    getTranPosData(data, convertInfo, ifRevert ){
-        let position = new THREE.Vector3, target = new THREE.Vector3
-        
-        if(data.position){
-            position = new THREE.Vector3().copy(data.position)
-        } 
-        if(!data.target){
-            if(data.quaternion){ 
-                let dir = new THREE.Vector3(0, 0, -1).applyQuaternion(data.quaternion)
-                target.copy(position).add(dir) 
-            }
-        }else{ 
-            target.copy(data.target) 
-        } 
-        
-        if(ifRevert){
-            position.applyMatrix4(convertInfo.convertMatrixInvert)
-            target.applyMatrix4(convertInfo.convertMatrixInvert)
-            if(convertInfo.convertAxis){
-                position = math.convertVector[convertInfo.convertAxis](position)
-                target = math.convertVector[convertInfo.convertAxis](target)
-            }
-        }else{
-            if(convertInfo.convertAxis){
-                position = math.convertVector[convertInfo.convertAxis](position)
-                target = math.convertVector[convertInfo.convertAxis](target)
-            }
-
-            position.applyMatrix4(convertInfo.convertMatrix)
-            target.applyMatrix4(convertInfo.convertMatrix)
-        }
-        return {position, target}
-    }
     
-    bindFakeWithBim(sourceFakeApp, targetApp, panoData ){// bim和其他类型互转
+    bindFakeWithBim(sourceFakeApp, targetApp, panoData ){// bim和其他类型互转(mobile)
         if(!panoData)return
     
     
@@ -456,11 +259,8 @@ export default class ConvertViews extends THREE.EventDispatcher{
                     this.syncPosRot(sourceFakeApp.viewInfo, targetApp, convertInfo) 
                 }else{
                     selectBestPose()
-                }
-                
-            },1000)
-        
-        
+                } 
+            },1000) 
         }else{//bim -> 固定点位
             selectBestPose()
              
@@ -640,108 +440,9 @@ export default class ConvertViews extends THREE.EventDispatcher{
         }    
     }
     
-    ifCanChangePos(app){
-        return app.sceneType == 'laser' && app.Potree.settings.displayMode != 'showPanos'   //app.fakeApp.viewInfo.displayMode != 'showPanos'
-    }
     
     
-    bimFlyTo(data){
-        let info = bimViewer.getCameraStatus() 
-        let dir = new THREE.Vector3().subVectors(info.target, info.position).normalize()
-        let position = data.position
-        if(!position){
-            position = new THREE.Vector3().addVectors(info.position, dir.clone().multiplyScalar(data.forwardDis))//forwardDis:前进距离
-       
-        }
-        
-        let target = new THREE.Vector3().addVectors(position, dir)
-        let msg = {
-            position,
-            target,
-            up: new THREE.Vector3(0,0,1),
-            //前三个缺一不可  
-            
-        } 
-        bimViewer.setCameraStatus(msg)
-        
-    }
  
-    bindCamEvent(){//传递到另一边的dom 
-        this.lockCamera(true)
-        
-        
-        /* this.targetApp.addEventListener(this.targetApp.Glodon.Bimface.Viewer.Viewer3DEvent.MouseClicked,(e)=>{
-            console.log('MouseClicked',e)
-        }); */
-        let dom1 = this.bimViewer.getDomElement() 
-        
-        let getEvent = (type, e)=>{
-          
-            let clientWidth1 = this.sourceDom.clientWidth
-            let clientHeight1 = this.sourceDom.clientHeight
-            let clientWidth2 = dom1.clientWidth
-            let clientHeight2 = dom1.clientHeight
-            return new MouseEvent(type, {
-                bubbles: false,//?
-                cancelable: true,
-                view: this.sourceApp,
-                
-                /* clientX: e.clientX, 
-                clientY: e.clientY, */ 
-                clientX: clientWidth1 * e.clientX / clientWidth2 , //鼠标在右屏的比例的左屏的相同,针对右屏全屏等左右不对称的情况
-                clientY: clientHeight1 * e.clientY / clientHeight2,
-                button: e.button, buttons: e.buttons,  which: e.which,
-                altKey: e.altKey, ctrlKey: e.ctrlKey, shiftKey:e.shiftKey, metaKey: e.metaKey, 
-                detail:e.detail, 
-                //target :  dom2  
-            });
-            
-        }  
-        
-        
-        //let pointerDownPos = new THREE.Vector2
-        dom1.addEventListener('mousedown',(e)=>{
-            let event = getEvent('mousedown', e)
-            this.sourceApp && this.sourceDom.dispatchEvent(event)  
-            //pointerDownPos.set(e.clientX,e.clientY)
-        })
-        dom1.addEventListener('mousemove',(e)=>{
-            let event = getEvent('mousemove', e)
-            this.sourceApp && this.sourceDom.dispatchEvent(event)  
-        })
-        dom1.addEventListener('mouseup',(e)=>{  
-            if(!this.sourceApp)return
-            let event = getEvent('mouseup', e)
-            event.unableClick = true //最好禁止右侧点击行走。否则和点击效果冲突
-            if(this.sourceApp.sceneType == 'laser'){
-                this.sourceApp.dispatchEvent(event)   //mouseup 在laser中加在window上的 
-            }else{
-                let player = this.sourceApp.app.core.get('Player')
-                player.mouseCouldBeClickToMove = false  //dont click
-                this.sourceDom.dispatchEvent(event)
-            }
-             
-        })
-        dom1.addEventListener('mousewheel',(e)=>{
-            let event = getEvent('mousewheel', e)
-            event.wheelDelta = e.wheelDelta  //wheelDelta没法在getEvent参数中赋值
-            this.sourceApp && this.sourceDom.dispatchEvent(event)  
-        })
-        let stop = (e)=>{ //drag到另一边时停止旋转, 防止转到另一边
-            let event = getEvent('mouseup', e)
-            this.sourceApp && this.sourceApp.dispatchEvent(event)   
-        }
-        dom1.addEventListener('mouseout',stop)
-        dom1.addEventListener('mouseover',stop)
-    
-    }
-
-
-    laserSyncView(app,data){
-        app.viewer.mainViewport.view.position.copy(data.position)
-        app.viewer.mainViewport.view.lookAt(data.target)
-    }
-    
     
     
     syncPosRot(data, customer, convertInfo ){//同步 自由位置和朝向(不被漫游点束缚时)
@@ -751,31 +452,7 @@ export default class ConvertViews extends THREE.EventDispatcher{
         } */
         convertInfo = convertInfo || this.convertInfo
         let {position,target} = this.getTranPosData(data, convertInfo ) 
-
-        /* let position = new THREE.Vector3, target = new THREE.Vector3
-       
-        if(data.position){
-            position = new THREE.Vector3().copy(data.position)
-        } 
-        
-        
-        
-        if(!data.target){
-            if(data.quaternion){ 
-                let dir = new THREE.Vector3(0, 0, -1).applyQuaternion(data.quaternion)
-                target.copy(position).add(dir) 
-            }
-        }else{ 
-            target.copy(data.target) 
-        }
-        
-        if(convertInfo.convertAxis){
-            position = math.convertVector[convertInfo.convertAxis](position)
-            target = math.convertVector[convertInfo.convertAxis](target)
-        }
-
-        position.applyMatrix4(convertInfo.convertMatrix)
-        target.applyMatrix4(convertInfo.convertMatrix) */
+ 
 
         if(customer && customer.sceneType == 'laser'){
             this.laserSyncView(customer, {position,target})
@@ -800,22 +477,21 @@ export default class ConvertViews extends THREE.EventDispatcher{
         }
 
     }
-
+    
+    
+    
+    
+    
+    ifCanChangePos(app){
+        return app.sceneType == 'laser' && app.Potree.settings.displayMode != 'showPanos'   //app.fakeApp.viewInfo.displayMode != 'showPanos'
+    }
+    
+    
 
     send(info){ 
         //let camera = bimViewer.getViewer().camera
         let data = this.getTranPosData(info, this.convertInfo, true ) 
-        /* let data = { 
-            position : new THREE.Vector3().copy(info.position).applyMatrix4(this.convertInfo.convertMatrixInvert),
-            //quaternion : camera.quaternion.clone().applyMatrix4(this.convertMatrix),
-            target : new THREE.Vector3().copy(info.target).applyMatrix4(this.convertInfo.convertMatrixInvert),
-        }  
-        
-        if(this.convertInfo.convertAxis){
-            data.position = math.convertVector[this.convertInfo.convertAxis](data.position)
-            data.target = math.convertVector[this.convertInfo.convertAxis](data.target)
-        } */
-         
+      
         this.laserSyncView(this.sourceApp, data) //左侧只有laser点云模式才能接收到
     } 
 
@@ -871,7 +547,7 @@ export default class ConvertViews extends THREE.EventDispatcher{
         let panoPos1, panoPos2
          
         if(o.sourceApp && o.targetApp && o.sourceApp.sceneType == o.targetApp.sceneType){
-            var angle = this.diffLon; //直接使用 更精准
+            var angle = o.convertInfo.diffLon; //直接使用 更精准
             panoPos1 = o.sourceApp.fakeApp.panos.map(e=>{
                 return e.position
             })
@@ -905,7 +581,240 @@ export default class ConvertViews extends THREE.EventDispatcher{
           
 
     }
+    
+    
+     
+    /* 
+        laser暂时做成这样: 全景模式时不跟踪pos,跟踪pano变化。点云模式时也跟踪pano变化,但移动时完全跟踪位置变化 ,所以会有左边marker在脚下,右边marker不在脚下的情况。
+        
+    */
+    
+    getCameraData(app){ 
+        if(app.sceneType == 'laser'){
+            let camera = app.viewer.mainViewport.camera
+            return {
+                position: camera.position.clone(),
+                quaternion: camera.quaternion.clone(),
+                fov: camera.fov,
+            }
+        }else if(app.sceneType == 'kankan'){
+            let player = app.app.core.get('Player')
+            return {
+                position: player.position.clone(),
+                quaternion: player.quaternion.clone(),
+                fov: player.zoomFov,
+            }
+        }else{
+            let bimViewer = app.viewer
+            let info = bimViewer.getCameraStatus();
+            return {
+                position: info.position,
+                target: info.target,
+                fov: info.fov,
+            }
+        }     
+    }
+    
+    
+    createTempApp(app, addsubInfo){//for mobile 
+          
+        let fakeApp = {
+            isFake : true, //标志是虚拟的app。每个真实的app都要带一个这个。在移动端如果大的销毁了还有小的
+            sceneType : app.sceneType 
+        }
+        if(app.sceneType != 'bim'){
+            function getPanos(panos){ // only data
+                return panos.map(e=>{return {id:e.id, position:e.position, quaternion:e.quaternion}})
+            }   
+            fakeApp.panos = app.sceneType == 'laser' ? getPanos(app.viewer.images360.panos) : getPanos(app.app.core.get('Player').model.panos.list) 
+        }
+         
+        app.fakeApp = fakeApp
+        
+        if(addsubInfo){
+            this.addViewInfo(app) 
+        } 
+        return fakeApp
+    }
+    
+    addViewInfo(app){
+        let viewInfo 
+        let cameraData = this.getCameraData(app)
+        if(app.sceneType == 'laser'){
+            let images360 = app.viewer.images360
+            viewInfo = {
+                displayMode : app.Potree.settings.displayMode,
+                currentPano :  images360.currentPano && images360.currentPano.id,
+                isAtPano : images360.isAtPano(),
+                quaternionChanged : true,
+                
+            } 
+        }else if(app.sceneType == 'kankan'){
+            let player = app.app.core.get('Player')
+            viewInfo = {
+                currentPano : player.currentPano.id,
+                lon : player.cameraControls.activeControl.lon,
+                lat : player.cameraControls.activeControl.lat,
+                zoomLevel : player.zoomLevel,
+            }
+        }else{
+            viewInfo = {}
+        }
+        
+        
+        for(let i in cameraData){
+            viewInfo[i] = cameraData[i]
+        }
+         
+        
+        app.fakeApp.viewInfo = viewInfo
+        
+    }
+    
+    
+    /* getPano(app){
+        return app.sceneType == 'laser' ? app.viewer.images360.getPano(id) : app.app.core.get('Player').panos.index[id]
+    } */
+    
+    syncView(master, customer, convertInfo ){//同类型 相当于moveCamera的函数 
+        let fakeApp = master.fakeApp;
+        convertInfo = convertInfo || this.convertInfo
+        if(fakeApp.sceneType == 'laser'){
+            customer.Potree.settings.displayMode = fakeApp.viewInfo.displayMode
+            if(fakeApp.viewInfo.isAtPano || fakeApp.viewInfo.displayMode == 'showPanos'){ //不改变漫游点,仅转换朝向 
+                if( fakeApp.viewInfo.quaternionChanged){
+             
+                    let diffQua = customer == this.targetApp ? convertInfo.diffQua : convertInfo.diffQuaInvert
+                    let quaternion = fakeApp.viewInfo.quaternion.clone().premultiply(diffQua)
+                    let rotation = new THREE.Euler().setFromQuaternion(quaternion)  
+                    customer.viewer.mainViewport.view.rotation = rotation
+                    //console.log('cameraMove',customer == this.targetApp) 
+                }
+                if(fakeApp.viewInfo.displayMode == 'showPanos' ){
+                    if(customer.viewer.mainViewport.camera.fov != fakeApp.viewInfo.fov){
+                        customer.viewer.mainViewport.camera.fov = fakeApp.viewInfo.fov
+                        customer.viewer.mainViewport.camera.updateProjectionMatrix()
+                    }
+                }
+            }else{//转换朝向和位置 
+                this.syncPosRot(fakeApp.viewInfo, customer , convertInfo) 
+            } 
+        }else if(fakeApp.sceneType == 'kankan'){
+            let player = customer.app.core.get('Player')
+            let diffLon = THREE.Math.radToDeg(customer == this.sourceApp ? -convertInfo.diffLon : convertInfo.diffLon)
+            player.cameraControls.controls.panorama.lon = fakeApp.viewInfo.lon + diffLon
+            player.cameraControls.controls.panorama.lat = fakeApp.viewInfo.lat
+            
+            if(player.zoomLevel != fakeApp.viewInfo.zoomLevel){
+                player.zoomTo(fakeApp.viewInfo.zoomLevel)
+            }
+        }
+        
+        
+    }
+    
+    
+    bimGetPanoData(sourceApp, targetApp, panoData){
+        if(panoData){
+            let sourcePano,targetPano 
+            let pano1 = [{position:new THREE.Vector3().copy(panoData.p1.position)},{position:new THREE.Vector3().copy(panoData.p2.position)}]
+            
+            let getPano2 = (app)=>{
+                return [app.fakeApp.panos.find(e=>e.id == panoData.p1.id), app.fakeApp.panos.find(e=>e.id == panoData.p2.id)] 
+            }
+            
+            if(targetApp.sceneType == 'bim'){ 
+                targetPano = pano1 
+                sourcePano = getPano2(sourceApp)
+            }else{ 
+                targetPano = getPano2(targetApp) 
+                sourcePano = pano1
+            }
+            
+            if( !sourcePano[0] || !sourcePano[1] || !targetPano[0] || !targetPano[1] ){
+                console.error('!sourcePano[0] || !sourcePano[1] || !targetPano[0] || !targetPano[1]')
+            }
+            
+            
+            return {sourcePano, targetPano} 
+        }else return {}
+    }
+    
+    
+    getTranPosData(data, convertInfo, ifRevert ){
+        let position = new THREE.Vector3, target = new THREE.Vector3
+        
+        if(data.position){
+            position = new THREE.Vector3().copy(data.position)
+        } 
+        if(!data.target){
+            if(data.quaternion){ 
+                let dir = new THREE.Vector3(0, 0, -1).applyQuaternion(data.quaternion)
+                target.copy(position).add(dir) 
+            }
+        }else{ 
+            target.copy(data.target) 
+        } 
+        
+        if(ifRevert){
+            position.applyMatrix4(convertInfo.convertMatrixInvert)
+            target.applyMatrix4(convertInfo.convertMatrixInvert)
+            if(convertInfo.convertAxis){
+                position = math.convertVector[convertInfo.convertAxis](position)
+                target = math.convertVector[convertInfo.convertAxis](target)
+            }
+        }else{
+            if(convertInfo.convertAxis){
+                position = math.convertVector[convertInfo.convertAxis](position)
+                target = math.convertVector[convertInfo.convertAxis](target)
+            }
+
+            position.applyMatrix4(convertInfo.convertMatrix)
+            target.applyMatrix4(convertInfo.convertMatrix)
+        }
+        return {position, target}
+    }
+    bimFlyTo(data){
+        let info = bimViewer.getCameraStatus() 
+        let dir = new THREE.Vector3().subVectors(info.target, info.position).normalize()
+        let position = data.position
+        if(!position){
+            position = new THREE.Vector3().addVectors(info.position, dir.clone().multiplyScalar(data.forwardDis))//forwardDis:前进距离
+       
+        }
+        
+        let target = new THREE.Vector3().addVectors(position, dir)
+        let msg = {
+            position,
+            target,
+            up: new THREE.Vector3(0,0,1),
+            //前三个缺一不可  
+            
+        } 
+        bimViewer.setCameraStatus(msg)
+        
+    }
+    
+    flyToPano(app, panoId, o={}){
+        if(app.sceneType == 'laser'){ 
+            app.viewer.images360.cancelFlyToPano() 
+            app.viewer.images360.flyToPano(Object.assign({},{ 
+                pano: app.viewer.images360.getPano(panoId)
+            },o)) 
+        }else{
+            let player = app.app.core.get('Player')
+            player.flyToPano(Object.assign({},{ 
+                pano: player.model.panos.index[panoId]
+            },o))
+             
+        }  
+    }
 
+    laserSyncView(app,data){
+        app.viewer.mainViewport.view.position.copy(data.position)
+        app.viewer.mainViewport.view.lookAt(data.target)
+    }
+    
 
     lockCamera(locked){//禁止操作改变相机
         this.locked = locked 
@@ -921,7 +830,75 @@ export default class ConvertViews extends THREE.EventDispatcher{
         this.bimViewer.camera3D.enableRotate(this.locked ? false : true)
         this.bimViewer.enableShortcutKey((this.locked || this.isPanoMode) ? false : true) //键盘移动
     }
-
+    bindCamEvent(){//传递到另一边的dom 
+        this.lockCamera(true)
+        
+        
+        /* this.targetApp.addEventListener(this.targetApp.Glodon.Bimface.Viewer.Viewer3DEvent.MouseClicked,(e)=>{
+            console.log('MouseClicked',e)
+        }); */
+        let dom1 = this.bimViewer.getDomElement() 
+        
+        let getEvent = (type, e)=>{
+          
+            let clientWidth1 = this.sourceDom.clientWidth
+            let clientHeight1 = this.sourceDom.clientHeight
+            let clientWidth2 = dom1.clientWidth
+            let clientHeight2 = dom1.clientHeight
+            return new MouseEvent(type, {
+                bubbles: false,//?
+                cancelable: true,
+                view: this.sourceApp,
+                
+                /* clientX: e.clientX, 
+                clientY: e.clientY, */ 
+                clientX: clientWidth1 * e.clientX / clientWidth2 , //鼠标在右屏的比例的左屏的相同,针对右屏全屏等左右不对称的情况
+                clientY: clientHeight1 * e.clientY / clientHeight2,
+                button: e.button, buttons: e.buttons,  which: e.which,
+                altKey: e.altKey, ctrlKey: e.ctrlKey, shiftKey:e.shiftKey, metaKey: e.metaKey, 
+                detail:e.detail, 
+                //target :  dom2  
+            });
+            
+        }  
+        
+        
+        //let pointerDownPos = new THREE.Vector2
+        dom1.addEventListener('mousedown',(e)=>{
+            let event = getEvent('mousedown', e)
+            this.sourceApp && this.sourceDom.dispatchEvent(event)  
+            //pointerDownPos.set(e.clientX,e.clientY)
+        })
+        dom1.addEventListener('mousemove',(e)=>{
+            let event = getEvent('mousemove', e)
+            this.sourceApp && this.sourceDom.dispatchEvent(event)  
+        })
+        dom1.addEventListener('mouseup',(e)=>{  
+            if(!this.sourceApp)return
+            let event = getEvent('mouseup', e)
+            event.unableClick = true //最好禁止右侧点击行走。否则和点击效果冲突
+            if(this.sourceApp.sceneType == 'laser'){
+                this.sourceApp.dispatchEvent(event)   //mouseup 在laser中加在window上的 
+            }else{
+                let player = this.sourceApp.app.core.get('Player')
+                player.mouseCouldBeClickToMove = false  //dont click
+                this.sourceDom.dispatchEvent(event)
+            }
+             
+        })
+        dom1.addEventListener('mousewheel',(e)=>{
+            let event = getEvent('mousewheel', e)
+            event.wheelDelta = e.wheelDelta  //wheelDelta没法在getEvent参数中赋值
+            this.sourceApp && this.sourceDom.dispatchEvent(event)  
+        })
+        let stop = (e)=>{ //drag到另一边时停止旋转, 防止转到另一边
+            let event = getEvent('mouseup', e)
+            this.sourceApp && this.sourceApp.dispatchEvent(event)   
+        }
+        dom1.addEventListener('mouseout',stop)
+        dom1.addEventListener('mouseover',stop)
+    
+    }
 
     clear(o={}){
         this.loaded = false;

+ 9 - 5
src/utils/sync.js

@@ -85,7 +85,7 @@ export function beforeChangeURL(which  ){
  * 左屏加载
  * @param {String} type kankan|laser
  */
-export function loadSourceScene(sourceFrame,type) {
+export function loadSourceScene(sourceFrame,type,mode) {
      
     /* if (views.loaded ) {
         isSwitchScene = true
@@ -106,7 +106,7 @@ export function loadSourceScene(sourceFrame,type) {
     
     if(type == 'laser'){
         win.loaded.then(sdk => { 
-            laserLoaded(win)
+            laserLoaded(win,mode)
             loaded()
         })  
     }else if(type == 'kankan'){  
@@ -153,7 +153,7 @@ export function loadTargetScene(targetFrame, type, mode) {
         win.loaded.then(sdk => {
             //targetApp.viewer.scene.changeMode(mode)  
             if(type == 'laser'){
-                laserLoaded(win)
+                laserLoaded(win,mode)
             }else if(type == 'bim'){
             } 
           
@@ -179,12 +179,12 @@ window.Log = function(value, color, fontSize){
     console.warn(`%c${value}`, `color:${color};font-size:${fontSize}px`) 
 }
   
-function laserLoaded(app){
+function laserLoaded(app,mode){
     if(!app.viewer){
         return console.error('!app.viewer', app.viewer)
     }
     
-    
+    app.viewer.images360.cancelFlyToPano() 
     app.viewer.mainViewport.view.minPitch += 0.01 //防止bim垂直视角上的闪烁(似乎是因 up 要乘以某矩阵导致微小偏差所致)
     app.viewer.mainViewport.view.minPitch -= 0.01
     app.viewer.images360.panos.forEach(pano=>{
@@ -195,6 +195,10 @@ function laserLoaded(app){
     app.Potree.settings.UserDensityPercent = 1 ; //因为nodeMaxLevel不同,感觉只有最高质量能看起来一样
     app.viewer.setPointLevels()
     app.Potree.settings.rotAroundPoint = false   //去除原因:比较好同步,尤其当左边在当前点位,右边同步后却离开当前点位的话拖拽就会绕点旋转了
+    setTimeout(()=>{//laser的代码中莫名会请求showPointCloud,所以尽量晚一点覆盖它
+        app.Potree.settings.displayMode = mode == 0 ? "showPanos" : "showPointCloud"
+    },1000)
+
 }