ソースを参照

fix: 调整整体加载内存大小

xzw 2 年 前
コミット
2d7b0f5340
3 ファイル変更155 行追加70 行削除
  1. 132 42
      public/lib/potree/potree.js
  2. 1 1
      public/lib/potree/potree.js.map
  3. 22 27
      src/sdk/cover/index.js

+ 132 - 42
public/lib/potree/potree.js

@@ -71781,6 +71781,8 @@ void main()
 			lowestSpacing: lowestSpacing
 		};
 	};
+
+	Potree.numVisiblePoints = 0;
 	/* 
 	    note:
 	    缓存中的点数 Potree.lru.numPoints 一般会 大于 每个点云显示点总数的numVisiblePoints 
@@ -73176,7 +73178,7 @@ void main()
 	            }
 	            
 	            
-	            model.isPointcloud || MergeEditor.updatePointQuality();
+	            MergeEditor.modelAdded(model);
 	            
 	        };
 	        
@@ -73440,13 +73442,12 @@ void main()
 	    
 	    urls:{
 	        //localTextures:'../resources/textures/', 
-	        prefix1: 'https://laser-oss.4dkankan.com',//oss
+	        prefix1: 'https://laser-oss.4dkankan.com',//oss 
 	        prefix2: 'https://testlaser.4dkankan.com',
 	        prefix3: 'https://4dkk.4dage.com',
 	        prefix4: 'https://uat-laser.4dkankan.com',//test.4dkankan
-	        prefix5: 'https://laser.4dkankan.com',
-	        prefix6: 'https://mix3d.4dkankan.com/backend',
-	        
+	        prefix5: 'https://laser.4dkankan.com/backend',
+	        prefix6: 'https://mix3d.4dkankan.com/backend', 
 	    },
 	    
 	    transitionsTime:{
@@ -73470,7 +73471,7 @@ void main()
 	        cameraHeight : 1000,  //最高  ,注意(如sitemodel)其他的物体不能超过这个高度
 	    },
 	    minNodeSize:30, // perspectiveCamera允许加载的node的最小可见像素宽度。越大越省性能
-	    
+	    tiles3DMaxMemory: 250,//M. 最大支持3dTiles的内存大小 超出会崩溃
 	    pointDensity:{
 	        magnifier:{  
 	            maxLevelPercent: 1,
@@ -73659,7 +73660,7 @@ void main()
 	    panoFieldRadius : 10, //当前位置多远范围内可以切全景模式
 	    clickMaxDragDis:5,
 	    clickMaxPressTime:500, //ms
-	    doubleClickTime:200,//双击间隔时间
+	    doubleClickTime:300,//双击间隔时间
 	    testNodeCount1: browser.isMobile() ? 8 : 6,  //testMaxNode次数达到这个数字时,changePointSize才使用nodeMaxLevel。 (调试时比较卡,在线上实际只需要3)
 	     
 	    background: '#232323',
@@ -73811,12 +73812,18 @@ void main()
 	    showAxis : isTest,
 	    // testCube : true,
 	    // moveToCenter:true, //针对数据集间隔很远的场景  dis>5000 容易抖动
-	    
+	    tiles3DMaxMemory: config$1.tiles3DMaxMemory,
 	};
 	  
 	 
 	settings.isLocalhost = settings.prefix.includes('localhost');
 
+	settings.isFormal = browser.urlHasValue('formal');//正式环境 本地测试
+	if(settings.isFormal){ 
+	    settings.urls.prefix = settings.urls.prefix5;
+	    settings.webSite = 'datav1';
+	}
+
 	console.log('2023-1');
 
 	class Action extends EventDispatcher$1 {
@@ -90839,11 +90846,11 @@ void main()
 			
 	        this.domElement.addEventListener('keydown', this.onKeyDown.bind(this));
 			window.addEventListener('keyup', this.onKeyUp.bind(this));
-	        
+	         
 	        
 	        window.addEventListener('blur',this.onKeyUp.bind(this)); //add
 	            
-	             
+	              
 	         
 			this.domElement.addEventListener('touchstart', this.onTouchStart.bind(this));
 			this.domElement.addEventListener('touchend', this.onTouchEnd.bind(this));
@@ -116136,6 +116143,15 @@ ENDSEC
 	          
 	        }) */
 	        
