Procházet zdrojové kódy

根据当前位置更新显示一定范围内的箭头

xzw před 3 roky
rodič
revize
6baa948a29
2 změnil soubory, kde provedl 107 přidání a 18 odebrání
  1. 30 1
      src/navigation/RouteGuider.js
  2. 77 17
      src/viewer/viewer.js

+ 30 - 1
src/navigation/RouteGuider.js

@@ -13,7 +13,7 @@ const planeGeo = new THREE.PlaneBufferGeometry(1,1);
 const sphereSizeInfo = {
       nearBound : 2, scale:arrowSize, restricMeshScale : true,
 }
-
+const arrowsShowingCount = 25; //场景里最多展示多少个箭头
 
 export class RouteGuider extends EventDispatcher{
     constructor () {
@@ -21,6 +21,7 @@ export class RouteGuider extends EventDispatcher{
         
         this.route = [];
         this.curve = []
+        this.scenePoints = []
         this.sceneMeshGroup = new THREE.Object3D;
         this.mapMeshGroup = new THREE.Object3D;
         this.generateDeferred;
@@ -40,6 +41,11 @@ export class RouteGuider extends EventDispatcher{
             } 
         })
         
+        viewer.addEventListener('camera_changed', e => {
+            this.updateArrowDisplay()
+        })
+        
+        
         
         var polesMats = {
             shadowMat: new THREE.MeshBasicMaterial({ 
@@ -452,7 +458,29 @@ export class RouteGuider extends EventDispatcher{
     }
     
     
+    updateArrowDisplay(){//根据当前位置更新显示一定范围内的箭头 
     
+        if(this.scenePoints.length == 0)return
+        
+        var a = Common.sortByScore(this.scenePoints , null, [(point)=>{   //是否还要再requires里限制最远距离?
+            var playerPos = viewer.scene.getActiveCamera().position.clone().setZ(0)
+            
+            var pos = point.clone().setZ(0) 
+            
+            return -pos.distanceTo(playerPos);
+            
+        }]);
+        //获得展示的起始点 
+        let start = a[0].item
+        let startIndex = this.scenePoints.indexOf(start)
+        this.arrows.children.forEach((e,i)=>{
+            if(i<startIndex || i>startIndex+arrowsShowingCount)e.visible = false
+            else e.visible = true
+        })
+        
+        
+        
+    }
     
     
     displayRoute(o={}){
@@ -470,6 +498,7 @@ export class RouteGuider extends EventDispatcher{
         this.mapPoints.forEach(e=>this.addMapArrow(e))
         this.mapArrows.children.forEach((e,i)=>this.setArrowDir(this.mapArrows.children,i));
         viewer.mapViewer.dispatchEvent({'type':'content_changed'})
+        this.updateArrowDisplay()
     }
     
     clearRoute(o={}){

+ 77 - 17
src/viewer/viewer.js

@@ -82,6 +82,8 @@ export class Viewer extends ViewerBase{
         mapArea = mapArea_
 		//-------------
         
+        this.supportExtFragDepth = !!this.renderer.getContext().getExtension('EXT_frag_depth') ;//iphoneX居然不支持
+        console.log('this.supportExtFragDepth ',this.supportExtFragDepth)
         
         
 		this.guiLoaded = false;
@@ -420,7 +422,23 @@ export class Viewer extends ViewerBase{
 			this.onCrash(e);
 		}
         
-        {//add
+        //-----------------------add----------------------------------------------------
+        
+        
+        {
+            let ratio
+            this.addEventListener('resize',(e)=>{
+                if(ratio != e.deviceRatio){ //因为devicePixelRatio会影响到点云大小,所以改变时计算下点云大小
+                    viewer.scene.pointclouds.forEach(p => {
+                        p.changePointSize()
+                    })
+                }
+                ratio = e.deviceRatio
+                
+            }) 
+        }
+        
+        { 
             let pointDensity = ''
             Object.defineProperty(Potree.settings , "pointDensity",{ 
                 get: function() {
@@ -508,7 +526,7 @@ export class Viewer extends ViewerBase{
             
         }
         
-        
+         
 	}
 
     
@@ -523,7 +541,7 @@ export class Viewer extends ViewerBase{
                 e.maxLevel = 12;//先加载到最大的直到测试完毕。由于5个level为一组来加载,所以如果写4最高能加载到5,如果写5最高能加载到下一个级别的最高也就是10
                 //console.log('maxLevel: '+e.maxLevel +  ' testingMaxLevel中 '  )                                
             }else{
-                let percent = Potree.settings.displayMode == 'showPanos' ? config.maxLevelPercent :  (Potree.settings.UserDensityPercent || config.maxLevelPercent)
+                let percent = (Potree.settings.displayMode == 'showPanos') ? config.maxLevelPercent :  (Potree.settings.UserDensityPercent == void 0 ? config.maxLevelPercent : Potree.settings.UserDensityPercent)
                 e.maxLevel = Math.round( percent * e.nodeMaxLevel); 
                 console.log('maxLevel: '+e.maxLevel +  ',   density : '+Potree.settings.pointDensity,  ",  percent :"+percent);
                 
@@ -867,10 +885,11 @@ export class Viewer extends ViewerBase{
 
 	setFOV (value) {
 		if (this.fov !== value) {
+            let oldFov = this.fov
 			this.fov = value;
             this.scene.cameraP.fov = this.fov;
             this.scene.cameraP.updateProjectionMatrix()
-			this.dispatchEvent({'type': 'fov_changed', 'viewer': this});
+			this.dispatchEvent({'type': 'fov_changed', 'viewer': this,  oldFov, fov:this.fov});
 		}
 	};
 
@@ -2378,7 +2397,7 @@ export class Viewer extends ViewerBase{
 		 
 	}
 
-
+    
 
 	renderDefault(params_={}){
 		let pRenderer = this.getPRenderer();
@@ -2840,11 +2859,42 @@ export class Viewer extends ViewerBase{
             })
             return deferred.promise();//不能打扰 从点云转向全景图时 的飞行
         }
-        if (type == 'measure') {  
+        if (type == 'measure') { 
+
+        
+            
+                
             target.copy(object.getCenter()) 
        
             
             var cameraTemp = camera.clone()
+            
+             //试试改变位置,直视测量线。能避免倾斜角度造成的非常不居中、以及看不到面的情况,但镜头旋转幅度太大了
+            if(object.facePlane/*  && window.focusMeasureFaceToIt */){
+                let normal
+                if(object.facePlane){
+                    normal = object.facePlane.normal.clone()
+                }/* else{ 
+                    if(object.points.length>2){
+                        console.error('怎么有多个点却没有facePlane?')
+                    }else{
+                        normal = //以后再写
+                    }
+                }  */                 
+                let angle = this.scene.view.direction.angleTo(normal)
+                if(angle<Math.PI*0.7){//当几乎正对时就不执行
+                    if(angle<Math.PI/2){
+                        normal.negate()
+                    }
+                    let dir = new THREE.Vector3().subVectors(camera.position, target).normalize() 
+                    let newDir = new THREE.Vector3().addVectors(dir,normal)//两个角度的中间
+                    cameraTemp.position.copy(target.clone().add(newDir))
+                }
+                
+                
+            } 
+            
+            
             cameraTemp.lookAt(target);
             cameraTemp.updateMatrix();
             cameraTemp.updateMatrixWorld();
@@ -2875,21 +2925,31 @@ export class Viewer extends ViewerBase{
                 this.scene.scene.add(this.boundBox); 
             }
              
-            
+           
             this.boundBox.position.copy(target)
             this.boundBox.scale.copy(boundSize)
-            this.boundBox.lookAt(camera.position)
+            this.boundBox.lookAt(cameraTemp.position)
+            
+            
+            {
+                let scale = 1.1; //稍微放大一些,不然会靠到屏幕边缘
+                boundSize.x *= scale 
+                boundSize.y *= scale 
+                
+            }
+            
             
-             
             
             let aspect = boundSize.x / boundSize.y
             if(camera.aspect > aspect){//视野更宽则用bound的纵向来决定
-                dis = boundSize.y/2/ THREE.Math.degToRad(camera.fov / 2) + boundSize.z/2 
+                dis = boundSize.y/2/ Math.tan(THREE.Math.degToRad(camera.fov / 2)) + boundSize.z/2 
             }else{
-                let hfov = cameraLight.getHFOVForCamera(camera, camera.aspect, 1 );
-                dis = boundSize.x/2 / THREE.Math.degToRad(hfov / 2) + boundSize.z/2
-            }//为何在只有两点的情况下,依然不能使box的边界刚好对着屏幕边界? 会缩小一些。  而三点以上的中心在这个视角上也不准确,所以点会超出box范围。
-             
+                let hfov = cameraLight.getHFOVForCamera(camera, true);
+                dis = boundSize.x/2 / Math.tan(hfov / 2) + boundSize.z/2
+            }
+            
+            //三个顶点以上的由于measure的中心不等于bound的中心,所以点会超出bound外。 且由于视椎近大远小,即使是两个点的,bound居中后线看上去仍旧不居中.
+            
             
             if(this.mapViewer.attachedToViewer){ 
                 //console.log('mapFocusOn: '+target.toArray())
@@ -2901,8 +2961,8 @@ export class Viewer extends ViewerBase{
             }
             
             
-            if(Potree.settings.displayMode == 'showPointCloud'){  //点云
-                let dir = new THREE.Vector3().subVectors(camera.position, target).normalize() 
+            if(Potree.settings.displayMode == 'showPointCloud'){  //点云 
+                let dir = new THREE.Vector3().subVectors(cameraTemp.position, target).normalize()
                 position.copy(target).add(dir.multiplyScalar(dis))
                  
             }else if(Potree.settings.displayMode == 'showPanos'){//全景 (比较难校准)
@@ -3207,7 +3267,7 @@ export class Viewer extends ViewerBase{
         }
        
         0 === this.waitQueue.length && this.emit("loading", false) 
-    }
+    } 
     
     
     setView(o={}){