xzw 2 年之前
父節點
當前提交
40396e413d
共有 6 個文件被更改,包括 405 次插入132951 次删除
  1. 0 132592
      public/static/lib/potree/potree.js
  2. 0 1
      public/static/lib/potree/potree.js.map
  3. 31 21
      src/pages/SViewer.vue
  4. 5 2
      src/pages/Viewer.vue
  5. 326 296
      src/utils/ConvertViews.js
  6. 43 39
      src/utils/sync.js

文件差異過大導致無法顯示
+ 0 - 132592
public/static/lib/potree/potree.js


文件差異過大導致無法顯示
+ 0 - 1
public/static/lib/potree/potree.js.map


+ 31 - 21
src/pages/SViewer.vue

@@ -28,11 +28,11 @@ import { http } from '@/utils/request'
 import Toast from '@/components/dialog/Toast'
 import browser from '@/utils/browser'
 import Calendar from '@/components/calendar/mobile.vue'
-import sync, { loadSourceScene, loadTargetScene } from '@/utils/sync'
+import sync, { loadSourceScene, loadTargetScene , setPanoWithBim} from '@/utils/sync'
 
 // 点位信息
 let lastFakeApp = null
-
+let panoData
 const showBimTips = ref(false)
 
 const showTips = ref(null)
