Prechádzať zdrojové kódy

fix: 之前有bug:在全景模式用了深度图来pick了。另外更新下pick,优化

xzw 1 rok pred
rodič
commit
ce7f38b797

+ 21 - 19
src/ExtendPointCloudOctree.js

@@ -221,11 +221,16 @@ export class ExtendPointCloudOctree extends PointCloudOctree{
 		viewer.addTimeMark('pick','start')
 
 		let getVal = (a, b) => a != void 0 ? a : b;
-         
-      
-        let pickWindowSize_ = THREE.Math.clamp( Math.round((1.1-this.maxLevel/this.nodeMaxLevel)*80),  5, 100)
-		let pickWindowSize = getVal(params.pickWindowSize, pickWindowSize_    ); /* 65 */ //拾取像素边长,越小越精准,但点云稀疏的话可能容易出现识别不到的情况。 另外左下侧会有缝隙无法识别到,缝隙大小和这个值有关//突然发现pickWindowSize在一百以内的变化对pick费时影响甚微,1和100差1毫秒不到,但400时会多4毫秒
-            
+        let pickWindowSize = params.pickWindowSize;   //拾取像素边长,越小越精准,但点云稀疏的话可能容易出现识别不到的情况。 另外左下侧会有缝隙无法识别到,缝隙大小和这个值有关//突然发现pickWindowSize在一百以内的变化对pick费时影响甚微,1和100差1毫秒不到,但400时会多4毫秒
+        if(pickWindowSize == void 0){
+            if(Potree.settings.displayMode == 'showPanos'){ 
+                pickWindowSize = 50
+            }else{
+                let r0 = this.nodeMaxLevel > 0 ? this.maxLevel/this.nodeMaxLevel : 0.5
+                pickWindowSize = THREE.Math.clamp( Math.round((1.1-r0)*80),  15, 100)
+            }
+        }
+        
         if(camera.type == 'OrthographicCamera'){
             var cameraDir = new THREE.Vector3(0,0,-1).applyQuaternion(camera.quaternion) 
             pickWindowSize *= 4  //pointsize比较大时截取太小会没多少点可以选
@@ -242,7 +247,7 @@ export class ExtendPointCloudOctree extends PointCloudOctree{
             if(window.testScreen){            
                 let dataUrl = Potree.Utils.renderTargetToDataUrl(pickState.renderTarget, width, height, renderer)
              
-                Common.downloadFile(dataUrl, 'screenshot.jpg')  //为什么图片上不是只有pickWindowSize区域有颜色??
+                Potree.Common.downloadFile(dataUrl, 'screenshot.jpg')  //为什么图片上不是只有pickWindowSize区域有颜色??
                 window.testScreen = 0
             } 
         }
@@ -312,12 +317,8 @@ export class ExtendPointCloudOctree extends PointCloudOctree{
 		let pixelPos = new THREE.Vector2(params.x, params.y);
 
 		let gl = renderer.getContext();
-		gl.enable(gl.SCISSOR_TEST);
-		gl.scissor(  //规定渲染范围,只渲染一小块
-			parseInt(pixelPos.x - (pickWindowSize - 1) / 2),
-			parseInt(pixelPos.y - (pickWindowSize - 1) / 2),
-			parseInt(pickWindowSize), parseInt(pickWindowSize));
- 
+		pickState.renderTarget.scissor.set(parseInt(pixelPos.x - (pickWindowSize - 1) / 2),  parseInt(pixelPos.y - (pickWindowSize - 1) / 2),parseInt(pickWindowSize), parseInt(pickWindowSize)); 
+        pickState.renderTarget.scissorTest = true
 
 		renderer.state.buffers.depth.setTest(pickMaterial.depthTest);
 		renderer.state.buffers.depth.setMask(pickMaterial.depthWrite);
@@ -327,7 +328,7 @@ export class ExtendPointCloudOctree extends PointCloudOctree{
 		{ // RENDER
 			renderer.setRenderTarget(pickState.renderTarget);
 			gl.clearColor(0, 0, 0, 0);
-			renderer.clear(true, true, true);
+			//renderer.clear(true, true, true);
 
 			let tmp = this.material;
 			this.material = pickMaterial;
@@ -351,7 +352,8 @@ export class ExtendPointCloudOctree extends PointCloudOctree{
         //w<pickWindowSize会报错
     
 		gl.readPixels(x, y, pickWindowSize, pickWindowSize, gl.RGBA, gl.UNSIGNED_BYTE, buffer); //这句花费最多时间 pc:2-4, 即使只有1*1像素
- 
+        renderer.clear(true, true, true);  //绘制完就clear否则download的图会有上次的轨迹
+        
 		renderer.setRenderTarget(null);
 		renderer.state.reset();
 		renderer.setScissorTest(false);
@@ -510,12 +512,12 @@ export class ExtendPointCloudOctree extends PointCloudOctree{
                 
                 let nearest = sorted1[0]  //return nearest.point;  //直接用最近点 在点云稀疏时不太跟手,如地面上,最近点往往在鼠标下方
                  
-                let r = 10
+                let pickFrontRatio = 20
                 
                 hits.forEach( hit=>{
                     let disDiff = hit.disSquare - nearest.disSquare //和最近点的偏差 
                     hit.disDiff = disDiff 
-                    hit.score = -hit.distanceToCenter - disDiff * r
+                    hit.score = -hit.distanceToCenter - disDiff * pickFrontRatio
                 })
                 
                 let sorted2 = hits.sort( (a, b) => b.score - a.score  );
@@ -544,7 +546,7 @@ export class ExtendPointCloudOctree extends PointCloudOctree{
             }
             num_ = num_ / (Potree.config.material.realPointSize / Potree.config.material.pointSize) //兼容 
                
-            num_ = Math.pow(num_, 1.05) * 5 
+            //num_ = Math.pow(num_, 1.05) * 5 
              
             
             nodeMaxLevel = this.testMaxNodeCount >= Potree.config.testNodeCount1 ? this.nodeMaxLevel : this.nodeMaxLevelPredict.max //防止刚开始因nodeMaxLevel没涨完,导致过大的点云突然出现
@@ -559,7 +561,7 @@ export class ExtendPointCloudOctree extends PointCloudOctree{
                     let base = this.material.spacing / Math.pow(2, this.maxLevel) //点云大小在level为0时设置为spacing,每长一级,大小就除以2.  (不同场景还是会有偏差)
                     base *=  nodeMaxLevel > 0 ? Math.max(0.1, Math.pow(this.maxLevel /  nodeMaxLevel, 1.4)) : 0.1 //低质量的缩小点,因为视觉上看太大了。navvis是不铺满的,我们也留一点缝隙(但是ortho是不用缩小的,如果能分开判断就好了)
 
-                    size = base * 5 * num_/*  * window.devicePixelRatio */
+                    size = base * 20 * num_/*  * window.devicePixelRatio */
                     //在t-8BCqxQAr93 会议室 和 t-e2Kb2iU 隧道 两个场景里调节,因为它们的spacing相差较大,观察会议室墙壁的龟裂程度
                     this.temp.sizeFitToLevel[str] = size
                 }
@@ -568,7 +570,7 @@ export class ExtendPointCloudOctree extends PointCloudOctree{
                 /* let base = 0.007; */ let base = this.material.spacing / Math.pow(2,  nodeMaxLevel) //点云大小在level为0时设置为spacing,每长一级,大小就除以2
                 //base的数值理论上应该是右侧算出来的,但发现有的场景nodeMaxLevel和nodeMaxLevelPredict差别较大的点云显示也过大,而直接换成固定值反而可以适应所有场景。该固定值来源于 getHighestNodeSpacing 最小值,修改了下。(会不会是我们的相机其实该值是固定的,根据该值算出的spacing才是有误差的? 如果换了相机是否要改值?)
                 //2022-12-21又换回非固定值。因为有的场景如SS-t-t01myDqnfE的两个数据集密集程度差别很大,应该将稀疏点云的大小设置的大些。 但是这样的缺点是两个数据集因相接处有大有小无法融合。
-                size = base * 5 * num_ /* * window.devicePixelRatio  */
+                size = base * 20 * num_ /* * window.devicePixelRatio  */
             } 
             
         }  

+ 30 - 7
src/custom/potree.shim.js

@@ -278,6 +278,8 @@ Utils.getMousePointCloudIntersection = function(viewport, mouse, pointer, camera
     let old_clipBoxes_out = new Map()  
     let old_bigClipInBox = new Map()  
     let old_highlightBoxes = new Map()   
+    let old_visibleNodes = new Map()
+    
     
     //bigClipInBox 最好也写下 
     let density
@@ -294,13 +296,11 @@ Utils.getMousePointCloudIntersection = function(viewport, mouse, pointer, camera
             visiMap.set(e,e.visible)
             e.visible = Potree.Utils.getObjVisiByReason(e, 'datasetSelection'); //先将隐藏的点云显示
             if(!e.visible)return
-             
-            
+              
             size.set(e, e.temp.pointSize)    
             sizeType = e.material.pointSizeType  
-            e.material.pointSizeType = Potree.config.material.pointSizeType 
-             
-            e.changePointSize(Potree.config.material.realPointSize*2, true)//更改点云大小到能铺满为止,否则容易识别不到
+            e.material.pointSizeType = Potree.config.material.pointSizeType  
+            //e.changePointSize(Potree.config.material.realPointSize*2, true)//更改点云大小到能铺满为止,否则容易识别不到
         }) 
         needsUpdate = true
     }else{ 
@@ -323,7 +323,21 @@ Utils.getMousePointCloudIntersection = function(viewport, mouse, pointer, camera
     }
     
     if(needsUpdate){
-        Potree.updatePointClouds(pointclouds,  camera, viewport.resolution );  //最好只更新pick的范围的resolution
+        for(let pointcloud of pointclouds){  
+            old_visibleNodes.set(pointcloud, pointcloud.visibleNodes)
+        } 
+        
+        if(window.notViewOffset){ 
+            Potree.updatePointClouds(pointclouds,  camera, viewport.resolution );  
+        }else{
+            //尽量减少点云加载的范围,集中在pick的空间。但似乎感觉这部分空间没加载到最密
+            let viewWidth = 100//viewer.magnifier ? viewer.magnifier.viewport.resolution.x : 200
+            let camera_ = camera.clone()
+            camera_.setViewOffset( viewport.resolution.x, viewport.resolution.y,   pickParams.x-viewWidth/2, pickParams.y-viewWidth/2,    viewWidth, viewWidth );
+            Potree.updatePointClouds(pointclouds,  camera_, viewport.resolution );   
+        } 
+    
+    
     }
     //------------------------------------------------
     
@@ -358,7 +372,7 @@ Utils.getMousePointCloudIntersection = function(viewport, mouse, pointer, camera
         pointclouds.forEach(e=>{
             if(e.visible){
                 e.material.pointSizeType = sizeType
-                e.changePointSize(size.get(e))
+                //e.changePointSize(size.get(e))
             }
             e.visible = visiMap.get(e)  
         })
@@ -367,12 +381,21 @@ Utils.getMousePointCloudIntersection = function(viewport, mouse, pointer, camera
             viewport.afterRender && viewport.afterRender() 
         } */
     }
+     
+    
     if(!pickParams.pickClipped){//add  
         for(let pointcloud of pointclouds){  
             pointcloud.material.setClipBoxes(old_bigClipInBox.get(pointcloud), old_clipBoxes_in.get(pointcloud), old_clipBoxes_out.get(pointcloud), old_highlightBoxes.get(pointcloud))  
         } 
     }
 
+
+    if(needsUpdate){ 
+        for(let pointcloud of pointclouds){  //不恢复的话(尤其cameraChanged时),在下次render前,再次pick可能是错的。表现为多数据集刚开始reticule消失了,直到ifPointBlockedByIntersect停止 
+            pointcloud.visibleNodes = old_visibleNodes.get(pointcloud)
+        }  
+    }
+
     if (selectedPointcloud) {
         return {
             location: closestIntersection,

+ 2 - 1
src/custom/settings.js

@@ -99,7 +99,8 @@ const config = {//配置参数   不可修改
     
     pointDensity:{
         magnifier:{  
-            maxLevelPercent: 1 
+            maxLevelPercent: 1,
+            pointBudget: 1*1000*1000,
         },
         panorama:{//显示全景时的漫游。因为点只能显示1个像素的大小,所以必须很密集,但又要限制点的数量
             maxLevelPercent: 0.6,

+ 11 - 7
src/custom/viewer/ViewerNew.js

@@ -558,19 +558,23 @@ export class Viewer extends ViewerBase{
                     return pointDensity
                 },
                 set: (density)=>{
-                    if(density && density != pointDensity){  
-                        let pointBudget;
-                        var config = Potree.config.pointDensity[density]; 
-                        pointBudget = config.pointBudget
+                    if(density){  
+                        
+                        let config = Potree.config.pointDensity[density];
+                        let pointBudget = config.pointBudget;
+                        if(density == 'magnifier'){//尽可能不变pointBudget,否则点云可能会闪烁,因点云被释放又加载,如SS-t-7DUfWAUZ3V 
+                            pointBudget = Math.max(Potree.pointBudget,  Potree.config.pointDensity['magnifier'].pointBudget)
+                        }else if(this.magnifier.visible){//放大镜打开时要保证最低点云数量(全景模式没点)
+                            pointBudget = Math.max(pointBudget,  Potree.config.pointDensity['magnifier'].pointBudget)
+                        } 
                         viewer.setMinNodeSize(config.minNodeSize || Potree.config.minNodeSize)
-                        viewer.setPointBudget(pointBudget );
-                        //Potree.maxPointLevel = config.maxLevel
+                        viewer.setPointBudget(pointBudget ); 
                         
                         pointDensity = density
                         
                         this.setPointLevels()
                         
-                        
+                          
                     }
                 }
             })

+ 5 - 9
src/navigation/InputHandlerNew.js

@@ -854,7 +854,7 @@ export class InputHandler extends THREE.EventDispatcher {
                 camera, 
                 this.viewer, 
                 this.viewer.scene.pointclouds,
-                {pickClipped: true, measuring: this.measuring.length>0, pickWindowSize, cameraChanged: !!point }  
+                {pickClipped: true, isMeasuring: this.measuring.length>0, pickWindowSize, cameraChanged: !!point }  
                 
             );
             
@@ -901,17 +901,13 @@ export class InputHandler extends THREE.EventDispatcher {
         if(!intersect){
             let canUseDepthTex = !Potree.settings.unableUseDepTexPick && (Potree.settings.displayMode == 'showPanos' || useDepthTex)
                 && viewer.images360.currentPano.pointcloud.hasDepthTex && viewport == viewer.mainViewport && !usePointcloud 
-            
-            
-            /* if(canUseDepthTex)getByDepthTex()
-            else getByCloud()  */
-            if(canUseDepthTex && !this.isMeasuring){
+            //交通的深度图不准,先只用在reticule上
+          
+            if(canUseDepthTex && this.measuring.length == 0){
                 getByDepthTex()
             }else{
                 getByCloud() 
-                /* if(!intersectPoint && canUseDepthTex  ){  //若在测量,先尝试点云,再用全景 //后来发现有深度图的点云全景visibleNode为空,pick不到的//如果允许的话,裁剪掉的点云也会得到intersect
-                    getByDepthTex()
-                } */
+                
             }