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