@@ -57,9 +57,7 @@ const scenes = computed(() => {
     })
 })
 const sourceURL = computed(() => {
-    if (bimChecked.value) {
-        return `smart-bim.html?m=${project.value.bimData.bimOssFilePath}`
-    }
+     
     /*if (source.value.type < 2) {
         let pose = ''
         // 获取当前点位旋转值
@@ -76,11 +74,12 @@ const sourceURL = computed(() => {
         return `smart-kankan.html?m=${source.value.num}`//`smart-laser.html?m=${source.value.num}&dev`
     }*/ 
     
-    if(sourceFrame.value && (sourceFrame.value.contentWindow.app || sourceFrame.value.contentWindow.loaded)){
+    if(sourceFrame.value && (bimChecked.value || sourceFrame.value.contentWindow.app || sourceFrame.value.contentWindow.loaded)){
         sync.views.addViewInfo(sourceFrame.value.contentWindow)
     }
-    
-    if(source.value.type < 2) {
+    if(bimChecked.value){
+        return `smart-bim.html?m=${project.value.bimData.bimOssFilePath}`
+    }else if(source.value.type < 2) {
         return `smart-kankan.html?m=${source.value.num}`
     } else {
         return `smart-laser.html?m=${source.value.num}&dev`
@@ -92,27 +91,33 @@ const onLoadSource = () => {
         window.app = win
         
     let loaded = ()=>{
-        if (lastFakeApp) { 
-            sync.views.bindWithSameFakeType(lastFakeApp,win)   
-        }
-         
-        lastFakeApp = sync.views.createTempApp(sourceFrame.value.contentWindow); 
-    
+        if (lastFakeApp) {
+            if(bimChecked.value || lastFakeApp.sceneType == 'bim'){//->bim
+                sync.views.bindFakeWithBim(lastFakeApp, win, panoData) 
+            }else{
+                sync.views.bindWithSameFakeType(lastFakeApp,win) 
+            }
+            
+              
+        } 
+        lastFakeApp = sync.views.createTempApp(sourceFrame.value.contentWindow);  
     } 
 
-    console.log(source.value.type)
-    
-    if (source.value.type < 2) {
+     
+    if(bimChecked.value){//bim
+        win.sceneType = 'bim'
+        win.loaded.then(sdk => { 
+            loaded() 
+        }) 
+    }else if (source.value.type < 2) {
         win.sceneType = 'kankan'
         let sdk = win.app 
         sdk.Scene.on('loaded', () => {
             loaded() 
         }) 
-    }else{ 
-        debugger
+    }else{  
         win.sceneType = 'laser' 
-        win.loaded.then(sdk => {
-            debugger
+        win.loaded.then(sdk => { 
             loaded() 
         }) 
     }
@@ -229,6 +234,11 @@ onMounted(() => {
                 if (project.value.sceneList.length) {
                     source.value = project.value.sceneList[0]
                 }
+                if(response.data.panos){
+                    response.data.panos = JSON.parse(response.data.panos)
+                    panoData = response.data.panos  //convert with bim
+                }
+                
             } else {
                 showTips.value = response.message
             }

+ 5 - 2
src/pages/Viewer.vue

@@ -70,7 +70,7 @@ import browser from '@/utils/browser'
 import Toast from '@/components/dialog/Toast'
 import AppHeader from '@/components/header'
 import Calendar from '@/components/calendar'
-import sync, { loadSourceScene, loadTargetScene, setPanoWithBim, flyToP1P2} from '@/utils/sync'
+import sync, { beforeChangeURL, loadSourceScene, loadTargetScene, setPanoWithBim, flyToP1P2} from '@/utils/sync'
 
 // 是否BIM模式
 const showBim = ref(browser.urlHasValue('bim'))
@@ -108,10 +108,13 @@ const scenes = computed(() => {
     })
 })
 const sourceURL = computed(() => {
+
+    beforeChangeURL('source' ) 
+
     if (bimChecked.value && !dbsChecked.value) {
         return `smart-bim.html?m=${project.value.bimData.bimOssFilePath}`
     }
-
+       
     if (source.value.type < 2) {
         // 看看、看见场景
         return `smart-kankan.html?m=${source.value.num}&dev`

+ 326 - 296
src/utils/ConvertViews.js

@@ -14,16 +14,6 @@ export default class ConvertViews extends THREE.EventDispatcher{
     }
 
      
-    clear(o={}){
-        this.loaded = false;
-        this.sourceApp = null;
-        if(!o.dontClearTarget){
-            this.targetApp = null
-        }
-        
-        this.dispatchEvent({type:'clearBind-sameType'})
-        window.Log('clear done')
-    }
     /* 
         laser暂时做成这样: 全景模式时不跟踪pos,跟踪pano变化。点云模式时也跟踪pano变化,但移动时完全跟踪位置变化 ,所以会有左边marker在脚下,右边marker不在脚下的情况。
         
@@ -44,21 +34,31 @@ export default class ConvertViews extends THREE.EventDispatcher{
                 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, 
-            panos : app.sceneType == 'laser' ? getPanos(app.viewer.images360.panos) : getPanos(app.app.core.get('Player').model.panos.list) 
-            
+            sceneType : app.sceneType 
         }
-        
-        function getPanos(panos){ // only data
-            return panos.map(e=>{return {id:e.id, position:e.position, quaternion:e.quaternion}})
+        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){
@@ -87,11 +87,15 @@ export default class ConvertViews extends THREE.EventDispatcher{
                 lat : player.cameraControls.activeControl.lat,
                 zoomLevel : player.zoomLevel,
             }
+        }else{
+            viewInfo = {}
         }
         
-        viewInfo.position = cameraData.position
-        viewInfo.quaternion = cameraData.quaternion
-        viewInfo.fov = cameraData.fov
+        
+        for(let i in cameraData){
+            viewInfo[i] = cameraData[i]
+        }
+         
         
         app.fakeApp.viewInfo = viewInfo
         
@@ -102,13 +106,15 @@ export default class ConvertViews extends THREE.EventDispatcher{
         return app.sceneType == 'laser' ? app.viewer.images360.getPano(id) : app.app.core.get('Player').panos.index[id]
     } */
     
-    syncView(master, customer ){//补充一下 moveCamera的函数 
+    syncView(master, customer, convertInfo ){//同类型 相当于moveCamera的函数 
         let fakeApp = master.fakeApp;
+        convertInfo = convertInfo || this.convertInfo
         if(fakeApp.sceneType == 'laser'){
-            if(fakeApp.viewInfo.isAtPano || fakeApp.viewInfo.displayMode == 'showPanos'){ //转换朝向 
+            customer.Potree.settings.displayMode = fakeApp.viewInfo.displayMode
+            if(fakeApp.viewInfo.isAtPano || fakeApp.viewInfo.displayMode == 'showPanos'){ //不改变漫游点,仅转换朝向 
                 if( fakeApp.viewInfo.quaternionChanged){
              
-                    let diffQua = customer == this.targetApp ? this.diffQuaternion : this.diffQuaternionInvert
+                    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
@@ -121,11 +127,11 @@ export default class ConvertViews extends THREE.EventDispatcher{
                     }
                 }
             }else{//转换朝向和位置 
-                this.receive(fakeApp.viewInfo, customer ) 
+                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 ? -this.diffLon : this.diffLon)
+            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
             
@@ -141,24 +147,45 @@ export default class ConvertViews extends THREE.EventDispatcher{
     
     
     bindWithSameFakeType(sourceFakeApp, targetApp){//for mobile 实际只有一个场景,未分屏,和上一个场景相比
-        this.sourceApp = {sceneType: targetApp.sceneType,  fakeApp:sourceFakeApp} 
-        this.targetApp = targetApp
+        let sourceApp = {sceneType: sourceFakeApp.sceneType,  fakeApp:sourceFakeApp} 
+ 
         this.createTempApp(targetApp, true)
-        this.computeAveDiffLon(sourceFakeApp, targetApp.fakeApp)
-        this.sourceApp.sceneName = 'sourceApp'
-        this.targetApp.sceneName = 'targetApp'
         
+        let convertInfo = this.computeAveDiffLon(sourceFakeApp, targetApp.fakeApp)
         
-        if(this.sourceApp.sceneType == 'laser'){
-            this.computeShift() //因为有点云模式自由移动所以需要计算
-            
-        }
+        sourceApp.sceneName = 'sourceApp'
+        targetApp.sceneName = 'targetApp'
+         
         
-        this.syncView(this.sourceApp, this.targetApp)
+        if(sourceApp.sceneType == 'laser'){
+            let data = this.computeShift({sourceApp,targetApp}) //因为有点云模式自由移动所以需要计算
+            convertInfo.convertMatrix = data.convertMatrix
+            convertInfo.convertMatrixInvert = data.convertMatrixInvert
+        }
+        this.flyToPano(targetApp, sourceFakeApp.viewInfo.currentPano,{duration:0})
+        this.syncView(sourceApp, targetApp, convertInfo)
         
+        if(sourceApp.sceneType == 'laser'){
+            targetApp.viewer.mainViewport.view.applyToCamera(targetApp.viewer.mainViewport.camera)//使获得的cameraInfo正确
+        }else if(sourceApp.sceneType == 'kankan'){ 
+            targetApp.app.core.get('Player').cameraControls.activeControl.locked = false  //怎么刚加载时lock了
+            targetApp.app.core.get('Player').update()//cameraControls.activeControl.update() //使获得的cameraInfo正确
+        }        
     }
     
-    
+    flyToPano(app, panoId, o={}){
+        if(app.sceneType == 'laser'){
+            app.viewer.images360.flyToPano(Object.assign({},{ 
+                pano: app.viewer.images360.panos.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){ 
         
@@ -168,13 +195,17 @@ export default class ConvertViews extends THREE.EventDispatcher{
         this.createTempApp(sourceApp)
         this.createTempApp(targetApp)
         
-        this.computeAveDiffLon(sourceApp.fakeApp, targetApp.fakeApp)
+        this.convertInfo = this.computeAveDiffLon(sourceApp.fakeApp, targetApp.fakeApp)
          
         sourceApp.sceneName = 'sourceApp'
         targetApp.sceneName = 'targetApp'
         
-        if(sourceApp.sceneType == 'laser'){
-            this.computeShift() //因为有点云模式自由移动所以需要计算
+        if(sourceApp.sceneType == 'laser'){ 
+            {
+                let data = this.computeShift({sourceApp,targetApp}) //因为有点云模式自由移动所以需要计算
+                this.convertInfo.convertMatrix = data.convertMatrix
+                this.convertInfo.convertMatrixInvert = data.convertMatrixInvert
+            }
             //只监听左边
             let displayMode = (e)=>{
                 targetApp.Potree.settings.displayMode = e.mode
@@ -199,38 +230,14 @@ export default class ConvertViews extends THREE.EventDispatcher{
                     customer.viewer.images360.flyToPano({pano} )
                 }
                 master.viewer.images360.addEventListener('flyToPano',flyToPano)
-             
-                
-                
+              
                 var cameraMove = (e)=>{ 
                     if(master != this.masterApp || !customer.viewer )return
                     
                     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)
-                            let diffQua = master == this.sourceApp ? this.diffQuaternion : this.diffQuaternionInvert
-                            let quaternion = data.quaternion.premultiply(diffQua)
-                            let rotation = new THREE.Euler().setFromQuaternion(quaternion)  
-                            customer.viewer.mainViewport.view.rotation = rotation
-                            //console.log('cameraMove',customer == this.targetApp) 
-                        }
-                        if(master.Potree.settings.displayMode == 'showPanos' ){
-                            if(customer.viewer.mainViewport.camera.fov != master.viewer.mainViewport.camera.fov){
-                                customer.viewer.mainViewport.camera.fov = master.viewer.mainViewport.camera.fov
-                                customer.viewer.mainViewport.camera.updateProjectionMatrix()
-                            }
-                        }
-                    }else{//转换朝向和位置
-                        let data = this.getCameraData(master)
-                        this.receive(data, customer ) 
-                    }  */
-                                            
+                    this.syncView(master, customer) 
                 } 
                 master.viewer.addEventListener('camera_changed',cameraMove)
                 
@@ -258,29 +265,16 @@ export default class ConvertViews extends THREE.EventDispatcher{
                 
                 
                 var cameraMove = (e)=>{//暂时只有漫游模式
-                    if(!e.hasChanged.cameraChanged)return
+                    if(!e.hasChanged.cameraChanged || !customer.app || !customer.app.core)return
                     
                     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)
-                    } */
-                    
+                    this.syncView(master, customer) 
                 }
                 player1.on("update",cameraMove)
-                
-                
+                 
             }
             
-           
-        
-        
-        
+            
             
             let changeMaster = ()=>{
                 this.masterApp = master  //主控方。只有主控方能控制被控方。鼠标操作过mousedown mousewheel等才能认定为主控方
@@ -325,8 +319,7 @@ export default class ConvertViews extends THREE.EventDispatcher{
                 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
@@ -349,15 +342,137 @@ export default class ConvertViews extends THREE.EventDispatcher{
     
     
     
+    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和其他类型互转
+        if(!panoData)return
+    
+    
+        let sourceApp = {sceneType: sourceFakeApp.sceneType,  fakeApp:sourceFakeApp} 
+    
+        this.createTempApp(targetApp)
+        let {sourcePano, targetPano} = this.bimGetPanoData(sourceApp, targetApp, panoData) 
+        
+        let convertAxis = sourceApp.sceneType == 'kankan' ? 'YupToZup' : targetApp.sceneType == 'kankan' ? 'ZupToYup' : null
+             
+        let convertInfo = this.computeShift({sourcePano, targetPano, convertAxis})  
+       
+        console.log('convertInfo', convertInfo, sourcePano, targetPano)
+         
+        
+        if(targetApp.sceneType == 'bim'){
+            bimViewer = targetApp.viewer
+            bimViewer.getViewer().setTransitionAnimationState(false)
+            targetApp.CLOUD.GlobalData.WalkRotationSpeed = -0.2 //反向一下
+        }
+        
+        //this.syncView(sourceApp, targetApp)
+        if(targetApp.sceneType == 'bim' || this.ifCanChangePos(targetApp)){
+            
+            this.syncPosRot(sourceFakeApp.viewInfo, targetApp, convertInfo) 
+            
+        }else if(targetApp.sceneType == 'laser' ){
+            setTimeout(()=>{//一开始虽然是点云模式,但过后又变成showPano所以是没加载好
+                
+                this.syncPosRot(sourceFakeApp.viewInfo, targetApp, convertInfo) 
+            },1000)
+        
+        
+        }else{//bim -> 固定点位
+           
+            let data = this.getTranPosData(sourceFakeApp.viewInfo, convertInfo ) 
+  
+            let panos = targetApp.fakeApp.panos;
+            
+            let panos2 = panos.sort((a,b)=>{ 
+                return data.position.distanceToSquared(a.position) - data.position.distanceToSquared(b.position)
+            })
+            let dir = new THREE.Vector3().subVectors( data.target, data.position )
+            console.log('dir', dir)
+            let prop = { duration:0,}
+            if(targetApp.sceneType == 'laser'){ 
+                targetApp.viewer.mainViewport.view.direction = dir  
+            }else{
+                let player = targetApp.app.core.get('Player') 
+                console.log('nearest:', panos2[0].id)
+                prop.aimDuration = 0                   
+                prop.lookAtPoint = new THREE.Vector3().addVectors(panos2[0].position, dir)
+
+            } 
+            this.flyToPano(targetApp, panos2[0].id, prop)     
+             
+        }
+        
+    }
+    
+    
+     
      
-    bindWithBim(sourceApp, targetApp,   sourcePano, targetPano  ) {
+    bindWithBim(sourceApp, targetApp, panoData ) {
         //if (!this.player1.model.panos.list.length || !this.player2.model.panos.list.length) return
         
         if(this.loaded || !targetApp ) return 
         let needBindEvent = !this.targetApp // 若targetApp存在表明targetApp的dom未换掉,事件还存在
+        this.createTempApp(sourceApp)
+        this.createTempApp(targetApp)
+        let {sourcePano, targetPano} = this.bimGetPanoData(sourceApp, targetApp, panoData)
+          
         this.sourceApp = sourceApp
         this.targetApp = targetApp
-        let data = this.getCameraData(sourceApp)
+        
         let modelSize = new THREE.Vector3
         bimViewer = this.bimViewer = targetApp.viewer 
         let modelBound = bimViewer.getViewer().modelManager.boundingBox
@@ -366,11 +481,7 @@ export default class ConvertViews extends THREE.EventDispatcher{
         bimViewer.setFlySpeedRate(THREE.MathUtils.clamp(  modelSize.length() / 10, 1, 6)) //会被限制
         //bimViewer.getViewer().setWalkSpeedRate(2)
         
-        let camera = bimViewer.getViewer().camera
-        if(camera.fov != data.fov){
-            camera.fov = data.fov
-            camera.updateProjectionMatrix()
-        }
+        
         
         this.sourceDom = sourceApp.sceneType == 'laser' ? this.sourceApp.viewer.inputHandler.domElement : this.sourceApp.app.core.get('Player').domElement
        
@@ -378,10 +489,14 @@ export default class ConvertViews extends THREE.EventDispatcher{
             bimViewer.getViewer().setTransitionAnimationState(false) //setCameraStatus瞬间变化相机 ,or setCameraAnimation?
             
             
-            this.needConvertAxis = sourceApp.sceneType == 'kankan' && targetApp.sceneType == 'bim'// Y朝上需要转换
+            var convertAxis = sourceApp.sceneType == 'kankan' && targetApp.sceneType == 'bim' && 'YupToZup'// Y朝上需要转换
             
             this.lastCamStatus = bimViewer.getCameraStatus()
-            this.computeShift(sourcePano, targetPano)
+            
+            this.convertInfo = this.computeShift({sourcePano, targetPano, convertAxis})
+            
+            
+            
             bimViewer.addEventListener('Rendered', (e)=>{//反向改变左侧相机
                  
                 let info = bimViewer.getCameraStatus() 
@@ -390,52 +505,80 @@ export default class ConvertViews extends THREE.EventDispatcher{
                     || !math.closeTo(this.lastCamStatus.fov, info.fov)
                 
                 if(poseChanged){ 
-                    if(this.leftCanChangePos()){
+                    if(this.ifCanChangePos(this.sourceApp)){
                         this.send(info)
                         this.lastCamStatus = info 
                     }  
                 } 
                 
             })  
-            if(sourceApp.sceneType == 'laser'){
-                
-                sourceApp.viewer.addEventListener('camera_changed', e => {
-                    targetApp && this.receive(this.getCameraData(sourceApp))
-                })
-                //master.viewer.images360.isAtPano() || master.Potree.settings.displayMode == 'showPanos'
-                /* if(this.lastBimStatus){
-                    this.lastBimStatus
-                    let pano 
-                    if(this.lastBimStatus.panoId != void 0) pano = this.sourceApp.viewer.images360.panos[this.lastBimStatus.panoId]
-                    this.sourceApp.viewer.dispatchEvent({type:'camera_changed',changeInfo:{quaternionChanged:true},viewport:this.sourceApp.viewer.mainViewport }) //朝向位置同步
-                    
-                    pano && customer.viewer.images360.flyToPano({pano, duration: 0 }) 
-                } */
-                
+            
+            if(needBindEvent){
+                this.bindCamEvent()  
+            }else{//替换的左侧的,需要使左侧和右侧同步, 其实是左侧要和上一个左侧先同步,再让右侧和左侧同步
+                 
+                this.bindWithSameFakeType(this.lastFakeApp, sourceApp)
+                 
+            }
+            
+            {
                 
-            }else if(sourceApp.sceneType == 'kankan'){
-                let player = this.sourceApp.app.core.get('Player')
-                //this.sourceDom = player.domElement 
-                var cameraMove = (e)=>{//暂时只有漫游模式
-                    if(!e.hasChanged.cameraChanged2)return
-                    this.receive(this.getCameraData(sourceApp)) 
-                }
-                player.on("update",cameraMove)
+                let cameraMove
+                if(sourceApp.sceneType == 'laser'){ 
+                    cameraMove = e => {
+                        targetApp && this.syncPosRot(this.getCameraData(sourceApp))
+                    }   
+                    sourceApp.viewer.addEventListener('camera_changed', cameraMove)
+                }else if(sourceApp.sceneType == 'kankan'){
+                    var player = this.sourceApp.app.core.get('Player')
+                    //this.sourceDom = player.domElement 
+                    cameraMove = (e)=>{//暂时只有漫游模式
+                        if(!e.hasChanged.cameraChanged2)return
+                        //console.log('cameraMove', this.getCameraData(sourceApp)) 
+                        this.syncPosRot(this.getCameraData(sourceApp)) 
+                    }
+                    player.on("update",cameraMove) 
+                } 
+                 
+                let dispose = ()=>{ 
+                    if(sourceApp.sceneType == 'laser'){
+                        //if(!sourceApp.viewer || !sourceApp.viewer.images360)return
+                        sourceApp.viewer.removeEventListener('camera_changed', cameraMove)
+                    }else{
+                        //if(!sourceApp.app || !sourceApp.app.core)return
+                        player.off("update",cameraMove) 
+                    } 
+                    this.removeEventListener('clearBind-sameType',dispose)
+                } 
+                this.addEventListener('clearBind-sameType',dispose) 
             }
             
             /* bimViewer.addEventListener(targetApp.Glodon.Bimface.Viewer.Viewer3DEvent.ViewAdded,
                 ()=>{
                     this.loaded = true
                     if(this.firstData){
-                        this.receive(this.firstData)
+                        this.syncPosRot(this.firstData)
                     }
                 }
             ) */
             
-            needBindEvent && this.bindCamEvent() 
+            
+            
+            let data = this.getCameraData(sourceApp)  
+            this.syncPosRot(data)
             this.loaded = true
-            this.receive(data)
         }else{
+            //分屏 不同步
+            
+            let data = this.getCameraData(sourceApp)
+            let camera = bimViewer.getViewer().camera
+            if(camera.fov != data.fov){
+                camera.fov = data.fov
+                camera.updateProjectionMatrix()
+            }
+            
+            
+            
             //补充control
             
             bimViewer.getViewer().animator.setDuration(60)//滚轮缩放时长,原先:1000
@@ -484,16 +627,11 @@ export default class ConvertViews extends THREE.EventDispatcher{
              
             //bimViewer.viewer.getViewer().editorManager.userInputEditor.enable = true//这句近似将control切换成orbit
             
-        }
-         
-        
-        
-        
-          
+        }    
     }
     
-    leftCanChangePos(){
-        return this.sourceApp.sceneType == 'laser' && this.sourceApp.Potree.settings.displayMode != 'showPanos'
+    ifCanChangePos(app){
+        return app.sceneType == 'laser' && app.Potree.settings.displayMode != 'showPanos'   //app.fakeApp.viewInfo.displayMode != 'showPanos'
     }
     
     
@@ -594,16 +732,17 @@ export default class ConvertViews extends THREE.EventDispatcher{
         app.viewer.mainViewport.view.lookAt(data.target)
     }
     
-    receive(data, customer){
-        
+    
+    
+    syncPosRot(data, customer, convertInfo ){//同步 自由位置和朝向(不被漫游点束缚时)
+        /* 
         if(!this.loaded){
             return this.firstData = data
-        }
-        /* if(this.isMaster){
-            return //正在操作当前,不接收 
         } */
-        
-        let position = new THREE.Vector3, target = new THREE.Vector3
+        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)
@@ -613,30 +752,20 @@ export default class ConvertViews extends THREE.EventDispatcher{
         
         if(!data.target){
             if(data.quaternion){ 
-                /* if(this.needConvertAxis){
-                    data.quaternion = math.convertQuaternion.YupToZup(data.quaternion)
-                } */
                 let dir = new THREE.Vector3(0, 0, -1).applyQuaternion(data.quaternion)
-                //dir.applyQuaternion(this.diffQuaternion)/////!
-                 
-                
                 target.copy(position).add(dir) 
             }
-        }else{
-            if(this.needConvertAxis){
-                target = math.convertVector.YupToZup(target)
-            }else{
-                target.copy(data.target)
-            } 
+        }else{ 
+            target.copy(data.target) 
         }
         
-        if(this.needConvertAxis){
-            position = math.convertVector.YupToZup(position)
-            target = math.convertVector.YupToZup(target)
+        if(convertInfo.convertAxis){
+            position = math.convertVector[convertInfo.convertAxis](position)
+            target = math.convertVector[convertInfo.convertAxis](target)
         }
 
-        position.applyMatrix4(this.convertMatrix)
-        target.applyMatrix4(this.convertMatrix)
+        position.applyMatrix4(convertInfo.convertMatrix)
+        target.applyMatrix4(convertInfo.convertMatrix) */
 
         if(customer && customer.sceneType == 'laser'){
             this.laserSyncView(customer, {position,target})
@@ -658,41 +787,25 @@ export default class ConvertViews extends THREE.EventDispatcher{
                 camera.updateProjectionMatrix()
             }
 
-            //fov, near,  far
-            /*   aspect: 0.7879440258342304
-                coordinateSystem: "world"
-                far: 11485.989363357028
-                fov: 45
-                name: "persp"
-                near: 1.1852000000072447
-                position: {x: -1130.0432094639486, y: -6058.569138159733, z: 2265.9284566100446}
-                target: {x: 310.3968263091223, y: -66.0595010237127, z: 1477.7045866099475}
-                up: {x: 0, y: 1.534753124827774e-13, z: 1}
-                version: 1
-                zoom: 0 */
-
         }
 
     }
 
 
     send(info){ 
-        let camera = this.bimViewer.getViewer().camera
-        
-        let data = { 
-            position : new THREE.Vector3().copy(info.position).applyMatrix4(this.convertMatrixInvert),
+        //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.convertMatrixInvert),
+            target : new THREE.Vector3().copy(info.target).applyMatrix4(this.convertInfo.convertMatrixInvert),
         }  
         
-        if(this.needConvertAxis){
-            data.position = math.convertVector.ZupToYup(data.position)
-            data.target = math.convertVector.ZupToYup(data.target)
-        }
-        /* this.dispatchEvent({
-            type: 'sendCameraData',
-            data
-        }) */
+        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点云模式才能接收到
     } 
 
@@ -709,25 +822,7 @@ export default class ConvertViews extends THREE.EventDispatcher{
         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
-            })
-            panoPos2 = this.targetApp.viewer.images360.panos.map(e=>{
-                return e.position
-            }) 
              
-        }else{
-            panoPos1 = this.sourceApp.app.core.get('Player').model.panos.list.map(e=>{
-                return e.position
-            })
-            panoPos2 = this.targetApp.app.core.get('Player').model.panos.list.map(e=>{
-                return e.position
-            })  
-        } */
-        
-        
         length = panoPos1.length
 
         //挑选连续的两个点为向量来计算,如有123个漫游点,则选取12 23 31作为向量
@@ -750,33 +845,35 @@ export default class ConvertViews extends THREE.EventDispatcher{
         diffLonAve /= length
         console.log('diffLonAve', diffLonAve)
         
-        this.diffLon = diffLonAve
-        this.diffQuaternion = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0, 1, 0), this.diffLon)
-        this.diffQuaternionInvert = this.diffQuaternion.clone().invert()
-        
+        let diffQua = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0, 1, 0), diffLonAve) 
         
+        return {
+            diffLon : diffLonAve,
+            diffQua  ,
+            diffQuaInvert : diffQua.clone().invert() 
+        } 
         
     }
 
-    computeShift(sourcePano, targetPano) { //获取两个场景的旋转和位移偏差值
+    computeShift(o={}/* sourcePano, targetPano */) { //获取两个场景的旋转和位移偏差值
         //需要点的个数>1, 且两个场景点一一对应,位置接近且顺序一致
         
         let panoPos1, panoPos2
          
-        if(this.sourceApp.sceneType == this.targetApp.sceneType){
+        if(o.sourceApp && o.targetApp && o.sourceApp.sceneType == o.targetApp.sceneType){
             var angle = this.diffLon; //直接使用 更精准
-            panoPos1 = this.sourceApp.fakeApp.panos.map(e=>{
+            panoPos1 = o.sourceApp.fakeApp.panos.map(e=>{
                 return e.position
             })
-            panoPos2 = this.targetApp.fakeApp.panos.map(e=>{
+            panoPos2 = o.targetApp.fakeApp.panos.map(e=>{
                 return e.position
             }) 
         }else{
-            panoPos1 = sourcePano.map(e=>e.position) //pick两个点来计算
-            panoPos2 = targetPano.map(e=>e.position)
-        
-            if(this.needConvertAxis){
-                panoPos1 = panoPos1.map(e=>math.convertVector.YupToZup(e))
+            panoPos1 = o.sourcePano.map(e=>e.position) //pick两个点来计算
+            panoPos2 = o.targetPano.map(e=>e.position)
+             
+            if(o.convertAxis){
+                panoPos1 = panoPos1.map(e=>math.convertVector[o.convertAxis](e))
             }
             var vec1 = new THREE.Vector3().subVectors(panoPos1[0], panoPos1[1]) //旧的向量
             var vec2 = new THREE.Vector3().subVectors(panoPos2[0], panoPos2[1])//新的向量
@@ -794,11 +891,8 @@ export default class ConvertViews extends THREE.EventDispatcher{
         matrix.premultiply(moveBackMatrix)//再移动到realPosition的点0处
 
 
-
-        this.convertMatrix = matrix
-        this.convertMatrixInvert = matrix.clone().invert()
-        
-        
+        return { convertMatrix:  matrix, convertMatrixInvert:matrix.clone().invert(), convertAxis:o.convertAxis}
+          
 
     }
 
@@ -819,90 +913,26 @@ export default class ConvertViews extends THREE.EventDispatcher{
     }
 
 
-
-
-
-    /* applyDiff(app) {
-        //sourcePlayer -> targetPlayer
-        if (!this.player1 || !this.player2 || this.targetApp.config.num == this.sourceApp.config.num) return //场景码相同的话返回
-        if (this.player1.mode != this.player2.mode) return
-
-        let player1, player2, quaternion //player1为要改变的, player2是参照
-        if (app == this.sourceApp) {
-            player1 = this.player1
-            player2 = this.player2
-            quaternion = this.diffQuaternion
-        } else {
-            player1 = this.player2
-            player2 = this.player1
-            quaternion = this.diffQuaternionInvert
-        }
-
-        let control1 = player1.cameraControls.activeControl
-        let control2 = player2.cameraControls.activeControl
-        //if(!control1 || !control2)return
-
-        player1.quaternion.copy(player2.quaternion).premultiply(quaternion)
-
-        if (player1.mode == 'panorama') {
-            //平移
-            let dir = new THREE.Vector3().subVectors(control2.target, player2.position)
-            dir.applyQuaternion(quaternion)
-            let target1 = new THREE.Vector3().addVectors(player1.position, dir)
-            control1.lookAt(target1)
-            control1.target.copy(target1)
-        } else if (control2) {
-            //修改target,保证target在panos之间的相对位置一样
-            //console.log('target', control2.target.clone())
-            //console.log('position', control2.target.clone())
-            let vec = new THREE.Vector3().subVectors(control2.target, player2.model.panos.list[0].position)
-            vec.applyQuaternion(quaternion)
-            control1.target.addVectors(player1.model.panos.list[0].position, vec)
-            player1.target.copy(control1.target)
-            //修改position,保证方向一样
-            let dir = new THREE.Vector3().subVectors(control2.camera.position , control2.target)
-            dir.applyQuaternion(quaternion)
-            player1.position = new THREE.Vector3().addVectors(control1.target, dir)
-
-            control1.camera.position.copy(player1.position)
-        }
-        control1.camera.quaternion.copy(player1.quaternion)
-    } */
-
-    /* applyDiff(app, data) {
-        //sourcePlayer -> targetPlayer
-
-        let quaternion
-        if (data.quaternion) {
-            quaternion = new THREE.Quaternion().copy(data.quaternion)
-            data.quaternion = quaternion
-        } else if (data.info && data.info.quaternion) {
-            //飞出
-            quaternion = new THREE.Quaternion(data.info.quaternion._x, data.info.quaternion._y, data.info.quaternion._z, data.info.quaternion._w)
-            data.info.quaternion = quaternion
-            //let radius = data.info.position.distanceTo(data.info.target)
-        }
-        if (!quaternion) return
-
-        if (app == this.sourceApp) {
-            quaternion.premultiply(this.diffQuaternionInvert)
-        } else {
-            quaternion.premultiply(this.diffQuaternion)
-        }
-
-        if (data.info && data.info.quaternion) {
-            //飞出
-            let dir = new THREE.Vector3().subVectors(data.info.position, data.info.target)
-            dir.applyQuaternion(app == this.sourceApp ? this.diffQuaternionInvert : this.diffQuaternion)
-            data.info.position = new THREE.Vector3().addVectors(data.info.target, dir)
+    clear(o={}){
+        this.loaded = false;
+        
+        
+        
+        if(o.dontClearTarget){
+            if(this.sourceApp){
+                this.lastFakeApp = this.sourceApp.fakeApp //记住当前左屏
+                this.addViewInfo(this.sourceApp)
+            }
+        }else{ 
+            this.targetApp = null
+            this.lastFakeApp = null
         }
-
-         
-
-        //先不管飞出后的位置平移
-
-        //位置参照第一个漫游点。保持相机相对第一个漫游点的位移和
-    } */
+        
+        this.sourceApp = null;
+        this.dispatchEvent({type:'clearBind-sameType'})
+        window.Log('clear done')
+    }
+ 
 }
 
 

+ 43 - 39
src/utils/sync.js

@@ -8,7 +8,7 @@ let sourceApp = null,
   
 const isEdit = browser.urlHasValue('adjust')
 
-let panoData = {p1:{id:0},p2:{id:1}}//默认
+let panoData //= {p1:{id:0},p2:{id:1}}//默认
 let targetPano /* = isEdit ? null : [//targetPano
                         {position: new THREE.Vector3( -5.313605730801787,  -4.889868407960505,  1.237447893355817),},
                         {position: new THREE.Vector3( -5.337403524084278,  -2.5012228235167737, 1.2808838933558175),} 
@@ -16,8 +16,7 @@ let targetPano /* = isEdit ? null : [//targetPano
 export function setPanoWithBim(data){
     if(!isEdit){
         panoData = data 
-        targetPano = [{position:new THREE.Vector3().copy(data.p1.position)},{position:new THREE.Vector3().copy(data.p2.position)}]
-    }  
+     }  
 }
 
 export function flyToP1P2(data){
@@ -34,36 +33,26 @@ export function flyToP1P2(data){
     }
 }
 
-
+/* const getSourcePanos = (sourceApp)=>{
+    let sourcePanos
+    if(sourceApp.sceneType == 'laser'){  
+        sourcePanos = [sourceApp.viewer.images360.panos[panoData.p1.id], sourceApp.viewer.images360.panos[panoData.p2.id]], //sourceApp.viewer.images360.panos.slice(0, 2),
+          
+        sourceApp.Potree.settings.rotAroundPoint = false
+        
+    }else if(sourceApp.sceneType == 'kankan'){ 
+        sourcePanos = [sourceApp.app.core.get('Player').model.panos.index[panoData.p1.id], sourceApp.app.core.get('Player').model.panos.index[panoData.p2.id]],//sourceApp.app.core.get('Player').model.panos.list.slice(0, 2), 
+        
+    }
+    return sourcePanos
+} */
  
 const initConvertView = (isSwitchScene) => {  
 
     if (sourceApp && targetApp) {
-        if(targetApp.sceneType == 'bim'){
-              
-            if(sourceApp.sceneType == 'laser'){ 
-                views.bindWithBim(
-                    sourceApp,
-                    targetApp, 
-                    [sourceApp.viewer.images360.panos[panoData.p1.id], sourceApp.viewer.images360.panos[panoData.p2.id]], //sourceApp.viewer.images360.panos.slice(0, 2),
-                    
-                    targetPano
-                     
-                )
-                sourceApp.Potree.settings.rotAroundPoint = false
-                
-            }else if(sourceApp.sceneType == 'kankan'){
-                
-                views.bindWithBim(
-                    sourceApp,
-                    targetApp,
-                    [sourceApp.app.core.get('Player').model.panos.index[panoData.p1.id], sourceApp.app.core.get('Player').model.panos.index[panoData.p2.id]],//sourceApp.app.core.get('Player').model.panos.list.slice(0, 2), 
-                    targetPano,
-                     
-                )
-                
-                
-            }
+        if(targetApp.sceneType == 'bim'){  
+            views.bindWithBim( sourceApp, targetApp, panoData/* getSourcePanos(sourceApp),  targetPano */) 
+            
         }else if(sourceApp.sceneType == targetApp.sceneType){
             
             views.bindWithSameType(sourceApp,targetApp, isSwitchScene)
@@ -72,16 +61,36 @@ const initConvertView = (isSwitchScene) => {
             
     }
 }
+
+export function singleConvert(lastFakeApp, targetApp ){//单屏转换
+
+    if(targetApp.sceneType == 'bim'){
+         
+        views.fakeWithBim(lastFakeApp, targetApp, getSourcePanos(sourceApp), targetPano)
+    } 
+    
+}
+
+let isSwitchScene
+
+ 
+export function beforeChangeURL(which  ){
+    //if (views.loaded ) {
+        isSwitchScene = true
+        views.clear({ dontClearTarget: targetApp && targetApp.sceneType == 'bim' })
+    //} 
+}
+
 /**
  * 左屏加载
  * @param {String} type kankan|laser
  */
 export function loadSourceScene(sourceFrame,type) {
-    let isSwitchScene 
-    if (views.loaded ) {
+     
+    /* if (views.loaded ) {
         isSwitchScene = true
         views.clear({ dontClearTarget: targetApp.sceneType == 'bim' })
-    }
+    } */
     
     Log('loadSourceScene, ' + type)
     sourceApp = window.app1 = null 
@@ -151,13 +160,7 @@ export function loadTargetScene(targetFrame, type, mode) {
             loaded()
         }) 
         
-    }        
-    
-    
-    
-    
-    
-     
+    }     
 
 }
 
@@ -212,6 +215,7 @@ export default {
     get targetInst() {
         return targetApp
     },
+    
 }
 
 /*