xzw 1 jaar geleden
bovenliggende
commit
405b3608e8

+ 1 - 1
src/custom/modules/panos/Images360.js

@@ -2170,7 +2170,7 @@ export class Images360 extends THREE.EventDispatcher{
                 }
             })
             this.highMapCube.visibleTiles = list.filter(e => e.score > -100)
-            list.forEach(e=>e.scoreLabel.setText(e.scores))
+            //list.forEach(e=>e.scoreLabel.setText(e.scores))
         }
 
         let needRecover = this.highMapCube.visibleTiles.filter(e => !e.material.map)

+ 8 - 3
src/custom/modules/panos/tile/TilePrioritizer.js

@@ -224,11 +224,16 @@ TilePrioritizer.prototype.filterDepthTex = function (panos ) {// 下载depthTex
     
     
      
-    let depTexDlCount = browser.isMobile() ? 1 : 2; 
+    let dlCount = browser.isMobile() ? 1 : 2; 
     
     let loadingCount = panos.filter(p=>p.depthTexLoading).length
-    if(loadingCount<depTexDlCount){
-        nearPanos.filter(p=>!p.depthTex).slice(0, depTexDlCount-loadingCount).forEach(p=>p.loadDepthImg())  
+    if(viewer.mapViewer){
+        let mapLayer = viewer.mapViewer.mapLayer 
+        loadingCount +=  mapLayer.loadingInProgress * 1.5 + mapLayer.waitQueue.length  
+    }
+    
+    if(loadingCount<dlCount){
+        nearPanos.filter(p=>!p.depthTex).slice(0, dlCount-loadingCount).forEach(p=>p.loadDepthImg())  
     }
     this.nearPanos = nearPanos; 
 }

+ 26 - 4
src/custom/modules/siteModel/SiteModel.js

@@ -105,19 +105,41 @@ var SiteModel = {
         //console.log('changedCallback')
     },
     
-    updateEntityAt(force){
+    updateEntityAt(force,{measure}={}){
         //if(!this.entities.length || this.editing) return //编辑时也要根据位置显示不同楼层的漫游点与cad
         
         let fun = ()=>{ //延时update,防止卡顿
             let currPos = viewer.mainViewport.view.position
-            
+            if(this.pauseUpdateEntity)return // console.error('pauseUpdateEntity')
             //if(force   || !currPos.equals(this.lastPos) ){
                 //console.log('currPos ', currPos.toArray())
                 this.lastPos.copy(currPos)
                 let entity;
                 
-                let searchPos = Potree.settings.displayMode == 'showPanos' ? viewer.images360.currentPano : currPos
-                entity = this.pointInWhichEntity(searchPos, 'room');
+                
+                if(measure){//因为测量线的点可能在多个房间,所以干脆直接找在哪个楼层
+                    let list = []
+                    measure.points.forEach(e=>{
+                        let entity = this.pointInWhichEntity(e, 'floor' )//每个点都找到其所在楼层
+                        let item = list.find(e=>e.entity == entity); 
+                        if(item){
+                            item.count ++ 
+                        }else{
+                            list.push({entity, count:1})
+                        }
+                    })
+                    list.sort((a,b)=>{return b.count-a.count})//找出出现次数最多的楼层
+                    if(list[0]){
+                        entity = list[0].entity
+                    }
+                }else{
+                    let searchPos = Potree.settings.displayMode == 'showPanos' ? viewer.images360.currentPano : currPos
+                    entity = this.pointInWhichEntity(searchPos, 'room');  
+                }
+                
+                
+                 
+                
                 
                 if(force || this.inEntity != entity ){
                     let oldEntity = this.inEntity

+ 3 - 10
src/custom/objects/tool/Measure.js

@@ -1030,22 +1030,15 @@ export class Measure extends ctrlPolygon{
 }
 
 
-
-
-
-
-
-
+ 
 
 function setLabelHightState(label, state){
     if(state){ 
-        label.backgroundColor =  {r: highlightColor.r*255, g: highlightColor.g*255, b: highlightColor.b*255, a:config.measure.highlight.opacity},
-        label.backgroundColor.a = config.measure.highlight.opacity
+        label.setBackgroundColor({r: highlightColor.r*255, g: highlightColor.g*255, b: highlightColor.b*255, a:config.measure.highlight.labelOpacity})
         label.sprite.material.useDepth = false;
         
     }else{
-        label.backgroundColor = mainLabelProp.backgroundColor
-        label.backgroundColor.a = config.measure.default.opacity
+        label.setBackgroundColor(mainLabelProp.backgroundColor)  
         label.sprite.material.useDepth = true
         
     } 

+ 18 - 4
src/custom/objects/tool/ctrlPolygon.js

@@ -85,7 +85,7 @@ export class ctrlPolygon extends THREE.Object3D {
                 } 
             }  
             
-            this.getFacePlane()
+            this.facePlane = this.getFacePlane()
             this.getPoint2dInfo(this.points)
             
             this.update({ifUpdateMarkers:true})
@@ -479,10 +479,24 @@ export class ctrlPolygon extends THREE.Object3D {
         return true
     };
     
+     
     getFacePlane(){//最普通一种get方法,根据顶点。且假设所有点已经共面,且不重合
-        if(!this.atPlane || this.points.length<3) return
-        this.facePlane = new THREE.Plane().setFromCoplanarPoints(...this.points.slice(0,3) )
-         
+        if(/* !this.atPlane ||  */this.points.length<3) return
+        /* this.facePlane = new THREE.Plane().setFromCoplanarPoints(...this.points.slice(0,3) ) */ 
+        let facePlane = this.facePlane
+        if(!this.atPlane || !facePlane){//多折线 没有实时更新facePlane所以重新算
+            let normal = new THREE.Vector3, len = this.points.length - 2
+            for(let i=0;i<len;i++){
+                let vec0 = new THREE.Vector3().subVectors(this.points[i], this.points[i+1])
+                let vec1 = new THREE.Vector3().subVectors(this.points[i+2], this.points[i+1])
+                let nor = vec0.cross(vec1).normalize();
+                normal.add(nor)
+            }
+            normal.normalize(); 
+            facePlane = new THREE.Plane().setFromNormalAndCoplanarPoint(normal, center)  
+        } 
+        return facePlane
+    
     }
     
     getPoint2dInfo(points){ //在更新areaplane之前必须更新过point2dInfo

+ 1 - 1
src/custom/potree.shim.js

@@ -1486,7 +1486,7 @@ Potree.updateVisibility = function(pointclouds, camera, areaSize){
             //console.log('load done!')
             setTimeout(()=>{
                 Potree.pointsLoading || viewer.dispatchEvent('pointsLoaded')
-            },50) 
+            },document.hidden ? 100 : 50) 
         } 
     }
     

+ 4 - 3
src/custom/settings.js

@@ -172,12 +172,13 @@ const config = {//配置参数   不可修改
             opacity:0.7
         },
         highlight:{
-            color:'#00C8AF',//"#00c7b2",
-            opacity:1
+            color:'#00C8AF',//"#00c7b2", 
+            opacity:1,
+            labelOpacity:0.7//1会挡住线和端点
         },
         guide:{
             color:'#FFFFFF', 
-            opacity:1
+            opacity:0.8
         }
         ,   
         backColor:'#333333',

+ 17 - 1
src/custom/start.js

@@ -121,12 +121,28 @@ export function start(dom, mapDom, number ){ //t-Zvd3w0m
                         }) 
                     }else{//SG-t-DXmdymgZ2sX 无漫游点
                         //从bounding的外部看向中心 
-                        let bound = viewer.bound.boundingBox.clone()  
+                        /* let bound = viewer.bound.boundingBox.clone()  
                         let hopeSize = new THREE.Vector3(30,30,20).min(viewer.bound.boundSize)//希望看到的范围 
                         bound.expandByVector(new THREE.Vector3().subVectors(hopeSize,viewer.bound.boundSize).multiplyScalar(0.5))
                         bound.min.z = viewer.bound.boundingBox.min.z+0.5//z集中于地面
                         bound.max.z = bound.min.z+hopeSize.z 
+                        viewer.focusOnObject({boundingBox:bound},'boundingBox',0,{dontChangeCamDir:true}) */
+                        //SG-t-XPf1k9pv3Zg 总有极端的场景,如这是倾斜的桥 - -, 只能调整为看到全局了
+                        const far = 20
+                        viewer.mainViewport.camera.far = 10000
+                        let bound = viewer.bound.boundingBox.clone()
+                        // bound.expandByVector(new THREE.Vector3().subVectors(hopeSize,viewer.bound.boundSize).multiplyScalar(0.5))                        
                         viewer.focusOnObject({boundingBox:bound},'boundingBox',0,{dontChangeCamDir:true})
+                        //等有点云加载出来后,再去focus其中一个,使camera.far不超过最大值
+                        
+                        viewer.addEventListener('pointcloud_changed',()=>{
+                            setTimeout(()=>{
+                                console.log(viewer.visibleNodes)
+                            },50)
+                        },{once:true})
+                        
+                        
+                        
                         
                     }
                 } 