+	                   
+	        viewer.addEventListener('camera_changed',()=>{
+	            Common$1.intervalTool.isWaiting('updateMemoryUsage', ()=>{  
+	                 this.updateMemoryUsage();
+	            },  1000); 
+	        }); 
+	         
+	        
+	        viewer.addEventListener('setDisplay',this.updateMemoryUsage.bind(this));
 	    },
 	    
 	    
@@ -116266,7 +116282,7 @@ ENDSEC
 	                dispose(e); 
 	            });
 	            viewer.objs.remove(model);
-	            this.updatePointQuality();
+	            this.updateMemoryUsage();
 	        }   
 	        
 	        
@@ -116513,31 +116529,69 @@ ENDSEC
 	        
 	    },
 	    
+	    modelAdded(model){
+	        model.addEventListener('isVisible',(e)=>{ 
+	            if(e.reason == "overlinePass")return
+	            //console.log(e)
+	            viewer.addEventListener('update',()=>{ //下一次更新结束后
+	                this.updateMemoryUsage();
+	            },{once:true});  
+	        });
+	        this.updateMemoryUsage();
+	    },
+	    
+	    
 	    
-	    updatePointQuality(){
+	    updateMemoryUsage(){
+	        
+	        //obj暂时不管其贴图大小, 因为顶点造成的不仅是内存还有卡顿所以先只看顶点
+	        const maxMemory = Potree.config.tiles3DMaxMemory + 100; //M  实际估计是这个的10倍
+	        const eachObjPosWeight = 100/1000/1000;  //M  每个顶点pos是3*4个字节?法线3*4和uv2*4  其实还有贴图 
+	        const eachCloudPointWeight = 12/1000/1000; //M 每个点 pos + 颜色 + 法线 大概  
+	        const eachVisiCPointWeight = eachCloudPointWeight * 5;    // 或 maxMemory / (6*1000*1000) 大概值接近 (再除以一个数是因为显示的要比内存中的耗更多资源
+	        const eachGltfPosWeight = 100/1000/1000;  //M  每个顶点pos是3*4个字节?法线3*4和uv2*4  其实还有贴图 
+	        let posCount=0;
+
 	        
-	        let posCount=0, gltfCount=0;     //gltf的怎么获取模型复杂度?暂时只根据个数吧
 	        viewer.objs.children.forEach(e=>{
-	            if(e.name == 'glb' || e.name == 'obj'){
+	            if(e.fileType == 'glb' || e.fileType == 'obj'){
 	                e.traverse((mesh)=>{
 	                    if(mesh.geometry){
 	                        posCount += mesh.geometry.attributes.position.count;
-	                    }
+	                    } 
 	                });
-	            }else if(e.name == 'gltf'){
-	                gltfCount ++;
+	            }else if(e.fileType == '3dTiles'){
+	                  
 	            }
 	        });
-	        let score = posCount + gltfCount * 5000;
-	        let min = 3, max = 5, minP = 20000, maxP = 1000000;
-	        let ratio = max - ( max - min) * MathUtils.clamp((score - minP)  / (maxP - minP),0,1);  
-	                
+	        
+	        //获取点云的内存限制
+	        let objWeight = posCount*eachObjPosWeight;
+	        let laserWeight = Potree.numVisiblePoints  * eachCloudPointWeight; //点云实际显示所占大小
+	        let laserMemoryWeight =  Potree.lru.numPoints * eachCloudPointWeight;   //点云所使用内存大小
+	        let tiles3DWeight = viewer.tiles3dVisiVCount * eachGltfPosWeight; //M   3dTiles所占内存大小
+	        let tiles3DMemoryWeight = viewer.tiles3dMemoryUsage / 1000 / 1000;  //M   3dTiles显示的所占内存大小
+	        
+	        /* let min = 0.1, max = 6, minP = 100, maxP = 1000000; 
+	        let ratio = Math.round(math.linearClamp(score, minP, maxP, max, min ));  */
+		    let rest = maxMemory - objWeight - tiles3DWeight;         
+	        Potree.pointBudget = Math.max(30000, Math.round(rest/eachVisiCPointWeight)); 
+	        
+	        //获取3dTiles的内存限制 
+	        let tiles3DMaxMemory = maxMemory - Math.round(objWeight + laserWeight);
+	        Potree.settings.tiles3DMaxMemory = MathUtils.clamp(tiles3DMaxMemory , 30, Potree.config.tiles3DMaxMemory );
 	        
 	        
-	        Potree.pointBudget = ratio*1000*1000;
 	        
+	        //还存在的问题:仍然有隐患,因为没用到真实缓存的大小: tiles3DMemoryWeight  laserMemoryWeight, 它们比真实可见的要多。不使用是因为它们无法反应出实际需要的内存量,缓存是只增不减
+	        //obj等普通mesh限制不了
 	        
 	        
+	        //console.log('objWeight',objWeight.toFixed(1), 'laserMemoryWeight',laserMemoryWeight.toFixed(1), 'tiles3DWeight',tiles3DWeight.toFixed(1),  'pointBudget',Potree.pointBudget, 'tiles3DMaxMemory',tiles3DMaxMemory)
+	        
+	        
+	        //总内存 = 内存占用空间+图片缓存 , obj的缓存比较多在图片中
+	        
 	        
 	    },
 	};   
