xzw 3 rokov pred
rodič
commit
67ef090531
2 zmenil súbory, kde vykonal 238 pridanie a 97 odobranie
  1. 166 56
      src/utils/ConvertViews.js
  2. 72 41
      src/utils/sync.js

+ 166 - 56
src/utils/ConvertViews.js

@@ -19,7 +19,9 @@ export default class ConvertViews extends THREE.EventDispatcher{
         this.sourceApp = null;
         if(!o.dontClearTarget){
             this.targetApp = null
-        } 
+        }
+
+        this.dispatchEvent({type:'clearBind-sameType'})
     }
     /* 
         laser暂时做成这样: 全景模式时不跟踪pos,跟踪pano变化。点云模式时也跟踪pano变化,但移动时完全跟踪位置变化 ,所以会有左边marker在脚下,右边marker不在脚下的情况。
@@ -27,13 +29,21 @@ export default class ConvertViews extends THREE.EventDispatcher{
     */
     
     getCameraData(app){ 
-        let camera = app.viewer.mainViewport.camera
-        return {
-            position: camera.position.clone(),
-            quaternion: camera.quaternion.clone(),
-            fov: camera.fov,
-        }
-         
+        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,
+            }
+        }     
     }
     
     bindWithSameType(sourceApp,targetApp){ 
@@ -44,23 +54,32 @@ export default class ConvertViews extends THREE.EventDispatcher{
         this.diffQuaternion = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0, 1, 0), this.diffLon)
         this.diffQuaternionInvert = this.diffQuaternion.clone().invert()
        
