xzw пре 3 година
родитељ
комит
0a4dc227f8

+ 145 - 0
note笔记笔记笔记.txt

@@ -0,0 +1,145 @@
+https://potree.org/potree/examples/page.html 
+http://localhost:1234/examples/page.html
+
+ 
+
+应用navvis : 
+https://testlaser.4dkankan.com/maxkk/t-iksBApb/?image=1&vlon=4.91&vlat=-0.13&fov=100.0
+https://hq.iv.navvis.com/?site=1493761991057195&vlon=1.12&vlat=-0.52&fov=100.0&image=16902
+http://139.224.42.18:8080/siemens/?pc=true&vlon=2.59&vlat=-0.03&fov=100.0&lon=116.46694741&lat=39.98387332&z=1.807
+http://indoor.popsmart.cn:8084/sxswsw-sx/?vlon=5.25&vlat=0.03&fov=100.0&pc=true&lon=120.58634810&lat=29.99135414&z=2.002
+
+用户名:admin
+密码:ipadmin
+
+ 
+========
+
+
+测试服务器可以:
+t-CwfhfqJ 大佛 有平面图 (贴图和点云有微微错位) 
+t-e2Kb2iU 隧道 
+t-8KbK1JjubE  回家湘
+t-Y22JxCS7sP 小区
+t-8BCqxQAr93 小会议室
+t-AY03FoVZhm 一楼 
+t-GusppsiKEC 字节跳动楼外场景
+
+正式服务器:
+3o5II3n9Rs 地下车库
+ 
+4dkk.html 场景:
+
+t-ia44BhY 机场(两个数据集。点量大 )
+t-iksBApb 一楼 一个数据集 十个点左右
+t-Zvd3w0m 室内 4dkk的场景 三个点 
+t-OW5ShsQ 一楼 有平面图 点五个
+
+ 
+ 
+
+
+============== 
+添加数据集登录4dkk
+18666146601
+Aa123456
+
+==========================================================================================
+
+待完善:
+
+
+
+
+---------
+优化:  |
+---------
+加载深度图(因为一开始用的全景)( 用深度图来模拟全景漫游的mesh似乎行不通,因为是非线性的,但可以加载chunks,超低模,或者重写点云shader,改成mesh的,只加载到level3)
+setView 旋转改成4dkk那种
+
+当距离很远的过渡可以考虑瞬间过渡
+热点可能需要再次矫正
+ 
+ 
+测量线截图的抗锯齿
+
+
+初始加载全景的话容易崩溃。 要不要减少点云加载。或在unfocus页面时释放点云和贴图。
+注意是否暂停下载点云or贴图了(异步请求过多会崩溃) 
+
+是否可以监听到场景的变化,变化了才渲染。要监听所有材质变化、object改变。
+
+
+---------
+Bug	|
+---------
+
+
+
+不是我的bug:
+
+有的点位贴图不准,回复说是计算问题。
+
+----------------
+截图时map为何闪一下
+ 
+隐藏数据集后再全景
+
+  
+
+空间模型 这里要显示的是自定义的平面图,但是如果没有自定义的,应该是不显示这个选项的
+
+ 
+ 
+
+地图坐标矫正??
+
+ 
+
+
+
+
+
+ 
+
+测量线点有时出来的很慢
+截图的等待全景图加载的地方写全  现在暂时用的延时
+ 
+
+
+
+测量在地图上的高度确定:
+  navvis很奇怪,在地面上很准,但是到了房屋上就只能在当前高度了。在房屋内是依靠空间模型判断属于哪个Floor楼层,得到层高。
+地图上画的datasetpoints为空   
+导航在地图上的高度怎么定
+ 
+ 
+ 
+
+
+23212 (导航)在导航页面停留一段时间不操作,界面会异常向上转 http://192.168.0.21/index.php?m=bug&f=view&bugID=23212
+ 
+分享的测量线地图上的端点大小有时大有时小 偶现
+ 
+  
+四个屏时会不停调整size opacity
+
+----
+
+春节过后改的or下周:
+
+显示mini视角 - 地图opacity变为0 获取个事件 使关闭渲染。
+
+漫游飞行的时候增加点云pointBudget, 或者创建少量的鳞片矩形(但非朝向相机,而是使用normal)
+
+
+触屏的设备还不支持。macbook触摸板的也没有检查。 还不知道navvis的表现如何
+
+
+
+根据鼠标所在位置来放大
+
+
+
+导航距离很短时,只得到一个点时,地图上的箭头好像偏离了起点终点?  
+导航地图上的margin再检查下 似乎没问题

+ 1 - 1
src/PointCloudOctree.js