+ 115 - 88
src/custom/viewer/ViewerNew.js

@@ -190,11 +190,8 @@ export class Viewer extends ViewerBase{
          
         this.fakeMeasure = {};
          
-        document.addEventListener('visibilitychange',(e)=>{ 
-            //console.log('visibilitychange', !document.hidden )
-            this.dispatchEvent({type:'pageVisible', v:!document.hidden} )
-              
-        })
+         
+       
         
          
             
@@ -802,7 +799,24 @@ export class Viewer extends ViewerBase{
             
             
         } 
-        
+        { 
+            let interval 
+            document.addEventListener('visibilitychange',(e)=>{ 
+                let v = !document.hidden
+                console.warn('visibilitychange', v )
+                this.dispatchEvent({type:'pageVisible', v } )
+                
+                if(this.screenshoting && !v){
+                    interval = setInterval(()=>{
+                        if(this.screenshoting){ //截图完成时如果还没回来就不loop
+                            this.loop(Date.now()) 
+                        }
+                    },30)  
+                }else if(v && interval){
+                    clearInterval(interval)
+                }   
+            })
+        }
         
         /* if(!Potree.isIframeChild){
             window.winIndex = 0;
@@ -3487,7 +3501,8 @@ export class Viewer extends ViewerBase{
                 //离屏渲染 有抗锯齿问题、在手机上速度慢
                 var { dataUrl  } = viewerMaster.makeScreenshot( new THREE.Vector2(width,height), null, compressRatio    );
                 
-            }else{
+            }else{ 
+                
                 //直接渲染 会改变canvas大小
                 let canvas = this.renderArea.getElementsByTagName('canvas')[0] 
                 this.render({  screenshot : true,   width , height,   resize :true  }); //需要resize
@@ -3548,6 +3563,7 @@ export class Viewer extends ViewerBase{
                  
                 
                 if(info.type == 'measure'){
+                    this.modules.SiteModel.pauseUpdateEntity = false
                     this.scene.measurements.forEach(e=>Potree.Utils.updateVisible(e, 'screenshot',true))
                     info.measurement.setSelected(false, 'screenshot')
                 }
@@ -3620,9 +3636,7 @@ export class Viewer extends ViewerBase{
             oldStates.viewports.push(mapViewport.clone())  
             oldStates.attachedToViewer = this.mapViewer.attachedToViewer
             oldStates.mapZoom = mapViewport.camera.zoom
-            
-            
-            
+             
             Potree.Utils.updateVisible(this.mapViewer.cursor, 'screenshot', false)//令mapCursor不可见
         }
          
@@ -3634,8 +3648,7 @@ export class Viewer extends ViewerBase{
             }) 
         }                    
         Potree.Utils.updateVisible(this.reticule, 'screenshot', false)//令reticule不可见 
-                            
-                            
+                                  
         Potree.settings.pointDensity = 'screenshot'
         
         
@@ -3662,7 +3675,7 @@ export class Viewer extends ViewerBase{
             }
             
             
-            let maxTime = 2000
+            let maxTime = 1000
             setTimeout(()=>{
                 if(Potree.pointsLoading && Potree.settings.displayMode == 'showPointCloud'){//如果还在加载 
                     
@@ -3670,39 +3683,18 @@ export class Viewer extends ViewerBase{
                         //if(!finish)console.warn('加载完毕', ' numVisiblePoints', Potree.numVisiblePoints)                         
                         dealDone()
                     },{once:true})
-                    let lastNumVisiblePoints  
-                    /* { //perspective的不需要,远处加载不完也没大碍
-                        setTimeout(()=>{//超时不候 
-                            if(!finish ){
-                                console.warn('加载时间达最长限制的50%,降level, numVisiblePoints', Potree.numVisiblePoints)  
-                                lastNumVisiblePoints = Potree.numVisiblePoints      
-                                decreaseLevel() //加载时间过长 
-                            } 
-                        },maxTime*0.5)
-                        setTimeout(()=>{// 第一次降有可能没效果,因为大部分level不是最高的
-                            console.warn('加载时间达最长限制的60%,numVisiblePoints', Potree.numVisiblePoints)        
-                            if(!finish && (Potree.numVisiblePoints - lastNumVisiblePoints) > -20000  ){ //没怎么降
-                                console.warn('加载时间达最长限制的60%,降level, numVisiblePoints', Potree.numVisiblePoints)        
-                                decreaseLevel() //加载时间过长
-                            } 
-                        },maxTime*0.6)
-                    } */
-                    setTimeout(()=>{//超时不候 
+                     
+                     
+                    setTimeout(()=>{//超时不候(其实之后等待地图还会再加载几秒)
                         //if(!finish)console.warn('超时, numVisiblePoints', Potree.numVisiblePoints)  
                         dealDone()
                     },maxTime)
                 }else{
                     dealDone()
                 } 
-            },200)//先加载一段时间
-            
-            
-             
+            },200)//先加载一段时间  
         }
