123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245 |
- import math from './math.js'
- let bimViewer
- export default class ConvertViews extends THREE.EventDispatcher{
- constructor(isMobile ) {
- super()
- this.settings = {
- durations : {flyToPano:1000, dolly:20, bimAniOrigin:1000},
- checkModeDelay : 1000,
- }
- this.convertInfo //包含转换信息
- this.isMobile = isMobile
- }
-
-
- bindWithSameFakeType(sourceFakeApp, targetApp){//和另一个虚拟场景数据相配。 用于手机未分屏,切换场景;或者pc和bim对比时切换场景。
- let sourceApp = {sceneType: sourceFakeApp.sceneType, fakeApp:sourceFakeApp} //上一个场景
- this.createFakeApp(targetApp, true)//当前场景
- sourceApp.sceneName = 'sourceApp'
- targetApp.sceneName = 'targetApp'
-
- let convertInfo = this.computeAveDiffLon(sourceFakeApp, targetApp.fakeApp)
-
- if(sourceApp.sceneType == 'laser'){
- let data = this.computeShift({sourceApp,targetApp, convertInfo}) //因为有点云模式自由移动所以需要计算
-
- }
-
- //this.syncPosRot(sourceFakeApp.viewInfo, targetApp , convertInfo) //修改好位置朝向 这个4dkk的会报错但上一版是用这句
- if(sourceApp.sceneType == 'kankan' || sourceFakeApp.viewInfo.isAtPano){
- this.flyToPano(targetApp, sourceFakeApp.viewInfo.currentPano, null, {duration:0, zoomLevel:sourceFakeApp.viewInfo.zoomLevel})
- }
- this.syncView(sourceApp, targetApp, convertInfo)//这个不记得有什么bug了
-
-
-
- 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正确
- }
- return convertInfo
- }
-
-
- bindWithSameType(sourceApp,targetApp, isSwitchScene){ //左右分屏 同类型
- console.log('bindWithSameType')
-
- let reverse = isSwitchScene == 'source' //如果是左屏被换,则是左屏要跟右屏同步
-
- let master = reverse ? targetApp : sourceApp
- let customer = reverse ? sourceApp : targetApp
- this.createFakeApp(master,true)
- this.convertInfo = this.bindWithSameFakeType(master.fakeApp, customer) //先同步第一个画面
-
- //-------------------
-
-
-
- this.sourceApp = sourceApp
- this.targetApp = targetApp
- sourceApp.sceneName = 'sourceApp'
- targetApp.sceneName = 'targetApp'
-
-
-
- //后续的同步
-
- if(sourceApp.sceneType == 'laser'){
- //只监听左边
- let displayMode = (e)=>{
- targetApp.Potree.settings.displayMode = e.mode
- }
- sourceApp.viewer.images360.addEventListener('endChangeMode', displayMode)
-
- let dispose = ()=>{
- if(!sourceApp.viewer || !sourceApp.viewer.images360)return
- sourceApp.viewer.images360.removeEventListener('endChangeMode', displayMode)
- this.removeEventListener('clearBind-sameType',dispose)
- }
- this.addEventListener('clearBind-sameType',dispose)
- /*targetApp.viewer.images360.addEventListener('requestMode', (e)=>{
- console.error('requestMode targetApp', targetApp.name, e.mode)
- })
- targetApp.viewer.images360.addEventListener('endChangeMode', (e)=>{
- console.error('endChangeMode targetApp', targetApp.name, e.mode)
- })*/
-
- }else if(sourceApp.sceneType == 'kankan'){
- //暂时关闭快速过渡,因为跟不上
- sourceApp.app.core.get('Player').setPanoTaskEnable(false)
- targetApp.app.core.get('Player').setPanoTaskEnable(false)
- }
-
- let bind = (master, customer)=>{ //相互都能带动对方
- if(sourceApp.sceneType == 'laser'){
-
- var flyToPano = (e)=>{//同步点位
- if(master != this.masterApp )return
- let pano = customer.viewer.images360.getPano(e.toPano.pano.id)
- if(!pano)return console.error('找不到该e.panoId', e.toPano.pano.id)
- customer.viewer.images360.flyToPano({pano} )
- }
- master.viewer.images360.addEventListener('flyToPano',flyToPano)
-
-
- var cancelFlyToPano = (e)=>{//防止点云模式下飞到pano途中停止后另一边还在飞
- e.disturb && this.laserCancelFly(customer)
- }
- master.viewer.images360.addEventListener('flyToPanoDone',cancelFlyToPano)
-
-
- var cameraMove = (e)=>{
- if(master != this.masterApp || !customer.viewer )return
-
- this.fakeAppUpdateInfo(master)
-
- master.fakeApp.viewInfo.quaternionChanged = e.changeInfo && e.changeInfo.quaternionChanged
- this.syncView(master, customer)
- }
- master.viewer.addEventListener('camera_changed',cameraMove)
-
-
- var dragEnd = (e)=>{
- if(customer.viewer.inputHandler.drag){
- customer.viewer.inputHandler.onMouseUp(e) //从一侧拖拽到另一侧松开时,需要执行原先一侧的mouseup
- }
- }
- master.addEventListener('mouseup',dragEnd)
-
-
- var pointDensityChanged = ()=>{
- if(customer.Potree.settings.UserDensityPercent != master.Potree.settings.UserDensityPercent){
- customer.Potree.settings.UserDensityPercent = master.Potree.settings.UserDensityPercent //在sdk里初始化了UserDensityPercent所以不能只用UserPointDensity了
- customer.viewer.setPointLevels()
- console.log('UserPointDensity', master.sceneName, master.Potree.settings.UserDensityPercent)
- }
-
- }
- master.viewer.addEventListener('densityChange',pointDensityChanged)
-
-
- }else if(sourceApp.sceneType == 'kankan'){
-
-
- var player1 = master.app.core.get('Player')
- var player2 = customer.app.core.get('Player')
- let this_ = this
- var flyToPano = (e)=>{//同步点位
- if(master != this_.masterApp )return
- let pano = player2.model.panos.index[e.panoId]
- if(!pano)return console.error('找不到该e.panoId',e.panoId)
- player2.flyToPano({pano} )
- }
- player1.on("flying.started",flyToPano)
-
-
- var cameraMove = (e)=>{//暂时只有漫游模式
- if(!e.hasChanged.cameraChanged || !customer.app || !customer.app.core||
- master != this_.masterApp
- )return
- //console.log('cameraMove', master.sceneName)
- this.fakeAppUpdateInfo(master)
- this.syncView(master, customer)
- }
- player1.on("update",cameraMove)
-
- }
-
-
-
- let changeMaster = ()=>{
- this.masterApp = master //主控方。只有主控方能控制被控方。鼠标操作过mousedown mousewheel等才能认定为主控方
- }
- let dom = sourceApp.sceneType == 'laser' ? master.viewer.inputHandler.domElement : master.app.core.get('Player').domElement
- dom.addEventListener('pointerdown',changeMaster )
- dom.addEventListener('mousewheel',changeMaster )
-
-
- let dispose = ()=>{
- if(master.sceneType == 'laser'){
- if(!master.viewer )return //master已替换,不用处理
- master.viewer.images360.removeEventListener('flyToPano',flyToPano)
- master.viewer.images360.removeEventListener('flyToPanoDone',cancelFlyToPano)
- master.viewer.removeEventListener('camera_changed',cameraMove)
- master.viewer.removeEventListener('densityChange',pointDensityChanged)
-
- }else if(master.sceneType == 'kankan'){
- player1.off("flying.started",flyToPano)
- player1.off("update",cameraMove)
- }
-
- dom.removeEventListener('pointerdown',changeMaster)
- dom.removeEventListener('mousewheel',changeMaster)
- master.removeEventListener('mouseup',dragEnd)
- this.removeEventListener('clearBind-sameType',dispose)
- }
- this.addEventListener('clearBind-sameType',dispose)
-
-
- }
-
- bind(sourceApp, targetApp)
- bind(targetApp, sourceApp)
- sourceApp.sceneType == 'laser' && master.viewer.dispatchEvent('densityChange')//同步点云质量
-
-
- this.loaded = true
- }
-
-
-
-
- bindFakeWithBim(sourceFakeApp, targetApp, panoData ){// bim和其他类型互转(mobile), bim不一定是target
- if(targetApp.sceneType == 'bim'){
- bimViewer = targetApp.viewer
- bimViewer.getViewer().setTransitionAnimationState(false)
- targetApp.CLOUD.GlobalData.WalkRotationSpeed = -0.2 //反向一下
- }
- if(sourceFakeApp.sceneType == 'bim' && targetApp.sceneType == 'bim' ){
- console.log('还是bim')
- this.syncPosRot(sourceFakeApp.viewInfo, targetApp )
- return;
- }
-
-
-
-
- if(!panoData)return
-
-
- let sourceApp = {sceneType: sourceFakeApp.sceneType, fakeApp:sourceFakeApp}
-
- this.createFakeApp(targetApp)
- let {sourcePano, targetPano} = this.bimGetPanoData(sourceApp, targetApp, panoData)
-
- let convertAxis = sourceApp.sceneType == 'kankan' ? 'YupToZup' : targetApp.sceneType == 'kankan' ? 'ZupToYup' : null
- let convertInfo = {convertAxis}
- this.computeShift({sourcePano, targetPano, convertInfo})
-
- //console.log('convertInfo', convertInfo, sourcePano, targetPano)
-
-
- let selectBestPose = ()=>{
-
- let data = this.getTranPosData(sourceFakeApp.viewInfo, convertInfo, convertInfo.targetFakeApp == targetApp.fakeApp)
-
- 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, null, prop)
-
-
- }
-
-
-
-
- if(targetApp.sceneType == 'bim' ){
- sourceFakeApp.viewInfo.fov = null; //暂不改变bim单屏的fov,因为bim变不回来
- this.syncPosRot(sourceFakeApp.viewInfo, targetApp, convertInfo)
-
- }else if(targetApp.sceneType == 'laser' ){
- selectBestPose() //刚好在点位上的话这句设置完就正确了
- let currFakeApp = targetApp.fakeApp
- setTimeout(()=>{ //刚开始总是showPointCloud (且稍后会自动飞到某点)所以需要延时
- if(targetApp.fakeApp != currFakeApp)return //已经加载别的场景
- this.laserCancelFly(targetApp)
- if(this.ifCanChangePos(targetApp)){//点云模式的话
- this.syncPosRot(sourceFakeApp.viewInfo, targetApp, convertInfo)
- }else{
-
- }
- },this.settings.checkModeDelay+10)
- }else{//bim -> 固定点位
- selectBestPose()
-
- }
-
- }
-
-
-
-
- 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.createFakeApp(sourceApp)
- this.createFakeApp(targetApp)
- let {sourcePano, targetPano} = this.bimGetPanoData(sourceApp, targetApp, panoData)
-
- this.sourceApp = sourceApp
- this.targetApp = targetApp
-
- bimViewer = this.bimViewer = targetApp.viewer
- let modelSize = new THREE.Vector3
- let modelBound = bimViewer.getViewer().modelManager.boundingBox
- modelBound.getSize(modelSize)
- bimViewer.setNavigationMode(targetApp.Glodon.Bimface.Viewer.NavigationMode3D.Walk)
- //bimViewer.setFlySpeedRate(THREE.MathUtils.clamp( modelSize.length() / 10, 1, 6)) //会被限制
- bimViewer.setFlySpeedRate(1.5) //方向键速度,保持较小匀速,方便细调。
-
- this.sourceDom = sourceApp.sceneType == 'laser' ? this.sourceApp.viewer.inputHandler.domElement : this.sourceApp.app.core.get('Player').domElement
-
- if(targetPano){
- bimViewer.getViewer().setTransitionAnimationState(false) //setCameraStatus瞬间变化相机 ,or setCameraAnimation?
-
-
- var convertAxis = sourceApp.sceneType == 'kankan' && targetApp.sceneType == 'bim' && 'YupToZup'// Y朝上需要转换
-
- this.convertInfo = this.computeShift({sourcePano, targetPano, convertInfo:{convertAxis}})
-
- this.lastCamStatus = bimViewer.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)
-
- if(poseChanged){
- if(this.ifCanChangePos(this.sourceApp)){
-
- let data = this.getTranPosData(info, this.convertInfo, true )
-
- this.laserSyncView(this.sourceApp, data)
-
-
- this.lastCamStatus = info
- }
- }
-
- })
-
- if(needBindEvent){
- this.bimBindCamEvent()
- }else{//替换的左侧的,需要使左侧和右侧同步, 其实是左侧要和上一个左侧先同步,再让右侧和左侧同步
-
- this.bindWithSameFakeType(this.lastFakeApp, sourceApp)
-
- }
-
- {
-
- 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.syncPosRot(this.firstData)
- }
- }
- ) */
-
-
-
- let data = this.getCameraData(sourceApp)
- this.syncPosRot(data)
- this.loaded = true
- }else{
- //分屏 不同步(设置点位绑定页面)
-
- let data = this.getCameraData(sourceApp)
- let camera = bimViewer.getViewer().camera
- if(data.fov && camera.fov != data.fov){
- camera.fov = data.fov
- camera.updateProjectionMatrix()
- }
-
-
-
-
- //将第一人称control补充完:
-
- //scroll
- let baseSpeed = THREE.MathUtils.clamp( Math.sqrt(modelSize.length()) / 5, 0.3, 3) //在modelBound中时的速度
- //console.log('baseSpeed',baseSpeed)
- let dom = bimViewer.getDomElement();
- dom.addEventListener('mousewheel', e => { //原版滚轮不能缩放,自己加一个
- if(e.wheelDelta == 0)return //mac
- let info = bimViewer.getCameraStatus()
- let dis = modelBound.distanceToPoint(info.position)
- let speed = baseSpeed + dis / 6
- //console.log('speed', speed)
-
- this.bimFlyTo({forwardDis: e.wheelDelta > 0 ? speed : -speed, duration:this.settings.durations.dolly , minRadius : baseSpeed})
- })
-
- //右键pan
- let dragging , pointerDelta = new THREE.Vector2, pointerStart = new THREE.Vector2
- dom.addEventListener('mousedown', e => {
- if(e.button == 2){//右键
- dragging = true
- pointerStart.set(e.clientX, e.clientY)
- }
- })
- dom.addEventListener('mousemove', e => {
- if(!dragging)return
- let pointerEnd = new THREE.Vector2(e.clientX, e.clientY)
- pointerDelta.subVectors(pointerEnd, pointerStart)
- pointerStart.copy(pointerEnd)
-
- bimViewer.getViewer().cameraControl.pan(pointerDelta.x,pointerDelta.y)
- })
-
- let mouseupAt = (target,e)=>{//触发target的mouseup
- if(!e.view && !e.isTrusted)return //应该就是由mouseupAt发出的事件,不再复制
- let event = new MouseEvent('mouseup', {
- button : e.button, buttons:e.buttons
- })
- target.dispatchEvent(event)
- }
- targetApp.addEventListener('mouseup', e => {
- dragging = false
- //触发当前sourceDom的mouseup
- mouseupAt(this.sourceDom,e)
- })
- this.sourceDom.addEventListener('mouseup', e => {
- dragging = false
- //触发当前targetApp的mouseup
- mouseupAt(targetApp,e)
- })
- this.addEventListener('mouseupOutOfWin', e => {
- dragging = false
- //触发当前targetApp的mouseup
- mouseupAt(targetApp,e)
- })
-
-
- targetApp.CLOUD.GlobalData.WalkRotationSpeed = -0.2 //反向一下
-
- //bimViewer.viewer.getViewer().editorManager.userInputEditor.enable = true//这句近似将control切换成orbit
-
- }
- }
-
-
-
-
- computeAveDiffLon(sourceFakeApp, targetFakeApp) {
- //获取两个场景的lon偏差值
- //需要点的个数>1, 且两个场景点一一对应,位置接近且顺序一致
- let diffLonAve = 0, length, diffLon,
- diffLons = []
-
- let panoPos1 = sourceFakeApp.panos.map(e=>{
- return e.position
- })
- let panoPos2 = targetFakeApp.panos.map(e=>{
- return e.position
- })
-
-
- if(panoPos1.length!=panoPos2.length){
- console.error('两个场景漫游点数量不同!',panoPos1,panoPos2)
- }
- length = Math.min(panoPos1.length, panoPos2.length )
-
- if(length<2){
- console.error('最小漫游点个数少于两个!!!')
- }
- if(length==0){//slam
- return {
- diffLon:0, //diffLonAve,
- diffQua: new THREE.Quaternion ,
- diffQuaInvert: new THREE.Quaternion,
- sourceFakeApp,
- targetFakeApp
- }
- }
- //挑选连续的两个点为向量来计算,如有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)
- let vec2 = new THREE.Vector3().subVectors(pos21, pos22)
-
- if(sourceFakeApp.sceneType == "laser" ){
- vec1.setZ(0), vec2.setZ(0)
- }else{
- vec1.setY(0), vec2.setY(0)
- }
-
- let diffLon0 = math.getAngle(vec1, vec2, sourceFakeApp.sceneType == "laser" ? 'z' : 'y')
-
- diffLons.push(diffLon0)
- diffLonAve += diffLon0
- index++
- }
- console.log('diffLons', diffLons)
- diffLonAve /= length
-
-
- diffLons = diffLons.sort((a,b)=>{return a-b})
-
- if(length<=2){
- diffLon = diffLonAve
- }else{
- //只选中间的一部分(类似中位数),以去掉坏点
- let i=1/3, j=2/3; //起始和终止。选取中间的三分之一
- let midList = diffLons.slice(i*length,Math.ceil(j*length));
- let sum = midList.reduce((total,cur)=>{return total+cur},0);
- diffLon = sum / midList.length;
- }
-
- let upVec = sourceFakeApp.sceneType == "laser" ? new THREE.Vector3(0, 0, 1) : new THREE.Vector3(0, 1, 0) //左右两个场景类型一样。暂不会有laser和4dkankan同步的情况
- let diffQua = new THREE.Quaternion().setFromAxisAngle(upVec, diffLon)
- console.log('diffLonAve', diffLonAve, 'diffLon', diffLon)
-
- return {
- diffLon, //diffLonAve,
- diffQua ,
- diffQuaInvert : diffQua.clone().invert(),
- sourceFakeApp,
- targetFakeApp
- }
-
- }
- computeShift(o={} ) { //获取两个可自由移动的场景的旋转和位移偏差值
- //需要点的个数>1, 且两个场景点一一对应,位置接近且顺序一致
-
- let panoPos1, panoPos2, convertInfo = o.convertInfo || {}, center1, center2, matrix
-
- if(o.sourceApp && o.targetApp && o.sourceApp.sceneType == o.targetApp.sceneType){
- var angle = convertInfo.diffLon; //直接使用 更精准
- panoPos1 = o.sourceApp.fakeApp.panos.map(e=>{
- return e.position
- })
- panoPos2 = o.targetApp.fakeApp.panos.map(e=>{
- return e.position
- })
- convertInfo.sourceFakeApp = o.sourceApp.fakeApp
- convertInfo.targetFakeApp = o.targetApp.fakeApp
- }else{//bim
- panoPos1 = o.sourcePano.map(e=>e.position) //pick两个点来计算
- panoPos2 = o.targetPano.map(e=>e.position)
-
- if(convertInfo.convertAxis){
- panoPos1 = panoPos1.map(e=>math.convertVector[convertInfo.convertAxis](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')
- }
-
- let compute = (panoPos1,panoPos2)=>{
- //中心点
- center1 = panoPos1.reduce((t,c)=>{return t.add(c)},new THREE.Vector3())
- center2 = panoPos2.reduce((t,c)=>{return t.add(c)},new THREE.Vector3())
- center1.multiplyScalar(1/panoPos1.length)
- center2.multiplyScalar(1/panoPos2.length)
-
- //var scale = vec2.length()/vec1.length()
- //var scaleMatrix = new THREE.Matrix4().makeScale(scale,scale,scale) //默认为1, 但由于坐标暂时是自己采集的,所以结果会是第一个点附近比较正确,越远偏差越大
- var matrix = new THREE.Matrix4().setPosition(/* panoPos1[0] */center1.clone().negate())//先以点0为基准平移到000
- //matrix.premultiply(scaleMatrix)//再缩放
- var rotateMatrix = new THREE.Matrix4().makeRotationAxis(new THREE.Vector3(0,0,1), angle );
- matrix.premultiply(rotateMatrix)//和旋转
- var moveBackMatrix = new THREE.Matrix4().setPosition(/* panoPos2[0] */center2)
- matrix.premultiply(moveBackMatrix)//再移动到realPosition的点0处
- return matrix
- }
- let length = Math.min(panoPos1.length, panoPos2.length)
- if(length == 0){
- convertInfo.convertMatrix = new THREE.Matrix4
- convertInfo.convertMatrixInvert = new THREE.Matrix4
- return convertInfo
- }
- matrix = compute(panoPos1,panoPos2)
-
-
- //检查是否重合。直接将matrix作用于pos1中,理想情况是会和pos2完全一样。
-
- if(length>2){
- let diffVecs = panoPos1.slice(0,length).map((e,i)=>{
- let newPos = e.clone().applyMatrix4(matrix) //旋转过后。
- return new THREE.Vector3().subVectors(newPos, panoPos2[i]) // 和pos1之间的偏差。越小越重合
- })
- let disDiffs = diffVecs.map(e=>e.length())
- let disDiffs2 = disDiffs.sort((a,b)=>{return a-b})
- let maxTolerance = 2 * disDiffs2[Math.round(diffVecs.length/3)] //最大值限制在1/3的两倍处。不用绝对数值的原因:主要考虑到万一拍摄间隔很大,那么最小的diff都可能很大,所以还是按比例划分吧。
- if(disDiffs2[1]>=maxTolerance){//至少有两个
- maxTolerance = disDiffs2[1]
- }
- console.log('difVecs',diffVecs, 'disDiffs2',disDiffs2,'maxTolerance',maxTolerance)
-
-
- //排除掉偏差大的坏点
- let panoPos1new = panoPos1.filter((p,i)=>{return disDiffs[i]<=maxTolerance})
- let panoPos2new = panoPos2.filter((p,i)=>{return disDiffs[i]<=maxTolerance})
- if(panoPos1new.length > 1 && panoPos2new.length > 1){ //用剩下的点再算一次
- matrix = compute(panoPos1new,panoPos2new)
- }
- }
-
- convertInfo.convertMatrix = matrix
- convertInfo.convertMatrixInvert = matrix.clone().invert()
- return convertInfo
- //return { convertMatrix: matrix, convertMatrixInvert:matrix.clone().invert(), convertAxis:o.convertAxis}
- /*
- 用于场景自由移动时。缺点:切换点云模式时,如果点位不准 偏差大,就会瞬移一下。
- 不过目前四维看看不支持到dollhouse
- */
- }
-
-
-
- syncPosRot(data, customer, convertInfo ){//同步 自由位置和朝向(不被漫游点束缚时)
- /*
- if(!this.loaded){
- return this.firstData = data
- } */
- convertInfo = convertInfo || this.convertInfo || {}
- let {position,target} = this.getTranPosData(data, convertInfo, customer && customer.fakeApp == convertInfo.sourceFakeApp )
-
- if(customer && customer.sceneType == 'laser'){
- this.laserSyncView(customer, {position,target})
- }else if(customer && customer.sceneType == 'kankan'){
- this.syncView(sourceApp, targetApp, convertInfo)
- }else{
- let info = bimViewer.getCameraStatus()
- let msg = {
- position,
- target,
- up:info.up,
- //前三个缺一不可
- fov: data.fov || info.fov, //fov 用setCameraStatus 无效
- }
-
- bimViewer.setCameraStatus(msg)
- this.lastCamStatus = msg //记录下来,防止反向传输
-
- let camera = bimViewer.getViewer().camera
- if(data.fov && camera.fov != data.fov){
- camera.fov = data.fov
- camera.updateProjectionMatrix()
- }
- }
- }
-
-
- ifCanChangePos(app){
- return app.sceneType == 'laser' && app.Potree.settings.displayMode != 'showPanos' //app.fakeApp.viewInfo.displayMode != 'showPanos'
- }
-
-
-
-
- /*
- laser暂时做成这样: 全景模式时不跟踪pos,跟踪pano变化。点云模式时也跟踪pano变化,但移动时完全跟踪位置变化 ,所以会有左边marker在脚下,右边marker不在脚下的情况。
-
- */
-
- bimGetPanoData(sourceApp, targetApp, panoData){
- if(panoData){
- let sourcePano,targetPano
- let pano1 = [//bim
- {position:new THREE.Vector3().copy(panoData.p1.pos2 || panoData.p1.position)},
- {position:new THREE.Vector3().copy(panoData.p2.pos2 || panoData.p2.position)}
- ]
-
- let getPano2 = (app)=>{
- if(panoData.p1.id != void 0){//老数据用的id, 因为slam场景无漫游点所以改为用pos
- return [
- app.fakeApp.panos.find(e=>e.sid == panoData.p1.id || e.id == panoData.p1.id),
- app.fakeApp.panos.find(e=>e.sid == panoData.p2.id || e.id == panoData.p2.id)
- ]
- }else{
- return [
- {position:new THREE.Vector3().copy(panoData.p1.pos1)},
- {position:new THREE.Vector3().copy(panoData.p2.pos1)}
- ]
- }
- }
-
- 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, targetPano )
- }//可能原因:漫游点改变
-
-
- return {sourcePano, targetPano}
- }else return {}
- }
-
-
- getTranPosData(data, convertInfo={}, ifRevert ){//根据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.convertMatrix){
- 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}
- }
-
- getCameraData(app){
- if(app.sceneType == 'laser'){
- let camera = app.viewer.mainViewport.camera
- return {
- position: camera.position.clone(),
- quaternion: camera.quaternion.clone(),
- fov: camera.fov,
- zoomLevel: app.viewer.images360.zoomLevel,
- }
- }else if(app.sceneType == 'kankan'){
- let player = app.app.core.get('Player')
- return {
- position: player.position.clone(),
- quaternion: player.quaternion.clone(),
- zoomLevel: player.zoomLevel,//fov: player.zoomFov,
- }
- }else{
- let bimViewer = app.viewer
- let info = bimViewer.getCameraStatus();
- return {
- position: info.position,
- target: info.target,
- fov: info.fov,
- }
- }
- }
-
-
- createFakeApp(app, addsubInfo){ //为每个app创建fakeApp, 里面包含了场景基本信息。
- if(!app.fakeApp){//不能重复建立,作为唯一标识
- let fakeApp = {
- isFake : true, //标志是虚拟的app。每个真实的app都要带一个这个。在移动端如果大的销毁了还有小的
- sceneType : app.sceneType,
- id : getId(),
-
- }
- if(app.sceneType != 'bim'){
- function getPanos(panos){ // only data
- return panos.map(e=>{return {id:e.id, sid:e.sid, 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)
- }
-
- Object.defineProperty(app,'fakeApp',{
- value: fakeApp,
- Configurable : false, //不可替换和删除
- })
-
- }
- if(addsubInfo){
- this.fakeAppUpdateInfo(app)
- }
- return app.fakeApp
- }
-
- fakeAppUpdateInfo(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,
- bumping: images360.bumping,
- isFlyToPano: !!images360.latestToPano
-
- }
- }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.bumping || fakeApp.viewInfo.isFlyToPano || fakeApp.viewInfo.displayMode == 'showPanos'){ //不改变漫游点,仅转换朝向
- if( fakeApp.viewInfo.quaternionChanged){
- let diffQua = customer.fakeApp == convertInfo.targetFakeApp ? convertInfo.diffQua : convertInfo.diffQuaInvert
- //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()
- } */
-
- if(customer.viewer.images360.zoomLevel != fakeApp.viewInfo.zoomLevel){
- customer.viewer.images360.zoomTo(fakeApp.viewInfo.zoomLevel , !0)
- //customer.viewer.mainViewport.camera.updateProjectionMatrix()
- }
- customer.Potree.settings.zoom.max = Math.max(fakeApp.viewInfo.zoomLevel, customer.Potree.settings.zoom.max);//防止最大只有2
- }
- }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)
- }
- }
-
- }
-
- laserSyncView(app,data){
- app.viewer.mainViewport.view.position.copy(data.position)
- app.viewer.mainViewport.view.lookAt(data.target)
- }
-
- laserCancelFly(app){//laser清除移动到下一个位置的动画
- app.viewer.images360.cancelFlyToPano()
- app.viewer.mainViewport.view.cancelFlying()
- }
-
- laserInit(app, mode){//加载完laser后立即初始化
- if(!app.viewer){
- return console.error('!app.viewer', app.viewer)
- }
- console.warn('laserInit', app.name, mode)
- this.laserMode = mode
- app.Potree.settings.displayMode = this.laserMode == 0 ? "showPanos" : "showPointCloud" //先修改否则一开始不一样后面位置同步不了
-
-
- app.viewer.images360.baseFov = app.Potree.config.view.fov //暂时加这一句,过后删除
-
- this.laserCancelFly(app)//app.viewer.images360.cancelFlyToPano()
- 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.pointDensity = 'high'
- app.Potree.settings.UserDensityPercent = 1; //在sdk里初始化了UserDensityPercent所以不能只用UserPointDensity了
- app.viewer.setPointLevels()
- app.Potree.settings.rotAroundPoint = false //去除原因:比较好同步,尤其当左边在当前点位,右边同步后却离开当前点位的话拖拽就会绕点旋转了
- setTimeout(()=>{//laser的代码中莫名会请求showPointCloud,所以尽量晚一点覆盖它,再确保一次
- if(app.Potree){
- app.Potree.settings.displayMode = this.laserMode == 0 ? "showPanos" : "showPointCloud"
- }
- }, this.settings.checkModeDelay)
-
- }
- laserChangeMode(mode){//整个页面的mode是统一的
- this.laserMode = mode
- }
-
- bimFlyTo(data){//bim修改位置,可渐变
- let info = bimViewer.getCameraStatus()
-
- let vec = new THREE.Vector3().subVectors(info.target, info.position)
- let radius = 10//vec.length() //修改了target到position的距离会影响pan时的速度
- let dir = vec.clone().normalize()
-
- let position = data.position
- if(!position){
- position = new THREE.Vector3().addVectors(info.position, dir.clone().multiplyScalar(data.forwardDis))//forwardDis:前进距离
- radius = Math.max(radius-data.forwardDis, data.minRadius || 0.7)
- }
- if(data.duration != void 0){
- bimViewer.getViewer().animator.setDuration(data.duration)//滚轮缩放时长,原先:1000
- }
-
- //console.log('radius',radius)
-
- let target = new THREE.Vector3().addVectors(position, dir.clone().multiplyScalar(radius))
- let msg = {//不能修改
- position,
- target,
- up: info.up, // 不能是Vector3(0,0,1),否则俯视时会不受控制打转
- //前三个缺一不可
-
- }
- bimViewer.setCameraStatus(msg)
-
- }
-
- flyToPano(app, panoId, position, o={}){
- if(app.sceneType == 'laser'){
- this.laserCancelFly(app)//app.viewer.images360.cancelFlyToPano()
- if(app.viewer.images360.panos.length == 0){//slam
- app.viewer.mainViewport.view.setView({position, duration:1000})
- }else{
-
- app.viewer.images360.flyToPano(Object.assign({},{
- pano: app.viewer.images360.getPano(panoId, (panoId+'').includes('|')?'sid':'id')
- },o))
- }
- }else{
- let player = app.app.core.get('Player')
- player.flyToPano(Object.assign({},{
- pano: player.model.panos.index[panoId]
- },o))
-
- }
- }
- lockCamera(locked){//禁止操作改变相机
- this.locked = locked
- this.updateCtrlEnable()
- }
- setPanoMode(state){
- this.isPanoMode = state
- this.updateCtrlEnable()
- }
- updateCtrlEnable(){//是否禁止bim响应操作
- this.bimViewer.camera3D.enableRotate(this.locked ? false : true)
- this.bimViewer.enableShortcutKey((this.locked || this.isPanoMode) ? false : true) //键盘移动
- }
-
- bimBindCamEvent(){//bim的分屏 是由另一方的camera带动bim的camera,故需要将bim的鼠标事件传递到另一边
- this.lockCamera(true)
-
-
- /* this.targetApp.viewer.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;
-
- if(o.dontClearTarget){
- if(this.sourceApp){
- this.lastFakeApp = this.sourceApp.fakeApp //记住当前左屏
- this.fakeAppUpdateInfo(this.sourceApp)
- }
- }else{
- this.targetApp = null
- this.lastFakeApp = null
- }
-
- this.sourceApp = null;
- this.dispatchEvent({type:'clearBind-sameType'})
- window.Log('clear done')
- }
-
- }
- let num = 0
- function getId(){
- return num++
- }
-
- /*
- note:
- 还不支持laser和4dkk同屏
- 访问:
-
- window.global__.sourceApp.fakeApp
- window.global__.targetApp.fakeApp
- window[1] 不准确,不一定是targetApp
- 旋转只能通过target设置, 不能直接改camera.quaternion
- 当且仅当发送方相机属性变化后才传递过来,就不在这里判断是否变化了。
- (所以只需要实时检测相机是否改变, hasChanged后发送)
- 如果角度同步有偏差,请查看
- computeAveDiffLon
- 如果位置同步有偏差,请查看
- computeShift,
- 添加label:
- window[1].viewer.images360.panos.forEach(e=>e.addLabel())
- */
-
- /*
- 其他代码:
-
- initTagAdd(){
- let markerConfig = new Bimface.Plugins.Marker3D.Marker3DContainerConfig();
- markerConfig.viewer = this.viewer;
- let tags = new Bimface.Plugins.Marker3D.Marker3DContainer(markerConfig);
- console.log('tags',tags)
-
- this.addEventListener('addTag',(e)=>{
- if(this.targetPano[e.index].tag){
- tags.removeItemById(this.targetPano[e.index].tag.id)
- }
- let position = new THREE.Vector3
- if(e.position){
- position.copy(e.position)
- }else{
- let currStatus = this.viewer.getCameraStatus()
- position.copy(currStatus.position)
- }
-
-
-
- let marker3dConfig = new Bimface.Plugins.Marker3D.Marker3DConfig();
-
- marker3dConfig.src = 'images/hotpoint'+ e.index +'.png'//"http://static.bimface.com/resources/3DMarker/warner/warner_red.png";
-
- marker3dConfig.worldPosition = new THREE.Vector3().copy(position)
- marker3dConfig.worldPosition.z -= belowHeight
- marker3dConfig.tooltip = '此为漫游点'+e.index //三维标签的提示
- let tag = new Bimface.Plugins.Marker3D.Marker3D(marker3dConfig);
- tags.addItem(tag);
- this.viewer.clearSelectedComponents();
- this.viewer.render();
- this.targetPano[e.index].tag = tag
- this.updatePanoMatch(position, e.index )
- })
- }
-
-
-
- this.viewer.addEventListener( Bimface.Viewer.Viewer3DEvent.MouseClicked, (objectData)=>{
-
- let position = objectData.worldPosition.clone().add({x:0,y:0,z:height});
- })
-
-
-
-
- addMesh(cameraData){
-
- var mesh = new Bimface.Plugins.Geometry.Plane({
- type:'rectangle', points:[{x:-0.1,y:-0.1,z:0},{x:0.1,y:0.1,z:0}]
- });
-
- var extObjMng = new Bimface.Plugins.ExternalObject.ExternalObjectManager(viewer2);
- extObjMng.loadObject({ name: 'plane', object: mesh});//作为外部构件添加到场景中
- //mesh.children[0].position.copy(cameraData.position).setZ(0.5)
- mesh.children[0].up.set(0,0,1)
- mesh.children[0].rotation.set(0,0,Math.PI/2)
-
- this.plane = mesh
- window.extObjMng = extObjMng
-
-
- }
-
- */
|