xzw 3 tahun lalu
induk
melakukan
94424b7c61
2 mengubah file dengan 225 tambahan dan 79 penghapusan
  1. 139 44
      src/utils/ConvertViews.js
  2. 86 35
      src/utils/sync.js

+ 139 - 44
src/utils/ConvertViews.js

@@ -1,12 +1,16 @@
 import math from './math.js'
 
+let bimViewer
+
 export default class ConvertViews extends THREE.EventDispatcher{
     constructor() {
         super()
         this.sourceApp = null
         this.targetApp = null
         this.sourceType = null
-       
+        this.targetPano = null
+        
+         
     }
 
      
@@ -17,8 +21,51 @@ export default class ConvertViews extends THREE.EventDispatcher{
             this.targetApp = null
         } 
     }
+    /* 
+        laser暂时做成这样: 全景模式时不跟踪pos,跟踪点位变化。点云模式时无论是否在漫游点上,都跟踪pos,不跟踪点位,所以会有左边marker在脚下,右边marker不在脚下的情况。
+        
+    */
+    bindWithSameType(sourceApp,targetApp){ 
+        this.sourceApp = sourceApp
+        this.targetApp = 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.computeShift()
+        
+        if(sourceApp.sceneType == 'laser'){
+            sourceApp.viewer.images360.addEventListener('endChangeMode',e=>{//只监听左边
+                sourceApp.Potree.settings.displayMode = e.mode
+            })
+
+            let bind = (master, customer)=>{ //相互都能带动对方
+                let flyToPano = (e)=>{
+                    customer.viewer.images360.flyToPano({pano: customer.viewer.images360.panos[e.toPano.id]} )
+                }
+                master.viewer.images360.addEventListener('flyToPano',flyToPano)
+                 
+                let cameraMove = (e)=>{
+                    //if(e.changeInfo && e.changeInfo.positionChanged){
+                } 
+                master.viewer.addEventListener('camera_changed',cameraMove)
+                
+                this.addEventListener('clearBind-sameType',()=>{
+                    master.viewer.images360.removeEventListener('flyToPano',flyToPano)
+                    
+                })
+            }
+            
+            bind(sourceApp, targetApp) 
+            bind(targetApp, sourceApp) 
+            
+            
+        }
+    }
     
