Jelajahi Sumber

增加6k漫游点。没完全改完,太复杂。如假设maxRenderSize是4k,当加入6k时创建了highCube,那zoomRenderTarget还没删。

xzw 2 minggu lalu
induk
melakukan
3a56025e4a

+ 2 - 0
src/Potree.js

@@ -620,6 +620,8 @@ export function load4dkkPanos(sceneCode, model, defaultRotation, done, tileRes){
         mapping: model.props.raw.mapping
     }
     model.tileRes = tileRes
+    Potree.Utils.setTileClass(model, model.tileRes)    
+    
     model.bound = new THREE.Box3
     
     let path 

+ 63 - 58
src/custom/mergeStartTest.js

@@ -160,10 +160,8 @@ var start = function(dom, mapDom, number, fileServer, webSite){ //t-Zvd3w0m
         if(data.length>1)console.log('该场景有多个数据集只取第一个')    
         data = [data[0]] //只需要一个
         Potree.datasetData = data
-        viewer.transform = null
-        var datasetLength = data.length 
-        var pointcloudLoaded = 0
-        var panosLoaded = 0
+       
+       
         var pointcloudLoadDone = function(){//点云cloud.js加载完毕后 
             viewer.updateModelBound()
             let {boundSize, center} = viewer.bound
@@ -176,11 +174,6 @@ var start = function(dom, mapDom, number, fileServer, webSite){ //t-Zvd3w0m
             
             
             if(!ifReload){    
-                /* viewer.scene.view.setView({ 
-                    position: center.clone().add(new THREE.Vector3(10,5,10)), 
-                    target: center
-                }) */
-                 
                 viewer.dispatchEvent({type:'loadPointCloudDone'})
             
                 if(!Potree.settings.UserPointDensity){
@@ -239,10 +232,8 @@ var start = function(dom, mapDom, number, fileServer, webSite){ //t-Zvd3w0m
              
         }
         
-        if(!Potree.settings.originDatasetId)Potree.settings.originDatasetId = data[0].id
-        var originDataset =  data.find(e=>e.id == Potree.settings.originDatasetId)  
-        
-        {//拿初始数据集作为基准。它的位置是000
+     
+        /* {//拿初始数据集作为基准。它的位置是000
             var locationLonLat = originDataset.location.slice(0,2)
             proj4.defs("NAVVIS:TMERC", "+proj=tmerc +ellps=WGS84 +lon_0=" + locationLonLat[0].toPrecision(15) + " +lat_0=" + locationLonLat[1].toPrecision(15));
             proj4.defs("WGS84", "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs");
@@ -259,7 +250,7 @@ var start = function(dom, mapDom, number, fileServer, webSite){ //t-Zvd3w0m
             viewer.mapViewer && viewer.mapViewer.mapLayer.maps[0].updateProjection()
             
         }  
-          
+           */
         
         data.forEach((dataset,index)=>{  
             if(!ifReload){
@@ -282,7 +273,7 @@ var start = function(dom, mapDom, number, fileServer, webSite){ //t-Zvd3w0m
                     let material = pointcloud.material; 
                     
                     pointcloud.datasetData = dataset
-                    
+                    Potree.Utils.setTileClass(pointcloud, pointcloudsList[curPointIndex].resolution || dataset?.sceneResolution) 
                     material.minSize =  config.minSize
                     material.maxSize =  config.maxSize   
                     material.pointSizeType = config.pointSizeType //Potree.PointSizeType[config.pointSizeType]//Potree.PointSizeType.ADAPTIVE;//FIXED
@@ -292,18 +283,14 @@ var start = function(dom, mapDom, number, fileServer, webSite){ //t-Zvd3w0m
                     pointcloud.color = pointcloud.material.color = dataset.color  
                     pointcloud.dataset_id = dataset.id;//供漫游点找到属于的dataset点云
                     pointcloud.timeStamp = timeStamp 
-                    transformPointcloud(pointcloud,dataset)
-                    scene.addPointCloud(pointcloud);
-                    pointcloudLoaded ++;
-                    if(pointcloudLoaded == datasetLength)pointcloudLoadDone()
+                    //transformPointcloud(pointcloud,dataset)
+                    scene.addPointCloud(pointcloud); 
+                    pointcloudLoadDone()
                         
                     Potree.loadPanos(dataset.id, (data) => { 
                         //console.log('loadPanos',dataset.sceneCode, dataset.id, data)
-                        viewer.images360.addPanoData(data, pointcloud )
-                        panosLoaded ++; 
-                        if(panosLoaded == datasetLength){
-                            panosLoadDone() 
-                        } 
+                        viewer.images360.addPanoData(data, pointcloud ) 
+                        panosLoadDone()  
                     })
                 })
             }else{
@@ -471,7 +458,7 @@ var start = function(dom, mapDom, number, fileServer, webSite){ //t-Zvd3w0m
     
     
     let objUrls = [ 
-        Potree.resourcePath+'/models/obj/man1/1', 
+        //Potree.resourcePath+'/models/obj/man1/1', 
         'https://4dkk.4dage.com/scene_view_data/KK-t-JyP3NbEwHAi/data/mesh/mesh',
         Potree.resourcePath+'/models/obj/sphere', 
         Potree.resourcePath+'/models/obj/28M/GW1H',
@@ -481,6 +468,15 @@ var start = function(dom, mapDom, number, fileServer, webSite){ //t-Zvd3w0m
         Potree.resourcePath+'/models/obj/53M/output_00',
     ], objIndex = 0
     
+    let pointcloudsList = [
+        Potree.settings.number,//4k
+        'SG-t-VzzjhSgyaAd',//6k
+        {number:'SG-t-PMC5t3krozE', resolution:'2k'}//pretend 2k 
+    
+    ],curPointIndex = -1
+    
+    
+    
     //initializeTransformation(lonlat)
     // // 1. 定义 CGCS2000 (EPSG:4490) 和 地心坐标系 (EPSG:4978)
     // // EPSG:4490 是经纬度坐标系  3d-tiles就是使用这个坐标系
@@ -489,9 +485,8 @@ var start = function(dom, mapDom, number, fileServer, webSite){ //t-Zvd3w0m
     proj4.defs("EPSG:4978",  "+proj=geocent +datum=WGS84 +units=m +no_defs +type=crs"  );
     
     let lonlat = Potree.browser.urlHasValue('lonlat',true).split(',') 
-    lonlat = lonlat.length == 2 ? lonlat.map(e=>parseFloat(e)) : [113.60,22.36 ]
-    //[83.0246,41.715012] /* */
-    Potree.settings.useRectProj = Potree.browser.urlHasValue('rectProj')
+    lonlat = lonlat.length == 2 ? lonlat.map(e=>parseFloat(e)) : [113.60,22.36 ] 
+    Potree.settings.useRectProj = Potree.browser.urlHasValue('rectProj') 
     Potree.setLonlat(...lonlat)
      
     /* proj4.defs(
@@ -499,13 +494,42 @@ var start = function(dom, mapDom, number, fileServer, webSite){ //t-Zvd3w0m
         `+proj=tmerc +lat_0=${lonlat[1]} +lon_0=${lonlat[0]} +k=1 +x_0=0 +y_0=0 +ellps=WGS84 +units=m +no_defs`
     ); */
     
+    viewer.images360.addEventListener('endChangeMode',(e)=>{ 
+        //Potree.Utils.updateVisible(MergeEditor.transformControls, 'showPanos', e.mode == 'showPointCloud')
+        //Potree.Utils.updateVisible(MergeEditor.boxHelper, 'showPanos', e.mode == 'showPointCloud')
+         
+        if(e.mode == 'showPanos'){
+            viewer.setControls( viewer.fpControls )
+            viewer.removeEventListener('camera_changed', camera_changed)
+        }else{ 
+            viewer.addEventListener('camera_changed', camera_changed)
+        }
+         
+        /* viewer.objs.children.forEach((e)=>{changeMeshVisi(e)})
+        
+        Potree.settings.canWalkThroughModel || viewer.images360.panos.forEach(pano => {
+            pano.setEnable(e.mode == 'showPanos' ? pano.pointcloud == viewer.images360.currentPano.model : true)
+        })  
+         */
+         
+         Potree.settings.unableNavigate = e.mode == 'showPointCloud' 
+    })
     
     
     
+    let camera_changed = (e) => {
+        if (e.viewport.name == 'MainView' && e.changeInfo.positionChanged) {
+            //viewer.mainViewport.camera.position
+            viewer.mainViewport.view.radius = 0.1 //使pivot在面前一丢丢距离
+            viewer.setControls(viewer.orbitControls)
+            viewer.removeEventListener('camera_changed', camera_changed)  
+        }
+    }
 
     
    
     
+    
     createCesiumMap() 
     
     let modelType,  modelEditing 
@@ -518,17 +542,10 @@ var start = function(dom, mapDom, number, fileServer, webSite){ //t-Zvd3w0m
             MergeEditor.modelAdded(model)
             if(!fixPose){
                 modelEditing = model; 
-                           
-                /* if(name == '3dTiles'){
-                    setTimeout(()=>{
-                        moveModel({pointer:{x:0,y:0}}) //3dTiles的移动会错乱,先默认放在当前视图中间吧 
-                        confirmPos()
-                    },1)
-                }else{ */
-                   
-                    viewer.addEventListener('global_mousemove', moveModel); 
-                    viewer.addEventListener('global_click', confirmPos, 3);
-                //} 
+                            
+                viewer.addEventListener('global_mousemove', moveModel); 
+                viewer.addEventListener('global_click', confirmPos, 3);
+                
             }else{
                 modelEditing = null
                 
@@ -536,22 +553,9 @@ var start = function(dom, mapDom, number, fileServer, webSite){ //t-Zvd3w0m
                     let center = new THREE.Vector3().fromArray(model.runtime.getTileset().tileset.root.transform.slice(12,15))
                          
                     let pos = Potree.math.fromCes(center) 
-                    model.position.copy(pos) 
-
-
-                   /*  
-                    let pos2 = ecefToLngLat(center)
-                    //pos2 = viewer.transform.lonlatToLocal.forward(new THREE.Vector3(pos2.x,pos2.y,0))  
-                    pos2 = proj4("EPSG:4326", "center",  pos2), 
-                    model.position.x = pos2.x, model.position.y = pos2.y  
-                    //viewer.modules.MergeEditor.moveBoundCenterTo( model, new THREE.Vector3().fromArray(pos) )  
-                    //因为bound中心在原点所以上面两句都可以  */
-                    
+                    model.position.copy(pos)  
                     model.hasLonLat = true 
-                }
-                
-                
-                
+                }  
             }
             
             
@@ -609,15 +613,16 @@ var start = function(dom, mapDom, number, fileServer, webSite){ //t-Zvd3w0m
                     viewer.scene.addPointCloud(e.pointcloud);
                 })
             }else{
-                Potree.loadDatasets(Potree.loadDatasetsCallback) 
+                 let o = pointcloudsList[++curPointIndex]
+                Potree.loadDatasets(Potree.loadDatasetsCallback, o.number || o ) 
                 viewer.addEventListener('allLoaded',()=>{
-                    let pointcloud = modelEditing = viewer.scene.pointclouds[0]; 
-                    pointcloud.matrixAutoUpdate  = true
+                    let pointcloud = modelEditing = viewer.scene.pointclouds[viewer.scene.pointclouds.length-1] 
+                    pointcloud.matrixAutoUpdate = true
                     pointcloud.initialPosition = pointcloud.position.clone() 
                     pointcloud.pos1MatrixInvert = new THREE.Matrix4().setPosition(pointcloud.initialPosition).invert()
                          
                     loadDone(pointcloud)
-                })
+                },{once:true})
             }
             
             

+ 67 - 30
src/custom/modules/panos/Images360.js

@@ -915,21 +915,22 @@ export class Images360 extends THREE.EventDispatcher{
     }
 
 
-    flyToPano(toPano) {  //飞向漫游点
-        if(!toPano)return
+    flyToPano(toPano={}) {  //飞向漫游点
+         
         if(typeof toPano == 'number')toPano = this.panos[toPano]
         if(toPano instanceof Panorama){
             toPano = {pano: toPano}
         }
+        if(!toPano?.pano )return toPano?.deferred?.resolve(false)
          
         
         let done = (makeIt, disturb)=>{
             //console.log('flyToPano done ', toPano.pano.id, makeIt, disturb ) 
             if(makeIt || disturb) { // disturb已经开始飞行但中途取消
-                toPano.callback && toPano.callback(makeIt) 
                 //this.flying = false
                 this.cancelFlyToPano(toPano)
                 this.updateClosestPano(this.closestPano,false) //飞行结束后取消点击漫游点时得到的closestPano
+                toPano.callback && toPano.callback(makeIt) 
             }else{ 
                 if(toPano.retryUntilArrive){//一直试直到可以飞成功
                     //console.log('wait for reFly to pano ', toPano.pano.id)
@@ -1835,10 +1836,10 @@ export class Images360 extends THREE.EventDispatcher{
         option1 = void 0 !== option1 ? option1 : 0.6   //.75;    2024.3.22改小,也就是可以走的角度范围增加,主要针对像山野那种很大的场景,不知道可以走哪,容易因角度范围内无近点而飞到远处的情况。但不能太小,总是横着走路
         var o = option2 ? "angle" : "direction";
         
-        var floor = viewer.modules.SiteModel.currentFloor;
+       /*  var floor = viewer.modules.SiteModel.currentFloor;
         var entity = viewer.modules.SiteModel.inEntity; 
         let scaleFactor = Math.pow( this.currentPano?.pointcloud.scale.x || 1 , 2) 
-        let changeTexCount = 0, maxWaitDur = 300  
+         */let changeTexCount = 0, maxWaitDur = 300  
             //maxSamplerChangeTex = THREE.Math.clamp( maxWaitDur / Potree.timeCollect.depthSampler.median, 2, 10)  //计算换贴图最大数目
          
         
@@ -2165,7 +2166,7 @@ export class Images360 extends THREE.EventDispatcher{
                     let cos = dir.dot(vec2)  
                     //let result = (- dis1  - Math.pow(dis2 , 1.5)) / (cos + 2)  // cos+2是为了调整到1-3, 
                     
-                    let result =  (dis1 + dis2*0.3) * ( -1 + cos*0.4 ) //尽量贴近最佳位置的角度, 或贴近相机原来的角度 。尽量靠近最佳观测点,并且优先选择靠近目标点的位置.(注意cos的乘数不能太接近1,否则容易只考虑角度)
+                    let result =  (dis1 + dis2*0.3) * ( -1 + cos*0.9 ) //尽量贴近最佳位置的角度, 或贴近相机原来的角度 。尽量靠近最佳观测点,并且优先选择靠近目标点的位置.(注意cos的乘数不能太接近1,否则容易只考虑角度)
                     //Potree.Log(pano.id, dis1, dis2,  cos,  result,{font:{toFixed:2,fontSize:10}}) 
                      
                     return  result
@@ -2314,7 +2315,7 @@ export class Images360 extends THREE.EventDispatcher{
                 
                 let levelThreshold1 = Potree.settings.navTileClass == '1k' ? 1.3 : 1.7 , levelThreshold2 = 2
                  
-                var t = this.zoomLevel > levelThreshold1,
+                var t = Potree.settings.highestQualityTile || this.zoomLevel > levelThreshold1,
                     n = !(this.flying && this.nextPano && this.nextPano !== this.currentPano),
                     r = t && n;
                 this.tileDownloader.tilePrioritizer.setZoomingActive(r);
@@ -2336,13 +2337,13 @@ export class Images360 extends THREE.EventDispatcher{
                 if (r && (!currentPano.zoomed || this.qualityManager.zoomLevelResolution && this.qualityManager.zoomLevelResolution != '4k')) {//needZoom
                     currentPano.zoomed || o(currentPano, !0); 
                     
-                    if(Potree.settings.navTileClass == '1k' && Potree.settings.tileClass != '1k' && this.zoomLevel < levelThreshold2){
+                    if(Potree.settings.navTileClass == 1024 && Potree.settings.tileClass > 1024 && this.zoomLevel < levelThreshold2){
                         this.panoRenderer.enableHighQuality( function() {//开启2k 
-                            if(Potree.settings.tileClass != '4k')  o(currentPano, !0); 
+                            if(Potree.settings.tileClass < 4096)  o(currentPano, !0); 
                         }.bind(this));
                     }else{ 
                         this.panoRenderer.enableUltraHighQualityMode(function() {//开启4k getMaxZoomPanoSize
-                            this.qualityManager.useUltraHighResolutionPanos && (Potree.settings.zoom.max = Potree.config.ultraHighQualityMaxZoom);
+                            //this.qualityManager.useUltraHighResolutionPanos && (Potree.settings.zoom.max = this.currentPano.getZoomMax()  ) //加了其他逻辑太复杂,改为一开始就根据tileClass修改好了max
                             o(currentPano, !0)
                         }.bind(this));
                     } 
@@ -2352,7 +2353,7 @@ export class Images360 extends THREE.EventDispatcher{
                 
                 
                 
-                if(r && Potree.settings.navTileClass == '1k' && Potree.settings.tileClass == '4k'  ){ //目前只有手机端navTileClass == '1k' (分三个梯度)
+                if(r && Potree.settings.navTileClass == 1024 && Potree.settings.tileClass >= 4096 ){ //目前只有手机端navTileClass == '1k' (分三个梯度)
                     var change = (zoomedFlag)=>{ 
                         this.qualityManager.updateMaximums()//更新maxZoomPanoSize
                         this.panoRenderer.setupZoomRenderTarget() //更新renderTarget  
@@ -2387,7 +2388,7 @@ export class Images360 extends THREE.EventDispatcher{
 
     addHighMapCube(){//创建8*8的tile  cube   主要因手机版崩溃  要在电脑端测试得设置maxRenderTargetSize
         
-        if( Potree.settings.tileClass == '4k' && this.qualityManager.maxRenderTargetSize == 2048){
+        if( this.qualityManager.maxRenderTargetSize < Potree.settings.tileClass && !this.highMapCube){
             
             var geo = new THREE.PlaneGeometry(1, 1, 1, 1)
             var cube = new THREE.Object3D;
@@ -2475,10 +2476,10 @@ export class Images360 extends THREE.EventDispatcher{
                 cube.scale.set(s,s,s)
             }//注:由于原本的mesh上加了深度贴图,可能距离镜头比这里的近。凡是在cube以内的部分都会挡住cube导致模糊。但是应该不常见吧(另外到天空的边缘也是很近)。姑且depthTest=false
             
-            this.highMapCube.visible = false; 
-            Potree.Utils.setObjectLayers(this.highMapCube, 'sceneObjects'/* 'skybox' */) //它的深度是错误的,故不在skybox层渲染,影响edlRT, 而在renderOverlay时渲染覆盖。
+            this.hideHighMap()
+            Potree.Utils.setObjectLayers(this.highMapCube, 'sceneObjects'/* 'skybox' */) // 它的深度是错误的,故不在skybox层渲染,影响edlRT, 而在renderOverlay时渲染覆盖。
             //console.warn('addHighMapCube')
-            
+            //this.panoRenderer.deleteZoomRT() //要等不在使用时再删
             
             viewer.addEventListener('update',()=>{
                 if (this.highMapCube.visibleTiles) {
@@ -2511,7 +2512,7 @@ export class Images360 extends THREE.EventDispatcher{
     
     
     updateTiles(direction) {
-        if (!this.highMapCube || !this.highMapCube.visible) return
+        if (!this.canUseMapCube() || !this.highMapCube.visible) return
 
         if (this.highMapCube.tiles.filter(e => e.image).length <= 10) return //加载的太少了
         //performance.mark('updateTiles-start')
@@ -2523,31 +2524,59 @@ export class Images360 extends THREE.EventDispatcher{
             /* let hcos = Math.cos(hfov / 2)
             let vcos = Math.cos(vfov / 2)  */
             let list = this.highMapCube.tiles
+            
+
+            let frustumMatrix = new THREE.Matrix4
+                frustumMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse)
+            let frustum = new THREE.Frustum();
+                frustum.setFromProjectionMatrix(frustumMatrix) 
+            let p_ = new THREE.Vector3
+            let time = performance.now()
+            
+            //let history_ = [],same = 0
+             
             list.forEach(e => {
                 //屏幕外的不显示
-                let pos = e.getWorldPosition(new THREE.Vector3())
+               /*  let pos = e.getWorldPosition(new THREE.Vector3())
                 let dir = new THREE.Vector3().subVectors(pos, this.highMapCube.position).normalize()
-
+                //再看好像不对
                 let hcos_ = dir.clone().setZ(direction.z).normalize().dot(direction) //在direction的斜面上水平角度差
                 let hRad = Math.acos(hcos_)
                 let vRad = -200
-                if (/* hRad > hfov + 0.08 */ hRad / hfov > 1.5 ) {   
+                if ( hRad / hfov > 1.5 ) {   
                     e.score = -100
                 } else {
                     vRad = Math.abs(Math.acos(dir.z) - Math.acos(direction.z))
-                    if (/* vRad > vfov + 0.08 */ vRad / vfov > 1.5 ) {
+                    if ( vRad / vfov > 1.5 ) {
                         e.score = -100
                     } else {
                         e.score = -(hRad / hfov + vRad / vfov)
                     }
-                }
-                e.scores = hRad.toFixed(3) + ', ' + vRad.toFixed(3)
-
+                } */
+                let a = frustum.intersectsObject(e)//外包围球粗略判断
+                if(a){//显示所有在屏幕上有显示的tile
+                    e.score = 1 
+                    /* for(let i=0;i<4;i++){//精确计算,检测是否四个顶点都在屏幕内(虽然减少不了多少个  )
+                        p_.copy(e.geometry.vertices[i]).applyMatrix4(e.matrixWorld) 
+                       
+                        if(history_.find(o=>math.closeTo(o,p_)) || frustum.containsPoint(p_) ){
+                            e.score = 2 
+                            history_.push(  p_.clone() )
+                            break
+                        }//  
+                         若tile底部横跨屏幕,且中心点不在屏幕,将检测不到,所以不算了
+                    */  
+                }else e.score = -100 
+                //e.score = frustum.intersectsObject(e) ? 1 : -100
+                //e.scores = hRad.toFixed(3) + ', ' + vRad.toFixed(3) 
                 if (e.score == -100) {
                     this.resetTile(e)
                 }
             })
             this.highMapCube.visibleTiles = list.filter(e => e.score > -100)
+            
+            
+            //console.log('cost', performance.now() - time, 'same',same)
             //list.forEach(e=>e.scoreLabel.setText(e.scores))
         }
 
@@ -2646,11 +2675,14 @@ export class Images360 extends THREE.EventDispatcher{
         }
     }    
     
-    
+    canUseMapCube(pano = this.currentPano, panoSize){
+        if(typeof pano == 'number') pano = this.getPano(pano)
+        return this.highMapCube && (panoSize || pano?.pointcloud.tileClass) >= 4096//this.qualityManager.maxRenderTargetSize
+    }   //考虑到可能2k 4k 6k的场景同时存在,而maxRenderTargetSize也可能是任意一个,所以只要有一个>4096的,4096时也用cube
     
     
     resetHighMap() {
-        if (!this.highMapCube) return
+        if (!this.canUseMapCube()) return
         this.highMapCube.children.forEach(e =>
             e.children.forEach(tile => {
                 this.resetTile(tile, true)
@@ -2663,7 +2695,7 @@ export class Images360 extends THREE.EventDispatcher{
     }
     
     setHighMap(pano){ 
-        if(!this.highMapCube)   return 
+        if(!this.canUseMapCube())   return 
         this.highMapCube.position.copy(pano.position)
  
         //可以利用第0个pano查看,其 rotation4dkk是(_x: 0, _y: -1.5707963267948966, _z: 0 )而手动旋转至(_x:1.5707963, _y: -1.57079, _z: 0)时才正确,说明要在4dkk的旋转基础上,绕x轴转90度,(也就是转成navvis坐标系), 然后得到YupToZup的函数写法的
@@ -2679,15 +2711,15 @@ export class Images360 extends THREE.EventDispatcher{
     }
     
     showHighMap(){  
-        if(!this.highMapCube)   return 
+        if(!this.canUseMapCube() || this.currentPano.tile)   return 
         //console.warn('showHighMap')
-        this.highMapCube.visible = true; 
+        Potree.Utils.updateVisible(this.highMapCube, 'show',  true)
          
     } 
     hideHighMap(){ 
         if(!this.highMapCube)   return
         //console.warn('hideHighMap')        
-        this.highMapCube.visible = false;
+        Potree.Utils.updateVisible(this.highMapCube, 'show',  false) 
     }
     //缩小后继续显示cube呢还是不显示?  不显示的话,就要把cube上的复制到renderTarget上……会不会又崩溃,or没加载的显示???
     
@@ -2722,7 +2754,12 @@ export class Images360 extends THREE.EventDispatcher{
             if(Potree.settings.editType == 'pano'){
                 Potree.settings.datasetsPanos[pointcloud.dataset_id].panos.push(pano);
             }
-        })   
+        }) 
+
+        if(data.length){ 
+            this.qualityManager.updateTileClass(pointcloud.tileClass) 
+            this.addHighMapCube() 
+        }
     }
     
     

+ 7 - 2
src/custom/modules/panos/Panorama.js

@@ -544,6 +544,7 @@ class Panorama extends THREE.EventDispatcher{
         this.setZoomed(!1) 
         viewer.dispatchEvent({type:PanoramaEvents.Enter,  oldPano:old, newPano:this  }  )
         old = this 
+        Potree.settings.zoom.max = this.getZoomMax()  
         //console.log("enter pano "+ this.id)
     } 
 
@@ -574,8 +575,8 @@ class Panorama extends THREE.EventDispatcher{
     getSkyboxTexture(){
      
         if(this.minimumTiledPanoLoaded)
-        {
-            if(this.zoomed && this.images360.qualityManager.maxRenderTargetSize > this.images360.qualityManager.maxNavPanoSize)//change 如果放大后和不放大都是2k就不用这个
+        {                       //2026:若maxRenderTargetSize是4k,同时存在4k、6k,则4k也显示cube
+            if(this.zoomed && !this.images360.canUseMapCube(this) && this.pointcloud.tileClass/*this.images360.qualityManager.maxRenderTargetSize*/ > this.images360.qualityManager.maxNavPanoSize )//change 如果放大后和不放大都是2k就不用这个
             {
                 return this.images360.panoRenderer.zoomRenderTarget.texture;   
             }
@@ -767,10 +768,14 @@ class Panorama extends THREE.EventDispatcher{
         
         return this.ceilZ 
 
+    } 
     
         
+    getZoomMax(){
+        return Math.max(2,this.pointcloud.tileClass / 4096 * 3)
     }
     
+    
 };
 
 

+ 31 - 12
src/custom/modules/panos/tile/PanoRenderer.js

@@ -127,10 +127,12 @@ class PanoRenderer extends THREE.EventDispatcher{
 
 
     enableUltraHighQualityMode(e) {
-        if(config.tileClass == "2k"||config.tileClass == "1k")return this.enableHighQuality(e)//xzw add     濡傛灉鏈€澶氬彧瑕?k鐨勮瘽
+        if(Potree.settings.tileClass <= 2048)return this.enableHighQuality(e)//xzw add     
         if (!this.qualityManager.ultraHighQualityModeEnabled()) {
-            var t = this.qualityManager.getPanoSize(PanoSizeClass.ULTRAHIGH);
-            this.tileDownloader.testDownload(t, TileUtils.TILE_SIZE, function (t) {
+            var s = this.qualityManager.getPanoSize(PanoSizeClass.ULTRAHIGH);
+            this.tileDownloader.testDownload(s, 
+                Potree.settings.tileClass == 6144 ? TileUtils.TILE_SIZE * 1.5 : TileUtils.TILE_SIZE, //改 TileUtils.TILE_SIZE,
+                function (t) {
                      t && (this.qualityManager.enableUltraHighQualityMode(),
                         this.setupZoomRenderTarget(),
                         e())  
@@ -145,7 +147,7 @@ class PanoRenderer extends THREE.EventDispatcher{
         
         i && this.clearAllQueuedUploads();
         for (var n = 0; n < TileUtils.FACES_PER_PANO; n++)
-            this.initTileTree(pano.id, n, this.qualityManager.getMaxPossiblePanoSize()); //得到this.tileTrees[pano.id],arr[6]
+            this.initTileTree(pano.id, n, pano.pointcloud.tileClass/* this.qualityManager.getMaxPossiblePanoSize() */); //得到this.tileTrees[pano.id],arr[6]
         this.linkAllTilesAndNodes(pano);
         var r = this.getActiveRenderTargetDescriptor(pano.id),
             l = size;
@@ -317,7 +319,7 @@ class PanoRenderer extends THREE.EventDispatcher{
             && (!(e.panoSize > this.qualityManager.getMaxNavPanoSize()) || this.zoomingActive &&  viewer.images360.getPano(e.panoId).tileRes != '2k')) {
  
             
-            var r = this.getUploadQueueForPano(e.panoId);
+            var uploadQueues = this.getUploadQueueForPano(e.panoId);
             //console.log(window.sceneName, 'queueTileUpload: ', e.panoId, e.tileIndex,   i)
             if(i){
                 //console.log('512下载好了直接uploadTile')
@@ -327,8 +329,10 @@ class PanoRenderer extends THREE.EventDispatcher{
                     this.forceQueue.push(e)
                 }else{
                     if(t && this.direction){
-                        TilePrioritizer.insertSortedPanoTile(r, e, n.pano, this.direction) 
-                    }else r.push(e) 
+                        TilePrioritizer.insertSortedPanoTile(uploadQueues, e, n.pano, this.direction) 
+                    }else{ 
+                         uploadQueues.push(e) 
+                    }
                 }
                 e.uploadQueued = !0 
                 this.uploadInterval || this.uploadIntervalCancelled || this.refreshUploadInterval(0)
@@ -771,7 +775,7 @@ PanoRenderer.prototype.setupZoomRenderTarget = function(){
             
             var size = this.qualityManager.getMaxZoomPanoSize()
             if(size > this.qualityManager.maxRenderTargetSize){ 
-                return 
+                return //use cube
             } 
             
             if(targets[size]){
@@ -785,17 +789,32 @@ PanoRenderer.prototype.setupZoomRenderTarget = function(){
                 var t = e.width,
                     i = this.zoomRenderTarget.width; 
                 this.copyCubeMap(e.texture, this.zoomRenderTarget, t, t, i, i),
-                    e.texture.dispose(),
+                    /* e.texture.dispose(),
                     e.texture.loaded = !1,
                     e.texture.version = 0,
                     this.deallocateCubeTexture(e.texture),
-                    e.texture = null
+                    e.texture = null */
+                    this.deleteZoomRT(e)
             }
             this.zoomPanoRenderingDisabled = !1
         } else
         this.zoomPanoRenderingDisabled = !0
     }
 }()
+
+
+PanoRenderer.prototype.deleteZoomRT = function(e){//xzw add 
+    let renderTarget = e || this.zoomRenderTarget
+    if(!renderTarget)return
+    renderTarget.texture.dispose(),
+    renderTarget.texture.loaded = !1,
+    renderTarget.texture.version = 0,
+    this.deallocateCubeTexture(renderTarget.texture),
+    renderTarget.texture = null
+    if(!e) this.zoomRenderTarget = null
+}
+
+
 PanoRenderer.prototype.updateActivePanos = function () {
     var e = [];
     return function (t, i) {
@@ -984,7 +1003,7 @@ PanoRenderer.prototype.uploadTile = function () {//重写
                 b = C / panoSize * size,  // tile在renderTarget上渲染的startX
                 w = I / panoSize * size;  // tile在renderTarget上渲染的startY
              
-            if(panoSize > this.qualityManager.maxRenderTargetSize ){ //4096 改
+            if(this.viewer.images360.canUseMapCube(id,panoSize)/* panoSize > this.qualityManager.maxRenderTargetSize  */){ //4096 改
                 /* var tex = this.initSizedTexture2D(tileSize, THREE.ClampToEdgeWrapping);
                 var loaded = this.viewer.images360.isHighMapLoaded(info.cubeFace, tileX,tileY)   */ 
                 this.viewer.images360.getHighImage(img, info.cubeFace, tileX, tileY)                
@@ -994,7 +1013,7 @@ PanoRenderer.prototype.uploadTile = function () {//重写
              
                 this.uploadTexture2D(img, tex, 0, 0, tileSize, tileSize);//只替换tex对应的img,不新建
                   
-                if(panoSize > this.qualityManager.maxRenderTargetSize){
+                if(this.viewer.images360.canUseMapCube(id,panoSize)/* panoSize > this.qualityManager.maxRenderTargetSize */){
                     loaded || this.viewer.images360.updateHighMap(tex, info.cubeFace, tileX,tileY) 
                 }else{ 
                     if (1 === overlayStyle || 2 === overlayStyle) {

+ 19 - 8
src/custom/modules/panos/tile/QualityManager.js

@@ -23,13 +23,25 @@ export default class QualityManager {
         this.modelHasUltraHighPanos = !1;
         this.qualityManager = this;
         
-        this.maxRenderTargetSize = browser.isMobile() ? 2048 : 4096  //add
-          
-        this.maxRenderTargetSize = Math.min( viewer.renderer.capabilities.maxCubemapSize,  this.maxRenderTargetSize)//部分系统老浏览器只能2048
         
         this.init()
     }
 
+
+    updateTileClass(curTileClass){ 
+        let oldTileClass = Potree.settings.tileClass || 2048 
+        Potree.settings.tileClass = Math.max(oldTileClass, curTileClass)//只增不减,不考虑删除场景,太复杂了orz 
+        this.maxRenderTargetSize = browser.isMobile() ? 2048 : Potree.settings.tileClass 
+        this.maxRenderTargetSize = Math.min( viewer.renderer.capabilities.maxCubemapSize,  this.maxRenderTargetSize)//部分系统老浏览器只能2048
+        
+        this.maxRenderTargetSize = 4096////test
+        this.buildPanoSizeClassMap(this.devicePixelDensity, this.deviceScreenSize, this.clientBandwidth);
+        this.updateMaximums()
+        console.log('updateTileClass, curTileClass', curTileClass, Potree.settings.tileClass)
+    }
+
+
+
     init(e ) {
         //var metadata = store.getters['scene/metadata'] ;//有时候请求不到
         //if(metadata.sceneSource == 11 || metadata.sceneScheme == 12){
@@ -37,8 +49,7 @@ export default class QualityManager {
             this.useHighResolutionPanos = false    //xzw add 只加载1k
         } */
          
-        
-        this.buildPanoSizeClassMap(this.devicePixelDensity, this.deviceScreenSize, this.clientBandwidth);
+        this.updateTileClass(2048) //初始值                             
         this.ultraHighSize = this.getPanoSize(PanoSizeClass.ULTRAHIGH);
         this.highSize = this.getPanoSize(PanoSizeClass.HIGH);
         this.standardSize = this.getPanoSize(PanoSizeClass.STANDARD);
@@ -92,7 +103,7 @@ export default class QualityManager {
         this.panoSizeClassMap[PanoSizeClass.BASE] = 512,
             this.panoSizeClassMap[PanoSizeClass.STANDARD] = 1024,
             this.panoSizeClassMap[PanoSizeClass.HIGH] = 2048,
-            this.panoSizeClassMap[PanoSizeClass.ULTRAHIGH] = 4096
+            this.panoSizeClassMap[PanoSizeClass.ULTRAHIGH] = Math.max(4096, Potree.settings.tileClass) //无所谓 不用这个
     }
 
     getPanoSize(e) {
@@ -122,10 +133,10 @@ export default class QualityManager {
         }
         return PanoSizeClass.HIGH  */
         switch(Potree.settings.navTileClass){  
-            case '1k':
+            case 1024:
                 return PanoSizeClass.STANDARD;
                 break;
-            case '2k':             
+            case 2048:             
             default:
                 return PanoSizeClass.HIGH;
         }

+ 12 - 8
src/custom/modules/panos/tile/TileDownloader.js

@@ -128,7 +128,7 @@ class TileDownloader extends THREE.EventDispatcher{
         }
   
         
-        let time2 = 1000//Potree.Common.getBestCountFPS('filterDepthTex',  false,  5000, 88, 2, 63  ) 
+        let time2 = Potree.settings.displayMode == 'showPanos' ? 1000 : 8000 //Potree.Common.getBestCountFPS('filterDepthTex',  false,  5000, 88, 2, 63  ) 
         Potree.Common.intervalTool.isWaiting('filterDepthTex', ()=>{  
             this.tilePrioritizer.filterDepthTex(this.panos)//下载深度图
         }, time2)
@@ -232,7 +232,7 @@ class TileDownloader extends THREE.EventDispatcher{
         if (n)
             return void(n === this.freeze.Success ? callback(!0) : n === this.freeze.Fail && callback(!1));
         this.downloadTestResults[panoSize] = this.freeze.Testing;
-        var r = this.panos[0],
+        var r = this.panos.find(e=>e.pointcloud.tileClass == panoSize),//this.panos[0],
             o = this.getTileUrl({pano:r, panoSize, tileSize, tileIndex:0}   /* r.id, panoSize, tileSize, 0 */),
             a = function(t) {
                 this.downloadTestResults[panoSize] = this.freeze.Success,
@@ -384,6 +384,10 @@ class TileDownloader extends THREE.EventDispatcher{
         desc.totalTiles = TileUtils.getTileCountForSize(size);
         desc.status = DownloadStatus.None;
         desc.image = null;
+        if (size == 6144) {
+            //desc.panoSize = 6144  //4096 * 1.5
+            desc.tileSize = 768 //512 * 1.5
+        }
         TileUtils.getTileLocation(desc.panoSize, desc.tileIndex, desc);//得到该tile在这个face中的具体位置(tileX等)
         TileUtils.getTileVector(desc.panoSize, desc.tileSize, desc.cubeFace, desc.tileX, desc.tileY, TileUtils.LocationOnTile.Center, 0, desc.direction);
     }
@@ -498,7 +502,7 @@ TileDownloader.prototype.getTileUrl = function() {
             tileIndex = o.tileIndex,
             sceneCode = o.pano.pointcloud.sceneCode,
             useV4url = Potree.settings.useV4url && (!o.pano.pointcloud.datasetData || o.pano.pointcloud.datasetData.sceneVersion == 'V4')        //v4的全景图等路径不一样  
-        var resolution = o.pano.pointcloud.tileRes || '4k'
+        var resolution = o.pano.pointcloud.tileRes || o.pano.pointcloud.datasetData?.sceneResolution || '4k'  
         var metadata = {sceneScheme:10}  
         
         
@@ -526,25 +530,25 @@ TileDownloader.prototype.getTileUrl = function() {
             } else {
                 //4k的图,移动端是1k,pc端是2k,放大才是4k
                 if (e[panoSize] == '1k' || e[panoSize] == '2k') {  //https://4dkk.4dage.com/images/imagesx4iqYDG3/tiles/4k/122_skybox0.jpg?x-oss-process=image/resize,m_lfit,w_1024/crop,w_512,h_512,x_511,y_0
-                    d += 'image/resize,m_lfit,w_' + panoSize + '/crop,w_512,h_512,';
+                    d += `image/resize,m_lfit,w_${panoSize}/crop,w_${tileSize},h_${tileSize},`
                 } else {
-                    d = 'tiles/'+ resolution +'/' + id + '_skybox' + h + '.jpg?x-oss-process=image/crop,w_512,h_512,';
+                    d += `image/crop,w_${tileSize},h_${tileSize},`
                 }
                 //起始位置
                 if (t.tileX == 0) {
                     d += 'x_0,';
                 } else {
-                    d += 'x_' + (512 * t.tileX /* - 1 */) + ',';
+                    d += 'x_' + (tileSize * t.tileX /* - 1 */) + ',';
                 }
 
                 if (t.tileY == 0) {
                     d += 'y_0';
                 } else {
-                    d += 'y_' + (512 * t.tileY /* - 1 */);
+                    d += 'y_' + (tileSize * t.tileY /* - 1 */);
                 } 
             }
             
-            d = this.getTiles(d, sceneCode, useV4url, o.pano.pointcloud);
+            d = this.getTiles(d, sceneCode, useV4url, o.pano.pointcloud );
             g = "&" 
         } 
         //Potree.settings.panoVersion = 4

+ 1 - 1
src/custom/modules/panos/tile/TilePrioritizer.js

@@ -294,7 +294,7 @@ TilePrioritizer.prototype.filterAndPrioritize = function () {//挑选出优先
             ,
             c = this.highSize //2048
             ,
-            h = this.ultraHighSize; //4096
+            h = this.priorityCriteria.pano.pointcloud.tileClass //xzw   //this.ultraHighSize; //4096
             
             
         this.queueTilesForPano(queue, tileDownloader, this.priorityCriteria.pano, s);  //把当前pano的512下载了

+ 9 - 7
src/custom/modules/panos/tile/TileUtils.js

@@ -14,7 +14,9 @@ TileUtils.LocationOnTile = {
     LowerRight: 3,
     LowerLeft: 4
 },
-
+TileUtils.getTileSize = function(panoSize) {
+    return panoSize == 6144 ? 768 : TileUtils.TILE_SIZE
+},
 
 /*
  * 获取某tile在cube中的方向 direction (向量起点在cube中心,终点在tile图的指定位置)。spherical通过先求uv,再直接得到dir
@@ -91,7 +93,7 @@ TileUtils.getTileVector = function() {//获取某tile在cube中的方向 directi
  * 获取该tile在第几个面(简易装载法) 
  */
 TileUtils.getFaceForTile = function(size, index) {//获取该tile在第几个面
-    var tileSize = TileUtils.TILE_SIZE;
+    var tileSize = this.getTileSize(size) //xzw改 
     size < TileUtils.TILE_SIZE && (tileSize = size);
     var n = Math.floor(size / tileSize)
         , sum = n * n; //得每个面tile总数
@@ -101,7 +103,7 @@ TileUtils.getFaceForTile = function(size, index) {//获取该tile在第几个面
 
 
 TileUtils.getTileLocation = function(size, t, result) {
-    var tileSize = TileUtils.TILE_SIZE;
+    var tileSize = this.getTileSize(size) //xzw改
     size < TileUtils.TILE_SIZE && (tileSize = size);
     var r = TileUtils.getFaceForTile(size, t)
         , a = Math.floor(size / tileSize)
@@ -118,10 +120,10 @@ TileUtils.getTileLocation = function(size, t, result) {
 /*
  * 求size分辨率需要多少张tile
  */
-TileUtils.getTileCountForSize = function(e) {
-    if (e <= TileUtils.TILE_SIZE)
-        return TileUtils.FACES_PER_PANO;
-    var t = Math.floor(e / TileUtils.TILE_SIZE)
+TileUtils.getTileCountForSize = function(size) {
+    var tileSize = this.getTileSize(size)
+    if (size <= tileSize) return TileUtils.FACES_PER_PANO
+    var t = Math.floor(size / tileSize)
         , i = t * t
         , n = i * TileUtils.FACES_PER_PANO;
     return n

+ 11 - 0
src/custom/potree.shim.js

@@ -1040,6 +1040,17 @@ Utils.tran4dkkVecInModel = (vec, model)=>{//将四维看看里的坐标转换成
     return Potree.math.convertVector.YupToZup(vec).applyMatrix4(model.posRot1MatrixInvert)  //若要全局坐标,可以直接像pano那样转换,多乘个matrix
 } 
 
+Utils.setTileClass = (model, resolution )=>{ 
+    if(resolution == void 0){
+        resolution = model.isPointcloud ? '4k' : '2k' //点云没见过低于4k的
+    }
+    
+    if(resolution.indexOf('/') != -1) {
+        resolution = resolution.split('/')[1]
+    } 
+    model.tileClass = parseInt(resolution) * 1024 
+}
+
 
 BinaryLoader.prototype.load = function(node, callback){//解析点云
     if (node.loaded) {

+ 2 - 2
src/custom/settings.js

@@ -495,8 +495,8 @@ let settings = {//设置   可修改
                                  
     },
     navConstantly:true,
-    navTileClass:  /*  browser.isMobile() ? '1k' :  */  '2k',  //默认加载到
-    tileClass:'4k',     //最高可达
+    navTileClass: '2k',  //默认加载到
+    tileClass: 2048,     //最高可达  场景类型多,先设置个小的
     /* loadTilesWhenUnfocus:false, //页面unfocus时也仍在加载tiles
     loadPointsWhenUnfocus:true, //页面unfocus时也仍在加载点云 */
    

File diff ditekan karena terlalu besar
+ 8 - 204
src/custom/start.js


+ 1 - 1
src/custom/viewer/viewerBase.js

@@ -322,7 +322,7 @@ export class ViewerBase extends THREE.EventDispatcher{
     
     dispose(scene=this.scene){
          
-        scene.clear();
+        //scene.clear();
         this.renderer.dispose()
         this.renderer.forceContextLoss()
         let gl = this.renderer.getContext();