@@ -108,7 +108,7 @@ export class PointCloudOctree extends PointCloudTree {
 	constructor (geometry, material) {
 		super();
     
-		this.pointBudget = Infinity;
+		//this.pointBudget = Infinity;
 		this.pcoGeometry = geometry;
 		this.boundingBox = this.pcoGeometry.boundingBox;
 		this.boundingSphere = this.boundingBox.getBoundingSphere(new THREE.Sphere());

+ 2 - 2
src/loader/BinaryLoader.js

@@ -4,7 +4,7 @@ import * as THREE from "../../libs/three.js/build/three.module.js";
 import {Version} from "../Version.js";
 import {XHRFactory} from "../XHRFactory.js";
 
-
+//加载 解析点云
 export class BinaryLoader{
 
 	constructor(version, boundingBox, scale){
@@ -52,7 +52,7 @@ export class BinaryLoader{
 		}
 	};
 
-	parse(node, buffer){
+	parse(node, buffer){ //解析点云
 		let pointAttributes = node.pcoGeometry.pointAttributes;
 		let numPoints = buffer.byteLength / node.pcoGeometry.pointAttributes.byteSize;
 

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

@@ -204,20 +204,24 @@ export class Images360 extends EventDispatcher{
         
         {//切换模式
             let displayMode = '';  
-            let lastRequestMode = '';//因为可能延迟,所以记录下每次的请求模式,延迟后判断这个
+            let latestRequestMode = '';//因为可能延迟,所以记录下每次的请求模式,延迟后判断这个
             Object.defineProperty(Potree.settings , "displayMode",{  
                 get: function() {
                     return displayMode
                 },
                 set:  (mode)=> {
-                    lastRequestMode = mode                   
+                    latestRequestMode = mode
+                    console.log('Request setMode: ' + mode)  
+                                   
                     if(mode != displayMode){
+                        this.modeChanging = true //主要是因为到全景图不会立刻成功
+                           
                         let config = Potree.config.displayMode[mode]
                         let config2 
                         let camera = viewer.scene.getActiveCamera()
                         if(mode == 'showPanos' && this.flying){//飞完才能切换全景
                             this.once('cameraMoveDone', ()=>{
-                                if(lastRequestMode == mode){//如果ui还是停在这个模式的话
+                                if(latestRequestMode == mode){//如果ui还是停在这个模式的话
                                     Potree.settings.displayMode = mode 
                                 } 
                             })
@@ -234,7 +238,7 @@ export class Images360 extends EventDispatcher{
                                 this.flyToPano({
                                     pano: /* this.currentPano ||  */Common.sortByScore(this.panos,null,[e=>-e.position.distanceTo(this.position)])[0].item,   
                                     callback: ()=>{
-                                        if(lastRequestMode == mode ){
+                                        if(latestRequestMode == mode ){
                                             Potree.settings.displayMode = mode 
                                         } 
                                     }
@@ -258,7 +262,7 @@ export class Images360 extends EventDispatcher{
                         if(config2.showSkybox || config2.pointUsePanoTex){
                             if(this.checkAndWaitForPanoLoad(this.currentPano,  this.basePanoSize, ()=> {
                                     setTimeout( ()=>{
-                                        if(lastRequestMode == mode ){
+                                        if(latestRequestMode == mode ){
                                             Potree.settings.displayMode = mode 
                                         }
                                     },1)
@@ -327,6 +331,13 @@ export class Images360 extends EventDispatcher{
                         if(this.elDisplayModel){
                             this.elDisplayModel.value = mode == 'showPointCloud' ? ">>全景" : '>>点云'
                         }
+                         
+                        this.modeChanging = false
+                        this.emit('endChangeMode',mode)  
+                        console.log('setModeSuccess: ' + mode)       
+                    }else{
+                        this.modeChanging = false  //取消modeChanging
+                        this.emit('endChangeMode',mode)    
                     }                        
                 }
             }) 
@@ -551,7 +562,7 @@ export class Images360 extends EventDispatcher{
         this.nextPano = pano
         //不飞的话是否不要执行这段?
         if(config.atPano.showSkybox || config.atPano.pointUsePanoTex){
-            if(this.checkAndWaitForPanoLoad(pano,   this.basePanoSize, ()=> {
+            if(this.checkAndWaitForPanoLoad(pano, toPano.basePanoSize || this.basePanoSize, ()=> {
                 //console.log('setTimeout 1 flyToPano')
                     setTimeout( ()=>{
                         this.flyToPano(toPano)

+ 28 - 7
src/modules/Images360/tile/TileDownloader.js

@@ -32,7 +32,14 @@ class TileDownloader extends EventDispatcher{
             Success: 2,
             Fail: 3
         });
-
+        
+        this.visible = true //add   借用viewer.updateVisible来判断是否start
+         
+        viewer.on('pageVisible', (state)=>{//不可见时不refreshUpdateInterval 
+            console.log('visibilitychange:', state)
+            viewer.updateVisible(this,  'pageVisible', state) 
+            this.judgeStart() 
+        }) 
          
     }
 
@@ -41,15 +48,28 @@ class TileDownloader extends EventDispatcher{
         this.imagePanos = t 
           //  this.panoGroupId = i
     }
-
-    start() {
-        this.started = true //add
-        this.refreshUpdateInterval(0)
+  
+    start() { 
+        viewer.updateVisible(this,'pano', true ) 
+        this.judgeStart()
     }
 
     stop() {
-        this.started = false
-        window.clearTimeout(this.refreshInterval)
+        viewer.updateVisible(this,'pano', false )
+        this.judgeStart()
+    }
+
+    judgeStart(){//add
+        if(this.visible){
+            console.log('judgeStart true')
+            this.started = true 
+            this.refreshUpdateInterval(0)
+        }else{
+            console.log('judgeStart false')
+            this.started = false
+            window.clearTimeout(this.refreshInterval)
+        }
+        
     }
 
     refreshUpdateInterval(e) {
@@ -161,6 +181,7 @@ class TileDownloader extends EventDispatcher{
     }
 
     startDownload(e) {//开始下载啦
+        //console.log('startDownload')
         e.status = DownloadStatus.Downloading;
         var t = this.getTileUrl(e/* e.pano.id, e.panoSize, e.tileSize, e.tileIndex, e.pano.alignmentType */);//xzw add alignmentType
         if(!t)return;

+ 15 - 7
src/navigation/InputHandler.js

@@ -100,6 +100,10 @@ export class InputHandler extends EventDispatcher {
 
 		e.preventDefault();
 
+
+
+
+
 		if (e.touches.length === 1) {
 			let rect = this.domElement.getBoundingClientRect();
 			let x = e.touches[0].pageX - rect.left;
@@ -275,7 +279,11 @@ export class InputHandler extends EventDispatcher {
 	onMouseDown (e) {
          
 		if (this.logMessages) console.log(this.constructor.name + ': onMouseDown');
-    
+        
+        //重新获取一下pointer, 因点击了浏览器的按钮展开列表时 move回来不会触发onmousemove,所以pointer是旧的
+        var  {  camera, viewport  } = this.getPointerInViewport(e.clientX, e.clientY ) 
+		this.hoverViewport = viewport
+        if(!viewport)return 
     
 		e.preventDefault(); 
         
@@ -323,9 +331,7 @@ export class InputHandler extends EventDispatcher {
 			}
 		}
         
-        
-        
-        
+         
         //add
         this.drag.pointerDragStart = this.pointer.clone()
         this.drag.intersectStart = this.intersectPoint;
@@ -539,10 +545,12 @@ export class InputHandler extends EventDispatcher {
         }
     }
 
+
+    
+
+
 	onMouseMove (e) {
-         
-		
-       
+          
         var  {  camera, viewport  } = this.getPointerInViewport(e.clientX, e.clientY,  this.dragViewport) 
 		this.hoverViewport = viewport
         if(!viewport)return//刚变化viewport时会找不到

+ 5 - 3
src/navigation/OrbitControls.js

@@ -30,7 +30,9 @@ export class OrbitControls extends EventDispatcher{
 		this.scene = null;
 		this.sceneControls = new THREE.Scene();
 
-		this.rotationSpeed = 5;
+		this.rotationSpeed = 3;  //旋转速度
+        this.panSpeed = 0.0002;  //平移速度
+        
 
 		this.fadeFactor = 20;
 		this.yawDelta = 0;
@@ -67,8 +69,8 @@ export class OrbitControls extends EventDispatcher{
 
 				this.stopTweens();
 			} else if (e.drag.mouse === MOUSE.RIGHT) {
-				this.panDelta.x += ndrag.x;
-				this.panDelta.y += ndrag.y;
+				this.panDelta.x += ndrag.x * (this.renderer.domElement.clientWidth) * this.panSpeed;
+				this.panDelta.y += ndrag.y * (this.renderer.domElement.clientWidth) * this.panSpeed;
 
 				this.stopTweens();
 			}

+ 7 - 1
src/navigation/Reticule.js

@@ -79,7 +79,13 @@ export default class Reticule extends THREE.Mesh{
             if (!intersectPoint /* || !intersectPoint.point.normal */)
                 return //this.hide();
             var atMap = !intersectPoint.location
-            let normal = intersectPoint.point ? new THREE.Vector3().fromArray(intersectPoint.point.normal ) : new THREE.Vector3(0,0,1)//地图无normal
+            let normal
+            if(atMap){
+                normal =  new THREE.Vector3(0,0,1)//地图无normal
+            }else{
+                normal = new THREE.Vector3().fromArray(intersectPoint.point.normal ).applyMatrix4(intersectPoint.pointcloud.transformMatrix);
+            }
+             
             let s, camera
             let location = intersectPoint.location || intersectPoint.orthoIntersect.clone()
                 

+ 60 - 40
src/navigation/RouteGuider.js

@@ -3,7 +3,7 @@ import * as THREE from "../../libs/three.js/build/three.module.js";
 import {Utils} from "../utils.js";
 import { EventDispatcher } from "../EventDispatcher.js";
 import Sprite from '../viewer/Sprite'
-
+import Common from "../utils/Common.js";
 
 const texLoader = new THREE.TextureLoader()
 const arrowSpacing = 1 //间隔
@@ -175,7 +175,7 @@ export class RouteGuider extends EventDispatcher{
     setArrowDir(arrows,index){
         let arrow = arrows[index]
         var nextOne = arrows[index+1];
-        var nextPos = nextOne ? nextOne.position : this.routeEnd
+        var nextPos = nextOne ? nextOne.position : this.endPolePos //routeEnd
         var direction = new THREE.Vector3().subVectors(arrow.position, nextPos).setZ(0);
         //direction.normalize();
         //console.log(direction.toArray())
@@ -188,35 +188,38 @@ export class RouteGuider extends EventDispatcher{
      
     
     
-    setRouteStart(pos, dealMapZ, ifReset){
+    setRouteStart(pos, dealMapZ   ){
         if(this.routeStart && pos && this.routeStart.equals(pos)) return //可能重复设置
         this.routeStart = pos && new THREE.Vector3().copy(pos) 
         //if(dealMapZ && this.routeStart) this.routeStart.setZ(0)//后端要求设置为0,但设置后反而得不到了。直接用的是接近boundingbox.min.z的值
-            console.log('setRouteStart',ifReset,this.routeStart&&this.routeStart.toArray()) 
-       
-        if(ifReset){
-            this.bus && this.bus.emit('reposStartMarker', pos)
-        }else{
-            this.generateRoute()
-        }
+        console.log('setRouteStart',this.routeStart&&this.routeStart.toArray()) 
+        
+        
+        this.generateRoute()
+        
         
     }
     
+    setStartPole(pos){
+        this.startPolePos = pos
+        this.bus && this.bus.emit('reposStartMarker', pos)
+    }
+     
     
-    
-    setRouteEnd(pos, dealMapZ, ifReset){ 
+    setRouteEnd(pos, dealMapZ   ){ 
         if(this.routeEnd && pos && this.routeEnd.equals(pos)) return 
         this.routeEnd = pos && new THREE.Vector3().copy(pos)
         //if(dealMapZ && this.routeEnd) this.routeEnd.setZ(0)//后端要求设置为0
-            console.log('setRouteEnd',ifReset,this.routeEnd&&this.routeEnd.toArray())        
+        console.log('setRouteEnd',this.routeEnd&&this.routeEnd.toArray())        
+        
+        
+        this.generateRoute()
         
-        if(ifReset){
-            this.bus && this.bus.emit('reposEndMarker', pos)
-        }else{
-            this.generateRoute()
-        }
     }
-    
+    setEndPole(pos){
+        this.endPolePos = pos
+        this.bus && this.bus.emit('reposEndMarker', pos)
+    }
     
     getSourceProjectionIndex(route) {//真正的起始
         var e = route.findIndex(function(t) {
@@ -233,6 +236,7 @@ export class RouteGuider extends EventDispatcher{
     
     generateRoute(){
         if(!this.routeStart || !this.routeEnd){ 
+            
             return
         }
         
@@ -260,7 +264,7 @@ export class RouteGuider extends EventDispatcher{
             this.updateMapArrows() 
             this.displayRoute()
             
-            {
+            {//map focus on this area
                 
                 const minBound = new THREE.Vector2(1,1)//针对垂直线,在地图上只有一个点
                 let bound = new THREE.Box2;
@@ -268,7 +272,13 @@ export class RouteGuider extends EventDispatcher{
                     bound.expandByPoint(e)
                 })
                 let size = bound.getSize(new THREE.Vector2)
-                let margin = viewer.mapViewer.viewports[0].resolution2.clone().multiplyScalar(0.01)
+                let markerSize = new THREE.Vector2(115,40) //起始和终点的标识呈长方形
+                let areaSize = viewer.mapViewer.viewports[0].resolution2
+                let areaArea = areaSize.x * areaSize.y
+                if(areaArea> 800 * 400){//是放大的 
+                    markerSize.multiplyScalar(areaArea / (800 * 400) /* / (size.x * size.y) */) 
+                }
+                let margin = size.clone().divide(viewer.mapViewer.viewports[0].resolution2).multiply(markerSize) ///边距 重点是起始和终点的标识占据较大
                 size.add(margin)
                 let center = bound.getCenter(new THREE.Vector2)
                 
@@ -287,19 +297,28 @@ export class RouteGuider extends EventDispatcher{
         if(Potree.fileServer){
             let dealData = (data)=>{
                 
-                if(!data){
+                if(!data.data){
                     console.log('没有数据')
-                    this.bus && this.bus.emit('gotResult','没有数据')
+                    let result
+                    if(data && data.code == 4002){
+                        result = data;//正被修改数据集
+                    }else{
+                        result = { code: 500, msg: '超出数据集范围,无法规划路线' }
+                    }
+                    this.clearRoute()  
+                    this.bus && this.bus.emit('gotResult', result )
                     
                     return //this.generateDeferred && this.generateDeferred.resolve()
                 }
-                 
+                
+                
+                data = data.data 
                   
                 this.clearRoute()
                 let length = data.length
                 
-                if(length == 0){//可能距离太短
-                    console.log('路径点数为0,直接取起点和终点连线')
+                if(length < 2){//可能距离太短 
+                    console.log('路径点数为'+length+',直接取起点和终点连线') 
                     this.route = [this.routeStart, this.routeEnd];
                 }else{ 
                     let startIndex = this.getSourceProjectionIndex(data)
@@ -315,8 +334,8 @@ export class RouteGuider extends EventDispatcher{
                     
                     console.log(this.route)
                     
-                    this.setRouteStart(this.route[0],false, true) 
-                    this.setRouteEnd(this.route[this.route.length-1],false,true) 
+                    this.setStartPole(this.route[0]) 
+                    this.setEndPole(this.route[this.route.length-1]) 
                 }
                 create()
                 /*
@@ -334,21 +353,20 @@ export class RouteGuider extends EventDispatcher{
             
             
             
-            if(this.lastResult){
-                let data, use;  //直接用上次的结果
+            if(this.lastResult && (this.lastResult.data || this.lastResult.data.code != 4002)){//正被修改数据集的话要重新计算
+                let data = Common.CloneObject(this.lastResult.data) ,  use;  //直接用上次的结果
                 if(this.lastResult.routeStart.equals(this.routeStart) &&  this.lastResult.routeEnd.equals(this.routeEnd)){//和上次请求相同
-                    use = true
-                    data = this.lastResult.data
-                    
+                    use = true 
                 }else if(this.lastResult.routeStart.equals(this.routeEnd) &&  this.lastResult.routeEnd.equals(this.routeStart)){//..反向
                     use = true
-                    data = this.lastResult.data.slice(0).reverse()
+                    if(data.data){
+                        data.data = this.lastResult.data.data.slice(0).reverse()
+                    }    
                 }
                 if(use){
                     console.log('直接用上次的结果')
                     return setTimeout(()=>{dealData(data)}, 1)//延迟是为了等待获得 RouteGuider.generateDeferred
-                     
-                    
+                       
                 }
                 
             }
@@ -381,10 +399,11 @@ export class RouteGuider extends EventDispatcher{
                 this.lastResult = {//保存数据
                     routeStart : this.routeStart.clone(),
                     routeEnd: this.routeEnd.clone(),
-                    data : data.data
+                    data,
+                     
                 }
                 
-                dealData(data.data)
+                dealData(data)
                 
             })
             
@@ -439,8 +458,8 @@ export class RouteGuider extends EventDispatcher{
     displayRoute(o={}){
         if(!o.resetMap){ 
             
-            this.poleStart.position.copy(this.routeStart)
-            this.poleEnd.position.copy(this.routeEnd)
+            this.poleStart.position.copy(this.startPolePos || this.routeStart)
+            this.poleEnd.position.copy(this.endPolePos || 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))
@@ -472,6 +491,7 @@ export class RouteGuider extends EventDispatcher{
         
         this.sceneMeshGroup.visible = false 
         this.mapMeshGroup.visible = false
+        viewer.mapViewer.dispatchEvent({'type':'content_changed'})
     }
     
     clear(){//退出

+ 21 - 1
src/settings.js

@@ -97,7 +97,7 @@ const config = {//配置参数   不可修改
             pointBudget :0.25*1000*1000, // 只要限制这个就足够 (为什么分屏focus区域不同会闪烁,navvis不会)(navvis:maxLevel:5,pointBudget:1*1000*1000)
         },
         low:{//highPerformance
-            maxLevelPercent: 0.5, //最小为0
+            maxLevelPercent: 0.4, //最小为0
             pointBudget :1*1000*1000,
         }, 
         middle:{//balanced  //不同场景相同级别所产生的numVisibleNodes和numVisiblePoints不同,如果分层比较细,可能要到level8才能看清,那么level5看到的点就很大且很少,如隧道t-e2Kb2iU
@@ -109,6 +109,7 @@ const config = {//配置参数   不可修改
             pointBudget:8*1000*1000,
         }
         //minNodeSize?
+        //数值由testLevelSteps得来,其中nodeMaxLevel为2时,low和middle的都是1,如果真有这么低的点云就单独处理下。
     },
     
     
@@ -293,6 +294,9 @@ let settings = {//设置   可修改
     
     navTileClass:'2k',  //默认加载到
     tileClass:'4k',     //最高可达
+    /* loadTilesWhenUnfocus:false, //页面unfocus时也仍在加载tiles
+    loadPointsWhenUnfocus:true, //页面unfocus时也仍在加载点云 */
+   
     //initialShowPano:true
 }
 
@@ -307,4 +311,20 @@ settings.isLocalhost = settings.prefix.includes('localhost')
  
  
  */
+ 
+ 
+window.testLevelSteps = function(steps){//[0.4,0.7,1]
+    if(!steps){
+        let s = Potree.config.pointDensity;
+        steps = [s.low.maxLevelPercent, s.middle.maxLevelPercent, s.high.maxLevelPercent, ]
+    }
+    let max = 1
+    while(++max<=12){ 
+        let r1 = steps.map(e=>e * max);
+        let r2 = steps.map(e=>Math.round(e * max));
+        console.log(`当nodeMaxLevel为${max}时,每一级的level分别为${r2}, (小数:${r1})`) 
+    }
+    console.log('请检查每一层的三个level是否有重复')
+     
+} 
 export {config, settings}

+ 1 - 1
src/start.js

@@ -10,7 +10,7 @@ import {Utils} from "../src/utils.js"
 
 var start = function(dom, mapDom, number, fileServer){ //t-Zvd3w0m
 
-    console.log('start')
+    
     Potree.settings.number = number || 't-o5YMR13'// 't-iksBApb'// 写在viewer前
     Potree.fileServer = fileServer
     

+ 2 - 2
src/utils/Common.js

@@ -99,7 +99,7 @@ var Common = {
             return copyObj.slice(0);*/ //如果是数组,直接复制返回(排除数组内是object 
             return copyObj.map(e=>{
                 if(e instanceof Object){
-                    return CloneObject(e)
+                    return this.CloneObject(e)
                 }else return e 
             })
            
@@ -110,7 +110,7 @@ var Common = {
         }
         for (var key in copyObj) {
             if (copyObj[key] instanceof Object && !isSimpleCopy)
-                result[key] = CloneObject(copyObj[key]);
+                result[key] = this.CloneObject(copyObj[key]);
             else
                 result[key] = copyObj[key];
             //如果是函数类同基本数据,即复制引用

+ 1 - 1
src/utils/Measure.js

@@ -22,7 +22,7 @@ var lineMats;
 var planeMats 
 
 const markerSizeInfo = {
-    minSize : 25 ,  maxSize : 65,   nearBound : 0.2, farBound : 8,
+    minSize : 25 ,  maxSize : 65,   nearBound : 0.2, farBound : 4,
 }
 const labelSizeInfo = {width2d:200}
 const mainLabelProp = { 

+ 42 - 42
src/viewer/View.js

@@ -220,6 +220,48 @@ export class View{
 	} */
 
 
+
+    restrictPos(){//add
+        if(this.limitBound){
+            this.position.clamp(this.limitBound.min, this.limitBound.max)
+        }
+    }
+
+
+
+    setCubeView(dir) {
+		 
+		switch(dir) {
+			case "Front":
+				this.yaw = 0;
+                this.pitch = 0;
+				break;
+			case "Back":
+				this.yaw =  Math.PI;  
+                this.pitch = 0;
+				break;
+			case "Left":
+				this.yaw = -Math.PI / 2;
+                this.pitch = 0;
+				break;
+			case "Right":
+				this.yaw = Math.PI / 2;
+                this.pitch = 0;
+				break;
+			case "Top":
+				this.yaw = 0;
+                this.pitch = -Math.PI / 2;
+				break;
+			case "Bottom":
+				this.yaw = -Math.PI;
+                this.pitch = Math.PI / 2;
+				break;
+		}
+	}
+    
+    
+    
+    
     setView(position, target, duration = 0, callback = null, onUpdate = null, Easing=''){
         //待改成quater渐变
         let endPosition = null;
@@ -269,48 +311,6 @@ export class View{
         } 
 
     }
-
-    restrictPos(){//add
-        if(this.limitBound){
-            this.position.clamp(this.limitBound.min, this.limitBound.max)
-        }
-    }
-
-
-
-    setCubeView(dir) {
-		 
-		switch(dir) {
-			case "Front":
-				this.yaw = 0;
-                this.pitch = 0;
-				break;
-			case "Back":
-				this.yaw =  Math.PI;  
-                this.pitch = 0;
-				break;
-			case "Left":
-				this.yaw = -Math.PI / 2;
-                this.pitch = 0;
-				break;
-			case "Right":
-				this.yaw = Math.PI / 2;
-                this.pitch = 0;
-				break;
-			case "Top":
-				this.yaw = 0;
-                this.pitch = -Math.PI / 2;
-				break;
-			case "Bottom":
-				this.yaw = -Math.PI;
-                this.pitch = Math.PI / 2;
-				break;
-		}
-	}
-    
-    
-    
-    
     
     
 };

+ 19 - 12
src/viewer/map/Map.js

@@ -51,15 +51,15 @@ export class MapLayer extends EventDispatcher{ // 包括了 MapLayerBase SceneLa
         this.frustum = new THREE.Frustum 
         this.frustumMatrix = new THREE.Matrix4 
         this.tileColor = /* i && i.tileColor ? i.tileColor :  */new THREE.Color(16777215)
-        
-        
+        this.viewport = viewport
+        this.changeViewer(viewer_) 
         //添加地图
         var map = new TiledMapOpenStreetMap(this, this.tileColor )
         this.addMap(map)
-         
+        //map.setEnable(false)
+        
+        
         
-        this.viewport = viewport
-        this.changeViewer(viewer_) 
         
         /* this.on('needUpdate',()=>{ 
             this.mapLayer.update()
@@ -140,7 +140,7 @@ export class MapLayer extends EventDispatcher{ // 包括了 MapLayerBase SceneLa
         this.needUpdate = false
         if(this.disabled || !this.maps.find(e=>!e.disabled) || !this.maps.find(e=>e.objectGroup.visible)   )return  //add
         
-         
+          
         var e, n, i, r, o;
         
         this.updateTimer = void 0,
@@ -222,6 +222,8 @@ export class TiledMapBase extends EventDispatcher{
         if(this._zoomLevel != zoomLevel){
             this._zoomLevel = zoomLevel
             this.emit('zoomLevelChange',zoomLevel)
+             
+            if(this.name == 'map')console.log(zoomLevel,viewer.mapViewer.camera.zoom)
         }
     }
     
@@ -285,14 +287,14 @@ export class TiledMapBase extends EventDispatcher{
     
     update(e, n){
         
-        
-        if(this.disabled || !this.objectGroup.visible)return
+        var unavailable = (this.disabled || !this.objectGroup.visible)//地图即使不显示也要获得zoomlevel
+        if(this.name != 'map' && unavailable)return 
         
         this.updateProjection()
         
         if(!this.transformMapToLocal)return
         
-        if ( !this.isTileVisible(new THREE.Vector3(0,0,0), this.mapSizeM, e))
+        if (!this.isTileVisible(new THREE.Vector3(0,0,0), this.mapSizeM, e))
             return this.removeFromSceneGroup(n), !0;
         
         let viewport = this.mapLayer.viewport
@@ -310,17 +312,22 @@ export class TiledMapBase extends EventDispatcher{
         i.sub(o),
         i.x *= a / 2,
         i.y *= s / 2;
+        
         var c = this.tileSizePx / i.length()
           , level = Math.ceil(-Math.log(c) / Math.log(2) - this.bias);
         level = Math.max(level, 0) 
         level = Math.min(level, void 0 === this.maxDepth ? 1 / 0 : this.maxDepth) 
         this.zoomLevel = level//add
         //console.log(level)
-        
-        this.addToSceneGroup(n) 
-        return this.baseTile.update(this, e, level, this.mapSizeM, 0, 0, "")
+        if(!unavailable){
+            this.addToSceneGroup(n) 
+            return this.baseTile.update(this, e, level, this.mapSizeM, 0, 0, "")
+        }
     }
      
+     
+     
+     
     isTileVisible(e, n, i){
         if (n > HALF_WORLD_SIZE) return !0;
         var r = .5 * n;

+ 26 - 12
src/viewer/viewer.js

@@ -96,7 +96,12 @@ export class Viewer extends ViewerBase{
 		</div>`);
 		$(domElement).append(this.elMessages);
 		
+         
+        document.addEventListener('visibilitychange',(e)=>{ 
+            this.emit('pageVisible', !document.hidden )
+        })
         
+         
             
         try{
             
@@ -431,15 +436,15 @@ export class Viewer extends ViewerBase{
                                 e.maxLevel = 12;//先加载到最大的直到测试完毕。由于5个level为一组来加载,所以如果写4最高能加载到5,如果写5最高能加载到下一个级别的最高也就是10
                                 //console.log('maxLevel: '+e.maxLevel +  ' testingMaxLevel中 '  )                                
                             }else{
-                                e.maxLevel = Math.floor(config.maxLevelPercent * e.nodeMaxLevel); 
-                                //console.log('maxLevel: '+e.maxLevel +  '  ( density : '+density);
+                                e.maxLevel = Math.round(config.maxLevelPercent * e.nodeMaxLevel); 
+                                console.log('maxLevel: '+e.maxLevel +  '  ( density : '+density);
                                 
                                 if(Potree.settings.sizeFitToLevel){
                                     e.changePointSize() 
                                 } 
                                 e.changePointOpacity()
                             } 
-                            
+                             
                            
                         }) 
                         pointDensity = density
@@ -2595,14 +2600,14 @@ export class Viewer extends ViewerBase{
      
      
      
-     
-     
+    /* 大规模WebGL应用引发浏览器崩溃的几种情况及解决办法
+    https://blog.csdn.net/weixin_30378311/article/details/94846947 */
      
 	render(params){//add params
 		if(Potree.measureTimings) performance.mark("render-start");
 
 		//try{
-
+            //console.log('rendering')//在unfocus页面时就会停止渲染
 			const vrActive = this.renderer.xr.isPresenting;
 
 			if(vrActive){
@@ -2665,6 +2670,7 @@ export class Viewer extends ViewerBase{
                 
                 if(info.type == 'measure'){
                     this.scene.measurements.forEach(e=>this.updateVisible(e, 'screenshot',true))
+                    info.measurement.setSelected(false, 'screenshot')
                 }
                 this.images360.panos.forEach(pano=>{
                     viewer.updateVisible(pano, 'screenshot', true)
@@ -2741,14 +2747,14 @@ export class Viewer extends ViewerBase{
         
         if(info.type == 'measure'){//要截图双屏 
             this.scene.measurements.forEach(e=>this.updateVisible(e,'screenshot',e == info.measurement)  )
-             
+            info.measurement.setSelected(true, 'screenshot')
             
             this.mapViewer.attachToMainViewer(true, 'measure', 0.5  )//不要移动相机去适应
            
             viewer.updateScreenSize({forceUpdateSize:true, width, height}) //更新viewports相机透视
             
             //不同角度截图 得到三维的会不一样,因为focusOnObject是根据方向的
-            let promise = this.focusOnObject(info.measurement, 'measure', 0, /*  {mapDont:true} */)
+            let promise = this.focusOnObject(info.measurement, 'measure', 0,    {basePanoSize:1024} )
             promise.done(()=>{ 
                 console.log('promise.done') 
                 this.viewports.forEach(e=>{
@@ -2804,15 +2810,22 @@ export class Viewer extends ViewerBase{
     focusOnObject(object, type, duration, o={} ) {
         //飞向热点、测量线等 。
         
+        console.log('focusOnObject: '+object.name,  type)
         
-        
-        let deferred = $.Deferred();
+        let deferred = o.deferred || $.Deferred();
         let target  = new THREE.Vector3,
             position = new THREE.Vector3, 
             dis;
         duration = duration == void 0 ? 2000 : duration;     
         let camera = viewer.scene.getActiveCamera()
         
+        
+        if(this.images360.modeChanging){
+            this.images360.once('endChangeMode',()=>{
+                this.focusOnObject(object, type, duration, $.extend(o,{deferred}))
+            })
+            return deferred.promise();//不能打扰 从点云转向全景图时 的飞行
+        }
         if (type == 'measure') {  
             target.copy(object.getCenter()) 
        
@@ -2884,7 +2897,7 @@ export class Viewer extends ViewerBase{
                     //bestDistance : dis * 0.5, //乘以小数是为了尽量靠近 
                     boundSphere: boundOri.getBoundingSphere(new THREE.Sphere),
                 })
-                pano && viewer.images360.flyToPano({pano, target, duration, deferred, dontMoveMap:true })//dontMoveMap不要移动map,否则flytopano会自动在map中focus到漫游点的位置,而非测量线了
+                pano && viewer.images360.flyToPano({pano, target, duration, deferred, dontMoveMap:true  , basePanoSize:o.basePanoSize})//dontMoveMap不要移动map,否则flytopano会自动在map中focus到漫游点的位置,而非测量线了
                 
                 if(!pano){
                     console.error('no pano')
@@ -2913,7 +2926,7 @@ export class Viewer extends ViewerBase{
                     point : target,
                     bestDistance  //越近越好,但不要太近,bestDistance左右差不多
                 })
-                pano && viewer.images360.flyToPano({pano, target, duration, deferred, dontMoveMap:true  })
+                pano && viewer.images360.flyToPano({pano, target, duration, deferred, dontMoveMap:true , basePanoSize:o.basePanoSize })
                 return deferred                
             }
         }
@@ -2932,6 +2945,7 @@ export class Viewer extends ViewerBase{
         } */
 
         viewer.scene.view.setView(position, target, duration, ()=>{
+            console.log('focusOnObjectSuccess: '+object.name,  type)
             deferred.resolve()
         })