@@ -129675,8 +129729,8 @@ ENDSEC
 	***************************************************************************** */
 
 
-	window.visiVertexCount = 0;
-	window.visiGeoCount = 0;
+	let visiVertexCount = 0;
+	let visiGeoCount = 0;
 	const maxVertexVisi = 5e6;
 	const maxTexVisi = 500;
 
@@ -129694,6 +129748,9 @@ ENDSEC
 	    if(win.parent != win){//还有父级页面。 暂时只有子级需要考虑父级,假设父级在前台时子级已经销毁
 	        c += getGpuMemoryUsage(win.parent);
 	    } 
+	    
+	    viewer.tiles3dMemoryUsage = c;
+	    viewer.tiles3dVisiVCount = visiVertexCount;
 	    return  c
 	}
 
@@ -137172,7 +137229,7 @@ ENDSEC
 	    const trimTiles = this._trimTiles;
 	    this._trimTiles = false;
 	    const list = this._list;
-	    const maximumMemoryUsageInBytes = tileset.maximumMemoryUsage * 1024 * 1024;
+	    const maximumMemoryUsageInBytes = (Potree.settings.tiles3DMaxMemory ||  tileset.maximumMemoryUsage) * 1024 * 1024;
 	    const sentinel = this._sentinel;
 	    let node = list.head;
 
@@ -138914,7 +138971,9 @@ ENDSEC
 	  }
 
 	  get isVisibleAndInRequestVolume() {
-	    return  /* this._visible &&  */this.tileset.visible && this._inRequestVolume; //用_updateBoundingVolume这个算的在相机靠近时不准确,容易缺块
+	    let v =  /* this._visible &&  */this.tileset.visible && this._inRequestVolume; //用_updateBoundingVolume这个算的在相机靠近时不准确,容易缺块
+	    if(window.tileVisi2)v = this._visible && v;
+	    return v 
 	  }
 
 	  get hasRenderContent() {
@@ -147379,11 +147438,15 @@ ENDSEC
 	                            model.add(mesh);
 	                        return model;
 	                    },