-        this.computeShift()
+       
+        
         
         if(sourceApp.sceneType == 'laser'){
+            this.computeShift()
+            
             sourceApp.viewer.images360.addEventListener('endChangeMode',e=>{//只监听左边
                 targetApp.Potree.settings.displayMode = e.mode
             })
-
-            let bind = (master, customer)=>{ //相互都能带动对方
-                let flyToPano = (e)=>{//同步点位
+        }
+        
+        let bind = (master, customer)=>{ //相互都能带动对方
+            if(sourceApp.sceneType == 'laser'){
+                
+                var flyToPano = (e)=>{//同步点位
+                    if(master != this.masterApp )return
                     customer.viewer.images360.flyToPano({pano: customer.viewer.images360.panos[e.toPano.pano.id]} )
                 }
                 master.viewer.images360.addEventListener('flyToPano',flyToPano)
-                 
-                let cameraMove = (e)=>{ 
+             
+                
+                
+                var cameraMove = (e)=>{ 
                     if(master != this.masterApp )return
                     
-                    if(master.Potree.settings.displayMode == 'showPanos'){ //转换朝向 
+                    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
@@ -69,6 +88,12 @@ export default class ConvertViews extends THREE.EventDispatcher{
                             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 ) 
@@ -77,46 +102,102 @@ export default class ConvertViews extends THREE.EventDispatcher{
                 } 
                 master.viewer.addEventListener('camera_changed',cameraMove)
                 
-                let changeMaster = ()=>{
-                    this.masterApp = master
+                
+                var dragEnd = (e)=>{
+                    if(customer.viewer.inputHandler.drag){
+                        customer.viewer.inputHandler.onMouseUp(e) //从一侧拖拽到另一侧松开时,需要执行原先一侧的mouseup
+                    }
                 }
-                let dom = master.viewer.inputHandler.domElement
-                dom.addEventListener('mousedown',changeMaster)
-                dom.addEventListener('mousewheel',changeMaster)
-                this.addEventListener('clearBind-sameType',()=>{
-                    master.viewer.images360.removeEventListener('flyToPano',flyToPano)
-                    master.viewer.removeEventListener('camera_changed',cameraMove)
-                    dom.removeEventListener('mousedown',changeMaster)
-                    dom.removeEventListener('mousewheel',changeMaster)
-                })
+                master.addEventListener('mouseup',dragEnd)
+                    
+            }else if(sourceApp.sceneType == 'kankan'){
+                
+                
+                var player1 = master.app.core.get('Player')
+                var player2 = customer.app.core.get('Player')
+                var flyToPano = (e)=>{//同步点位
+                    if(master != this.masterApp )return
+                    player2.flyToPano({pano: player2.model.panos.index[e.panoId]} )
+                }
+                player1.on("flying.started",flyToPano)
+                
+                
+                var cameraMove = (e)=>{//暂时只有漫游模式
+                    if(!e.hasChanged.cameraChanged)return
+                    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)
                 
                 
             }
             
-            bind(sourceApp, targetApp) 
-            bind(targetApp, sourceApp) 
+           
+        
+        
+        
+            
+            let changeMaster = ()=>{
+                this.masterApp = master  //主控方。只有主控方能控制被控方。鼠标操作过mousedown mousewheel等才能认定为主控方
+            }
+            //let dom = sourceApp.sceneType == 'laser' ? master.viewer.inputHandler.domElement : player1.domElement
+            master.addEventListener('mousedown',changeMaster)
+            master.addEventListener('mousewheel',changeMaster)
+            
+            
+            let dispose = ()=>{
+                if(sourceApp.sceneType == 'laser'){
+                    if(!master.viewer)return //master已被替换成别的类型的场景
+                    master.viewer.images360.removeEventListener('flyToPano',flyToPano)
+                    master.viewer.removeEventListener('camera_changed',cameraMove)
+                }else if(sourceApp.sceneType == 'kankan'){
+                    player1.off("flying.started",flyToPano)
+                    player1.off("update",cameraMove)
+                }
+                
+                master.removeEventListener('mousedown',changeMaster)
+                master.removeEventListener('mousewheel',changeMaster)
+                master.removeEventListener('mouseup',dragEnd)
+                this.removeEventListener('clearBind-sameType',dispose)
+            } 
+            this.addEventListener('clearBind-sameType',dispose)
             
             
         }
+        
+        bind(sourceApp, targetApp) 
+        bind(targetApp, sourceApp) 
+        
+        
+        
+         
+        
+        
         this.loaded = true
     }
     
      
-    bindWithBim(sourceApp, targetApp,   sourcePano, targetPano, cameraData  ) {
+    bindWithBim(sourceApp, targetApp,   sourcePano, targetPano  ) {
         //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.sourceApp = sourceApp
         this.targetApp = targetApp
-        this.sourceDom = this.sourceApp.viewer.inputHandler.    
+        
        
         bimViewer = this.bimViewer = targetApp.viewer 
         
         this.needConvertAxis = sourceApp.sceneType == 'kankan' && targetApp.sceneType == 'bim'// Y朝上需要转换
         
         this.lastCamStatus = bimViewer.getCameraStatus()
-        this.computeShift(sourcePano)
+        this.computeShift(sourcePano, targetPano)
         
         bimViewer.setNavigationMode(targetApp.Glodon.Bimface.Viewer.NavigationMode3D.Walk)
         bimViewer.setFlySpeedRate(5)
@@ -128,18 +209,29 @@ export default class ConvertViews extends THREE.EventDispatcher{
                 || !math.closeTo(this.lastCamStatus.target, info.target)
                 || !math.closeTo(this.lastCamStatus.fov, info.fov)
             
-            if(poseChanged){
-                if(sourceApp.canChangePos()){
+            if(poseChanged){ 
+                if(this.leftCanChangePos()){
                     this.send(info)
                     this.lastCamStatus = info 
                 }  
             } 
             
         })  
+        if(sourceApp.sceneType == 'laser'){
+            this.sourceDom = this.sourceApp.viewer.inputHandler.domElement  
+            sourceApp.viewer.addEventListener('camera_changed', e => {
+                targetApp && this.receive(this.getCameraData(sourceApp))
+            })
+        }else if(sourceApp.sceneType == 'kankan'){
+            let player = this.sourceApp.app.core.get('Player')
+            this.sourceDom = player.domElement 
+            var cameraMove = (e)=>{//暂时只有漫游模式
+                if(!e.hasChanged.cameraChanged)return
+                this.receive(this.getCameraData(sourceApp)) 
+            }
+            player.on("update",cameraMove)
+        }
         
-        sourceApp.viewer.addEventListener('camera_changed', e => {
-            targetApp && this.receive(this.getCameraData(sourceApp))
-        })
         /* bimViewer.addEventListener(targetApp.Glodon.Bimface.Viewer.Viewer3DEvent.ViewAdded,
             ()=>{
                 this.loaded = true
@@ -149,12 +241,14 @@ export default class ConvertViews extends THREE.EventDispatcher{
             }
         ) */
         this.loaded = true
-        this.receive(cameraData)
+        this.receive(this.getCameraData(sourceApp))
         needBindEvent && this.bindCamEvent() 
           
     }
-
-
+    
+    leftCanChangePos(){
+        return this.sourceApp.sceneType == 'laser' && this.sourceApp.Potree.settings.displayMode != 'showPanos'
+    }
 
  
     bindCamEvent(){//传递到另一边的dom 
@@ -164,14 +258,23 @@ export default class ConvertViews extends THREE.EventDispatcher{
         /* 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: 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, 
@@ -180,7 +283,7 @@ export default class ConvertViews extends THREE.EventDispatcher{
             
         }  
         
-        let dom1 = this.targetApp.getDomElement() 
+        
         //let pointerDownPos = new THREE.Vector2
         dom1.addEventListener('mousedown',(e)=>{
             let event = getEvent('mousedown', e)
@@ -192,9 +295,17 @@ export default class ConvertViews extends THREE.EventDispatcher{
             this.sourceApp && this.sourceDom.dispatchEvent(event)  
         })
         dom1.addEventListener('mouseup',(e)=>{  
+            if(!this.sourceApp)return
             let event = getEvent('mouseup', e)
             event.unableClick = true //最好禁止右侧点击行走。否则和点击效果冲突
-            this.sourceApp && this.sourceApp.dispatchEvent(event)   //mouseup 在laser中加在window上的 
+            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)
@@ -208,7 +319,6 @@ export default class ConvertViews extends THREE.EventDispatcher{
         dom1.addEventListener('mouseout',stop)
         dom1.addEventListener('mouseover',stop)
     
-        
     }
 
 
@@ -271,13 +381,11 @@ export default class ConvertViews extends THREE.EventDispatcher{
                 //前三个缺一不可  
                 fov: data.fov ,      //fov 用setCameraStatus 无效
             }
-            
-            
              
-            this.viewer.setCameraStatus(msg)    
+            bimViewer.setCameraStatus(msg)    
             this.lastCamStatus = msg //记录下来,防止反向传输
             
-            let camera = this.viewer.getViewer().camera
+            let camera = bimViewer.getViewer().camera
             if(camera.fov != data.fov){
                 camera.fov = data.fov
                 camera.updateProjectionMatrix()
@@ -318,7 +426,7 @@ export default class ConvertViews extends THREE.EventDispatcher{
             type: 'sendCameraData',
             data
         }) */
-        this.laserSyncView(this.sourceApp, data)
+        this.laserSyncView(this.sourceApp, data) //左侧只有laser点云模式才能接收到
     } 
 
     computeAveDiffLon() {
@@ -338,10 +446,12 @@ export default class ConvertViews extends THREE.EventDispatcher{
             }) 
              
         }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
 
@@ -367,7 +477,7 @@ export default class ConvertViews extends THREE.EventDispatcher{
         return /* KanKan.THREE.MathUtils.radToDeg( */ diffLonAve /* ) */
     }
 
-    computeShift(sourcePano) { //获取两个场景的旋转和位移偏差值
+    computeShift(sourcePano, targetPano) { //获取两个场景的旋转和位移偏差值
         //需要点的个数>1, 且两个场景点一一对应,位置接近且顺序一致
         //pick两个点来计算
         let diffLonAve = 0, panoPos1, panoPos2,
@@ -390,8 +500,8 @@ export default class ConvertViews extends THREE.EventDispatcher{
                 return e.position
             }) 
         }else{
-            panoPos1 = this.sourcePano.map(e=>e.position) 
-            panoPos2 = this.targetPano.map(e=>e.position)
+            panoPos1 = sourcePano.map(e=>e.position) 
+            panoPos2 = targetPano.map(e=>e.position)
         
             if(this.needConvertAxis){
                 panoPos1 = panoPos1.map(e=>math.convertVector.YupToZup(e))

+ 72 - 41
src/utils/sync.js

@@ -6,16 +6,19 @@ let sourceApp = null,
     targetApp = null 
   
 
-const getView = () => {
+/* const getView = () => {
     let camera = sourceApp.viewer.mainViewport.camera
     return {
         position: camera.position,
         quaternion: camera.quaternion,
         fov: camera.fov,
     }
-}
+} */
 
 const initConvertView = noNeedBindEvent => { 
+
+    
+
     if (sourceApp && targetApp) {
         if(targetApp.sceneType == 'bim'){
         
@@ -24,26 +27,26 @@ const initConvertView = noNeedBindEvent => {
                 views.bindWithBim(
                     sourceApp,
                     targetApp,
-                    sourceApp.viewer.images360.panos.slice(0, 2).map(e => e.position),
+                    sourceApp.viewer.images360.panos.slice(0, 2),
                     [//targetPano
                         {position: new THREE.Vector3( -5.313605730801787,  -4.889868407960505,  1.237447893355817),},
                         {position: new THREE.Vector3( -5.337403524084278,  -2.5012228235167737, 1.2808838933558175),} 
                     ],
-                    getView(),
+                     
                 )
                 sourceApp.Potree.settings.rotAroundPoint = false
-                targetApp.Potree.settings.rotAroundPoint = false
+                
             }else if(sourceApp.sceneType == 'kankan'){
                 
                 views.bindWithBim(
                     sourceApp,
                     targetApp,
-                    sourceApp.viewer.images360.panos.slice(0, 2).map(e => e.position),
+                    sourceApp.app.core.get('Player').model.panos.list.slice(0, 2), 
                     [//targetPano
                         {position: new THREE.Vector3( -5.313605730801787,  -4.889868407960505,  1.237447893355817),},
                         {position: new THREE.Vector3( -5.337403524084278,  -2.5012228235167737, 1.2808838933558175),} 
                     ],
-                    getView(),
+                     
                 )
                 
                 
@@ -61,44 +64,30 @@ const initConvertView = noNeedBindEvent => {
  * @param {String} type kankan|laser
  */
 export function loadSourceScene(sourceFrame,type) {
-
-    if (views.loaded) {
-        views.clear({ dontClearTarget: true })
+    if (views.loaded ) {
+        views.clear({ dontClearTarget: this.targetApp.sceneType == 'bim' })
     }
+    
     Log('loadSourceScene, ' + type)
     sourceApp = sourceFrame.value.contentWindow
     sourceApp.sceneType = type
     window.app1 = sourceApp
-    let loaded = ()=>{
-        
-        initConvertView()
-        
-        
+    let loaded = ()=>{ 
+        initConvertView()  
     }
     
     
     if(type == 'laser'){
         sourceApp.loaded.then(sdk => {
-            // if (mode.value != 0) {
-            //     sdk.scene.changeMode(mode.value)
-            // }  
-            window.viewer1 = sourceApp.viewer
-            sourceApp.Potree.settings.rotAroundPoint = false
-            viewer1.mainViewport.view.minPitch += 0.01 //防止bim垂直视角上的闪烁(似乎是因 up 要乘以某矩阵导致微小偏差所致)
-            viewer1.mainViewport.view.minPitch -= 0.01
-            viewer1.images360.panos.forEach(pano=>{
-                viewer1.updateVisible(pano.label2, 'notDisplay', true)
-                pano.dispatchEvent({type:'changeMarkerTex',name:'ring'})
-            }) 
-            sourceApp.canChangePos = () => {
-                return sourceApp.Potree.settings.displayMode != 'showPanos'
-            }
-            
+             
+            let viewer = sourceApp.viewer 
+             
+            laserLoaded(sourceApp)
             loaded()
         })  
     }else if(type == 'kankan'){  
-        sourceApp.app.Scene.on('loaded', () => {
-            //window.player1 = sourceApp.__sdk
+        sourceApp.app.Scene.on('loaded', (e) => {
+            let player = sourceApp.app.core.get('Player')
             loaded()
         })
     }
@@ -109,18 +98,46 @@ export function loadSourceScene(sourceFrame,type) {
  * @param {String} type kankan|laser|bim
  * @param {mode} mode 0|1
  */
-export function loadTargetScene(targetFrame, type,mode) {
+export function loadTargetScene(targetFrame, type, mode) {
     Log('loadTargetScene, ' + type)
-    targetApp = targetFrame.value.contentWindow
+    if (views.loaded ) {
+        views.clear( )
+    }
+    
+    targetApp = targetFrame.value.contentWindow   //其实只用赋值一次
     targetApp.sceneType = type
-    targetApp.loaded.then(viewer => {
-        if(type == 'laser'){
-            viewer.scene.changeMode(mode)
-        }
+    window.app2 = targetApp
+    let loaded = ()=>{
         
-        window.viewer2 = targetApp.viewer
         initConvertView()
-    })
+    }
+    
+    
+    
+    if(type == 'kankan'){  
+        targetApp.app.Scene.on('loaded', () => {
+            let player = targetApp.app.core.get('Player')
+            
+            loaded()
+        })
+    }else{
+        targetApp.loaded.then(sdk => {
+            //targetApp.viewer.scene.changeMode(mode)  
+            if(type == 'laser'){
+                laserLoaded(targetApp)
+            }else if(type == 'kankan'){
+            } 
+          
+            loaded()
+        }) 
+        
+    }        
+    
+    
+    
+    
+    
+     
 
 }
 
@@ -138,8 +155,22 @@ window.Log = function(value, color, fontSize){
     fontSize = fontSize || 13
     console.warn(`%c${value}`, `color:${color};font-size:${fontSize}px`) 
 }
+  
+function laserLoaded(app){
+    window.addEventListener('mouseup',(e)=>{
+        app.viewer.inputHandler.onMouseUp(e) //iframe的window的mouseup 在拖拽出窗口外居然不执行,只好用全局的通知它们
+    })
+    
+    app.viewer.mainViewport.view.minPitch += 0.01 //防止bim垂直视角上的闪烁(似乎是因 up 要乘以某矩阵导致微小偏差所致)
+    app.viewer.mainViewport.view.minPitch -= 0.01
+    app.viewer.images360.panos.forEach(pano=>{
+        app.viewer.updateVisible(pano.label2, 'notDisplay', true)
+        pano.dispatchEvent({type:'changeMarkerTex',name:'ring'})
+    }) 
 
-
+    app.Potree.settings.rotAroundPoint = false   //去除原因:比较好同步,尤其当左边在当前点位,右边同步后却离开当前点位的话拖拽就会绕点旋转了
+}
+  
 export default {
     get sourceInst() {
         return sourceApp