xzw 3 tahun lalu
induk
melakukan
d7436d69dd

+ 8 - 6
libs/three.js/lines/LineMaterial.js

@@ -353,21 +353,23 @@ var LineMaterial = function ( parameters ) {
     })   
 
     let setSize = (e)=>{ 
-        let viewportOffset = new Vector2(e.left||0, e.bottom||0) 
-        this.uniforms.resolution.value.copy(e.resolution)
-        this.uniforms.viewportOffset.value.copy(viewportOffset)
+        let viewport = e.viewport
+        let viewportOffset = viewport.offset || new Vector2() 
+        this.uniforms.resolution.value.copy(viewport.resolution2) 
+        this.uniforms.viewportOffset.value.copy(viewportOffset) 
+         
     }
     
     let viewport = viewer.mainViewport;
      
-    setSize(viewport)
+    setSize({viewport})
 
 
     viewer.addEventListener('resize',(e)=>{
-        //if(!e.viewport || e.viewport.name != 'mapViewport'){
+        if(!e.viewport || e.viewport.name != 'mapViewport'){
             setSize(e)
             //console.log(this.name +  viewportOffset.toArray())     
-        //} 
+        } 
     })  
     
     

+ 6 - 2
note.txt

@@ -24,10 +24,14 @@ https://hq.iv.navvis.com/?fov=100.0&site=1493761991057195&hsCtaTracking=8ca25304
 
 t-ia44BhY 机场(两个数据集。点量大 )
 t-iksBApb 一楼 一个数据集 十个点左右
-t-Zvd3w0m 室内 4dkk的场景 三个点
-t-CwfhfqJ 大佛 有平面图
+t-Zvd3w0m 室内 4dkk的场景 三个点 
 t-OW5ShsQ 一楼 有平面图 点五个
 
+
+
+测试服务器可以:
+t-CwfhfqJ 大佛 有平面图  
+t-e2Kb2iU 隧道
 ------------
 本地测试
 t-bnC8jkv

+ 20 - 6
src/PointCloudOctree.js