-	                    update: function (dt, renderer, camera) {
+	                    update: function (dt, renderer, camera, ifForce) {
 	                        cameraReference = camera;
-	                        rendererReference = renderer;
+	                        rendererReference = renderer; 
 	                        timer += dt;
-	                        if (tileset && timer >= UPDATE_INTERVAL) {
+	                        
+	                        if(!ifForce) ifForce = tileset.nextForceUpdate;
+	                        tileset.nextForceUpdate = false;
+	                        
+	                        if (tileset && (timer >= UPDATE_INTERVAL || ifForce)) {
 	                            if (!lastRootTransform.equals(root.matrixWorld)) {
 	                                timer = 0;
 	                                lastRootTransform.copy(root.matrixWorld);
@@ -147412,7 +147475,7 @@ ENDSEC
 	                            else {
 	                                const cameraChanged = !camera.matrixWorld.equals(this.lastCameraTransform) ||
 	                                    !(camera.aspect == lastCameraAspect);
-	                                if (cameraChanged) {
+	                                if (cameraChanged || ifForce) {
 	                                    timer = 0;
 	                                    tileset._frameNumber++;
 	                                    camera.getWorldPosition(lastCameraPosition);
@@ -147656,7 +147719,7 @@ ENDSEC
 	tile.computedTransform   被我修改了,之前左乘了tileset.modelMatrix,现只包含了transform信息     _updateTransform(parentTransfor  其中有_updateBoundingVolume,这个影响可见性, 在computeVisibilityWithPlaneMask中计算
 
 	 
-	 
+	tileset._cache.trim(), 然后再update //可以将所有不可见的tiles dispose
 
 
 
@@ -147665,8 +147728,8 @@ ENDSEC
 	    return  this._inRequestVolume; //去掉了_visible ||  
 	}
 
-	显示所有tile似乎也不会卡顿. 但好像影响了加载顺序从而变慢了
-
+	显示所有tile似乎也不会卡顿. 但好像影响了加载顺序从而变慢了。visiVertexCount过量。 怀疑应该还是文件的bound有问题。
+	原本会消失的地方虽然不会消失了但一直是模糊的
 	 */
 
 	/**
@@ -150521,12 +150584,12 @@ ENDSEC
 	    let rootWin = Common$1.getRootWindow(); 
 	    rootWin.viewer.dispatchEvent({type:'createIframe', window}); //给祖先页面发送信息
 	} 
-	window.addEventListener('focus',()=>{
-	    console.log('focus',window.winIndex);
-	});
+	/* window.addEventListener('focus',()=>{
+	    console.log('focus',window.winIndex)
+	})
 	window.addEventListener('blur',()=>{
-	    console.log('blur',window.winIndex);
-	});
+	    console.log('blur',window.winIndex)
+	}) */
 
 	class Viewer extends ViewerBase{
 		
@@ -150595,6 +150658,7 @@ ENDSEC
 	        this.objs = new Object3D;
 	        
 	        this.testMaxNodeCount = 0;
+	        this.tiles3dVisiVCount = 0;
 	        //this.lastPos = new THREE.Vector3(Infinity,Infinity,Infinity) 
 			//-------------
 	        
@@ -150693,7 +150757,7 @@ ENDSEC
 	                 
 	            }
 	            
-
+	            this.tiles3dMemoryUsage = 0;
 	            
 	            this.pointCloudLoadedCallback = args.onPointCloudLoaded || function () {};
 
@@ -153431,7 +153495,7 @@ ENDSEC
 
 		renderDefault(params_={}){
 	        
-	        if(!this.visible || this.paused  )return
+	        if(!this.visible  )return
 	        
 	         
 			let pRenderer = this.getPRenderer();
@@ -154669,7 +154733,7 @@ ENDSEC
 		loop(timestamp){
 	        //let startTime = performance.now()
 	        //console.log('间隔:' ,parseInt((startTime - this.lastEndTime)*100 )/100)
-	        
+	        if(this.paused)return
 	        if(performance.getEntriesByName("loopWaitNext-start").length)viewer.addTimeMark('loopWaitNext','end'); 
 	        
 	         
@@ -155251,7 +155315,7 @@ ENDSEC
 	                    //basisTranscoderPath: '../utils/loaders/KTX2Loader/basis',
 	                    maximumScreenSpaceError: 30,  //如果本身tiles很密很小这个值就不能很大。
 	                    maxDepth: 100, 
-	                    maximumMemoryUsage: 200, //缓存大小。单位M(但实际结果是 2.5*maximumMemoryUsage + 750  。超过2G会崩, 所以应该小于540) 若太小,密集的tile反复加载很卡. 
+	                    maximumMemoryUsage: 200, //缓存大小。单位M(但实际结果是 2.5*maximumMemoryUsage + 750  。超过2G会崩, 所以应该小于540) 若太小,密集的tile反复加载很卡. (任务管理器刷新网页后若内存不掉就要结束进程否则虚高)
 	                    //debug:true,
 	                    parent: this.scene.scene
 	                },
@@ -155283,6 +155347,7 @@ ENDSEC
 	                    set: function(v) {
 	                        vi = v; 
 	                        tileset.visible = v;  //同步,使不加载
+	                        tileset.nextForceUpdate = true;
 	                    }
 	                });  
 	            }
@@ -155302,6 +155367,31 @@ ENDSEC
 	    
 	    
 	     
+	    
+	    setDisplay(state, cause='setDisplay'){//如果创建了iframe,主页的需要隐藏的话需要释放一些内存出来。iframe关闭前也释放下比较保险
+	        state = !!state;
+	        this.objs.children.forEach(e=>{
+	            if(e.fileType == '3dTiles'){
+	                let tileset = e.runtime.getTileset();
+	                Potree.Utils.updateVisible(e,  cause, state);
+	                if(!state) tileset._cache.trim(); //使下一次update时dispose所有不可见的tiles
+	                e.runtime.update(16, this.renderer, this.mainViewport.camera, true);
+	                if(state) this.dispatchEvent('content_changed');
+	            }
+	        });
+	        
+	        
+	        if(state){
+	            Potree.pointBudget = 6*1000*1000; //先随便写一个, 随后mergeEditor.updateMemoryUsage
+	        }else {
+	            Potree.pointBudget = 0;
+	            Potree.updatePointClouds(this.scene.pointclouds,  this.mainViewport.camera,  this.mainViewport.resolution );
+	        }
+	        this.dispatchEvent({type:'setDisplay',state});
+	        
+	        this.paused = !state;  
+	    }
+	     
 	        
 	    addFire(){   
 	  

ファイルの差分が大きいため隠しています
+ 1 - 1
public/lib/potree/potree.js.map


+ 22 - 27
src/sdk/cover/index.js

@@ -38,36 +38,31 @@ export const enter = (dom, isLocal) => {
     })
     
     
-    
-    if(!Potree.isIframeChild){
-        
-        viewer.addEventListener('createIframe',(e)=>{//创建了子页面
-            let child = e.window;
-            //案件里视图提取页面子页面覆盖了父级页面,父级的模型可以隐藏
-            console.log('createIframe', child.winIndex)
-            viewer.objs.children.forEach(e=>{
-                if(e.fileType == '3dTiles'){
-                    let tileset = e.runtime.getTileset()
-                    Potree.Utils.updateVisible(e, 'createIframe', false)
-                    tileset._cache.trim(); //使下一次update时dispose所有不可见的tiles
-                    e.runtime.update(16, viewer.renderer, viewer.mainViewport.camera, true)
-                    viewer.dispatchEvent('content_changed')
-                }
-            })
-            
-        }) 
-        //不知道删除iframe时是否那些模型还在内存里,需要释放吗? 如果要需要加一个事件
-    }else{
-        window.beforeDestroy = function(){
-            console.log('window.beforeDestroy', window.winIndex)
-           /*  Common.getRootWindow().
-            Potree.Utils.updateVisible(e, 'createIframe', false)
-                      
-                      viewer.dispatchEvent('content_changed') */
+    {
+        
+        //let setDisplay()
+        
+        if(!Potree.isIframeChild){
+            
+            viewer.addEventListener('createIframe',(e)=>{//创建了子页面
+                let child = e.window;
+                //案件里视图提取页面子页面覆盖了父级页面,父级的模型可以隐藏以释放内存
+                console.log('createIframe', child.winIndex)
+                viewer.setDisplay(false ) 
+            }) 
+            //不知道删除iframe时是否那些模型还在内存里,需要释放吗? 如果要需要加一个事件
+        }else{
+            window.beforeDestroy = function(){
+                console.log('window.beforeDestroy', window.winIndex)
+                
+                viewer.setDisplay(false  )
+                
+                let rootWin = Potree.Common.getRootWindow()
+                rootWin.viewer.setDisplay(true )//恢复主页的模型显示
+            }
         }
     }
     
-    
     window.THREE = THREE
     //isLocal = false 
     let autoLoads = []