-    init(sourceApp, targetApp, sourceDom, sourceType, cameraData, sourcePano) {
+     
+    bindWithBim(sourceApp, targetApp, sourceDom  , sourcePano, targetPano, cameraData  ) {
         //if (!this.player1.model.panos.list.length || !this.player2.model.panos.list.length) return
         
         if(this.loaded || !targetApp ) return 
@@ -26,20 +73,20 @@ export default class ConvertViews extends THREE.EventDispatcher{
         this.sourceApp = sourceApp
         this.targetApp = targetApp
         this.sourceDom = sourceDom
-        this.sourceType = sourceType
-        let viewer = this.viewer = targetApp.viewer 
+       
+        bimViewer = this.bimViewer = targetApp.viewer 
         
-        this.needConvertAxis = sourceType == '4dkk' // Y朝上需要转换
+        this.needConvertAxis = sourceApp.sceneType == 'kankan' && targetApp.sceneType == 'bim'// Y朝上需要转换
         
-        this.lastCamStatus = viewer.getCameraStatus()
+        this.lastCamStatus = bimViewer.getCameraStatus()
         this.computeShift(sourcePano)
         
-        viewer.setNavigationMode(targetApp.Glodon.Bimface.Viewer.NavigationMode3D.Walk)
-        viewer.setFlySpeedRate(5)
-        viewer.getViewer().setTransitionAnimationState(false) //setCameraStatus瞬间变化相机 ,or setCameraAnimation?
+        bimViewer.setNavigationMode(targetApp.Glodon.Bimface.Viewer.NavigationMode3D.Walk)
+        bimViewer.setFlySpeedRate(5)
+        bimViewer.getViewer().setTransitionAnimationState(false) //setCameraStatus瞬间变化相机 ,or setCameraAnimation?
          
-        viewer.addEventListener('Rendered', (e)=>{//反向改变左侧相机
-            let info = viewer.getCameraStatus() 
+        bimViewer.addEventListener('Rendered', (e)=>{//反向改变左侧相机
+            let info = bimViewer.getCameraStatus() 
             let poseChanged = !math.closeTo(this.lastCamStatus.position, info.position)
                 || !math.closeTo(this.lastCamStatus.target, info.target)
                 || !math.closeTo(this.lastCamStatus.fov, info.fov)
@@ -53,7 +100,7 @@ export default class ConvertViews extends THREE.EventDispatcher{
         })  
         
         
-        /* viewer.addEventListener(targetApp.Glodon.Bimface.Viewer.Viewer3DEvent.ViewAdded,
+        /* bimViewer.addEventListener(targetApp.Glodon.Bimface.Viewer.Viewer3DEvent.ViewAdded,
             ()=>{
                 this.loaded = true
                 if(this.firstData){
@@ -74,7 +121,7 @@ export default class ConvertViews extends THREE.EventDispatcher{
         this.lockCamera(true)
         
         
-        /* this.viewer.addEventListener(this.targetApp.Glodon.Bimface.Viewer.Viewer3DEvent.MouseClicked,(e)=>{
+        /* this.targetApp.addEventListener(this.targetApp.Glodon.Bimface.Viewer.Viewer3DEvent.MouseClicked,(e)=>{
             console.log('MouseClicked',e)
         }); */
         
@@ -93,7 +140,7 @@ export default class ConvertViews extends THREE.EventDispatcher{
             
         }  
         
-        let dom1 = this.viewer.getDomElement() 
+        let dom1 = this.targetApp.getDomElement() 
         //let pointerDownPos = new THREE.Vector2
         dom1.addEventListener('mousedown',(e)=>{
             let event = getEvent('mousedown', e)
@@ -134,7 +181,7 @@ export default class ConvertViews extends THREE.EventDispatcher{
         } */
         
         let position = new THREE.Vector3, target = new THREE.Vector3
-        let currStatus = this.viewer.getCameraStatus()
+        let currStatus = this.bimViewer.getCameraStatus()
         if(data.position){
             position = new THREE.Vector3().copy(data.position)
         } 
@@ -206,7 +253,7 @@ export default class ConvertViews extends THREE.EventDispatcher{
 
 
     send(info){ 
-        let camera = this.viewer.getViewer().camera
+        let camera = this.bimViewer.getViewer().camera
         
         let data = { 
             position : new THREE.Vector3().copy(info.position).applyMatrix4(this.convertMatrixInvert),
@@ -224,12 +271,56 @@ export default class ConvertViews extends THREE.EventDispatcher{
         })
     } 
 
+    computeAveDiffLon() {
+        //获取两个场景的lon偏差值
+        //需要点的个数>1, 且两个场景点一一对应,位置接近且顺序一致
+
+        let diffLonAve = 0, length,
+            diffLons = [],
+            panoPos1, panoPos2  
+        
+        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{
+            
+            
+            
+            
+        }
+        length = panoPos1.length
+
+        //挑选连续的两个点为向量来计算,如有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).setY(0)
+            let vec2 = new THREE.Vector3().subVectors(pos21, pos22).setY(0)
+            let diffLon = math.getAngle(vec1, vec2, 'z')
+            diffLons.push(diffLon)
+            diffLonAve += diffLon
+            index++
+        }
+
+        console.log('diffLons', diffLons)
+        diffLonAve /= length
+        console.log('diffLonAve', diffLonAve)
+        return /* KanKan.THREE.MathUtils.radToDeg( */ diffLonAve /* ) */
+    }
 
     computeShift(sourcePano) { //获取两个场景的旋转和位移偏差值
         //需要点的个数>1, 且两个场景点一一对应,位置接近且顺序一致
         //pick两个点来计算
-        let diffLonAve = 0,
+        let diffLonAve = 0, panoPos1, panoPos2,
             diffLons = []
 
         /* let panoPos1 = [//4dkk   SS-t-lc5OWhZPaC 
@@ -237,26 +328,30 @@ export default class ConvertViews extends THREE.EventDispatcher{
             new THREE.Vector3( 4.07288387528266,  1.8350265362839944, 0.04772775)
         ] */
         
-        let panoPos1 = sourcePano
         
-        let panoPos2 = [
-            new THREE.Vector3( -5.313605730801787,  -4.889868407960505,  1.237447893355817),
-            new THREE.Vector3( -5.337403524084278,  -2.5012228235167737, 1.2808838933558175) 
-        ]
+        
          
-        let length = panoPos1.length
+        if(this.sourceApp.sceneType == this.targetApp.sceneType){
+            var angle = this.diffLonAve;
+            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.sourcePano.map(e=>e.position) 
+            panoPos2 = this.targetPano.map(e=>e.position)
         
-        if(this.needConvertAxis){
-            panoPos1 = panoPos1.map(e=>math.convertVector.YupToZup(e))
-        }
-
-
-        var vec1 = new THREE.Vector3().subVectors(panoPos1[0], panoPos1[1]) //旧的向量
-        var vec2 = new THREE.Vector3().subVectors(panoPos2[0], panoPos2[1])//新的向量
+            if(this.needConvertAxis){
+                panoPos1 = panoPos1.map(e=>math.convertVector.YupToZup(e))
+            }
+            var vec1 = new THREE.Vector3().subVectors(panoPos1[0], panoPos1[1]) //旧的向量
+            var vec2 = new THREE.Vector3().subVectors(panoPos2[0], panoPos2[1])//新的向量
    
-        var angle = math.getAngle(vec1, vec2, 'z')
-
-
+            var angle = math.getAngle(vec1, vec2, 'z')
+        }
+        
         //var scale = vec2.length()/vec1.length() 
         //var scaleMatrix = new THREE.Matrix4().makeScale(scale,scale,scale)   //默认为1, 但由于坐标暂时是自己采集的,所以结果会是第一个点附近比较正确,越远偏差越大
         var matrix = new THREE.Matrix4().setPosition(panoPos1[0].clone().negate())//先以点0为基准平移到000
@@ -314,8 +409,8 @@ export default class ConvertViews extends THREE.EventDispatcher{
     }
 
     updateCtrlEnable(){
-        this.viewer.camera3D.enableRotate(this.locked ? false : true)
-        this.viewer.enableShortcutKey((this.locked || this.isPanoMode) ? false : true) //键盘移动
+        this.bimViewer.camera3D.enableRotate(this.locked ? false : true)
+        this.bimViewer.enableShortcutKey((this.locked || this.isPanoMode) ? false : true) //键盘移动
     }
 
 
@@ -346,23 +441,23 @@ export default class ConvertViews extends THREE.EventDispatcher{
 
         if (player1.mode == 'panorama') {
             //平移
-            let dir = new this.KanKan.THREE.Vector3().subVectors(control2.target, player2.position)
+            let dir = new THREE.Vector3().subVectors(control2.target, player2.position)
             dir.applyQuaternion(quaternion)
-            let target1 = new this.KanKan.THREE.Vector3().addVectors(player1.position, dir)
+            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 this.KanKan.THREE.Vector3().subVectors(control2.target, player2.model.panos.list[0].position)
+            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 this.KanKan.THREE.Vector3().subVectors(control2.camera.position , control2.target)
+            let dir = new THREE.Vector3().subVectors(control2.camera.position , control2.target)
             dir.applyQuaternion(quaternion)
-            player1.position = new this.KanKan.THREE.Vector3().addVectors(control1.target, dir)
+            player1.position = new THREE.Vector3().addVectors(control1.target, dir)
 
             control1.camera.position.copy(player1.position)
         }
@@ -374,11 +469,11 @@ export default class ConvertViews extends THREE.EventDispatcher{
 
         let quaternion
         if (data.quaternion) {
-            quaternion = new this.KanKan.THREE.Quaternion().copy(data.quaternion)
+            quaternion = new THREE.Quaternion().copy(data.quaternion)
             data.quaternion = quaternion
         } else if (data.info && data.info.quaternion) {
             //飞出
-            quaternion = new this.KanKan.THREE.Quaternion(data.info.quaternion._x, data.info.quaternion._y, data.info.quaternion._z, data.info.quaternion._w)
+            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)
         }
@@ -392,9 +487,9 @@ export default class ConvertViews extends THREE.EventDispatcher{
 
         if (data.info && data.info.quaternion) {
             //飞出
-            let dir = new this.KanKan.THREE.Vector3().subVectors(data.info.position, data.info.target)
+            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 this.KanKan.THREE.Vector3().addVectors(data.info.target, dir)
+            data.info.position = new THREE.Vector3().addVectors(data.info.target, dir)
         }
 
          

+ 86 - 35
src/utils/sync.js

@@ -3,7 +3,8 @@ import ConvertViews from '@/utils/ConvertViews'
 const views = new ConvertViews()
 
 let sourceApp = null,
-    targetApp = null
+    targetApp = null 
+  
 
 const getView = () => {
     let camera = sourceApp.viewer.mainViewport.camera
@@ -14,16 +15,45 @@ const getView = () => {
     }
 }
 
-const initConvertView = noNeedBindEvent => {
+const initConvertView = noNeedBindEvent => { 
     if (sourceApp && targetApp) {
-        views.init(
-            sourceApp,
-            targetApp,
-            sourceApp.viewer.inputHandler.domElement,
-            'laser',
-            getView(),
-            sourceApp.viewer.images360.panos.slice(0, 2).map(e => e.position)
-        )
+        if(targetApp.sceneType == 'bim'){
+        
+        
+            if(sourceApp.sceneType == 'laser'){ 
+                views.bindWithBim(
+                    sourceApp,
+                    targetApp,
+                    sourceApp.viewer.inputHandler.domElement, 
+                    sourceApp.viewer.images360.panos.slice(0, 2).map(e => e.position),
+                    [//targetPano
+                        {position: new THREE.Vector3( -5.313605730801787,  -4.889868407960505,  1.237447893355817),},
+                        {position: new THREE.Vector3( -5.337403524084278,  -2.5012228235167737, 1.2808838933558175),} 
+                    ],
+                    getView(),
+                )
+            }else if(sourceApp.sceneType == 'kankan'){
+                
+                views.bindWithBim(
+                    sourceApp,
+                    targetApp,
+                    sourceApp.domElement, 
+                    sourceApp.viewer.images360.panos.slice(0, 2).map(e => e.position),
+                    [//targetPano
+                        {position: new THREE.Vector3( -5.313605730801787,  -4.889868407960505,  1.237447893355817),},
+                        {position: new THREE.Vector3( -5.337403524084278,  -2.5012228235167737, 1.2808838933558175),} 
+                    ],
+                    getView(),
+                )
+                
+                
+            }
+        }else if(sourceApp.sceneType == targetApp.sceneType){
+            
+            views.bindWithSameType(sourceApp,targetApp)
+             
+        }
+            
     }
 }
 /**
@@ -35,19 +65,27 @@ export function loadSourceScene(sourceFrame,type) {
     if (views.loaded) {
         views.clear({ dontClearTarget: true })
     }
-
+    Log('loadSourceScene, ' + type)
     sourceApp = sourceFrame.value.contentWindow
-    sourceApp.loaded.then(sdk => {
-        // if (mode.value != 0) {
-        //     sdk.scene.changeMode(mode.value)
-        // }
-
-        window.viewer1 = sourceApp.viewer
-        window.app1 = sourceApp
-        viewer1.mainViewport.view.minPitch += 0.01 //防止bim垂直视角上的闪烁(似乎是因 up 要乘以某矩阵导致微小偏差所致)
-        viewer1.mainViewport.view.minPitch -= 0.01
-        if(type == 'laser'){
+    sourceApp.sceneType = type
+    window.app1 = sourceApp
+    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'})
@@ -55,26 +93,29 @@ export function loadSourceScene(sourceFrame,type) {
             sourceApp.canChangePos = () => {
                 return sourceApp.Potree.settings.displayMode != 'showPanos'
             }
-        }
-        initConvertView()
-        console.log('\n loadSourceScene', type)
-        sourceApp.viewer.addEventListener('camera_changed', e => {
-            targetApp && views.receive(getView())
+            sourceApp.viewer.addEventListener('camera_changed', e => {
+                targetApp && views.receive(getView())
+            })
+            loaded()
+        })  
+    }else if(type == 'kankan'){  
+        sourceApp.app.Scene.on('loaded', () => {
+            //window.player1 = sourceApp.__sdk
+            loaded()
         })
-    })
-
-    
+    }
 }
 
 /**
  * 右屏加载
  * @param {String} type kankan|laser|bim
  */
-export function loadTargetScene(targetFrame,type) {
-    
+export function loadTargetScene(targetFrame, type) {
+    Log('loadTargetScene, ' + type)
     targetApp = targetFrame.value.contentWindow
+    targetApp.sceneType = type
     targetApp.loaded.then(viewer => {
-        console.log('loadTargetScene')
+        
         window.viewer2 = targetApp.viewer
         initConvertView()
     })
@@ -82,11 +123,21 @@ export function loadTargetScene(targetFrame,type) {
 }
 
 views.addEventListener('sendCameraData', e => {
-    //同步右侧数据
-    sourceApp.viewer.mainViewport.view.position.copy(e.data.position)
-    sourceApp.viewer.mainViewport.view.lookAt(e.data.target)
+    //同步右侧数据到左侧
+    if(sourceApp.sceneType == 'laser'){
+        sourceApp.viewer.mainViewport.view.position.copy(e.data.position)
+        sourceApp.viewer.mainViewport.view.lookAt(e.data.target)
+    }
 })
 
+
+window.Log = function(value, color, fontSize){ 
+    color = color || '#ff4399'
+    fontSize = fontSize || 13
+    console.warn(`%c${value}`, `color:${color};font-size:${fontSize}px`) 
+}
+
+
 export default {
     get sourceInst() {
         return sourceApp