-        
-            
-        let waitPointsTime = Potree.settings.displayMode == 'showPointCloud' ? 300 : 0 //等点云加载  
-        
+         
         
         if(info.type == 'measure'){//要截图双屏 
             this.scene.measurements.forEach(e=>Potree.Utils.updateVisible(e,'screenshot',e == info.measurement)  )
@@ -3721,35 +3713,36 @@ export class Viewer extends ViewerBase{
                 updateCamera() 
                 if(useMap){
                     let waitMap = ()=>{
-                        console.log('waitMap: '+sid, Date.now(), this.mapViewer.mapLayer.loadingInProgress ) 
+                        console.log('waitMap: '+sid, Date.now(), this.mapViewer.mapLayer.loadingInProgress )  
                         this.mapViewer.waitLoadDone(screenshot.bind(this))//等待地图所有加载完 
-                    }  
-                    
-                    waitPointLoad(waitMap)
-                    
-                    //setTimeout(waitMap.bind(this), waitPointsTime)  
-                }else{ 
-                    //setTimeout(screenshot.bind(this), waitPointsTime)
+                    }   
+                    waitPointLoad(waitMap) 
+                }else{  
                     waitPointLoad()
                 } 
             }
             
-            let {promise} = this.focusOnObject(info.measurement, 'measure', 0,     {basePanoSize:1024}  )//注意:不同角度截图 得到三维的会不一样,因为focusOnObject是根据方向的
+            let {promise} = this.focusOnObject(info.measurement, 'measure', 0, {
+                basePanoSize:1024,  gotoBestView:true,
+                minMapWidth: this.mapViewer.mapLayer.maps.find(e=>e.name == 'map').disabled ? 10 : 20  //有地图的话为了显示出名字需要更大范围
+            })//注意:不同角度截图 得到三维的会不一样,因为focusOnObject是根据方向的
             promise.done(()=>{  
                 //console.log('promise.done') 
                 //根据当前位置更新floorplan显示
                 //console.log('view Pos ', this.mainViewport.view.position.toArray())
-                this.updateDatasetAt(true) 
-                this.modules.SiteModel.updateEntityAt(true) 
+                 
+                this.updateDatasetAt(true)  
+                this.modules.SiteModel.updateEntityAt(true, {measure:info.measurement}) //更新测量线所在楼层,展示俯视图
+                this.modules.SiteModel.pauseUpdateEntity = true
                 //this.updateFpVisiDatasets() 
                 
                 //console.log('currentFloor', this.modules.SiteModel.currentFloor, 'currentDataset', this.atDatasets )    
-                 
+           
                 let floorplanShowed = this.mapViewer.mapLayer.maps.some(e => e.name.includes('floorplan') && e.objectGroup.visible)//如果没有floorplan展示就不分屏(如果focus时飞出数据集从而不展示怎么办。尤其是俯瞰比较长的线时容易这样,或许要根据其所在数据集强制显示)
                 if(!floorplanShowed && this.mapViewer.attachedToViewer){ 
                     this.mapViewer.attachToMainViewer(false) //取消分屏
                     viewer.updateScreenSize({forceUpdateSize:true, width, height}) //更新viewports相机透视
-                    let {promise} = this.focusOnObject(info.measurement, 'measure', 0,     {basePanoSize:1024}  )//因画面比例更改,重新focus
+                    let {promise} = this.focusOnObject(info.measurement, 'measure', 0,     {basePanoSize:1024,gotoBestView:true,}  )//因画面比例更改,重新focus
                     promise.done(()=>{ 
                         begin()  
                     }) 
@@ -3891,41 +3884,74 @@ export class Viewer extends ViewerBase{
         if (type == 'measure') {  
             target.copy(object.getCenter()) 
         
-              
-            
             //试试改变位置(方向),直视测量线。能避免倾斜角度造成的非常不居中、以及看不到面的情况 
-            if(object.points.length>2/*  && window.focusMeasureFaceToIt */){
-                
-                let facePlane = object.facePlane || new THREE.Plane().setFromCoplanarPoints(...object.points.slice(0,3) )
-                let normal = facePlane.normal.clone()                
-                let angle = this.scene.view.direction.angleTo(normal)
-                let minDiff = THREE.Math.degToRad(60) 
-                //console.log('angle',angle)
-                if(angle>minDiff && angle<Math.PI-minDiff){//当几乎正对时就不执行
-                    if(angle<Math.PI/2){ //在背面
-                        normal.negate()
-                    }
-                    let dir = new THREE.Vector3().subVectors(camera.position, target).normalize() 
-                    let newDir = new THREE.Vector3().addVectors(dir,normal)//两个角度的中间
-                    cameraPos.copy(target.clone().add(newDir))
-                }   
-            }else if(object.points.length == 2){ //线段
-                let lineDir = new THREE.Vector3().subVectors(object.points[0],object.points[1]).normalize()
-                let angle = this.scene.view.direction.angleTo(lineDir)
-                let maxDiff = Math.PI*0.25// 45度
-                if(angle<maxDiff || angle>Math.PI-maxDiff){//当几乎正对时就不执行
-                    if(angle>Math.PI/2){  //令dir和lineDir成钝角
-                        lineDir.negate()
+            if(o.gotoBestView){//直接沿着法线方向看
+                if(object.points.length>2){
+                    let facePlane = object.getFacePlane(target) 
+                    let normal = facePlane.normal.clone();
+                    
+                    if(normal.dot(this.mainViewport.view.direction) > 0){
+                        normal.negate() //顺着视线
                     } 
-                    let dir = new THREE.Vector3().subVectors(camera.position, target).normalize() 
-                    let mid = new THREE.Vector3().addVectors(lineDir, dir).normalize() //中间法向量(如果刚好dir和lineDir反向,那得到的为零向量,就不移动了,但一般不会酱紫吧)
-                    let newDir = new THREE.Vector3().addVectors(dir, mid)
-                    cameraPos.copy(target.clone().add(newDir))
-                } 
+                    //normal.z = Math.max(0.2, normal.z)//尽量不要仰视
+                    cameraPos.copy(target).add(normal)
+                }else{
+                    let lineDir = new THREE.Vector3().subVectors(object.points[0],object.points[1]).normalize()
+                    let facePlane = new THREE.Plane().setFromNormalAndCoplanarPoint(lineDir, target) 
+                    //if(cameraPos.z < target.z + 1)cameraPos.z = target.z + 1//尽量不要仰视
+                    
+                    let dir = new THREE.Vector3().subVectors(cameraPos,target).normalize()
+                    dir.z = Math.max(dir.z, 0.4);
+                    cameraPos.copy(target).add(dir)//尽量不要仰视 
+                    
+                    
+                    let dis = cameraPos.distanceTo(target)
+                    dir = lineDir.clone().multiplyScalar(dis) 
+                    let line = new THREE.Line3().set(cameraPos.clone().add(dir), cameraPos.clone().add(dir.negate())) //过相机位置作到面的垂线
+                    facePlane.intersectLine(line, cameraPos ) //得垂足,作为新的相机位置。就能在测量线中间看测量线
+                    
+                }
             }else{
-                console.error('measure 没有facePlane points点数还不为2?')
-            } 
-
+                if(object.points.length>2){ 
+                    let facePlane = object.getFacePlane(target) 
+                    let normal = facePlane.normal.clone()                
+                    let angle = this.scene.view.direction.angleTo(normal)
+                    let minDiff = THREE.Math.degToRad(60) 
+                    //console.log('angle',angle)
+                    if(angle>minDiff && angle<Math.PI-minDiff){//当几乎正对时就不执行
+                        if(angle<Math.PI/2){ //在背面
+                            normal.negate()
+                        }
+                        let dir = new THREE.Vector3().subVectors(camera.position, target).normalize() 
+                        let newDir = new THREE.Vector3().addVectors(dir,normal)//两个角度的中间
+                        cameraPos.copy(target.clone().add(newDir))
+                    }   
+                }else if(object.points.length == 2){ //线段
+                    let lineDir = new THREE.Vector3().subVectors(object.points[0],object.points[1]).normalize()
+                    let angle = this.scene.view.direction.angleTo(lineDir)
+                    let maxDiff = Math.PI*0.25// 45度
+                    if(angle<maxDiff || angle>Math.PI-maxDiff){//当几乎正对时就不执行
+                        if(angle>Math.PI/2){  //令dir和lineDir成钝角
+                            lineDir.negate()
+                        } 
+                        let dir = new THREE.Vector3().subVectors(camera.position, target).normalize() 
+                        let mid = new THREE.Vector3().addVectors(lineDir, dir).normalize() //中间法向量(如果刚好dir和lineDir反向,那得到的为零向量,就不移动了,但一般不会酱紫吧)
+                        let newDir = new THREE.Vector3().addVectors(dir, mid)
+                        cameraPos.copy(target.clone().add(newDir))
+                    } 
+                }else{
+                    console.error('measure 没有facePlane points点数还不为2?')
+                }  
+            }   
+            //截图时直接飞到最佳视角,也就是平视它所在面。其余时候为了避免镜头旋转过大就算了。
+            
+            
+            
+            
+            
+            
+            
+            
              
             position = getPosWithFullBound(object.points, null, target, cameraPos  )
             
@@ -3934,7 +3960,8 @@ export class Viewer extends ViewerBase{
             
             if(this.mapViewer/* .attachedToViewer */){ 
                 //console.log('mapFocusOn: '+target.toArray())
-                const minBound = new THREE.Vector2(2,2)//针对垂直线,在地图上只有一个点
+                const minMapWidth = o.minMapWidth || 2 //截图的时候要显示的地图范围较大,为了显示出地区名字
+                const minBound = new THREE.Vector2(minMapWidth,minMapWidth)//针对垂直线,在地图上只有一个点
                 //原始的bound
                 let boundOri = new THREE.Box3() 
                 object.points.forEach(e=>{ 
@@ -3955,7 +3982,7 @@ export class Viewer extends ViewerBase{
             if(Potree.settings.displayMode == 'showPointCloud'){  //点云 
                 let minDis = 0.3;
                 
-                //if(o.checkIntersect){
+                if(0 ){//如果没有被选中,会被遮挡。 2023.11.15 最好展示全局(尤其截图时),虽然被遮挡,但focus的过程是选中状态全显示的,可以看出所在范围。
                     let checkIntersect = ( )=>{ 
                         let intersect = this.inputHandler.ifBlockedByIntersect({pos3d:position, cameraPos: target})// 不一定准确
                         if(intersect){ 
@@ -4009,7 +4036,7 @@ export class Viewer extends ViewerBase{
                     
                     checkIntersect() 
                     //多折线没有areaPlane 有时候会看向空白区域 - -
-                //}      
+                }      
             }else if(Potree.settings.displayMode == 'showPanos'){//全景 (比较难校准)
                 let target2, dir
                 if( object.measureType.includes('MulDistance')){//因为该线不闭合,可能看向target的方向会没有线,所以换一个target
@@ -4423,7 +4450,7 @@ export class Viewer extends ViewerBase{
 
 	loop(timestamp){
         //let startTime = performance.now()
-        //console.log('间隔:' ,parseInt((startTime - this.lastEndTime)*100 )/100)
+        console.log('间隔:' /*, parseInt((startTime - this.lastEndTime)*100 )/100 */)
         if(this.paused)return
         if(performance.getEntriesByName("loopWaitNext-start").length)viewer.addTimeMark('loopWaitNext','end') 
         

+ 45 - 28
src/custom/viewer/map/Map.js

@@ -54,7 +54,7 @@ export class MapLayer extends THREE.EventDispatcher{ // 包括了 MapLayerBase S
         super()
         this.sceneGroup = new THREE.Object3D;
         this.sceneGroup.name = "MapLayer" 
-         
+        this.waitQueue = [] //等待加载的
         
         this.loadingInProgress = 0
         this.maps = [] 
@@ -338,20 +338,27 @@ export class TiledMapBase extends THREE.EventDispatcher{
         i.y *= s / 2;
         
         
-        //add 高纬度的因倾斜而造成tile较小,所以放大些,否则会造成显示的tile过多而卡
-        let lonlat = viewer.transform.lonlatToLocal.inverse(viewport.camera.position.clone()) 
-        let cos = Math.cos(THREE.Math.degToRad(lonlat.y)); //越小就在纬度上越高,tile表现越小
-        //为什么lonlat.y会超出90?
-        /* if(lonlat.y>90){
-            console.log('lonlat.y>90',lonlat.y)
-        }  */
-        
-        cos = THREE.Math.clamp(cos, 0,1)
-        let lonShift =  Math.abs(viewer.mapViewer.camera.position.x / this.mapSizeM * 16  )  //越大就在经度离中心越远,tile表现越大  。  
-        lonShift = THREE.Math.clamp(lonShift, 0, Math.PI)
-        lonShift = (1 - Math.sin( 1/2 * lonShift +  Math.PI/2 )) * Math.PI // 0-Math.PI   sin增速向上
+         
+        let scale  
+        if(this.name == 'map'){ 
+            //add 高纬度的因倾斜而造成tile较小,所以放大些,否则会造成显示的tile过多而卡
+            let lonlat = viewer.transform.lonlatToLocal.inverse(viewport.camera.position.clone()) 
+            let cos = Math.cos(THREE.Math.degToRad(lonlat.y)); //越小就在纬度上越高,tile表现越小
+            //为什么lonlat.y会超出90?
+            /* if(lonlat.y>90){
+                console.log('lonlat.y>90',lonlat.y)
+            }  */
+            
+            cos = THREE.Math.clamp(cos, 0,1)
+            let lonShift =  Math.abs(viewer.mapViewer.camera.position.x / this.mapSizeM * 16  )  //越大就在经度离中心越远,tile表现越大  。  
+            lonShift = THREE.Math.clamp(lonShift, 0, Math.PI)
+            lonShift = (1 - Math.sin( 1/2 * lonShift +  Math.PI/2 )) * Math.PI // 0-Math.PI   sin增速向上
+            
+            scale = 0.5 * cos * (1+lonShift)  +  0.5 * Math.pow(cos, lonShift)   
+        }else{
+            scale = 1
+        }
         
-        let scale = 0.5 * cos * (1+lonShift)  +    0.5 * Math.pow(cos, lonShift)   
         var c = this.tileSizePx / i.length() / scale      //多除以一个scale缩放因子,scale越大level越小
           , level = Math.ceil(-Math.log(c) / Math.log(2) - this.bias);
          
@@ -444,18 +451,19 @@ export class TiledMapBase extends THREE.EventDispatcher{
 
 
 
-const waitQueue = [] //等待加载的
+ 
 const loadDone = (tile, success)=>{
     tile.map.mapLayer.loadingInProgress--
     tile.map.loadingInProgress--
-    
+    //console.log('loaddone', tile.name, 'loadingInProgress',tile.map.mapLayer.loadingInProgress, Date.now())
     tile.loading = false
      
-    let next = waitQueue[0]
+    let next = tile.map.mapLayer.waitQueue[0]
     if(next){
         addLoadTile(next)
     }else{
-        if(tile.map.mapLayer.loadingInProgress == 0){
+        if(tile.map.mapLayer.loadingInProgress == 0){//注意这时候不一定就加载完了,300ms后可能还会有新的tile加载
+            //console.log('loadDone All ?', Date.now())
             tile.map.mapLayer.dispatchEvent('loadDone') 
         }
     }
@@ -470,11 +478,13 @@ function addLoadTile(tile){
 
         tile.map.mapLayer.loadingInProgress++ 
         tile.map.loadingInProgress ++ 
+        tile.map.mapLayer.dispatchEvent('startLoad') 
+        //console.log('addLoad', 'loadingInProgress',tile.map.mapLayer.loadingInProgress, Date.now())
         //tile.texURL && tile.texURL.includes('testdata') && console.log('addLoadTile',   tile.texURL.split('map_tiles/')[1] )
          
         tile.loading = true
-        let index = waitQueue.indexOf(tile);
-        index > -1 && waitQueue.splice(index,1)
+        let index = tile.map.mapLayer.waitQueue.indexOf(tile);
+        index > -1 && tile.map.mapLayer.waitQueue.splice(index,1)
         
         
         let tex = tile.mesh.material.map = texLoader.load(tile.texURL, (tex)=>{      //如果一直加载不了会影响其他的加载,如google地图没有vpn会使全景图一直加载不了
@@ -513,16 +523,14 @@ function addLoadTile(tile){
         tex.magFilter = THREE.LinearFilter 
           
     }else{
-        waitQueue.includes(tile) || waitQueue.push(tile) 
+        tile.map.mapLayer.waitQueue.includes(tile) || tile.map.mapLayer.waitQueue.push(tile) 
     }
     
 }
-function cancelLoad(tile,log){//如果等待加载,但还没开始加载,取消加载
- 
-    
+function cancelLoad(tile,log){//如果等待加载,但还没开始加载,取消加载 
     if(!tile.loading){ 
-        let index = waitQueue.indexOf(tile);
-        index > -1 && waitQueue.splice(index,1)   
+        let index = tile.map.mapLayer.waitQueue.indexOf(tile);
+        index > -1 && tile.map.mapLayer.waitQueue.splice(index,1)   
         //index > -1 && tile.texURL && tile.texURL.includes('testdata') && console.log('cancelLoad',   tile.texURL.split('map_tiles/')[1]/* ,  (log && waitQueue.indexOf(tile)>-1) ? log:'' ,  tile.loading */ )
   
     } 
@@ -807,7 +815,12 @@ export class TiledMapFromEntity extends TiledMapBase{
         //this.projection = n.crsLocal,
         this.zIndex = 0, 
         this.tilePresenceMap = this.decodeBitStream(this.tiledMapEntity.quadtree) //包含tile分裂信息,如果写错了会造成tile显示不全
-         
+        this.maxLoading = 5
+        this.bias = 0.5   //越大加载层级越低,越模糊 
+        
+        if(window.devicePixelRatio>=2 && window.innerHeight * window.innerWidth < 768*1024){ //手机还是加载高清点(反正也不需要截图等待),但平板太大了,要铺满屏幕可能慢,所以稍微模糊点?(反正可以继续放大去看)
+            this.bias = 0 //level更高些
+        }
     }
   
     fillFromData(e){ 
@@ -959,7 +972,7 @@ export class TiledMapFromEntity extends TiledMapBase{
  
  
  
- 打印所有mapTile的名字,字符串最长的代表有显示的mesh。
+ 打印所有mapTile的名字,字符串最长的代表有显示的mesh。  
  viewer.mapViewer.mapLayer.maps[0].baseTile.traverse(function(e){console.log(e.name)})
  
  
@@ -967,6 +980,10 @@ export class TiledMapFromEntity extends TiledMapBase{
  viewer.mapViewer.mapLayer.maps[0].objectGroup.children
  
  
+ 图片地址中 tiles/4/3/9.png 第一个数字越高代表level越高,放得越大 . (tile.name.length也能反映出
+ viewer.mapViewer.mapLayer.maps[1].objectGroup.children.map(e=>e.name.length)
+ 
+ 
  目前看的几个场景floorplan原图是1米=33.03个像素  图宽度= 512*2^(max_depth-1) ,   map_size_m 代表整个地图是多少米
  
 

+ 28 - 11
src/custom/viewer/map/MapViewer.js

@@ -157,21 +157,38 @@ export class MapViewer extends ViewerBase{
     
     
     
-    waitLoadDone(callback){//确保加载完后执行
-        if(this.mapLayer.loadingInProgress == 0){
-            callback()
-        }else{
-            var f = ()=>{
-                setTimeout(()=>{
-                    callback()
-                },500) //等待tex准备好 能渲染出来
-                this.mapLayer.removeEventListener('loadDone', f)
-            } 
-            this.mapLayer.addEventListener('loadDone', f)  
+    waitLoadDone(callback){//确保加载完后执行 
+        let timer, maxWaitTime = 500; //等待一段时间看有没有新加载的tile,如果超过这个时间没有就不等了,算加载结束
+     
+        let pauseCountDown = ()=>{//重新等待加载结束,中断倒计时 
+            clearTimeout(timer) 
+            //console.log('pauseCountDown')
         }
         
+        let freshCountDown = ()=>{//刷新倒计时
+            //console.log('freshCountDown') 
+             
+            clearTimeout(timer) 
+            timer = setTimeout(()=>{   
+                this.mapLayer.removeEventListener('loadDone', freshCountDown)
+                this.mapLayer.removeEventListener('startLoad', pauseCountDown) 
+                callback() 
+            },maxWaitTime)    
+        } 
+           
+        
+        this.mapLayer.addEventListener('loadDone', freshCountDown) 
+        this.mapLayer.addEventListener('startLoad', pauseCountDown)
+        if(this.mapLayer.loadingInProgress == 0){
+            freshCountDown()
+        }
     }
     
+    
+    
+    
+    
+    
     addListener(images360){
         images360.addEventListener('flyToPano',e=>{
             let toPano = e.toPano