xzw 1 year ago
parent
commit
d4f524aa63

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

@@ -1798,6 +1798,11 @@ export class Images360 extends THREE.EventDispatcher{
                     return -dis1 
                 }else{
                     let dis2 = disSquareMap.get(pano)
+                    
+                    if(o.gotoBestView){//忽略和当前视线的角度
+                        return -(dis1 + dis2*0.3)
+                    }
+                    
                     let vec2 = new THREE.Vector3().subVectors(target,pano.position).normalize()
                     let cos = dir.dot(vec2)  
                     //let result = (- dis1  - Math.pow(dis2 , 1.5)) / (cos + 2)  // cos+2是为了调整到1-3, 
@@ -1829,7 +1834,7 @@ export class Images360 extends THREE.EventDispatcher{
         
 		 
 		var g = Common.sortByScore(panos,  require, rank);
-        //console.log(g)
+        // console.log(g)
         
 		/* let result1 = g && g.slice(0, 10)
         if(result1){ 

+ 2 - 2
src/custom/objects/Magnifier.js

@@ -6,7 +6,7 @@ import Viewport from '../viewer/Viewport.js'
 import {ExtendView} from "../../viewer/ExtendView.js"; 
 const texLoader = new THREE.TextureLoader() 
 const circleGeo = new THREE.CircleGeometry(1.45,100);
-const sphereGeo = new THREE.SphereBufferGeometry(0.012,8,8);
+const sphereGeo = new THREE.SphereBufferGeometry(0.008,8,8);
  
  
 const magDisMin = 1;//相机离目标位置的距离的分界线,当离得远时要缩小fov以使看到的视野固定(望远镜效果)
@@ -14,7 +14,7 @@ const magDisMax = 20
 /* const radius_ = 0.2; //当相机离目标位置的距离>magDistance_时,希望看到的视野的半径
 const maxFov = THREE.Math.radToDeg(Math.atan(radius_ / magDisMin )) * 2//提前计算出当相机离目标位置的距离<magDisMin时的fov,均使用=magDisMin时的fov。只要保证该fov大于主相机的fov就会有放大效果 
  */
-let w = 250/1.43;
+let w = 230/1.43;
 let maxPX = 1366*1024 //ipad pro.  大于这个分辨率的就直接用devicePixelRatio, 如macbook也是
 const width2dPX = Math.round(window.devicePixelRatio >= 2 ? ( window.screen.width * window.screen.height >= maxPX ? window.devicePixelRatio/1.2 : window.devicePixelRatio/1.5)*w : w)  //触屏或高分辨率的可能要放大些。但在手机上不能太大
 //console.log('width2dPX', width2dPX)

+ 23 - 7
src/custom/objects/Reticule.js

@@ -5,7 +5,7 @@ import math from '../utils/math.js'
 
 
 let texLoader = new THREE.TextureLoader()
-let defaultOpacity =  0.7
+let defaultOpacity =  0.5
 let Buttons = Potree.defines.Buttons
 
 
@@ -98,7 +98,7 @@ export default class Reticule extends THREE.Mesh{
 
 
     move(e){ 
-        if(e.type == "global_mousemove" && (e.isTouch || e.buttons != Buttons.NONE) && this.state != 'crosshair'){
+        if(e.type == "global_mousemove" && (e.isTouch || e.buttons != Buttons.NONE) && !this.state.cross){
             return//按下时不更新,除非拖拽测量
         }
            
@@ -168,14 +168,30 @@ export default class Reticule extends THREE.Mesh{
             s = math.getScaleForConstantSize($.extend(   sizeInfo ,  
             {position:this.position, camera, resolution:viewport.resolution/* 2 */} ))
             
-        }else{
-            
+        }else{ 
             let n = camera.position.distanceTo(this.position)
-            s = 1 + .1 * n;
-            n < 1 && (s -= 1 - n)
+              
+            if( n < 1 ){
+                if(this.state.cross ){   //测量时更精细些
+                     s = 0.7 * n
+                }else{
+                     s = 1.1 * n 
+                }
+            }else{
+                if(this.state.cross ){  
+                     s = 0.4 + 0.3 * n //n乘以的系数越高,其越不近大远小(大小越恒定)
+                }else{
+                     s = 1 + 0.1 * n; 
+                }  
+            }
+            
+            if(this.state.cross ){  //测量时更精细些
+                s /= viewer.images360.zoomLevel
+            } 
+            
         }
         this.scale.set(s, s, s);
-        
+         
     }
 
     updateAtViewports(viewport){//当多个viewports时更新。更新大小等

+ 34 - 13
src/custom/objects/Sprite.js

@@ -16,8 +16,16 @@ export default class Sprite extends THREE.Mesh{
         this.options = options 
         this.position.y = options.disToLine || 0 //离线距离
         
-        this.root.matrixAutoUpdate = false;
-        this.matrixMap = new Map()
+         
+        this.matrixAutoUpdate = false;
+        this.matrixMap = new Map() 
+        
+        if(this.root != this){
+            this.matrixMapRoot = new Map() 
+            this.root.matrixAutoUpdate = false;
+        }
+        
+        
         this.visiMap = new Map()
         this.name = options.name || 'sprite'
         this.useViewport = null
@@ -146,8 +154,8 @@ export default class Sprite extends THREE.Mesh{
         if(!this.dontFixOrient){        //orthoCamera一般要加dontFixOrient  
             let orient2dAngle    
     
-            if(this.root.lineDir){  
-                this.root.updateMatrix();//先更新,getWorldPosition才能得到正确的
+            if(this.root.lineDir){   
+                this.root.updateMatrix();//先更新,getWorldPosition才能得到正确的 
                 this.root.updateMatrixWorld(true)
                 let center = this.root.getWorldPosition(new THREE.Vector3())
                 //由于两个端点容易在屏幕外,所以使用center和center加dir
@@ -198,9 +206,7 @@ export default class Sprite extends THREE.Mesh{
                     return  setVisi(false)//, console.log('  !r2.trueSide', )
                 }
                  
-                
-                
-                let orient2dInfo = {} 
+                 
                 let p1 = r1.pos,  p2 = r2.pos 
                 if(p2StateHistory.filter(e=>e == 'tooLong-reverse').length%2 == 1){//反,for marker
                     p2 = r1.pos,  p1 = r2.pos
@@ -268,10 +274,17 @@ export default class Sprite extends THREE.Mesh{
                 this.root.scale.set(scale, scale, scale); 
             } 
         }
-        this.root.updateMatrix();
-        this.root.updateMatrixWorld(true)
+        
+        
+        this.updateMatrix();
+        //this.root.updateMatrixWorld(true)
         //console.log(this.root.text, this.root.matrix.elements)
-        this.matrixMap.set(e.viewport, this.root.matrix.clone())
+        this.matrixMap.set(e.viewport, this.matrix.clone())
+        if(this.root != this){
+            this.root.updateMatrix(); //因this.position可能在两个viewport不同          
+            this.matrixMapRoot.set(e.viewport, this.root.matrix.clone())
+        }
+         
         this.needsUpdate = false
         this.useViewport = e.viewport
          
@@ -299,11 +312,19 @@ export default class Sprite extends THREE.Mesh{
         }
         
         if(e.viewport == this.useViewport){
-            return
+            return 
         }       
         this.useViewport = e.viewport   
-        this.root.matrix.copy(matrix) 
-        this.root.updateMatrixWorld(true)
+         
+        this.matrix.copy(matrix)  
+        
+         
+        if(this.root != this){
+            var matrix2 = this.matrixMapRoot.get(e.viewport);
+            this.root.matrix.copy(matrix2) 
+        }
+        if(e.raycaster)console.log(3)  
+        e.raycaster && this.root.updateMatrixWorld(true)//渲染前会自动updateMatrixWorld,但raycaster不会
         //console.log(this.root.name + e.viewport.name + " : "+this.root.matrixWorld.elements)
     }
     

+ 23 - 20
src/custom/objects/TextSprite.js

@@ -53,6 +53,7 @@ export class TextSprite extends THREE.Object3D{
 			this.text = text + '';
 
 			this.updateTexture();
+            this.sprite.waitUpdate() //重新计算各个viewport的matrix 
 		}
 	}
 
@@ -89,28 +90,27 @@ export class TextSprite extends THREE.Object3D{
 	updateTexture(){
 		let canvas = document.createElement('canvas');
 		let context = canvas.getContext('2d');
-		context.font = this.fontWeight + ' ' + this.fontsize + 'px ' + this.fontface; 
+        const r = window.devicePixelRatio
+		context.font = this.fontWeight + ' ' + this.fontsize * r + 'px ' + this.fontface; 
        
         //context["font-weight"] = 100; //语法与 CSS font 属性相同。
-		// get size data (height depends only on font size)
-        
+		 
         //this.text = '啊啊啊啊啊啊fag'
         
 		let metrics = context.measureText(this.text );
 		let textWidth = metrics.width;
-		let margin = this.margin || new THREE.Vector2(this.fontsize, Math.max(  this.fontsize*0.4, 10)  );
-		let spriteWidth = 2 * margin.x + textWidth + 2 * this.rectBorderThick;
-		let spriteHeight = 2 * margin.y + this.fontsize + 2 * this.rectBorderThick; 
+		let margin = (this.margin ? new THREE.Vector2().copy(this.margin) : new THREE.Vector2(this.fontsize, Math.max(  this.fontsize*0.4, 10)  )).clone().multiplyScalar(r); 
+		let spriteWidth = 2 * margin.x + textWidth + 2 * this.rectBorderThick * r ;
+		let spriteHeight = 2 * margin.y + this.fontsize * r + 2 * this.rectBorderThick * r; 
 		context.canvas.width = spriteWidth;
 		context.canvas.height = spriteHeight;
-		context.font = this.fontWeight + ' ' + this.fontsize + 'px ' + this.fontface; 
-
-         
+		context.font = this.fontWeight + ' ' + this.fontsize * r + 'px ' + this.fontface; 
+ 
         /* let diff = 2//针对英文大部分在baseLine之上所以降低一点(metrics.fontBoundingBoxAscent - metrics.fontBoundingBoxDescent) / 2
 
         context.textBaseline = "middle"
          */
-        let expand = Math.max(1, Math.pow(this.fontsize / 16, 1.3)) // 针对英文大部分在baseLine之上所以降低一点,或者可以识别当不包含jgqp时才加这个值  
+        let expand = Math.max(1, Math.pow(this.fontsize / 16, 1.3)) * r  // 针对英文大部分在baseLine之上所以降低一点,或者可以识别当不包含jgqp时才加这个值  
          
         //canvas原点在左上角
         context.textBaseline = 'alphabetic' //  "middle"  //设置文字基线。当起点y设置为0时,只有该线以下的部分被绘制出来。middle时文字显示一半(但是对该字体所有字的一半,有的字是不一定显示一半的,尤其汉字),alphabetic时是英文字母的那条基线。
@@ -118,32 +118,34 @@ export class TextSprite extends THREE.Object3D{
         //let actualHeight = metrics.actualBoundingBoxAscent + metrics.actualBoundingBoxDescent; // 当前文本字符串在这个字体下用的实际高度
         
         //文字y向距离从textBaseline向上算
-        let actualBoundingBoxAscent = metrics.actualBoundingBoxAscent == void 0 ? this.fontsize * 0.8 : metrics.actualBoundingBoxAscent //有的流览器没有。只能大概给一个
+        let actualBoundingBoxAscent = metrics.actualBoundingBoxAscent == void 0 ? this.fontsize * r * 0.8 : metrics.actualBoundingBoxAscent //有的流览器没有。只能大概给一个
         let y = actualBoundingBoxAscent + margin.y + expand 
         //console.log(this.text, 'y' , y, 'actualBoundingBoxAscent', metrics.actualBoundingBoxAscent,'expand',expand )
                                   
         // border color
         context.strokeStyle = 'rgba(' + this.borderColor.r + ',' + this.borderColor.g + ',' +
             this.borderColor.b + ',' + this.borderColor.a + ')';
-  
-        context.lineWidth = this.rectBorderThick;
+            
+        let rectBorderThick = this.rectBorderThick * r;
+        
+        context.lineWidth = rectBorderThick
 		// background color
 		context.fillStyle = 'rgba(' + this.backgroundColor.r + ',' + this.backgroundColor.g + ',' +
 			this.backgroundColor.b + ',' + this.backgroundColor.a + ')';
-        this.roundRect(context, this.rectBorderThick / 2, this.rectBorderThick / 2,
-            spriteWidth - this.rectBorderThick, spriteHeight - this.rectBorderThick, this.borderRadius);
+        this.roundRect(context, rectBorderThick / 2 , rectBorderThick / 2,
+            spriteWidth - rectBorderThick, spriteHeight - rectBorderThick, this.borderRadius * r);
         
 		// text color
         if(this.textBorderThick){
             context.strokeStyle = 'rgba(' + this.textBorderColor.r + ',' + this.textBorderColor.g + ',' +
                 this.textBorderColor.b + ',' + this.textBorderColor.a + ')';
-            context.lineWidth = this.textBorderThick;
-            context.strokeText(this.text , this.rectBorderThick + margin.x,  y /* spriteHeight/2  + diff */ );
+            context.lineWidth = this.textBorderThick * r;
+            context.strokeText(this.text , rectBorderThick + margin.x,  y /* spriteHeight/2  + diff */ );
         }
         
 		context.fillStyle = 'rgba(' + this.textColor.r + ',' + this.textColor.g + ',' +
 			this.textColor.b + ',' + this.textColor.a + ')';
-		context.fillText(this.text , this.rectBorderThick + margin.x,  y/* spriteHeight/2  + diff */ );//x,y
+		context.fillText(this.text , rectBorderThick + margin.x,  y/* spriteHeight/2  + diff */ );//x,y
  
 
 		let texture = new THREE.Texture(canvas);
@@ -156,10 +158,11 @@ export class TextSprite extends THREE.Object3D{
             this.sprite.material.map.dispose()
         }
 		this.sprite.material.map = texture;
-		 
+		  
+		this.sprite.scale.set(spriteWidth * 0.01 / r, spriteHeight * 0.01 / r, 1.0);
         
         
-		this.sprite.scale.set(spriteWidth * 0.01, spriteHeight * 0.01, 1.0);
+         
 	}
 
 	roundRect(ctx, x, y, w, h, r){

+ 170 - 20
src/custom/objects/tool/Measure.js

@@ -22,7 +22,7 @@ var markerMats;
 var lineMats;  
 var planeMats 
  
-const textSizeRatio = math.linearClamp(window.innerWidth * window.innerHeight , 360*720,   1920*1080, 0.75, 1)  //pc字显示大一些
+const textSizeRatio = math.linearClamp(window.innerWidth * window.innerHeight , 360*720,   1920*1080, 0.7, 1)  //pc字显示大一些
  
 const lineDepthInfo = {
     clipDistance : 4,//消失距离
@@ -137,14 +137,23 @@ export class Measure extends ctrlPolygon{
         this.setUnitSystem(prop.unit || viewer.unitConvert.UnitService.defaultSystem)
         Potree.Utils.setObjectLayers(this, 'measure' )
         
+        
+        /* if(this.measureType == 'MulDistance'){
+            this.showTotalDis = true
+            
+            this.totalDisLabel = this.createTotalDisLabel()
+            this.add(this.totalDisLabel) 
+        }
+         */
+        
         //addMarkers:
-       
+         
         this.initData(prop)
         
          
         this.points_datasets || (this.points_datasets = []) //存每个点是哪个数据集
 
-
+        
         
         
         this.addEventListener('marker_dropped',(e)=>{ 
@@ -303,13 +312,20 @@ export class Measure extends ctrlPolygon{
                 let distance = point.distanceTo(nextPoint)
                 edgeLabel.shouldVisi = (index < lastIndex || this.isRect || this.closed && !this.isNew ) && distance>0 
                 /* this.closed || */edgeLabel.setVisible(edgeLabel.shouldVisi)  
-                if(edgeLabel.visible){
+                
+                if(edgeLabel.shouldVisi){
                     edgeLabel.lineDir = new THREE.Vector3().subVectors(point,nextPoint).normalize() //[point,nextPoint]
                     setEdgeLabel(edgeLabel,point,nextPoint,distance)
                 }  
             }
         } 
-
+        
+        
+        if(Potree.config.measure.mulLabelHideFaraway ){
+            this.measureType == 'MulDistance' && this.clearEdgeLabelVisi()
+        }
+        
+        
         if(this.measureType == 'Distance' && this.points.length>1){//设置水平垂直辅助线
             var pTop, pBtm
             if(this.points[0].z > this.points[1].z ){
@@ -353,10 +369,117 @@ export class Measure extends ctrlPolygon{
                 this.areaLabel.setVisible(true)
             //}  
         }  
+        
+        
+        if(this.showTotalDis && this.points.length > 2){  
+            //this.ifShowTotalDis()
+            let dis = this.getTotalDistance()
+            let msg = viewer.unitConvert.convert(dis, 'distance',  Potree.settings.precision , this.unitSystem, 0.01 , true  ) 
+            this.center = this.getCenter()
+            this.totalDisLabel.setPos(this.center);
+            this.totalDisLabel.setText(msg);
+            this.totalDisLabel.setVisible(true)
+        
+        }  
+        
 	};
     
      
-    
+    ifShowTotalDis(){ 
+        if(this.measureType == 'MulDistance' ){ 
+            let show = this.points.length > 2
+            
+            if(show){
+                
+                
+                
+                
+                
+            }
+            
+            
+            this.showTotalDis = show
+        }  
+        /* 连续测量:
+        1. ≥2次测量,单个距离<15cm时,居中显示总长
+        2. 若连续测量的线段中,大于等于1段超出15cm,所有线段均显示长度
+        -------------------
+        所有连续测量共用逻辑:
+        选中或者鼠标悬浮时,显示所有单个线段的长度(第1点不同,选中或悬浮也显示总长)
+        离开时,均显示总长 */
+    }
+
+    clearEdgeLabelVisi(){//修改点位置后清空,下次render时会自动getEdgeLabelVisi
+        let lastIndex = this.points.length - 1;   
+        for (let index = 0; index <= lastIndex; index++) {
+            if(!this.closed && index == lastIndex)continue  
+            let edgeLabel = this.edgeLabels[index];  
+            edgeLabel.visiMap.clear()  
+        }
+    }
+     
+
+    getEdgeLabelVisi(viewport){//获取多折线的edgelabel在不同视图里的可见性。要保证任何时候label能出现的线最小二维长度一致
+        let camera = viewport.camera  
+        let lastIndex = this.points.length - 1; 
+        /* let pos2ds = this.points.map(point=> point.clone().project(camera) )  //即使只是旋转也会变动,尤其是转到屏幕外后变为显示。所以不用这种
+        let minDis = 0.01; */
+        let minDis = 0.02  , minAngleRatio = 0.07, minAngle
+        let vecs
+        let forceShow 
+        if(camera.type == 'OrthographicCamera'){
+            minDis *= Math.pow(camera.top / camera.zoom, 2);
+            //console.log(minDis)
+        }else{
+            if(Potree.settings.displayMode == 'showPanos' && viewer.images360.zoomLevel == Potree.settings.zoom.max){
+                forceShow = true  //当zoom到最大时强制显示,避免有的线太短永远显示不出长度
+            }else{  
+                vecs = this.points.map(point=> new THREE.Vector3().subVectors(point, camera.position).normalize())
+                minAngleRatio /= viewport.resolution.y / 1000 / textSizeRatio //角度占fov最小比率
+                minAngle = minAngleRatio * THREE.Math.degToRad(camera.fov)
+            }
+        }
+        
+        
+        for (let index = 0; index <= lastIndex; index++) {
+            if(!this.closed && index == lastIndex)continue 
+            let edgeLabel = this.edgeLabels[index]; 
+            
+            let nextIndex = (index + 1 > lastIndex) ? 0 : index + 1;
+            let previousIndex = (index === 0) ? lastIndex : index - 1;
+            
+            let point = this.points[index];
+            let nextPoint = this.points[nextIndex]; 
+            /* let point2d = pos2ds[index];
+            let nextPoint2d = pos2ds[nextIndex];  
+            let dis2d = point2d.distanceToSquared(nextPoint2d)
+            let v = dis2d > minDis  //可见长度太小,为避免拥挤,不显示
+            edgeLabel.visiMap.set(camera, v)     */
+            let v
+            
+            if(forceShow){ 
+                v = true
+                
+            }else if(camera.type == 'OrthographicCamera'){
+                let vec = new THREE.Vector3().subVectors(point,nextPoint)
+                let projVec = vec.projectOnPlane(viewport.view.direction)
+                v = projVec.lengthSq() > minDis 
+            }else{ 
+                let vec0 = vecs[index];
+                let vec1 = vecs[nextIndex];
+                v = Math.acos(vec0.dot(vec1)) > minAngle  //角度过小代表可见长度太小,为避免拥挤,不显示
+                
+            }
+            edgeLabel.visiMap.set(camera, v) 
+            
+        }
+    } 
+
+
+
+
+
+
 
     setEdgeLabelPos(label,p1,p2){ //调整label的位置,使倾斜后看起来在线的中心,而不要挡住端点
         let center = new THREE.Vector3().addVectors(p1,p2).multiplyScalar(0.5);  
@@ -461,6 +584,11 @@ export class Measure extends ctrlPolygon{
                 edge.addEventListener('mouseover', mouseover);
                 edge.addEventListener('mouseleave', mouseleave); 
                 edge.removeEventListener('addHoverEvent', addHoverEvent);
+                
+                edge.addEventListener('click',()=>{
+                    this.isNew || viewer.focusOnObject(this, 'measure')
+                })
+                
             }
             edge.addEventListener('addHoverEvent', addHoverEvent);
 		}
@@ -787,32 +915,51 @@ export class Measure extends ctrlPolygon{
         edgeLabel.sprite.material.depthTestWhenPick = true
         Potree.Utils.setObjectLayers(edgeLabel, 'measure' )
         this.add(edgeLabel)
+        
+        if(this.measureType == 'MulDistance'){
+            edgeLabel.visiMap = new Map()
+        }
+        
+        
+        
         return edgeLabel
     }
     
-    createAreaLabel(){ 
+    createAreaLabel(){  
+        const areaLabel = this.createCenterLabel('areaLabel')
+        
+        return areaLabel; 
+    }
+    
+    createTotalDisLabel(){  
+        const totalDisLabel = this.createCenterLabel('totalDisLabel')
+        
+        return totalDisLabel;  
+    }
     
-        const areaLabel = new TextSprite(
-            $.extend({},mainLabelProp,{sizeInfo: labelSizeInfo, name:'areaLabel_', disToLine:0, fontsize:16*textSizeRatio} )
+    createCenterLabel(name){
+        const centerLabel = new TextSprite(
+            $.extend({},mainLabelProp,{sizeInfo: labelSizeInfo, name, disToLine:0, fontsize:16*textSizeRatio} )
         )
         
-        areaLabel.addEventListener('mouseover',()=>{
-            this.setSelected(true, 'areaLabel')
+        centerLabel.addEventListener('mouseover',()=>{
+            this.setSelected(true, 'centerLabel')
         })
-        areaLabel.addEventListener('mouseleave',()=>{
-            this.setSelected(false, 'areaLabel')
+        centerLabel.addEventListener('mouseleave',()=>{
+            this.setSelected(false, 'centerLabel')
         }) 
-        areaLabel.addEventListener('click',()=>{
+        centerLabel.addEventListener('click',()=>{
             this.isNew || viewer.focusOnObject(this, 'measure')
         })
-        Potree.Utils.setObjectLayers(areaLabel, 'measure' )
-        areaLabel.setVisible(false) 
-        
-        return areaLabel;
-        
+        Potree.Utils.setObjectLayers(centerLabel, 'measure' )
+        centerLabel.setVisible(false) 
         
+        return centerLabel; 
     }
-
+    
+    
+    
+    
     
     getMarkerMaterial(type) { 
         if(!markerMats){
@@ -1052,6 +1199,9 @@ export class Measure extends ctrlPolygon{
             this.area = {value:0};
             this.areaLabel && this.areaLabel.setVisible(false)
         }
+        if(this.showTotalDis){
+            this.totalDisLabel && this.totalDisLabel.setVisible(false) 
+        }
         viewer.inputHandler.dispatchEvent( {type:'isMeasuring', v:true, cause:'reDraw'}  )
 	            
     } 

+ 63 - 27
src/custom/objects/tool/MeasuringTool.js

@@ -155,10 +155,15 @@ export class MeasuringTool extends THREE.EventDispatcher{
 			this.onAdd({measurement: measurement});
 		}
 		 
-        viewer.addEventListener('camera_changed',(e)=>{ 
-            if(e.viewport == viewer.mainViewport ) this.update()
-        })
-        
+        if(Potree.config.measure.mulLabelHideFaraway ){
+         
+            viewer.addEventListener('camera_changed', this.update.bind(this),{importance:10})//优先级高于sprite
+       
+            viewer.addEventListener("raycaster", this.beforeDraw.bind(this),{importance:10})   //before render
+            viewer.addEventListener("render.begin", this.beforeDraw.bind(this),{importance:10}) //before render   
+            viewer.addEventListener("render.begin2", this.beforeDraw.bind(this),{importance:10})  
+          
+        }
         
 		//viewer.addEventListener("update", this.update.bind(this));
 		viewer.addEventListener("render.pass.perspective_overlay", this.render.bind(this));
@@ -199,39 +204,70 @@ export class MeasuringTool extends THREE.EventDispatcher{
     }
     
     
-	update(){
-        return;
+    beforeDraw(e){
+        if(e.viewport.name == 'mapViewport' && !viewer.mapViewer.attachedToViewer)return //no measures
         
+
         viewer.scene.measurements.forEach(measure=>{
-            
+            if(measure.measureType != 'MulDistance' || (measure.isNew ? measure.points.length<4 : measure.points.length<3))  return
             let lastIndex = measure.points.length - 1; 
             for (let index = 0; index <= lastIndex; index++) {
+                if(!measure.closed && index == lastIndex)continue 
+                let edgeLabel = measure.edgeLabels[index];
+                let v = edgeLabel.visiMap.get(e.viewport.camera)
                 
-                let nextIndex = (index + 1 > lastIndex) ? 0 : index + 1;
-                let previousIndex = (index === 0) ? lastIndex : index - 1;
-                
-                let point = measure.points[index];
-                let nextPoint = measure.points[nextIndex];
-                let previousPoint = measure.points[previousIndex];
- 
-                if(measure.showDistances || measure.labelText){ // edge labels
-                    let edgeLabel = measure.edgeLabels[index];
-                  
-                    if(edgeLabel.visible){
-                        measure.setEdgeLabelPos(edgeLabel, point, nextPoint  )
-                    }  
+                if(v == void 0){
+                    return measure.getEdgeLabelVisi(e.viewport)
                 }
-            }  
-        })
-        
-        
+                
+                Potree.Utils.updateVisible(edgeLabel, 'tooFar', v === false ? false : true)
+            }
+        })      
+                
+    }
+    
+	update(e){
         
         
         
+        if(e.changeInfo.projectionChanged || e.viewport.camera.type == 'PerspectiveCamera' && e.changeInfo.positionChanged){//for MulDistance
+          
+             
+            viewer.scene.measurements.forEach(measure=>{
+                if(measure.measureType != 'MulDistance' || (measure.isNew ? measure.points.length<4 : measure.points.length<3)) return
+                measure.getEdgeLabelVisi(e.viewport)
+                return  
+                
+                let lastIndex = measure.points.length - 1; 
+                for (let index = 0; index <= lastIndex; index++) {
+                    if(!measure.closed && index == lastIndex)continue 
+                    
+                    let nextIndex = (index + 1 > lastIndex) ? 0 : index + 1;
+                    let previousIndex = (index === 0) ? lastIndex : index - 1;
+                    
+                    let point = measure.points[index];
+                    let nextPoint = measure.points[nextIndex];
+                    let previousPoint = measure.points[previousIndex];
+                    let point2d = new THREE.Vector2().copy(pos2ds[index]);
+                    let nextPoint2d = new THREE.Vector2().copy(pos2ds[nextIndex]);
+                    if(measure.showDistances || measure.labelText){ // edge labels
+                        let edgeLabel = measure.edgeLabels[index];
+                      
+                        if(edgeLabel.visible){
+                            measure.setEdgeLabelPos(edgeLabel, point, nextPoint  )
+                        }  
+                    }  
+                }  
+            })
+            
+        }
+            
+            
+            
         return;
-        
-        
-        
+            
+            
+            
         
 		let camera = this.viewer.scene.getActiveCamera();
 		let domElement = this.renderer.domElement;

+ 8 - 5
src/custom/objects/tool/ctrlPolygon.js

@@ -305,7 +305,7 @@ export class ctrlPolygon extends THREE.Object3D {
                     }
                 }
                 
-                if( this.facePlane && !this.cannotConfirmNormal  ){//之后加的点一定要在面上  
+                if(this.atPlane && this.facePlane && !this.cannotConfirmNormal  ){//之后加的点一定要在面上  
                     if(atMap){ 
                         //地图上用垂直线,得到和面的交点。
                         verticalLine.set(location.clone().setZ(100000), location.clone().setZ(-100000))//确保长度范围覆盖所有测量面 
@@ -319,10 +319,13 @@ export class ctrlPolygon extends THREE.Object3D {
                 points[i].copy(location)//再copy确认一次
                 
                 
-                if(len == 3 && this.faceDirection == 'horizontal'){ //normal方向还不确定 会影响label在里侧还是外侧
-                    let facePlane = new THREE.Plane().setFromCoplanarPoints(...points)
-                    this.facePlane = facePlane
-                    //console.log(this.facePlane.normal, this.facePlane.constant)
+                if(len == 3 && this.faceDirection == 'horizontal' && this.closed){ //normal方向还不确定 会影响label在里侧还是外侧
+                    let facePlane = new THREE.Plane().setFromCoplanarPoints(...points)  
+                    if(facePlane.normal.z && facePlane.normal.z * this.facePlane.normal.z < 0){ 
+                        this.facePlane.normal.z *= -1,  this.facePlane.constant *= -1 
+                        //console.log(this.facePlane.normal, this.facePlane.constant)
+                    }
+                      
                 }
                 
                 

+ 2 - 1
src/custom/objects/tool/mapClipBox.js

@@ -304,7 +304,7 @@ export class mapClipBox extends ctrlPolygon {
         {//update rotateBar
             let center = new THREE.Vector3().addVectors(this.points[0], this.points[1]).multiplyScalar(0.5); 
             this.rotateBar.position.copy(center) 
-            this.rotateBar.bar.update()//更新sprite matrix
+            this.rotateBar.bar.waitUpdate()//更新sprite matrix
         }
         {
             for(let i=0;i<4;i++){
@@ -324,6 +324,7 @@ export class mapClipBox extends ctrlPolygon {
     dispose(){
         super.dispose()
         this.dispatchEvent('dispose')
+        this.rotateBar.bar.dispose()
         
     }
      

+ 7 - 3
src/custom/settings.js

@@ -185,9 +185,9 @@ const config = {//配置参数   不可修改
          
         lineWidth: 3,
        
-        textColor: "#000000" //"#FFFFFF"
-        
+        textColor: "#000000", //"#FFFFFF"
         
+        mulLabelHideFaraway : false // 多折线根据远近显示label
     },
     material:{//初始化
         pointSize: 0.1,  
@@ -450,7 +450,11 @@ let settings = {//设置   可修改
     // testCube : true,
     // moveToCenter:true, //针对数据集间隔很远的场景  dis>5000 容易抖动
     tiles3DMaxMemory: config.tiles3DMaxMemory,
+    
+   
 }
+
+
   
  
 settings.isLocalhost = settings.prefix.includes('localhost')
@@ -461,6 +465,6 @@ if(settings.isFormal){
     settings.webSite = 'datav1'
 }
 
-console.log('2023-1')
+console.log('2023-11')
  
 export {config, settings}

+ 4 - 2
src/custom/start.js

@@ -138,7 +138,9 @@ export function start(dom, mapDom, number ){ //t-Zvd3w0m
                                 viewer.mainViewport.camera.far = Potree.settings.cameraFar; 
                                 viewer.mainViewport.camera.updateProjectionMatrix() 
                                 viewer.removeEventListener('pageVisible', focusPoint )
+                                clearTimeout(timer)
                             }
+                            let timer 
                             let focusPoint = (e)=>{//拉近到某个点
                                 if(e && e.v === false)return
                                 viewer.removeEventListener('pageVisible', focusPoint )
@@ -154,7 +156,7 @@ export function start(dom, mapDom, number ){ //t-Zvd3w0m
                                             return viewer.addEventListener('pageVisible', focusPoint )
                                         }
                                         count_ ++ //如果在别的
-                                        setTimeout(focusPoint, 200) 
+                                        timer = setTimeout(focusPoint, 200) 
                                     }else{ //放弃
                                         console.log('初始加载focus点云 放弃')
                                         done()
@@ -167,7 +169,7 @@ export function start(dom, mapDom, number ){ //t-Zvd3w0m
                                 done()
                             } 
                             let focus = ()=>{ 
-                                setTimeout(focusPoint, 300) 
+                                timer = setTimeout(focusPoint, 300) 
                             }
                             viewer.addEventListener('setPose',()=>{//设置了初始画面
                                 viewer.removeEventListener('pointcloud_changed',focus)

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

@@ -4141,7 +4141,7 @@ export class Viewer extends ViewerBase{
                     dir,  
                     point : position,
                     bestDistance : 0 , 
-                    checkIntersect: o.checkIntersect                    
+                    checkIntersect: o.checkIntersect,  gotoBestView: o.gotoBestView                    
                 })
                 
                 

+ 22 - 12
src/viewer/ExtendView.js

@@ -231,7 +231,24 @@ class ExtendView extends View {
         
         this.restrictPos(endPosition)
          
-         
+        if(info.endYaw == void 0){
+            if(info.target ){
+                endTarget = new THREE.Vector3().copy(info.target)  
+                endQuaternion = math.getQuaFromPosAim(endPosition,endTarget) //若为垂直,会自动偏向x负的方向
+           
+            }else if(info.quaternion){
+                endQuaternion = info.quaternion.clone()
+            }   
+            
+            if(endQuaternion && math.closeTo(Math.abs(this.direction.z), 1, 1e-4)){ //在垂直的视角下的quaternion刚开始突变的厉害,这时候可能渐变yaw比较好(如俯视时点击测量线)
+                let a = this.clone();
+                a.quaternion = endQuaternion;
+                info.endYaw = a.yaw; info.endPitch = a.pitch;
+                console.log('turn to yaw')
+            }
+        }
+        
+ 
         if(info.endYaw != void 0) { 
             startPitch = this.pitch
             endPitch = info.endPitch;
@@ -240,15 +257,8 @@ class ExtendView extends View {
             if(Math.abs(startYaw - endYaw)>Math.PI){//如果差距大于半个圆,就要反个方向转(把大的那个数字减去360度)
                 startYaw > endYaw ? (startYaw -= Math.PI*2) : (endYaw -= Math.PI*2) 
             }
-            
-		}else if(info.target ){
-			endTarget = new THREE.Vector3().copy(info.target)  
-            endQuaternion = math.getQuaFromPosAim(endPosition,endTarget) //若为垂直,会自动偏向x负的方向
-            dir = new THREE.Vector3().subVectors(endTarget, endPosition).normalize()
-            //console.log(dir, this.direction)   
-		}else if(info.quaternion){
-            endQuaternion = info.quaternion.clone()
-        }
+            console.log('startYaw', startYaw, 'endYaw', endYaw)
+		}  
          
         if(endQuaternion){ 
             startQuaternion = this.quaternion 
@@ -295,9 +305,9 @@ class ExtendView extends View {
                     }else{ 
                         let quaternion = (new THREE.Quaternion()).copy(startQuaternion) 
                         lerp.quaternion(quaternion, endQuaternion)(progress)  //在垂直的视角下的角度突变的厉害,这时候可能渐变yaw比较好
-                        //console.log(quaternion)
-                        //this.rotation = new THREE.Euler().setFromQuaternion(quaternion)
+                         
                         this.quaternion = quaternion
+                        //console.log(quaternion,this.yaw)
                     }
                     posChange || info.onUpdate && info.onUpdate(progress, delta)