@@ -120,7 +120,7 @@ export class PointCloudOctree extends PointCloudTree {
 		this.level = 0;
 		this.position.copy(geometry.offset);
 		this.updateMatrix();
-        
+        this.transformMatrix = new THREE.Matrix4;//add 数据集的变化矩阵
         
 		{
 
@@ -163,7 +163,7 @@ export class PointCloudOctree extends PointCloudTree {
 		this.name = '';
 		this._visible = true;
         //this._isVisible = true//add
-        this.unvisibleReasons = []
+        //this.unvisibleReasons = []
         
 		{
 			let box = [this.pcoGeometry.tightBoundingBox, this.getBoundingBoxWorld()]
@@ -1151,24 +1151,38 @@ export class PointCloudOctree extends PointCloudTree {
 
 	}
     
+    
+    //数据集的显示影响到其下的:点云、marker  .不会影响地图上的显示
+    
+    /*
     updateVisible(reason, ifShow){//当所有加入的条件都不为false时才显示
         if(ifShow){
             var index = this.unvisibleReasons.indexOf(reason);
             index > -1 && this.unvisibleReasons.splice(index, 1);
-            if(this.unvisibleReasons.length == 0)this.visible = true;
+            if(this.unvisibleReasons.length == 0){
+                this.visible = true;
+                this.dispatchEvent({
+                    type: 'isVisible'
+                    visible:true
+                })
+            }
         }else {
             if(!this.unvisibleReasons.includes(reason)) this.unvisibleReasons.push(reason);
-            this.visible = false;    
+            this.visible = false;  
+            this.dispatchEvent({
+                type: 'isVisible'
+                visible:false
+            })            
         }
         
     }
     
-    getVisible(reason){//获取在某条件下是否可见.  注: 用户在数据集选择可不可见为"datasetSelection"
+     getVisible(reason){//获取在某条件下是否可见.  注: 用户在数据集选择可不可见为"datasetSelection"
         if(this.visible)return true
         else{
             return !this.unvisibleReasons.includes(reason)  
         }
-    }
+    } */
     
     
     /* get isVisible(){//add 手动在数据集选择是否显示(和是否全景图、隐藏点云无关)

+ 56 - 3
src/Potree.js

@@ -171,10 +171,20 @@ export async function loadDatasets(callback){//之后直接把path写进来
     return loadFile(path, callback)
     
 }
-export async function loadMapEntity(callback){
+export async function loadMapEntity(){
     var path 
+    let callback = (data)=>{
+        var map = viewer.mapViewer.mapLayer.maps.find(e => e.name == 'floorplan')
+        if(map){
+            viewer.mapViewer.mapLayer.removeMap(map)
+        }else{
+            
+        }
+        
+        viewer.mapViewer.mapLayer.addMapEntity(data)
+    }
     if(Potree.fileServer){
-        if(!Potree.settings.floorplanType)return /* 等待平面图类型定义好会加载 */
+        if(!Potree.settings.floorplanType || !Potree.settings.floorplanEnable)return /* 等待平面图类型定义好会加载 */
         path = `/laser/tiledMap/${Potree.settings.number}/tiledMap/${Potree.settings.floorplanType}` 
     }else{
         path = `https://${Potree.config.urls.prefix2}/indoor/${Potree.settings.number}/api/tiled_maps`
@@ -187,7 +197,7 @@ export async function loadMapEntity(callback){
  
 export async function loadPanos(center, callback){
     var path 
-    let query = `?lat=${center.lat}&lon=${center.lon}&radius=200000`
+    let query = ''//`?lat=${center.lat}&lon=${center.lon}&radius=200000`
     if(Potree.fileServer){
         path = `/laser/filter/${Potree.settings.number}/query` + query
     }else{ 
@@ -201,6 +211,49 @@ export async function loadPanos(center, callback){
 
 
 
+//site_model
+/* {
+    "area": 2503.30551910935,
+    "attributes": {},
+    "center": [
+        113.59568277455075,
+        22.366566635195288,
+        12.78751625
+    ],
+    "children": [],
+    "geometry_hash": 1891071345,
+    "id": 10,
+    "name": "港湾一号",
+    "parentId": null,
+    "polygon": {
+        "coordinates": [
+            [
+                [
+                    113.59590810534583,
+                    22.36679132753878
+                ],
+                [
+                    113.59590810534583,
+                    22.366807172528629
+                ],
+                [
+                    113.59545610274934,
+                    22.366807172528629
+                ],
+                [
+                    113.59545610274934,
+                    22.36679132753878
+                ]
+            ]
+        ],
+        "type": "Polygon"
+    },
+    "type": "BUILDING",
+    "volume": null,
+    "z_max": null,
+    "z_min": null
+}
+ */
 
 
 

+ 2 - 2
src/Potree_update_visibility.js

@@ -76,7 +76,7 @@ export function updateVisibilityStructures(pointclouds, camera, areaSize) {
 		let camObjPos = new THREE.Vector3().setFromMatrixPosition(camMatrixObject);
 		camObjPositions.push(camObjPos);
 
-		if ( pointcloud.getVisible('datasetSelection') &&  pointcloud.root !== null) {//改 visible -> 
+		if ( viewer.getObjVisiByReason(pointcloud, 'datasetSelection') &&  pointcloud.root !== null) {//改 visible -> 
 			priorityQueue.push({pointcloud: i, node: pointcloud.root, weight: Number.MAX_VALUE});
 		}
 
@@ -133,7 +133,7 @@ export function updateVisibility(pointclouds, camera, areaSize){
 	let pointcloudTransformVersion = Potree._pointcloudTransformVersion;
 	for(let pointcloud of pointclouds){
 
-		if(!pointcloud.getVisible('datasetSelection')){//改 visible ->  
+		if(!viewer.getObjVisiByReason(pointcloud, 'datasetSelection')){//改 visible ->  
 			continue;
 		}
 

+ 1 - 1
src/materials/PointCloudMaterial.js

@@ -1145,7 +1145,7 @@ export class PointCloudMaterial extends THREE.RawShaderMaterial {
 		this.uniforms.pano0Matrix.value.copy(pano0.panoMatrix/* pano0.mesh.matrixWorld */ );
 		//pano1.ensureSkyboxReadyForRender();
  
-        this.uniforms.easeInOutRatio.value =  easeInOutRatio || 0;
+        this.uniforms.easeInOutRatio.value =  easeInOutRatio || 0; //之前做点云和全景混合时加的,为了让点云颜色柔和切换到全景颜色。如不混合就0
 		
 		this.uniforms.pano1Map.value = pano1.getSkyboxTexture()
 		this.uniforms.pano1Position.value.copy(pano1.position)

+ 17 - 36
src/modules/Images360/Images360.js

@@ -83,7 +83,7 @@ export class Images360 extends EventDispatcher{
         
         
         viewer.addEventListener('global_click'/* "global_drop" */, (e) => {//不用"mouseup" 是因为 mouseup有drag object时也会触发
-            if(this.flying  || e.button != THREE.MOUSE.LEFT  )return //
+            if(Potree.settings.unableNavigate || this.flying  || e.button != THREE.MOUSE.LEFT  )return //
             
             /* if(currentlyHovered && currentlyHovered.pano){
 				this.focusPano(currentlyHovered.pano);
@@ -97,7 +97,7 @@ export class Images360 extends EventDispatcher{
         })
         
         viewer.addEventListener("global_mousemove", (e) => { 
-            if(Potree.settings.ifShowMarker && e.hoverViewport == viewer.mainViewport){//如果不显示marker,就在点击时再更新
+            if(!Potree.settings.unableNavigate && Potree.settings.ifShowMarker && e.hoverViewport == viewer.mainViewport){//如果不显示marker,就在点击时再更新
                 this.updateClosestPano(e.intersectPoint)
             }
 		});
@@ -132,10 +132,11 @@ export class Images360 extends EventDispatcher{
             }) 
             this.domRoot.appendChild(elHide[0]);
             elHide.on("click", (e) => { 
-                viewer.scene.pointclouds.forEach(e=>{
-                    e.visible = !e.visible 
+                let visi = viewer.getObjVisiByReason(viewer.scene.pointclouds[0], 'force')
+                viewer.scene.pointclouds.forEach(e=>{ 
+                    viewer.updateVisible(e, 'force', !visi) 
                 })
-                elHide.val(viewer.scene.pointclouds[0].visible ? "隐藏点云" : "显示点云")  
+                elHide.val(!visi ? "隐藏点云" : "显示点云")  
             });
             
             
@@ -213,14 +214,10 @@ export class Images360 extends EventDispatcher{
                             }
                         } 
 
-                        
-                        
-                        
-                        
-                        
+                         
                         
                         viewer.scene.pointclouds.forEach(e=>{
-                            e.visible = config2.showPoint 
+                            viewer.updateVisible(e, 'displayMode', config2.showPoint) 
                         })
                         this.cube.visible = config2.showSkybox
                         if(config2.pointUsePanoTex){  
@@ -283,11 +280,9 @@ export class Images360 extends EventDispatcher{
                     show = !!show
                     if(show != ifShowMarker){
                         this.panos.forEach(pano=>{
-                            pano.marker.visible = show
-                            Potree.settings.showPanoMesh && (pano.mesh.visible = show)
-                            //pano.mesh.label && (pano.mesh.label
+                            viewer.updateVisible(pano, 'ifShowMarker', show) 
                         })
-                        this.emit('markersDisplayChange', show) 
+                        //this.emit('markersDisplayChange', show) 
                         ifShowMarker = show
                     }
                      
@@ -400,22 +395,7 @@ export class Images360 extends EventDispatcher{
  
 
 
-    setView(o={}){
-        let callback = ()=>{
-            if(o.displayMode){
-                Potree.settings.displayMode = o.displayMode
-            }
-            o.callback && o.callback()
-        } 
-        
-        if(o.pano != void 0){//pano 权重高于 position
-            flyToPano(o)
-        }else{
-            viewer.scene.view.setView(o.position, o.target, o.duration, callback)
-        }
-        
-        
-    }
+    
 
 
 
@@ -475,13 +455,14 @@ export class Images360 extends EventDispatcher{
             
             
             
-            var easeInOutRatio = pointcloudVisi ? 0.3 : 0
+            
             viewer.scene.pointclouds.forEach(e=>{
-                e.visible = config.transition.showPoint
+                viewer.updateVisible(e, 'displayMode',config.transition.showPoint) 
             }) 
              
             
             if(config.transition.pointUsePanoTex){
+                let easeInOutRatio = pointcloudVisi ? 0.3 : 0
                 viewer.scene.pointclouds.forEach(e=>{
                     e.material.setProjectedPanos(this.currentPano, pano, 0, easeInOutRatio)
                 }) 
@@ -503,7 +484,7 @@ export class Images360 extends EventDispatcher{
                 this.flying = false 
                 this.nextPano = null;
                 viewer.scene.pointclouds.forEach(e=>{
-                    e.visible = pointcloudVisi
+                    viewer.updateVisible(e, 'displayMode',pointcloudVisi) 
                 })
                 done(true);
             },(progress)=>{//onUpdate
@@ -943,9 +924,9 @@ export class Images360 extends EventDispatcher{
         vectorForward = math.convertVector.ZupToYup(vectorForward)  
         
         if (!pano.isLoaded(basePanoSize)) {
-            /* iswait && this.model.waitForLoad(pano, function() {
+            iswait && viewer.waitForLoad(pano, function() {//发送loading
                 return pano.isLoaded(basePanoSize)
-            }); */
+            }); 
             
         
             

+ 17 - 5
src/modules/Images360/Panorama.js

@@ -19,12 +19,12 @@ let getMarerMat = function(){
     if(!standardMarkerMat) {
         let map = texLoader.load( Potree.resourcePath+'/textures/marker.png' )
         map.anisotropy = 4 // 各向异性过滤 .防止倾斜模糊
-        standardMarkerMat = new THREE.MeshBasicMaterial({opacity:0.5, side: THREE.DoubleSide , map ,transparent:true})
+        standardMarkerMat = new THREE.MeshBasicMaterial({opacity:0.7, side: THREE.DoubleSide , map ,transparent:true, depthTest:false})//总是被点云遮住,所以depthTest:false
     }
     return standardMarkerMat.clone()
 }
 //显示全景图时marker没有被遮挡,如果需要,要换成depthBasicMaterial  或者直接把skybox的深度修改(拿到深度贴图后更如此)
-let planeGeo = new THREE.PlaneBufferGeometry(0.1,0.1);
+let planeGeo = new THREE.PlaneBufferGeometry(0.2,0.2);
 
 
 
@@ -57,6 +57,7 @@ class Panorama extends EventDispatcher{
         this.id = o.id;
         this.images360 = images360
         this.transform =  transform
+        this.visible = true  //for viewer updateVisible
         //this.position.set(this.position.x, -this.position.z, this.position.y) //4dkk的坐标绕x旋转90°
 
         /* this.longitude = o.location[0]
@@ -71,6 +72,17 @@ class Panorama extends EventDispatcher{
         
         this.pointcloud = viewer.scene.pointclouds.find(e=>e.dataset_id == o.dataset_id) || viewer.scene.pointclouds[0]
         this.pointcloud.panos.push(this)
+        this.pointcloud.addEventListener('isVisible',(e)=>{ 
+            viewer.updateVisible(this, 'pointcloudVisi', e.visible) 
+        })
+        this.addEventListener('isVisible',(e)=>{//是否显示该点的mesh(不显示也能走)
+            this.marker.visible = e.visible
+            Potree.settings.showPanoMesh && (this.mesh.visible = e.visible)
+            if(e.reason == 'screenshot' || e.visible){
+                this.label && (this.label.visible = e.visible)//截图时隐藏下
+            }
+        })
+        
         
         //全景图和Cube的水平采样起始坐标相差90度 
         
@@ -201,8 +213,8 @@ class Panorama extends EventDispatcher{
                     
         /* this.position.        
         this.position.addVectors(this.originPosition,  pointcloud.translateUser)  */
-        let position = this.originPosition.clone().applyMatrix4(this.pointcloud.matrixForPano);
-        let floorPosition = this.originFloorPosition.clone().applyMatrix4(this.pointcloud.matrixForPano);
+        let position = this.originPosition.clone().applyMatrix4(this.pointcloud.transformMatrix);
+        let floorPosition = this.originFloorPosition.clone().applyMatrix4(this.pointcloud.transformMatrix);
         this.setPosition(position, floorPosition) 
         this.panoMatrix = new THREE.Matrix4().multiplyMatrices(this.oriPanoMatrix, this.pointcloud.rotateMatrix) 
     }
@@ -355,7 +367,7 @@ class Panorama extends EventDispatcher{
             t > this.highestPartialTileRenderOpCompleted && (this.highestPartialTileRenderOpCompleted = t);//应该是更新最高获取到的Partial size
             !n && t > this.highestFullTileRenderOpCompleted && (this.highestFullTileRenderOpCompleted = t); //应该是更新最高获取到的Full size
             //this.emit("load", t);
-            //this.model.emit("load", this);
+            viewer.ifAllLoaded( this);
             this.dispatchEvent({type:PanoramaEvents.LoadComplete, size:t, count:i});
         }
     }

+ 3 - 6
src/modules/datasetAlignment/Alignment.js

@@ -8,18 +8,15 @@ import SplitScreen from "../../utils/SplitScreen"
 var Alignment = {
      
     setMatrix :  function(pointcloud){
-        var vec1 = pointcloud.position
+        var vec1 = pointcloud.position     //position为数据集内部的偏移,在navvis中对应的是dataset.pointCloudSceneNode的children[0].position
         var vec2 = pointcloud.translateUser
         var angle = pointcloud.orientationUser
         var pos1Matrix = new THREE.Matrix4().setPosition(vec1);//移动到中心
         var rotMatrix = new THREE.Matrix4().makeRotationAxis(new THREE.Vector3(0,0,1), angle)//再旋转 
         var pos2Matrix = new THREE.Matrix4().setPosition(vec2);//最后是平移
-        
-        /* var matrix = new THREE.Matrix4().multiplyMatrices(rotMatrix,pos1Matrix)
-        matrix = matrix.multiplyMatrices(pos2Matrix, matrix) */
-        
+         
         var matrix = new THREE.Matrix4().multiplyMatrices(pos2Matrix, rotMatrix);
-        pointcloud.matrixForPano = matrix.clone();//漫游点用的
+        pointcloud.transformMatrix = matrix.clone();//为该数据集的变化矩阵。 对应navvis的m2w_
         pointcloud.rotateMatrix = rotMatrix
         pointcloud.panos.forEach(e=>e.transformByPointcloud())
         

+ 7 - 14
src/navigation/FirstPersonControls.js

@@ -75,24 +75,17 @@ export class FirstPersonControls extends EventDispatcher {
         
 
 		let drag = (e) => {
-            if(!this.enabled)return
-			/* if (e.drag.object !== null) {
-				return;
-			} */
-
-			if (e.drag.startHandled === undefined) {
+            if(!this.enabled)return 
+            let viewport = e.drag.dragViewport;
+            if(!viewport)return
+            let camera = viewport.camera 
+            let mode = e.drag.mouse === MOUSE.LEFT && (!e.drag.dragViewport || e.drag.dragViewport.name == 'MainView') ? 'rotate' : 'pan'
+            let moveSpeed = this.currentViewport.getMoveSpeed();
+            if (e.drag.startHandled === undefined) {///???????
 				e.drag.startHandled = true;
 
 				this.dispatchEvent({type: 'start'});
 			}
-
-			let moveSpeed = this.currentViewport.getMoveSpeed();
- 
-            
-            let camera = e.drag.dragViewport.camera 
-            let mode = e.drag.mouse === MOUSE.LEFT && (!e.drag.dragViewport || e.drag.dragViewport.name == 'MainView') ? 'rotate' : 'pan'
-            let viewport = e.drag.dragViewport;
-            
             
 			if (mode == 'rotate') {//旋转   (为什么开启调试时旋转很慢?)
 				

+ 2 - 1
src/navigation/Reticule.js

@@ -63,6 +63,7 @@ export default class Reticule extends THREE.Mesh{
     }
 
     show(){
+        if(!this.visible)return
         //console.log("show Reticule")
         this.hidden = !1,
         this.material.opacity <= 0 && transitions.start(lerp.property(this.material, "opacity", defaultOpacity), 300)
@@ -74,7 +75,7 @@ export default class Reticule extends THREE.Mesh{
     }
 
     updatePosition(intersectPoint, cameraPos ){ //在地图(当地图融合到viewer时)和场景里都显示且完全相同(大小可能不同)
-        if (!this.hidden) {
+        if (!this.hidden && this.visible) {
             if (!intersectPoint /* || !intersectPoint.point.normal */)
                 return //this.hide();
              

+ 87 - 49
src/navigation/RouteGuider.js

@@ -24,13 +24,23 @@ export class RouteGuider extends EventDispatcher{
         this.curve = []
         this.sceneMeshGroup = new THREE.Object3D;
         this.mapMeshGroup = new THREE.Object3D;
-        
+        this.generateDeferred;
         viewer.addEventListener('loadPointCloudDone',this.init.bind(this))
         
+        
     
     }
     init(){
         if(this.inited) return;
+        let zoom;
+        viewer.mapViewer.addEventListener('camera_changed', e => {
+            var camera = e.viewport.camera
+            if(camera.zoom != zoom){ 
+                this.updateMapArrows(true)
+                zoom = camera.zoom
+            } 
+        })
+        
         
         var polesMats = {
             shadowMat: new THREE.MeshBasicMaterial({ 
@@ -95,7 +105,7 @@ export class RouteGuider extends EventDispatcher{
             transparent:true, depthTest:false,
             map: texLoader.load(Potree.resourcePath+'/textures/map_instruction_target_reached.png' )  
         }))
-        
+        this.mapMarkStart.renderOrder = this.mapMarkEnd.renderOrder = 2//在箭头之上
         
         this.mapArrow = new THREE.Mesh( planeGeo, new THREE.MeshBasicMaterial({
             transparent:true, depthTest:false,
@@ -181,7 +191,11 @@ export class RouteGuider extends EventDispatcher{
     }
     
     set routeStart(pos){
-        this._routeStart = pos && pos.clone()
+        console.log('routeStart' )
+        console.log(pos)
+        if(this._routeStart && pos && this._routeStart.equals(pos)) return //可能重复设置
+        this._routeStart = pos && new THREE.Vector3().copy(pos) 
+         
         this.generateRoute()
     }
     
@@ -190,7 +204,10 @@ export class RouteGuider extends EventDispatcher{
     }
     
     set routeEnd(pos){
-        this._routeEnd = pos && pos.clone()
+        console.log('routeEnd' )
+        console.log(pos)
+        if(this._routeEnd && pos && this._routeEnd.equals(pos)) return 
+        this._routeEnd = pos && new THREE.Vector3().copy(pos)  
         this.generateRoute()
     }
     
@@ -198,21 +215,24 @@ export class RouteGuider extends EventDispatcher{
     
     
     generateRoute(){
-        if(!this.routeStart || !this.routeEnd)return
-        this.clearRoute()
+        if(!this.routeStart || !this.routeEnd){
+            this.clearRoute()
+            return
+        }
+        
         
         //array.reduce(function(total, currentValue, currentIndex, arr), initialValue)
         
         
         let create = ()=>{ 
-            this.routeLenth = this.route.reduce((total, currentValue, currentIndex, arr)=>{
+            this.routeLength = this.route.reduce((total, currentValue, currentIndex, arr)=>{
                 if(currentIndex == 0)return 0
                 return total + currentValue.distanceTo(arr[currentIndex-1]);
             },0)
-            let count = Math.max(2,Math.round(this.routeLenth / arrowSpacing))//点数
+            let count = Math.max(2,Math.round(this.routeLength / arrowSpacing))//点数
             
             const curve = new THREE.CatmullRomCurve3( this.route ); 
-            curve.curveType = 'catmullrom'
+            curve.curveType = 'chordal'//'centripetal'  'catmullrom'这个可能会超出路径外
             this.curve = curve
             
             const scenePoints = curve.getSpacedPoints( count );//更平均
@@ -221,11 +241,11 @@ export class RouteGuider extends EventDispatcher{
             scenePoints.pop()
             this.scenePoints = scenePoints
             
-            this.updateMapArrows()
-            
+            this.updateMapArrows() 
+            this.displayRoute()
             
             
-            this.displayRoute()
+            this.generateDeferred && this.generateDeferred.resolve({dis:this.routeLength})
         }
         
         
@@ -252,24 +272,25 @@ export class RouteGuider extends EventDispatcher{
             
             Potree.fileServer.get(url).then((data)=>{
                 console.log(data)
-                 
+                if(!this.routeStart || !this.routeEnd)return 
+                
                 data.forEach(item=>{
-                    let pos = viewer.transform.lonlatToLocal.forward(item.location)
+                    let pos = viewer.transform.lonlatToLocal.forward(item.location.slice(0))
                     pos = new THREE.Vector3().fromArray(pos)
                     this.route.push(pos)
                 })
                 
                 create()
-               /*
-                distance: 0.17581000000000116
-                distance_to_previous: 0.17581000000000116
-                id: 567
-                instruction: {type: 'source_projection_to_navgraph'}
-                latitude: 22.366605927999238
-                location: (3) [113.5957510575092, 22.366605927999238, -1.12419]
-                longitude: 113.5957510575092
-                z: -1.12419
-                             */
+                /*
+                    distance: 0.17581000000000116
+                    distance_to_previous: 0.17581000000000116
+                    id: 567
+                    instruction: {type: 'source_projection_to_navgraph'}
+                    latitude: 22.366605927999238
+                    location: (3) [113.5957510575092, 22.366605927999238, -1.12419]
+                    longitude: 113.5957510575092
+                    z: -1.12419
+                */
                 
             })
             
@@ -294,42 +315,59 @@ export class RouteGuider extends EventDispatcher{
           
     }
     
-    updateMapArrows(){
-          
-        let count = Math.max(2,Math.round(this.routeLenth / viewer.mapViewer.camera.zoom *10/ arrowSpacing))//点数
+    updateMapArrows(ifReset){
+        if(this.route.length == 0)return  
+        var zoom = viewer.mapViewer.camera.zoom
+        let count = Math.max(2,Math.round(this.routeLength * zoom  / arrowSpacing / 25))//点数
         const mapPoints = this.curve.getSpacedPoints( count ); 
         mapPoints.splice(0,1);//去掉首尾
-        mapPoints.pop()
-        
+        mapPoints.pop() 
         this.mapPoints = mapPoints
+        
+        
+        var scale = 25/zoom
+        this.mapArrow.scale.set(scale*0.6,scale*0.6,scale*0.6) 
+        this.mapMarkStart.scale.set(scale,scale,scale) 
+        this.mapMarkEnd.scale.set(scale,scale,scale) 
+         
+        
+        if(ifReset){//因为缩放而重新排布箭头
+            this.clearRoute({resetMap:true})
+            this.displayRoute({resetMap:true}) 
+        }
     }
     
     
     
-    displayRoute(){
-        this.sceneMeshGroup.visible = true 
-        this.mapMeshGroup.visible = true
-        this.poleStart.position.copy(this.routeStart)
-        this.poleEnd.position.copy(this.routeEnd)
-        this.mapMarkStart.position.copy(this.routeStart).setZ(0)
-        this.mapMarkEnd.position.copy(this.routeEnd).setZ(0)
-        this.scenePoints.forEach(e=>this.addArrow(e))
+    displayRoute(o={}){
+        if(!o.resetMap){ 
+            this.sceneMeshGroup.visible = true 
+            this.mapMeshGroup.visible = true
+            this.poleStart.position.copy(this.route[0])
+            this.poleEnd.position.copy(this.route[this.route.length-1])
+            this.mapMarkStart.position.copy(this.route[0]).setZ(0)
+            this.mapMarkEnd.position.copy(this.route[this.route.length-1]).setZ(0)
+            this.scenePoints.forEach(e=>this.addArrow(e))
+            this.arrows.children.forEach((e,i)=>this.setArrowDir(this.arrows.children,i));
+        }
+           
         this.mapPoints.forEach(e=>this.addMapArrow(e))
-        this.arrows.children.forEach((e,i)=>this.setArrowDir(this.arrows.children,i));
         this.mapArrows.children.forEach((e,i)=>this.setArrowDir(this.mapArrows.children,i));
     }
     
-    clearRoute(){
-        this.routeLenth = 0
-        this.route = []
-        this.scenePoints = []
-        this.mapPoints = []
-        
-        let arrows = this.arrows.children.slice(0)
-        let mapArrows = this.mapArrows.children.slice(0)
-        arrows.forEach(e=>{
-            this.arrows.remove(e)
-        })
+    clearRoute(o={}){
+        if(!o.resetMap){
+            this.routeLength = 0
+            this.route = []
+            this.scenePoints = []
+            this.mapPoints = []
+            let arrows = this.arrows.children.slice(0)
+            arrows.forEach(e=>{
+                this.arrows.remove(e)
+            })
+        } 
+        
+        let mapArrows = this.mapArrows.children.slice(0) 
         mapArrows.forEach(e=>{
             this.mapArrows.remove(e)
         })

+ 4 - 3
src/settings.js

@@ -71,8 +71,8 @@ const config = {//配置参数   不可修改
     },
      
     transitionsTime:{
-        flySpeed : 400, // 毫秒/米
-        panoToPano: 2000,
+        flySpeed : 200,//400, // 毫秒/米
+        panoToPano: 1000,//2000,
         flyIn:1000,
         flyOut:1000,
     }
@@ -198,12 +198,13 @@ let settings = {//设置   可修改
     pointDensity: '',
     ifShowMarker:true,//显示漫游点
     floorplanType:null,//平面图类型 'default' | 'diy'
+    floorplanEnable:false,
     cameraFar : 300, //相机最远范围 1-300
     limitFar: true, //是否使用setting的cameraFar来限制(如在点云裁剪时为false)
     showPanoMesh:false, //显示小球,
     dblToFocusPoint:false,//调试时如果需要双击飞向某个点云的点,就打开。此时不在漫游点的话单击将无法漫游。//因和单击漫游冲突 
     
-    
+    unableNavigate : false//进入如裁剪界面时 禁止漫游
 }
 
 

+ 1 - 1
src/utils/ClipVolume.js

@@ -3,7 +3,7 @@ import * as THREE from "../../libs/three.js/build/three.module.js";
 
 export class ClipVolume extends THREE.Object3D{
 	
-	constructor(args){
+	constructor(args={}){
 		super();
 		
 		this.constructor.counter = (this.constructor.counter === undefined) ? 0 : this.constructor.counter + 1;

+ 12 - 0
src/utils/ClippingTool.js

@@ -39,6 +39,18 @@ export class ClippingTool extends EventDispatcher{
 			let polyVolumes = e.selection.filter(e => (e instanceof PolygonClipVolume));
 			polyVolumes.forEach(e => this.viewer.scene.removePolygonClipVolume(e));
 		});
+        
+        
+        
+        
+        
+        
+        
+        //----
+        
+        /* var a = new ClipVolume()
+        viewer.scene.addVolume(a);
+        viewer.setObjectLayers(a, 'volume' ) */
 	}
 
 	setScene(scene){

+ 12 - 10
src/utils/Magnifier.js

@@ -26,6 +26,8 @@ export default class Magnifier extends THREE.Object3D {//放大镜or望远镜
         this.viewport = new Viewport( null, this.camera, {
             left:0, bottom:0, width:1, height: 1, name:'magnifier' 
         })
+        this.viewport.setResolution(this.width, this.height,0,0)
+        
         
         this.renderTarget = new THREE.WebGLRenderTarget(this.width,this.height, { 
             minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter,
@@ -74,7 +76,7 @@ export default class Magnifier extends THREE.Object3D {//放大镜or望远镜
         })
             
 
-        this.unvisibleReasons = []; //如果length>0代表不可见
+        
         
         this.mesh.layers.set(Potree.config.renderLayers.magnifier);
         this.overlayMesh.layers.set(Potree.config.renderLayers.magnifier);
@@ -90,10 +92,10 @@ export default class Magnifier extends THREE.Object3D {//放大镜or望远镜
         
         viewer.addEventListener('global_mousemove', (e)=>{
             if(e.hoverViewport == viewer.mainViewport){
-                this.updateVisible("atViewport", true)
+                viewer.updateVisible(this,"atViewport", true)
                 this.update(e.intersectPoint && e.intersectPoint.location)
             }else{
-                this.updateVisible("atViewport", false) //小地图不显示
+                viewer.updateVisible(this,"atViewport", false) //小地图不显示
             }
         })
         
@@ -110,25 +112,25 @@ export default class Magnifier extends THREE.Object3D {//放大镜or望远镜
          
          
         this.addEventListener("setEnable",(e)=>{
-            this.updateVisible("enable", e.value) //界面开关
+            viewer.updateVisible(this, "enable", e.value) //界面开关
         })
          
          
         if(Potree.settings.isOfficial){
-            this.updateVisible("enable", false) 
+            viewer.updateVisible(this, "enable", false) 
         }else{
-            this.updateVisible("measure", false) 
+            viewer.updateVisible(this, "measure", false) 
             viewer.addEventListener("measureMovePoint",()=>{//测量开始
-                this.updateVisible("measure", true) 
+                viewer.updateVisible(this, "measure", true) 
             })
             viewer.addEventListener("endMeasureMove",()=>{
-                this.updateVisible("measure", false) 
+                viewer.updateVisible(this, "measure", false) 
             })
         }
     }
     
     
-    updateVisible(reason, ifShow){//当所有加入的条件都不为false时才显示
+    /* updateVisible(reason, ifShow){//当所有加入的条件都不为false时才显示
         if(ifShow){
             var index = this.unvisibleReasons.indexOf(reason)
             index > -1 && this.unvisibleReasons.splice(index, 1)
@@ -138,7 +140,7 @@ export default class Magnifier extends THREE.Object3D {//放大镜or望远镜
             this.visible = false    
         }
         
-    }
+    } */
     
     
     update(aimPos){ 

+ 79 - 422
src/utils/Measure.js

@@ -10,6 +10,9 @@ import DepthBasicMaterial from "../materials/DepthBasicMaterial.js";
 import Sprite from '../viewer/Sprite'
 import {config} from '../settings'
 
+import {ctrlPolygon} from './ctrlPolygon'
+
+
 let texLoader = new THREE.TextureLoader() 
 const defaultNormal = new THREE.Vector2(0,1)
 let color = new THREE.Color(config.measure.lineColor)
@@ -37,25 +40,18 @@ const subLabelProp = {
     renderOrder : 4
 }
 
-const verticalLine = new THREE.Line3()
 
     
  
 
-export class Measure extends THREE.Object3D {
+export class Measure extends ctrlPolygon{
 	constructor (prop) {
-		super();
+		super('measure',prop);
 		this.constructor.counter = (this.constructor.counter === undefined) ? 0 : this.constructor.counter + 1;
-		
-		this.maxMarkers = Number.MAX_SAFE_INTEGER;
+		 
         
-        this.transformData(prop);
-        for(let i in prop){
-            this[i] = prop[i]
-        }
         this.name = this.measureType + this.constructor.counter  //'Measure_' + this.constructor.counter;
-        
-		this.points = [];
+         
 		this._showDistances = true;
 		this._showCoordinates = false;
 		this._showArea = false;
@@ -66,22 +62,21 @@ export class Measure extends THREE.Object3D {
 		this._showEdges = true;
 		this._showAzimuth = false;
 
-		this.sphereGeometry = new THREE.SphereGeometry(0.4, 10, 10);
+		//this.sphereGeometry = new THREE.SphereGeometry(0.4, 10, 10);
 		this.color = new THREE.Color(config.measure.lineColor)//new THREE.Color(0xff0000);
 
-		this.spheres = [];
-		this.edges = [];
+		
 		this.sphereLabels = [];
 		this.edgeLabels = [];
 		this.angleLabels = [];
 		this.coordinateLabels = [];
         this.area = {value:0,string:''}
-
+        
         
         
         if(this.showArea){
             this.areaLabel = this.createAreaLabel();
-            this.areaPlane = createAreaPlane(); 
+            this.areaPlane = this.createAreaPlane(); 
             this.add(this.areaPlane)
             this.add(this.areaLabel)
         }
@@ -115,7 +110,10 @@ export class Measure extends THREE.Object3D {
         this.selectStates = {}
         
         this.setUnitSystem(prop.unit || viewer.unitConvert.UnitService.defaultSystem)
-         
+        viewer.setObjectLayers(this, 'measure' )
+        
+        //addMarkers:
+        this.initData(prop)
 	}
  
  
@@ -131,7 +129,7 @@ export class Measure extends THREE.Object3D {
             if(this.showCoordinates){
                 let point = this.points[0];
                 let position = point 
-                this.spheres[0].position.copy(position);
+                this.markers[0].position.copy(position);
 
                 { // coordinate labels
                     let coordinateLabel = this.coordinateLabels[0];
@@ -228,29 +226,11 @@ export class Measure extends THREE.Object3D {
             
             if(this.showArea && this.point2dInfo){ // update area   
                 
-                this.areaPlane.geometry = MeshDraw.getShapeGeo(this.point2dInfo.points2d)
-                var center = math.getCenterOfGravityPoint(this.point2dInfo.points2d) //重心 
-                  
-                var firstPos =  this.point2dInfo.points2d[0].clone()
-                firstPos.z = 0                  //因为shape只读取了xy,所以位移下, 再算出最终位置,得到差距
-                firstPos.applyQuaternion(this.point2dInfo.quaInverse)
-                var vec = this.point2dInfo.originPoint0.clone().sub(firstPos)
-                center = new THREE.Vector3(center.x, center.y, 0)
-                center.applyQuaternion(this.point2dInfo.quaInverse)
-                this.areaPlane.quaternion.copy(this.point2dInfo.quaInverse) 
-                this.areaPlane.position.copy(vec)       
-                center.add(vec)
-                this.center = center
-                let area = Math.abs(math.getArea(this.point2dInfo.points2d))//this.getArea();
-                //label
-                this.areaLabel.setPos(center); 
-                /* 
-
-                let suffix = "m";
-                this.area = area
-                let txtArea = Utils.addCommas(area.toFixed(2));
-                let msg =  `${this.measureType} ${txtArea} ${suffix}\u00B2`; */
+                this.updateAreaPlane()
                 
+                let area = Math.abs(math.getArea(this.point2dInfo.points2d))//this.getArea();
+                 
+                this.areaLabel.setPos(this.center); 
                 
                 let msg = viewer.unitConvert.convert(area, 'area', void 0, this.unitSystem/* , 0.1 */ )
                 this.area = {value:area, string:msg}
@@ -320,42 +300,27 @@ export class Measure extends THREE.Object3D {
 	};
 
  
-    
- 
- 
+  
 
 
-	addMarker (point) {
-        if(point instanceof Array){
-            point = new THREE.Vector3(...point) 
-        } 
-		this.points.push(point);
+	addMarker (o={}) {
          
-        
-		// sphere 
-        //let sphere = new THREE.Sprite(this.getSphereMaterial('default')  );
-       
         let sphere = new Sprite({mat:this.getSphereMaterial('default'), sizeInfo: sphereSizeInfo, name:"measure_point"} )
         viewer.setObjectLayers(sphere, 'measure' )
-        sphere.renderOrder = 3
+        sphere.renderOrder = 3 
         sphere.sphereSelectStates = {}
-		this.add(sphere);
-		this.spheres.push(sphere);
-        this.updateSphere(sphere, point)
         
         
+         
+        this.updateMarker(sphere, o.point)
+        
+        let edge
 		{ // edges 
-            let edge = LineDraw.createFatLine( [
+            edge = LineDraw.createFatLine( [
 					0, 0, 0,
 					0, 0, 0,
-			],{material:this.getLineMat('edgeDefault')} )
-            
-            
-            viewer.setObjectLayers(edge, 'measure' )
-			this.add(edge);
-			this.edges.push(edge);
-            
-            
+			],{material:this.getLineMat('edgeDefault')} ) 
+            viewer.setObjectLayers(edge, 'measure' ) 
             
             //----
             let mouseover = (e) => {this.setSelected(true, 'edge')};
@@ -364,13 +329,15 @@ export class Measure extends THREE.Object3D {
 			 
 			edge.addEventListener('mouseover', mouseover);
 			edge.addEventListener('mouseleave', mouseleave);
-            
-            
-            
+             
             
             
 		}
- 
+        
+        super.addMarker({point:o.point, marker:sphere,  edge})
+        
+        
+        
 		if(this.showEdges){ // edge labels 
             var className = 'measure_length';
             if(this.closed){
@@ -426,72 +393,7 @@ export class Measure extends THREE.Object3D {
         
         
         
-		{ // Event Listeners 
-			let drag = (e) => {
-                
-                var I, atMap 
-                
-                
-                atMap = e.drag.dragViewport.name == 'mapViewport'
-                I = e.intersectPoint && (e.intersectPoint.location ? e.intersectPoint.location : e.intersectPoint)
-                
-                //在三维中脱离点云(在map中拉到周围都没有点云的地方)的顶点,无法拖拽怎么办
-                
-                
-				if (I) {
-					let i = this.spheres.indexOf(e.drag.object);
-					if (i !== -1) { 
-                        this.dragChange(I, i, atMap) 
-					}
-				}
-                
-                
-                this.editStateChange(true)
-                
-			};
-
-			let drop = e => {
-                if(!e.isAtDomElement && this.isNew){//如果是刚添加时在其他dom点击, 不要响应
-                    setTimeout(()=>{//等 drag=null之后 //右键拖拽结束后需要重新得到drag
-                        if(viewer.scene.measurements.includes(this)){
-                            viewer.inputHandler.startDragging(e.drag.object,
-                                {endDragFun: e.drag.endDragFun} 
-                            )
-                        } 
-                    },1) 
-                    return
-                }
-				let i = this.spheres.indexOf(e.drag.object); 
-				if (i !== -1) {
-					this.dispatchEvent({
-						'type': 'marker_dropped',
-						'measurement': this,
-						'index': i
-					});
-                    if(this.spheres.length>2 && this.facePlane)this.cannotConfirmNormal = false
-                    this.guideLine &&(this.guideLine.visible = false)
-				}
-                
-                viewer.dispatchEvent({
-                    type : "CursorChange", action : "remove",  name:"measure_isIntersectSelf"
-                })
-                
-                this.setSphereSelected(e.drag.object, false, 'single') 
-                
-                this.editStateChange(false)
-                e.drag.endDragFun && e.drag.endDragFun(e)//  addmarker
-                if(this.changeCallBack)this.changeCallBack()
-            };
-
-            
-			let mouseover = (e) => {this.setSphereSelected(e.object, true, 'single');/* console.log('hover')  */};
-			let mouseleave = (e) => {this.setSphereSelected(e.object, false, 'single');/* console.log('hoveroff')  */}
-
-			sphere.addEventListener('drag', drag);
-			sphere.addEventListener('drop', drop);
-			sphere.addEventListener('mouseover', mouseover);
-			sphere.addEventListener('mouseleave', mouseleave);
-		}
+		
 
 		let event = {
 			type: 'marker_added',
@@ -509,173 +411,7 @@ export class Measure extends THREE.Object3D {
 
        
 
-    dragChange(intersectPos,i, atMap){ 
-        var len = this.spheres.length
-        var location = intersectPos.clone()
-
-        if(this.faceDirection && this.maxMarkers == 2 && len == 2){//add 固定方向的点不直接拖拽
-            var p1 = this.spheres[0].position
-            if(this.faceDirection == 'horizontal'){
-                var projectPos = location.clone().setZ(p1.z)
-            }else{
-                var projectPos = p1.clone().setZ(location.z)
-            }
-            //var p2 = p1.clone().add(this.direction)
-            //var projectPos = math.getFootPoint(location, p1, p2)
-            
-            
-            this.updateLine(this.guideLine, location, projectPos)
-            this.setPosition(i, projectPos);
-            this.guideLine.visible = true
-        }else if( len > 1){ 
-             
-            var points = this.points//.map(e=>e.position.clone())
-            points[i].copy(location) //算normal需要提前确认point
-            
-            //若为定义了面朝向的矩形
-            if(this.faceDirection == 'horizontal'){
-                if(len == 2){
-                    location.setZ(this.points[0].z) 
-                }
-                if(!this.facePlane){//一个点就能确定面
-                    this.facePlane = new THREE.Plane().setFromNormalAndCoplanarPoint( new THREE.Vector3(0,0,1), this.points[0]  )
-                }
-            }else if(this.faceDirection == 'vertical'){//当有两个点时, 有两个方向的可能
-                if(len == 2){
-                    if(this.isRect){
-                        let vec = points[0].clone().sub(location) 
-                        if(Math.sqrt(vec.x*vec.x+vec.y*vec.y) > Math.abs(vec.z) ){//水平(高度差小于水平距离时)
-                            location.setZ(this.points[0].z) 
-                            //this.cannotConfirmNormal = false;//能确定面为水平方向
-                        }else{//垂直 (当两点一样时也属于这种)
-                            location.setX(points[0].x);
-                            location.setY(points[0].y);
-                            //this.cannotConfirmNormal = true; //不能确定面,因第三点可绕着纵轴线自由移动
-                        }
-                    }
-                }else{ 
-                    {//判断cannotConfirmNormal. 如果前几段都在竖直线上,就不能固定出面方向。
-                        this.cannotConfirmNormal = true
-                        let max = this.isRect ? 1 : len-2 
-                        for(let i=0;i<max;i++){
-                            let p1 = points[i].clone()
-                            let p2 = points[i+1].clone()
-                            let vec = p1.sub(p2);
-                            if(vec.x != 0 || vec.y != 0){
-                                this.cannotConfirmNormal = false
-                                break;
-                            } 
-                        } 
-                    }
-                    
-                    if(!this.facePlane || this.cannotConfirmNormal){//三个点且为水平方向时,计算面
-                          
-                        var points_ = points.map(e=>new THREE.Vector2(e.x,e.y))
-                        var points2 = getDifferentPoint(points_, 2); 
-                        if(points2){
-                            let normal = math.getNormal2d({p1:points2[0], p2:points2[1]})  
-                            normal = new THREE.Vector3(normal.x, normal.y, 0)
-                            this.facePlane = new THREE.Plane().setFromNormalAndCoplanarPoint( normal, this.points[0]  )
-                        } 
-                    }
-                }
-            } 
-
-            if(len > 2){//area
-            
-                if(!this.faceDirection){ 
-                    if(len == 3 || this.isRect) this.cannotConfirmNormal = true //当第三个点固定后(有四个点时)才能固定面
-                    if(!this.facePlane || this.cannotConfirmNormal){
-                        var points3 = getDifferentPoint(points, 3);//只有找到三个不同的点算拥有面和area
-                        if(points3){
-                            this.facePlane = new THREE.Plane().setFromCoplanarPoints(...points3 )
-                        }
-                    }
-                }
-                
-                if( this.facePlane && !this.cannotConfirmNormal  ){//之后加的点一定要在面上  
-                    if(atMap){ 
-                        //地图上用垂直线,得到和面的交点。
-                        verticalLine.set(location.clone().setZ(100000), location.clone().setZ(-100000))//确保长度范围覆盖所有测量面 
-                        location = this.facePlane.intersectLine(verticalLine, new THREE.Vector3() )
-                        if(!location) return; 
-                    }else{ 
-                        location = this.facePlane.projectPoint(intersectPos, new THREE.Vector3() )
-                    }
-                }  
-                
-                
-                points[i].copy(location)//再copy确认一次
-                
-                if(this.isRect){ //是矩形 (即使没有faceDirection也能执行)
-                    //根据前两个点计算当前和下一个点
-                    var p1 = this.points[(i-2+len)%len]
-                    var p2 = this.points[(i-1+len)%len]
-                    if(p1.equals(p2)){//意外情况:重复点两次 ( bug点,改了好多遍)
-                        if(this.faceDirection == 'vertical'){
-                            p2.add(new THREE.Vector3(0,0,0.0001))
-                        }else{
-                            p2.add(new THREE.Vector3(0,0.0001,0))
-                        } 
-                    } 
-                    //p3 : location 
-                    var foot = math.getFootPoint(location, p1, p2)//p2 修改p2到垂足的位置
-                    var vec = foot.clone().sub(location)
-                    var p4 = p1.clone().sub(vec) 
-                     
-                    
-                    points[(i-1+len)%len].copy(foot) 
-                    points[(i+1)%len].copy(p4) 
-                    this.setPosition((i-1+len)%len, foot);//p2
-                    this.setPosition((i+1)%len, p4);
-                    
-                }  
-                
-                let points2d;
-                if(this.facePlane){
-                    var originPoint0 = points[0].clone() 
-                    var qua = math.getQuaBetween2Vector(this.facePlane.normal, new THREE.Vector3(0,0,1), new THREE.Vector3(0,0,1));
-                    points2d = points.map(e=>e.clone().applyQuaternion(qua))  
-                }
-                
-                
-                var isIntersectSelf = !this.isRect && len > 3 && this.intersectSelf(points2d)//检测相交
-                if(isIntersectSelf){
-                    //not-allowed
-                    viewer.dispatchEvent({
-                        type : "CursorChange", action : "add",  name:"measure_isIntersectSelf"
-                    })  
-                    return
-                }else{
-                    viewer.dispatchEvent({
-                        type : "CursorChange", action : "remove",  name:"measure_isIntersectSelf"
-                    })
-                    this.facePlane && (this.point2dInfo = {
-                        originPoint0 ,
-                        points2d,
-                        quaInverse : qua.clone().invert()
-                    })
-                }
-                
-                
-                 
-            }
-            
-            var showGuideLine = len>1 && (this.faceDirection || len > 3)
-            if(showGuideLine){
-                this.updateLine(this.guideLine, intersectPos, location)
-                this.guideLine.visible = true
-            } 
-            this.setPosition(i, location);
-            //console.log(this.points.map(e=>e.toArray())) 
-
-        }else{
-            this.setPosition(i, location);
-        }
-        
-        this.update()
-    }
-
+     
 
 
 
@@ -704,7 +440,7 @@ export class Measure extends THREE.Object3D {
 
 
     
-    setSphereSelected(sphere, state, hoverObject){
+    setMarkerSelected(sphere, state, hoverObject){
         
         //console.warn(sphere.id , state, hoverObject)
         
@@ -738,7 +474,7 @@ export class Measure extends THREE.Object3D {
         
         
         if(absoluteState){
-            this.spheres.forEach(e=>this.setSphereSelected(e,true,'selectAll' ) )
+            this.markers.forEach(e=>this.setMarkerSelected(e,true,'selectAll' ) )
             
             this.edges.forEach(e=>e.material = this.getLineMat('edgeSelect')   )
 			 
@@ -756,7 +492,7 @@ export class Measure extends THREE.Object3D {
             
             
         }else{
-            this.spheres.forEach(e=>this.setSphereSelected(e,false,'selectAll' ))
+            this.markers.forEach(e=>this.setMarkerSelected(e,false,'selectAll' ))
             this.edges.forEach(e=>e.material = this.getLineMat('edgeDefault')  )
             this.areaPlane && (this.areaPlane.material = planeMats.default)
             this.closed && this.edgeLabels.forEach(e=>e.setVisible( false))
@@ -771,55 +507,30 @@ export class Measure extends THREE.Object3D {
         viewer.mapViewer.emit('content_changed')
     }
     
-	removeMarker (index) {
-		this.points.splice(index, 1);
-
-		this.remove(this.spheres[index]); 
-        this.coordinateLabels.splice(index, 1);   
-
-
-		let edgeIndex = (index === 0) ? 0 : (index - 1);
-		this.remove(this.edges[edgeIndex]);
-		this.edges.splice(edgeIndex, 1);
-
-
-        if(this.edgeLabels[edgeIndex]){
-            //this.edgeLabels[edgeIndex].remove();
+	removeMarker(index){
+        super.removeMarker(index)
+        this.coordinateLabels.splice(index, 1);
+        if(this.edgeLabels[edgeIndex]){ 
             this.edgeLabels[edgeIndex].parent.remove(this.edgeLabels[edgeIndex])
             this.edgeLabels.splice(edgeIndex, 1);
         }
-
-		  
         if(this.angleLabels[index]){
             this.angleLabels[index].remove()
             this.angleLabels.splice(index, 1);
         }
-		 
-		 
-		this.spheres.splice(index, 1);
-
-        this.point2dInfo && this.point2dInfo.points2d.splice(index, 1); //add
-
-
-		this.update();
-
-		this.dispatchEvent({type: 'marker_removed', measurement: this});
-	};
-
-	/* setMarker (index, point) {
-		this.points[index] = point;
-
-		let event = {
+        this.dispatchEvent({type: 'marker_removed', measurement: this});
+    }
+    
+    setPosition(index, position) {
+        super.setPosition(index, position)
+        let event = {
 			type: 'marker_moved',
 			measure:	this,
 			index:	index,
-			position: point.position.clone()
+			position: position.clone()
 		};
-		this.dispatchEvent(event);
-
-		this.update();
-	} */
-    
+		this.dispatchEvent(event); 
+    }
     
     dispose(){//add
         var labels = this.edgeLabels.concat(this.coordinateLabels)
@@ -829,49 +540,7 @@ export class Measure extends THREE.Object3D {
         this.parent.remove(this)
     }
     
-    
-	setPosition (index, position) {
-		let point = this.points[index];
-		point.copy(position);
-
-		let event = {
-			type: 'marker_moved',
-			measure:	this,
-			index:	index,
-			position: position.clone()
-		};
-		this.dispatchEvent(event);
-        
-        let sphere = this.spheres[index];  
-        this.updateSphere(sphere, point)
-	 
-	};
-    intersectSelf(points2d){//add
-        var len =  points2d.length
-        for(var i=0;i<len;i++){
-            for(var j=i+2;j<len;j++){
-                if(Math.abs(j-len-i)<2)continue;//不和邻边比
-                
-                var p1 =  points2d[i]
-                var p2 =  points2d[i+1]
-                var p3 =  points2d[j]
-                var p4 =  points2d[(j+1)%len] 
-                if(p1.equals(p2) || p3.equals(p4) || p1.equals(p3) || p2.equals(p3) || p1.equals(p4) || p2.equals(p4))continue 
-             
-                
-                var line1 = [p1,p2]
-                var line2 = [p3,p4]
-                var intersect = math.isLineIntersect(line1, line2, false, 0.001)
-                if(intersect){
-                    return true
-                    break
-                } 
-            }
-        }
-          
-    }
-	
-
+     
 	getTotalDistance () {
 		if (this.points.length === 0) {
 			return 0;
@@ -954,6 +623,7 @@ export class Measure extends THREE.Object3D {
             0, 0, 0,
         ],{material:this.getLineMat('guide')} )
         guideEdge.visible = false 
+        
         return guideEdge;
     }
     
@@ -1048,6 +718,25 @@ export class Measure extends THREE.Object3D {
     }
     
     
+    createAreaPlane(){
+        planeMats || (planeMats = { 
+            default: new DepthBasicMaterial({
+                color:color,
+                side:THREE.DoubleSide,
+                opacity:0.2,
+                transparent:true,
+                useDepth:true 
+            }), 
+            selected: new DepthBasicMaterial({
+                color:color,
+                side:THREE.DoubleSide,
+                opacity:0.3,
+                transparent:true
+            }) 
+        },Measure.planeMats = planeMats)
+        return super.createAreaPlane(planeMats.default)
+    }
+    
     updateLine(line, p1,p2){
        
         LineDraw.moveFatLine(line,[
@@ -1056,7 +745,7 @@ export class Measure extends THREE.Object3D {
     }
 	raycast (raycaster, intersects) {
 		for (let i = 0; i < this.points.length; i++) {
-			let sphere = this.spheres[i];
+			let sphere = this.markers[i];
 
 			sphere.raycast(raycaster, intersects);
 		}
@@ -1072,10 +761,7 @@ export class Measure extends THREE.Object3D {
 		intersects.sort(function (a, b) { return a.distance - b.distance; });
 	};
 
-    updateSphere(sphere, pos){
-        sphere.position.copy(pos);
-        sphere.update();
-    }
+    
     
     transformData(prop){
         if(prop.measureType == 'Point'){ 
@@ -1257,38 +943,9 @@ export class Measure extends THREE.Object3D {
 
 
 
-function getDifferentPoint(points, count){//for facePlane
-    var result = [];
-    for(let i=0;i<points.length;i++){
-        var p = points[i];
-        if(result.find(e=>e.equals(p)))continue;
-        else result.push(p)
-        if(result.length == count)break
-    }
-    if(result.length == count)return result
-}
 
-function createAreaPlane(){
-    planeMats || (planeMats = { 
-        default: new DepthBasicMaterial({
-            color:color,
-            side:THREE.DoubleSide,
-            opacity:0.2,
-            transparent:true,
-            useDepth:true 
-        }), 
-        selected: new DepthBasicMaterial({
-            color:color,
-            side:THREE.DoubleSide,
-            opacity:0.3,
-            transparent:true
-        }) 
-    },Measure.planeMats = planeMats)
-    var geometry = new THREE.Geometry();
-    var mesh = new THREE.Mesh(geometry, planeMats.default)
-    viewer.setObjectLayers(mesh, 'measure' )
-    return mesh
-}
+
+
 
 function setLabelHightState(label, state){
     if(state){

+ 31 - 36
src/utils/MeasuringTool.js

@@ -178,7 +178,7 @@ export class MeasuringTool extends EventDispatcher{
 		e.scene.addEventListener('measurement_removed', this.onRemove);
 	}
 
-	startInsertion (args = {}, callback) {
+	startInsertion (args = {}, callback, cancelFun) {
         
         
 		let domElement = this.viewer.renderer.domElement;
@@ -224,14 +224,25 @@ export class MeasuringTool extends EventDispatcher{
         measure.editStateChange(true)
         let timer;
 
+
+        let continueDrag = (marker)=>{
+            timer = setTimeout(()=>{//等 drag=null之后 //右键拖拽结束后需要重新得到drag
+                this.viewer.inputHandler.startDragging(marker,
+                    {endDragFun} 
+                ); 
+            },1)  
+        }
+
 		let endDragFun = (e) => {
-           
+            
+                
+            
 			if (e.button == THREE.MOUSE.LEFT /* e.drag.mouse == MOUSE.LEFT */) {
 				if (measure.points.length >= measure.maxMarkers) {
                     end({complete:true});
 				}else{
                     if(measure.points.length == 1){//点击第一下,恢复可见
-                        measure.spheres[0].visible = true;
+                        measure.markers[0].visible = true;
                         /* if(e.drag.hoverViewport.name == 'mapViewport'){//如果在地图点击,直接使用地图上的
                             let pos2d = e.drag.hoverViewport.end;
                             let newPos = new THREE.Vector3(pos2d.x,pos2d.y,-1).unproject(e.drag.hoverViewport.camera); //z:-1朝外   
@@ -243,53 +254,43 @@ export class MeasuringTool extends EventDispatcher{
                     
                     var marker = measure.addMarker(measure.points[measure.points.length - 1].clone())
                      
-                    if(args.isRect && measure.spheres.length == 3){
+                    if(args.isRect && measure.markers.length == 3){
                         measure.addMarker(measure.points[0].clone())
                     }
                     measure.editStateChange(true) //重新激活reticule状态
-                    timer = setTimeout(()=>{//等 drag=null之后
-                        this.viewer.inputHandler.startDragging(marker,
-                            {endDragFun} 
-                        ); 
-                    },1)    
+                    continueDrag(marker) 
                 } 
 				 
 			} else if (e.button === THREE.MOUSE.RIGHT /* e.drag.mouse === MOUSE.RIGHT */) {
 				if(e.pressDistance < 2 )end(e);//非拖拽的话
-                else {
-                    timer = setTimeout(()=>{//等 drag=null之后 //右键拖拽结束后需要重新得到drag
-                        this.viewer.inputHandler.startDragging(e.drag.object,
-                            {endDragFun} 
-                        ); 
-                    },1) 
-                }
+                else continueDrag(e.drag.object)
+                 
 			}
 		};
 
 		let end = (e={}) => {//确定、结束
             if(args.minMarkers != void 0){
-                if(!e.complete && measure.spheres.length<=args.minMarkers){//右键  当个数不够时取消 
-                    if(!Potree.settings.isOfficial) this.viewer.scene.removeMeasurement(measure)
+                if(!e.complete && measure.markers.length<=args.minMarkers){//右键  当个数不够时取消 
+                    this.viewer.scene.removeMeasurement(measure)
+                    cancelFun && cancelFun()
+                    return
+                    
+                    /* if(!Potree.settings.isOfficial) this.viewer.scene.removeMeasurement(measure)
                     else if(e.drag){ //正式版本不允许右键退出, 继续
-                        timer = setTimeout(()=>{//等 drag=null之后 //右键拖拽结束后需要重新得到drag
-                            this.viewer.inputHandler.startDragging(e.drag.object,
-                                {endDragFun} 
-                            ); 
-                        },1) ;
+                        continueDrag(e.drag.object)
                         measure.editStateChange(true)
                         return
-                    }
+                    } */
                 } 
             }
-            if (!e.complete && measure.spheres.length > 3) {
-				measure.removeMarker(measure.points.length - 1);
+            if (!e.complete && measure.markers.length > 3) {
+				measure.removeMarker(measure.points.length - 1); 
 			}
             measure.isNew = false
             clearTimeout(timer) 
 			this.viewer.removeEventListener('cancel_insertions', Exit);
             pressExit && this.viewer.inputHandler.removeEventListener('keydown', pressExit);
-            callback && callback()
-            
+            callback && callback() 
             /* this.viewer.dispatchEvent({
                 type: 'finish_inserting_measurement',
                 measure: measure
@@ -342,14 +343,8 @@ export class MeasuringTool extends EventDispatcher{
     createMeasureFromData(data){//add
         const measure = new Measure(data);
         
-        for(const point of data.points){
-            const pos = new THREE.Vector3().copy(point) 
-            measure.addMarker(pos); 
-        }
-        measure.dragChange(new THREE.Vector3().copy(data.points[data.points.length-1]) , data.points.length-1); 
-        //measure.update()
         viewer.scene.addMeasurement(measure);
-        measure.setSelected(false )
+        
         if(measure.guideLine)measure.guideLine.visible = false
         return  measure       
     }
@@ -374,7 +369,7 @@ export class MeasuringTool extends EventDispatcher{
 			updateAzimuth(this.viewer, measure);
 
 			 
-            /*  [...measure.spheres, ...measure.edgeLabels, measure.areaLabel].forEach(e=>{
+            /*  [...measure.markers, ...measure.edgeLabels, measure.areaLabel].forEach(e=>{
                 e && e.update() 
             }); */
              

+ 17 - 22
src/viewer/EDLRenderer.js

@@ -13,7 +13,7 @@ export class EDLRenderer{//Eye-Dome Lighting 眼罩照明
 
 		this.edlMaterial = null;
 
-		this.rtRegular;
+		//this.rtRegular;
 		this.rtEDL;
 
 		this.gl = viewer.renderer.getContext();
@@ -21,10 +21,10 @@ export class EDLRenderer{//Eye-Dome Lighting 眼罩照明
 		this.shadowMap = new PointCloudSM(this.viewer.pRenderer);
         
         viewer.addEventListener('resize',this.resize.bind(this))
-        this.initEDL()
+        this.initEDL(viewer)
 	}
 
-	initEDL(){
+	initEDL(viewer){
 		if (this.edlMaterial != null) {
 			return;
 		}
@@ -33,8 +33,8 @@ export class EDLRenderer{//Eye-Dome Lighting 眼罩照明
 		this.edlMaterial.depthTest = true;
 		this.edlMaterial.depthWrite = true;
 		this.edlMaterial.transparent = true;
-
-		this.rtEDL = new THREE.WebGLRenderTarget(1024, 1024, {
+        
+		this.rtEDL = new THREE.WebGLRenderTarget(viewer.mainViewport.resolution2.x, viewer.mainViewport.resolution2.y, {
 			minFilter: THREE.NearestFilter,
 			magFilter: THREE.NearestFilter,
 			format: THREE.RGBAFormat,
@@ -42,13 +42,13 @@ export class EDLRenderer{//Eye-Dome Lighting 眼罩照明
 			depthTexture: new THREE.DepthTexture(undefined, undefined, THREE.UnsignedIntType)
 		});
 
-		this.rtRegular = new THREE.WebGLRenderTarget(1024, 1024, {
+		/* this.rtRegular = new THREE.WebGLRenderTarget(viewer.mainViewport.resolution2.x, viewer.mainViewport.resolution2.y, {
 			minFilter: THREE.NearestFilter,
 			magFilter: THREE.NearestFilter,
 			format: THREE.RGBAFormat,
 			depthTexture: new THREE.DepthTexture(undefined, undefined, THREE.UnsignedIntType)
 		});
-        
+         */
         
         
         
@@ -69,14 +69,9 @@ export class EDLRenderer{//Eye-Dome Lighting 眼罩照明
 	};
 
 	resize(e){
-        //width, height
-		/* if(this.screenshot){
-			width = this.screenshot.target.width;
-			height = this.screenshot.target.height;
-		} */
-     
-		this.rtEDL.setSize(e.resolution.x, e.resolution.y);
-		this.rtRegular.setSize(e.resolution.x, e.resolution.y);
+        let viewport = e.viewport
+		this.rtEDL.setSize(viewport.resolution2.x, viewport.resolution2.y);
+		//this.rtRegular.setSize(e.resolution.x, e.resolution.y);
         
 	}
 
@@ -100,8 +95,8 @@ export class EDLRenderer{//Eye-Dome Lighting 眼罩照明
             renderer.clear( true, true, true );
         }
 
-		renderer.setRenderTarget( this.rtRegular );
-		renderer.clear( true, true, false );
+		//renderer.setRenderTarget( this.rtRegular );
+		//renderer.clear( true, true, false );
 
 		renderer.setRenderTarget(oldTarget);
 	}
@@ -184,15 +179,15 @@ export class EDLRenderer{//Eye-Dome Lighting 眼罩照明
 	
 		                                           
 		//const visiblePointClouds = viewer.scene.pointclouds.filter(pc =>  pc.visible );
-		const visiblePointClouds2 = viewer.scene.pointclouds.filter(pc => pc.getVisible('datasetSelection')  ); 
+		const visiblePointClouds2 = viewer.scene.pointclouds.filter(pc => viewer.getObjVisiByReason(pc,'datasetSelection')  ); 
 		const showPointClouds = viewer.scene.pointclouds.some(e=>e.visible)
          
         viewer.scene.pointclouds.forEach(e=>{//为了绘制到depthTexture,先显示(展示全景图时隐藏了点云,所以需要显示下。且放大镜需要绘制点云)
             e.oldVisi = e.visible
-            if(e.getVisible('datasetSelection') )e.visible = true; 
+            if(viewer.getObjVisiByReason(e, 'datasetSelection') ) e.visible = true; 
         }) 
         
-        
+         
         
  
 		let lights = [];
@@ -246,7 +241,7 @@ export class EDLRenderer{//Eye-Dome Lighting 眼罩照明
                 material.far = camera.far;
                 material.uniforms.octreeSize.value = octreeSize
 	
-                if(viewer.useEDL){ 
+                if(viewer.useEDL && Potree.settings.displayMode != 'showPanos'){ 
                     /* material.weighted = false;
                     material.useLogarithmicDepthBuffer = false;  */ 
                     material.useEDL = true;
@@ -276,7 +271,7 @@ export class EDLRenderer{//Eye-Dome Lighting 眼罩照明
         
          
         //渲染到rtEDL完毕
-		viewer.dispatchEvent({type: "render.pass.scene", viewer: viewer, renderTarget: this.rtRegular});
+		viewer.dispatchEvent({type: "render.pass.scene", viewer: viewer/* , renderTarget: this.rtRegular */});
 		viewer.renderer.setRenderTarget(params.target || null);
         
         viewer.scene.pointclouds.forEach(e=>{

+ 160 - 48
src/viewer/viewer.js

@@ -68,10 +68,10 @@ export class Viewer extends ViewerBase{
         
         
         
-        //add --------
-        
+        //add -------- 
         this.navigateMode = 'free' // 'panorama'; 'free'自由模式是只显示点云或者未进入到漫游点, 
         this.isEdit = true
+        this.waitQueue = [] 
         CursorDeal.attachToViewer(this)//ADD
         this.unitConvert = new UoMService();
         mapArea = mapArea_
@@ -2003,7 +2003,11 @@ export class Viewer extends ViewerBase{
 
         //改:不根据点云修改视野near far
         var near = camera.near, far = camera.far
-        if(Potree.settings.limitFar){
+        
+        if(Potree.settings.displayMode == 'showPanos'){
+            camera.near = 0.1; 
+            camera.far = viewer.farWhenShowPano 
+        }else if(Potree.settings.limitFar){
             camera.near = 0.1;
             camera.far = Potree.settings.cameraFar; 
         }else if(result.lowestSpacing !== Infinity){
@@ -2238,6 +2242,9 @@ export class Viewer extends ViewerBase{
         let renderSize
         if(params_.target){
             renderSize =  new THREE.Vector2(params_.target.width, params_.target.height)
+            if(!params_.viewports){
+                console.warn('必须指定target的viewport! 且target大小和viewport.resolution2相同')
+            }
         }else{
             renderSize = this.renderer.getSize(new THREE.Vector2());
         }
@@ -2260,14 +2267,14 @@ export class Viewer extends ViewerBase{
                 left = Math.floor(renderSize.x * view.left)
                 bottom = Math.floor(renderSize.y * view.bottom)
                 
-                if(params_.target){//有target时最好viewport是专门建出来的
+                /* if(params_.target){//有target时最好viewport是专门建出来的
                     width = Math.floor(renderSize.x * view.width)
                     height = Math.floor(renderSize.y * view.height)
-                }else{
+                }else{ */
                     width = view.resolution.x // 用的是client的width和height
                     height = view.resolution.y
-                }
-                
+                //}
+                if(width == 0 || height == 0)return
                 
                 let scissorTest = view.width<1 || view.height<1
                 if(params_.target){
@@ -2283,9 +2290,11 @@ export class Viewer extends ViewerBase{
                
             }    
              
-              
-
-            needSResize && this.emitResizeMsg({resolution: new THREE.Vector2(width,height), left:view.left,  bottom:view.bottom })//resize everything  such as lines  targets 
+            if(needSResize){
+                this.emitResizeMsg( { viewport:view} )
+            } 
+            
+            //needSResize && this.emitResizeMsg({resolution: params_.target ? new THREE.Vector2(width,height) : view.resolution2, left:view.left,  bottom:view.bottom })//resize everything  such as lines  targets 
             
             viewer.dispatchEvent({type: "render.begin",  viewer: viewer, viewport:view, params });
             
@@ -2363,7 +2372,7 @@ export class Viewer extends ViewerBase{
          
         if(!params.magnifier){ 
             //测量线 
-            this.dispatchEvent({type: "render.pass.perspective_overlay", viewer:this, camera});
+            this.dispatchEvent({type: "render.pass.perspective_overlay", camera});
             
             if(!params.screenshot && !params.isMap){
                 this.setCameraLayers(camera, ['magnifier']) //magnifier 遮住测量线 
@@ -2405,6 +2414,47 @@ export class Viewer extends ViewerBase{
     }
     
      
+    updateVisible(object, reason, ifShow){//当所有加入的条件都不为false时才显示. reason='force'一般是强制、临时的
+        if(!object.unvisibleReasons) object.unvisibleReasons = []; //如果length>0代表不可见
+           
+        
+        if(ifShow){
+            var index = object.unvisibleReasons.indexOf(reason)
+            index > -1 && object.unvisibleReasons.splice(index, 1)
+            if(object.unvisibleReasons.length == 0){
+                object.visible = true;
+                object.dispatchEvent({
+                    type: 'isVisible',
+                    visible:true
+                })
+            }
+        }else{
+            var visiBefore = object.visible
+            if(!object.unvisibleReasons.includes(reason)) object.unvisibleReasons.push(reason)
+            object.visible = false    
+            visiBefore && object.dispatchEvent({
+                type: 'isVisible',
+                visible:false,
+                reason,
+            }) 
+        }
+        
+    } 
+     
+    getObjVisiByReason(object,reason){//获取在某条件下是否可见.  注: 用户在数据集选择可不可见为"datasetSelection"
+        if(object.visible)return true
+        else{
+            return !object.unvisibleReasons || !object.unvisibleReasons.includes(reason)  
+        }
+    } 
+     
+     
+     
+     
+     
+     
+     
+     
 	render(params){//add params
 		if(Potree.measureTimings) performance.mark("render-start");
 
@@ -2431,9 +2481,14 @@ export class Viewer extends ViewerBase{
 
 
     startScreenshot(info={},  width=800, height=400, compressRatio){//add
-        //可能需要一定时间,因在全景图模式需要加载完图片,所以返回一个promise
+    
+    
+    //抗锯齿待加 1 post处理 2截图大张再抗锯齿缩小
+    
+         
         
         let deferred = $.Deferred();
+        
         var screenshot = ()=>{
             var { buffer  } = this.makeScreenshot( new THREE.Vector2(width,height)  );
         
@@ -2443,7 +2498,49 @@ export class Viewer extends ViewerBase{
                 Common.downloadFile(dataUrl, 'screenshot.jpg') 
             } 
             deferred.resolve(dataUrl)
-           
+            
+            
+            
+            {//恢复:
+                
+                if(info.type == 'measure'){
+                    this.scene.measurements.forEach(e=>this.updateVisible(e, 'screenshot',true))
+                }
+                this.images360.panos.forEach(pano=>{
+                    viewer.updateVisible(pano, 'screenshot', true)
+                })    
+                viewer.updateVisible(this.reticule, 'screenshot', true)
+                viewer.updateVisible(this.mapViewer.cursor, 'screenshot', true)
+            
+                if(oldStates.attachedToViewer != this.mapViewer.attachedToViewer){
+                    if(info.type == 'measure'){
+                        this.mapViewer.attachToMainViewer(false)
+                    } 
+                }
+                mapViewport.camera.zoom = oldStates.mapZoom
+                
+                
+                
+                oldStates.viewports.forEach(old=>{//恢复相机
+                    var viewport = [mapViewport, mainViewport].find(v=>v.name == old.name);
+                    viewport.left = old.left;
+                    viewport.width = old.width;
+                    viewport.view.copy(old.view) 
+                    viewport.view.applyToCamera(viewport.camera);  
+                     
+                }) 
+                
+                viewer.updateScreenSize({forceUpdateSize:true})//更新像素
+                
+                oldStates.viewports.forEach(old=>{//恢复相机
+                    var viewport = [mapViewport, mainViewport].find(v=>v.name == old.name);
+                    this.dispatchEvent({  //update map
+                        type: "camera_changed", 
+                        camera: viewport.camera,
+                        viewport : viewport
+                    }) 
+                })  
+            } 
         }
         
         let mapViewport = this.mapViewer.viewports[0]
@@ -2455,11 +2552,23 @@ export class Viewer extends ViewerBase{
             }),
             mapZoom: mapViewport.camera.zoom
         }
-        if(info.type == 'measure'){//要截图双屏
+        //令漫游点不可见
+        this.images360.panos.forEach(pano=>{
+            viewer.updateVisible(pano, 'screenshot', false)
+        })
+        //令reticule不可见
+        viewer.updateVisible(this.reticule, 'screenshot', false)
+        //令mapCursor不可见
+        viewer.updateVisible(this.mapViewer.cursor, 'screenshot', false)
+        
+        
+        if(info.type == 'measure'){//要截图双屏 
+            this.scene.measurements.forEach(e=>this.updateVisible(e,'screenshot',e == info.measurement)  )
              
+            
             this.mapViewer.attachToMainViewer(true, 'measure', 0.5)
            
-            //viewer.updateScreenSize({forceUpdateSize:true, width, height}) 
+            viewer.updateScreenSize({forceUpdateSize:true, width, height}) //更新viewports相机透视
             
             //不同角度截图 得到三维的会不一样,因为focusOnObject是根据方向的
             let promise = this.focusOnObject(info.measurement, 'measure', 0, /*  {mapDont:true} */)
@@ -2475,8 +2584,9 @@ export class Viewer extends ViewerBase{
                     })   
                     
                 }) 
-                screenshot()
                 
+                this.mapViewer.waitLoadDone(screenshot.bind(this))//等待地图所有加载完
+                  
             })
             
         }else{
@@ -2484,37 +2594,7 @@ export class Viewer extends ViewerBase{
         }            
          
          
-        {
-        //恢复:
-            if(oldStates.attachedToViewer != this.mapViewer.attachedToViewer){
-                if(info.type == 'measure'){
-                    this.mapViewer.attachToMainViewer(false)
-                } 
-            }
-            mapViewport.camera.zoom = oldStates.mapZoom
-            
-            
-            
-            oldStates.viewports.forEach(old=>{//恢复相机
-                var viewport = [mapViewport, mainViewport].find(v=>v.name == old.name);
-                viewport.left = old.left;
-                viewport.width = old.width;
-                viewport.view.copy(old.view) 
-                viewport.view.applyToCamera(viewport.camera);  
-                 
-            }) 
-            
-            viewer.updateScreenSize({forceUpdateSize:true})//更新像素
-            
-            oldStates.viewports.forEach(old=>{//恢复相机
-                var viewport = [mapViewport, mainViewport].find(v=>v.name == old.name);
-                this.dispatchEvent({  //update map
-                    type: "camera_changed", 
-                    camera: viewport.camera,
-                    viewport : viewport
-                }) 
-            })
-        }
+        
         
         return deferred.promise()
         
@@ -2803,8 +2883,40 @@ export class Viewer extends ViewerBase{
              
     }
     
-   
+    waitForLoad(object, isLoadedCallback){//等待加载时显示loading。主要是贴图
+        this.waitQueue.push({
+            object,
+            isLoadedCallback,
+        }) 
+        1 === this.waitQueue.length && this.emit("loading", true)
+    }
+    ifAllLoaded(object){
+        if(this.waitQueue.length>0){
+            this.waitQueue = this.waitQueue.filter(function(e) {
+                return !e.isLoadedCallback()
+            })  
+        }
+       
+        0 === this.waitQueue.length && this.emit("loading", false) 
+    }
+    
     
+    setView(o={}){
+        let callback = ()=>{
+            if(o.displayMode){
+                Potree.settings.displayMode = o.displayMode
+            }
+            o.callback && o.callback()
+        } 
+        
+        if(o.pano != void 0){//pano 权重高于 position
+            this.images360.flyToPano(o)
+        }else{
+            this.scene.view.setView(o.position, o.target, o.duration, callback)
+        }
+        
+        
+    }
 };