xzw пре 2 година
родитељ
комит
ba59fa2e29
3 измењених фајлова са 219 додато и 75 уклоњено
  1. 48 14
      src/pages/SViewer.vue
  2. 169 60
      src/utils/ConvertViews.js
  3. 2 1
      src/utils/sync.js

+ 48 - 14
src/pages/SViewer.vue

@@ -31,7 +31,7 @@ import Calendar from '@/components/calendar/mobile.vue'
 import sync, { loadSourceScene, loadTargetScene } from '@/utils/sync'
 
 // 点位信息
-let panoInfo = null
+let lastFakeApp = null
 
 const showBimTips = ref(false)
 
@@ -60,22 +60,63 @@ const sourceURL = computed(() => {
     if (bimChecked.value) {
         return `smart-bim.html?m=${project.value.bimData.bimOssFilePath}`
     }
-    if (source.value.type < 2) {
+    /*if (source.value.type < 2) {
         let pose = ''
         // 获取当前点位旋转值
         if (sourceFrame.value && sourceFrame.value.contentWindow.app && sourceFrame.value.contentWindow.app.Camera) {
             let sdk = sourceFrame.value.contentWindow.app
-            panoInfo = sdk.Camera.getPose()
-            pose = '&'+sdk.Camera.getPoseUrlParams()
+            lastFakeApp = sync.views.createTempApp(sourceFrame.value.contentWindow, true);
+              
+            //pose = '&'+sdk.Camera.getPoseUrlParams()
         }
         // 看看、看见场景
-        return `smart-kankan.html?m=${source.value.num}${pose}`
+        return `smart-kankan.html?m=${source.value.num}`//`smart-kankan.html?m=${source.value.num}${pose}`
     } else {
         // 深时场景
-        return `smart-laser.html?m=${source.value.num}&dev`
+        return `smart-kankan.html?m=${source.value.num}`//`smart-laser.html?m=${source.value.num}&dev`
+    }*/
+    
+    if (sourceFrame.value && sourceFrame.value.contentWindow){ 
+        lastFakeApp = sync.views.createTempApp(sourceFrame.value.contentWindow, true);
+        
+        return `smart-kankan.html?m=${source.value.num}`
     }
+    
 })
 
+const onLoadSource = () => { 
+    let win = sourceFrame.value.contentWindow 
+        window.app = win
+    if (source.value.type < 2) {
+        win.sceneType = 'kankan'
+        let sdk = win.app 
+        sdk.Scene.on('loaded', () => {
+            if (lastFakeApp) {
+                if(sdk){
+                    sync.views.bindWithSameFakeType(lastFakeApp,win)  
+                }
+            }
+        }) 
+    }else{ 
+        win.sceneType = 'laser' 
+        win.loaded.then(sdk => {
+            if (lastFakeApp) {
+                 
+                    sync.views.bindWithSameFakeType(lastFakeApp,win)  
+                 
+            }
+        }) 
+    }
+     
+     
+}
+
+
+
+
+
+
+
 const sourceDate = computed(() => {
     if (source.value) {
         return source.value.createTime.toDate()
@@ -105,14 +146,7 @@ const sourceDays = computed(() => {
     return outDays
 })
 
-const onLoadSource = () => {
-    if (panoInfo) {
-        let sdk = sourceFrame.value.contentWindow.app
-        sdk.Scene.on('loaded', () => {
-           
-        })
-    }
-}
+
 
 const onModeChange = targetMode => {
     if (sourceFrame.value && sourceFrame.value.contentWindow.loaded) {

+ 169 - 60
src/utils/ConvertViews.js

@@ -47,21 +47,134 @@ export default class ConvertViews extends THREE.EventDispatcher{
         }     
     }
     
+    
+    createTempApp(app, addsubInfo){//for mobile 
+        let fakeApp = {
+            isFake : true, //标志是虚拟的app。每个真实的app都要带一个这个。在移动端如果大的销毁了还有小的
+            sceneType : app.sceneType, 
+            panos : app.sceneType == 'laser' ? getPanos(app.viewer.images360.panos) : getPanos(app.app.core.get('Player').model.panos.list) 
+            
+        }
+        
+        function getPanos(panos){ // only data
+            return panos.map(e=>{return {id:e.id, position:e.position, quaternion:e.quaternion}})
+        }
+        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.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,
+            }
+        }
+        
+        viewInfo.position = cameraData.position
+        viewInfo.quaternion = cameraData.quaternion
+        viewInfo.fov = cameraData.fov
+        
+        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 ){//补充一下 moveCamera的函数 
+        let fakeApp = master.fakeApp;
+        if(fakeApp.sceneType == 'laser'){
+            if(fakeApp.viewInfo.isAtPano || fakeApp.viewInfo.displayMode == 'showPanos'){ //转换朝向 
+                if( fakeApp.viewInfo.quaternionChanged){
+             
+                    let diffQua = customer == this.targetApp ? this.diffQuaternion : this.diffQuaternionInvert
+                    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.receive(fakeApp.viewInfo, customer ) 
+            } 
+        }else if(fakeApp.sceneType == 'kankan'){
+            let player = customer.app.core.get('Player')
+            let diffLon = THREE.Math.radToDeg(customer == this.sourceApp ? -this.diffLon : this.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 实际只有一个场景,未分屏,和上一个场景相比
+        this.sourceApp = {sceneType: targetApp.sceneType,  fakeApp:sourceFakeApp} 
+        this.targetApp = targetApp
+        this.createTempApp(targetApp, true)
+        this.computeAveDiffLon(sourceFakeApp, targetApp.fakeApp)
+        this.sourceApp.sceneName = 'sourceApp'
+        this.targetApp.sceneName = 'targetApp'
+        
+        
+        if(this.sourceApp.sceneType == 'laser'){
+            this.computeShift() //因为有点云模式自由移动所以需要计算
+            
+        }
+        
+        this.syncView(this.sourceApp, this.targetApp)
+        
+    }
+    
+    
+    
     bindWithSameType(sourceApp,targetApp, isSwitchScene){ 
         
         
         this.sourceApp = sourceApp
         this.targetApp = targetApp
+        this.createTempApp(sourceApp)
+        this.createTempApp(targetApp)
         
-        this.diffLon = this.computeAveDiffLon()
-        this.diffQuaternion = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0, 1, 0), this.diffLon)
-        this.diffQuaternionInvert = this.diffQuaternion.clone().invert()
-       
+        this.computeAveDiffLon(sourceApp.fakeApp, targetApp.fakeApp)
+         
         sourceApp.sceneName = 'sourceApp'
         targetApp.sceneName = 'targetApp'
         
         if(sourceApp.sceneType == 'laser'){
-            this.computeShift()
+            this.computeShift() //因为有点云模式自由移动所以需要计算
             //只监听左边
             let displayMode = (e)=>{
                 targetApp.Potree.settings.displayMode = e.mode
@@ -91,7 +204,13 @@ export default class ConvertViews extends THREE.EventDispatcher{
                 
                 var cameraMove = (e)=>{ 
                     if(master != this.masterApp || !customer.viewer )return
-                    //console.log('cameraMove')
+                    
+                    this.addViewInfo(master)
+                    
+                    master.fakeApp.viewInfo.quaternionChanged = e.changeInfo && e.changeInfo.quaternionChanged
+                    this.syncView(master, customer)
+                    
+                    /* //console.log('cameraMove')
                     if(master.viewer.images360.isAtPano() || master.Potree.settings.displayMode == 'showPanos'){ //转换朝向 
                         if(e.changeInfo && e.changeInfo.quaternionChanged){
                             let data = this.getCameraData(master)
@@ -110,7 +229,7 @@ export default class ConvertViews extends THREE.EventDispatcher{
                     }else{//转换朝向和位置
                         let data = this.getCameraData(master)
                         this.receive(data, customer ) 
-                    } 
+                    }  */
                                             
                 } 
                 master.viewer.addEventListener('camera_changed',cameraMove)
@@ -140,13 +259,17 @@ export default class ConvertViews extends THREE.EventDispatcher{
                 
                 var cameraMove = (e)=>{//暂时只有漫游模式
                     if(!e.hasChanged.cameraChanged)return
-                    let diffLon = master == this.sourceApp ? this.diffLon : -this.diffLon
+                    
+                    this.addViewInfo(master)
+                    this.syncView(master, customer)
+                    
+                    /* let diffLon = master == this.sourceApp ? this.diffLon : -this.diffLon
                     player2.cameraControls.controls.panorama.lon = player1.cameraControls.controls.panorama.lon + diffLon
                     player2.cameraControls.controls.panorama.lat = player1.cameraControls.controls.panorama.lat
                     
                     if(player2.zoomLevel != player1.zoomLevel){
                         player2.zoomTo(player1.zoomLevel)
-                    }
+                    } */
                     
                 }
                 player1.on("update",cameraMove)
@@ -198,18 +321,24 @@ export default class ConvertViews extends THREE.EventDispatcher{
                 let master = isSwitchScene == 'target' ? sourceApp : targetApp
                 let customer = isSwitchScene == 'target' ? targetApp : sourceApp
                 this.masterApp = master 
+                
+                this.addViewInfo(master)
+                this.syncView(master, customer)
+                    
+                
+                
                 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 })
-                    master.viewer.dispatchEvent({type:'camera_changed',changeInfo:{quaternionChanged:true},viewport:master.viewer.mainViewport }) //朝向位置同步
+                    //master.viewer.dispatchEvent({type:'camera_changed',changeInfo:{quaternionChanged:true},viewport:master.viewer.mainViewport }) //朝向位置同步
                 }else{ 
-                    master.app.core.get('Player').emit("update",{ hasChanged:{cameraChanged:true}  })//朝向同步
+                    //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})
-                }
+                } 
             },1)//要延迟,否则角度和pano都不成功
         }
         
@@ -218,6 +347,8 @@ export default class ConvertViews extends THREE.EventDispatcher{
        
     }
     
+    
+    
      
     bindWithBim(sourceApp, targetApp,   sourcePano, targetPano  ) {
         //if (!this.player1.model.panos.list.length || !this.player2.model.panos.list.length) return
@@ -532,15 +663,21 @@ export default class ConvertViews extends THREE.EventDispatcher{
         this.laserSyncView(this.sourceApp, data) //左侧只有laser点云模式才能接收到
     } 
 
-    computeAveDiffLon() {
+    computeAveDiffLon(sourceFakeApp, targetFakeApp) {
         //获取两个场景的lon偏差值
         //需要点的个数>1, 且两个场景点一一对应,位置接近且顺序一致
 
         let diffLonAve = 0, length,
-            diffLons = [],
-            panoPos1, panoPos2  
-        
-        if(this.sourceApp.sceneType == 'laser'){
+            diffLons = [] 
+             
+        let panoPos1 = sourceFakeApp.panos.map(e=>{
+            return e.position
+        })
+        let panoPos2 = targetFakeApp.panos.map(e=>{
+            return e.position
+        })    
+            
+        /* if(this.sourceApp.sceneType == 'laser'){
             panoPos1 = this.sourceApp.viewer.images360.panos.map(e=>{
                 return e.position
             })
@@ -555,7 +692,9 @@ export default class ConvertViews extends THREE.EventDispatcher{
             panoPos2 = this.targetApp.app.core.get('Player').model.panos.list.map(e=>{
                 return e.position
             })  
-        }
+        } */
+        
+        
         length = panoPos1.length
 
         //挑选连续的两个点为向量来计算,如有123个漫游点,则选取12 23 31作为向量
@@ -577,33 +716,30 @@ export default class ConvertViews extends THREE.EventDispatcher{
         console.log('diffLons', diffLons)
         diffLonAve /= length
         console.log('diffLonAve', diffLonAve)
-        return /* KanKan.THREE.MathUtils.radToDeg( */ diffLonAve /* ) */
+        
+        this.diffLon = diffLonAve
+        this.diffQuaternion = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0, 1, 0), this.diffLon)
+        this.diffQuaternionInvert = this.diffQuaternion.clone().invert()
+        
+        
+        
     }
 
     computeShift(sourcePano, targetPano) { //获取两个场景的旋转和位移偏差值
         //需要点的个数>1, 且两个场景点一一对应,位置接近且顺序一致
-        //pick两个点来计算
-        let diffLonAve = 0, panoPos1, panoPos2,
-            diffLons = []
-
-        /* let panoPos1 = [//4dkk   SS-t-lc5OWhZPaC 
-            new THREE.Vector3( 2.1985836955069153,  -0.7253820937020852,  -0.01348725),
-            new THREE.Vector3( 4.07288387528266,  1.8350265362839944, 0.04772775)
-        ] */
-        
-        
         
+        let panoPos1, panoPos2
          
         if(this.sourceApp.sceneType == this.targetApp.sceneType){
-            var angle = this.diffLon;
-            panoPos1 = this.sourceApp.viewer.images360.panos.map(e=>{
+            var angle = this.diffLon; //直接使用 更精准
+            panoPos1 = this.sourceApp.fakeApp.panos.map(e=>{
                 return e.position
             })
-            panoPos2 = this.targetApp.viewer.images360.panos.map(e=>{
+            panoPos2 = this.targetApp.fakeApp.panos.map(e=>{
                 return e.position
             }) 
         }else{
-            panoPos1 = sourcePano.map(e=>e.position) 
+            panoPos1 = sourcePano.map(e=>e.position) //pick两个点来计算
             panoPos2 = targetPano.map(e=>e.position)
         
             if(this.needConvertAxis){
@@ -629,34 +765,7 @@ export default class ConvertViews extends THREE.EventDispatcher{
         this.convertMatrix = matrix
         this.convertMatrixInvert = matrix.clone().invert()
         
-        /* var pos = panoPos1.map(e=>{ 
-            return e.clone().applyMatrix4(matrix)
-        })
-        console.log(pos) */
-
-
-        //挑选连续的两个点为向量来计算,如有123个漫游点,则选取12 23 31作为向量
-            
-        /* let index = 0
-        while (index < length) {
-            let pos11 = new THREE.Vector3().copy(panoPos1[index])
-            let pos12 = new THREE.Vector3().copy(panoPos1[(index + 1) % length])
-            let pos21 = new THREE.Vector3().copy(panoPos2[index])
-            let pos22 = new THREE.Vector3().copy(panoPos2[(index + 1) % length])
-            let vec1 = new THREE.Vector3().subVectors(pos11, pos12).setZ(0)
-            let vec2 = new THREE.Vector3().subVectors(pos21, pos22).setZ(0)
-            let diffLon = math.getAngle(vec1, vec2, 'z')
-            diffLons.push(diffLon)
-            diffLonAve += diffLon
-            index++
-        }
-
-        console.log('diffLons', diffLons)
-        diffLonAve /= length
-        console.log('diffLonAve', diffLonAve)
         
-        this.diffQuaternion = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0, 1, 0),  diffLonAve)
-        this.diffQuaternionInvert = this.diffQuaternion.clone().invert() */
 
     }
 

+ 2 - 1
src/utils/sync.js

@@ -2,7 +2,7 @@ import ConvertViews from '@/utils/ConvertViews'
 import browser from '@/utils/browser'
 
 const views = new ConvertViews()
-window.views = views
+
 let sourceApp = null,
     targetApp = null 
   
@@ -203,6 +203,7 @@ window.addEventListener('mouseup',(e)=>{
 
   
 export default {
+    views,
     get sourceInst() {
         return sourceApp
     },